@quilted/quilt 0.5.154 → 0.5.156
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +71 -0
- package/build/cjs/graphql/testing/matchers/operations.cjs +42 -0
- package/build/cjs/graphql/testing/matchers/utilities.cjs +43 -0
- package/build/cjs/graphql/testing/matchers.cjs +10 -0
- package/build/cjs/graphql/testing.cjs +11 -24
- package/build/cjs/graphql.cjs +10 -32
- package/build/esm/graphql/testing/matchers/operations.mjs +40 -0
- package/build/esm/graphql/testing/matchers/utilities.mjs +40 -0
- package/build/esm/graphql/testing/matchers.mjs +8 -0
- package/build/esm/graphql/testing.mjs +2 -1
- package/build/esm/graphql.mjs +1 -1
- package/build/esnext/graphql/testing/matchers/operations.esnext +40 -0
- package/build/esnext/graphql/testing/matchers/utilities.esnext +40 -0
- package/build/esnext/graphql/testing/matchers.esnext +8 -0
- package/build/esnext/graphql/testing.esnext +2 -1
- package/build/esnext/graphql.esnext +1 -1
- package/build/tsconfig.tsbuildinfo +1 -1
- package/build/typescript/graphql/testing.d.ts +2 -3
- package/build/typescript/graphql/testing.d.ts.map +1 -1
- package/build/typescript/graphql.d.ts +1 -2
- package/build/typescript/graphql.d.ts.map +1 -1
- package/package.json +6 -3
- package/source/graphql/testing/matchers/operations.ts +117 -0
- package/source/graphql/testing/matchers/utilities.ts +68 -0
- package/source/graphql/testing/matchers.ts +31 -0
- package/source/graphql/testing.ts +2 -32
- package/source/graphql.ts +1 -31
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,76 @@
|
|
|
1
1
|
# @quilted/quilt
|
|
2
2
|
|
|
3
|
+
## 0.5.156
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- [`ca9e1de5`](https://github.com/lemonmade/quilt/commit/ca9e1de5ab2723ca7bfae1cf29dd5472a158bacd) Thanks [@lemonmade](https://github.com/lemonmade)! - Fix tree-shaken GraphQL matchers import
|
|
8
|
+
|
|
9
|
+
## 0.5.155
|
|
10
|
+
|
|
11
|
+
### Patch Changes
|
|
12
|
+
|
|
13
|
+
- [`a68e6915`](https://github.com/lemonmade/quilt/commit/a68e691535e0b472883bebc4b4b3671ad885cfd9) Thanks [@lemonmade](https://github.com/lemonmade)! - Add back GraphQL matchers
|
|
14
|
+
|
|
15
|
+
- [`055ffe19`](https://github.com/lemonmade/quilt/commit/055ffe19fdfde694d24f700d8cd8c7636491556a) Thanks [@{id:](https://github.com/{id:), [@{id:](https://github.com/{id:), [@{id:](https://github.com/{id:)! - Simplify `GraphQLFetch` type and separate HTTP options
|
|
16
|
+
|
|
17
|
+
The `GraphQLFetch` and `GraphQLStreamingFetch` types previous had the assumption of an HTTP transport baked into their options. This made it awkward to use in other contexts, like a directly-callable function.
|
|
18
|
+
|
|
19
|
+
To fix this issue, we’ve simplified the `GraphQLFetch` and `GraphQLStreamingFetch` types so that they only accept options universal to all transports: `variables`, for the operation variables, and `signal`, for an optional `AbortSignal` that should cancel the request. The previous HTTP-specific options have been moved to new `GraphQLFetchOverHTTPOptions` and `GraphQLStreamingFetchOverHTTPOptions` types. The `GraphQLFetch` function was also made a little more strict (requiring it to return a `Promise` for a GraphQL result).
|
|
20
|
+
|
|
21
|
+
Additionally, the extendable `GraphQLFetchContext` type has been removed from this library. This type could previously be extended to declare additional context that would be optionally available in a GraphQL fetch function:
|
|
22
|
+
|
|
23
|
+
```ts
|
|
24
|
+
import type {GraphQLFetch} from '@quilted/graphql';
|
|
25
|
+
|
|
26
|
+
// A "module augmentation" that tells TypeScript
|
|
27
|
+
// a `user` field is required
|
|
28
|
+
declare module '@quilted/graphql' {
|
|
29
|
+
interface GraphQLFetchContext {
|
|
30
|
+
string};
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
const fetch: GraphQLFetch = async (operation, {variables}, context) => {
|
|
35
|
+
// `user` is available because of our module augmentation
|
|
36
|
+
const user = context?.user;
|
|
37
|
+
|
|
38
|
+
// ... do something with the user and return a result
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
const result = await fetch('query { message }', {}, {user: {id: '123'}});
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
This type was removed in favor of a new `Context` generic on the `GraphQLFetch` and `GraphQLStreamingFetch` types. These allow you to define the types of any additional context you need for your GraphQL fetcher explicitly, without a module augmentation:
|
|
45
|
+
|
|
46
|
+
```ts
|
|
47
|
+
import type {GraphQLFetch} from '@quilted/graphql';
|
|
48
|
+
|
|
49
|
+
// A "module augmentation" that tells TypeScript
|
|
50
|
+
// a `user` field is required
|
|
51
|
+
declare module '@quilted/graphql' {
|
|
52
|
+
interface GraphQLFetchContext {
|
|
53
|
+
string};
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
const fetch: GraphQLFetch<{
|
|
58
|
+
string};
|
|
59
|
+
}> = async (operation, {variables}, context) => {
|
|
60
|
+
// `user` is available because of our module augmentation
|
|
61
|
+
const user = context?.user;
|
|
62
|
+
|
|
63
|
+
// ... do something with the user and return a result
|
|
64
|
+
};
|
|
65
|
+
|
|
66
|
+
const result = await fetch('query { message }', {}, {user: {id: '123'}});
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
Finally, the `GraphQLVariableOptions` has been simplified. It no longer requires that variables be defined if there are non-nullable variables for the operation. This bit of type safety was very nice, but it was hard to build on top of the `GraphQLVariableOptions` type because of the advanced TypeScript features this type previously used. The new type is a simpler interface that is easy to extend.
|
|
70
|
+
|
|
71
|
+
- Updated dependencies [[`772fd3d1`](https://github.com/lemonmade/quilt/commit/772fd3d1ae845cf990c7b6c1fef0d92669dea660), [`055ffe19`](https://github.com/lemonmade/quilt/commit/055ffe19fdfde694d24f700d8cd8c7636491556a), [`055ffe19`](https://github.com/lemonmade/quilt/commit/055ffe19fdfde694d24f700d8cd8c7636491556a)]:
|
|
72
|
+
- @quilted/graphql@2.0.0
|
|
73
|
+
|
|
3
74
|
## 0.5.154
|
|
4
75
|
|
|
5
76
|
### Patch Changes
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var jestMatcherUtils = require('jest-matcher-utils');
|
|
4
|
+
var ast = require('@quilted/graphql/ast');
|
|
5
|
+
var utilities = require('./utilities.cjs');
|
|
6
|
+
|
|
7
|
+
function toHavePerformedGraphQLOperation(graphql, operation, variables) {
|
|
8
|
+
utilities.assertIsGraphQLController(graphql, {
|
|
9
|
+
expectation: 'toHavePerformedGraphQLOperation',
|
|
10
|
+
isNot: this.isNot
|
|
11
|
+
});
|
|
12
|
+
const foundByOperation = graphql.completed.all({
|
|
13
|
+
operation
|
|
14
|
+
});
|
|
15
|
+
const foundByVariables = variables == null ? foundByOperation : foundByOperation.filter(operation => Object.keys(variables).every(key => this.equals(variables[key], (operation.variables ?? {})[key])));
|
|
16
|
+
const pass = foundByVariables.length > 0;
|
|
17
|
+
const {
|
|
18
|
+
name
|
|
19
|
+
} = ast.normalizeOperation(operation);
|
|
20
|
+
const message = pass ? () => `${jestMatcherUtils.matcherHint('.not.toHavePerformedGraphQLOperation')}\n\n` + `Expected not to have performed GraphQL operation:\n ${jestMatcherUtils.EXPECTED_COLOR(name)}\n${variables ? `With variables matching:\n ${jestMatcherUtils.printExpected(variables)}\n` : ''}` + `But ${foundByVariables.length} matching ${foundByVariables.length === 1 ? 'operation was' : 'operations were'} found.\n` : () => `${`${jestMatcherUtils.matcherHint('.toHavePerformedGraphQLOperation')}\n\n` + `Expected to have performed GraphQL operation:\n ${jestMatcherUtils.EXPECTED_COLOR(name)}\n${variables ? `With variables matching:\n ${jestMatcherUtils.printExpected(variables)}\n` : ''}`}${foundByOperation.length === 0 ? `But no matching operations were found.\n` : `But the ${foundByVariables.length === 1 ? 'found operation has' : 'found operations have'} the following variable differences:\n\n${diffs(foundByVariables, variables, this.expand)}`}`;
|
|
21
|
+
return {
|
|
22
|
+
pass,
|
|
23
|
+
message
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
function diffs(requests, variables, expand) {
|
|
27
|
+
return requests.reduce((diffs, request, index) => `${diffs}${index === 0 ? '' : '\n\n'}${normalizedDiff(request, variables, {
|
|
28
|
+
expand,
|
|
29
|
+
showLegend: index === 0
|
|
30
|
+
})}`, '');
|
|
31
|
+
}
|
|
32
|
+
function normalizedDiff(request, variables, {
|
|
33
|
+
expand = false,
|
|
34
|
+
showLegend = false
|
|
35
|
+
}) {
|
|
36
|
+
const result = utilities.diffVariables(request.variables ?? {}, variables, {
|
|
37
|
+
expand
|
|
38
|
+
}) || '';
|
|
39
|
+
return showLegend ? result : result.split('\n\n')[1];
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
exports.toHavePerformedGraphQLOperation = toHavePerformedGraphQLOperation;
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var jestMatcherUtils = require('jest-matcher-utils');
|
|
4
|
+
var testing = require('@quilted/graphql/testing');
|
|
5
|
+
|
|
6
|
+
function assertIsGraphQLController(graphql, {
|
|
7
|
+
expectation,
|
|
8
|
+
isNot
|
|
9
|
+
}) {
|
|
10
|
+
if (!(graphql instanceof testing.GraphQLController)) {
|
|
11
|
+
throw new Error(jestMatcherUtils.matcherErrorMessage(jestMatcherUtils.matcherHint(`.${expectation}`, undefined, undefined, {
|
|
12
|
+
isNot
|
|
13
|
+
}), `${jestMatcherUtils.RECEIVED_COLOR('received')} value must be a @quilted/graphql/fixtures GraphQLController object`, jestMatcherUtils.printWithType('Received', graphql, jestMatcherUtils.printReceived)));
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
function diffVariables(actual, expected, {
|
|
17
|
+
expand = false
|
|
18
|
+
}) {
|
|
19
|
+
return jestMatcherUtils.diff(expected, getObjectSubset(actual, expected), {
|
|
20
|
+
expand
|
|
21
|
+
});
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
// Original from https://github.com/facebook/jest/blob/master/packages/expect/source/utils.ts#L107
|
|
25
|
+
function getObjectSubset(object, subset) {
|
|
26
|
+
if (Array.isArray(object)) {
|
|
27
|
+
if (Array.isArray(subset) && subset.length === object.length) {
|
|
28
|
+
return subset.map((sub, i) => getObjectSubset(object[i], sub));
|
|
29
|
+
}
|
|
30
|
+
} else if (object instanceof Date) {
|
|
31
|
+
return object;
|
|
32
|
+
} else if (typeof object === 'object' && object !== null && typeof subset === 'object' && subset !== null) {
|
|
33
|
+
const trimmed = {};
|
|
34
|
+
Object.keys(subset).filter(key => Reflect.has(object, key)).forEach(key => trimmed[key] = getObjectSubset(object[key], subset[key]));
|
|
35
|
+
if (Object.keys(trimmed).length > 0) {
|
|
36
|
+
return trimmed;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
return object;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
exports.assertIsGraphQLController = assertIsGraphQLController;
|
|
43
|
+
exports.diffVariables = diffVariables;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var testing = require('@quilted/testing');
|
|
4
|
+
var operations = require('./matchers/operations.cjs');
|
|
5
|
+
|
|
6
|
+
testing.expect.extend({
|
|
7
|
+
toHavePerformedGraphQLOperation: operations.toHavePerformedGraphQLOperation,
|
|
8
|
+
toHavePerformedGraphQLQuery: operations.toHavePerformedGraphQLOperation,
|
|
9
|
+
toHavePerformedGraphQLMutation: operations.toHavePerformedGraphQLOperation
|
|
10
|
+
});
|
|
@@ -1,31 +1,18 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
var testing$1 = require('@quilted/
|
|
3
|
+
require('./testing/matchers.cjs');
|
|
4
|
+
var testing$1 = require('@quilted/graphql/testing');
|
|
5
|
+
var testing = require('@quilted/react-graphql/testing');
|
|
5
6
|
|
|
6
7
|
|
|
7
8
|
|
|
8
|
-
Object.defineProperty(exports, 'GraphQLController', {
|
|
9
|
-
enumerable: true,
|
|
10
|
-
get: function () { return testing.GraphQLController; }
|
|
11
|
-
});
|
|
12
|
-
Object.defineProperty(exports, 'createGraphQLFiller', {
|
|
13
|
-
enumerable: true,
|
|
14
|
-
get: function () { return testing.createGraphQLFiller; }
|
|
15
|
-
});
|
|
16
|
-
Object.defineProperty(exports, 'createGraphQLSchema', {
|
|
17
|
-
enumerable: true,
|
|
18
|
-
get: function () { return testing.createGraphQLSchema; }
|
|
19
|
-
});
|
|
20
|
-
Object.defineProperty(exports, 'gql', {
|
|
21
|
-
enumerable: true,
|
|
22
|
-
get: function () { return testing.gql; }
|
|
23
|
-
});
|
|
24
|
-
Object.defineProperty(exports, 'graphql', {
|
|
25
|
-
enumerable: true,
|
|
26
|
-
get: function () { return testing.graphql; }
|
|
27
|
-
});
|
|
28
9
|
Object.defineProperty(exports, 'GraphQLTesting', {
|
|
29
|
-
|
|
30
|
-
|
|
10
|
+
enumerable: true,
|
|
11
|
+
get: function () { return testing.GraphQLTesting; }
|
|
12
|
+
});
|
|
13
|
+
Object.keys(testing$1).forEach(function (k) {
|
|
14
|
+
if (k !== 'default' && !Object.prototype.hasOwnProperty.call(exports, k)) Object.defineProperty(exports, k, {
|
|
15
|
+
enumerable: true,
|
|
16
|
+
get: function () { return testing$1[k]; }
|
|
17
|
+
});
|
|
31
18
|
});
|
package/build/cjs/graphql.cjs
CHANGED
|
@@ -5,39 +5,17 @@ var reactGraphql = require('@quilted/react-graphql');
|
|
|
5
5
|
|
|
6
6
|
|
|
7
7
|
|
|
8
|
-
Object.defineProperty(exports, 'GraphQLFetchRequest', {
|
|
9
|
-
enumerable: true,
|
|
10
|
-
get: function () { return graphql.GraphQLFetchRequest; }
|
|
11
|
-
});
|
|
12
|
-
Object.defineProperty(exports, 'createGraphQLHttpFetch', {
|
|
13
|
-
enumerable: true,
|
|
14
|
-
get: function () { return graphql.createGraphQLHttpFetch; }
|
|
15
|
-
});
|
|
16
|
-
Object.defineProperty(exports, 'createGraphQLHttpStreamingFetch', {
|
|
17
|
-
enumerable: true,
|
|
18
|
-
get: function () { return graphql.createGraphQLHttpStreamingFetch; }
|
|
19
|
-
});
|
|
20
|
-
Object.defineProperty(exports, 'gql', {
|
|
21
|
-
enumerable: true,
|
|
22
|
-
get: function () { return graphql.gql; }
|
|
23
|
-
});
|
|
24
|
-
Object.defineProperty(exports, 'graphql', {
|
|
25
|
-
enumerable: true,
|
|
26
|
-
get: function () { return graphql.graphql; }
|
|
27
|
-
});
|
|
28
|
-
Object.defineProperty(exports, 'toGraphQLOperation', {
|
|
29
|
-
enumerable: true,
|
|
30
|
-
get: function () { return graphql.toGraphQLOperation; }
|
|
31
|
-
});
|
|
32
|
-
Object.defineProperty(exports, 'toGraphQLSource', {
|
|
33
|
-
enumerable: true,
|
|
34
|
-
get: function () { return graphql.toGraphQLSource; }
|
|
35
|
-
});
|
|
36
8
|
Object.defineProperty(exports, 'GraphQLContext', {
|
|
37
|
-
|
|
38
|
-
|
|
9
|
+
enumerable: true,
|
|
10
|
+
get: function () { return reactGraphql.GraphQLContext; }
|
|
39
11
|
});
|
|
40
12
|
Object.defineProperty(exports, 'useGraphQLFetch', {
|
|
41
|
-
|
|
42
|
-
|
|
13
|
+
enumerable: true,
|
|
14
|
+
get: function () { return reactGraphql.useGraphQLFetch; }
|
|
15
|
+
});
|
|
16
|
+
Object.keys(graphql).forEach(function (k) {
|
|
17
|
+
if (k !== 'default' && !Object.prototype.hasOwnProperty.call(exports, k)) Object.defineProperty(exports, k, {
|
|
18
|
+
enumerable: true,
|
|
19
|
+
get: function () { return graphql[k]; }
|
|
20
|
+
});
|
|
43
21
|
});
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { matcherHint, EXPECTED_COLOR, printExpected } from 'jest-matcher-utils';
|
|
2
|
+
import { normalizeOperation } from '@quilted/graphql/ast';
|
|
3
|
+
import { assertIsGraphQLController, diffVariables } from './utilities.mjs';
|
|
4
|
+
|
|
5
|
+
function toHavePerformedGraphQLOperation(graphql, operation, variables) {
|
|
6
|
+
assertIsGraphQLController(graphql, {
|
|
7
|
+
expectation: 'toHavePerformedGraphQLOperation',
|
|
8
|
+
isNot: this.isNot
|
|
9
|
+
});
|
|
10
|
+
const foundByOperation = graphql.completed.all({
|
|
11
|
+
operation
|
|
12
|
+
});
|
|
13
|
+
const foundByVariables = variables == null ? foundByOperation : foundByOperation.filter(operation => Object.keys(variables).every(key => this.equals(variables[key], (operation.variables ?? {})[key])));
|
|
14
|
+
const pass = foundByVariables.length > 0;
|
|
15
|
+
const {
|
|
16
|
+
name
|
|
17
|
+
} = normalizeOperation(operation);
|
|
18
|
+
const message = pass ? () => `${matcherHint('.not.toHavePerformedGraphQLOperation')}\n\n` + `Expected not to have performed GraphQL operation:\n ${EXPECTED_COLOR(name)}\n${variables ? `With variables matching:\n ${printExpected(variables)}\n` : ''}` + `But ${foundByVariables.length} matching ${foundByVariables.length === 1 ? 'operation was' : 'operations were'} found.\n` : () => `${`${matcherHint('.toHavePerformedGraphQLOperation')}\n\n` + `Expected to have performed GraphQL operation:\n ${EXPECTED_COLOR(name)}\n${variables ? `With variables matching:\n ${printExpected(variables)}\n` : ''}`}${foundByOperation.length === 0 ? `But no matching operations were found.\n` : `But the ${foundByVariables.length === 1 ? 'found operation has' : 'found operations have'} the following variable differences:\n\n${diffs(foundByVariables, variables, this.expand)}`}`;
|
|
19
|
+
return {
|
|
20
|
+
pass,
|
|
21
|
+
message
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
function diffs(requests, variables, expand) {
|
|
25
|
+
return requests.reduce((diffs, request, index) => `${diffs}${index === 0 ? '' : '\n\n'}${normalizedDiff(request, variables, {
|
|
26
|
+
expand,
|
|
27
|
+
showLegend: index === 0
|
|
28
|
+
})}`, '');
|
|
29
|
+
}
|
|
30
|
+
function normalizedDiff(request, variables, {
|
|
31
|
+
expand = false,
|
|
32
|
+
showLegend = false
|
|
33
|
+
}) {
|
|
34
|
+
const result = diffVariables(request.variables ?? {}, variables, {
|
|
35
|
+
expand
|
|
36
|
+
}) || '';
|
|
37
|
+
return showLegend ? result : result.split('\n\n')[1];
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export { toHavePerformedGraphQLOperation };
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { matcherErrorMessage, matcherHint, RECEIVED_COLOR, printWithType, printReceived, diff } from 'jest-matcher-utils';
|
|
2
|
+
import { GraphQLController } from '@quilted/graphql/testing';
|
|
3
|
+
|
|
4
|
+
function assertIsGraphQLController(graphql, {
|
|
5
|
+
expectation,
|
|
6
|
+
isNot
|
|
7
|
+
}) {
|
|
8
|
+
if (!(graphql instanceof GraphQLController)) {
|
|
9
|
+
throw new Error(matcherErrorMessage(matcherHint(`.${expectation}`, undefined, undefined, {
|
|
10
|
+
isNot
|
|
11
|
+
}), `${RECEIVED_COLOR('received')} value must be a @quilted/graphql/fixtures GraphQLController object`, printWithType('Received', graphql, printReceived)));
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
function diffVariables(actual, expected, {
|
|
15
|
+
expand = false
|
|
16
|
+
}) {
|
|
17
|
+
return diff(expected, getObjectSubset(actual, expected), {
|
|
18
|
+
expand
|
|
19
|
+
});
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
// Original from https://github.com/facebook/jest/blob/master/packages/expect/source/utils.ts#L107
|
|
23
|
+
function getObjectSubset(object, subset) {
|
|
24
|
+
if (Array.isArray(object)) {
|
|
25
|
+
if (Array.isArray(subset) && subset.length === object.length) {
|
|
26
|
+
return subset.map((sub, i) => getObjectSubset(object[i], sub));
|
|
27
|
+
}
|
|
28
|
+
} else if (object instanceof Date) {
|
|
29
|
+
return object;
|
|
30
|
+
} else if (typeof object === 'object' && object !== null && typeof subset === 'object' && subset !== null) {
|
|
31
|
+
const trimmed = {};
|
|
32
|
+
Object.keys(subset).filter(key => Reflect.has(object, key)).forEach(key => trimmed[key] = getObjectSubset(object[key], subset[key]));
|
|
33
|
+
if (Object.keys(trimmed).length > 0) {
|
|
34
|
+
return trimmed;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
return object;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export { assertIsGraphQLController, diffVariables };
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { expect } from '@quilted/testing';
|
|
2
|
+
import { toHavePerformedGraphQLOperation } from './matchers/operations.mjs';
|
|
3
|
+
|
|
4
|
+
expect.extend({
|
|
5
|
+
toHavePerformedGraphQLOperation,
|
|
6
|
+
toHavePerformedGraphQLQuery: toHavePerformedGraphQLOperation,
|
|
7
|
+
toHavePerformedGraphQLMutation: toHavePerformedGraphQLOperation
|
|
8
|
+
});
|
package/build/esm/graphql.mjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export
|
|
1
|
+
export * from '@quilted/graphql';
|
|
2
2
|
export { GraphQLContext, useGraphQLFetch } from '@quilted/react-graphql';
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { matcherHint, EXPECTED_COLOR, printExpected } from 'jest-matcher-utils';
|
|
2
|
+
import { normalizeOperation } from '@quilted/graphql/ast';
|
|
3
|
+
import { assertIsGraphQLController, diffVariables } from './utilities.esnext';
|
|
4
|
+
|
|
5
|
+
function toHavePerformedGraphQLOperation(graphql, operation, variables) {
|
|
6
|
+
assertIsGraphQLController(graphql, {
|
|
7
|
+
expectation: 'toHavePerformedGraphQLOperation',
|
|
8
|
+
isNot: this.isNot
|
|
9
|
+
});
|
|
10
|
+
const foundByOperation = graphql.completed.all({
|
|
11
|
+
operation
|
|
12
|
+
});
|
|
13
|
+
const foundByVariables = variables == null ? foundByOperation : foundByOperation.filter(operation => Object.keys(variables).every(key => this.equals(variables[key], (operation.variables ?? {})[key])));
|
|
14
|
+
const pass = foundByVariables.length > 0;
|
|
15
|
+
const {
|
|
16
|
+
name
|
|
17
|
+
} = normalizeOperation(operation);
|
|
18
|
+
const message = pass ? () => `${matcherHint('.not.toHavePerformedGraphQLOperation')}\n\n` + `Expected not to have performed GraphQL operation:\n ${EXPECTED_COLOR(name)}\n${variables ? `With variables matching:\n ${printExpected(variables)}\n` : ''}` + `But ${foundByVariables.length} matching ${foundByVariables.length === 1 ? 'operation was' : 'operations were'} found.\n` : () => `${`${matcherHint('.toHavePerformedGraphQLOperation')}\n\n` + `Expected to have performed GraphQL operation:\n ${EXPECTED_COLOR(name)}\n${variables ? `With variables matching:\n ${printExpected(variables)}\n` : ''}`}${foundByOperation.length === 0 ? `But no matching operations were found.\n` : `But the ${foundByVariables.length === 1 ? 'found operation has' : 'found operations have'} the following variable differences:\n\n${diffs(foundByVariables, variables, this.expand)}`}`;
|
|
19
|
+
return {
|
|
20
|
+
pass,
|
|
21
|
+
message
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
function diffs(requests, variables, expand) {
|
|
25
|
+
return requests.reduce((diffs, request, index) => `${diffs}${index === 0 ? '' : '\n\n'}${normalizedDiff(request, variables, {
|
|
26
|
+
expand,
|
|
27
|
+
showLegend: index === 0
|
|
28
|
+
})}`, '');
|
|
29
|
+
}
|
|
30
|
+
function normalizedDiff(request, variables, {
|
|
31
|
+
expand = false,
|
|
32
|
+
showLegend = false
|
|
33
|
+
}) {
|
|
34
|
+
const result = diffVariables(request.variables ?? {}, variables, {
|
|
35
|
+
expand
|
|
36
|
+
}) || '';
|
|
37
|
+
return showLegend ? result : result.split('\n\n')[1];
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export { toHavePerformedGraphQLOperation };
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { matcherErrorMessage, matcherHint, RECEIVED_COLOR, printWithType, printReceived, diff } from 'jest-matcher-utils';
|
|
2
|
+
import { GraphQLController } from '@quilted/graphql/testing';
|
|
3
|
+
|
|
4
|
+
function assertIsGraphQLController(graphql, {
|
|
5
|
+
expectation,
|
|
6
|
+
isNot
|
|
7
|
+
}) {
|
|
8
|
+
if (!(graphql instanceof GraphQLController)) {
|
|
9
|
+
throw new Error(matcherErrorMessage(matcherHint(`.${expectation}`, undefined, undefined, {
|
|
10
|
+
isNot
|
|
11
|
+
}), `${RECEIVED_COLOR('received')} value must be a @quilted/graphql/fixtures GraphQLController object`, printWithType('Received', graphql, printReceived)));
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
function diffVariables(actual, expected, {
|
|
15
|
+
expand = false
|
|
16
|
+
}) {
|
|
17
|
+
return diff(expected, getObjectSubset(actual, expected), {
|
|
18
|
+
expand
|
|
19
|
+
});
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
// Original from https://github.com/facebook/jest/blob/master/packages/expect/source/utils.ts#L107
|
|
23
|
+
function getObjectSubset(object, subset) {
|
|
24
|
+
if (Array.isArray(object)) {
|
|
25
|
+
if (Array.isArray(subset) && subset.length === object.length) {
|
|
26
|
+
return subset.map((sub, i) => getObjectSubset(object[i], sub));
|
|
27
|
+
}
|
|
28
|
+
} else if (object instanceof Date) {
|
|
29
|
+
return object;
|
|
30
|
+
} else if (typeof object === 'object' && object !== null && typeof subset === 'object' && subset !== null) {
|
|
31
|
+
const trimmed = {};
|
|
32
|
+
Object.keys(subset).filter(key => Reflect.has(object, key)).forEach(key => trimmed[key] = getObjectSubset(object[key], subset[key]));
|
|
33
|
+
if (Object.keys(trimmed).length > 0) {
|
|
34
|
+
return trimmed;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
return object;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export { assertIsGraphQLController, diffVariables };
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { expect } from '@quilted/testing';
|
|
2
|
+
import { toHavePerformedGraphQLOperation } from './matchers/operations.esnext';
|
|
3
|
+
|
|
4
|
+
expect.extend({
|
|
5
|
+
toHavePerformedGraphQLOperation,
|
|
6
|
+
toHavePerformedGraphQLQuery: toHavePerformedGraphQLOperation,
|
|
7
|
+
toHavePerformedGraphQLMutation: toHavePerformedGraphQLOperation
|
|
8
|
+
});
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export
|
|
1
|
+
export * from '@quilted/graphql';
|
|
2
2
|
export { GraphQLContext, useGraphQLFetch } from '@quilted/react-graphql';
|