Skip to content

Commit 3786a27

Browse files
author
mattia rossi
committed
Add exported schema test functionality, fix standard tests by removing some EXPORTABLE calls
1 parent 7319096 commit 3786a27

4 files changed

Lines changed: 162 additions & 193 deletions

File tree

__tests__/integration/queries.test.ts

Lines changed: 127 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
import * as fs from "fs";
22
import * as path from "path";
33
import * as pg from "pg";
4+
//import * as vm from "node:vm";
5+
46
import { promisify } from "util";
5-
import { ExecutionArgs, parse, validate } from "graphql";
7+
import { ExecutionArgs, GraphQLSchema, parse, validate } from "graphql";
68
import { withPgClient, withPgPool } from "../helpers";
79
import { PgConditionArgumentPlugin } from "graphile-build-pg";
810
import { postgraphilePresetAmber } from "postgraphile/presets/amber";
@@ -13,9 +15,49 @@ import CustomOperatorsPlugin from "./../customOperatorsPlugin";
1315
import { execute, hookArgs } from "grafast";
1416
import { SchemaResult } from "graphile-build";
1517
import { makeWithPgClientViaPgClientAlreadyInTransaction } from "@dataplan/pg/adaptors/pg";
18+
import { exportSchemaAsString } from "graphile-export";
19+
import _module = require("module");
20+
import { dirname } from "path";
21+
const { Module, builtinModules } = _module;
22+
import { transformSync } from "@babel/core";
1623

1724
// TODO: remove this once Grafast gets it's planning under control :D
18-
jest.setTimeout(30000);
25+
jest.setTimeout(3000000);
26+
/*
27+
const vmEval = (code: string) => {
28+
const context = {} as GraphQLSchema;
29+
// Load the module with the dyanamic script.
30+
vm.runInNewContext(code, vm.createContext(context));
31+
console.log("Returning context: ", JSON.stringify(context, null, 2));
32+
return context;
33+
};
34+
*/
35+
let cachedSchema = {} as GraphQLSchema;
36+
let haveCache = false;
37+
const vmEval = (code: string) => {
38+
if (!haveCache) {
39+
const filename = "exported-v5-schema.mjs";
40+
// Load the module with the dyanamic script.
41+
const replacementModule = new Module(filename, this);
42+
replacementModule.filename = filename;
43+
// @ts-ignore
44+
replacementModule.paths = Module._nodeModulePaths(dirname(filename));
45+
const commonJScode = transformSync(code, {
46+
filename,
47+
compact: true,
48+
plugins: ["@babel/plugin-transform-runtime"],
49+
});
50+
// @ts-ignore
51+
replacementModule._compile(commonJScode.code, filename);
52+
replacementModule.loaded = true;
53+
cachedSchema = replacementModule.exports.schema as GraphQLSchema;
54+
haveCache = true;
55+
console.log("Schema import done - no cache");
56+
} else {
57+
console.log("Schema import done - from cache");
58+
}
59+
return cachedSchema;
60+
};
1961

2062
const createPostGraphileSchema = async (
2163
pool: pg.Pool,
@@ -44,7 +86,23 @@ const createPostGraphileSchema = async (
4486
],
4587
};
4688
const params = await makeSchema(preset);
47-
return params;
89+
if (process.env.TEST_EXPORTED_SCHEMA) {
90+
return {
91+
...params,
92+
schema: vmEval(
93+
(
94+
await exportSchemaAsString(params.schema, {
95+
mode: "graphql-js",
96+
// or:
97+
// mode: "typeDefs",
98+
modules: {},
99+
})
100+
).code
101+
),
102+
};
103+
} else {
104+
return params;
105+
}
48106
};
49107

