Skip to content

Commit

Permalink
Merge branch 'master' into fix-alias-problems
Browse files Browse the repository at this point in the history
  • Loading branch information
Sashko Stubailo committed Oct 4, 2017
2 parents 5dd25a8 + 5c5418c commit 8ef5e2b
Show file tree
Hide file tree
Showing 7 changed files with 144 additions and 104 deletions.
23 changes: 13 additions & 10 deletions src/mock.ts
Expand Up @@ -369,16 +369,19 @@ function addMockFunctionsToSchema({
return undefined !== resolvedValue ? resolvedValue : mockedValue;
}

if (isObject(mockedValue) && isObject(resolvedValue)) {
// Object.assign() won't do here, as we need to all properties, including
// the non-enumerable ones and defined using Object.defineProperty
const emptyObject = Object.create(Object.getPrototypeOf(resolvedValue));
return copyOwnProps(emptyObject, resolvedValue, mockedValue);
}
return (undefined !== resolvedValue) ? resolvedValue : mockedValue;
});
}
});
if (isObject(mockedValue) && isObject(resolvedValue)) {
// Object.assign() won't do here, as we need to all properties, including
// the non-enumerable ones and defined using Object.defineProperty
const emptyObject = Object.create(
Object.getPrototypeOf(resolvedValue),
);
return copyOwnProps(emptyObject, resolvedValue, mockedValue);
}
return undefined !== resolvedValue ? resolvedValue : mockedValue;
});
}
},
);
}

