Imports
Imports
Section titled “Imports”Imports allow you to reuse setup functions, fixtures, and test utilities across multiple scaf files.
Basic Syntax
Section titled “Basic Syntax”// Import a moduleimport "./shared/fixtures"
// Import with aliasimport fixtures "./shared/fixtures"Import Paths
Section titled “Import Paths”Paths are relative to the current file:
project/├── queries/│ ├── users.scaf # import "../shared/fixtures"│ └── posts.scaf # import "../shared/fixtures"├── shared/│ └── fixtures.scaf # defines reusable setups└── .scaf.yamlUsing Imported Setups
Section titled “Using Imported Setups”After importing, use the module’s functions in setup blocks:
import fixtures "./shared/fixtures"
// Use as named setupsetup fixtures.CreateUsers()
// With parameters (no $ prefix)setup fixtures.CreatePosts(count: 10, authorId: 1)Defining Reusable Setups
Section titled “Defining Reusable Setups”In your shared file, define functions that can be called as setups:
// Simple setup - no parametersfn CreateUsers() `CREATE (alice:User {id: 1, name: "Alice", email: "alice@example.com", age: 30})CREATE (bob:User {id: 2, name: "Bob", email: "bob@example.com", age: 25})`
// Parameterized setupfn CreatePosts(count: int, authorId: int) `UNWIND range(1, $count) as iCREATE (:Post { id: i, authorId: $authorId, title: "Post " + toString(i), createdAt: timestamp()})`
// Setup with relationshipsfn CreateFriendships(userId: int, friendIds: [int]) `MATCH (u1:User {id: $userId})UNWIND $friendIds as friendIdMATCH (u2:User {id: friendId})CREATE (u1)-[:FRIENDS_WITH]->(u2)`Using Fixtures
Section titled “Using Fixtures”import fixtures "../shared/fixtures"
fn GetUser(userId: string) `MATCH (u:User {id: $userId})RETURN u.name, u.email, u.age`
// Suite setup using fixturesetup fixtures.CreateUsers()
GetUser { // Scope setup with parameters (no $ prefix) setup fixtures.CreatePosts(count: 5, authorId: 1)
group "with friends" { // Group setup with parameters setup fixtures.CreateFriendships(userId: 1, friendIds: [2])
test "user has friends and posts" { $userId: 1 u.name: "Alice" } }}Aliases
Section titled “Aliases”Use aliases to distinguish between multiple imports:
import users "./shared/user-fixtures"import posts "./shared/post-fixtures"import common "./shared/common"
setup common.ClearDatabase()setup users.CreateTestUsers()setup posts.CreateTestPosts(count: 10)Import Resolution
Section titled “Import Resolution”scaf resolves imports at parse time:
- Path is resolved relative to the importing file
- The imported file is parsed
- Function definitions become available via the alias
Module Organization
Section titled “Module Organization”By Data Type
Section titled “By Data Type”shared/├── users.scaf # User fixtures├── posts.scaf # Post fixtures├── comments.scaf # Comment fixtures└── common.scaf # Clear database, etc.By Purpose
Section titled “By Purpose”shared/├── fixtures.scaf # Test data creation├── cleanup.scaf # Teardown utilities└── assertions.scaf # Common assertion functionsHierarchical
Section titled “Hierarchical”shared/├── fixtures/│ ├── users.scaf│ ├── posts.scaf│ └── index.scaf # Re-exports all└── utils/ └── cleanup.scafPassing Parameters
Section titled “Passing Parameters”Simple Values
Section titled “Simple Values”setup fixtures.CreateUser(id: 1, name: "Alice")Collections
Section titled “Collections”setup fixtures.CreateFriendships( userId: 1, friendIds: [2, 3, 4, 5])setup fixtures.CreateUser( id: 1, data: {name: "Alice", email: "alice@example.com", age: 30})From Query Results (Field References)
Section titled “From Query Results (Field References)”test "with dynamic data" { $userId: 1
u.id: 1
// Use result value as parameter assert fixtures.CountPosts(authorId: u.id) { (count >= 0) }}Best Practices
Section titled “Best Practices”-
Group related fixtures — Keep user fixtures together, post fixtures together, etc.
-
Use descriptive names —
CreateUserWithPostsis clearer thanSetup1 -
Parameterize when possible — Make fixtures flexible
-
Add type annotations — Improves documentation and validation
-
Document complex fixtures — Add comments explaining the data structure
-
Keep fixtures focused — One responsibility per setup function
// Creates a standard test user with optional profile// Parameters:// id: User ID (required)// name: Display name (required)// withProfile: Create profile if true (optional, default false)fn CreateUserWithProfile(id: string, name: string, withProfile: bool?) `CREATE (u:User {id: $id, name: $name})WITH uFOREACH (x IN CASE WHEN $withProfile THEN [1] ELSE [] END | CREATE (u)-[:HAS_PROFILE]->(:Profile {bio: "Hello, I am " + $name}))RETURN u`Import Errors
Section titled “Import Errors”scaf reports errors for:
- File not found
- Circular imports
- Invalid path syntax
- Missing function definitions
Error: import "./shared/fixtures" → file not found: ./shared/fixtures.scaf
Error: circular import detected → a.scaf imports b.scaf imports a.scaf