Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve typing of options and add more codegen tests #465

Merged
merged 6 commits into from
Jul 5, 2018
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
7,961 changes: 846 additions & 7,115 deletions package-lock.json

Large diffs are not rendered by default.

14,157 changes: 4,378 additions & 9,779 deletions packages/apollo-cli/package-lock.json

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
@@ -1,5 +1,70 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`successful codegen generates operation IDs files when flag is set 1`] = `
"{
\\"4de1e386589b0853a102a87a3f21ca25266116517e59c1e8be9442e2571f00bc\\": {
\\"name\\": \\"SimpleQuery\\",
\\"source\\": \\"query SimpleQuery {\\\\n hello\\\\n}\\"
}
}"
`;

exports[`successful codegen handles only flag for Swift target 1`] = `
Array [
Array [
"../../../../outDirectory/__create_this_directory",
"",
],
Array [
"../../../../outDirectory/Types.graphql.swift",
"// This file was automatically generated and should not be edited.

import Apollo",
],
Array [
"../../../../outDirectory/queryTwo.graphql.swift",
"// This file was automatically generated and should not be edited.

import Apollo

public final class OtherQueryQuery: GraphQLQuery {
public let operationDefinition =
\\"query OtherQuery {\\\\n hello\\\\n}\\"

public init() {
}

public struct Data: GraphQLSelectionSet {
public static let possibleTypes = [\\"Query\\"]

public static let selections: [GraphQLSelection] = [
GraphQLField(\\"hello\\", type: .nonNull(.scalar(String.self))),
]

public private(set) var resultMap: ResultMap

public init(unsafeResultMap: ResultMap) {
self.resultMap = unsafeResultMap
}

public init(hello: String) {
self.init(unsafeResultMap: [\\"__typename\\": \\"Query\\", \\"hello\\": hello])
}

public var hello: String {
get {
return resultMap[\\"hello\\"]! as! String
}
set {
resultMap.updateValue(newValue, forKey: \\"hello\\")
}
}
}
}",
],
]
`;

exports[`successful codegen infers Flow target and writes types 1`] = `
"

Expand Down Expand Up @@ -309,3 +374,59 @@ export interface SimpleQuery {
// END Enums and Input Objects
//=============================================================="
`;

exports[`successful codegen writes exact Flow types when the flag is set 1`] = `
"

/* @flow */
/* eslint-disable */
// This file was automatically generated and should not be edited.

// ====================================================
// GraphQL query operation: SimpleQuery
// ====================================================

export type SimpleQuery = {|
hello: string
|};

/* @flow */
/* eslint-disable */
// This file was automatically generated and should not be edited.

//==============================================================
// START Enums and Input Objects
//==============================================================

//==============================================================
// END Enums and Input Objects
//=============================================================="
`;

exports[`successful codegen writes read-only Flow types when the flag is set 1`] = `
"

/* @flow */
/* eslint-disable */
// This file was automatically generated and should not be edited.

// ====================================================
// GraphQL query operation: SimpleQuery
// ====================================================

export type SimpleQuery = {
+hello: string
};

/* @flow */
/* eslint-disable */
// This file was automatically generated and should not be edited.

//==============================================================
// START Enums and Input Objects
//==============================================================

//==============================================================
// END Enums and Input Objects
//=============================================================="
`;
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
query OtherQuery {
hello
}
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,10 @@ const simpleQuery = fs.readFileSync(
path.resolve(__dirname, "./fixtures/simpleQuery.graphql")
);

const otherQuery = fs.readFileSync(
path.resolve(__dirname, "./fixtures/otherQuery.graphql")
);

