Skip to content

Commit cb420b2

Browse files
committed
refresh the readme with recent changes
1 parent 03173f2 commit cb420b2

File tree

1 file changed

+230
-37
lines changed

1 file changed

+230
-37
lines changed

README.md

Lines changed: 230 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# Shopify Functions WASM Testing Helpers
22

3-
A JavaScript library that rpovides helpers for testing Shopify Functions WASM (WebAssembly) modules. This library provides four core utilities: `loadFixture`, `validateFixture`, `buildFunction`, and `runFunction`.
3+
A JavaScript library that provides helpers for testing Shopify Functions WASM (WebAssembly) modules. This library provides utilities for loading fixtures, validating test assets, building functions, and running functions.
44

55
## Installation
66

@@ -13,70 +13,258 @@ npm install @shopify/shopify-function-test-helpers
1313
### Basic Usage
1414

1515
```javascript
16-
const {
16+
import {
17+
buildFunction,
1718
loadFixture,
18-
validateFixture,
19+
loadSchema,
20+
loadInputQuery,
21+
validateTestAssets,
22+
runFunction,
23+
} from "@shopify/shopify-function-test-helpers";
24+
25+
// Load the GraphQL schema and input query
26+
const schema = await loadSchema("/path/to/schema.graphql");
27+
const inputQueryAST = await loadInputQuery("/path/to/src/run.graphql");
28+
29+
// Load a test fixture
30+
const fixture = await loadFixture("/path/to/fixtures/my-test.json");
31+
32+
// Build the function
33+
await buildFunction("/path/to/function");
34+
35+
// Validate the test assets
36+
const validationResult = await validateTestAssets({
37+
schema,
38+
fixture,
39+
inputQueryAST,
40+
});
41+
42+
console.log(` Input Query: ${validationResult.inputQuery.valid ? '' : ''}`);
43+
console.log(` Input Fixture: ${validationResult.inputFixture.valid ? '' : ''}`);
44+
console.log(` Input Query-Fixture Match: ${validationResult.inputQueryFixtureMatch.valid ? '' : ''}`);
45+
console.log(` Output Fixture: ${validationResult.outputFixture.valid ? '' : ''}`);
46+
47+
// Run the function
48+
const runResult = await runFunction(
49+
fixture.export,
50+
fixture.input,
51+
"/path/to/function"
52+
);
53+
54+
console.log("Output:", runResult.result.output);
55+
console.log("Expected:", fixture.expectedOutput);
56+
```
57+
58+
### Complete Test Example
59+
60+
For a full test suite that runs multiple fixtures:
61+
62+
```javascript
63+
import path from "path";
64+
import fs from "fs";
65+
import {
1966
buildFunction,
20-
runFunction
21-
} = require('@shopify/shopify-function-test-helpers');
67+
loadFixture,
68+
runFunction,
69+
validateTestAssets,
70+
loadSchema,
71+
loadInputQuery,
72+
} from "@shopify/shopify-function-test-helpers";
73+
74+
describe("Function Tests", () => {
75+
let schema;
76+
let inputQueryAST;
77+
let functionDir;
78+
79+
beforeAll(async () => {
80+
functionDir = path.dirname(__dirname);
81+
await buildFunction(functionDir);
82+
83+
const schemaPath = path.join(functionDir, "schema.graphql");
84+
const inputQueryPath = path.join(functionDir, "src/run.graphql");
85+
86+
schema = await loadSchema(schemaPath);
87+
inputQueryAST = await loadInputQuery(inputQueryPath);
88+
}, 10000);
89+
90+
const fixturesDir = path.join(__dirname, "fixtures");
91+
const fixtureFiles = fs
92+
.readdirSync(fixturesDir)
93+
.filter((file) => file.endsWith(".json"))
94+
.map((file) => path.join(fixturesDir, file));
95+
96+
fixtureFiles.forEach((fixtureFile) => {
97+
test(`runs ${path.basename(fixtureFile)}`, async () => {
98+
const fixture = await loadFixture(fixtureFile);
99+
100+
const validationResult = await validateTestAssets({
101+
schema,
102+
fixture,
103+
inputQueryAST,
104+
});
105+
106+
expect(validationResult.inputQuery.valid).toBe(true);
107+
expect(validationResult.inputFixture.valid).toBe(true);
108+
expect(validationResult.inputQueryFixtureMatch.valid).toBe(true);
109+
expect(validationResult.outputFixture.valid).toBe(true);
110+
111+
const runResult = await runFunction(
112+
fixture.export,
113+
fixture.input,
114+
functionDir
115+
);
116+
117+
expect(runResult.error).toBeNull();
118+
expect(runResult.result.output).toEqual(fixture.expectedOutput);
119+
}, 10000);
120+
});
121+
});
122+
```
22123

