Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions src/@types/buildTypeWeights.d.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
interface Fields {
[index: string]: number;
readonly [index: string]: number | ((arg: number, type: Type) => number);
}

interface Type {
weight: number;
fields: Fields;
readonly weight: number;
readonly fields: Fields;
}

interface TypeWeightObject {
[index: string]: Type;
readonly [index: string]: Type;
}

interface TypeWeightConfig {
Expand Down
239 changes: 224 additions & 15 deletions test/analysis/buildTypeWeights.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,18 @@ import { buildSchema } from 'graphql';
import { GraphQLSchema } from 'graphql/type/schema';
import buildTypeWeightsFromSchema from '../../src/analysis/buildTypeWeights';

// these types allow the tests to overwite properties on the typeWeightObject
interface TestFields {
[index: string]: number;
}
interface TestType {
weight: number;
fields: TestFields;
}
interface TestTypeWeightObject {
[index: string]: TestType;
}

xdescribe('Test buildTypeWeightsFromSchema function', () => {
let schema: GraphQLSchema;

Expand All @@ -28,18 +40,25 @@ xdescribe('Test buildTypeWeightsFromSchema function', () => {

test('multiple types', () => {
schema = buildSchema(`
type Query {
user: User,
movie: Movie,
}
type User {
name: String
email: String
}

type Movie {
name: String
director: String
}
`);

expect(buildTypeWeightsFromSchema(schema)).toEqual({
Query: {
weight: 1,
fields: {},
},
User: {
weight: 1,
fields: {
Expand All @@ -63,12 +82,10 @@ xdescribe('Test buildTypeWeightsFromSchema function', () => {
user: User
movie: Movie
}

type User {
name: String
email: String
film: Movie
}

type Movie {
name: String
director: User
Expand Down Expand Up @@ -121,29 +138,220 @@ xdescribe('Test buildTypeWeightsFromSchema function', () => {
});
});

test('types with arguments', () => {
schema = buildSchema(`
type Query {
character(id: ID!): Character
}
type Character {
id: ID!
name: String!
}`);
expect(buildTypeWeightsFromSchema(schema)).toEqual({
Query: {
weight: 1,
fields: {},
},
Character: {
weight: 1,
fields: {
id: 0,
name: 0,
},
},
});
});

test('enum types', () => {
schema = buildSchema(`
type Query {
hero(episode: Episode): Character
}
type Character {
id: ID!
name: String!
}
enum Episode {
NEWHOPE
EMPIRE
JEDI
}`);
expect(buildTypeWeightsFromSchema(schema)).toEqual({
Query: {
weight: 1,
fields: {},
},
Character: {
weight: 1,
fields: {
id: 0,
name: 0,
},
},
Episode: {
weight: 0,
fields: {},
},
});
});

test('fields returning lists of objects of determinate size', () => {
schema = buildSchema(`
type Query {
reviews(episode: Episode!, first: Int): [Review]
}
type Review {
episode: Episode
stars: Int!
commentary: String
}
enum Episode {
NEWHOPE
EMPIRE
JEDI
}`);
expect(buildTypeWeightsFromSchema(schema)).toEqual({
Query: {
weight: 1,
fields: {
// FIXME: check the best solution during implementation and update the tests here.
reviews: (arg: number, type: Type) => arg * type.weight,
// code from PR review -> reviews: (type) => args[multiplierName] * typeWeightObject[type].weight
},
},
Review: {
weight: 1,
fields: {
stars: 0,
commentary: 0,
},
},
Episode: {
weight: 0,
fields: {},
},
});
});

// TODO: need to figure out how to handle this situation. Skip for now.
// The field friends returns a list of an unknown number of objects.
xtest('fields returning lists of objects of indetermitae size', () => {
schema = buildSchema(`
type Human {
id: ID!
name: String!
homePlanet: String
friends: [Human]
}
`);
expect(buildTypeWeightsFromSchema(schema)).toEqual({
Human: {
weight: 1,
fields: {
// FIXME: check the best solution during implementation and update the tests here.
friends: (arg: number, type: Type) => arg * type.weight,
},
},
});
});

test('interface types', () => {
schema = buildSchema(`
interface Character {
id: ID!
name: String!
}

type Human implements Character {
id: ID!
name: String!
homePlanet: String
}

type Droid implements Character {
id: ID!
name: String!
primaryFunction: String
}`);
expect(buildTypeWeightsFromSchema(schema)).toEqual({
Character: {
weight: 1,
fields: {
id: 0,
name: 0,
},
},
Human: {
weight: 1,
fields: {
id: 0,
name: 0,
homePlanet: 0,
},
},
Droid: {
weight: 1,
fields: {
id: 0,
name: 0,
primaryFunction: 0,
},
},
Episode: {
weight: 0,
fields: {},
},
});
});

test('union tyes', () => {
schema = buildSchema(`
union SearchResult = Human | Droid
type Human{
homePlanet: String
}
type Droid {
primaryFunction: String
}`);
expect(buildTypeWeightsFromSchema(schema)).toEqual({
SearchResult: {
weight: 1,
fields: {},
},
human: {
weight: 1,
fields: {
homePlanet: 0,
},
},
droid: {
weight: 1,
fields: {
primaryFunction: 0,
},
},
});
});

// TODO: Tests should be written to acount for the additional scenarios possible in a schema
// Mutation type
// Input types (a part of mutations?)
// Subscription type
// List type
// Enem types
// Interface
// Unions
// Input types
});

describe('changes "type weight object" type weights with user configuration of...', () => {
let expectedOutput: TypeWeightObject;
let expectedOutput: TestTypeWeightObject;

beforeEach(() => {
schema = buildSchema(`
type Query {
user: User
movie: Movie
user(id: ID!): User
movie(id: ID!): Movie
}

type User {
name: String
email: String
film: Movie
}

type Movie {
Expand All @@ -163,7 +371,6 @@ xdescribe('Test buildTypeWeightsFromSchema function', () => {
weight: 1,
fields: {
name: 0,
email: 0,
},
},
Movie: {
Expand Down Expand Up @@ -202,7 +409,6 @@ xdescribe('Test buildTypeWeightsFromSchema function', () => {
});

expectedOutput.user.fields.name = 2;
expectedOutput.user.fields.email = 2;
expectedOutput.movie.fields.name = 2;

expect(typeWeightObject).toEqual({ expectedOutput });
Expand Down Expand Up @@ -249,5 +455,8 @@ xdescribe('Test buildTypeWeightsFromSchema function', () => {
'negative'
);
});

// TODO: throw validation error if schema is invalid
test('schema is invalid', () => {});
});
});