beforeEach(() => {
vol.reset();
vol.fromJSON({
Expand All @@ -50,6 +54,32 @@ describe("successful codegen", () => {
expect(mockFS.readFileSync("API.swift").toString()).toMatchSnapshot();
});

test
.do(() => {
vol.fromJSON({
"schema.json": JSON.stringify(fullSchema.__schema),
"queryOne.graphql": simpleQuery.toString()
});
})
.command(["codegen:generate", "--schema=schema.json", "--operationIdsPath=myOperationIDs.json", "API.swift"])
.it("generates operation IDs files when flag is set", () => {
expect(mockFS.readFileSync("myOperationIDs.json").toString()).toMatchSnapshot();
});

test
.do(() => {
vol.fromJSON({
"schema.json": JSON.stringify(fullSchema.__schema),
"queryOne.graphql": simpleQuery.toString(),
"queryTwo.graphql": otherQuery.toString(),
"outDirectory/__create_this_directory": ""
});
})
.command(["codegen:generate", "--schema=schema.json", "--only=queryTwo.graphql", "--target=swift", "outDirectory"])
.it("handles only flag for Swift target", () => {
expect(Object.entries(vol.toJSON("outDirectory")).map(arr => [path.relative(__dirname, arr[0]), arr[1]])).toMatchSnapshot();
});

test
.do(() => {
vol.fromJSON({
Expand Down Expand Up @@ -86,6 +116,30 @@ describe("successful codegen", () => {
expect(mockFS.readFileSync("API.js").toString()).toMatchSnapshot();
});

test
.do(() => {
vol.fromJSON({
"schema.json": JSON.stringify(fullSchema.__schema),
"queryOne.graphql": simpleQuery.toString()
});
})
.command(["codegen:generate", "--schema=schema.json", "--useFlowExactObjects", "--outputFlat", "API.js"])
.it("writes exact Flow types when the flag is set", () => {
expect(mockFS.readFileSync("API.js").toString()).toMatchSnapshot();
});

test
.do(() => {
vol.fromJSON({
"schema.json": JSON.stringify(fullSchema.__schema),
"queryOne.graphql": simpleQuery.toString()
});
})
.command(["codegen:generate", "--schema=schema.json", "--useFlowReadOnlyTypes", "--outputFlat", "API.js"])
.it("writes read-only Flow types when the flag is set", () => {
expect(mockFS.readFileSync("API.js").toString()).toMatchSnapshot();
});

test
.do(() => {
vol.fromJSON({
Expand Down Expand Up @@ -287,4 +341,9 @@ describe("error handling", () => {
expect(err.message).toMatch(/The output path must be specified/)
)
.it("errors when no output file is provided");

test
.command(["codegen:generate", "output-file"])
.catch(err => expect(err.message).toMatch(/Could not infer target from output file type, please use --target/))
.it("errors when target cannot be inferred");
});
6 changes: 3 additions & 3 deletions packages/apollo-cli/src/commands/codegen/generate.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ export default class Generate extends Command {
description: "Merge fragment fields onto its enclosing type"
}),
useFlowExactObjects: flags.boolean({
description: "Use Flow read only types for generated types [flow only]"
description: "Use Flow exact objects for generated types [flow only]"
}),
useFlowReadOnlyTypes: flags.boolean({
description: "Use Flow read only types for generated types [flow only]"
Expand Down Expand Up @@ -212,13 +212,13 @@ export default class Generate extends Command {
ctx.queryPaths,
ctx.schema,
typeof args.output === "string" ? args.output : "__generated__",
flags.only ? path.resolve(flags.only) : "",
flags.only,
inferredTarget,
flags.tagName as string,
!flags.outputFlat,
{
passthroughCustomScalars:
flags.passthroughCustomScalars || flags.customScalarsPrefix,
flags.passthroughCustomScalars || !!flags.customScalarsPrefix,
customScalarsPrefix: flags.customScalarsPrefix || "",
addTypename: flags.addTypename,
namespace: flags.namespace,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@ describe("successful checks", () => {
.nock(ENGINE_URI, engineSuccess())
.env({ ENGINE_API_KEY })
.stdout()
.command(["queries:check", "--queries=./client/**"])
.command(["queries:check", "--queries=./client/*.graphql"])
.exit(1)
.it("compares against a schema from a custom directory", () => {
expect(stdout).toContain("FAILURE");
Expand Down
17 changes: 10 additions & 7 deletions packages/apollo-cli/src/generate.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ import * as path from "path";

import { loadAndMergeQueryDocuments } from "apollo-codegen-core/lib/loading";
import { validateQueryDocument } from "./validation";
import { compileToIR } from "apollo-codegen-core/lib/compiler";
import { compileToLegacyIR } from "apollo-codegen-core/lib/compiler/legacyIR";
import { compileToIR, CompilerContext, CompilerOptions } from "apollo-codegen-core/lib/compiler";
import { compileToLegacyIR, CompilerOptions as LegacyCompilerOptions } from "apollo-codegen-core/lib/compiler/legacyIR";
import serializeToJSON from "apollo-codegen-core/lib/serializeToJSON";
import { BasicGeneratedFile } from "apollo-codegen-core/lib/utilities/CodeGenerator";

Expand All @@ -15,6 +15,7 @@ import { generateSource as generateFlowSource } from "apollo-codegen-flow";
import { generateSource as generateTypescriptSource } from "apollo-codegen-typescript";
import { generateSource as generateScalaSource } from "apollo-codegen-scala";
import { GraphQLSchema } from "graphql";
import { FlowCompilerOptions } from '../../apollo-codegen-flow/lib/language';

export type TargetType =
| "json"
Expand All @@ -27,15 +28,17 @@ export type TargetType =
| "typescript"
| "ts";

export type GenerationOptions = CompilerOptions & LegacyCompilerOptions & FlowCompilerOptions;

export default function generate(
inputPaths: string[],
schema: GraphQLSchema,
outputPath: string,
only: string,
only: string | undefined,
target: TargetType,
tagName: string,
nextToSources: boolean | string,
options: any
options: GenerationOptions
): number {
let writtenFiles = 0;

Expand Down Expand Up @@ -159,14 +162,14 @@ interface OperationIdsMap {
source: string;
}

function writeOperationIdsMap(context: any) {
function writeOperationIdsMap(context: CompilerContext) {
let operationIdsMap: { [id: string]: OperationIdsMap } = {};
Object.keys(context.operations)
.map(k => context.operations[k])
.forEach(operation => {
operationIdsMap[operation.operationId] = {
operationIdsMap[operation.operationId!] = {
name: operation.operationName,
source: operation.sourceWithFragments
source: operation.source
};
});
fs.writeFileSync(
Expand Down
1 change: 1 addition & 0 deletions packages/apollo-codegen-core/src/compiler/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ export interface CompilerOptions {
customScalarsPrefix?: string;
namespace?: string;
generateOperationIds?: boolean;
operationIdsPath?: string;
}

export interface CompilerContext {
Expand Down