class MockList {
Expand Down
4 changes: 2 additions & 2 deletions src/stitching/introspectSchema.ts
Expand Up @@ -7,15 +7,15 @@ const parsedIntrospectionQuery = parse(introspectionQuery);

export default async function introspectSchema(
link: ApolloLink | Fetcher,
context?: { [key: string]: any },
linkContext?: { [key: string]: any },
): Promise<GraphQLSchema> {
if (!(link as ApolloLink).request) {
link = fetcherToLink(link as Fetcher);
}
const introspectionResult = await makePromise(
execute(link as ApolloLink, {
query: parsedIntrospectionQuery,
context,
context: linkContext,
}),
);
if (introspectionResult.errors || !introspectionResult.data.__schema) {
Expand Down
12 changes: 6 additions & 6 deletions src/stitching/makeRemoteExecutableSchema.ts
Expand Up @@ -24,19 +24,19 @@ export type Fetcher = (
operationName?: string;
variables?: { [key: string]: any };
context?: { [key: string]: any };
},
}
) => Promise<ExecutionResult>;

export const fetcherToLink = (fetcher: Fetcher): ApolloLink => {
return new ApolloLink(operation => {
return new Observable(observer => {
const { query, operationName, variables } = operation;
const context = operation.getContext();
const { graphqlContext } = operation.getContext();
fetcher({
query: typeof query === 'string' ? query : print(query),
operationName,
variables,
context,
context: graphqlContext,
})
.then((result: ExecutionResult) => {
observer.next(result);
Expand Down Expand Up @@ -119,7 +119,7 @@ export default function makeRemoteExecutableSchema({
function createResolver(link: ApolloLink): GraphQLFieldResolver<any, any> {
return async (root, args, context, info) => {
const fragments = Object.keys(info.fragments).map(
fragment => info.fragments[fragment],
fragment => info.fragments[fragment]
);
const document = {
kind: Kind.DOCUMENT,
Expand All @@ -129,8 +129,8 @@ function createResolver(link: ApolloLink): GraphQLFieldResolver<any, any> {
execute(link, {
query: document,
variables: info.variableValues,
context,
}),
context: { graphqlContext: context },
})
);
const fieldName = info.fieldNodes[0].alias
? info.fieldNodes[0].alias.value
Expand Down
67 changes: 37 additions & 30 deletions src/test/testMocking.ts
Expand Up @@ -153,17 +153,21 @@ describe('Mock', () => {
Bird: () => ({ returnInt: () => 54321 }),
Bee: () => ({ returnInt: () => 54321 }),
};
return mockServer(shorthand, mockMap).query(testQuery).then((res: any) => {
expect(res.data.returnInt).to.equal(12345);
expect(res.data.returnFloat).to.be.a('number').within(-1000, 1000);
expect(res.data.returnBoolean).to.be.a('boolean');
expect(res.data.returnString).to.be.a('string');
expect(res.data.returnID).to.be.a('string');
// tests that resolveType is correctly set for unions and interfaces
// and that the correct mock function is used
expect(res.data.returnBirdsAndBees[0].returnInt).to.equal(54321);
expect(res.data.returnBirdsAndBees[1].returnInt).to.equal(54321);
});
return mockServer(shorthand, mockMap)
.query(testQuery)
.then((res: any) => {
expect(res.data.returnInt).to.equal(12345);
expect(res.data.returnFloat)
.to.be.a('number')
.within(-1000, 1000);
expect(res.data.returnBoolean).to.be.a('boolean');
expect(res.data.returnString).to.be.a('string');
expect(res.data.returnID).to.be.a('string');
// tests that resolveType is correctly set for unions and interfaces
// and that the correct mock function is used
expect(res.data.returnBirdsAndBees[0].returnInt).to.equal(54321);
expect(res.data.returnBirdsAndBees[1].returnInt).to.equal(54321);
});
});

it('mockServer is able to preserveResolvers of a prebuilt schema', () => {
Expand Down Expand Up @@ -227,17 +231,21 @@ describe('Mock', () => {
Bird: () => ({ returnInt: () => 54321 }),
Bee: () => ({ returnInt: () => 54321 }),
};
return mockServer(jsSchema, mockMap).query(testQuery).then((res: any) => {
expect(res.data.returnInt).to.equal(12345);
expect(res.data.returnFloat).to.be.a('number').within(-1000, 1000);
expect(res.data.returnBoolean).to.be.a('boolean');
expect(res.data.returnString).to.be.a('string');
expect(res.data.returnID).to.be.a('string');
// tests that resolveType is correctly set for unions and interfaces
// and that the correct mock function is used
expect(res.data.returnBirdsAndBees[0].returnInt).to.equal(54321);
expect(res.data.returnBirdsAndBees[1].returnInt).to.equal(54321);
});
return mockServer(jsSchema, mockMap)
.query(testQuery)
.then((res: any) => {
expect(res.data.returnInt).to.equal(12345);
expect(res.data.returnFloat)
.to.be.a('number')
.within(-1000, 1000);
expect(res.data.returnBoolean).to.be.a('boolean');
expect(res.data.returnString).to.be.a('string');
expect(res.data.returnID).to.be.a('string');
// tests that resolveType is correctly set for unions and interfaces
// and that the correct mock function is used
expect(res.data.returnBirdsAndBees[0].returnInt).to.equal(54321);
expect(res.data.returnBirdsAndBees[1].returnInt).to.equal(54321);
});
});

it('does not mask resolveType functions if you tell it not to', () => {
Expand Down Expand Up @@ -1379,7 +1387,6 @@ describe('Mock', () => {
});

it('allows instanceof checks in __resolveType', () => {

class Account {
public id: string;
public username: string;
Expand Down Expand Up @@ -1413,7 +1420,7 @@ describe('Mock', () => {
Query: {
node: () => {
return new Account();
}
},
},
Node: {
__resolveType: (obj: any) => {
Expand All @@ -1422,8 +1429,8 @@ describe('Mock', () => {
} else {
return null;
}
}
}
},
},
};

const schema = makeExecutableSchema({
Expand All @@ -1433,7 +1440,7 @@ describe('Mock', () => {

addMockFunctionsToSchema({
schema,
preserveResolvers: true
preserveResolvers: true,
});

const query = `
Expand All @@ -1451,9 +1458,9 @@ describe('Mock', () => {
data: {
node: {
id: '123nmasb',
username: 'foo@bar.com'
}
}
username: 'foo@bar.com',
},
},
};
return graphql(schema, query).then(res => {
expect(res).to.deep.equal(expected);
Expand Down
79 changes: 45 additions & 34 deletions src/test/testResolution.ts
Expand Up @@ -31,16 +31,16 @@ describe('Resolve', () => {
const resolvers = {
RootQuery: {
printRoot,
printRootAgain: printRoot
printRootAgain: printRoot,
},
RootMutation: {
printRoot
printRoot,
},
RootSubscription: {
printRoot: {
subscribe: () => pubsub.asyncIterator('printRootChannel')
}
}
subscribe: () => pubsub.asyncIterator('printRootChannel'),
},
},
};
const schema = makeExecutableSchema({ typeDefs, resolvers });
let schemaLevelResolveFunctionCalls = 0;
Expand All @@ -60,11 +60,11 @@ describe('Resolve', () => {
printRootAgain
}
`,
root
root,
).then(({ data }) => {
assert.deepEqual(data, {
printRoot: root,
printRootAgain: root
printRootAgain: root,
});
assert.equal(schemaLevelResolveFunctionCalls, 1);
});
Expand All @@ -85,31 +85,42 @@ describe('Resolve', () => {
subscription TestSubscription {
printRoot
}
`)
).then(results => {
forAwaitEach(results as AsyncIterable<ExecutionResult>, (result: ExecutionResult) => {
if (result.errors) {
return done(new Error(`Unexpected errors in GraphQL result: ${result.errors}`));
}
`),
)
.then(results => {
forAwaitEach(
results as AsyncIterable<ExecutionResult>,
(result: ExecutionResult) => {
if (result.errors) {
return done(
new Error(
`Unexpected errors in GraphQL result: ${result.errors}`,
),
);
}

const subsData = result.data;
subsCbkCalls++;
try {
if (subsCbkCalls === 1) {
assert.equal(schemaLevelResolveFunctionCalls, 1);
assert.deepEqual(subsData, { printRoot: subscriptionRoot });
return resolveFirst();
} else if (subsCbkCalls === 2) {
assert.equal(schemaLevelResolveFunctionCalls, 4);
assert.deepEqual(subsData, { printRoot: subscriptionRoot2 });
return done();
}
} catch (e) {
return done(e);
}
done(new Error('Too many subscription fired'));
}).catch(done);
}).catch(done);
const subsData = result.data;
subsCbkCalls++;
try {
if (subsCbkCalls === 1) {
assert.equal(schemaLevelResolveFunctionCalls, 1);
assert.deepEqual(subsData, { printRoot: subscriptionRoot });
return resolveFirst();
} else if (subsCbkCalls === 2) {
assert.equal(schemaLevelResolveFunctionCalls, 4);
assert.deepEqual(subsData, {
printRoot: subscriptionRoot2,
});
return done();
}
} catch (e) {
return done(e);
}
done(new Error('Too many subscription fired'));
},
).catch(done);
})
.catch(done);
});

pubsub.publish('printRootChannel', { printRoot: subscriptionRoot });
Expand All @@ -123,8 +134,8 @@ describe('Resolve', () => {
printRoot
}
`,
queryRoot
)
queryRoot,
),
)
.then(({ data }) => {
assert.equal(schemaLevelResolveFunctionCalls, 2);
Expand All @@ -136,7 +147,7 @@ describe('Resolve', () => {
printRoot
}
`,
mutationRoot
mutationRoot,
);
})
.then(({ data: mutationData }) => {
Expand Down
26 changes: 15 additions & 11 deletions src/test/testSchemaGenerator.ts
Expand Up @@ -10,7 +10,7 @@ import {
IntValueNode,
parse,
ExecutionResult,
GraphQLError
GraphQLError,
} from 'graphql';
// import { printSchema } from 'graphql';
const GraphQLJSON = require('graphql-type-json');
Expand All @@ -25,7 +25,11 @@ import {
chainResolvers,
concatenateTypeDefs,
} from '../schemaGenerator';
import { IResolverValidationOptions, IResolvers, IExecutableSchemaDefinition } from '../Interfaces';
import {
IResolverValidationOptions,
IResolvers,
IExecutableSchemaDefinition,
} from '../Interfaces';
import 'mocha';

interface Bird {
Expand Down Expand Up @@ -657,8 +661,8 @@ describe('generating schema from shorthand', () => {
});
expect(jsSchema.getQueryType().name).to.equal('Query');
expect(jsSchema.getType('JSON')).to.be.an.instanceof(GraphQLScalarType);
expect(jsSchema.getType('JSON')).to.have
.property('description')
expect(jsSchema.getType('JSON'))
.to.have.property('description')
.that.is.a('string');
expect(jsSchema.getType('JSON')['description']).to.have.length.above(0);
});
Expand Down Expand Up @@ -972,7 +976,10 @@ describe('generating schema from shorthand', () => {
const rf = { Query: { bird: 'NOT A FUNCTION' } };

expect(() =>
makeExecutableSchema({ typeDefs: short, resolvers: rf } as IExecutableSchemaDefinition),
makeExecutableSchema({
typeDefs: short,
resolvers: rf,
} as IExecutableSchemaDefinition),
).to.throw('Resolver Query.bird must be object or function');
});

Expand Down Expand Up @@ -1847,12 +1854,9 @@ describe('chainResolvers', () => {
const rChained = chainResolvers([r1, undefined, r3]);
// faking the resolve info here.
expect(
rChained(
0,
{ name: 'tony' },
null,
{ fieldName: 'person' } as GraphQLResolveInfo,
),
rChained(0, { name: 'tony' }, null, {
fieldName: 'person',
} as GraphQLResolveInfo),
).to.equals('tony');
});
});

0 comments on commit 8ef5e2b

Please sign in to comment.