50108
const readFile = promisify(fs.readFile);
@@ -146,67 +204,73 @@ beforeAll(async () => {
146204

147205
for (const queryFileName of queryFileNames) {
148206
// eslint-disable-next-line jest/valid-title
149-
test(queryFileName, async () => {
150-
// Read the query from the file system.
151-
const query = await readFile(
152-
path.resolve(queriesDir, queryFileName),
153-
"utf8"
154-
);
155-
// Get the appropriate GraphQL schema for this fixture. We want to test
156-
// some specific fixtures against a schema configured slightly
157-
// differently.
158-
const gqlSchemaByQueryFileName: {
159-
[queryFileName: string]: SchemaResult;
160-
} = {
161-
"addConnectionFilterOperator.graphql":
162-
gqlSchemas.addConnectionFilterOperator,
163-
"dynamicJsonTrue.graphql": gqlSchemas.dynamicJson,
164-
"types.cidr.graphql": gqlSchemas.networkScalars,
165-
"types.macaddr.graphql": gqlSchemas.networkScalars,
166-
"arrayTypes.cidrArray.graphql": gqlSchemas.networkScalars,
167-
"arrayTypes.macaddrArray.graphql": gqlSchemas.networkScalars,
168-
"relations.graphql": gqlSchemas.relations,
169-
"simpleCollections.graphql": gqlSchemas.simpleCollections,
170-
"nullAndEmptyAllowed.graphql": gqlSchemas.nullAndEmptyAllowed,
171-
};
172-
const { schema, resolvedPreset } =
173-
queryFileName in gqlSchemaByQueryFileName
174-
? gqlSchemaByQueryFileName[queryFileName]
175-
: gqlSchemas.normal;
176-
177-
const document = parse(query);
178-
const errors = validate(schema, document);
179-
if (errors.length > 0) {
180-
throw new Error(
181-
`GraphQL validation errors:\n${errors.map((e) => e.message).join("\n")}`
207+
test(
208+
queryFileName,
209+
async () => {
210+
// Read the query from the file system.
211+
const query = await readFile(
212+
path.resolve(queriesDir, queryFileName),
213+
"utf8"
182214
);
183-
}
184-
const args: ExecutionArgs = {
185-
schema,
186-
document,
187-
};
188-
await hookArgs(args, resolvedPreset, {});
189-
//const pgSubscriber = new PgSubscriber(pool);
190-
const result = (await withPgClient(async (pgClient) => {
191-
// We must override the context because we didn't use a pool above and so
192-
// we need to add our own client
193-
194-
// NOTE: the withPgClient needed on context is **VERY DIFFERENT** to our
195-
// withPgClient test helper. We should rename our test helper ;)
196-
const contextWithPgClient =
197-
makeWithPgClientViaPgClientAlreadyInTransaction(pgClient, false);
198-
try {
199-
args.contextValue = {
200-
pgSettings: (args.contextValue as any).pgSettings,
201-
withPgClient: contextWithPgClient,
202-
//pgSubscriber,
203-
};
215+
// Get the appropriate GraphQL schema for this fixture. We want to test
216+
// some specific fixtures against a schema configured slightly
217+
// differently.
218+
const gqlSchemaByQueryFileName: {
219+
[queryFileName: string]: SchemaResult;
220+
} = {
221+
"addConnectionFilterOperator.graphql":
222+
gqlSchemas.addConnectionFilterOperator,
223+
"dynamicJsonTrue.graphql": gqlSchemas.dynamicJson,
224+
"types.cidr.graphql": gqlSchemas.networkScalars,
225+
"types.macaddr.graphql": gqlSchemas.networkScalars,
226+
"arrayTypes.cidrArray.graphql": gqlSchemas.networkScalars,
227+
"arrayTypes.macaddrArray.graphql": gqlSchemas.networkScalars,
228+
"relations.graphql": gqlSchemas.relations,
229+
"simpleCollections.graphql": gqlSchemas.simpleCollections,
230+
"nullAndEmptyAllowed.graphql": gqlSchemas.nullAndEmptyAllowed,
231+
};
232+
const { schema, resolvedPreset } =
233+
queryFileName in gqlSchemaByQueryFileName
234+
? gqlSchemaByQueryFileName[queryFileName]
235+
: gqlSchemas.normal;
204236

205-
return (await execute(args)) as any;
206-
} finally {
207-
contextWithPgClient.release?.();
237+
const document = parse(query);
238+
const errors = validate(schema, document);
239+
if (errors.length > 0) {
240+
throw new Error(
241+
`GraphQL validation errors:\n${errors
242+
.map((e) => e.message)
243+
.join("\n")}`
244+
);
208245
}
209-
})) as any;
210-
expect(result).toMatchSnapshot();
211-
});
246+
const args: ExecutionArgs = {
247+
schema,
248+
document,
249+
};
250+
await hookArgs(args, resolvedPreset, {});
251+
//const pgSubscriber = new PgSubscriber(pool);
252+
const result = (await withPgClient(async (pgClient) => {
253+
// We must override the context because we didn't use a pool above and so
254+
// we need to add our own client
255+
256+
// NOTE: the withPgClient needed on context is **VERY DIFFERENT** to our
257+
// withPgClient test helper. We should rename our test helper ;)
258+
const contextWithPgClient =
259+
makeWithPgClientViaPgClientAlreadyInTransaction(pgClient, false);
260+
try {
261+
args.contextValue = {
262+
pgSettings: (args.contextValue as any).pgSettings,
263+
withPgClient: contextWithPgClient,
264+
//pgSubscriber,
265+
};
266+
267+
return (await execute(args)) as any;
268+
} finally {
269+
contextWithPgClient.release?.();
270+
}
271+
})) as any;
272+
expect(result).toMatchSnapshot();
273+
},
274+
100000000
275+
);
212276
}

package.json

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,7 @@
3131
},
3232
"devDependencies": {
3333
"@babel/eslint-parser": "^7.22.11",
34-
"@babel/plugin-transform-modules-commonjs": "^7.22.11",
35-
"@babel/plugin-transform-runtime": "^7.22.10",
34+
"@babel/plugin-transform-runtime": "^7.23.3",
3635
"@babel/preset-env": "^7.22.14",
3736
"@babel/preset-typescript": "^7.22.11",
3837
"@dataplan/pg": "^0.0.1-beta.1",

0 commit comments

Comments
 (0)