Skip to content

Commit 531895f

Browse files
authored
Merge pull request #21 from Shopify/lopert.update-readme
refresh the readme with recent changes
2 parents 03173f2 + 7cb881b commit 531895f

File tree

4 files changed

+136
-73
lines changed

4 files changed

+136
-73
lines changed

README.md

Lines changed: 120 additions & 59 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,126 @@ npm install @shopify/shopify-function-test-helpers
1313
### Basic Usage
1414

1515
```javascript
16-
const {
17-
loadFixture,
18-
validateFixture,
16+
import {
1917
buildFunction,
20-
runFunction
21-
} = require('@shopify/shopify-function-test-helpers');
22-
23-
// Load a fixture from test data
24-
const fixture = loadFixture('20250915_184036_156Z_extensions_cart-checkout-validation_ba711d.json');
25-
26-
// Validate the fixture structure
27-
const validation = validateFixture(fixture);
28-
console.log('Is valid:', validation.isValid);
18+
loadFixture,
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+
```
2957

30-
// Build a function
31-
const payload = buildFunction();
58+
### Complete Test Example
3259

33-
// Run a function implementation
60+
For a full test suite that runs multiple fixtures:
3461

35-
const result = runFunction(payload, mockFunction);
36-
console.log('Result status:', result.status);
62+
```javascript
63+
import path from "path";
64+
import fs from "fs";
65+
import {
66+
buildFunction,
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+
}, 20000);
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+
});
37122
```
38123

39124
## API Reference
40125

41-
### Functions
42-
43-
#### `loadFixture(filename)`
44-
Loads a fixture from the test_data directory.
45-
46-
**Parameters:**
47-
- `filename`: Name of the fixture file
48-
49-
**Returns:** Fixture object
50-
51-
**Throws:** Error if fixture file is not found
52-
53-
#### `validateFixture(fixture)`
54-
Validates a fixture to ensure it has the correct structure.
55-
56-
**Parameters:**
57-
- `fixture`: The fixture data to validate
126+
### Core Functions
58127

59-
**Returns:** ValidationResult object with `isValid` boolean and `errors` array
128+
- [`loadFixture`](./src/methods/load-fixture.ts) - Load a fixture file from the specified path
129+
- [`loadSchema`](./src/methods/load-schema.ts) - Load a GraphQL schema from a file
130+
- [`loadInputQuery`](./src/methods/load-input-query.ts) - Load and parse a GraphQL input query
131+
- [`validateTestAssets`](./src/methods/validate-test-assets.ts) - Validate test assets including input query, fixture input/output, and query-fixture match
132+
- [`buildFunction`](./src/methods/build-function.ts) - Build a Shopify function using the Shopify CLI
133+
- [`runFunction`](./src/methods/run-function.ts) - Run a Shopify function using the Shopify CLI
60134

61-
#### `buildFunction(functionPath?)`
62-
Builds a Shopify function using the Shopify CLI.
63-
64-
**Parameters:**
65-
- `functionPath` (optional): Path to the function directory. If not provided, will auto-detect from current working directory.
66-
67-
**Returns:** Promise that resolves to build result object with `success`, `output`, and `error` properties.
68-
69-
#### `runFunction(exportName, input, functionPath?)`
70-
Runs a Shopify function using the Shopify CLI.
71-
72-
**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.
76-
77-
**Returns:** Promise that resolves to result object with `result` and `error` properties.
78-
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.
135+
See [wasm-testing-helpers.ts](./src/wasm-testing-helpers.ts) for all exported types.
80136

81137
## Development
82138

@@ -91,6 +147,15 @@ npm run test:watch
91147

92148
# Run tests with coverage
93149
npm run test:coverage
150+
151+
# Run example integration tests
152+
npm run test:examples
153+
```
154+
155+
### Building
156+
157+
```bash
158+
npm run build
94159
```
95160

96161
### Linting
@@ -115,7 +180,3 @@ MIT
115180
4. Add tests for your changes
116181
5. Run the test suite
117182
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)

test-app/extensions/cart-validation-js/tests/default.test.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ describe("Default Integration Test", () => {
2626

2727
schema = await loadSchema(schemaPath);
2828
inputQueryAST = await loadInputQuery(inputQueryPath);
29-
}, 10000); // 10 second timeout for building the function
29+
}, 20000); // 20 second timeout for building the function
3030

3131
const fixturesDir = path.join(__dirname, "fixtures");
3232
const fixtureFiles = fs

test-app/extensions/discount-function/tests/default.test.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ describe("Default Integration Test", () => {
2626

2727
schema = await loadSchema(schemaPath);
2828
inputQueryAST = await loadInputQuery(inputQueryPath);
29-
}, 10000); // 10 second timeout for building the function
29+
}, 20000); // 20 second timeout for building the function
3030

3131
const fixturesDir = path.join(__dirname, "fixtures");
3232
const fixtureFiles = fs
Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,15 @@
1-
import { describe, it, expect } from 'vitest';
2-
import { buildFunction } from '../../src/methods/build-function.ts';
1+
import { describe, it, expect } from "vitest";
2+
import { buildFunction } from "../../src/methods/build-function.ts";
33

4-
describe('buildFunction', () => {
5-
it('should build a function using Shopify CLI', async () => {
6-
const result = await buildFunction('test-app/extensions/cart-validation-js');
7-
8-
expect(result).toBeDefined();
9-
expect(result).toHaveProperty('success');
10-
expect(result).toHaveProperty('output');
11-
expect(result).toHaveProperty('error');
12-
}, 10000); // 10 second timeout for build operations
13-
});
4+
describe("buildFunction", () => {
5+
it("should build a function using Shopify CLI", async () => {
6+
const result = await buildFunction(
7+
"test-app/extensions/cart-validation-js"
8+
);
9+
10+
expect(result).toBeDefined();
11+
expect(result).toHaveProperty("success");
12+
expect(result).toHaveProperty("output");
13+
expect(result).toHaveProperty("error");
14+
}, 20000); // 10 second timeout for build operations
15+
});

0 commit comments

Comments
 (0)