23-
// Load a fixture from test data
24-
const fixture = loadFixture('20250915_184036_156Z_extensions_cart-checkout-validation_ba711d.json');
124+
## API Reference
125+
126+
### Core Functions
127+
128+
#### `loadFixture(fixturePath)`
129+
130+
Loads a fixture file from the specified path.
25131

26-
// Validate the fixture structure
27-
const validation = validateFixture(fixture);
28-
console.log('Is valid:', validation.isValid);
132+
**Parameters:**
133+
134+
- `fixturePath` (string): Path to the fixture JSON file
29135

30-
// Build a function
31-
const payload = buildFunction();
136+
**Returns:** Promise<FixtureData> - Fixture object containing `export`, `input`, `expectedOutput`, and `target`
32137

33-
// Run a function implementation
138+
**Example:**
34139

35-
const result = runFunction(payload, mockFunction);
36-
console.log('Result status:', result.status);
140+
```javascript
141+
const fixture = await loadFixture("./fixtures/my-test.json");
37142
```
38143

39-
## API Reference
144+
---
40145

41-
### Functions
146+
#### `loadSchema(schemaPath)`
42147

43-
#### `loadFixture(filename)`
44-
Loads a fixture from the test_data directory.
148+
Loads a GraphQL schema from a file.
45149

46150
**Parameters:**
47-
- `filename`: Name of the fixture file
48151

49-
**Returns:** Fixture object
152+
- `schemaPath` (string): Path to the schema.graphql file
50153

51-
**Throws:** Error if fixture file is not found
154+
**Returns:** Promise<GraphQLSchema> - Parsed GraphQL schema
52155

53-
#### `validateFixture(fixture)`
54-
Validates a fixture to ensure it has the correct structure.
156+
**Example:**
157+
158+
```javascript
159+
const schema = await loadSchema("./schema.graphql");
160+
```
161+
162+
---
163+
164+
#### `loadInputQuery(queryPath)`
165+
166+
Loads and parses a GraphQL input query.
55167

56168
**Parameters:**
57-
- `fixture`: The fixture data to validate
58169

59-
**Returns:** ValidationResult object with `isValid` boolean and `errors` array
170+
- `queryPath` (string): Path to the GraphQL query file
171+
172+
**Returns:** Promise<DocumentNode> - Parsed GraphQL query AST
173+
174+
**Example:**
175+
176+
```javascript
177+
const inputQueryAST = await loadInputQuery("./src/run.graphql");
178+
```
179+
180+
---
181+
182+
#### `validateTestAssets(options)`
183+
184+
Validates test assets including input query, fixture input/output, and query-fixture match.
185+
186+
**Parameters:**
187+
188+
- `options` (ValidateTestAssetsOptions):
189+
- `schema` (GraphQLSchema): The GraphQL schema
190+
- `fixture` (FixtureData): The fixture to validate
191+
- `inputQueryAST` (DocumentNode): The input query AST
192+
- `mutationName` (string, optional): The mutation name (auto-detected if not provided)
193+
- `resultParameterName` (string, optional): The result parameter name (auto-detected if not provided)
194+
195+
**Returns:** Promise<CompleteValidationResult> - Validation results for all validation steps:
196+
197+
- `inputQuery`: { valid: boolean, errors: readonly GraphQLError[] }
198+
- `inputFixture`: { valid: boolean, errors: string[], data: any }
199+
- `inputQueryFixtureMatch`: { valid: boolean, errors: string[] }
200+
- `outputFixture`: { valid: boolean, errors: { message: string }[], mutationName: string | null, resultParameterType: string | null }
201+
- `mutationName?`: string - Auto-detected mutation name
202+
- `resultParameterName?`: string - Auto-detected result parameter name
203+
- `error?`: string - Top-level error if validation fails
204+
205+
**Example:**
206+
207+
```javascript
208+
const validationResult = await validateTestAssets({
209+
schema,
210+
fixture,
211+
inputQueryAST,
212+
});
213+
214+
// Log validation results
215+
console.log(` Input Query: ${validationResult.inputQuery.valid ? '' : ''}`);
216+
console.log(` Input Fixture: ${validationResult.inputFixture.valid ? '' : ''}`);
217+
console.log(` Input Query-Fixture Match: ${validationResult.inputQueryFixtureMatch.valid ? '' : ''}`);
218+
console.log(` Output Fixture: ${validationResult.outputFixture.valid ? '' : ''}`);
219+
```
220+
221+
---
60222

