Skip to content

Commit 4d5ad79

Browse files
committed
added tests and functionality complete
1 parent a189620 commit 4d5ad79

File tree

3 files changed

+80
-28
lines changed

3 files changed

+80
-28
lines changed

src/analysis/buildTypeWeights.ts

Lines changed: 23 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,29 @@ function parseObjectFields(
113113
resolveTo: listType.toString().toLocaleLowerCase(),
114114
};
115115
} else {
116+
// if the @listCost directive is given for the field,
117+
// apply the cost argument's value to the field's weight
118+
const directives = fields[field].astNode?.directives;
119+
120+
if (directives && directives.length > 0) {
121+
// eslint-disable-next-line consistent-return
122+
directives.forEach((dir) => {
123+
if (dir.name.value === 'listCost') {
124+
if (dir.arguments && dir.arguments[0])
125+
result.fields[field] = {
126+
resolveTo: listType.toString().toLocaleLowerCase(),
127+
weight: Number(
128+
// ts-error: 'value does not exist on type ConstValueNode'
129+
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
130+
// @ts-ignore
131+
dir.arguments[0].value.value
132+
),
133+
};
134+
}
135+
});
136+
}
137+
138+
// if no directive is supplied to list field
116139
fields[field].args.forEach((arg: GraphQLArgument) => {
117140
// If field has an argument matching one of the limiting keywords and resolves to a list
118141
// then the weight of the field should be dependent on both the weight of the
@@ -148,25 +171,6 @@ function parseObjectFields(
148171
// ? what else can get through here
149172
}
150173

151-
// if the @listCost directive is given for the field,
152-
// apply the cost argument's value to the field's weight
153-
const directives = fields[field].astNode?.directives;
154-
if (directives && directives.length > 0) {
155-
// eslint-disable-next-line consistent-return
156-
directives.forEach((dir) => {
157-
if (dir.name.value === 'listCost') {
158-
if (dir.arguments && dir.arguments[0])
159-
return {
160-
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
161-
// @ts-ignore
162-
// ignoring for the time being,
163-
// 'value does not exist on type ConstValueNode'
164-
weight: Number(dir.arguments[0].value.value),
165-
};
166-
}
167-
});
168-
}
169-
170174
// if there is no argument provided with the query, check the schema for a default
171175
if (arg.defaultValue) {
172176
return Number(arg.defaultValue) * (selectionsCost + weight);

test/analysis/buildTypeWeights.test.ts

Lines changed: 55 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -388,14 +388,39 @@ describe('Test buildTypeWeightsFromSchema function', () => {
388388
});
389389
});
390390

391-
// FIXME: need to figure out how to handle this situation. Skip for now.
391+
// the field 'humans' on Query returns an unbounded list
392+
test('query definitions returning lists of indeterminate size', () => {
393+
schema = buildSchema(`
394+
directive @listCost(cost: Int!) on FIELD_DEFINITION
395+
type Human {
396+
id: ID!
397+
}
398+
type Query {
399+
humans: [Human] @listCost(cost: 10)
400+
}
401+
`);
402+
expect(buildTypeWeightsFromSchema(schema)).toEqual({
403+
human: {
404+
weight: 1,
405+
fields: {
406+
id: { weight: 0 },
407+
},
408+
},
409+
query: {
410+
weight: 1,
411+
fields: {
412+
humans: { weight: 10, resolveTo: 'human' },
413+
},
414+
},
415+
});
416+
});
417+
392418
// The field 'friends' returns a list of an unknown number of objects.
393-
xtest('fields returning lists of objects of indeterminate size', () => {
419+
test('fields returning lists of objects of indeterminate size', () => {
394420
schema = buildSchema(`
421+
directive @listCost(cost: Int!) on FIELD_DEFINITION
395422
type Human {
396423
id: ID!
397-
name: String!
398-
homePlanet: String
399424
friends: [Human] @listCost(cost: 10)
400425
}
401426
`);
@@ -404,10 +429,33 @@ describe('Test buildTypeWeightsFromSchema function', () => {
404429
weight: 1,
405430
fields: {
406431
id: { weight: 0 },
407-
name: { weight: 0 },
408-
hamePlanet: { weight: 0 },
409432
friends: {
410-
resolvesTo: 'human',
433+
resolveTo: 'human',
434+
weight: 10,
435+
},
436+
},
437+
},
438+
});
439+
});
440+
441+
// this test is just in place to make sure additional directives don't cause errors
442+
test('fields returning lists of objects of indeterminate size with multiple directives', () => {
443+
schema = buildSchema(`
444+
directive @listCost(cost: Int!) on FIELD_DEFINITION
445+
directive @testDirective(test: Int!) on FIELD_DEFINITION
446+
directive @testDirective2(test: Int!) on FIELD_DEFINITION
447+
type Human {
448+
id: ID!
449+
friends: [Human] @testDirective2(test: 10) @listCost(cost: 10) @testDirective(test: 10)
450+
}
451+
`);
452+
expect(buildTypeWeightsFromSchema(schema)).toEqual({
453+
human: {
454+
weight: 1,
455+
fields: {
456+
id: { weight: 0 },
457+
friends: {
458+
resolveTo: 'human',
411459
weight: 10,
412460
},
413461
},

test/analysis/typeComplexityAnalysis.test.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import getQueryTypeComplexity from '../../src/analysis/typeComplexityAnalysis';
33
import { TypeWeightObject, Variables } from '../../src/@types/buildTypeWeights';
44

55
/**
6-
* Here is the schema that creates the followning 'typeWeightsObject' used for the tests
6+
* Here is the schema that creates the following 'typeWeightsObject' used for the tests
77
*
88
type Query {
99
hero(episode: Episode): Character
@@ -136,7 +136,7 @@ describe('Test getQueryTypeComplexity function', () => {
136136
},
137137
search: {
138138
resolveTo: 'searchresult',
139-
weight: jest.fn(), // FIXME: Unbounded list result
139+
weight: 10, // FIXME: Unbounded list result
140140
},
141141
character: {
142142
resolveTo: 'character',

0 commit comments

Comments
 (0)