-
-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathweightFunction.test.ts
More file actions
168 lines (149 loc) · 7.79 KB
/
weightFunction.test.ts
File metadata and controls
168 lines (149 loc) · 7.79 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
import 'ts-jest';
import { buildSchema, DocumentNode, parse } from 'graphql';
import { TypeWeightObject } from '../../src/@types/buildTypeWeights.js';
import buildTypeWeightsFromSchema from '../../src/analysis/buildTypeWeights.js';
import QueryParser from '../../src/analysis/QueryParser.js';
// Test the weight function generated by the typeweights object when a limiting keyword is provided
// Test cases:
// Default value provided to schema
// Arg passed in as variable
// Arg passed in as scalar
// Invalid arg type provided
// Default value passed with query
describe('Weight Function correctly parses Argument Nodes if', () => {
const schema = buildSchema(`
type Query {
reviews(episode: Episode!, first: Int = 5): [Review]
heroes(episode: Episode!, first: Int): [Review]
villains(episode: Episode!, limit: Int! = 3): [Review]!
characters(episode: Episode!, limit: Int!): [Review!]
droids(episode: Episode!, limit: Int!): [Review!]!
}
type Review {
episode: Episode
stars: Int!
commentary: String
scalarList(last: Int): [Int]
objectList(first: Int): [Object]
}
type Object {
hi: String
}
enum Episode {
NEWHOPE
EMPIRE
JEDI
}`);
// building the typeWeights object here since we're testing the weight function created in
// the typeWeights object
const typeWeights: TypeWeightObject = buildTypeWeightsFromSchema(schema);
let queryParser: QueryParser;
describe('a default value is provided in the schema', () => {
beforeEach(() => {
queryParser = new QueryParser(typeWeights, {});
});
test('and a value is not provided with the query', () => {
const query = `query { reviews(episode: NEWHOPE) { stars, episode } }`;
const queryAST: DocumentNode = parse(query);
expect(queryParser.processQuery(queryAST)).toBe(6);
});
test('and a scalar value is provided with the query', () => {
const query = `query { reviews(episode: NEWHOPE, first: 3) { stars, episode } }`;
const queryAST: DocumentNode = parse(query);
expect(queryParser.processQuery(queryAST)).toBe(4);
});
test('and the argument is passed in as a variable', () => {
const query = `query variableQuery ($items: Int){ reviews(episode: NEWHOPE, first: $items) { stars, episode } }`;
const queryAST: DocumentNode = parse(query);
queryParser = new QueryParser(typeWeights, { items: 7, first: 4 });
expect(queryParser.processQuery(queryAST)).toBe(8);
queryParser = new QueryParser(typeWeights, { first: 4, items: 7 });
expect(queryParser.processQuery(queryAST)).toBe(8);
});
});
describe('a default value is not provided in the schema', () => {
xtest('and a value is not provied with the query', () => {
const query = `query { heroes(episode: NEWHOPE) { stars, episode } }`;
const queryAST: DocumentNode = parse(query);
// FIXME: Update expected result if unbounded lists are suppored
expect(queryParser.processQuery(queryAST)).toBe(5);
});
test('and a scalar value is provided with the query', () => {
const query = `query { heroes(episode: NEWHOPE, first: 3) { stars, episode } }`;
const queryAST: DocumentNode = parse(query);
expect(queryParser.processQuery(queryAST)).toBe(4);
});
test('and the argument is passed in as a variable', () => {
const query = `query variableQuery ($items: Int){ heroes(episode: NEWHOPE, first: $items) { stars, episode } }`;
const queryAST: DocumentNode = parse(query);
queryParser = new QueryParser(typeWeights, { items: 7 });
expect(queryParser.processQuery(queryAST)).toBe(8);
});
});
test('the list is defined with non-null operators (!)', () => {
const villainsQuery = `query { villains(episode: NEWHOPE, limit: 3) { stars, episode } }`;
const villainsQueryAST: DocumentNode = parse(villainsQuery);
expect(queryParser.processQuery(villainsQueryAST)).toBe(4);
const charQuery = `query { characters(episode: NEWHOPE, limit: 3) { stars, episode } }`;
const charQueryAST: DocumentNode = parse(charQuery);
expect(queryParser.processQuery(charQueryAST)).toBe(4);
const droidsQuery = `query droidsQuery { droids(episode: NEWHOPE, limit: 3) { stars, episode } }`;
const droidsQueryAST: DocumentNode = parse(droidsQuery);
expect(queryParser.processQuery(droidsQueryAST)).toBe(4);
});
test('a custom object weight was configured', () => {
const customTypeWeights: TypeWeightObject = buildTypeWeightsFromSchema(schema, {
object: 3,
});
queryParser = new QueryParser(customTypeWeights, {});
const query = `query { heroes(episode: NEWHOPE, first: 3) { stars, episode } }`;
const queryAST: DocumentNode = parse(query);
expect(queryParser.processQuery(queryAST)).toBe(10);
});
test('a custom object weight was set to 0', () => {
const customTypeWeights: TypeWeightObject = buildTypeWeightsFromSchema(schema, {
object: 0,
});
queryParser = new QueryParser(customTypeWeights, {});
const query = `query { heroes(episode: NEWHOPE, first: 3) { stars, episode } }`;
const queryAST: DocumentNode = parse(query);
expect(queryParser.processQuery(queryAST)).toBe(1); // 1 query
});
test('a custom scalar weight was set to greater than 0', () => {
const customTypeWeights: TypeWeightObject = buildTypeWeightsFromSchema(schema, {
scalar: 2,
});
queryParser = new QueryParser(customTypeWeights, {});
const query = `query { heroes(episode: NEWHOPE, first: 3) { stars, episode } }`;
const queryAST: DocumentNode = parse(query);
expect(queryParser.processQuery(queryAST)).toBe(16);
});
test('variable names matching limiting keywords do not interfere with scalar argument values', () => {
const query = `query variableQuery ($items: Int){ heroes(episode: NEWHOPE, first: 3) { stars, episode } }`;
const queryAST: DocumentNode = parse(query);
queryParser = new QueryParser(typeWeights, { first: 7 });
expect(queryParser.processQuery(queryAST)).toBe(4);
});
test('nested queries with lists', () => {
const query = `query { reviews(episode: NEWHOPE, first: 2) {stars, objectList(first: 3) {hi}}} `;
expect(queryParser.processQuery(parse(query))).toBe(9); // 1 Query + 2 review + (2 * 3 objects)
});
test('queries with inner scalar lists', () => {
const query = `query { reviews(episode: NEWHOPE, first: 2) {stars, scalarList(last: 3) }}`;
expect(queryParser.processQuery(parse(query))).toBe(3); // 1 Query + 2 reviews
});
test('queries with inner scalar lists and custom scalar weight greater than 0', () => {
const customTypeWeights: TypeWeightObject = buildTypeWeightsFromSchema(schema, {
scalar: 2,
});
queryParser = new QueryParser(customTypeWeights, {});
const query = `query { reviews(episode: NEWHOPE, first: 2) {stars, scalarList(last: 3) }}`;
expect(queryParser.processQuery(parse(query))).toBe(19); // 1 Query + 2 reviews + 2 * (2 stars + (3 * 2 scalarList)
});
xtest('an invalid arg type is provided', () => {
const query = `query { heroes(episode: NEWHOPE, first = 3) { stars, episode } }`;
const queryAST: DocumentNode = parse(query);
// FIXME: What is the expected behavior? Treat as unbounded?
fail('test not implemented');
});
});