61223
#### `buildFunction(functionPath?)`
224+
62225
Builds a Shopify function using the Shopify CLI.
63226

64227
**Parameters:**
65-
- `functionPath` (optional): Path to the function directory. If not provided, will auto-detect from current working directory.
66228

67-
**Returns:** Promise that resolves to build result object with `success`, `output`, and `error` properties.
229+
- `functionPath` (string, optional): Path to the function directory. If not provided, will auto-detect from current working directory.
230+
231+
**Returns:** Promise<BuildFunctionResult> - Build result with `success`, `output`, and `error` properties
232+
233+
**Example:**
234+
235+
```javascript
236+
const buildResult = await buildFunction("/path/to/function");
237+
if (!buildResult.success) {
238+
console.error("Build failed:", buildResult.error);
239+
}
240+
```
241+
242+
---
68243

69244
#### `runFunction(exportName, input, functionPath?)`
245+
70246
Runs a Shopify function using the Shopify CLI.
71247

72248
**Parameters:**
73-
- `exportName`: The export name of the function to run
74-
- `input`: The input data to pass to the function
75-
- `functionPath` (optional): Path to the function directory. If not provided, will auto-detect from current working directory.
76249

77-
**Returns:** Promise that resolves to result object with `result` and `error` properties.
250+
- `exportName` (string): The export name of the function to run
251+
- `input` (object): The input data to pass to the function
252+
- `functionPath` (string, optional): Path to the function directory. If not provided, will auto-detect from current working directory.
253+
254+
**Returns:** Promise<RunFunctionResult> - Result object with:
255+
- `result`: { output: any } | null - The function execution result
256+
- `error`: string | null - Error message if execution failed
257+
258+
**Example:**
259+
260+
```javascript
261+
const runResult = await runFunction("run", fixtureInput, "/path/to/function");
262+
console.log("Function output:", runResult.result.output);
263+
```
264+
265+
**Note:** Both `buildFunction` and `runFunction` will automatically detect the function directory by looking for `shopify.function.toml` in common locations (current directory, src/, functions/, extensions/).
78266

79-
**Note:** Both functions will automatically detect the function directory by looking for `shopify.function.toml` in common locations (current directory, src/, functions/, extensions/). You can also provide a specific path if needed.
267+
---
80268

81269
## Development
82270

@@ -91,6 +279,15 @@ npm run test:watch
91279

92280
# Run tests with coverage
93281
npm run test:coverage
282+
283+
# Run example integration tests
284+
npm run test:examples
285+
```
286+
287+
### Building
288+
289+
```bash
290+
npm run build
94291
```
95292

96293
### Linting
@@ -115,7 +312,3 @@ MIT
115312
4. Add tests for your changes
116313
5. Run the test suite
117314
6. Submit a pull request
118-
119-
## Related
120-
121-
- [Tech Design](https://docs.google.com/document/d/1nmJge_seHPgJlzYgux6S90NEVPcYgn9uqimx9AXP_m8/edit?tab=t.0#heading=h.9zotah988fq7)

0 commit comments

Comments
 (0)