mirror of
https://github.com/vale981/apollo-server
synced 2025-03-05 17:51:40 -05:00
Merge branch 'core-refactor' of github.com:apollostack/apollo-server into core-refactor-express
This commit is contained in:
commit
8fcde0f4d6
4 changed files with 145 additions and 17 deletions
|
@ -15,8 +15,8 @@ Contributions, issues and feature requests are very welcome. If you are using th
|
|||
**/src/core**:
|
||||
- contains the core functionality that is independent of any particular node.js server framework
|
||||
|
||||
**/src/bindings/\<name\>**:
|
||||
- Contains the bindings for Node.js server framework \<name\> (i.e. express, HAPI, Koa, connect)
|
||||
**/src/integrations/\<name\>**:
|
||||
- Contains the integrations for Node.js server framework \<name\> (i.e. express, HAPI, Koa, connect)
|
||||
|
||||
**/src/test**:
|
||||
- Contains only the `tests.ts` file that imports other tests. All real test files go in the same folder as the code they are testing, and should be named `*.test.ts`.
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
"posttest": "npm run lint",
|
||||
"lint": "tslint ./src/**/*",
|
||||
"watch": "tsc -w",
|
||||
"testonly": "mocha --reporter spec --full-trace ./dist/test/tests.js",
|
||||
"testonly": "mocha --harmony --harmony-destructuring --reporter spec --full-trace ./dist/test/tests.js",
|
||||
"coverage": "istanbul cover ./node_modules/mocha/bin/_mocha -- --reporter spec --full-trace --recursive ./dist/test",
|
||||
"postcoverage": "remap-istanbul --input coverage/coverage.raw.json --type lcovonly --output coverage/lcov.info"
|
||||
},
|
||||
|
|
|
@ -1,13 +1,14 @@
|
|||
import {
|
||||
assert,
|
||||
expect,
|
||||
} from 'chai';
|
||||
|
||||
// XXX can be removed after tests are actually writen
|
||||
/* tslint:disable:no-unused-variable */
|
||||
import {
|
||||
GraphQLSchema,
|
||||
GraphQLObjectType,
|
||||
GraphQLString,
|
||||
GraphQLInt,
|
||||
GraphQLNonNull,
|
||||
parse,
|
||||
} from 'graphql';
|
||||
|
||||
import { runQuery } from './runQuery';
|
||||
|
@ -21,20 +22,139 @@ const QueryType = new GraphQLObjectType({
|
|||
return 'it works';
|
||||
},
|
||||
},
|
||||
testRootValue: {
|
||||
type: GraphQLString,
|
||||
resolve(root) {
|
||||
return root + ' works';
|
||||
},
|
||||
},
|
||||
testContextValue: {
|
||||
type: GraphQLString,
|
||||
resolve(root, args, context) {
|
||||
return context + ' works';
|
||||
},
|
||||
},
|
||||
testArgumentValue: {
|
||||
type: GraphQLInt,
|
||||
resolve(root, args, context) {
|
||||
return args['base'] + 5;
|
||||
},
|
||||
args: {
|
||||
base: { type: new GraphQLNonNull(GraphQLInt) },
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
const Schema = new GraphQLSchema({
|
||||
query: QueryType,
|
||||
});
|
||||
// XXX can be removed after tests are actually writen
|
||||
/* tslint:enable:no-unused-variable */
|
||||
|
||||
describe('runQuery', () => {
|
||||
it('returns a response', () => {
|
||||
// XXX can be removed after tests are actually writen
|
||||
// tslint:disable-next-line:no-unused-variable
|
||||
it('returns the right result when query is a string', () => {
|
||||
const query = `{ testString }`;
|
||||
assert(true);
|
||||
const expected = { testString: 'it works' };
|
||||
return runQuery({ schema: Schema, query: query })
|
||||
.then((res) => {
|
||||
return expect(res.data).to.deep.equal(expected);
|
||||
});
|
||||
});
|
||||
|
||||
it('returns the right result when query is a document', () => {
|
||||
const query = parse(`{ testString }`);
|
||||
const expected = { testString: 'it works' };
|
||||
return runQuery({ schema: Schema, query: query })
|
||||
.then((res) => {
|
||||
return expect(res.data).to.deep.equal(expected);
|
||||
});
|
||||
});
|
||||
|
||||
it('returns a syntax error if the query string contains one', () => {
|
||||
const query = `query { test`;
|
||||
const expected = 'Syntax Error GraphQL (1:13) Expected Name, found EOF\n\n1: query { test\n ^\n';
|
||||
return runQuery({
|
||||
schema: Schema,
|
||||
query: query,
|
||||
variables: { base: 1 },
|
||||
}).then((res) => {
|
||||
expect(res.data).to.be.undefined;
|
||||
expect(res.errors.length).to.equal(1);
|
||||
return expect(res.errors[0].message).to.deep.equal(expected);
|
||||
});
|
||||
});
|
||||
|
||||
it('returns a validation error if the query string does not pass validation', () => {
|
||||
const query = `query TestVar($base: String){ testArgumentValue(base: $base) }`;
|
||||
const expected = 'Variable "$base" of type "String" used in position expecting type "Int!".';
|
||||
return runQuery({
|
||||
schema: Schema,
|
||||
query: query,
|
||||
variables: { base: 1 },
|
||||
}).then((res) => {
|
||||
expect(res.data).to.be.undefined;
|
||||
expect(res.errors.length).to.equal(1);
|
||||
return expect(res.errors[0].message).to.deep.equal(expected);
|
||||
});
|
||||
});
|
||||
|
||||
it('does not run validation if the query is a document', () => {
|
||||
// this would not pass validation, because $base ought to be Int!, not String
|
||||
// what effecively happens is string concatentation, but it's returned as Int
|
||||
const query = parse(`query TestVar($base: String){ testArgumentValue(base: $base) }`);
|
||||
const expected = { testArgumentValue: 15 };
|
||||
return runQuery({
|
||||
schema: Schema,
|
||||
query: query,
|
||||
variables: { base: 1 },
|
||||
}).then((res) => {
|
||||
return expect(res.data).to.deep.equal(expected);
|
||||
});
|
||||
});
|
||||
|
||||
it('correctly passes in the rootValue', () => {
|
||||
const query = `{ testRootValue }`;
|
||||
const expected = { testRootValue: 'it also works' };
|
||||
return runQuery({ schema: Schema, query: query, rootValue: 'it also' })
|
||||
.then((res) => {
|
||||
return expect(res.data).to.deep.equal(expected);
|
||||
});
|
||||
});
|
||||
|
||||
it('correctly passes in the context', () => {
|
||||
const query = `{ testContextValue }`;
|
||||
const expected = { testContextValue: 'it still works' };
|
||||
return runQuery({ schema: Schema, query: query, context: 'it still' })
|
||||
.then((res) => {
|
||||
return expect(res.data).to.deep.equal(expected);
|
||||
});
|
||||
});
|
||||
|
||||
it('correctly passes in variables (and arguments)', () => {
|
||||
const query = `query TestVar($base: Int!){ testArgumentValue(base: $base) }`;
|
||||
const expected = { testArgumentValue: 6 };
|
||||
return runQuery({
|
||||
schema: Schema,
|
||||
query: query,
|
||||
variables: { base: 1 },
|
||||
}).then((res) => {
|
||||
return expect(res.data).to.deep.equal(expected);
|
||||
});
|
||||
});
|
||||
|
||||
it('runs the correct operation when operationName is specified', () => {
|
||||
const query = `
|
||||
query Q1 {
|
||||
testString
|
||||
}
|
||||
query Q2 {
|
||||
testRootValue
|
||||
}`;
|
||||
const expected = {
|
||||
testString: 'it works',
|
||||
};
|
||||
return runQuery({ schema: Schema, query: query, operationName: 'Q1' })
|
||||
.then((res) => {
|
||||
return expect(res.data).to.deep.equal(expected);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -12,15 +12,23 @@ export interface GqlResponse {
|
|||
errors?: Array<string>;
|
||||
}
|
||||
|
||||
function runQuery(
|
||||
function runQuery({
|
||||
schema,
|
||||
query,
|
||||
rootValue,
|
||||
context,
|
||||
variables,
|
||||
operationName,
|
||||
}: {
|
||||
schema: GraphQLSchema,
|
||||
query: string | Document,
|
||||
rootValue?: any,
|
||||
context?: any,
|
||||
variables?: { [key: string]: any },
|
||||
operationName?: string
|
||||
//logFunction?: function => void,
|
||||
): Promise<GraphQLResult> {
|
||||
operationName?: string,
|
||||
//logFunction?: function => void
|
||||
//validationRules?: No, too risky. If you want extra validation rules, then parse it yourself.
|
||||
}): Promise<GraphQLResult> {
|
||||
let documentAST: Document;
|
||||
|
||||
// if query is already an AST, don't parse or validate
|
||||
|
@ -33,7 +41,7 @@ function runQuery(
|
|||
}
|
||||
|
||||
// validate
|
||||
const validationErrors = validate(schema, documentAST, []);
|
||||
const validationErrors = validate(schema, documentAST);
|
||||
if (validationErrors.length) {
|
||||
return Promise.resolve({ errors: validationErrors });
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue