diff --git a/.prettierignore b/.prettierignore index c3c435b3..781ba65d 100644 --- a/.prettierignore +++ b/.prettierignore @@ -16,3 +16,4 @@ examples/incremental-migration/schemas/gratsGeneratedSchema.ts # Local Netlify folder .netlify website/src/workers/ts.worker.mjs +*.expected.md diff --git a/src/tests/Markdown.ts b/src/tests/Markdown.ts new file mode 100644 index 00000000..4cc65ea2 --- /dev/null +++ b/src/tests/Markdown.ts @@ -0,0 +1,49 @@ +type MarkdownSection = + | { + kind: "header"; + level: number; + content: string; + } + | { + kind: "codeBlock"; + content: string; + fileType: string; + fileName?: string; + }; + +export class Markdown { + sections: MarkdownSection[] = []; + + addHeader(level: number, content: string) { + this.sections.push({ kind: "header", level, content }); + } + + addCodeBlock(content: string, fileType: string, fileName?: string) { + this.sections.push({ kind: "codeBlock", content, fileType, fileName }); + } + + addMarkdown(markdown: Markdown) { + for (const section of markdown.sections) { + this.sections.push(section); + } + } + + toString(): string { + let output = ""; + for (const section of this.sections) { + switch (section.kind) { + case "header": + output += `${"#".repeat(section.level)} ${section.content}\n\n`; + break; + case "codeBlock": { + const fileNamePart = section.fileName + ? ` title="${section.fileName}"` + : ""; + output += `\`\`\`${section.fileType}${fileNamePart}\n${section.content.trimEnd()}\n\`\`\`\n\n`; + break; + } + } + } + return output.trim(); + } +} diff --git a/src/tests/TestRunner.ts b/src/tests/TestRunner.ts index f3cc890f..e84f0e22 100644 --- a/src/tests/TestRunner.ts +++ b/src/tests/TestRunner.ts @@ -3,11 +3,14 @@ import * as path from "path"; import { diff } from "jest-diff"; import { ask } from "./yesNo"; import { Result } from "../utils/Result"; +import { Markdown } from "./Markdown"; -type Transformer = ( +export type TransformerResult = Result | false; + +export type Transformer = ( code: string, - filename: string, -) => Promise | false> | (Result | false); + fileName: string, +) => TransformerResult | Promise; /** * Looks in a fixtures dir for .ts files, transforms them according to the @@ -86,7 +89,7 @@ export default class TestRunner { fixture: string, { interactive }: { interactive: boolean }, ) { - const expectedFileName = fixture + ".expected"; + const expectedFileName = fixture + ".expected.md"; const expectedFilePath = path.join(this._fixturesDir, expectedFileName); if (this._otherFiles.has(expectedFileName)) { this._otherFiles.delete(expectedFileName); @@ -116,14 +119,19 @@ export default class TestRunner { ? transformResult.value : transformResult.err; - const testOutput = `----------------- -INPUT ------------------ -${fixtureContent} ------------------ -OUTPUT ------------------ -${actualOutput}`; + const fileType = path.extname(fixture).slice(1); + + const output = new Markdown(); + output.addHeader(2, "input"); + output.addCodeBlock(fixtureContent, fileType, fixture); + output.addHeader(2, "Output"); + if (actualOutput instanceof Markdown) { + output.addMarkdown(actualOutput); + } else { + output.addCodeBlock(actualOutput, ""); + } + + const testOutput = output.toString(); // Validate naming convention: .invalid files should have errors, others should succeed const isInvalidTest = fixture.includes(".invalid."); @@ -177,10 +185,7 @@ ${actualOutput}`; } } - async transform( - code: string, - filename: string, - ): Promise | false> { + async transform(code: string, filename: string): Promise { try { return await this._transformer(code, filename); } catch (e) { diff --git a/src/tests/configParserFixtures/empty.json.expected b/src/tests/configParserFixtures/empty.json.expected deleted file mode 100644 index cbed7d58..00000000 --- a/src/tests/configParserFixtures/empty.json.expected +++ /dev/null @@ -1,23 +0,0 @@ ------------------ -INPUT ------------------ -{} - ------------------ -OUTPUT ------------------ --- Parsed Config -- -{ - "graphqlSchema": "./schema.graphql", - "tsSchema": "./schema.ts", - "tsClientEnums": null, - "nullableByDefault": true, - "strictSemanticNullability": false, - "reportTypeScriptTypeErrors": false, - "schemaHeader": "# Schema generated by Grats (https://grats.capt.dev)\n# Do not manually edit. Regenerate by running `npx grats`.", - "tsSchemaHeader": "/**\n * Executable schema generated by Grats (https://grats.capt.dev)\n * Do not manually edit. Regenerate by running `npx grats`.\n */", - "tsClientEnumsHeader": "/**\n * TypeScript enum definitions generated by Grats (https://grats.capt.dev)\n * Do not manually edit. Regenerate by running `npx grats`.\n */", - "importModuleSpecifierEnding": "", - "EXPERIMENTAL__emitMetadata": false, - "EXPERIMENTAL__emitResolverMap": false -} \ No newline at end of file diff --git a/src/tests/configParserFixtures/empty.json.expected.md b/src/tests/configParserFixtures/empty.json.expected.md new file mode 100644 index 00000000..758dbcac --- /dev/null +++ b/src/tests/configParserFixtures/empty.json.expected.md @@ -0,0 +1,26 @@ +## input + +```json title="empty.json" +{} +``` + +## Output + +### Parsed Config + +```json +{ + "graphqlSchema": "./schema.graphql", + "tsSchema": "./schema.ts", + "tsClientEnums": null, + "nullableByDefault": true, + "strictSemanticNullability": false, + "reportTypeScriptTypeErrors": false, + "schemaHeader": "# Schema generated by Grats (https://grats.capt.dev)\n# Do not manually edit. Regenerate by running `npx grats`.", + "tsSchemaHeader": "/**\n * Executable schema generated by Grats (https://grats.capt.dev)\n * Do not manually edit. Regenerate by running `npx grats`.\n */", + "tsClientEnumsHeader": "/**\n * TypeScript enum definitions generated by Grats (https://grats.capt.dev)\n * Do not manually edit. Regenerate by running `npx grats`.\n */", + "importModuleSpecifierEnding": "", + "EXPERIMENTAL__emitMetadata": false, + "EXPERIMENTAL__emitResolverMap": false +} +``` \ No newline at end of file diff --git a/src/tests/configParserFixtures/experimentalField.json.expected b/src/tests/configParserFixtures/experimentalField.json.expected deleted file mode 100644 index 9c915af4..00000000 --- a/src/tests/configParserFixtures/experimentalField.json.expected +++ /dev/null @@ -1,27 +0,0 @@ ------------------ -INPUT ------------------ -{ - "EXPERIMENTAL__emitMetadata": true -} - ------------------ -OUTPUT ------------------ --- Parsed Config -- -{ - "graphqlSchema": "./schema.graphql", - "tsSchema": "./schema.ts", - "tsClientEnums": null, - "nullableByDefault": true, - "strictSemanticNullability": false, - "reportTypeScriptTypeErrors": false, - "schemaHeader": "# Schema generated by Grats (https://grats.capt.dev)\n# Do not manually edit. Regenerate by running `npx grats`.", - "tsSchemaHeader": "/**\n * Executable schema generated by Grats (https://grats.capt.dev)\n * Do not manually edit. Regenerate by running `npx grats`.\n */", - "tsClientEnumsHeader": "/**\n * TypeScript enum definitions generated by Grats (https://grats.capt.dev)\n * Do not manually edit. Regenerate by running `npx grats`.\n */", - "importModuleSpecifierEnding": "", - "EXPERIMENTAL__emitMetadata": true, - "EXPERIMENTAL__emitResolverMap": false -} --- Warnings -- -Grats: The `EXPERIMENTAL__emitMetadata` option is experimental and will be renamed or removed in a future release. \ No newline at end of file diff --git a/src/tests/configParserFixtures/experimentalField.json.expected.md b/src/tests/configParserFixtures/experimentalField.json.expected.md new file mode 100644 index 00000000..915dbe2b --- /dev/null +++ b/src/tests/configParserFixtures/experimentalField.json.expected.md @@ -0,0 +1,34 @@ +## input + +```json title="experimentalField.json" +{ + "EXPERIMENTAL__emitMetadata": true +} +``` + +## Output + +### Parsed Config + +```json +{ + "graphqlSchema": "./schema.graphql", + "tsSchema": "./schema.ts", + "tsClientEnums": null, + "nullableByDefault": true, + "strictSemanticNullability": false, + "reportTypeScriptTypeErrors": false, + "schemaHeader": "# Schema generated by Grats (https://grats.capt.dev)\n# Do not manually edit. Regenerate by running `npx grats`.", + "tsSchemaHeader": "/**\n * Executable schema generated by Grats (https://grats.capt.dev)\n * Do not manually edit. Regenerate by running `npx grats`.\n */", + "tsClientEnumsHeader": "/**\n * TypeScript enum definitions generated by Grats (https://grats.capt.dev)\n * Do not manually edit. Regenerate by running `npx grats`.\n */", + "importModuleSpecifierEnding": "", + "EXPERIMENTAL__emitMetadata": true, + "EXPERIMENTAL__emitResolverMap": false +} +``` + +### Warnings + +```text +Grats: The `EXPERIMENTAL__emitMetadata` option is experimental and will be renamed or removed in a future release. +``` \ No newline at end of file diff --git a/src/tests/configParserFixtures/invlaidKey.invalid.json.expected b/src/tests/configParserFixtures/invlaidKey.invalid.json.expected deleted file mode 100644 index b0224d82..00000000 --- a/src/tests/configParserFixtures/invlaidKey.invalid.json.expected +++ /dev/null @@ -1,11 +0,0 @@ ------------------ -INPUT ------------------ -{ - "lol": true -} - ------------------ -OUTPUT ------------------ -error: Unknown Grats config option `lol`. diff --git a/src/tests/configParserFixtures/invlaidKey.invalid.json.expected.md b/src/tests/configParserFixtures/invlaidKey.invalid.json.expected.md new file mode 100644 index 00000000..85461389 --- /dev/null +++ b/src/tests/configParserFixtures/invlaidKey.invalid.json.expected.md @@ -0,0 +1,15 @@ +## input + +```json title="invlaidKey.invalid.json" +{ + "lol": true +} +``` + +## Output + +### Error Report + +```text +error: Unknown Grats config option `lol`. +``` \ No newline at end of file diff --git a/src/tests/configParserFixtures/multiLineHeader.json.expected b/src/tests/configParserFixtures/multiLineHeader.json.expected deleted file mode 100644 index b8f64bb6..00000000 --- a/src/tests/configParserFixtures/multiLineHeader.json.expected +++ /dev/null @@ -1,25 +0,0 @@ ------------------ -INPUT ------------------ -{ - "schemaHeader": ["/**", " * An amazing GraphQL schema", " */"] -} - ------------------ -OUTPUT ------------------ --- Parsed Config -- -{ - "graphqlSchema": "./schema.graphql", - "tsSchema": "./schema.ts", - "tsClientEnums": null, - "nullableByDefault": true, - "strictSemanticNullability": false, - "reportTypeScriptTypeErrors": false, - "schemaHeader": "/**\n * An amazing GraphQL schema\n */", - "tsSchemaHeader": "/**\n * Executable schema generated by Grats (https://grats.capt.dev)\n * Do not manually edit. Regenerate by running `npx grats`.\n */", - "tsClientEnumsHeader": "/**\n * TypeScript enum definitions generated by Grats (https://grats.capt.dev)\n * Do not manually edit. Regenerate by running `npx grats`.\n */", - "importModuleSpecifierEnding": "", - "EXPERIMENTAL__emitMetadata": false, - "EXPERIMENTAL__emitResolverMap": false -} \ No newline at end of file diff --git a/src/tests/configParserFixtures/multiLineHeader.json.expected.md b/src/tests/configParserFixtures/multiLineHeader.json.expected.md new file mode 100644 index 00000000..1c1dafb5 --- /dev/null +++ b/src/tests/configParserFixtures/multiLineHeader.json.expected.md @@ -0,0 +1,28 @@ +## input + +```json title="multiLineHeader.json" +{ + "schemaHeader": ["/**", " * An amazing GraphQL schema", " */"] +} +``` + +## Output + +### Parsed Config + +```json +{ + "graphqlSchema": "./schema.graphql", + "tsSchema": "./schema.ts", + "tsClientEnums": null, + "nullableByDefault": true, + "strictSemanticNullability": false, + "reportTypeScriptTypeErrors": false, + "schemaHeader": "/**\n * An amazing GraphQL schema\n */", + "tsSchemaHeader": "/**\n * Executable schema generated by Grats (https://grats.capt.dev)\n * Do not manually edit. Regenerate by running `npx grats`.\n */", + "tsClientEnumsHeader": "/**\n * TypeScript enum definitions generated by Grats (https://grats.capt.dev)\n * Do not manually edit. Regenerate by running `npx grats`.\n */", + "importModuleSpecifierEnding": "", + "EXPERIMENTAL__emitMetadata": false, + "EXPERIMENTAL__emitResolverMap": false +} +``` \ No newline at end of file diff --git a/src/tests/configParserFixtures/multiLineNonHeader.invalid.json.expected b/src/tests/configParserFixtures/multiLineNonHeader.invalid.json.expected deleted file mode 100644 index 48deb38e..00000000 --- a/src/tests/configParserFixtures/multiLineNonHeader.invalid.json.expected +++ /dev/null @@ -1,11 +0,0 @@ ------------------ -INPUT ------------------ -{ - "tsSchema": ["/path/", "to/", "schema.ts"] -} - ------------------ -OUTPUT ------------------ -error: Expected property `tsSchema` to be a string, but got ["/path/","to/","schema.ts"]. diff --git a/src/tests/configParserFixtures/multiLineNonHeader.invalid.json.expected.md b/src/tests/configParserFixtures/multiLineNonHeader.invalid.json.expected.md new file mode 100644 index 00000000..364d89b8 --- /dev/null +++ b/src/tests/configParserFixtures/multiLineNonHeader.invalid.json.expected.md @@ -0,0 +1,15 @@ +## input + +```json title="multiLineNonHeader.invalid.json" +{ + "tsSchema": ["/path/", "to/", "schema.ts"] +} +``` + +## Output + +### Error Report + +```text +error: Expected property `tsSchema` to be a string, but got ["/path/","to/","schema.ts"]. +``` \ No newline at end of file diff --git a/src/tests/configParserFixtures/nonNullableFieldIsNull.invalid.json.expected b/src/tests/configParserFixtures/nonNullableFieldIsNull.invalid.json.expected deleted file mode 100644 index b8aa1b8d..00000000 --- a/src/tests/configParserFixtures/nonNullableFieldIsNull.invalid.json.expected +++ /dev/null @@ -1,11 +0,0 @@ ------------------ -INPUT ------------------ -{ - "importModuleSpecifierEnding": null -} - ------------------ -OUTPUT ------------------ -error: The Grats config option `importModuleSpecifierEnding` must be a `string` if provided. diff --git a/src/tests/configParserFixtures/nonNullableFieldIsNull.invalid.json.expected.md b/src/tests/configParserFixtures/nonNullableFieldIsNull.invalid.json.expected.md new file mode 100644 index 00000000..a44e0528 --- /dev/null +++ b/src/tests/configParserFixtures/nonNullableFieldIsNull.invalid.json.expected.md @@ -0,0 +1,15 @@ +## input + +```json title="nonNullableFieldIsNull.invalid.json" +{ + "importModuleSpecifierEnding": null +} +``` + +## Output + +### Error Report + +```text +error: The Grats config option `importModuleSpecifierEnding` must be a `string` if provided. +``` \ No newline at end of file diff --git a/src/tests/fixtures/arguments/ArgReferencesNonGqlType.invalid.ts.expected b/src/tests/fixtures/arguments/ArgReferencesNonGqlType.invalid.ts.expected deleted file mode 100644 index b3c55f74..00000000 --- a/src/tests/fixtures/arguments/ArgReferencesNonGqlType.invalid.ts.expected +++ /dev/null @@ -1,20 +0,0 @@ ------------------ -INPUT ------------------ -type NotGraphql = any; - -/** @gqlType */ -export default class SomeType { - /** @gqlField */ - hello({ greeting }: { greeting: NotGraphql }): string { - return "Hello world!"; - } -} - ------------------ -OUTPUT ------------------ -src/tests/fixtures/arguments/ArgReferencesNonGqlType.invalid.ts:6:35 - error: Unable to resolve type reference. In order to generate a GraphQL schema, Grats needs to determine which GraphQL type is being referenced. This requires being able to resolve type references to their `@gql` annotated declaration. However this reference could not be resolved. Is it possible that this type is not defined in this file? - -6 hello({ greeting }: { greeting: NotGraphql }): string { - ~~~~~~~~~~ diff --git a/src/tests/fixtures/arguments/ArgReferencesNonGqlType.invalid.ts.expected.md b/src/tests/fixtures/arguments/ArgReferencesNonGqlType.invalid.ts.expected.md new file mode 100644 index 00000000..8ae1a943 --- /dev/null +++ b/src/tests/fixtures/arguments/ArgReferencesNonGqlType.invalid.ts.expected.md @@ -0,0 +1,24 @@ +## input + +```ts title="arguments/ArgReferencesNonGqlType.invalid.ts" +type NotGraphql = any; + +/** @gqlType */ +export default class SomeType { + /** @gqlField */ + hello({ greeting }: { greeting: NotGraphql }): string { + return "Hello world!"; + } +} +``` + +## Output + +### Error Report + +```text +src/tests/fixtures/arguments/ArgReferencesNonGqlType.invalid.ts:6:35 - error: Unable to resolve type reference. In order to generate a GraphQL schema, Grats needs to determine which GraphQL type is being referenced. This requires being able to resolve type references to their `@gql` annotated declaration. However this reference could not be resolved. Is it possible that this type is not defined in this file? + +6 hello({ greeting }: { greeting: NotGraphql }): string { + ~~~~~~~~~~ +``` \ No newline at end of file diff --git a/src/tests/fixtures/arguments/ArgWithNoType.invalid.ts.expected b/src/tests/fixtures/arguments/ArgWithNoType.invalid.ts.expected deleted file mode 100644 index ae844548..00000000 --- a/src/tests/fixtures/arguments/ArgWithNoType.invalid.ts.expected +++ /dev/null @@ -1,18 +0,0 @@ ------------------ -INPUT ------------------ -/** @gqlType */ -export default class SomeType { - /** @gqlField */ - hello({ greeting }: { greeting }): string { - return "Hello world!"; - } -} - ------------------ -OUTPUT ------------------ -src/tests/fixtures/arguments/ArgWithNoType.invalid.ts:4:25 - error: Expected GraphQL field argument to have an explicit type annotation. For example: `{ someField: string }`. Grats needs to be able to see the type of the arguments to generate a GraphQL schema. - -4 hello({ greeting }: { greeting }): string { - ~~~~~~~~ diff --git a/src/tests/fixtures/arguments/ArgWithNoType.invalid.ts.expected.md b/src/tests/fixtures/arguments/ArgWithNoType.invalid.ts.expected.md new file mode 100644 index 00000000..96f03bee --- /dev/null +++ b/src/tests/fixtures/arguments/ArgWithNoType.invalid.ts.expected.md @@ -0,0 +1,22 @@ +## input + +```ts title="arguments/ArgWithNoType.invalid.ts" +/** @gqlType */ +export default class SomeType { + /** @gqlField */ + hello({ greeting }: { greeting }): string { + return "Hello world!"; + } +} +``` + +## Output + +### Error Report + +```text +src/tests/fixtures/arguments/ArgWithNoType.invalid.ts:4:25 - error: Expected GraphQL field argument to have an explicit type annotation. For example: `{ someField: string }`. Grats needs to be able to see the type of the arguments to generate a GraphQL schema. + +4 hello({ greeting }: { greeting }): string { + ~~~~~~~~ +``` \ No newline at end of file diff --git a/src/tests/fixtures/arguments/ArgumentWithDescription.ts.expected b/src/tests/fixtures/arguments/ArgumentWithDescription.ts.expected deleted file mode 100644 index bd158c52..00000000 --- a/src/tests/fixtures/arguments/ArgumentWithDescription.ts.expected +++ /dev/null @@ -1,48 +0,0 @@ ------------------ -INPUT ------------------ -/** @gqlType */ -export default class SomeType { - /** @gqlField */ - hello(args: { - /** The greeting to use. */ - greeting: string; - }): string { - return `${args.greeting} world!`; - } -} - ------------------ -OUTPUT ------------------ --- SDL -- -type SomeType { - hello( - """The greeting to use.""" - greeting: String! - ): String -} --- TypeScript -- -import { GraphQLSchema, GraphQLObjectType, GraphQLString, GraphQLNonNull } from "graphql"; -export function getSchema(): GraphQLSchema { - const SomeTypeType: GraphQLObjectType = new GraphQLObjectType({ - name: "SomeType", - fields() { - return { - hello: { - name: "hello", - type: GraphQLString, - args: { - greeting: { - description: "The greeting to use.", - type: new GraphQLNonNull(GraphQLString) - } - } - } - }; - } - }); - return new GraphQLSchema({ - types: [SomeTypeType] - }); -} diff --git a/src/tests/fixtures/arguments/ArgumentWithDescription.ts.expected.md b/src/tests/fixtures/arguments/ArgumentWithDescription.ts.expected.md new file mode 100644 index 00000000..ca131528 --- /dev/null +++ b/src/tests/fixtures/arguments/ArgumentWithDescription.ts.expected.md @@ -0,0 +1,55 @@ +## input + +```ts title="arguments/ArgumentWithDescription.ts" +/** @gqlType */ +export default class SomeType { + /** @gqlField */ + hello(args: { + /** The greeting to use. */ + greeting: string; + }): string { + return `${args.greeting} world!`; + } +} +``` + +## Output + +### SDL + +```graphql +type SomeType { + hello( + """The greeting to use.""" + greeting: String! + ): String +} +``` + +### TypeScript + +```ts +import { GraphQLSchema, GraphQLObjectType, GraphQLString, GraphQLNonNull } from "graphql"; +export function getSchema(): GraphQLSchema { + const SomeTypeType: GraphQLObjectType = new GraphQLObjectType({ + name: "SomeType", + fields() { + return { + hello: { + name: "hello", + type: GraphQLString, + args: { + greeting: { + description: "The greeting to use.", + type: new GraphQLNonNull(GraphQLString) + } + } + } + }; + } + }); + return new GraphQLSchema({ + types: [SomeTypeType] + }); +} +``` \ No newline at end of file diff --git a/src/tests/fixtures/arguments/AsyncIterableArgument.invalid.ts.expected b/src/tests/fixtures/arguments/AsyncIterableArgument.invalid.ts.expected deleted file mode 100644 index 1f92c22c..00000000 --- a/src/tests/fixtures/arguments/AsyncIterableArgument.invalid.ts.expected +++ /dev/null @@ -1,18 +0,0 @@ ------------------ -INPUT ------------------ -/** @gqlType */ -export default class SomeType { - /** @gqlField */ - hello(args: { greeting: AsyncIterable }): string { - return `${args.greeting} world!`; - } -} - ------------------ -OUTPUT ------------------ -src/tests/fixtures/arguments/AsyncIterableArgument.invalid.ts:4:27 - error: `AsyncIterable` is not a valid as an input type. - -4 hello(args: { greeting: AsyncIterable }): string { - ~~~~~~~~~~~~~~~~~~~~~ diff --git a/src/tests/fixtures/arguments/AsyncIterableArgument.invalid.ts.expected.md b/src/tests/fixtures/arguments/AsyncIterableArgument.invalid.ts.expected.md new file mode 100644 index 00000000..4a655b46 --- /dev/null +++ b/src/tests/fixtures/arguments/AsyncIterableArgument.invalid.ts.expected.md @@ -0,0 +1,22 @@ +## input + +```ts title="arguments/AsyncIterableArgument.invalid.ts" +/** @gqlType */ +export default class SomeType { + /** @gqlField */ + hello(args: { greeting: AsyncIterable }): string { + return `${args.greeting} world!`; + } +} +``` + +## Output + +### Error Report + +```text +src/tests/fixtures/arguments/AsyncIterableArgument.invalid.ts:4:27 - error: `AsyncIterable` is not a valid as an input type. + +4 hello(args: { greeting: AsyncIterable }): string { + ~~~~~~~~~~~~~~~~~~~~~ +``` \ No newline at end of file diff --git a/src/tests/fixtures/arguments/CustomScalarArgument.ts.expected b/src/tests/fixtures/arguments/CustomScalarArgument.ts.expected deleted file mode 100644 index f1bcebdd..00000000 --- a/src/tests/fixtures/arguments/CustomScalarArgument.ts.expected +++ /dev/null @@ -1,57 +0,0 @@ ------------------ -INPUT ------------------ -/** @gqlScalar */ -export type MyString = string; - -/** @gqlType */ -export default class SomeType { - /** @gqlField */ - hello({ greeting }: { greeting: MyString }): string { - return "Hello world!"; - } -} - ------------------ -OUTPUT ------------------ --- SDL -- -scalar MyString - -type SomeType { - hello(greeting: MyString!): String -} --- TypeScript -- -import type { GqlScalar } from "grats"; -import type { MyString as MyStringInternal } from "./CustomScalarArgument"; -import { GraphQLSchema, GraphQLScalarType, GraphQLObjectType, GraphQLString, GraphQLNonNull } from "graphql"; -export type SchemaConfig = { - scalars: { - MyString: GqlScalar; - }; -}; -export function getSchema(config: SchemaConfig): GraphQLSchema { - const MyStringType: GraphQLScalarType = new GraphQLScalarType({ - name: "MyString", - ...config.scalars.MyString - }); - const SomeTypeType: GraphQLObjectType = new GraphQLObjectType({ - name: "SomeType", - fields() { - return { - hello: { - name: "hello", - type: GraphQLString, - args: { - greeting: { - type: new GraphQLNonNull(MyStringType) - } - } - } - }; - } - }); - return new GraphQLSchema({ - types: [MyStringType, SomeTypeType] - }); -} diff --git a/src/tests/fixtures/arguments/CustomScalarArgument.ts.expected.md b/src/tests/fixtures/arguments/CustomScalarArgument.ts.expected.md new file mode 100644 index 00000000..f4a49802 --- /dev/null +++ b/src/tests/fixtures/arguments/CustomScalarArgument.ts.expected.md @@ -0,0 +1,64 @@ +## input + +```ts title="arguments/CustomScalarArgument.ts" +/** @gqlScalar */ +export type MyString = string; + +/** @gqlType */ +export default class SomeType { + /** @gqlField */ + hello({ greeting }: { greeting: MyString }): string { + return "Hello world!"; + } +} +``` + +## Output + +### SDL + +```graphql +scalar MyString + +type SomeType { + hello(greeting: MyString!): String +} +``` + +### TypeScript + +```ts +import type { GqlScalar } from "grats"; +import type { MyString as MyStringInternal } from "./CustomScalarArgument"; +import { GraphQLSchema, GraphQLScalarType, GraphQLObjectType, GraphQLString, GraphQLNonNull } from "graphql"; +export type SchemaConfig = { + scalars: { + MyString: GqlScalar; + }; +}; +export function getSchema(config: SchemaConfig): GraphQLSchema { + const MyStringType: GraphQLScalarType = new GraphQLScalarType({ + name: "MyString", + ...config.scalars.MyString + }); + const SomeTypeType: GraphQLObjectType = new GraphQLObjectType({ + name: "SomeType", + fields() { + return { + hello: { + name: "hello", + type: GraphQLString, + args: { + greeting: { + type: new GraphQLNonNull(MyStringType) + } + } + } + }; + } + }); + return new GraphQLSchema({ + types: [MyStringType, SomeTypeType] + }); +} +``` \ No newline at end of file diff --git a/src/tests/fixtures/arguments/DeprecatedArgument.ts.expected b/src/tests/fixtures/arguments/DeprecatedArgument.ts.expected deleted file mode 100644 index 88aba529..00000000 --- a/src/tests/fixtures/arguments/DeprecatedArgument.ts.expected +++ /dev/null @@ -1,47 +0,0 @@ ------------------ -INPUT ------------------ -/** @gqlType */ -export default class SomeType { - /** @gqlField */ - hello({ - greeting, - }: { - /** @deprecated Not used anymore */ - greeting?: string | null; - }): string { - return "Hello world!"; - } -} - ------------------ -OUTPUT ------------------ --- SDL -- -type SomeType { - hello(greeting: String @deprecated(reason: "Not used anymore")): String -} --- TypeScript -- -import { GraphQLSchema, GraphQLObjectType, GraphQLString } from "graphql"; -export function getSchema(): GraphQLSchema { - const SomeTypeType: GraphQLObjectType = new GraphQLObjectType({ - name: "SomeType", - fields() { - return { - hello: { - name: "hello", - type: GraphQLString, - args: { - greeting: { - deprecationReason: "Not used anymore", - type: GraphQLString - } - } - } - }; - } - }); - return new GraphQLSchema({ - types: [SomeTypeType] - }); -} diff --git a/src/tests/fixtures/arguments/DeprecatedArgument.ts.expected.md b/src/tests/fixtures/arguments/DeprecatedArgument.ts.expected.md new file mode 100644 index 00000000..1860d784 --- /dev/null +++ b/src/tests/fixtures/arguments/DeprecatedArgument.ts.expected.md @@ -0,0 +1,54 @@ +## input + +```ts title="arguments/DeprecatedArgument.ts" +/** @gqlType */ +export default class SomeType { + /** @gqlField */ + hello({ + greeting, + }: { + /** @deprecated Not used anymore */ + greeting?: string | null; + }): string { + return "Hello world!"; + } +} +``` + +## Output + +### SDL + +```graphql +type SomeType { + hello(greeting: String @deprecated(reason: "Not used anymore")): String +} +``` + +### TypeScript + +```ts +import { GraphQLSchema, GraphQLObjectType, GraphQLString } from "graphql"; +export function getSchema(): GraphQLSchema { + const SomeTypeType: GraphQLObjectType = new GraphQLObjectType({ + name: "SomeType", + fields() { + return { + hello: { + name: "hello", + type: GraphQLString, + args: { + greeting: { + deprecationReason: "Not used anymore", + type: GraphQLString + } + } + } + }; + } + }); + return new GraphQLSchema({ + types: [SomeTypeType] + }); +} +``` \ No newline at end of file diff --git a/src/tests/fixtures/arguments/DeprecatedRequiredArgument.invalid.ts.expected b/src/tests/fixtures/arguments/DeprecatedRequiredArgument.invalid.ts.expected deleted file mode 100644 index e8475115..00000000 --- a/src/tests/fixtures/arguments/DeprecatedRequiredArgument.invalid.ts.expected +++ /dev/null @@ -1,28 +0,0 @@ ------------------ -INPUT ------------------ -/** @gqlType */ -export default class SomeType { - /** @gqlField */ - hello({ - greeting, - }: { - /** @deprecated Not used anymore */ - greeting: string; - }): string { - return "Hello world!"; - } -} - ------------------ -OUTPUT ------------------ -src/tests/fixtures/arguments/DeprecatedRequiredArgument.invalid.ts:7:10 - error: Required argument SomeType.hello(greeting:) cannot be deprecated. - -7 /** @deprecated Not used anymore */ - ~~~~~~~~~~ - - src/tests/fixtures/arguments/DeprecatedRequiredArgument.invalid.ts:8:15 - 8 greeting: string; - ~~~~~~ - Related location diff --git a/src/tests/fixtures/arguments/DeprecatedRequiredArgument.invalid.ts.expected.md b/src/tests/fixtures/arguments/DeprecatedRequiredArgument.invalid.ts.expected.md new file mode 100644 index 00000000..5a061708 --- /dev/null +++ b/src/tests/fixtures/arguments/DeprecatedRequiredArgument.invalid.ts.expected.md @@ -0,0 +1,32 @@ +## input + +```ts title="arguments/DeprecatedRequiredArgument.invalid.ts" +/** @gqlType */ +export default class SomeType { + /** @gqlField */ + hello({ + greeting, + }: { + /** @deprecated Not used anymore */ + greeting: string; + }): string { + return "Hello world!"; + } +} +``` + +## Output + +### Error Report + +```text +src/tests/fixtures/arguments/DeprecatedRequiredArgument.invalid.ts:7:10 - error: Required argument SomeType.hello(greeting:) cannot be deprecated. + +7 /** @deprecated Not used anymore */ + ~~~~~~~~~~ + + src/tests/fixtures/arguments/DeprecatedRequiredArgument.invalid.ts:8:15 + 8 greeting: string; + ~~~~~~ + Related location +``` \ No newline at end of file diff --git a/src/tests/fixtures/arguments/GqlTypeUsedAsPositionalArg.ts.expected b/src/tests/fixtures/arguments/GqlTypeUsedAsPositionalArg.ts.expected deleted file mode 100644 index 2999df3b..00000000 --- a/src/tests/fixtures/arguments/GqlTypeUsedAsPositionalArg.ts.expected +++ /dev/null @@ -1,70 +0,0 @@ ------------------ -INPUT ------------------ -/** @gqlInput */ -type Greeting = { - name: string; - salutation: string; -}; - -/** @gqlType */ -export default class SomeType { - /** @gqlField */ - hello(greeting: Greeting): string { - return `${greeting.salutation} ${greeting.name}!`; - } -} - ------------------ -OUTPUT ------------------ --- SDL -- -input Greeting { - name: String! - salutation: String! -} - -type SomeType { - hello(greeting: Greeting!): String -} --- TypeScript -- -import { GraphQLSchema, GraphQLInputObjectType, GraphQLNonNull, GraphQLString, GraphQLObjectType } from "graphql"; -export function getSchema(): GraphQLSchema { - const GreetingType: GraphQLInputObjectType = new GraphQLInputObjectType({ - name: "Greeting", - fields() { - return { - name: { - name: "name", - type: new GraphQLNonNull(GraphQLString) - }, - salutation: { - name: "salutation", - type: new GraphQLNonNull(GraphQLString) - } - }; - } - }); - const SomeTypeType: GraphQLObjectType = new GraphQLObjectType({ - name: "SomeType", - fields() { - return { - hello: { - name: "hello", - type: GraphQLString, - args: { - greeting: { - type: new GraphQLNonNull(GreetingType) - } - }, - resolve(source, args) { - return source.hello(args.greeting); - } - } - }; - } - }); - return new GraphQLSchema({ - types: [GreetingType, SomeTypeType] - }); -} diff --git a/src/tests/fixtures/arguments/GqlTypeUsedAsPositionalArg.ts.expected.md b/src/tests/fixtures/arguments/GqlTypeUsedAsPositionalArg.ts.expected.md new file mode 100644 index 00000000..a599d0d5 --- /dev/null +++ b/src/tests/fixtures/arguments/GqlTypeUsedAsPositionalArg.ts.expected.md @@ -0,0 +1,77 @@ +## input + +```ts title="arguments/GqlTypeUsedAsPositionalArg.ts" +/** @gqlInput */ +type Greeting = { + name: string; + salutation: string; +}; + +/** @gqlType */ +export default class SomeType { + /** @gqlField */ + hello(greeting: Greeting): string { + return `${greeting.salutation} ${greeting.name}!`; + } +} +``` + +## Output + +### SDL + +```graphql +input Greeting { + name: String! + salutation: String! +} + +type SomeType { + hello(greeting: Greeting!): String +} +``` + +### TypeScript + +```ts +import { GraphQLSchema, GraphQLInputObjectType, GraphQLNonNull, GraphQLString, GraphQLObjectType } from "graphql"; +export function getSchema(): GraphQLSchema { + const GreetingType: GraphQLInputObjectType = new GraphQLInputObjectType({ + name: "Greeting", + fields() { + return { + name: { + name: "name", + type: new GraphQLNonNull(GraphQLString) + }, + salutation: { + name: "salutation", + type: new GraphQLNonNull(GraphQLString) + } + }; + } + }); + const SomeTypeType: GraphQLObjectType = new GraphQLObjectType({ + name: "SomeType", + fields() { + return { + hello: { + name: "hello", + type: GraphQLString, + args: { + greeting: { + type: new GraphQLNonNull(GreetingType) + } + }, + resolve(source, args) { + return source.hello(args.greeting); + } + } + }; + } + }); + return new GraphQLSchema({ + types: [GreetingType, SomeTypeType] + }); +} +``` \ No newline at end of file diff --git a/src/tests/fixtures/arguments/MultipleParamsTypedAsTypeLiteral.invalid.ts.expected b/src/tests/fixtures/arguments/MultipleParamsTypedAsTypeLiteral.invalid.ts.expected deleted file mode 100644 index 21fb631e..00000000 --- a/src/tests/fixtures/arguments/MultipleParamsTypedAsTypeLiteral.invalid.ts.expected +++ /dev/null @@ -1,23 +0,0 @@ ------------------ -INPUT ------------------ -/** @gqlType */ -export default class SomeType { - /** @gqlField */ - hello(args: { greeting: string }, alsoArgs: { farewell: string }): string { - return "Hello world!"; - } -} - ------------------ -OUTPUT ------------------ -src/tests/fixtures/arguments/MultipleParamsTypedAsTypeLiteral.invalid.ts:4:37 - error: Unexpected multiple resolver parameters typed with an object literal. Grats assumes a resolver parameter typed with object literals describes the GraphQL arguments. Therefore only one such parameter is permitted. - -4 hello(args: { greeting: string }, alsoArgs: { farewell: string }): string { - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - - src/tests/fixtures/arguments/MultipleParamsTypedAsTypeLiteral.invalid.ts:4:9 - 4 hello(args: { greeting: string }, alsoArgs: { farewell: string }): string { - ~~~~~~~~~~~~~~~~~~~~~~~~~~ - Previous type literal diff --git a/src/tests/fixtures/arguments/MultipleParamsTypedAsTypeLiteral.invalid.ts.expected.md b/src/tests/fixtures/arguments/MultipleParamsTypedAsTypeLiteral.invalid.ts.expected.md new file mode 100644 index 00000000..c4bb5193 --- /dev/null +++ b/src/tests/fixtures/arguments/MultipleParamsTypedAsTypeLiteral.invalid.ts.expected.md @@ -0,0 +1,27 @@ +## input + +```ts title="arguments/MultipleParamsTypedAsTypeLiteral.invalid.ts" +/** @gqlType */ +export default class SomeType { + /** @gqlField */ + hello(args: { greeting: string }, alsoArgs: { farewell: string }): string { + return "Hello world!"; + } +} +``` + +## Output + +### Error Report + +```text +src/tests/fixtures/arguments/MultipleParamsTypedAsTypeLiteral.invalid.ts:4:37 - error: Unexpected multiple resolver parameters typed with an object literal. Grats assumes a resolver parameter typed with object literals describes the GraphQL arguments. Therefore only one such parameter is permitted. + +4 hello(args: { greeting: string }, alsoArgs: { farewell: string }): string { + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + src/tests/fixtures/arguments/MultipleParamsTypedAsTypeLiteral.invalid.ts:4:9 + 4 hello(args: { greeting: string }, alsoArgs: { farewell: string }): string { + ~~~~~~~~~~~~~~~~~~~~~~~~~~ + Previous type literal +``` \ No newline at end of file diff --git a/src/tests/fixtures/arguments/NoArgsWithNever.invalid.ts.expected b/src/tests/fixtures/arguments/NoArgsWithNever.invalid.ts.expected deleted file mode 100644 index 9b907285..00000000 --- a/src/tests/fixtures/arguments/NoArgsWithNever.invalid.ts.expected +++ /dev/null @@ -1,21 +0,0 @@ ------------------ -INPUT ------------------ -/** @gqlType */ -export default class SomeType { - /** @gqlField */ - hello(args: never): string { - console.log("hello"); - return "Hello world!"; - } -} - ------------------ -OUTPUT ------------------ -src/tests/fixtures/arguments/NoArgsWithNever.invalid.ts:4:15 - error: Unknown GraphQL type. Grats does not know how to map this type to a GraphQL type. You may want to define a named GraphQL type elsewhere and reference it here. If you think Grats should be able to infer a GraphQL type from this type, please file an issue. - -If you think Grats should be able to infer this type, please report an issue at https://github.com/captbaritone/grats/issues. - -4 hello(args: never): string { - ~~~~~ diff --git a/src/tests/fixtures/arguments/NoArgsWithNever.invalid.ts.expected.md b/src/tests/fixtures/arguments/NoArgsWithNever.invalid.ts.expected.md new file mode 100644 index 00000000..04b33f2a --- /dev/null +++ b/src/tests/fixtures/arguments/NoArgsWithNever.invalid.ts.expected.md @@ -0,0 +1,25 @@ +## input + +```ts title="arguments/NoArgsWithNever.invalid.ts" +/** @gqlType */ +export default class SomeType { + /** @gqlField */ + hello(args: never): string { + console.log("hello"); + return "Hello world!"; + } +} +``` + +## Output + +### Error Report + +```text +src/tests/fixtures/arguments/NoArgsWithNever.invalid.ts:4:15 - error: Unknown GraphQL type. Grats does not know how to map this type to a GraphQL type. You may want to define a named GraphQL type elsewhere and reference it here. If you think Grats should be able to infer a GraphQL type from this type, please file an issue. + +If you think Grats should be able to infer this type, please report an issue at https://github.com/captbaritone/grats/issues. + +4 hello(args: never): string { + ~~~~~ +``` \ No newline at end of file diff --git a/src/tests/fixtures/arguments/NoArgsWithUnknown.invalid.ts.expected b/src/tests/fixtures/arguments/NoArgsWithUnknown.invalid.ts.expected deleted file mode 100644 index b372a7ce..00000000 --- a/src/tests/fixtures/arguments/NoArgsWithUnknown.invalid.ts.expected +++ /dev/null @@ -1,21 +0,0 @@ ------------------ -INPUT ------------------ -/** @gqlType */ -export default class SomeType { - /** @gqlField */ - hello(args: unknown): string { - console.log("hello"); - return "Hello world!"; - } -} - ------------------ -OUTPUT ------------------ -src/tests/fixtures/arguments/NoArgsWithUnknown.invalid.ts:4:15 - error: Unknown GraphQL type. Grats does not know how to map this type to a GraphQL type. You may want to define a named GraphQL type elsewhere and reference it here. If you think Grats should be able to infer a GraphQL type from this type, please file an issue. - -If you think Grats should be able to infer this type, please report an issue at https://github.com/captbaritone/grats/issues. - -4 hello(args: unknown): string { - ~~~~~~~ diff --git a/src/tests/fixtures/arguments/NoArgsWithUnknown.invalid.ts.expected.md b/src/tests/fixtures/arguments/NoArgsWithUnknown.invalid.ts.expected.md new file mode 100644 index 00000000..00289071 --- /dev/null +++ b/src/tests/fixtures/arguments/NoArgsWithUnknown.invalid.ts.expected.md @@ -0,0 +1,25 @@ +## input + +```ts title="arguments/NoArgsWithUnknown.invalid.ts" +/** @gqlType */ +export default class SomeType { + /** @gqlField */ + hello(args: unknown): string { + console.log("hello"); + return "Hello world!"; + } +} +``` + +## Output + +### Error Report + +```text +src/tests/fixtures/arguments/NoArgsWithUnknown.invalid.ts:4:15 - error: Unknown GraphQL type. Grats does not know how to map this type to a GraphQL type. You may want to define a named GraphQL type elsewhere and reference it here. If you think Grats should be able to infer a GraphQL type from this type, please file an issue. + +If you think Grats should be able to infer this type, please report an issue at https://github.com/captbaritone/grats/issues. + +4 hello(args: unknown): string { + ~~~~~~~ +``` \ No newline at end of file diff --git a/src/tests/fixtures/arguments/NoTypeAnnotation.invalid.ts.expected b/src/tests/fixtures/arguments/NoTypeAnnotation.invalid.ts.expected deleted file mode 100644 index b0f7947e..00000000 --- a/src/tests/fixtures/arguments/NoTypeAnnotation.invalid.ts.expected +++ /dev/null @@ -1,18 +0,0 @@ ------------------ -INPUT ------------------ -/** @gqlType */ -export default class SomeType { - /** @gqlField */ - hello(args): string { - return "Hello world!"; - } -} - ------------------ -OUTPUT ------------------ -src/tests/fixtures/arguments/NoTypeAnnotation.invalid.ts:4:9 - error: Missing type annotation for resolver argument. Expected all resolver arguments to have an explicit type annotation. Grats needs to be able to see the type of the arguments to generate an executable GraphQL schema. - -4 hello(args): string { - ~~~~ diff --git a/src/tests/fixtures/arguments/NoTypeAnnotation.invalid.ts.expected.md b/src/tests/fixtures/arguments/NoTypeAnnotation.invalid.ts.expected.md new file mode 100644 index 00000000..e7e95236 --- /dev/null +++ b/src/tests/fixtures/arguments/NoTypeAnnotation.invalid.ts.expected.md @@ -0,0 +1,22 @@ +## input + +```ts title="arguments/NoTypeAnnotation.invalid.ts" +/** @gqlType */ +export default class SomeType { + /** @gqlField */ + hello(args): string { + return "Hello world!"; + } +} +``` + +## Output + +### Error Report + +```text +src/tests/fixtures/arguments/NoTypeAnnotation.invalid.ts:4:9 - error: Missing type annotation for resolver argument. Expected all resolver arguments to have an explicit type annotation. Grats needs to be able to see the type of the arguments to generate an executable GraphQL schema. + +4 hello(args): string { + ~~~~ +``` \ No newline at end of file diff --git a/src/tests/fixtures/arguments/NullableArgumentErrors.invalid.ts.expected b/src/tests/fixtures/arguments/NullableArgumentErrors.invalid.ts.expected deleted file mode 100644 index 79d385e6..00000000 --- a/src/tests/fixtures/arguments/NullableArgumentErrors.invalid.ts.expected +++ /dev/null @@ -1,98 +0,0 @@ ------------------ -INPUT ------------------ -/** @gqlType */ -export default class SomeType { - /** @gqlField */ - hello1({ greeting }: { greeting: string | null }): string { - return "Hello world!"; - } - /** @gqlField */ - hello2({ greeting }: { greeting: string | void }): string { - return "Hello world!"; - } - /** @gqlField */ - hello3({ greeting }: { greeting: string | undefined }): string { - return "Hello world!"; - } - // TODO: This should be an error, but it's not. - /** @gqlField */ - hello5({ greeting }: { greeting?: string | undefined }): string { - return "Hello world!"; - } -} - ------------------ -OUTPUT ------------------ --- Error Report -- -src/tests/fixtures/arguments/NullableArgumentErrors.invalid.ts:4:26 - error: Expected nullable argument to _also_ be optional (`?`). graphql-js may omit properties on the argument object where an undefined GraphQL variable is passed, or if the argument is omitted in the operation text. To ensure your resolver is capable of handling this scenario, add a `?` to the end of the argument name to make it optional. e.g. `{greeting?: string | null}` - -4 hello1({ greeting }: { greeting: string | null }): string { - ~~~~~~~~ - -src/tests/fixtures/arguments/NullableArgumentErrors.invalid.ts:8:26 - error: Expected nullable argument to _also_ be optional (`?`). graphql-js may omit properties on the argument object where an undefined GraphQL variable is passed, or if the argument is omitted in the operation text. To ensure your resolver is capable of handling this scenario, add a `?` to the end of the argument name to make it optional. e.g. `{greeting?: string | null}` - -8 hello2({ greeting }: { greeting: string | void }): string { - ~~~~~~~~ - -src/tests/fixtures/arguments/NullableArgumentErrors.invalid.ts:12:26 - error: Expected nullable argument to _also_ be optional (`?`). graphql-js may omit properties on the argument object where an undefined GraphQL variable is passed, or if the argument is omitted in the operation text. To ensure your resolver is capable of handling this scenario, add a `?` to the end of the argument name to make it optional. e.g. `{greeting?: string | null}` - -12 hello3({ greeting }: { greeting: string | undefined }): string { - ~~~~~~~~ - - --- Code Action: "Make argument optional" (add-question-token-to-arg) -- -- Original -+ Fixed - -@@ -3,3 +3,3 @@ - /** @gqlField */ -- hello1({ greeting }: { greeting: string | null }): string { -+ hello1({ greeting }: { greeting?: string | null }): string { - return "Hello world!"; --- Code Action: "Make argument optional" (add-question-token-to-arg) -- -- Original -+ Fixed - -@@ -7,3 +7,3 @@ - /** @gqlField */ -- hello2({ greeting }: { greeting: string | void }): string { -+ hello2({ greeting }: { greeting?: string | void }): string { - return "Hello world!"; --- Code Action: "Make argument optional" (add-question-token-to-arg) -- -- Original -+ Fixed - -@@ -11,3 +11,3 @@ - /** @gqlField */ -- hello3({ greeting }: { greeting: string | undefined }): string { -+ hello3({ greeting }: { greeting?: string | undefined }): string { - return "Hello world!"; - --- Applied Fixes -- - * Applied fix "Make argument optional" in grats/src/tests/fixtures/arguments/NullableArgumentErrors.invalid.ts - * Applied fix "Make argument optional" in grats/src/tests/fixtures/arguments/NullableArgumentErrors.invalid.ts - * Applied fix "Make argument optional" in grats/src/tests/fixtures/arguments/NullableArgumentErrors.invalid.ts - --- Fixed Text -- -/** @gqlType */ -export default class SomeType { - /** @gqlField */ - hello1({ greeting }: { greeting?: string | null }): string { - return "Hello world!"; - } - /** @gqlField */ - hello2({ greeting }: { greeting?: string | void }): string { - return "Hello world!"; - } - /** @gqlField */ - hello3({ greeting }: { greeting?: string | undefined }): string { - return "Hello world!"; - } - // TODO: This should be an error, but it's not. - /** @gqlField */ - hello5({ greeting }: { greeting?: string | undefined }): string { - return "Hello world!"; - } -} diff --git a/src/tests/fixtures/arguments/NullableArgumentErrors.invalid.ts.expected.md b/src/tests/fixtures/arguments/NullableArgumentErrors.invalid.ts.expected.md new file mode 100644 index 00000000..150337a0 --- /dev/null +++ b/src/tests/fixtures/arguments/NullableArgumentErrors.invalid.ts.expected.md @@ -0,0 +1,117 @@ +## input + +```ts title="arguments/NullableArgumentErrors.invalid.ts" +/** @gqlType */ +export default class SomeType { + /** @gqlField */ + hello1({ greeting }: { greeting: string | null }): string { + return "Hello world!"; + } + /** @gqlField */ + hello2({ greeting }: { greeting: string | void }): string { + return "Hello world!"; + } + /** @gqlField */ + hello3({ greeting }: { greeting: string | undefined }): string { + return "Hello world!"; + } + // TODO: This should be an error, but it's not. + /** @gqlField */ + hello5({ greeting }: { greeting?: string | undefined }): string { + return "Hello world!"; + } +} +``` + +## Output + +### Error Report + +```text +src/tests/fixtures/arguments/NullableArgumentErrors.invalid.ts:4:26 - error: Expected nullable argument to _also_ be optional (`?`). graphql-js may omit properties on the argument object where an undefined GraphQL variable is passed, or if the argument is omitted in the operation text. To ensure your resolver is capable of handling this scenario, add a `?` to the end of the argument name to make it optional. e.g. `{greeting?: string | null}` + +4 hello1({ greeting }: { greeting: string | null }): string { + ~~~~~~~~ + +src/tests/fixtures/arguments/NullableArgumentErrors.invalid.ts:8:26 - error: Expected nullable argument to _also_ be optional (`?`). graphql-js may omit properties on the argument object where an undefined GraphQL variable is passed, or if the argument is omitted in the operation text. To ensure your resolver is capable of handling this scenario, add a `?` to the end of the argument name to make it optional. e.g. `{greeting?: string | null}` + +8 hello2({ greeting }: { greeting: string | void }): string { + ~~~~~~~~ + +src/tests/fixtures/arguments/NullableArgumentErrors.invalid.ts:12:26 - error: Expected nullable argument to _also_ be optional (`?`). graphql-js may omit properties on the argument object where an undefined GraphQL variable is passed, or if the argument is omitted in the operation text. To ensure your resolver is capable of handling this scenario, add a `?` to the end of the argument name to make it optional. e.g. `{greeting?: string | null}` + +12 hello3({ greeting }: { greeting: string | undefined }): string { + ~~~~~~~~ +``` + +#### Code Action: "Make argument optional" (add-question-token-to-arg) + +```diff +- Original ++ Fixed + +@@ -3,3 +3,3 @@ + /** @gqlField */ +- hello1({ greeting }: { greeting: string | null }): string { ++ hello1({ greeting }: { greeting?: string | null }): string { + return "Hello world!"; +``` + +#### Code Action: "Make argument optional" (add-question-token-to-arg) + +```diff +- Original ++ Fixed + +@@ -7,3 +7,3 @@ + /** @gqlField */ +- hello2({ greeting }: { greeting: string | void }): string { ++ hello2({ greeting }: { greeting?: string | void }): string { + return "Hello world!"; +``` + +#### Code Action: "Make argument optional" (add-question-token-to-arg) + +```diff +- Original ++ Fixed + +@@ -11,3 +11,3 @@ + /** @gqlField */ +- hello3({ greeting }: { greeting: string | undefined }): string { ++ hello3({ greeting }: { greeting?: string | undefined }): string { + return "Hello world!"; +``` + +#### Applied Fixes + +```text + * Applied fix "Make argument optional" in grats/src/tests/fixtures/arguments/NullableArgumentErrors.invalid.ts + * Applied fix "Make argument optional" in grats/src/tests/fixtures/arguments/NullableArgumentErrors.invalid.ts + * Applied fix "Make argument optional" in grats/src/tests/fixtures/arguments/NullableArgumentErrors.invalid.ts +``` + +#### Fixed Text + +```typescript +/** @gqlType */ +export default class SomeType { + /** @gqlField */ + hello1({ greeting }: { greeting?: string | null }): string { + return "Hello world!"; + } + /** @gqlField */ + hello2({ greeting }: { greeting?: string | void }): string { + return "Hello world!"; + } + /** @gqlField */ + hello3({ greeting }: { greeting?: string | undefined }): string { + return "Hello world!"; + } + // TODO: This should be an error, but it's not. + /** @gqlField */ + hello5({ greeting }: { greeting?: string | undefined }): string { + return "Hello world!"; + } +} +``` \ No newline at end of file diff --git a/src/tests/fixtures/arguments/NullableArguments.ts.expected b/src/tests/fixtures/arguments/NullableArguments.ts.expected deleted file mode 100644 index 64cbca40..00000000 --- a/src/tests/fixtures/arguments/NullableArguments.ts.expected +++ /dev/null @@ -1,59 +0,0 @@ ------------------ -INPUT ------------------ -/** @gqlType */ -export default class SomeType { - /** @gqlField */ - hello1({ greeting }: { greeting?: string | null }): string { - return "Hello world!"; - } - /** @gqlField */ - hello2({ - greeting, - }: { - greeting?: string | undefined | void | undefined; - }): string { - return "Hello world!"; - } -} - ------------------ -OUTPUT ------------------ --- SDL -- -type SomeType { - hello1(greeting: String): String - hello2(greeting: String): String -} --- TypeScript -- -import { GraphQLSchema, GraphQLObjectType, GraphQLString } from "graphql"; -export function getSchema(): GraphQLSchema { - const SomeTypeType: GraphQLObjectType = new GraphQLObjectType({ - name: "SomeType", - fields() { - return { - hello1: { - name: "hello1", - type: GraphQLString, - args: { - greeting: { - type: GraphQLString - } - } - }, - hello2: { - name: "hello2", - type: GraphQLString, - args: { - greeting: { - type: GraphQLString - } - } - } - }; - } - }); - return new GraphQLSchema({ - types: [SomeTypeType] - }); -} diff --git a/src/tests/fixtures/arguments/NullableArguments.ts.expected.md b/src/tests/fixtures/arguments/NullableArguments.ts.expected.md new file mode 100644 index 00000000..74e6b1d5 --- /dev/null +++ b/src/tests/fixtures/arguments/NullableArguments.ts.expected.md @@ -0,0 +1,66 @@ +## input + +```ts title="arguments/NullableArguments.ts" +/** @gqlType */ +export default class SomeType { + /** @gqlField */ + hello1({ greeting }: { greeting?: string | null }): string { + return "Hello world!"; + } + /** @gqlField */ + hello2({ + greeting, + }: { + greeting?: string | undefined | void | undefined; + }): string { + return "Hello world!"; + } +} +``` + +## Output + +### SDL + +```graphql +type SomeType { + hello1(greeting: String): String + hello2(greeting: String): String +} +``` + +### TypeScript + +```ts +import { GraphQLSchema, GraphQLObjectType, GraphQLString } from "graphql"; +export function getSchema(): GraphQLSchema { + const SomeTypeType: GraphQLObjectType = new GraphQLObjectType({ + name: "SomeType", + fields() { + return { + hello1: { + name: "hello1", + type: GraphQLString, + args: { + greeting: { + type: GraphQLString + } + } + }, + hello2: { + name: "hello2", + type: GraphQLString, + args: { + greeting: { + type: GraphQLString + } + } + } + }; + } + }); + return new GraphQLSchema({ + types: [SomeTypeType] + }); +} +``` \ No newline at end of file diff --git a/src/tests/fixtures/arguments/ObjectLiteralArgument.invalid.ts.expected b/src/tests/fixtures/arguments/ObjectLiteralArgument.invalid.ts.expected deleted file mode 100644 index 78785529..00000000 --- a/src/tests/fixtures/arguments/ObjectLiteralArgument.invalid.ts.expected +++ /dev/null @@ -1,18 +0,0 @@ ------------------ -INPUT ------------------ -/** @gqlType */ -export default class SomeType { - /** @gqlField */ - hello({ greeting }: { greeting: { foo: string; bar: string } }): string { - return "Hello world!"; - } -} - ------------------ -OUTPUT ------------------ -src/tests/fixtures/arguments/ObjectLiteralArgument.invalid.ts:4:35 - error: Unexpected type literal. Grats expects types in GraphQL positions to be scalar types, or reference a named GraphQL type directly. You may want to define a named GraphQL type elsewhere and reference it here. - -4 hello({ greeting }: { greeting: { foo: string; bar: string } }): string { - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/src/tests/fixtures/arguments/ObjectLiteralArgument.invalid.ts.expected.md b/src/tests/fixtures/arguments/ObjectLiteralArgument.invalid.ts.expected.md new file mode 100644 index 00000000..b1509d50 --- /dev/null +++ b/src/tests/fixtures/arguments/ObjectLiteralArgument.invalid.ts.expected.md @@ -0,0 +1,22 @@ +## input + +```ts title="arguments/ObjectLiteralArgument.invalid.ts" +/** @gqlType */ +export default class SomeType { + /** @gqlField */ + hello({ greeting }: { greeting: { foo: string; bar: string } }): string { + return "Hello world!"; + } +} +``` + +## Output + +### Error Report + +```text +src/tests/fixtures/arguments/ObjectLiteralArgument.invalid.ts:4:35 - error: Unexpected type literal. Grats expects types in GraphQL positions to be scalar types, or reference a named GraphQL type directly. You may want to define a named GraphQL type elsewhere and reference it here. + +4 hello({ greeting }: { greeting: { foo: string; bar: string } }): string { + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` \ No newline at end of file diff --git a/src/tests/fixtures/arguments/OpaqueArgType.invalid.ts.expected b/src/tests/fixtures/arguments/OpaqueArgType.invalid.ts.expected deleted file mode 100644 index f6b73905..00000000 --- a/src/tests/fixtures/arguments/OpaqueArgType.invalid.ts.expected +++ /dev/null @@ -1,20 +0,0 @@ ------------------ -INPUT ------------------ -type SomeType = any; - -/** @gqlType */ -export default class SomeType { - /** @gqlField */ - hello({ greeting }: SomeType): string { - return "Hello world!"; - } -} - ------------------ -OUTPUT ------------------ -src/tests/fixtures/arguments/OpaqueArgType.invalid.ts:6:23 - error: Unable to resolve type reference. In order to generate a GraphQL schema, Grats needs to determine which GraphQL type is being referenced. This requires being able to resolve type references to their `@gql` annotated declaration. However this reference could not be resolved. Is it possible that this type is not defined in this file? - -6 hello({ greeting }: SomeType): string { - ~~~~~~~~ diff --git a/src/tests/fixtures/arguments/OpaqueArgType.invalid.ts.expected.md b/src/tests/fixtures/arguments/OpaqueArgType.invalid.ts.expected.md new file mode 100644 index 00000000..ab9e3b51 --- /dev/null +++ b/src/tests/fixtures/arguments/OpaqueArgType.invalid.ts.expected.md @@ -0,0 +1,24 @@ +## input + +```ts title="arguments/OpaqueArgType.invalid.ts" +type SomeType = any; + +/** @gqlType */ +export default class SomeType { + /** @gqlField */ + hello({ greeting }: SomeType): string { + return "Hello world!"; + } +} +``` + +## Output + +### Error Report + +```text +src/tests/fixtures/arguments/OpaqueArgType.invalid.ts:6:23 - error: Unable to resolve type reference. In order to generate a GraphQL schema, Grats needs to determine which GraphQL type is being referenced. This requires being able to resolve type references to their `@gql` annotated declaration. However this reference could not be resolved. Is it possible that this type is not defined in this file? + +6 hello({ greeting }: SomeType): string { + ~~~~~~~~ +``` \ No newline at end of file diff --git a/src/tests/fixtures/arguments/OptionalArgument.ts.expected b/src/tests/fixtures/arguments/OptionalArgument.ts.expected deleted file mode 100644 index fdbe2165..00000000 --- a/src/tests/fixtures/arguments/OptionalArgument.ts.expected +++ /dev/null @@ -1,41 +0,0 @@ ------------------ -INPUT ------------------ -/** @gqlType */ -export default class SomeType { - /** @gqlField */ - hello({ greeting }: { greeting?: string | null }): string { - return `${greeting ?? "Hello"} World!`; - } -} - ------------------ -OUTPUT ------------------ --- SDL -- -type SomeType { - hello(greeting: String): String -} --- TypeScript -- -import { GraphQLSchema, GraphQLObjectType, GraphQLString } from "graphql"; -export function getSchema(): GraphQLSchema { - const SomeTypeType: GraphQLObjectType = new GraphQLObjectType({ - name: "SomeType", - fields() { - return { - hello: { - name: "hello", - type: GraphQLString, - args: { - greeting: { - type: GraphQLString - } - } - } - }; - } - }); - return new GraphQLSchema({ - types: [SomeTypeType] - }); -} diff --git a/src/tests/fixtures/arguments/OptionalArgument.ts.expected.md b/src/tests/fixtures/arguments/OptionalArgument.ts.expected.md new file mode 100644 index 00000000..e6b7fa77 --- /dev/null +++ b/src/tests/fixtures/arguments/OptionalArgument.ts.expected.md @@ -0,0 +1,48 @@ +## input + +```ts title="arguments/OptionalArgument.ts" +/** @gqlType */ +export default class SomeType { + /** @gqlField */ + hello({ greeting }: { greeting?: string | null }): string { + return `${greeting ?? "Hello"} World!`; + } +} +``` + +## Output + +### SDL + +```graphql +type SomeType { + hello(greeting: String): String +} +``` + +### TypeScript + +```ts +import { GraphQLSchema, GraphQLObjectType, GraphQLString } from "graphql"; +export function getSchema(): GraphQLSchema { + const SomeTypeType: GraphQLObjectType = new GraphQLObjectType({ + name: "SomeType", + fields() { + return { + hello: { + name: "hello", + type: GraphQLString, + args: { + greeting: { + type: GraphQLString + } + } + } + }; + } + }); + return new GraphQLSchema({ + types: [SomeTypeType] + }); +} +``` \ No newline at end of file diff --git a/src/tests/fixtures/arguments/OptionalNonNullableArgument.invalid.ts.expected b/src/tests/fixtures/arguments/OptionalNonNullableArgument.invalid.ts.expected deleted file mode 100644 index cd7ef7a2..00000000 --- a/src/tests/fixtures/arguments/OptionalNonNullableArgument.invalid.ts.expected +++ /dev/null @@ -1,42 +0,0 @@ ------------------ -INPUT ------------------ -/** @gqlType */ -export default class SomeType { - /** @gqlField */ - hello({ greeting }: { greeting?: string }): string { - return `${greeting ?? "Hello"} World!`; - } -} - ------------------ -OUTPUT ------------------ --- Error Report -- -src/tests/fixtures/arguments/OptionalNonNullableArgument.invalid.ts:4:33 - error: Unexpected optional argument that does not also accept `null`. Optional arguments in GraphQL may get passed an explicit `null` value by the GraphQL executor. This means optional arguments must be typed to also accept `null`. Consider adding `| null` to the end of the argument type. - -4 hello({ greeting }: { greeting?: string }): string { - ~ - - --- Code Action: "Add '| null' to the type" (add-null-to-optional-type) -- -- Original -+ Fixed - -@@ -3,3 +3,3 @@ - /** @gqlField */ -- hello({ greeting }: { greeting?: string }): string { -+ hello({ greeting }: { greeting?: string | null }): string { - return `${greeting ?? "Hello"} World!`; - --- Applied Fixes -- - * Applied fix "Add '| null' to the type" in grats/src/tests/fixtures/arguments/OptionalNonNullableArgument.invalid.ts - --- Fixed Text -- -/** @gqlType */ -export default class SomeType { - /** @gqlField */ - hello({ greeting }: { greeting?: string | null }): string { - return `${greeting ?? "Hello"} World!`; - } -} diff --git a/src/tests/fixtures/arguments/OptionalNonNullableArgument.invalid.ts.expected.md b/src/tests/fixtures/arguments/OptionalNonNullableArgument.invalid.ts.expected.md new file mode 100644 index 00000000..786e8868 --- /dev/null +++ b/src/tests/fixtures/arguments/OptionalNonNullableArgument.invalid.ts.expected.md @@ -0,0 +1,53 @@ +## input + +```ts title="arguments/OptionalNonNullableArgument.invalid.ts" +/** @gqlType */ +export default class SomeType { + /** @gqlField */ + hello({ greeting }: { greeting?: string }): string { + return `${greeting ?? "Hello"} World!`; + } +} +``` + +## Output + +### Error Report + +```text +src/tests/fixtures/arguments/OptionalNonNullableArgument.invalid.ts:4:33 - error: Unexpected optional argument that does not also accept `null`. Optional arguments in GraphQL may get passed an explicit `null` value by the GraphQL executor. This means optional arguments must be typed to also accept `null`. Consider adding `| null` to the end of the argument type. + +4 hello({ greeting }: { greeting?: string }): string { + ~ +``` + +#### Code Action: "Add '| null' to the type" (add-null-to-optional-type) + +```diff +- Original ++ Fixed + +@@ -3,3 +3,3 @@ + /** @gqlField */ +- hello({ greeting }: { greeting?: string }): string { ++ hello({ greeting }: { greeting?: string | null }): string { + return `${greeting ?? "Hello"} World!`; +``` + +#### Applied Fixes + +```text + * Applied fix "Add '| null' to the type" in grats/src/tests/fixtures/arguments/OptionalNonNullableArgument.invalid.ts +``` + +#### Fixed Text + +```typescript +/** @gqlType */ +export default class SomeType { + /** @gqlField */ + hello({ greeting }: { greeting?: string | null }): string { + return `${greeting ?? "Hello"} World!`; + } +} +``` \ No newline at end of file diff --git a/src/tests/fixtures/arguments/OptionalNonNullableArgumentWithDefault.ts.expected b/src/tests/fixtures/arguments/OptionalNonNullableArgumentWithDefault.ts.expected deleted file mode 100644 index aba02ae1..00000000 --- a/src/tests/fixtures/arguments/OptionalNonNullableArgumentWithDefault.ts.expected +++ /dev/null @@ -1,42 +0,0 @@ ------------------ -INPUT ------------------ -/** @gqlType */ -export default class SomeType { - /** @gqlField */ - hello({ greeting = "Hello" }: { greeting?: string }): string { - return `${greeting ?? "Hello"} World!`; - } -} - ------------------ -OUTPUT ------------------ --- SDL -- -type SomeType { - hello(greeting: String! = "Hello"): String -} --- TypeScript -- -import { GraphQLSchema, GraphQLObjectType, GraphQLString, GraphQLNonNull } from "graphql"; -export function getSchema(): GraphQLSchema { - const SomeTypeType: GraphQLObjectType = new GraphQLObjectType({ - name: "SomeType", - fields() { - return { - hello: { - name: "hello", - type: GraphQLString, - args: { - greeting: { - type: new GraphQLNonNull(GraphQLString), - defaultValue: "Hello" - } - } - } - }; - } - }); - return new GraphQLSchema({ - types: [SomeTypeType] - }); -} diff --git a/src/tests/fixtures/arguments/OptionalNonNullableArgumentWithDefault.ts.expected.md b/src/tests/fixtures/arguments/OptionalNonNullableArgumentWithDefault.ts.expected.md new file mode 100644 index 00000000..581d1d69 --- /dev/null +++ b/src/tests/fixtures/arguments/OptionalNonNullableArgumentWithDefault.ts.expected.md @@ -0,0 +1,49 @@ +## input + +```ts title="arguments/OptionalNonNullableArgumentWithDefault.ts" +/** @gqlType */ +export default class SomeType { + /** @gqlField */ + hello({ greeting = "Hello" }: { greeting?: string }): string { + return `${greeting ?? "Hello"} World!`; + } +} +``` + +## Output + +### SDL + +```graphql +type SomeType { + hello(greeting: String! = "Hello"): String +} +``` + +### TypeScript + +```ts +import { GraphQLSchema, GraphQLObjectType, GraphQLString, GraphQLNonNull } from "graphql"; +export function getSchema(): GraphQLSchema { + const SomeTypeType: GraphQLObjectType = new GraphQLObjectType({ + name: "SomeType", + fields() { + return { + hello: { + name: "hello", + type: GraphQLString, + args: { + greeting: { + type: new GraphQLNonNull(GraphQLString), + defaultValue: "Hello" + } + } + } + }; + } + }); + return new GraphQLSchema({ + types: [SomeTypeType] + }); +} +``` \ No newline at end of file diff --git a/src/tests/fixtures/arguments/PositionalArgAndArgs.invalid.ts.expected b/src/tests/fixtures/arguments/PositionalArgAndArgs.invalid.ts.expected deleted file mode 100644 index cd2cb114..00000000 --- a/src/tests/fixtures/arguments/PositionalArgAndArgs.invalid.ts.expected +++ /dev/null @@ -1,29 +0,0 @@ ------------------ -INPUT ------------------ -/** @gqlInput */ -type Greeting = { - name: string; - salutation: string; -}; - -/** @gqlType */ -export default class SomeType { - /** @gqlField */ - hello(greeting: Greeting, args: { notGreeting: string }): string { - return `${greeting.salutation} ${greeting.name} ${args.notGreeting}!`; - } -} - ------------------ -OUTPUT ------------------ -src/tests/fixtures/arguments/PositionalArgAndArgs.invalid.ts:10:29 - error: Unexpected arguments object in resolver that is also using positional GraphQL arguments. Grats expects that either all GraphQL arguments will be defined in a single object, or that all GraphQL arguments will be defined using positional arguments. The two strategies may not be combined. - -10 hello(greeting: Greeting, args: { notGreeting: string }): string { - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - - src/tests/fixtures/arguments/PositionalArgAndArgs.invalid.ts:10:9 - 10 hello(greeting: Greeting, args: { notGreeting: string }): string { - ~~~~~~~~~~~~~~~~~~ - Positional GraphQL argument defined here diff --git a/src/tests/fixtures/arguments/PositionalArgAndArgs.invalid.ts.expected.md b/src/tests/fixtures/arguments/PositionalArgAndArgs.invalid.ts.expected.md new file mode 100644 index 00000000..c30b1b0c --- /dev/null +++ b/src/tests/fixtures/arguments/PositionalArgAndArgs.invalid.ts.expected.md @@ -0,0 +1,33 @@ +## input + +```ts title="arguments/PositionalArgAndArgs.invalid.ts" +/** @gqlInput */ +type Greeting = { + name: string; + salutation: string; +}; + +/** @gqlType */ +export default class SomeType { + /** @gqlField */ + hello(greeting: Greeting, args: { notGreeting: string }): string { + return `${greeting.salutation} ${greeting.name} ${args.notGreeting}!`; + } +} +``` + +## Output + +### Error Report + +```text +src/tests/fixtures/arguments/PositionalArgAndArgs.invalid.ts:10:29 - error: Unexpected arguments object in resolver that is also using positional GraphQL arguments. Grats expects that either all GraphQL arguments will be defined in a single object, or that all GraphQL arguments will be defined using positional arguments. The two strategies may not be combined. + +10 hello(greeting: Greeting, args: { notGreeting: string }): string { + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + src/tests/fixtures/arguments/PositionalArgAndArgs.invalid.ts:10:9 + 10 hello(greeting: Greeting, args: { notGreeting: string }): string { + ~~~~~~~~~~~~~~~~~~ + Positional GraphQL argument defined here +``` \ No newline at end of file diff --git a/src/tests/fixtures/arguments/PositionalArgDeprecatedOptional.ts.expected b/src/tests/fixtures/arguments/PositionalArgDeprecatedOptional.ts.expected deleted file mode 100644 index b127fda2..00000000 --- a/src/tests/fixtures/arguments/PositionalArgDeprecatedOptional.ts.expected +++ /dev/null @@ -1,74 +0,0 @@ ------------------ -INPUT ------------------ -/** @gqlInput */ -type Greeting = { - name: string; - salutation: string; -}; - -/** @gqlType */ -export default class SomeType { - /** @gqlField */ - hello( - /** @deprecated Unused! */ - greeting?: Greeting | null, - ): string { - return `Hullo`; - } -} - ------------------ -OUTPUT ------------------ --- SDL -- -input Greeting { - name: String! - salutation: String! -} - -type SomeType { - hello(greeting: Greeting @deprecated(reason: "Unused!")): String -} --- TypeScript -- -import { GraphQLSchema, GraphQLInputObjectType, GraphQLNonNull, GraphQLString, GraphQLObjectType } from "graphql"; -export function getSchema(): GraphQLSchema { - const GreetingType: GraphQLInputObjectType = new GraphQLInputObjectType({ - name: "Greeting", - fields() { - return { - name: { - name: "name", - type: new GraphQLNonNull(GraphQLString) - }, - salutation: { - name: "salutation", - type: new GraphQLNonNull(GraphQLString) - } - }; - } - }); - const SomeTypeType: GraphQLObjectType = new GraphQLObjectType({ - name: "SomeType", - fields() { - return { - hello: { - name: "hello", - type: GraphQLString, - args: { - greeting: { - deprecationReason: "Unused!", - type: GreetingType - } - }, - resolve(source, args) { - return source.hello(args.greeting); - } - } - }; - } - }); - return new GraphQLSchema({ - types: [GreetingType, SomeTypeType] - }); -} diff --git a/src/tests/fixtures/arguments/PositionalArgDeprecatedOptional.ts.expected.md b/src/tests/fixtures/arguments/PositionalArgDeprecatedOptional.ts.expected.md new file mode 100644 index 00000000..56894526 --- /dev/null +++ b/src/tests/fixtures/arguments/PositionalArgDeprecatedOptional.ts.expected.md @@ -0,0 +1,81 @@ +## input + +```ts title="arguments/PositionalArgDeprecatedOptional.ts" +/** @gqlInput */ +type Greeting = { + name: string; + salutation: string; +}; + +/** @gqlType */ +export default class SomeType { + /** @gqlField */ + hello( + /** @deprecated Unused! */ + greeting?: Greeting | null, + ): string { + return `Hullo`; + } +} +``` + +## Output + +### SDL + +```graphql +input Greeting { + name: String! + salutation: String! +} + +type SomeType { + hello(greeting: Greeting @deprecated(reason: "Unused!")): String +} +``` + +### TypeScript + +```ts +import { GraphQLSchema, GraphQLInputObjectType, GraphQLNonNull, GraphQLString, GraphQLObjectType } from "graphql"; +export function getSchema(): GraphQLSchema { + const GreetingType: GraphQLInputObjectType = new GraphQLInputObjectType({ + name: "Greeting", + fields() { + return { + name: { + name: "name", + type: new GraphQLNonNull(GraphQLString) + }, + salutation: { + name: "salutation", + type: new GraphQLNonNull(GraphQLString) + } + }; + } + }); + const SomeTypeType: GraphQLObjectType = new GraphQLObjectType({ + name: "SomeType", + fields() { + return { + hello: { + name: "hello", + type: GraphQLString, + args: { + greeting: { + deprecationReason: "Unused!", + type: GreetingType + } + }, + resolve(source, args) { + return source.hello(args.greeting); + } + } + }; + } + }); + return new GraphQLSchema({ + types: [GreetingType, SomeTypeType] + }); +} +``` \ No newline at end of file diff --git a/src/tests/fixtures/arguments/PositionalArgDeprecatedWithDefault.ts.expected b/src/tests/fixtures/arguments/PositionalArgDeprecatedWithDefault.ts.expected deleted file mode 100644 index b0c058c1..00000000 --- a/src/tests/fixtures/arguments/PositionalArgDeprecatedWithDefault.ts.expected +++ /dev/null @@ -1,78 +0,0 @@ ------------------ -INPUT ------------------ -/** @gqlInput */ -type Greeting = { - name: string; - salutation: string; -}; - -/** @gqlType */ -export default class SomeType { - /** @gqlField */ - hello( - /** @deprecated Unused! */ - greeting: Greeting = { name: "Alice", salutation: "Hullo" }, - ): string { - return `Hullo`; - } -} - ------------------ -OUTPUT ------------------ --- SDL -- -input Greeting { - name: String! - salutation: String! -} - -type SomeType { - hello(greeting: Greeting! = {name: "Alice", salutation: "Hullo"} @deprecated(reason: "Unused!")): String -} --- TypeScript -- -import { GraphQLSchema, GraphQLInputObjectType, GraphQLNonNull, GraphQLString, GraphQLObjectType } from "graphql"; -export function getSchema(): GraphQLSchema { - const GreetingType: GraphQLInputObjectType = new GraphQLInputObjectType({ - name: "Greeting", - fields() { - return { - name: { - name: "name", - type: new GraphQLNonNull(GraphQLString) - }, - salutation: { - name: "salutation", - type: new GraphQLNonNull(GraphQLString) - } - }; - } - }); - const SomeTypeType: GraphQLObjectType = new GraphQLObjectType({ - name: "SomeType", - fields() { - return { - hello: { - name: "hello", - type: GraphQLString, - args: { - greeting: { - deprecationReason: "Unused!", - type: new GraphQLNonNull(GreetingType), - defaultValue: { - name: "Alice", - salutation: "Hullo" - } - } - }, - resolve(source, args) { - return source.hello(args.greeting); - } - } - }; - } - }); - return new GraphQLSchema({ - types: [GreetingType, SomeTypeType] - }); -} diff --git a/src/tests/fixtures/arguments/PositionalArgDeprecatedWithDefault.ts.expected.md b/src/tests/fixtures/arguments/PositionalArgDeprecatedWithDefault.ts.expected.md new file mode 100644 index 00000000..54281cc1 --- /dev/null +++ b/src/tests/fixtures/arguments/PositionalArgDeprecatedWithDefault.ts.expected.md @@ -0,0 +1,85 @@ +## input + +```ts title="arguments/PositionalArgDeprecatedWithDefault.ts" +/** @gqlInput */ +type Greeting = { + name: string; + salutation: string; +}; + +/** @gqlType */ +export default class SomeType { + /** @gqlField */ + hello( + /** @deprecated Unused! */ + greeting: Greeting = { name: "Alice", salutation: "Hullo" }, + ): string { + return `Hullo`; + } +} +``` + +## Output + +### SDL + +```graphql +input Greeting { + name: String! + salutation: String! +} + +type SomeType { + hello(greeting: Greeting! = {name: "Alice", salutation: "Hullo"} @deprecated(reason: "Unused!")): String +} +``` + +### TypeScript + +```ts +import { GraphQLSchema, GraphQLInputObjectType, GraphQLNonNull, GraphQLString, GraphQLObjectType } from "graphql"; +export function getSchema(): GraphQLSchema { + const GreetingType: GraphQLInputObjectType = new GraphQLInputObjectType({ + name: "Greeting", + fields() { + return { + name: { + name: "name", + type: new GraphQLNonNull(GraphQLString) + }, + salutation: { + name: "salutation", + type: new GraphQLNonNull(GraphQLString) + } + }; + } + }); + const SomeTypeType: GraphQLObjectType = new GraphQLObjectType({ + name: "SomeType", + fields() { + return { + hello: { + name: "hello", + type: GraphQLString, + args: { + greeting: { + deprecationReason: "Unused!", + type: new GraphQLNonNull(GreetingType), + defaultValue: { + name: "Alice", + salutation: "Hullo" + } + } + }, + resolve(source, args) { + return source.hello(args.greeting); + } + } + }; + } + }); + return new GraphQLSchema({ + types: [GreetingType, SomeTypeType] + }); +} +``` \ No newline at end of file diff --git a/src/tests/fixtures/arguments/PositionalArgOptional.ts.expected b/src/tests/fixtures/arguments/PositionalArgOptional.ts.expected deleted file mode 100644 index 59c0b855..00000000 --- a/src/tests/fixtures/arguments/PositionalArgOptional.ts.expected +++ /dev/null @@ -1,70 +0,0 @@ ------------------ -INPUT ------------------ -/** @gqlInput */ -type Greeting = { - name: string; - salutation: string; -}; - -/** @gqlType */ -export default class SomeType { - /** @gqlField */ - hello(greeting?: string | null): string { - return `${greeting ?? "Hello"} World`; - } -} - ------------------ -OUTPUT ------------------ --- SDL -- -input Greeting { - name: String! - salutation: String! -} - -type SomeType { - hello(greeting: String): String -} --- TypeScript -- -import { GraphQLSchema, GraphQLInputObjectType, GraphQLNonNull, GraphQLString, GraphQLObjectType } from "graphql"; -export function getSchema(): GraphQLSchema { - const GreetingType: GraphQLInputObjectType = new GraphQLInputObjectType({ - name: "Greeting", - fields() { - return { - name: { - name: "name", - type: new GraphQLNonNull(GraphQLString) - }, - salutation: { - name: "salutation", - type: new GraphQLNonNull(GraphQLString) - } - }; - } - }); - const SomeTypeType: GraphQLObjectType = new GraphQLObjectType({ - name: "SomeType", - fields() { - return { - hello: { - name: "hello", - type: GraphQLString, - args: { - greeting: { - type: GraphQLString - } - }, - resolve(source, args) { - return source.hello(args.greeting); - } - } - }; - } - }); - return new GraphQLSchema({ - types: [GreetingType, SomeTypeType] - }); -} diff --git a/src/tests/fixtures/arguments/PositionalArgOptional.ts.expected.md b/src/tests/fixtures/arguments/PositionalArgOptional.ts.expected.md new file mode 100644 index 00000000..af68649b --- /dev/null +++ b/src/tests/fixtures/arguments/PositionalArgOptional.ts.expected.md @@ -0,0 +1,77 @@ +## input + +```ts title="arguments/PositionalArgOptional.ts" +/** @gqlInput */ +type Greeting = { + name: string; + salutation: string; +}; + +/** @gqlType */ +export default class SomeType { + /** @gqlField */ + hello(greeting?: string | null): string { + return `${greeting ?? "Hello"} World`; + } +} +``` + +## Output + +### SDL + +```graphql +input Greeting { + name: String! + salutation: String! +} + +type SomeType { + hello(greeting: String): String +} +``` + +### TypeScript + +```ts +import { GraphQLSchema, GraphQLInputObjectType, GraphQLNonNull, GraphQLString, GraphQLObjectType } from "graphql"; +export function getSchema(): GraphQLSchema { + const GreetingType: GraphQLInputObjectType = new GraphQLInputObjectType({ + name: "Greeting", + fields() { + return { + name: { + name: "name", + type: new GraphQLNonNull(GraphQLString) + }, + salutation: { + name: "salutation", + type: new GraphQLNonNull(GraphQLString) + } + }; + } + }); + const SomeTypeType: GraphQLObjectType = new GraphQLObjectType({ + name: "SomeType", + fields() { + return { + hello: { + name: "hello", + type: GraphQLString, + args: { + greeting: { + type: GraphQLString + } + }, + resolve(source, args) { + return source.hello(args.greeting); + } + } + }; + } + }); + return new GraphQLSchema({ + types: [GreetingType, SomeTypeType] + }); +} +``` \ No newline at end of file diff --git a/src/tests/fixtures/arguments/PositionalArgOptionalNotNullable.invalid.ts.expected b/src/tests/fixtures/arguments/PositionalArgOptionalNotNullable.invalid.ts.expected deleted file mode 100644 index e776ccc8..00000000 --- a/src/tests/fixtures/arguments/PositionalArgOptionalNotNullable.invalid.ts.expected +++ /dev/null @@ -1,54 +0,0 @@ ------------------ -INPUT ------------------ -/** @gqlInput */ -type Greeting = { - name: string; - salutation: string; -}; - -/** @gqlType */ -export default class SomeType { - /** @gqlField */ - hello(greeting?: string): string { - return `${greeting ?? "Hello"} World`; - } -} - ------------------ -OUTPUT ------------------ --- Error Report -- -src/tests/fixtures/arguments/PositionalArgOptionalNotNullable.invalid.ts:10:17 - error: Unexpected optional argument that does not also accept `null`. Optional arguments in GraphQL may get passed an explicit `null` value by the GraphQL executor. This means optional arguments must be typed to also accept `null`. Consider adding `| null` to the end of the argument type. - -10 hello(greeting?: string): string { - ~ - - --- Code Action: "Add '| null' to the parameter type" (add-null-to-optional-parameter-type) -- -- Original -+ Fixed - -@@ -9,3 +9,3 @@ - /** @gqlField */ -- hello(greeting?: string): string { -+ hello(greeting?: string | null): string { - return `${greeting ?? "Hello"} World`; - --- Applied Fixes -- - * Applied fix "Add '| null' to the parameter type" in grats/src/tests/fixtures/arguments/PositionalArgOptionalNotNullable.invalid.ts - --- Fixed Text -- -/** @gqlInput */ -type Greeting = { - name: string; - salutation: string; -}; - -/** @gqlType */ -export default class SomeType { - /** @gqlField */ - hello(greeting?: string | null): string { - return `${greeting ?? "Hello"} World`; - } -} diff --git a/src/tests/fixtures/arguments/PositionalArgOptionalNotNullable.invalid.ts.expected.md b/src/tests/fixtures/arguments/PositionalArgOptionalNotNullable.invalid.ts.expected.md new file mode 100644 index 00000000..be0221c0 --- /dev/null +++ b/src/tests/fixtures/arguments/PositionalArgOptionalNotNullable.invalid.ts.expected.md @@ -0,0 +1,65 @@ +## input + +```ts title="arguments/PositionalArgOptionalNotNullable.invalid.ts" +/** @gqlInput */ +type Greeting = { + name: string; + salutation: string; +}; + +/** @gqlType */ +export default class SomeType { + /** @gqlField */ + hello(greeting?: string): string { + return `${greeting ?? "Hello"} World`; + } +} +``` + +## Output + +### Error Report + +```text +src/tests/fixtures/arguments/PositionalArgOptionalNotNullable.invalid.ts:10:17 - error: Unexpected optional argument that does not also accept `null`. Optional arguments in GraphQL may get passed an explicit `null` value by the GraphQL executor. This means optional arguments must be typed to also accept `null`. Consider adding `| null` to the end of the argument type. + +10 hello(greeting?: string): string { + ~ +``` + +#### Code Action: "Add '| null' to the parameter type" (add-null-to-optional-parameter-type) + +```diff +- Original ++ Fixed + +@@ -9,3 +9,3 @@ + /** @gqlField */ +- hello(greeting?: string): string { ++ hello(greeting?: string | null): string { + return `${greeting ?? "Hello"} World`; +``` + +#### Applied Fixes + +```text + * Applied fix "Add '| null' to the parameter type" in grats/src/tests/fixtures/arguments/PositionalArgOptionalNotNullable.invalid.ts +``` + +#### Fixed Text + +```typescript +/** @gqlInput */ +type Greeting = { + name: string; + salutation: string; +}; + +/** @gqlType */ +export default class SomeType { + /** @gqlField */ + hello(greeting?: string | null): string { + return `${greeting ?? "Hello"} World`; + } +} +``` \ No newline at end of file diff --git a/src/tests/fixtures/arguments/PositionalArgWithDefault.ts.expected b/src/tests/fixtures/arguments/PositionalArgWithDefault.ts.expected deleted file mode 100644 index e1009fd7..00000000 --- a/src/tests/fixtures/arguments/PositionalArgWithDefault.ts.expected +++ /dev/null @@ -1,45 +0,0 @@ ------------------ -INPUT ------------------ -/** @gqlType */ -export default class SomeType { - /** @gqlField */ - hello(greeting: string = "Hello"): string { - return `${greeting} World`; - } -} - ------------------ -OUTPUT ------------------ --- SDL -- -type SomeType { - hello(greeting: String! = "Hello"): String -} --- TypeScript -- -import { GraphQLSchema, GraphQLObjectType, GraphQLString, GraphQLNonNull } from "graphql"; -export function getSchema(): GraphQLSchema { - const SomeTypeType: GraphQLObjectType = new GraphQLObjectType({ - name: "SomeType", - fields() { - return { - hello: { - name: "hello", - type: GraphQLString, - args: { - greeting: { - type: new GraphQLNonNull(GraphQLString), - defaultValue: "Hello" - } - }, - resolve(source, args) { - return source.hello(args.greeting); - } - } - }; - } - }); - return new GraphQLSchema({ - types: [SomeTypeType] - }); -} diff --git a/src/tests/fixtures/arguments/PositionalArgWithDefault.ts.expected.md b/src/tests/fixtures/arguments/PositionalArgWithDefault.ts.expected.md new file mode 100644 index 00000000..267e2bf2 --- /dev/null +++ b/src/tests/fixtures/arguments/PositionalArgWithDefault.ts.expected.md @@ -0,0 +1,52 @@ +## input + +```ts title="arguments/PositionalArgWithDefault.ts" +/** @gqlType */ +export default class SomeType { + /** @gqlField */ + hello(greeting: string = "Hello"): string { + return `${greeting} World`; + } +} +``` + +## Output + +### SDL + +```graphql +type SomeType { + hello(greeting: String! = "Hello"): String +} +``` + +### TypeScript + +```ts +import { GraphQLSchema, GraphQLObjectType, GraphQLString, GraphQLNonNull } from "graphql"; +export function getSchema(): GraphQLSchema { + const SomeTypeType: GraphQLObjectType = new GraphQLObjectType({ + name: "SomeType", + fields() { + return { + hello: { + name: "hello", + type: GraphQLString, + args: { + greeting: { + type: new GraphQLNonNull(GraphQLString), + defaultValue: "Hello" + } + }, + resolve(source, args) { + return source.hello(args.greeting); + } + } + }; + } + }); + return new GraphQLSchema({ + types: [SomeTypeType] + }); +} +``` \ No newline at end of file diff --git a/src/tests/fixtures/arguments/PositionalArgWithDescription.ts.expected b/src/tests/fixtures/arguments/PositionalArgWithDescription.ts.expected deleted file mode 100644 index 44182b83..00000000 --- a/src/tests/fixtures/arguments/PositionalArgWithDescription.ts.expected +++ /dev/null @@ -1,77 +0,0 @@ ------------------ -INPUT ------------------ -/** @gqlInput */ -type Greeting = { - name: string; - salutation: string; -}; - -/** @gqlType */ -export default class SomeType { - /** @gqlField */ - hello( - /** How to greet the user */ - greeting: Greeting, - ): string { - return `${greeting.salutation} ${greeting.name}!`; - } -} - ------------------ -OUTPUT ------------------ --- SDL -- -input Greeting { - name: String! - salutation: String! -} - -type SomeType { - hello( - """How to greet the user""" - greeting: Greeting! - ): String -} --- TypeScript -- -import { GraphQLSchema, GraphQLInputObjectType, GraphQLNonNull, GraphQLString, GraphQLObjectType } from "graphql"; -export function getSchema(): GraphQLSchema { - const GreetingType: GraphQLInputObjectType = new GraphQLInputObjectType({ - name: "Greeting", - fields() { - return { - name: { - name: "name", - type: new GraphQLNonNull(GraphQLString) - }, - salutation: { - name: "salutation", - type: new GraphQLNonNull(GraphQLString) - } - }; - } - }); - const SomeTypeType: GraphQLObjectType = new GraphQLObjectType({ - name: "SomeType", - fields() { - return { - hello: { - name: "hello", - type: GraphQLString, - args: { - greeting: { - description: "How to greet the user", - type: new GraphQLNonNull(GreetingType) - } - }, - resolve(source, args) { - return source.hello(args.greeting); - } - } - }; - } - }); - return new GraphQLSchema({ - types: [GreetingType, SomeTypeType] - }); -} diff --git a/src/tests/fixtures/arguments/PositionalArgWithDescription.ts.expected.md b/src/tests/fixtures/arguments/PositionalArgWithDescription.ts.expected.md new file mode 100644 index 00000000..ebf4211b --- /dev/null +++ b/src/tests/fixtures/arguments/PositionalArgWithDescription.ts.expected.md @@ -0,0 +1,84 @@ +## input + +```ts title="arguments/PositionalArgWithDescription.ts" +/** @gqlInput */ +type Greeting = { + name: string; + salutation: string; +}; + +/** @gqlType */ +export default class SomeType { + /** @gqlField */ + hello( + /** How to greet the user */ + greeting: Greeting, + ): string { + return `${greeting.salutation} ${greeting.name}!`; + } +} +``` + +## Output + +### SDL + +```graphql +input Greeting { + name: String! + salutation: String! +} + +type SomeType { + hello( + """How to greet the user""" + greeting: Greeting! + ): String +} +``` + +### TypeScript + +```ts +import { GraphQLSchema, GraphQLInputObjectType, GraphQLNonNull, GraphQLString, GraphQLObjectType } from "graphql"; +export function getSchema(): GraphQLSchema { + const GreetingType: GraphQLInputObjectType = new GraphQLInputObjectType({ + name: "Greeting", + fields() { + return { + name: { + name: "name", + type: new GraphQLNonNull(GraphQLString) + }, + salutation: { + name: "salutation", + type: new GraphQLNonNull(GraphQLString) + } + }; + } + }); + const SomeTypeType: GraphQLObjectType = new GraphQLObjectType({ + name: "SomeType", + fields() { + return { + hello: { + name: "hello", + type: GraphQLString, + args: { + greeting: { + description: "How to greet the user", + type: new GraphQLNonNull(GreetingType) + } + }, + resolve(source, args) { + return source.hello(args.greeting); + } + } + }; + } + }); + return new GraphQLSchema({ + types: [GreetingType, SomeTypeType] + }); +} +``` \ No newline at end of file diff --git a/src/tests/fixtures/arguments/PromiseArgument.invalid.ts.expected b/src/tests/fixtures/arguments/PromiseArgument.invalid.ts.expected deleted file mode 100644 index 6abdbff9..00000000 --- a/src/tests/fixtures/arguments/PromiseArgument.invalid.ts.expected +++ /dev/null @@ -1,18 +0,0 @@ ------------------ -INPUT ------------------ -/** @gqlType */ -export default class SomeType { - /** @gqlField */ - hello(args: { greeting: Promise }): string { - return `${args.greeting} world!`; - } -} - ------------------ -OUTPUT ------------------ -src/tests/fixtures/arguments/PromiseArgument.invalid.ts:4:27 - error: `Promise` is not a valid as an input type. - -4 hello(args: { greeting: Promise }): string { - ~~~~~~~~~~~~~~~ diff --git a/src/tests/fixtures/arguments/PromiseArgument.invalid.ts.expected.md b/src/tests/fixtures/arguments/PromiseArgument.invalid.ts.expected.md new file mode 100644 index 00000000..722898f4 --- /dev/null +++ b/src/tests/fixtures/arguments/PromiseArgument.invalid.ts.expected.md @@ -0,0 +1,22 @@ +## input + +```ts title="arguments/PromiseArgument.invalid.ts" +/** @gqlType */ +export default class SomeType { + /** @gqlField */ + hello(args: { greeting: Promise }): string { + return `${args.greeting} world!`; + } +} +``` + +## Output + +### Error Report + +```text +src/tests/fixtures/arguments/PromiseArgument.invalid.ts:4:27 - error: `Promise` is not a valid as an input type. + +4 hello(args: { greeting: Promise }): string { + ~~~~~~~~~~~~~~~ +``` \ No newline at end of file diff --git a/src/tests/fixtures/arguments/StringArgument.ts.expected b/src/tests/fixtures/arguments/StringArgument.ts.expected deleted file mode 100644 index 72e3b046..00000000 --- a/src/tests/fixtures/arguments/StringArgument.ts.expected +++ /dev/null @@ -1,41 +0,0 @@ ------------------ -INPUT ------------------ -/** @gqlType */ -export default class SomeType { - /** @gqlField */ - hello({ greeting }: { greeting: string }): string { - return "Hello world!"; - } -} - ------------------ -OUTPUT ------------------ --- SDL -- -type SomeType { - hello(greeting: String!): String -} --- TypeScript -- -import { GraphQLSchema, GraphQLObjectType, GraphQLString, GraphQLNonNull } from "graphql"; -export function getSchema(): GraphQLSchema { - const SomeTypeType: GraphQLObjectType = new GraphQLObjectType({ - name: "SomeType", - fields() { - return { - hello: { - name: "hello", - type: GraphQLString, - args: { - greeting: { - type: new GraphQLNonNull(GraphQLString) - } - } - } - }; - } - }); - return new GraphQLSchema({ - types: [SomeTypeType] - }); -} diff --git a/src/tests/fixtures/arguments/StringArgument.ts.expected.md b/src/tests/fixtures/arguments/StringArgument.ts.expected.md new file mode 100644 index 00000000..0bc21cd9 --- /dev/null +++ b/src/tests/fixtures/arguments/StringArgument.ts.expected.md @@ -0,0 +1,48 @@ +## input + +```ts title="arguments/StringArgument.ts" +/** @gqlType */ +export default class SomeType { + /** @gqlField */ + hello({ greeting }: { greeting: string }): string { + return "Hello world!"; + } +} +``` + +## Output + +### SDL + +```graphql +type SomeType { + hello(greeting: String!): String +} +``` + +### TypeScript + +```ts +import { GraphQLSchema, GraphQLObjectType, GraphQLString, GraphQLNonNull } from "graphql"; +export function getSchema(): GraphQLSchema { + const SomeTypeType: GraphQLObjectType = new GraphQLObjectType({ + name: "SomeType", + fields() { + return { + hello: { + name: "hello", + type: GraphQLString, + args: { + greeting: { + type: new GraphQLNonNull(GraphQLString) + } + } + } + }; + } + }); + return new GraphQLSchema({ + types: [SomeTypeType] + }); +} +``` \ No newline at end of file diff --git a/src/tests/fixtures/arguments/TupleLiteralArgument.invalid.ts.expected b/src/tests/fixtures/arguments/TupleLiteralArgument.invalid.ts.expected deleted file mode 100644 index 4c330bd5..00000000 --- a/src/tests/fixtures/arguments/TupleLiteralArgument.invalid.ts.expected +++ /dev/null @@ -1,20 +0,0 @@ ------------------ -INPUT ------------------ -/** @gqlType */ -export default class SomeType { - /** @gqlField */ - hello({ greeting }: { greeting: [string] }): string { - return "Hello world!"; - } -} - ------------------ -OUTPUT ------------------ -src/tests/fixtures/arguments/TupleLiteralArgument.invalid.ts:4:35 - error: Unknown GraphQL type. Grats does not know how to map this type to a GraphQL type. You may want to define a named GraphQL type elsewhere and reference it here. If you think Grats should be able to infer a GraphQL type from this type, please file an issue. - -If you think Grats should be able to infer this type, please report an issue at https://github.com/captbaritone/grats/issues. - -4 hello({ greeting }: { greeting: [string] }): string { - ~~~~~~~~ diff --git a/src/tests/fixtures/arguments/TupleLiteralArgument.invalid.ts.expected.md b/src/tests/fixtures/arguments/TupleLiteralArgument.invalid.ts.expected.md new file mode 100644 index 00000000..c1b5bae9 --- /dev/null +++ b/src/tests/fixtures/arguments/TupleLiteralArgument.invalid.ts.expected.md @@ -0,0 +1,24 @@ +## input + +```ts title="arguments/TupleLiteralArgument.invalid.ts" +/** @gqlType */ +export default class SomeType { + /** @gqlField */ + hello({ greeting }: { greeting: [string] }): string { + return "Hello world!"; + } +} +``` + +## Output + +### Error Report + +```text +src/tests/fixtures/arguments/TupleLiteralArgument.invalid.ts:4:35 - error: Unknown GraphQL type. Grats does not know how to map this type to a GraphQL type. You may want to define a named GraphQL type elsewhere and reference it here. If you think Grats should be able to infer a GraphQL type from this type, please file an issue. + +If you think Grats should be able to infer this type, please report an issue at https://github.com/captbaritone/grats/issues. + +4 hello({ greeting }: { greeting: [string] }): string { + ~~~~~~~~ +``` \ No newline at end of file diff --git a/src/tests/fixtures/built_in_scalars/FloatField.ts.expected b/src/tests/fixtures/built_in_scalars/FloatField.ts.expected deleted file mode 100644 index dc6e8769..00000000 --- a/src/tests/fixtures/built_in_scalars/FloatField.ts.expected +++ /dev/null @@ -1,38 +0,0 @@ ------------------ -INPUT ------------------ -import { Float } from "../../../Types"; - -/** @gqlType */ -export default class SomeType { - /** @gqlField */ - ratio(): Float { - return 10; - } -} - ------------------ -OUTPUT ------------------ --- SDL -- -type SomeType { - ratio: Float -} --- TypeScript -- -import { GraphQLSchema, GraphQLObjectType, GraphQLFloat } from "graphql"; -export function getSchema(): GraphQLSchema { - const SomeTypeType: GraphQLObjectType = new GraphQLObjectType({ - name: "SomeType", - fields() { - return { - ratio: { - name: "ratio", - type: GraphQLFloat - } - }; - } - }); - return new GraphQLSchema({ - types: [SomeTypeType] - }); -} diff --git a/src/tests/fixtures/built_in_scalars/FloatField.ts.expected.md b/src/tests/fixtures/built_in_scalars/FloatField.ts.expected.md new file mode 100644 index 00000000..1a9166c1 --- /dev/null +++ b/src/tests/fixtures/built_in_scalars/FloatField.ts.expected.md @@ -0,0 +1,45 @@ +## input + +```ts title="built_in_scalars/FloatField.ts" +import { Float } from "../../../Types"; + +/** @gqlType */ +export default class SomeType { + /** @gqlField */ + ratio(): Float { + return 10; + } +} +``` + +## Output + +### SDL + +```graphql +type SomeType { + ratio: Float +} +``` + +### TypeScript + +```ts +import { GraphQLSchema, GraphQLObjectType, GraphQLFloat } from "graphql"; +export function getSchema(): GraphQLSchema { + const SomeTypeType: GraphQLObjectType = new GraphQLObjectType({ + name: "SomeType", + fields() { + return { + ratio: { + name: "ratio", + type: GraphQLFloat + } + }; + } + }); + return new GraphQLSchema({ + types: [SomeTypeType] + }); +} +``` \ No newline at end of file diff --git a/src/tests/fixtures/built_in_scalars/FloatFieldAliasedImport.ts.expected b/src/tests/fixtures/built_in_scalars/FloatFieldAliasedImport.ts.expected deleted file mode 100644 index de2d5463..00000000 --- a/src/tests/fixtures/built_in_scalars/FloatFieldAliasedImport.ts.expected +++ /dev/null @@ -1,38 +0,0 @@ ------------------ -INPUT ------------------ -import { Float as LocalFloat } from "../../../Types"; - -/** @gqlType */ -export default class SomeType { - /** @gqlField */ - ratio(): LocalFloat { - return 10; - } -} - ------------------ -OUTPUT ------------------ --- SDL -- -type SomeType { - ratio: Float -} --- TypeScript -- -import { GraphQLSchema, GraphQLObjectType, GraphQLFloat } from "graphql"; -export function getSchema(): GraphQLSchema { - const SomeTypeType: GraphQLObjectType = new GraphQLObjectType({ - name: "SomeType", - fields() { - return { - ratio: { - name: "ratio", - type: GraphQLFloat - } - }; - } - }); - return new GraphQLSchema({ - types: [SomeTypeType] - }); -} diff --git a/src/tests/fixtures/built_in_scalars/FloatFieldAliasedImport.ts.expected.md b/src/tests/fixtures/built_in_scalars/FloatFieldAliasedImport.ts.expected.md new file mode 100644 index 00000000..4823e9ce --- /dev/null +++ b/src/tests/fixtures/built_in_scalars/FloatFieldAliasedImport.ts.expected.md @@ -0,0 +1,45 @@ +## input + +```ts title="built_in_scalars/FloatFieldAliasedImport.ts" +import { Float as LocalFloat } from "../../../Types"; + +/** @gqlType */ +export default class SomeType { + /** @gqlField */ + ratio(): LocalFloat { + return 10; + } +} +``` + +## Output + +### SDL + +```graphql +type SomeType { + ratio: Float +} +``` + +### TypeScript + +```ts +import { GraphQLSchema, GraphQLObjectType, GraphQLFloat } from "graphql"; +export function getSchema(): GraphQLSchema { + const SomeTypeType: GraphQLObjectType = new GraphQLObjectType({ + name: "SomeType", + fields() { + return { + ratio: { + name: "ratio", + type: GraphQLFloat + } + }; + } + }); + return new GraphQLSchema({ + types: [SomeTypeType] + }); +} +``` \ No newline at end of file diff --git a/src/tests/fixtures/built_in_scalars/IdField.ts.expected b/src/tests/fixtures/built_in_scalars/IdField.ts.expected deleted file mode 100644 index 7ea3ec8c..00000000 --- a/src/tests/fixtures/built_in_scalars/IdField.ts.expected +++ /dev/null @@ -1,38 +0,0 @@ ------------------ -INPUT ------------------ -import { ID } from "../../../Types"; - -/** @gqlType */ -export default class SomeType { - /** @gqlField */ - id(): ID { - return "QUERY_ID"; - } -} - ------------------ -OUTPUT ------------------ --- SDL -- -type SomeType { - id: ID -} --- TypeScript -- -import { GraphQLSchema, GraphQLObjectType, GraphQLID } from "graphql"; -export function getSchema(): GraphQLSchema { - const SomeTypeType: GraphQLObjectType = new GraphQLObjectType({ - name: "SomeType", - fields() { - return { - id: { - name: "id", - type: GraphQLID - } - }; - } - }); - return new GraphQLSchema({ - types: [SomeTypeType] - }); -} diff --git a/src/tests/fixtures/built_in_scalars/IdField.ts.expected.md b/src/tests/fixtures/built_in_scalars/IdField.ts.expected.md new file mode 100644 index 00000000..c90ae9ca --- /dev/null +++ b/src/tests/fixtures/built_in_scalars/IdField.ts.expected.md @@ -0,0 +1,45 @@ +## input + +```ts title="built_in_scalars/IdField.ts" +import { ID } from "../../../Types"; + +/** @gqlType */ +export default class SomeType { + /** @gqlField */ + id(): ID { + return "QUERY_ID"; + } +} +``` + +## Output + +### SDL + +```graphql +type SomeType { + id: ID +} +``` + +### TypeScript + +```ts +import { GraphQLSchema, GraphQLObjectType, GraphQLID } from "graphql"; +export function getSchema(): GraphQLSchema { + const SomeTypeType: GraphQLObjectType = new GraphQLObjectType({ + name: "SomeType", + fields() { + return { + id: { + name: "id", + type: GraphQLID + } + }; + } + }); + return new GraphQLSchema({ + types: [SomeTypeType] + }); +} +``` \ No newline at end of file diff --git a/src/tests/fixtures/built_in_scalars/IntField.ts.expected b/src/tests/fixtures/built_in_scalars/IntField.ts.expected deleted file mode 100644 index aa597960..00000000 --- a/src/tests/fixtures/built_in_scalars/IntField.ts.expected +++ /dev/null @@ -1,38 +0,0 @@ ------------------ -INPUT ------------------ -import { Int } from "../../../Types"; - -/** @gqlType */ -export default class SomeType { - /** @gqlField */ - age(): Int { - return 10; - } -} - ------------------ -OUTPUT ------------------ --- SDL -- -type SomeType { - age: Int -} --- TypeScript -- -import { GraphQLSchema, GraphQLObjectType, GraphQLInt } from "graphql"; -export function getSchema(): GraphQLSchema { - const SomeTypeType: GraphQLObjectType = new GraphQLObjectType({ - name: "SomeType", - fields() { - return { - age: { - name: "age", - type: GraphQLInt - } - }; - } - }); - return new GraphQLSchema({ - types: [SomeTypeType] - }); -} diff --git a/src/tests/fixtures/built_in_scalars/IntField.ts.expected.md b/src/tests/fixtures/built_in_scalars/IntField.ts.expected.md new file mode 100644 index 00000000..7237f87d --- /dev/null +++ b/src/tests/fixtures/built_in_scalars/IntField.ts.expected.md @@ -0,0 +1,45 @@ +## input + +```ts title="built_in_scalars/IntField.ts" +import { Int } from "../../../Types"; + +/** @gqlType */ +export default class SomeType { + /** @gqlField */ + age(): Int { + return 10; + } +} +``` + +## Output + +### SDL + +```graphql +type SomeType { + age: Int +} +``` + +### TypeScript + +```ts +import { GraphQLSchema, GraphQLObjectType, GraphQLInt } from "graphql"; +export function getSchema(): GraphQLSchema { + const SomeTypeType: GraphQLObjectType = new GraphQLObjectType({ + name: "SomeType", + fields() { + return { + age: { + name: "age", + type: GraphQLInt + } + }; + } + }); + return new GraphQLSchema({ + types: [SomeTypeType] + }); +} +``` \ No newline at end of file diff --git a/src/tests/fixtures/comments/blockCommentThreeStars.invalid.ts.expected b/src/tests/fixtures/comments/blockCommentThreeStars.invalid.ts.expected deleted file mode 100644 index 8e8ecb11..00000000 --- a/src/tests/fixtures/comments/blockCommentThreeStars.invalid.ts.expected +++ /dev/null @@ -1,13 +0,0 @@ ------------------ -INPUT ------------------ -/*** @gqlType */ -class User {} - ------------------ -OUTPUT ------------------ -src/tests/fixtures/comments/blockCommentThreeStars.invalid.ts:1:6 - error: Unexpected Grats tag in detached docblock. Grats was unable to determine which TypeScript declaration this docblock is associated with. Moving the docblock to a position with is unambiguously "above" the relevant declaration may help. For more information see: https://grats.capt.dev/docs/getting-started/comment-syntax - -1 /*** @gqlType */ - ~~~~~~~~ diff --git a/src/tests/fixtures/comments/blockCommentThreeStars.invalid.ts.expected.md b/src/tests/fixtures/comments/blockCommentThreeStars.invalid.ts.expected.md new file mode 100644 index 00000000..e69de29b diff --git a/src/tests/fixtures/comments/commentFollowsDecorator.invalid.ts.expected b/src/tests/fixtures/comments/commentFollowsDecorator.invalid.ts.expected deleted file mode 100644 index 45598440..00000000 --- a/src/tests/fixtures/comments/commentFollowsDecorator.invalid.ts.expected +++ /dev/null @@ -1,24 +0,0 @@ ------------------ -INPUT ------------------ -@ObjectType() -/** @gqlType */ -export default class Composer { - @Field() - /** @gqlField */ - url(): string { - return `/composer/`; - } -} - ------------------ -OUTPUT ------------------ -src/tests/fixtures/comments/commentFollowsDecorator.invalid.ts:2:5 - error: Unexpected Grats tag in detached docblock. Grats was unable to determine which TypeScript declaration this docblock is associated with. Moving the docblock to a position that is unambiguously "above" the relevant declaration may help. For more information see: https://grats.capt.dev/docs/getting-started/comment-syntax - -2 /** @gqlType */ - ~~~~~~~~ -src/tests/fixtures/comments/commentFollowsDecorator.invalid.ts:5:7 - error: Unexpected Grats tag in detached docblock. Grats was unable to determine which TypeScript declaration this docblock is associated with. Moving the docblock to a position that is unambiguously "above" the relevant declaration may help. For more information see: https://grats.capt.dev/docs/getting-started/comment-syntax - -5 /** @gqlField */ - ~~~~~~~~~ diff --git a/src/tests/fixtures/comments/commentFollowsDecorator.invalid.ts.expected.md b/src/tests/fixtures/comments/commentFollowsDecorator.invalid.ts.expected.md new file mode 100644 index 00000000..bf2a17bc --- /dev/null +++ b/src/tests/fixtures/comments/commentFollowsDecorator.invalid.ts.expected.md @@ -0,0 +1,28 @@ +## input + +```ts title="comments/commentFollowsDecorator.invalid.ts" +@ObjectType() +/** @gqlType */ +export default class Composer { + @Field() + /** @gqlField */ + url(): string { + return `/composer/`; + } +} +``` + +## Output + +### Error Report + +```text +src/tests/fixtures/comments/commentFollowsDecorator.invalid.ts:2:5 - error: Unexpected Grats tag in detached docblock. Grats was unable to determine which TypeScript declaration this docblock is associated with. Moving the docblock to a position that is unambiguously "above" the relevant declaration may help. For more information see: https://grats.capt.dev/docs/getting-started/comment-syntax + +2 /** @gqlType */ + ~~~~~~~~ +src/tests/fixtures/comments/commentFollowsDecorator.invalid.ts:5:7 - error: Unexpected Grats tag in detached docblock. Grats was unable to determine which TypeScript declaration this docblock is associated with. Moving the docblock to a position that is unambiguously "above" the relevant declaration may help. For more information see: https://grats.capt.dev/docs/getting-started/comment-syntax + +5 /** @gqlField */ + ~~~~~~~~~ +``` \ No newline at end of file diff --git a/src/tests/fixtures/comments/detachedBlockComment.invalid.ts.expected b/src/tests/fixtures/comments/detachedBlockComment.invalid.ts.expected deleted file mode 100644 index 043631e3..00000000 --- a/src/tests/fixtures/comments/detachedBlockComment.invalid.ts.expected +++ /dev/null @@ -1,17 +0,0 @@ ------------------ -INPUT ------------------ -/** - * @gqlType - */ -/** - * Foo - */ - ------------------ -OUTPUT ------------------ -src/tests/fixtures/comments/detachedBlockComment.invalid.ts:2:4 - error: Unexpected Grats tag in detached docblock. Grats was unable to determine which TypeScript declaration this docblock is associated with. Moving the docblock to a position that is unambiguously "above" the relevant declaration may help. For more information see: https://grats.capt.dev/docs/getting-started/comment-syntax - -2 * @gqlType - ~~~~~~~~ diff --git a/src/tests/fixtures/comments/detachedBlockComment.invalid.ts.expected.md b/src/tests/fixtures/comments/detachedBlockComment.invalid.ts.expected.md new file mode 100644 index 00000000..8e187cf0 --- /dev/null +++ b/src/tests/fixtures/comments/detachedBlockComment.invalid.ts.expected.md @@ -0,0 +1,21 @@ +## input + +```ts title="comments/detachedBlockComment.invalid.ts" +/** + * @gqlType + */ +/** + * Foo + */ +``` + +## Output + +### Error Report + +```text +src/tests/fixtures/comments/detachedBlockComment.invalid.ts:2:4 - error: Unexpected Grats tag in detached docblock. Grats was unable to determine which TypeScript declaration this docblock is associated with. Moving the docblock to a position that is unambiguously "above" the relevant declaration may help. For more information see: https://grats.capt.dev/docs/getting-started/comment-syntax + +2 * @gqlType + ~~~~~~~~ +``` \ No newline at end of file diff --git a/src/tests/fixtures/comments/detachedBlockCommentNotJSDocWithoutStar.invalid.ts.expected b/src/tests/fixtures/comments/detachedBlockCommentNotJSDocWithoutStar.invalid.ts.expected deleted file mode 100644 index 026ae6e3..00000000 --- a/src/tests/fixtures/comments/detachedBlockCommentNotJSDocWithoutStar.invalid.ts.expected +++ /dev/null @@ -1,39 +0,0 @@ ------------------ -INPUT ------------------ -/* - @gqlType -*/ -/** - * Foo - */ - ------------------ -OUTPUT ------------------ --- Error Report -- -src/tests/fixtures/comments/detachedBlockCommentNotJSDocWithoutStar.invalid.ts:2:4 - error: Unexpected Grats tag in non-JSDoc-style block comment. Grats only looks for tags in JSDoc-style block comments which start with `/**`. For more information see: https://grats.capt.dev/docs/getting-started/comment-syntax - -2 @gqlType - ~~~~~~~~ - - --- Code Action: "Convert to a docblock comment" (convert-block-comment-to-docblock-comment) -- -- Original -+ Fixed - -@@ -1,2 +1,2 @@ -- /* -+ /** - @gqlType - --- Applied Fixes -- - * Applied fix "Convert to a docblock comment" in grats/src/tests/fixtures/comments/detachedBlockCommentNotJSDocWithoutStar.invalid.ts - --- Fixed Text -- -/** - @gqlType -*/ -/** - * Foo - */ diff --git a/src/tests/fixtures/comments/detachedBlockCommentNotJSDocWithoutStar.invalid.ts.expected.md b/src/tests/fixtures/comments/detachedBlockCommentNotJSDocWithoutStar.invalid.ts.expected.md new file mode 100644 index 00000000..a62df45d --- /dev/null +++ b/src/tests/fixtures/comments/detachedBlockCommentNotJSDocWithoutStar.invalid.ts.expected.md @@ -0,0 +1,50 @@ +## input + +```ts title="comments/detachedBlockCommentNotJSDocWithoutStar.invalid.ts" +/* + @gqlType +*/ +/** + * Foo + */ +``` + +## Output + +### Error Report + +```text +src/tests/fixtures/comments/detachedBlockCommentNotJSDocWithoutStar.invalid.ts:2:4 - error: Unexpected Grats tag in non-JSDoc-style block comment. Grats only looks for tags in JSDoc-style block comments which start with `/**`. For more information see: https://grats.capt.dev/docs/getting-started/comment-syntax + +2 @gqlType + ~~~~~~~~ +``` + +#### Code Action: "Convert to a docblock comment" (convert-block-comment-to-docblock-comment) + +```diff +- Original ++ Fixed + +@@ -1,2 +1,2 @@ +- /* ++ /** + @gqlType +``` + +#### Applied Fixes + +```text + * Applied fix "Convert to a docblock comment" in grats/src/tests/fixtures/comments/detachedBlockCommentNotJSDocWithoutStar.invalid.ts +``` + +#### Fixed Text + +```typescript +/** + @gqlType +*/ +/** + * Foo + */ +``` \ No newline at end of file diff --git a/src/tests/fixtures/comments/detachedBlockCommentWithInvalidTagName.invalid.ts.expected b/src/tests/fixtures/comments/detachedBlockCommentWithInvalidTagName.invalid.ts.expected deleted file mode 100644 index 8bcfbf3b..00000000 --- a/src/tests/fixtures/comments/detachedBlockCommentWithInvalidTagName.invalid.ts.expected +++ /dev/null @@ -1,21 +0,0 @@ ------------------ -INPUT ------------------ -/** - * @gqlTyp - */ -/** - * Foo - */ - ------------------ -OUTPUT ------------------ -src/tests/fixtures/comments/detachedBlockCommentWithInvalidTagName.invalid.ts:2:4 - error: `@gqlTyp` is not a valid Grats tag. Valid tags are: `@gqlType`, `@gqlField`, `@gqlScalar`, `@gqlInterface`, `@gqlEnum`, `@gqlUnion`, `@gqlInput`, `@gqlDirective`, `@gqlAnnotate`, `@gqlQueryField`, `@gqlMutationField`, `@gqlSubscriptionField`. - -2 * @gqlTyp - ~~~~~~~ -src/tests/fixtures/comments/detachedBlockCommentWithInvalidTagName.invalid.ts:2:4 - error: Unexpected Grats tag in detached docblock. Grats was unable to determine which TypeScript declaration this docblock is associated with. Moving the docblock to a position that is unambiguously "above" the relevant declaration may help. For more information see: https://grats.capt.dev/docs/getting-started/comment-syntax - -2 * @gqlTyp - ~~~~~~~ diff --git a/src/tests/fixtures/comments/detachedBlockCommentWithInvalidTagName.invalid.ts.expected.md b/src/tests/fixtures/comments/detachedBlockCommentWithInvalidTagName.invalid.ts.expected.md new file mode 100644 index 00000000..254180b4 --- /dev/null +++ b/src/tests/fixtures/comments/detachedBlockCommentWithInvalidTagName.invalid.ts.expected.md @@ -0,0 +1,25 @@ +## input + +```ts title="comments/detachedBlockCommentWithInvalidTagName.invalid.ts" +/** + * @gqlTyp + */ +/** + * Foo + */ +``` + +## Output + +### Error Report + +```text +src/tests/fixtures/comments/detachedBlockCommentWithInvalidTagName.invalid.ts:2:4 - error: `@gqlTyp` is not a valid Grats tag. Valid tags are: `@gqlType`, `@gqlField`, `@gqlScalar`, `@gqlInterface`, `@gqlEnum`, `@gqlUnion`, `@gqlInput`, `@gqlDirective`, `@gqlAnnotate`, `@gqlQueryField`, `@gqlMutationField`, `@gqlSubscriptionField`. + +2 * @gqlTyp + ~~~~~~~ +src/tests/fixtures/comments/detachedBlockCommentWithInvalidTagName.invalid.ts:2:4 - error: Unexpected Grats tag in detached docblock. Grats was unable to determine which TypeScript declaration this docblock is associated with. Moving the docblock to a position that is unambiguously "above" the relevant declaration may help. For more information see: https://grats.capt.dev/docs/getting-started/comment-syntax + +2 * @gqlTyp + ~~~~~~~ +``` \ No newline at end of file diff --git a/src/tests/fixtures/comments/detachedBlockCommentWithKillsParent.invalid.ts.expected b/src/tests/fixtures/comments/detachedBlockCommentWithKillsParent.invalid.ts.expected deleted file mode 100644 index a29c02d6..00000000 --- a/src/tests/fixtures/comments/detachedBlockCommentWithKillsParent.invalid.ts.expected +++ /dev/null @@ -1,17 +0,0 @@ ------------------ -INPUT ------------------ -/** - * @killsParentOnException - */ -/** - * Foo - */ - ------------------ -OUTPUT ------------------ -src/tests/fixtures/comments/detachedBlockCommentWithKillsParent.invalid.ts:2:4 - error: Unexpected Grats tag in detached docblock. Grats was unable to determine which TypeScript declaration this docblock is associated with. Moving the docblock to a position that is unambiguously "above" the relevant declaration may help. For more information see: https://grats.capt.dev/docs/getting-started/comment-syntax - -2 * @killsParentOnException - ~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/src/tests/fixtures/comments/detachedBlockCommentWithKillsParent.invalid.ts.expected.md b/src/tests/fixtures/comments/detachedBlockCommentWithKillsParent.invalid.ts.expected.md new file mode 100644 index 00000000..8d14ba68 --- /dev/null +++ b/src/tests/fixtures/comments/detachedBlockCommentWithKillsParent.invalid.ts.expected.md @@ -0,0 +1,21 @@ +## input + +```ts title="comments/detachedBlockCommentWithKillsParent.invalid.ts" +/** + * @killsParentOnException + */ +/** + * Foo + */ +``` + +## Output + +### Error Report + +```text +src/tests/fixtures/comments/detachedBlockCommentWithKillsParent.invalid.ts:2:4 - error: Unexpected Grats tag in detached docblock. Grats was unable to determine which TypeScript declaration this docblock is associated with. Moving the docblock to a position that is unambiguously "above" the relevant declaration may help. For more information see: https://grats.capt.dev/docs/getting-started/comment-syntax + +2 * @killsParentOnException + ~~~~~~~~~~~~~~~~~~~~~~~ +``` \ No newline at end of file diff --git a/src/tests/fixtures/comments/detachedBlockCommentWithoutStar.invalid.ts.expected b/src/tests/fixtures/comments/detachedBlockCommentWithoutStar.invalid.ts.expected deleted file mode 100644 index 148c5844..00000000 --- a/src/tests/fixtures/comments/detachedBlockCommentWithoutStar.invalid.ts.expected +++ /dev/null @@ -1,17 +0,0 @@ ------------------ -INPUT ------------------ -/** - @gqlType -*/ -/** - * Foo - */ - ------------------ -OUTPUT ------------------ -src/tests/fixtures/comments/detachedBlockCommentWithoutStar.invalid.ts:2:4 - error: Unexpected Grats tag in detached docblock. Grats was unable to determine which TypeScript declaration this docblock is associated with. Moving the docblock to a position that is unambiguously "above" the relevant declaration may help. For more information see: https://grats.capt.dev/docs/getting-started/comment-syntax - -2 @gqlType - ~~~~~~~~ diff --git a/src/tests/fixtures/comments/detachedBlockCommentWithoutStar.invalid.ts.expected.md b/src/tests/fixtures/comments/detachedBlockCommentWithoutStar.invalid.ts.expected.md new file mode 100644 index 00000000..335cdb02 --- /dev/null +++ b/src/tests/fixtures/comments/detachedBlockCommentWithoutStar.invalid.ts.expected.md @@ -0,0 +1,21 @@ +## input + +```ts title="comments/detachedBlockCommentWithoutStar.invalid.ts" +/** + @gqlType +*/ +/** + * Foo + */ +``` + +## Output + +### Error Report + +```text +src/tests/fixtures/comments/detachedBlockCommentWithoutStar.invalid.ts:2:4 - error: Unexpected Grats tag in detached docblock. Grats was unable to determine which TypeScript declaration this docblock is associated with. Moving the docblock to a position that is unambiguously "above" the relevant declaration may help. For more information see: https://grats.capt.dev/docs/getting-started/comment-syntax + +2 @gqlType + ~~~~~~~~ +``` \ No newline at end of file diff --git a/src/tests/fixtures/comments/invalidTagInLinecomment.invalid.ts.expected b/src/tests/fixtures/comments/invalidTagInLinecomment.invalid.ts.expected deleted file mode 100644 index ffa0d9c5..00000000 --- a/src/tests/fixtures/comments/invalidTagInLinecomment.invalid.ts.expected +++ /dev/null @@ -1,43 +0,0 @@ ------------------ -INPUT ------------------ -// @gqlTyp -export default class Composer { - url(): string { - return `/composer/`; - } -} - ------------------ -OUTPUT ------------------ --- Error Report -- -src/tests/fixtures/comments/invalidTagInLinecomment.invalid.ts:1:4 - error: `@gqlTyp` is not a valid Grats tag. Valid tags are: `@gqlType`, `@gqlField`, `@gqlScalar`, `@gqlInterface`, `@gqlEnum`, `@gqlUnion`, `@gqlInput`, `@gqlDirective`, `@gqlAnnotate`, `@gqlQueryField`, `@gqlMutationField`, `@gqlSubscriptionField`. - -1 // @gqlTyp - ~~~~~~~ -src/tests/fixtures/comments/invalidTagInLinecomment.invalid.ts:1:4 - error: Unexpected Grats tag in line (`//`) comment. Grats looks for tags in JSDoc-style block comments. e.g. `/** @gqlType */`. For more information see: https://grats.capt.dev/docs/getting-started/comment-syntax - -1 // @gqlTyp - ~~~~~~~ - - --- Code Action: "Convert to a docblock comment" (convert-line-comment-to-docblock-comment) -- -- Original -+ Fixed - -@@ -1,2 +1,2 @@ -- // @gqlTyp -+ /** @gqlTyp */ - export default class Composer { - --- Applied Fixes -- - * Applied fix "Convert to a docblock comment" in grats/src/tests/fixtures/comments/invalidTagInLinecomment.invalid.ts - --- Fixed Text -- -/** @gqlTyp */ -export default class Composer { - url(): string { - return `/composer/`; - } -} diff --git a/src/tests/fixtures/comments/invalidTagInLinecomment.invalid.ts.expected.md b/src/tests/fixtures/comments/invalidTagInLinecomment.invalid.ts.expected.md new file mode 100644 index 00000000..231527d7 --- /dev/null +++ b/src/tests/fixtures/comments/invalidTagInLinecomment.invalid.ts.expected.md @@ -0,0 +1,54 @@ +## input + +```ts title="comments/invalidTagInLinecomment.invalid.ts" +// @gqlTyp +export default class Composer { + url(): string { + return `/composer/`; + } +} +``` + +## Output + +### Error Report + +```text +src/tests/fixtures/comments/invalidTagInLinecomment.invalid.ts:1:4 - error: `@gqlTyp` is not a valid Grats tag. Valid tags are: `@gqlType`, `@gqlField`, `@gqlScalar`, `@gqlInterface`, `@gqlEnum`, `@gqlUnion`, `@gqlInput`, `@gqlDirective`, `@gqlAnnotate`, `@gqlQueryField`, `@gqlMutationField`, `@gqlSubscriptionField`. + +1 // @gqlTyp + ~~~~~~~ +src/tests/fixtures/comments/invalidTagInLinecomment.invalid.ts:1:4 - error: Unexpected Grats tag in line (`//`) comment. Grats looks for tags in JSDoc-style block comments. e.g. `/** @gqlType */`. For more information see: https://grats.capt.dev/docs/getting-started/comment-syntax + +1 // @gqlTyp + ~~~~~~~ +``` + +#### Code Action: "Convert to a docblock comment" (convert-line-comment-to-docblock-comment) + +```diff +- Original ++ Fixed + +@@ -1,2 +1,2 @@ +- // @gqlTyp ++ /** @gqlTyp */ + export default class Composer { +``` + +#### Applied Fixes + +```text + * Applied fix "Convert to a docblock comment" in grats/src/tests/fixtures/comments/invalidTagInLinecomment.invalid.ts +``` + +#### Fixed Text + +```typescript +/** @gqlTyp */ +export default class Composer { + url(): string { + return `/composer/`; + } +} +``` \ No newline at end of file diff --git a/src/tests/fixtures/comments/lineComment.invalid.ts.expected b/src/tests/fixtures/comments/lineComment.invalid.ts.expected deleted file mode 100644 index 6d82f1f6..00000000 --- a/src/tests/fixtures/comments/lineComment.invalid.ts.expected +++ /dev/null @@ -1,56 +0,0 @@ ------------------ -INPUT ------------------ -// @gqlType -export default class Composer { - // @gqlField - url(): string { - return `/composer/`; - } -} - ------------------ -OUTPUT ------------------ --- Error Report -- -src/tests/fixtures/comments/lineComment.invalid.ts:1:4 - error: Unexpected Grats tag in line (`//`) comment. Grats looks for tags in JSDoc-style block comments. e.g. `/** @gqlType */`. For more information see: https://grats.capt.dev/docs/getting-started/comment-syntax - -1 // @gqlType - ~~~~~~~~ - -src/tests/fixtures/comments/lineComment.invalid.ts:3:6 - error: Unexpected Grats tag in line (`//`) comment. Grats looks for tags in JSDoc-style block comments. e.g. `/** @gqlType */`. For more information see: https://grats.capt.dev/docs/getting-started/comment-syntax - -3 // @gqlField - ~~~~~~~~~ - - --- Code Action: "Convert to a docblock comment" (convert-line-comment-to-docblock-comment) -- -- Original -+ Fixed - -@@ -1,2 +1,2 @@ -- // @gqlType -+ /** @gqlType */ - export default class Composer { --- Code Action: "Convert to a docblock comment" (convert-line-comment-to-docblock-comment) -- -- Original -+ Fixed - -@@ -2,3 +2,3 @@ - export default class Composer { -- // @gqlField -+ /** @gqlField */ - url(): string { - --- Applied Fixes -- - * Applied fix "Convert to a docblock comment" in grats/src/tests/fixtures/comments/lineComment.invalid.ts - * Applied fix "Convert to a docblock comment" in grats/src/tests/fixtures/comments/lineComment.invalid.ts - --- Fixed Text -- -/** @gqlType */ -export default class Composer { - /** @gqlField */ - url(): string { - return `/composer/`; - } -} diff --git a/src/tests/fixtures/comments/lineComment.invalid.ts.expected.md b/src/tests/fixtures/comments/lineComment.invalid.ts.expected.md new file mode 100644 index 00000000..bf5c45a8 --- /dev/null +++ b/src/tests/fixtures/comments/lineComment.invalid.ts.expected.md @@ -0,0 +1,71 @@ +## input + +```ts title="comments/lineComment.invalid.ts" +// @gqlType +export default class Composer { + // @gqlField + url(): string { + return `/composer/`; + } +} +``` + +## Output + +### Error Report + +```text +src/tests/fixtures/comments/lineComment.invalid.ts:1:4 - error: Unexpected Grats tag in line (`//`) comment. Grats looks for tags in JSDoc-style block comments. e.g. `/** @gqlType */`. For more information see: https://grats.capt.dev/docs/getting-started/comment-syntax + +1 // @gqlType + ~~~~~~~~ + +src/tests/fixtures/comments/lineComment.invalid.ts:3:6 - error: Unexpected Grats tag in line (`//`) comment. Grats looks for tags in JSDoc-style block comments. e.g. `/** @gqlType */`. For more information see: https://grats.capt.dev/docs/getting-started/comment-syntax + +3 // @gqlField + ~~~~~~~~~ +``` + +#### Code Action: "Convert to a docblock comment" (convert-line-comment-to-docblock-comment) + +```diff +- Original ++ Fixed + +@@ -1,2 +1,2 @@ +- // @gqlType ++ /** @gqlType */ + export default class Composer { +``` + +#### Code Action: "Convert to a docblock comment" (convert-line-comment-to-docblock-comment) + +```diff +- Original ++ Fixed + +@@ -2,3 +2,3 @@ + export default class Composer { +- // @gqlField ++ /** @gqlField */ + url(): string { +``` + +#### Applied Fixes + +```text + * Applied fix "Convert to a docblock comment" in grats/src/tests/fixtures/comments/lineComment.invalid.ts + * Applied fix "Convert to a docblock comment" in grats/src/tests/fixtures/comments/lineComment.invalid.ts +``` + +#### Fixed Text + +```typescript +/** @gqlType */ +export default class Composer { + /** @gqlField */ + url(): string { + return `/composer/`; + } +} +``` \ No newline at end of file diff --git a/src/tests/fixtures/comments/lineCommentWrongCasing.invalid.ts.expected b/src/tests/fixtures/comments/lineCommentWrongCasing.invalid.ts.expected deleted file mode 100644 index c8911950..00000000 --- a/src/tests/fixtures/comments/lineCommentWrongCasing.invalid.ts.expected +++ /dev/null @@ -1,64 +0,0 @@ ------------------ -INPUT ------------------ -// @GQLtYPE -export default class Composer { - // @gqlfield - url(): string { - return `/composer/`; - } -} - ------------------ -OUTPUT ------------------ --- Error Report -- -src/tests/fixtures/comments/lineCommentWrongCasing.invalid.ts:1:4 - error: `@GQLtYPE` is not a valid Grats tag. Valid tags are: `@gqlType`, `@gqlField`, `@gqlScalar`, `@gqlInterface`, `@gqlEnum`, `@gqlUnion`, `@gqlInput`, `@gqlDirective`, `@gqlAnnotate`, `@gqlQueryField`, `@gqlMutationField`, `@gqlSubscriptionField`. - -1 // @GQLtYPE - ~~~~~~~~ -src/tests/fixtures/comments/lineCommentWrongCasing.invalid.ts:1:4 - error: Unexpected Grats tag in line (`//`) comment. Grats looks for tags in JSDoc-style block comments. e.g. `/** @gqlType */`. For more information see: https://grats.capt.dev/docs/getting-started/comment-syntax - -1 // @GQLtYPE - ~~~~~~~~ - -src/tests/fixtures/comments/lineCommentWrongCasing.invalid.ts:3:6 - error: `@gqlfield` is not a valid Grats tag. Valid tags are: `@gqlType`, `@gqlField`, `@gqlScalar`, `@gqlInterface`, `@gqlEnum`, `@gqlUnion`, `@gqlInput`, `@gqlDirective`, `@gqlAnnotate`, `@gqlQueryField`, `@gqlMutationField`, `@gqlSubscriptionField`. - -3 // @gqlfield - ~~~~~~~~~ -src/tests/fixtures/comments/lineCommentWrongCasing.invalid.ts:3:6 - error: Unexpected Grats tag in line (`//`) comment. Grats looks for tags in JSDoc-style block comments. e.g. `/** @gqlType */`. For more information see: https://grats.capt.dev/docs/getting-started/comment-syntax - -3 // @gqlfield - ~~~~~~~~~ - - --- Code Action: "Convert to a docblock comment" (convert-line-comment-to-docblock-comment) -- -- Original -+ Fixed - -@@ -1,2 +1,2 @@ -- // @GQLtYPE -+ /** @GQLtYPE */ - export default class Composer { --- Code Action: "Convert to a docblock comment" (convert-line-comment-to-docblock-comment) -- -- Original -+ Fixed - -@@ -2,3 +2,3 @@ - export default class Composer { -- // @gqlfield -+ /** @gqlfield */ - url(): string { - --- Applied Fixes -- - * Applied fix "Convert to a docblock comment" in grats/src/tests/fixtures/comments/lineCommentWrongCasing.invalid.ts - * Applied fix "Convert to a docblock comment" in grats/src/tests/fixtures/comments/lineCommentWrongCasing.invalid.ts - --- Fixed Text -- -/** @GQLtYPE */ -export default class Composer { - /** @gqlfield */ - url(): string { - return `/composer/`; - } -} diff --git a/src/tests/fixtures/comments/lineCommentWrongCasing.invalid.ts.expected.md b/src/tests/fixtures/comments/lineCommentWrongCasing.invalid.ts.expected.md new file mode 100644 index 00000000..f6253a8b --- /dev/null +++ b/src/tests/fixtures/comments/lineCommentWrongCasing.invalid.ts.expected.md @@ -0,0 +1,79 @@ +## input + +```ts title="comments/lineCommentWrongCasing.invalid.ts" +// @GQLtYPE +export default class Composer { + // @gqlfield + url(): string { + return `/composer/`; + } +} +``` + +## Output + +### Error Report + +```text +src/tests/fixtures/comments/lineCommentWrongCasing.invalid.ts:1:4 - error: `@GQLtYPE` is not a valid Grats tag. Valid tags are: `@gqlType`, `@gqlField`, `@gqlScalar`, `@gqlInterface`, `@gqlEnum`, `@gqlUnion`, `@gqlInput`, `@gqlDirective`, `@gqlAnnotate`, `@gqlQueryField`, `@gqlMutationField`, `@gqlSubscriptionField`. + +1 // @GQLtYPE + ~~~~~~~~ +src/tests/fixtures/comments/lineCommentWrongCasing.invalid.ts:1:4 - error: Unexpected Grats tag in line (`//`) comment. Grats looks for tags in JSDoc-style block comments. e.g. `/** @gqlType */`. For more information see: https://grats.capt.dev/docs/getting-started/comment-syntax + +1 // @GQLtYPE + ~~~~~~~~ + +src/tests/fixtures/comments/lineCommentWrongCasing.invalid.ts:3:6 - error: `@gqlfield` is not a valid Grats tag. Valid tags are: `@gqlType`, `@gqlField`, `@gqlScalar`, `@gqlInterface`, `@gqlEnum`, `@gqlUnion`, `@gqlInput`, `@gqlDirective`, `@gqlAnnotate`, `@gqlQueryField`, `@gqlMutationField`, `@gqlSubscriptionField`. + +3 // @gqlfield + ~~~~~~~~~ +src/tests/fixtures/comments/lineCommentWrongCasing.invalid.ts:3:6 - error: Unexpected Grats tag in line (`//`) comment. Grats looks for tags in JSDoc-style block comments. e.g. `/** @gqlType */`. For more information see: https://grats.capt.dev/docs/getting-started/comment-syntax + +3 // @gqlfield + ~~~~~~~~~ +``` + +#### Code Action: "Convert to a docblock comment" (convert-line-comment-to-docblock-comment) + +```diff +- Original ++ Fixed + +@@ -1,2 +1,2 @@ +- // @GQLtYPE ++ /** @GQLtYPE */ + export default class Composer { +``` + +#### Code Action: "Convert to a docblock comment" (convert-line-comment-to-docblock-comment) + +```diff +- Original ++ Fixed + +@@ -2,3 +2,3 @@ + export default class Composer { +- // @gqlfield ++ /** @gqlfield */ + url(): string { +``` + +#### Applied Fixes + +```text + * Applied fix "Convert to a docblock comment" in grats/src/tests/fixtures/comments/lineCommentWrongCasing.invalid.ts + * Applied fix "Convert to a docblock comment" in grats/src/tests/fixtures/comments/lineCommentWrongCasing.invalid.ts +``` + +#### Fixed Text + +```typescript +/** @GQLtYPE */ +export default class Composer { + /** @gqlfield */ + url(): string { + return `/composer/`; + } +} +``` \ No newline at end of file diff --git a/src/tests/fixtures/comments/nonJSDocBlockComment.invalid.ts.expected b/src/tests/fixtures/comments/nonJSDocBlockComment.invalid.ts.expected deleted file mode 100644 index 8c525196..00000000 --- a/src/tests/fixtures/comments/nonJSDocBlockComment.invalid.ts.expected +++ /dev/null @@ -1,36 +0,0 @@ ------------------ -INPUT ------------------ -// Oops! Forgot to use two asterisks for the JSDoc block comment. - -/* @gqlType */ -class Composer {} - ------------------ -OUTPUT ------------------ --- Error Report -- -src/tests/fixtures/comments/nonJSDocBlockComment.invalid.ts:3:4 - error: Unexpected Grats tag in non-JSDoc-style block comment. Grats only looks for tags in JSDoc-style block comments which start with `/**`. For more information see: https://grats.capt.dev/docs/getting-started/comment-syntax - -3 /* @gqlType */ - ~~~~~~~~ - - --- Code Action: "Convert to a docblock comment" (convert-block-comment-to-docblock-comment) -- -- Original -+ Fixed - -@@ -2,3 +2,3 @@ - -- /* @gqlType */ -+ /** @gqlType */ - class Composer {} - --- Applied Fixes -- - * Applied fix "Convert to a docblock comment" in grats/src/tests/fixtures/comments/nonJSDocBlockComment.invalid.ts - --- Fixed Text -- -// Oops! Forgot to use two asterisks for the JSDoc block comment. - -/** @gqlType */ -class Composer {} diff --git a/src/tests/fixtures/comments/nonJSDocBlockComment.invalid.ts.expected.md b/src/tests/fixtures/comments/nonJSDocBlockComment.invalid.ts.expected.md new file mode 100644 index 00000000..e5e1e560 --- /dev/null +++ b/src/tests/fixtures/comments/nonJSDocBlockComment.invalid.ts.expected.md @@ -0,0 +1,47 @@ +## input + +```ts title="comments/nonJSDocBlockComment.invalid.ts" +// Oops! Forgot to use two asterisks for the JSDoc block comment. + +/* @gqlType */ +class Composer {} +``` + +## Output + +### Error Report + +```text +src/tests/fixtures/comments/nonJSDocBlockComment.invalid.ts:3:4 - error: Unexpected Grats tag in non-JSDoc-style block comment. Grats only looks for tags in JSDoc-style block comments which start with `/**`. For more information see: https://grats.capt.dev/docs/getting-started/comment-syntax + +3 /* @gqlType */ + ~~~~~~~~ +``` + +#### Code Action: "Convert to a docblock comment" (convert-block-comment-to-docblock-comment) + +```diff +- Original ++ Fixed + +@@ -2,3 +2,3 @@ + +- /* @gqlType */ ++ /** @gqlType */ + class Composer {} +``` + +#### Applied Fixes + +```text + * Applied fix "Convert to a docblock comment" in grats/src/tests/fixtures/comments/nonJSDocBlockComment.invalid.ts +``` + +#### Fixed Text + +```typescript +// Oops! Forgot to use two asterisks for the JSDoc block comment. + +/** @gqlType */ +class Composer {} +``` \ No newline at end of file diff --git a/src/tests/fixtures/configOptions/headerIsArrayWithNumber.invalid.ts.expected b/src/tests/fixtures/configOptions/headerIsArrayWithNumber.invalid.ts.expected deleted file mode 100644 index 30ab8dd1..00000000 --- a/src/tests/fixtures/configOptions/headerIsArrayWithNumber.invalid.ts.expected +++ /dev/null @@ -1,14 +0,0 @@ ------------------ -INPUT ------------------ -// {"schemaHeader": ["Hello", 1]} -/** @gqlType */ -export default class SomeType { - /** @gqlField */ - hello: string; -} - ------------------ -OUTPUT ------------------ -error: Expected property `schemaHeader` to be a string or array of strings, but got ["Hello",1]. diff --git a/src/tests/fixtures/configOptions/headerIsArrayWithNumber.invalid.ts.expected.md b/src/tests/fixtures/configOptions/headerIsArrayWithNumber.invalid.ts.expected.md new file mode 100644 index 00000000..9f27f260 --- /dev/null +++ b/src/tests/fixtures/configOptions/headerIsArrayWithNumber.invalid.ts.expected.md @@ -0,0 +1,18 @@ +## input + +```ts title="configOptions/headerIsArrayWithNumber.invalid.ts" +// {"schemaHeader": ["Hello", 1]} +/** @gqlType */ +export default class SomeType { + /** @gqlField */ + hello: string; +} +``` + +## Output + +### Error Report + +```text +error: Expected property `schemaHeader` to be a string or array of strings, but got ["Hello",1]. +``` \ No newline at end of file diff --git a/src/tests/fixtures/configOptions/importModuleSpecifierEnding.ts.expected b/src/tests/fixtures/configOptions/importModuleSpecifierEnding.ts.expected deleted file mode 100644 index 791f133a..00000000 --- a/src/tests/fixtures/configOptions/importModuleSpecifierEnding.ts.expected +++ /dev/null @@ -1,50 +0,0 @@ ------------------ -INPUT ------------------ -// {"importModuleSpecifierEnding": ".js"} - -/** @gqlType */ -export default class SomeType { - /** @gqlField */ - hello: string; -} - -/** @gqlField */ -export function greeting(t: SomeType): string { - return t.hello + " world!"; -} - ------------------ -OUTPUT ------------------ --- SDL -- -type SomeType { - greeting: String - hello: String -} --- TypeScript -- -import { GraphQLSchema, GraphQLObjectType, GraphQLString } from "graphql"; -import { greeting as someTypeGreetingResolver } from "./importModuleSpecifierEnding.js"; -export function getSchema(): GraphQLSchema { - const SomeTypeType: GraphQLObjectType = new GraphQLObjectType({ - name: "SomeType", - fields() { - return { - greeting: { - name: "greeting", - type: GraphQLString, - resolve(source) { - return someTypeGreetingResolver(source); - } - }, - hello: { - name: "hello", - type: GraphQLString - } - }; - } - }); - return new GraphQLSchema({ - types: [SomeTypeType] - }); -} diff --git a/src/tests/fixtures/configOptions/importModuleSpecifierEnding.ts.expected.md b/src/tests/fixtures/configOptions/importModuleSpecifierEnding.ts.expected.md new file mode 100644 index 00000000..6fd1c1e2 --- /dev/null +++ b/src/tests/fixtures/configOptions/importModuleSpecifierEnding.ts.expected.md @@ -0,0 +1,57 @@ +## input + +```ts title="configOptions/importModuleSpecifierEnding.ts" +// {"importModuleSpecifierEnding": ".js"} + +/** @gqlType */ +export default class SomeType { + /** @gqlField */ + hello: string; +} + +/** @gqlField */ +export function greeting(t: SomeType): string { + return t.hello + " world!"; +} +``` + +## Output + +### SDL + +```graphql +type SomeType { + greeting: String + hello: String +} +``` + +### TypeScript + +```ts +import { GraphQLSchema, GraphQLObjectType, GraphQLString } from "graphql"; +import { greeting as someTypeGreetingResolver } from "./importModuleSpecifierEnding.js"; +export function getSchema(): GraphQLSchema { + const SomeTypeType: GraphQLObjectType = new GraphQLObjectType({ + name: "SomeType", + fields() { + return { + greeting: { + name: "greeting", + type: GraphQLString, + resolve(source) { + return someTypeGreetingResolver(source); + } + }, + hello: { + name: "hello", + type: GraphQLString + } + }; + } + }); + return new GraphQLSchema({ + types: [SomeTypeType] + }); +} +``` \ No newline at end of file diff --git a/src/tests/fixtures/configOptions/invalidKey.invalid.ts.expected b/src/tests/fixtures/configOptions/invalidKey.invalid.ts.expected deleted file mode 100644 index f0271a94..00000000 --- a/src/tests/fixtures/configOptions/invalidKey.invalid.ts.expected +++ /dev/null @@ -1,14 +0,0 @@ ------------------ -INPUT ------------------ -// {"invalidKey": "Oops"} -/** @gqlType */ -export default class SomeType { - /** @gqlField */ - hello: string; -} - ------------------ -OUTPUT ------------------ -error: Unknown Grats config option `invalidKey`. diff --git a/src/tests/fixtures/configOptions/invalidKey.invalid.ts.expected.md b/src/tests/fixtures/configOptions/invalidKey.invalid.ts.expected.md new file mode 100644 index 00000000..c9999cd1 --- /dev/null +++ b/src/tests/fixtures/configOptions/invalidKey.invalid.ts.expected.md @@ -0,0 +1,18 @@ +## input + +```ts title="configOptions/invalidKey.invalid.ts" +// {"invalidKey": "Oops"} +/** @gqlType */ +export default class SomeType { + /** @gqlField */ + hello: string; +} +``` + +## Output + +### Error Report + +```text +error: Unknown Grats config option `invalidKey`. +``` \ No newline at end of file diff --git a/src/tests/fixtures/configOptions/multipleInvalidKeys.invalid.ts.expected b/src/tests/fixtures/configOptions/multipleInvalidKeys.invalid.ts.expected deleted file mode 100644 index 03770353..00000000 --- a/src/tests/fixtures/configOptions/multipleInvalidKeys.invalid.ts.expected +++ /dev/null @@ -1,14 +0,0 @@ ------------------ -INPUT ------------------ -// {"invalidKey": "Oops", "anotherInvalidKey": "Oops"} -/** @gqlType */ -export default class SomeType { - /** @gqlField */ - hello: string; -} - ------------------ -OUTPUT ------------------ -error: Unknown Grats config option `invalidKey`. diff --git a/src/tests/fixtures/configOptions/multipleInvalidKeys.invalid.ts.expected.md b/src/tests/fixtures/configOptions/multipleInvalidKeys.invalid.ts.expected.md new file mode 100644 index 00000000..dea12ffe --- /dev/null +++ b/src/tests/fixtures/configOptions/multipleInvalidKeys.invalid.ts.expected.md @@ -0,0 +1,18 @@ +## input + +```ts title="configOptions/multipleInvalidKeys.invalid.ts" +// {"invalidKey": "Oops", "anotherInvalidKey": "Oops"} +/** @gqlType */ +export default class SomeType { + /** @gqlField */ + hello: string; +} +``` + +## Output + +### Error Report + +```text +error: Unknown Grats config option `invalidKey`. +``` \ No newline at end of file diff --git a/src/tests/fixtures/configOptions/nonNullableIsNull.invalid.ts.expected b/src/tests/fixtures/configOptions/nonNullableIsNull.invalid.ts.expected deleted file mode 100644 index 2e89fb2e..00000000 --- a/src/tests/fixtures/configOptions/nonNullableIsNull.invalid.ts.expected +++ /dev/null @@ -1,14 +0,0 @@ ------------------ -INPUT ------------------ -// {"tsSchema": null} -/** @gqlType */ -export default class SomeType { - /** @gqlField */ - hello: string; -} - ------------------ -OUTPUT ------------------ -error: The Grats config option `tsSchema` must be a `string` if provided. diff --git a/src/tests/fixtures/configOptions/nonNullableIsNull.invalid.ts.expected.md b/src/tests/fixtures/configOptions/nonNullableIsNull.invalid.ts.expected.md new file mode 100644 index 00000000..75d9cc1d --- /dev/null +++ b/src/tests/fixtures/configOptions/nonNullableIsNull.invalid.ts.expected.md @@ -0,0 +1,18 @@ +## input + +```ts title="configOptions/nonNullableIsNull.invalid.ts" +// {"tsSchema": null} +/** @gqlType */ +export default class SomeType { + /** @gqlField */ + hello: string; +} +``` + +## Output + +### Error Report + +```text +error: The Grats config option `tsSchema` must be a `string` if provided. +``` \ No newline at end of file diff --git a/src/tests/fixtures/custom_scalars/DefineCustomScalar.ts.expected b/src/tests/fixtures/custom_scalars/DefineCustomScalar.ts.expected deleted file mode 100644 index ba866e02..00000000 --- a/src/tests/fixtures/custom_scalars/DefineCustomScalar.ts.expected +++ /dev/null @@ -1,50 +0,0 @@ ------------------ -INPUT ------------------ -/** @gqlType */ -class SomeType { - /** @gqlField */ - hello: string; -} - -/** @gqlScalar */ -export type MyUrl = string; - ------------------ -OUTPUT ------------------ --- SDL -- -scalar MyUrl - -type SomeType { - hello: String -} --- TypeScript -- -import type { GqlScalar } from "grats"; -import type { MyUrl as MyUrlInternal } from "./DefineCustomScalar"; -import { GraphQLSchema, GraphQLScalarType, GraphQLObjectType, GraphQLString } from "graphql"; -export type SchemaConfig = { - scalars: { - MyUrl: GqlScalar; - }; -}; -export function getSchema(config: SchemaConfig): GraphQLSchema { - const MyUrlType: GraphQLScalarType = new GraphQLScalarType({ - name: "MyUrl", - ...config.scalars.MyUrl - }); - const SomeTypeType: GraphQLObjectType = new GraphQLObjectType({ - name: "SomeType", - fields() { - return { - hello: { - name: "hello", - type: GraphQLString - } - }; - } - }); - return new GraphQLSchema({ - types: [MyUrlType, SomeTypeType] - }); -} diff --git a/src/tests/fixtures/custom_scalars/DefineCustomScalar.ts.expected.md b/src/tests/fixtures/custom_scalars/DefineCustomScalar.ts.expected.md new file mode 100644 index 00000000..5501719a --- /dev/null +++ b/src/tests/fixtures/custom_scalars/DefineCustomScalar.ts.expected.md @@ -0,0 +1,57 @@ +## input + +```ts title="custom_scalars/DefineCustomScalar.ts" +/** @gqlType */ +class SomeType { + /** @gqlField */ + hello: string; +} + +/** @gqlScalar */ +export type MyUrl = string; +``` + +## Output + +### SDL + +```graphql +scalar MyUrl + +type SomeType { + hello: String +} +``` + +### TypeScript + +```ts +import type { GqlScalar } from "grats"; +import type { MyUrl as MyUrlInternal } from "./DefineCustomScalar"; +import { GraphQLSchema, GraphQLScalarType, GraphQLObjectType, GraphQLString } from "graphql"; +export type SchemaConfig = { + scalars: { + MyUrl: GqlScalar; + }; +}; +export function getSchema(config: SchemaConfig): GraphQLSchema { + const MyUrlType: GraphQLScalarType = new GraphQLScalarType({ + name: "MyUrl", + ...config.scalars.MyUrl + }); + const SomeTypeType: GraphQLObjectType = new GraphQLObjectType({ + name: "SomeType", + fields() { + return { + hello: { + name: "hello", + type: GraphQLString + } + }; + } + }); + return new GraphQLSchema({ + types: [MyUrlType, SomeTypeType] + }); +} +``` \ No newline at end of file diff --git a/src/tests/fixtures/custom_scalars/DefineCustomScalarWithDescription.ts.expected b/src/tests/fixtures/custom_scalars/DefineCustomScalarWithDescription.ts.expected deleted file mode 100644 index 474ca372..00000000 --- a/src/tests/fixtures/custom_scalars/DefineCustomScalarWithDescription.ts.expected +++ /dev/null @@ -1,55 +0,0 @@ ------------------ -INPUT ------------------ -/** @gqlType */ -class SomeType { - /** @gqlField */ - hello: string; -} - -/** - * Use this for URLs. - * @gqlScalar - */ -export type MyUrl = string; - ------------------ -OUTPUT ------------------ --- SDL -- -"""Use this for URLs.""" -scalar MyUrl - -type SomeType { - hello: String -} --- TypeScript -- -import type { GqlScalar } from "grats"; -import type { MyUrl as MyUrlInternal } from "./DefineCustomScalarWithDescription"; -import { GraphQLSchema, GraphQLScalarType, GraphQLObjectType, GraphQLString } from "graphql"; -export type SchemaConfig = { - scalars: { - MyUrl: GqlScalar; - }; -}; -export function getSchema(config: SchemaConfig): GraphQLSchema { - const MyUrlType: GraphQLScalarType = new GraphQLScalarType({ - description: "Use this for URLs.", - name: "MyUrl", - ...config.scalars.MyUrl - }); - const SomeTypeType: GraphQLObjectType = new GraphQLObjectType({ - name: "SomeType", - fields() { - return { - hello: { - name: "hello", - type: GraphQLString - } - }; - } - }); - return new GraphQLSchema({ - types: [MyUrlType, SomeTypeType] - }); -} diff --git a/src/tests/fixtures/custom_scalars/DefineCustomScalarWithDescription.ts.expected.md b/src/tests/fixtures/custom_scalars/DefineCustomScalarWithDescription.ts.expected.md new file mode 100644 index 00000000..16088c09 --- /dev/null +++ b/src/tests/fixtures/custom_scalars/DefineCustomScalarWithDescription.ts.expected.md @@ -0,0 +1,62 @@ +## input + +```ts title="custom_scalars/DefineCustomScalarWithDescription.ts" +/** @gqlType */ +class SomeType { + /** @gqlField */ + hello: string; +} + +/** + * Use this for URLs. + * @gqlScalar + */ +export type MyUrl = string; +``` + +## Output + +### SDL + +```graphql +"""Use this for URLs.""" +scalar MyUrl + +type SomeType { + hello: String +} +``` + +### TypeScript + +```ts +import type { GqlScalar } from "grats"; +import type { MyUrl as MyUrlInternal } from "./DefineCustomScalarWithDescription"; +import { GraphQLSchema, GraphQLScalarType, GraphQLObjectType, GraphQLString } from "graphql"; +export type SchemaConfig = { + scalars: { + MyUrl: GqlScalar; + }; +}; +export function getSchema(config: SchemaConfig): GraphQLSchema { + const MyUrlType: GraphQLScalarType = new GraphQLScalarType({ + description: "Use this for URLs.", + name: "MyUrl", + ...config.scalars.MyUrl + }); + const SomeTypeType: GraphQLObjectType = new GraphQLObjectType({ + name: "SomeType", + fields() { + return { + hello: { + name: "hello", + type: GraphQLString + } + }; + } + }); + return new GraphQLSchema({ + types: [MyUrlType, SomeTypeType] + }); +} +``` \ No newline at end of file diff --git a/src/tests/fixtures/custom_scalars/DefineRenamedCustomScalar.ts.expected b/src/tests/fixtures/custom_scalars/DefineRenamedCustomScalar.ts.expected deleted file mode 100644 index c378b3b6..00000000 --- a/src/tests/fixtures/custom_scalars/DefineRenamedCustomScalar.ts.expected +++ /dev/null @@ -1,50 +0,0 @@ ------------------ -INPUT ------------------ -/** @gqlType */ -class SomeType { - /** @gqlField */ - hello: string; -} - -/** @gqlScalar CustomName */ -export type MyUrl = string; - ------------------ -OUTPUT ------------------ --- SDL -- -scalar CustomName - -type SomeType { - hello: String -} --- TypeScript -- -import type { GqlScalar } from "grats"; -import type { MyUrl as CustomNameInternal } from "./DefineRenamedCustomScalar"; -import { GraphQLSchema, GraphQLScalarType, GraphQLObjectType, GraphQLString } from "graphql"; -export type SchemaConfig = { - scalars: { - CustomName: GqlScalar; - }; -}; -export function getSchema(config: SchemaConfig): GraphQLSchema { - const CustomNameType: GraphQLScalarType = new GraphQLScalarType({ - name: "CustomName", - ...config.scalars.CustomName - }); - const SomeTypeType: GraphQLObjectType = new GraphQLObjectType({ - name: "SomeType", - fields() { - return { - hello: { - name: "hello", - type: GraphQLString - } - }; - } - }); - return new GraphQLSchema({ - types: [CustomNameType, SomeTypeType] - }); -} diff --git a/src/tests/fixtures/custom_scalars/DefineRenamedCustomScalar.ts.expected.md b/src/tests/fixtures/custom_scalars/DefineRenamedCustomScalar.ts.expected.md new file mode 100644 index 00000000..4ffbbaa0 --- /dev/null +++ b/src/tests/fixtures/custom_scalars/DefineRenamedCustomScalar.ts.expected.md @@ -0,0 +1,57 @@ +## input + +```ts title="custom_scalars/DefineRenamedCustomScalar.ts" +/** @gqlType */ +class SomeType { + /** @gqlField */ + hello: string; +} + +/** @gqlScalar CustomName */ +export type MyUrl = string; +``` + +## Output + +### SDL + +```graphql +scalar CustomName + +type SomeType { + hello: String +} +``` + +### TypeScript + +```ts +import type { GqlScalar } from "grats"; +import type { MyUrl as CustomNameInternal } from "./DefineRenamedCustomScalar"; +import { GraphQLSchema, GraphQLScalarType, GraphQLObjectType, GraphQLString } from "graphql"; +export type SchemaConfig = { + scalars: { + CustomName: GqlScalar; + }; +}; +export function getSchema(config: SchemaConfig): GraphQLSchema { + const CustomNameType: GraphQLScalarType = new GraphQLScalarType({ + name: "CustomName", + ...config.scalars.CustomName + }); + const SomeTypeType: GraphQLObjectType = new GraphQLObjectType({ + name: "SomeType", + fields() { + return { + hello: { + name: "hello", + type: GraphQLString + } + }; + } + }); + return new GraphQLSchema({ + types: [CustomNameType, SomeTypeType] + }); +} +``` \ No newline at end of file diff --git a/src/tests/fixtures/custom_scalars/SpecifiedBy.ts.expected b/src/tests/fixtures/custom_scalars/SpecifiedBy.ts.expected deleted file mode 100644 index 82a51609..00000000 --- a/src/tests/fixtures/custom_scalars/SpecifiedBy.ts.expected +++ /dev/null @@ -1,33 +0,0 @@ ------------------ -INPUT ------------------ -/** - * @gqlScalar - * @gqlAnnotate specifiedBy(url: "https://tools.ietf.org/html/rfc4122") - */ -export type UUID = string; - ------------------ -OUTPUT ------------------ --- SDL -- -scalar UUID @specifiedBy(url: "https://tools.ietf.org/html/rfc4122") --- TypeScript -- -import type { GqlScalar } from "grats"; -import type { UUID as UUIDInternal } from "./SpecifiedBy"; -import { GraphQLSchema, GraphQLScalarType } from "graphql"; -export type SchemaConfig = { - scalars: { - UUID: GqlScalar; - }; -}; -export function getSchema(config: SchemaConfig): GraphQLSchema { - const UUIDType: GraphQLScalarType = new GraphQLScalarType({ - specifiedByURL: "https://tools.ietf.org/html/rfc4122", - name: "UUID", - ...config.scalars.UUID - }); - return new GraphQLSchema({ - types: [UUIDType] - }); -} diff --git a/src/tests/fixtures/custom_scalars/SpecifiedBy.ts.expected.md b/src/tests/fixtures/custom_scalars/SpecifiedBy.ts.expected.md new file mode 100644 index 00000000..e329197c --- /dev/null +++ b/src/tests/fixtures/custom_scalars/SpecifiedBy.ts.expected.md @@ -0,0 +1,40 @@ +## input + +```ts title="custom_scalars/SpecifiedBy.ts" +/** + * @gqlScalar + * @gqlAnnotate specifiedBy(url: "https://tools.ietf.org/html/rfc4122") + */ +export type UUID = string; +``` + +## Output + +### SDL + +```graphql +scalar UUID @specifiedBy(url: "https://tools.ietf.org/html/rfc4122") +``` + +### TypeScript + +```ts +import type { GqlScalar } from "grats"; +import type { UUID as UUIDInternal } from "./SpecifiedBy"; +import { GraphQLSchema, GraphQLScalarType } from "graphql"; +export type SchemaConfig = { + scalars: { + UUID: GqlScalar; + }; +}; +export function getSchema(config: SchemaConfig): GraphQLSchema { + const UUIDType: GraphQLScalarType = new GraphQLScalarType({ + specifiedByURL: "https://tools.ietf.org/html/rfc4122", + name: "UUID", + ...config.scalars.UUID + }); + return new GraphQLSchema({ + types: [UUIDType] + }); +} +``` \ No newline at end of file diff --git a/src/tests/fixtures/custom_scalars/SpecifiedByMissingUrlinvalid.invalid.ts.expected b/src/tests/fixtures/custom_scalars/SpecifiedByMissingUrlinvalid.invalid.ts.expected deleted file mode 100644 index 75a77e10..00000000 --- a/src/tests/fixtures/custom_scalars/SpecifiedByMissingUrlinvalid.invalid.ts.expected +++ /dev/null @@ -1,18 +0,0 @@ ------------------ -INPUT ------------------ -/** - * @gqlScalar - * @gqlAnnotate specifiedBy - */ -export type UUID = string; - ------------------ -OUTPUT ------------------ -src/tests/fixtures/custom_scalars/SpecifiedByMissingUrlinvalid.invalid.ts:3:4 - error: Directive "@specifiedBy" argument "url" of type "String!" is required, but it was not provided. - -3 * @gqlAnnotate specifiedBy - ~~~~~~~~~~~~~~~~~~~~~~~~ -4 */ - ~ diff --git a/src/tests/fixtures/custom_scalars/SpecifiedByMissingUrlinvalid.invalid.ts.expected.md b/src/tests/fixtures/custom_scalars/SpecifiedByMissingUrlinvalid.invalid.ts.expected.md new file mode 100644 index 00000000..34140b37 --- /dev/null +++ b/src/tests/fixtures/custom_scalars/SpecifiedByMissingUrlinvalid.invalid.ts.expected.md @@ -0,0 +1,22 @@ +## input + +```ts title="custom_scalars/SpecifiedByMissingUrlinvalid.invalid.ts" +/** + * @gqlScalar + * @gqlAnnotate specifiedBy + */ +export type UUID = string; +``` + +## Output + +### Error Report + +```text +src/tests/fixtures/custom_scalars/SpecifiedByMissingUrlinvalid.invalid.ts:3:4 - error: Directive "@specifiedBy" argument "url" of type "String!" is required, but it was not provided. + +3 * @gqlAnnotate specifiedBy + ~~~~~~~~~~~~~~~~~~~~~~~~ +4 */ + ~ +``` \ No newline at end of file diff --git a/src/tests/fixtures/custom_scalars/SpecifiedByOldSyntax.invalid.ts.expected b/src/tests/fixtures/custom_scalars/SpecifiedByOldSyntax.invalid.ts.expected deleted file mode 100644 index 38fd461b..00000000 --- a/src/tests/fixtures/custom_scalars/SpecifiedByOldSyntax.invalid.ts.expected +++ /dev/null @@ -1,40 +0,0 @@ ------------------ -INPUT ------------------ -/** - * @gqlScalar - * @specifiedBy https://tools.ietf.org/html/rfc4122 - */ -export type UUID = string; - ------------------ -OUTPUT ------------------ --- Error Report -- -src/tests/fixtures/custom_scalars/SpecifiedByOldSyntax.invalid.ts:3:4 - error: The `@specifiedBy` tag has been deprecated in favor of `@gqlAnnotate`. Use `@gqlAnnotate specifiedBy(url: "http://example.com")` instead. - -3 * @specifiedBy https://tools.ietf.org/html/rfc4122 - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -4 */ - ~ - - --- Code Action: "Replace @specifiedBy with @gqlAnnotate" (replace-specifiedBy-with-gqlAnnotate) -- -- Original -+ Fixed - -@@ -2,4 +2,3 @@ - * @gqlScalar -- * @specifiedBy https://tools.ietf.org/html/rfc4122 -- */ -+ * @gqlAnnotate specifiedBy(url: "https://tools.ietf.org/html/rfc4122")*/ - export type UUID = string; - --- Applied Fixes -- - * Applied fix "Replace @specifiedBy with @gqlAnnotate" in grats/src/tests/fixtures/custom_scalars/SpecifiedByOldSyntax.invalid.ts - --- Fixed Text -- -/** - * @gqlScalar - * @gqlAnnotate specifiedBy(url: "https://tools.ietf.org/html/rfc4122")*/ -export type UUID = string; diff --git a/src/tests/fixtures/custom_scalars/SpecifiedByOldSyntax.invalid.ts.expected.md b/src/tests/fixtures/custom_scalars/SpecifiedByOldSyntax.invalid.ts.expected.md new file mode 100644 index 00000000..cee29306 --- /dev/null +++ b/src/tests/fixtures/custom_scalars/SpecifiedByOldSyntax.invalid.ts.expected.md @@ -0,0 +1,51 @@ +## input + +```ts title="custom_scalars/SpecifiedByOldSyntax.invalid.ts" +/** + * @gqlScalar + * @specifiedBy https://tools.ietf.org/html/rfc4122 + */ +export type UUID = string; +``` + +## Output + +### Error Report + +```text +src/tests/fixtures/custom_scalars/SpecifiedByOldSyntax.invalid.ts:3:4 - error: The `@specifiedBy` tag has been deprecated in favor of `@gqlAnnotate`. Use `@gqlAnnotate specifiedBy(url: "http://example.com")` instead. + +3 * @specifiedBy https://tools.ietf.org/html/rfc4122 + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +4 */ + ~ +``` + +#### Code Action: "Replace @specifiedBy with @gqlAnnotate" (replace-specifiedBy-with-gqlAnnotate) + +```diff +- Original ++ Fixed + +@@ -2,4 +2,3 @@ + * @gqlScalar +- * @specifiedBy https://tools.ietf.org/html/rfc4122 +- */ ++ * @gqlAnnotate specifiedBy(url: "https://tools.ietf.org/html/rfc4122")*/ + export type UUID = string; +``` + +#### Applied Fixes + +```text + * Applied fix "Replace @specifiedBy with @gqlAnnotate" in grats/src/tests/fixtures/custom_scalars/SpecifiedByOldSyntax.invalid.ts +``` + +#### Fixed Text + +```typescript +/** + * @gqlScalar + * @gqlAnnotate specifiedBy(url: "https://tools.ietf.org/html/rfc4122")*/ +export type UUID = string; +``` \ No newline at end of file diff --git a/src/tests/fixtures/custom_scalars/SpecifiedByOnEnum.invalid.ts.expected b/src/tests/fixtures/custom_scalars/SpecifiedByOnEnum.invalid.ts.expected deleted file mode 100644 index 8a874364..00000000 --- a/src/tests/fixtures/custom_scalars/SpecifiedByOnEnum.invalid.ts.expected +++ /dev/null @@ -1,18 +0,0 @@ ------------------ -INPUT ------------------ -/** - * @gqlEnum - * @gqlAnnotate specifiedBy(url: "https://tools.ietf.org/html/rfc4122") - */ -export type MyEnum = "A" | "B" | "C"; - ------------------ -OUTPUT ------------------ -src/tests/fixtures/custom_scalars/SpecifiedByOnEnum.invalid.ts:3:4 - error: Directive "@specifiedBy" may not be used on ENUM. - -3 * @gqlAnnotate specifiedBy(url: "https://tools.ietf.org/html/rfc4122") - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -4 */ - ~ diff --git a/src/tests/fixtures/custom_scalars/SpecifiedByOnEnum.invalid.ts.expected.md b/src/tests/fixtures/custom_scalars/SpecifiedByOnEnum.invalid.ts.expected.md new file mode 100644 index 00000000..0b88c58b --- /dev/null +++ b/src/tests/fixtures/custom_scalars/SpecifiedByOnEnum.invalid.ts.expected.md @@ -0,0 +1,22 @@ +## input + +```ts title="custom_scalars/SpecifiedByOnEnum.invalid.ts" +/** + * @gqlEnum + * @gqlAnnotate specifiedBy(url: "https://tools.ietf.org/html/rfc4122") + */ +export type MyEnum = "A" | "B" | "C"; +``` + +## Output + +### Error Report + +```text +src/tests/fixtures/custom_scalars/SpecifiedByOnEnum.invalid.ts:3:4 - error: Directive "@specifiedBy" may not be used on ENUM. + +3 * @gqlAnnotate specifiedBy(url: "https://tools.ietf.org/html/rfc4122") + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +4 */ + ~ +``` \ No newline at end of file diff --git a/src/tests/fixtures/custom_scalars/TagAttachedToWrongNode.invalid.ts.expected b/src/tests/fixtures/custom_scalars/TagAttachedToWrongNode.invalid.ts.expected deleted file mode 100644 index 4a2d8c70..00000000 --- a/src/tests/fixtures/custom_scalars/TagAttachedToWrongNode.invalid.ts.expected +++ /dev/null @@ -1,13 +0,0 @@ ------------------ -INPUT ------------------ -/** @gqlScalar Matrix */ -function Foo() {} - ------------------ -OUTPUT ------------------ -src/tests/fixtures/custom_scalars/TagAttachedToWrongNode.invalid.ts:1:5 - error: `@gqlScalar` can only be used on type alias declarations. e.g. `type MyScalar = string` - -1 /** @gqlScalar Matrix */ - ~~~~~~~~~~~~~~~~~~ diff --git a/src/tests/fixtures/custom_scalars/TagAttachedToWrongNode.invalid.ts.expected.md b/src/tests/fixtures/custom_scalars/TagAttachedToWrongNode.invalid.ts.expected.md new file mode 100644 index 00000000..8852dff4 --- /dev/null +++ b/src/tests/fixtures/custom_scalars/TagAttachedToWrongNode.invalid.ts.expected.md @@ -0,0 +1,17 @@ +## input + +```ts title="custom_scalars/TagAttachedToWrongNode.invalid.ts" +/** @gqlScalar Matrix */ +function Foo() {} +``` + +## Output + +### Error Report + +```text +src/tests/fixtures/custom_scalars/TagAttachedToWrongNode.invalid.ts:1:5 - error: `@gqlScalar` can only be used on type alias declarations. e.g. `type MyScalar = string` + +1 /** @gqlScalar Matrix */ + ~~~~~~~~~~~~~~~~~~ +``` \ No newline at end of file diff --git a/src/tests/fixtures/default_values/DefaultArgumentArray.ts.expected b/src/tests/fixtures/default_values/DefaultArgumentArray.ts.expected deleted file mode 100644 index 68064910..00000000 --- a/src/tests/fixtures/default_values/DefaultArgumentArray.ts.expected +++ /dev/null @@ -1,52 +0,0 @@ ------------------ -INPUT ------------------ -/** @gqlType */ -export default class SomeType { - /** @gqlField */ - someField1({ - inputs = ["hello", "there"], - }: { - inputs?: string[] | null; - }): string { - if (inputs === null) { - return "got null"; - } - return inputs.join("|"); - } -} - ------------------ -OUTPUT ------------------ --- SDL -- -type SomeType { - someField1(inputs: [String!] = ["hello", "there"]): String -} --- TypeScript -- -import { GraphQLSchema, GraphQLObjectType, GraphQLString, GraphQLList, GraphQLNonNull } from "graphql"; -export function getSchema(): GraphQLSchema { - const SomeTypeType: GraphQLObjectType = new GraphQLObjectType({ - name: "SomeType", - fields() { - return { - someField1: { - name: "someField1", - type: GraphQLString, - args: { - inputs: { - type: new GraphQLList(new GraphQLNonNull(GraphQLString)), - defaultValue: [ - "hello", - "there" - ] - } - } - } - }; - } - }); - return new GraphQLSchema({ - types: [SomeTypeType] - }); -} diff --git a/src/tests/fixtures/default_values/DefaultArgumentArray.ts.expected.md b/src/tests/fixtures/default_values/DefaultArgumentArray.ts.expected.md new file mode 100644 index 00000000..ab5ded19 --- /dev/null +++ b/src/tests/fixtures/default_values/DefaultArgumentArray.ts.expected.md @@ -0,0 +1,59 @@ +## input + +```ts title="default_values/DefaultArgumentArray.ts" +/** @gqlType */ +export default class SomeType { + /** @gqlField */ + someField1({ + inputs = ["hello", "there"], + }: { + inputs?: string[] | null; + }): string { + if (inputs === null) { + return "got null"; + } + return inputs.join("|"); + } +} +``` + +## Output + +### SDL + +```graphql +type SomeType { + someField1(inputs: [String!] = ["hello", "there"]): String +} +``` + +### TypeScript + +```ts +import { GraphQLSchema, GraphQLObjectType, GraphQLString, GraphQLList, GraphQLNonNull } from "graphql"; +export function getSchema(): GraphQLSchema { + const SomeTypeType: GraphQLObjectType = new GraphQLObjectType({ + name: "SomeType", + fields() { + return { + someField1: { + name: "someField1", + type: GraphQLString, + args: { + inputs: { + type: new GraphQLList(new GraphQLNonNull(GraphQLString)), + defaultValue: [ + "hello", + "there" + ] + } + } + } + }; + } + }); + return new GraphQLSchema({ + types: [SomeTypeType] + }); +} +``` \ No newline at end of file diff --git a/src/tests/fixtures/default_values/DefaultArgumentArrayValuesInvalid.invalid.ts.expected b/src/tests/fixtures/default_values/DefaultArgumentArrayValuesInvalid.invalid.ts.expected deleted file mode 100644 index a0799fb5..00000000 --- a/src/tests/fixtures/default_values/DefaultArgumentArrayValuesInvalid.invalid.ts.expected +++ /dev/null @@ -1,37 +0,0 @@ ------------------ -INPUT ------------------ -/** @gqlType */ -export default class SomeType { - /** @gqlField */ - someField1({ - inputs = [func(), func()], - }: { - inputs?: string[] | null; - }): string { - if (inputs === null) { - return "got null"; - } - return inputs.join("|"); - } -} - -function func(): string { - return "sup"; -} - ------------------ -OUTPUT ------------------ -src/tests/fixtures/default_values/DefaultArgumentArrayValuesInvalid.invalid.ts:5:15 - error: Expected GraphQL field argument default values to be a literal. Grats interprets argument defaults as GraphQL default values, which must be literals. For example: `10` or `"foo"`. - -If you think Grats should be able to infer this constant value, please report an issue at https://github.com/captbaritone/grats/issues. - -5 inputs = [func(), func()], - ~~~~~~ -src/tests/fixtures/default_values/DefaultArgumentArrayValuesInvalid.invalid.ts:5:23 - error: Expected GraphQL field argument default values to be a literal. Grats interprets argument defaults as GraphQL default values, which must be literals. For example: `10` or `"foo"`. - -If you think Grats should be able to infer this constant value, please report an issue at https://github.com/captbaritone/grats/issues. - -5 inputs = [func(), func()], - ~~~~~~ diff --git a/src/tests/fixtures/default_values/DefaultArgumentArrayValuesInvalid.invalid.ts.expected.md b/src/tests/fixtures/default_values/DefaultArgumentArrayValuesInvalid.invalid.ts.expected.md new file mode 100644 index 00000000..6a463d3d --- /dev/null +++ b/src/tests/fixtures/default_values/DefaultArgumentArrayValuesInvalid.invalid.ts.expected.md @@ -0,0 +1,41 @@ +## input + +```ts title="default_values/DefaultArgumentArrayValuesInvalid.invalid.ts" +/** @gqlType */ +export default class SomeType { + /** @gqlField */ + someField1({ + inputs = [func(), func()], + }: { + inputs?: string[] | null; + }): string { + if (inputs === null) { + return "got null"; + } + return inputs.join("|"); + } +} + +function func(): string { + return "sup"; +} +``` + +## Output + +### Error Report + +```text +src/tests/fixtures/default_values/DefaultArgumentArrayValuesInvalid.invalid.ts:5:15 - error: Expected GraphQL field argument default values to be a literal. Grats interprets argument defaults as GraphQL default values, which must be literals. For example: `10` or `"foo"`. + +If you think Grats should be able to infer this constant value, please report an issue at https://github.com/captbaritone/grats/issues. + +5 inputs = [func(), func()], + ~~~~~~ +src/tests/fixtures/default_values/DefaultArgumentArrayValuesInvalid.invalid.ts:5:23 - error: Expected GraphQL field argument default values to be a literal. Grats interprets argument defaults as GraphQL default values, which must be literals. For example: `10` or `"foo"`. + +If you think Grats should be able to infer this constant value, please report an issue at https://github.com/captbaritone/grats/issues. + +5 inputs = [func(), func()], + ~~~~~~ +``` \ No newline at end of file diff --git a/src/tests/fixtures/default_values/DefaultArgumentBooleanLiteral.ts.expected b/src/tests/fixtures/default_values/DefaultArgumentBooleanLiteral.ts.expected deleted file mode 100644 index 11d274c0..00000000 --- a/src/tests/fixtures/default_values/DefaultArgumentBooleanLiteral.ts.expected +++ /dev/null @@ -1,60 +0,0 @@ ------------------ -INPUT ------------------ -/** @gqlType */ -export default class SomeType { - /** @gqlField */ - someField1({ greet = false }: { greet?: boolean | null }): string { - if (!greet) return ""; - return "hello"; - } - - /** @gqlField */ - someField2({ greet = true }: { greet?: boolean | null }): string { - if (!greet) return ""; - return "hello"; - } -} - ------------------ -OUTPUT ------------------ --- SDL -- -type SomeType { - someField1(greet: Boolean = false): String - someField2(greet: Boolean = true): String -} --- TypeScript -- -import { GraphQLSchema, GraphQLObjectType, GraphQLString, GraphQLBoolean } from "graphql"; -export function getSchema(): GraphQLSchema { - const SomeTypeType: GraphQLObjectType = new GraphQLObjectType({ - name: "SomeType", - fields() { - return { - someField1: { - name: "someField1", - type: GraphQLString, - args: { - greet: { - type: GraphQLBoolean, - defaultValue: false - } - } - }, - someField2: { - name: "someField2", - type: GraphQLString, - args: { - greet: { - type: GraphQLBoolean, - defaultValue: true - } - } - } - }; - } - }); - return new GraphQLSchema({ - types: [SomeTypeType] - }); -} diff --git a/src/tests/fixtures/default_values/DefaultArgumentBooleanLiteral.ts.expected.md b/src/tests/fixtures/default_values/DefaultArgumentBooleanLiteral.ts.expected.md new file mode 100644 index 00000000..d1bbd33b --- /dev/null +++ b/src/tests/fixtures/default_values/DefaultArgumentBooleanLiteral.ts.expected.md @@ -0,0 +1,67 @@ +## input + +```ts title="default_values/DefaultArgumentBooleanLiteral.ts" +/** @gqlType */ +export default class SomeType { + /** @gqlField */ + someField1({ greet = false }: { greet?: boolean | null }): string { + if (!greet) return ""; + return "hello"; + } + + /** @gqlField */ + someField2({ greet = true }: { greet?: boolean | null }): string { + if (!greet) return ""; + return "hello"; + } +} +``` + +## Output + +### SDL + +```graphql +type SomeType { + someField1(greet: Boolean = false): String + someField2(greet: Boolean = true): String +} +``` + +### TypeScript + +```ts +import { GraphQLSchema, GraphQLObjectType, GraphQLString, GraphQLBoolean } from "graphql"; +export function getSchema(): GraphQLSchema { + const SomeTypeType: GraphQLObjectType = new GraphQLObjectType({ + name: "SomeType", + fields() { + return { + someField1: { + name: "someField1", + type: GraphQLString, + args: { + greet: { + type: GraphQLBoolean, + defaultValue: false + } + } + }, + someField2: { + name: "someField2", + type: GraphQLString, + args: { + greet: { + type: GraphQLBoolean, + defaultValue: true + } + } + } + }; + } + }); + return new GraphQLSchema({ + types: [SomeTypeType] + }); +} +``` \ No newline at end of file diff --git a/src/tests/fixtures/default_values/DefaultArgumentNullLiteral.ts.expected b/src/tests/fixtures/default_values/DefaultArgumentNullLiteral.ts.expected deleted file mode 100644 index 8a9192f7..00000000 --- a/src/tests/fixtures/default_values/DefaultArgumentNullLiteral.ts.expected +++ /dev/null @@ -1,59 +0,0 @@ ------------------ -INPUT ------------------ -/** @gqlType */ -export default class SomeType { - /** @gqlField */ - someField1({ hello = null }: { hello?: string | null }): string { - if (hello === null) return "hello"; - return "hello"; - } - /** @gqlField */ - someField2({ hello = undefined }: { hello?: string | undefined }): string { - if (hello === null) return "hello"; - return "hello"; - } -} - ------------------ -OUTPUT ------------------ --- SDL -- -type SomeType { - someField1(hello: String = null): String - someField2(hello: String = null): String -} --- TypeScript -- -import { GraphQLSchema, GraphQLObjectType, GraphQLString } from "graphql"; -export function getSchema(): GraphQLSchema { - const SomeTypeType: GraphQLObjectType = new GraphQLObjectType({ - name: "SomeType", - fields() { - return { - someField1: { - name: "someField1", - type: GraphQLString, - args: { - hello: { - type: GraphQLString, - defaultValue: null - } - } - }, - someField2: { - name: "someField2", - type: GraphQLString, - args: { - hello: { - type: GraphQLString, - defaultValue: null - } - } - } - }; - } - }); - return new GraphQLSchema({ - types: [SomeTypeType] - }); -} diff --git a/src/tests/fixtures/default_values/DefaultArgumentNullLiteral.ts.expected.md b/src/tests/fixtures/default_values/DefaultArgumentNullLiteral.ts.expected.md new file mode 100644 index 00000000..fc579cd7 --- /dev/null +++ b/src/tests/fixtures/default_values/DefaultArgumentNullLiteral.ts.expected.md @@ -0,0 +1,66 @@ +## input + +```ts title="default_values/DefaultArgumentNullLiteral.ts" +/** @gqlType */ +export default class SomeType { + /** @gqlField */ + someField1({ hello = null }: { hello?: string | null }): string { + if (hello === null) return "hello"; + return "hello"; + } + /** @gqlField */ + someField2({ hello = undefined }: { hello?: string | undefined }): string { + if (hello === null) return "hello"; + return "hello"; + } +} +``` + +## Output + +### SDL + +```graphql +type SomeType { + someField1(hello: String = null): String + someField2(hello: String = null): String +} +``` + +### TypeScript + +```ts +import { GraphQLSchema, GraphQLObjectType, GraphQLString } from "graphql"; +export function getSchema(): GraphQLSchema { + const SomeTypeType: GraphQLObjectType = new GraphQLObjectType({ + name: "SomeType", + fields() { + return { + someField1: { + name: "someField1", + type: GraphQLString, + args: { + hello: { + type: GraphQLString, + defaultValue: null + } + } + }, + someField2: { + name: "someField2", + type: GraphQLString, + args: { + hello: { + type: GraphQLString, + defaultValue: null + } + } + } + }; + } + }); + return new GraphQLSchema({ + types: [SomeTypeType] + }); +} +``` \ No newline at end of file diff --git a/src/tests/fixtures/default_values/DefaultArgumentNumberLiteral.ts.expected b/src/tests/fixtures/default_values/DefaultArgumentNumberLiteral.ts.expected deleted file mode 100644 index 30387b80..00000000 --- a/src/tests/fixtures/default_values/DefaultArgumentNumberLiteral.ts.expected +++ /dev/null @@ -1,59 +0,0 @@ ------------------ -INPUT ------------------ -import { Float, Int } from "../../../Types"; - -/** @gqlType */ -export default class SomeType { - /** @gqlField */ - intField({ count = 10 }: { count: Int }): string { - return `${count} world!`; - } - /** @gqlField */ - floatField({ scale = 10.0 }: { scale: Float }): string { - return `${scale} world!`; - } -} - ------------------ -OUTPUT ------------------ --- SDL -- -type SomeType { - floatField(scale: Float! = 10): String - intField(count: Int! = 10): String -} --- TypeScript -- -import { GraphQLSchema, GraphQLObjectType, GraphQLString, GraphQLNonNull, GraphQLFloat, GraphQLInt } from "graphql"; -export function getSchema(): GraphQLSchema { - const SomeTypeType: GraphQLObjectType = new GraphQLObjectType({ - name: "SomeType", - fields() { - return { - floatField: { - name: "floatField", - type: GraphQLString, - args: { - scale: { - type: new GraphQLNonNull(GraphQLFloat), - defaultValue: 10 - } - } - }, - intField: { - name: "intField", - type: GraphQLString, - args: { - count: { - type: new GraphQLNonNull(GraphQLInt), - defaultValue: 10 - } - } - } - }; - } - }); - return new GraphQLSchema({ - types: [SomeTypeType] - }); -} diff --git a/src/tests/fixtures/default_values/DefaultArgumentNumberLiteral.ts.expected.md b/src/tests/fixtures/default_values/DefaultArgumentNumberLiteral.ts.expected.md new file mode 100644 index 00000000..d7b214c6 --- /dev/null +++ b/src/tests/fixtures/default_values/DefaultArgumentNumberLiteral.ts.expected.md @@ -0,0 +1,66 @@ +## input + +```ts title="default_values/DefaultArgumentNumberLiteral.ts" +import { Float, Int } from "../../../Types"; + +/** @gqlType */ +export default class SomeType { + /** @gqlField */ + intField({ count = 10 }: { count: Int }): string { + return `${count} world!`; + } + /** @gqlField */ + floatField({ scale = 10.0 }: { scale: Float }): string { + return `${scale} world!`; + } +} +``` + +## Output + +### SDL + +```graphql +type SomeType { + floatField(scale: Float! = 10): String + intField(count: Int! = 10): String +} +``` + +### TypeScript + +```ts +import { GraphQLSchema, GraphQLObjectType, GraphQLString, GraphQLNonNull, GraphQLFloat, GraphQLInt } from "graphql"; +export function getSchema(): GraphQLSchema { + const SomeTypeType: GraphQLObjectType = new GraphQLObjectType({ + name: "SomeType", + fields() { + return { + floatField: { + name: "floatField", + type: GraphQLString, + args: { + scale: { + type: new GraphQLNonNull(GraphQLFloat), + defaultValue: 10 + } + } + }, + intField: { + name: "intField", + type: GraphQLString, + args: { + count: { + type: new GraphQLNonNull(GraphQLInt), + defaultValue: 10 + } + } + } + }; + } + }); + return new GraphQLSchema({ + types: [SomeTypeType] + }); +} +``` \ No newline at end of file diff --git a/src/tests/fixtures/default_values/DefaultArgumentObjectLiteral.ts.expected b/src/tests/fixtures/default_values/DefaultArgumentObjectLiteral.ts.expected deleted file mode 100644 index f99e6834..00000000 --- a/src/tests/fixtures/default_values/DefaultArgumentObjectLiteral.ts.expected +++ /dev/null @@ -1,77 +0,0 @@ ------------------ -INPUT ------------------ -import { Int } from "../../../Types"; - -/** @gqlType */ -export default class SomeType { - /** @gqlField */ - someField1({ - input = { first: 10, offset: 100 }, - }: { - input?: ConnectionInput | null; - }): string { - return "hello"; - } -} - -/** @gqlInput */ -type ConnectionInput = { - first: Int; - offset: Int; -}; - ------------------ -OUTPUT ------------------ --- SDL -- -input ConnectionInput { - first: Int! - offset: Int! -} - -type SomeType { - someField1(input: ConnectionInput = {first: 10, offset: 100}): String -} --- TypeScript -- -import { GraphQLSchema, GraphQLInputObjectType, GraphQLNonNull, GraphQLInt, GraphQLObjectType, GraphQLString } from "graphql"; -export function getSchema(): GraphQLSchema { - const ConnectionInputType: GraphQLInputObjectType = new GraphQLInputObjectType({ - name: "ConnectionInput", - fields() { - return { - first: { - name: "first", - type: new GraphQLNonNull(GraphQLInt) - }, - offset: { - name: "offset", - type: new GraphQLNonNull(GraphQLInt) - } - }; - } - }); - const SomeTypeType: GraphQLObjectType = new GraphQLObjectType({ - name: "SomeType", - fields() { - return { - someField1: { - name: "someField1", - type: GraphQLString, - args: { - input: { - type: ConnectionInputType, - defaultValue: { - first: 10, - offset: 100 - } - } - } - } - }; - } - }); - return new GraphQLSchema({ - types: [ConnectionInputType, SomeTypeType] - }); -} diff --git a/src/tests/fixtures/default_values/DefaultArgumentObjectLiteral.ts.expected.md b/src/tests/fixtures/default_values/DefaultArgumentObjectLiteral.ts.expected.md new file mode 100644 index 00000000..87efdd46 --- /dev/null +++ b/src/tests/fixtures/default_values/DefaultArgumentObjectLiteral.ts.expected.md @@ -0,0 +1,84 @@ +## input + +```ts title="default_values/DefaultArgumentObjectLiteral.ts" +import { Int } from "../../../Types"; + +/** @gqlType */ +export default class SomeType { + /** @gqlField */ + someField1({ + input = { first: 10, offset: 100 }, + }: { + input?: ConnectionInput | null; + }): string { + return "hello"; + } +} + +/** @gqlInput */ +type ConnectionInput = { + first: Int; + offset: Int; +}; +``` + +## Output + +### SDL + +```graphql +input ConnectionInput { + first: Int! + offset: Int! +} + +type SomeType { + someField1(input: ConnectionInput = {first: 10, offset: 100}): String +} +``` + +### TypeScript + +```ts +import { GraphQLSchema, GraphQLInputObjectType, GraphQLNonNull, GraphQLInt, GraphQLObjectType, GraphQLString } from "graphql"; +export function getSchema(): GraphQLSchema { + const ConnectionInputType: GraphQLInputObjectType = new GraphQLInputObjectType({ + name: "ConnectionInput", + fields() { + return { + first: { + name: "first", + type: new GraphQLNonNull(GraphQLInt) + }, + offset: { + name: "offset", + type: new GraphQLNonNull(GraphQLInt) + } + }; + } + }); + const SomeTypeType: GraphQLObjectType = new GraphQLObjectType({ + name: "SomeType", + fields() { + return { + someField1: { + name: "someField1", + type: GraphQLString, + args: { + input: { + type: ConnectionInputType, + defaultValue: { + first: 10, + offset: 100 + } + } + } + } + }; + } + }); + return new GraphQLSchema({ + types: [ConnectionInputType, SomeTypeType] + }); +} +``` \ No newline at end of file diff --git a/src/tests/fixtures/default_values/DefaultArgumentObjectLiteralDynamicPropertyName.invalid.ts.expected b/src/tests/fixtures/default_values/DefaultArgumentObjectLiteralDynamicPropertyName.invalid.ts.expected deleted file mode 100644 index aa3d96ca..00000000 --- a/src/tests/fixtures/default_values/DefaultArgumentObjectLiteralDynamicPropertyName.invalid.ts.expected +++ /dev/null @@ -1,32 +0,0 @@ ------------------ -INPUT ------------------ -import { Int } from "../../../Types"; - -const x = "first"; - -/** @gqlType */ -export default class SomeType { - /** @gqlField */ - someField1({ - input = { [x]: 10, offset: 100 }, - }: { - input?: ConnectionInput | null; - }): string { - return "hello"; - } -} - -/** @gqlInput */ -type ConnectionInput = { - first: Int; - offset: Int; -}; - ------------------ -OUTPUT ------------------ -src/tests/fixtures/default_values/DefaultArgumentObjectLiteralDynamicPropertyName.invalid.ts:9:15 - error: Expected a name identifier. Grats expected to find a name here which it could use to derive the GraphQL name. - -9 input = { [x]: 10, offset: 100 }, - ~~~ diff --git a/src/tests/fixtures/default_values/DefaultArgumentObjectLiteralDynamicPropertyName.invalid.ts.expected.md b/src/tests/fixtures/default_values/DefaultArgumentObjectLiteralDynamicPropertyName.invalid.ts.expected.md new file mode 100644 index 00000000..31703ee9 --- /dev/null +++ b/src/tests/fixtures/default_values/DefaultArgumentObjectLiteralDynamicPropertyName.invalid.ts.expected.md @@ -0,0 +1,36 @@ +## input + +```ts title="default_values/DefaultArgumentObjectLiteralDynamicPropertyName.invalid.ts" +import { Int } from "../../../Types"; + +const x = "first"; + +/** @gqlType */ +export default class SomeType { + /** @gqlField */ + someField1({ + input = { [x]: 10, offset: 100 }, + }: { + input?: ConnectionInput | null; + }): string { + return "hello"; + } +} + +/** @gqlInput */ +type ConnectionInput = { + first: Int; + offset: Int; +}; +``` + +## Output + +### Error Report + +```text +src/tests/fixtures/default_values/DefaultArgumentObjectLiteralDynamicPropertyName.invalid.ts:9:15 - error: Expected a name identifier. Grats expected to find a name here which it could use to derive the GraphQL name. + +9 input = { [x]: 10, offset: 100 }, + ~~~ +``` \ No newline at end of file diff --git a/src/tests/fixtures/default_values/DefaultArgumentObjectLiteralInterpolation.invalid.ts.expected b/src/tests/fixtures/default_values/DefaultArgumentObjectLiteralInterpolation.invalid.ts.expected deleted file mode 100644 index 34b1929e..00000000 --- a/src/tests/fixtures/default_values/DefaultArgumentObjectLiteralInterpolation.invalid.ts.expected +++ /dev/null @@ -1,40 +0,0 @@ ------------------ -INPUT ------------------ -import { Int } from "../../../Types"; - -const first = 10; -const offset = 100; -/** @gqlType */ -export default class SomeType { - /** @gqlField */ - someField1({ - input = { first, offset }, - }: { - input?: ConnectionInput | null; - }): string { - return "hello"; - } -} - -/** @gqlInput */ -type ConnectionInput = { - first: Int; - offset: Int; -}; - ------------------ -OUTPUT ------------------ -src/tests/fixtures/default_values/DefaultArgumentObjectLiteralInterpolation.invalid.ts:9:15 - error: Expected property to be a default assignment. For example: `{ first = 10}`. Grats needs to extract a literal GraphQL value here, and that requires Grats being able to see the literal value in the source code. - -If you think Grats should be able to infer this constant value, please report an issue at https://github.com/captbaritone/grats/issues. - -9 input = { first, offset }, - ~~~~~ -src/tests/fixtures/default_values/DefaultArgumentObjectLiteralInterpolation.invalid.ts:9:22 - error: Expected property to be a default assignment. For example: `{ first = 10}`. Grats needs to extract a literal GraphQL value here, and that requires Grats being able to see the literal value in the source code. - -If you think Grats should be able to infer this constant value, please report an issue at https://github.com/captbaritone/grats/issues. - -9 input = { first, offset }, - ~~~~~~ diff --git a/src/tests/fixtures/default_values/DefaultArgumentObjectLiteralInterpolation.invalid.ts.expected.md b/src/tests/fixtures/default_values/DefaultArgumentObjectLiteralInterpolation.invalid.ts.expected.md new file mode 100644 index 00000000..703acd74 --- /dev/null +++ b/src/tests/fixtures/default_values/DefaultArgumentObjectLiteralInterpolation.invalid.ts.expected.md @@ -0,0 +1,44 @@ +## input + +```ts title="default_values/DefaultArgumentObjectLiteralInterpolation.invalid.ts" +import { Int } from "../../../Types"; + +const first = 10; +const offset = 100; +/** @gqlType */ +export default class SomeType { + /** @gqlField */ + someField1({ + input = { first, offset }, + }: { + input?: ConnectionInput | null; + }): string { + return "hello"; + } +} + +/** @gqlInput */ +type ConnectionInput = { + first: Int; + offset: Int; +}; +``` + +## Output + +### Error Report + +```text +src/tests/fixtures/default_values/DefaultArgumentObjectLiteralInterpolation.invalid.ts:9:15 - error: Expected property to be a default assignment. For example: `{ first = 10}`. Grats needs to extract a literal GraphQL value here, and that requires Grats being able to see the literal value in the source code. + +If you think Grats should be able to infer this constant value, please report an issue at https://github.com/captbaritone/grats/issues. + +9 input = { first, offset }, + ~~~~~ +src/tests/fixtures/default_values/DefaultArgumentObjectLiteralInterpolation.invalid.ts:9:22 - error: Expected property to be a default assignment. For example: `{ first = 10}`. Grats needs to extract a literal GraphQL value here, and that requires Grats being able to see the literal value in the source code. + +If you think Grats should be able to infer this constant value, please report an issue at https://github.com/captbaritone/grats/issues. + +9 input = { first, offset }, + ~~~~~~ +``` \ No newline at end of file diff --git a/src/tests/fixtures/default_values/DefaultArgumentObjectLiteralMultiplePropertyErrors.invalid.ts.expected b/src/tests/fixtures/default_values/DefaultArgumentObjectLiteralMultiplePropertyErrors.invalid.ts.expected deleted file mode 100644 index 752ea498..00000000 --- a/src/tests/fixtures/default_values/DefaultArgumentObjectLiteralMultiplePropertyErrors.invalid.ts.expected +++ /dev/null @@ -1,42 +0,0 @@ ------------------ -INPUT ------------------ -import { Int } from "../../../Types"; - -/** @gqlType */ -export default class SomeType { - /** @gqlField */ - someField1({ - input = { first: func(), offset: func() }, - }: { - input?: ConnectionInput | null; - }): string { - return "hello"; - } -} - -function func() { - return 10; -} - -/** @gqlInput */ -type ConnectionInput = { - first: Int; - offset: Int; -}; - ------------------ -OUTPUT ------------------ -src/tests/fixtures/default_values/DefaultArgumentObjectLiteralMultiplePropertyErrors.invalid.ts:7:22 - error: Expected GraphQL field argument default values to be a literal. Grats interprets argument defaults as GraphQL default values, which must be literals. For example: `10` or `"foo"`. - -If you think Grats should be able to infer this constant value, please report an issue at https://github.com/captbaritone/grats/issues. - -7 input = { first: func(), offset: func() }, - ~~~~~~ -src/tests/fixtures/default_values/DefaultArgumentObjectLiteralMultiplePropertyErrors.invalid.ts:7:38 - error: Expected GraphQL field argument default values to be a literal. Grats interprets argument defaults as GraphQL default values, which must be literals. For example: `10` or `"foo"`. - -If you think Grats should be able to infer this constant value, please report an issue at https://github.com/captbaritone/grats/issues. - -7 input = { first: func(), offset: func() }, - ~~~~~~ diff --git a/src/tests/fixtures/default_values/DefaultArgumentObjectLiteralMultiplePropertyErrors.invalid.ts.expected.md b/src/tests/fixtures/default_values/DefaultArgumentObjectLiteralMultiplePropertyErrors.invalid.ts.expected.md new file mode 100644 index 00000000..e167b689 --- /dev/null +++ b/src/tests/fixtures/default_values/DefaultArgumentObjectLiteralMultiplePropertyErrors.invalid.ts.expected.md @@ -0,0 +1,46 @@ +## input + +```ts title="default_values/DefaultArgumentObjectLiteralMultiplePropertyErrors.invalid.ts" +import { Int } from "../../../Types"; + +/** @gqlType */ +export default class SomeType { + /** @gqlField */ + someField1({ + input = { first: func(), offset: func() }, + }: { + input?: ConnectionInput | null; + }): string { + return "hello"; + } +} + +function func() { + return 10; +} + +/** @gqlInput */ +type ConnectionInput = { + first: Int; + offset: Int; +}; +``` + +## Output + +### Error Report + +```text +src/tests/fixtures/default_values/DefaultArgumentObjectLiteralMultiplePropertyErrors.invalid.ts:7:22 - error: Expected GraphQL field argument default values to be a literal. Grats interprets argument defaults as GraphQL default values, which must be literals. For example: `10` or `"foo"`. + +If you think Grats should be able to infer this constant value, please report an issue at https://github.com/captbaritone/grats/issues. + +7 input = { first: func(), offset: func() }, + ~~~~~~ +src/tests/fixtures/default_values/DefaultArgumentObjectLiteralMultiplePropertyErrors.invalid.ts:7:38 - error: Expected GraphQL field argument default values to be a literal. Grats interprets argument defaults as GraphQL default values, which must be literals. For example: `10` or `"foo"`. + +If you think Grats should be able to infer this constant value, please report an issue at https://github.com/captbaritone/grats/issues. + +7 input = { first: func(), offset: func() }, + ~~~~~~ +``` \ No newline at end of file diff --git a/src/tests/fixtures/default_values/DefaultArgumentObjectLiteralSpread.invalid.ts.expected b/src/tests/fixtures/default_values/DefaultArgumentObjectLiteralSpread.invalid.ts.expected deleted file mode 100644 index d8f35aa8..00000000 --- a/src/tests/fixtures/default_values/DefaultArgumentObjectLiteralSpread.invalid.ts.expected +++ /dev/null @@ -1,34 +0,0 @@ ------------------ -INPUT ------------------ -import { Int } from "../../../Types"; - -const defaultArgs = { first: 10, offset: 10 }; - -/** @gqlType */ -export default class SomeType { - /** @gqlField */ - someField1({ - input = { ...defaultArgs }, - }: { - input?: ConnectionInput | null; - }): string { - return "hello"; - } -} - -/** @gqlInput */ -type ConnectionInput = { - first: Int; - offset: Int; -}; - ------------------ -OUTPUT ------------------ -src/tests/fixtures/default_values/DefaultArgumentObjectLiteralSpread.invalid.ts:9:15 - error: Expected property to be a default assignment. For example: `{ first = 10}`. Grats needs to extract a literal GraphQL value here, and that requires Grats being able to see the literal value in the source code. - -If you think Grats should be able to infer this constant value, please report an issue at https://github.com/captbaritone/grats/issues. - -9 input = { ...defaultArgs }, - ~~~~~~~~~~~~~~ diff --git a/src/tests/fixtures/default_values/DefaultArgumentObjectLiteralSpread.invalid.ts.expected.md b/src/tests/fixtures/default_values/DefaultArgumentObjectLiteralSpread.invalid.ts.expected.md new file mode 100644 index 00000000..03e8898d --- /dev/null +++ b/src/tests/fixtures/default_values/DefaultArgumentObjectLiteralSpread.invalid.ts.expected.md @@ -0,0 +1,38 @@ +## input + +```ts title="default_values/DefaultArgumentObjectLiteralSpread.invalid.ts" +import { Int } from "../../../Types"; + +const defaultArgs = { first: 10, offset: 10 }; + +/** @gqlType */ +export default class SomeType { + /** @gqlField */ + someField1({ + input = { ...defaultArgs }, + }: { + input?: ConnectionInput | null; + }): string { + return "hello"; + } +} + +/** @gqlInput */ +type ConnectionInput = { + first: Int; + offset: Int; +}; +``` + +## Output + +### Error Report + +```text +src/tests/fixtures/default_values/DefaultArgumentObjectLiteralSpread.invalid.ts:9:15 - error: Expected property to be a default assignment. For example: `{ first = 10}`. Grats needs to extract a literal GraphQL value here, and that requires Grats being able to see the literal value in the source code. + +If you think Grats should be able to infer this constant value, please report an issue at https://github.com/captbaritone/grats/issues. + +9 input = { ...defaultArgs }, + ~~~~~~~~~~~~~~ +``` \ No newline at end of file diff --git a/src/tests/fixtures/default_values/DefaultArgumentPropertyName.ts.expected b/src/tests/fixtures/default_values/DefaultArgumentPropertyName.ts.expected deleted file mode 100644 index 9be72092..00000000 --- a/src/tests/fixtures/default_values/DefaultArgumentPropertyName.ts.expected +++ /dev/null @@ -1,42 +0,0 @@ ------------------ -INPUT ------------------ -/** @gqlType */ -export default class SomeType { - /** @gqlField */ - hello({ if: x = false }: { if: boolean }): string { - return x ? "hello" : "world"; - } -} - ------------------ -OUTPUT ------------------ --- SDL -- -type SomeType { - hello(if: Boolean! = false): String -} --- TypeScript -- -import { GraphQLSchema, GraphQLObjectType, GraphQLString, GraphQLNonNull, GraphQLBoolean } from "graphql"; -export function getSchema(): GraphQLSchema { - const SomeTypeType: GraphQLObjectType = new GraphQLObjectType({ - name: "SomeType", - fields() { - return { - hello: { - name: "hello", - type: GraphQLString, - args: { - if: { - type: new GraphQLNonNull(GraphQLBoolean), - defaultValue: false - } - } - } - }; - } - }); - return new GraphQLSchema({ - types: [SomeTypeType] - }); -} diff --git a/src/tests/fixtures/default_values/DefaultArgumentPropertyName.ts.expected.md b/src/tests/fixtures/default_values/DefaultArgumentPropertyName.ts.expected.md new file mode 100644 index 00000000..2a57a3db --- /dev/null +++ b/src/tests/fixtures/default_values/DefaultArgumentPropertyName.ts.expected.md @@ -0,0 +1,49 @@ +## input + +```ts title="default_values/DefaultArgumentPropertyName.ts" +/** @gqlType */ +export default class SomeType { + /** @gqlField */ + hello({ if: x = false }: { if: boolean }): string { + return x ? "hello" : "world"; + } +} +``` + +## Output + +### SDL + +```graphql +type SomeType { + hello(if: Boolean! = false): String +} +``` + +### TypeScript + +```ts +import { GraphQLSchema, GraphQLObjectType, GraphQLString, GraphQLNonNull, GraphQLBoolean } from "graphql"; +export function getSchema(): GraphQLSchema { + const SomeTypeType: GraphQLObjectType = new GraphQLObjectType({ + name: "SomeType", + fields() { + return { + hello: { + name: "hello", + type: GraphQLString, + args: { + if: { + type: new GraphQLNonNull(GraphQLBoolean), + defaultValue: false + } + } + } + }; + } + }); + return new GraphQLSchema({ + types: [SomeTypeType] + }); +} +``` \ No newline at end of file diff --git a/src/tests/fixtures/default_values/DefaultArgumentStringLiteral.ts.expected b/src/tests/fixtures/default_values/DefaultArgumentStringLiteral.ts.expected deleted file mode 100644 index e40fa82c..00000000 --- a/src/tests/fixtures/default_values/DefaultArgumentStringLiteral.ts.expected +++ /dev/null @@ -1,42 +0,0 @@ ------------------ -INPUT ------------------ -/** @gqlType */ -export default class SomeType { - /** @gqlField */ - hello({ greeting = "hello" }: { greeting: string }): string { - return `${greeting} world!`; - } -} - ------------------ -OUTPUT ------------------ --- SDL -- -type SomeType { - hello(greeting: String! = "hello"): String -} --- TypeScript -- -import { GraphQLSchema, GraphQLObjectType, GraphQLString, GraphQLNonNull } from "graphql"; -export function getSchema(): GraphQLSchema { - const SomeTypeType: GraphQLObjectType = new GraphQLObjectType({ - name: "SomeType", - fields() { - return { - hello: { - name: "hello", - type: GraphQLString, - args: { - greeting: { - type: new GraphQLNonNull(GraphQLString), - defaultValue: "hello" - } - } - } - }; - } - }); - return new GraphQLSchema({ - types: [SomeTypeType] - }); -} diff --git a/src/tests/fixtures/default_values/DefaultArgumentStringLiteral.ts.expected.md b/src/tests/fixtures/default_values/DefaultArgumentStringLiteral.ts.expected.md new file mode 100644 index 00000000..1c93e44c --- /dev/null +++ b/src/tests/fixtures/default_values/DefaultArgumentStringLiteral.ts.expected.md @@ -0,0 +1,49 @@ +## input + +```ts title="default_values/DefaultArgumentStringLiteral.ts" +/** @gqlType */ +export default class SomeType { + /** @gqlField */ + hello({ greeting = "hello" }: { greeting: string }): string { + return `${greeting} world!`; + } +} +``` + +## Output + +### SDL + +```graphql +type SomeType { + hello(greeting: String! = "hello"): String +} +``` + +### TypeScript + +```ts +import { GraphQLSchema, GraphQLObjectType, GraphQLString, GraphQLNonNull } from "graphql"; +export function getSchema(): GraphQLSchema { + const SomeTypeType: GraphQLObjectType = new GraphQLObjectType({ + name: "SomeType", + fields() { + return { + hello: { + name: "hello", + type: GraphQLString, + args: { + greeting: { + type: new GraphQLNonNull(GraphQLString), + defaultValue: "hello" + } + } + } + }; + } + }); + return new GraphQLSchema({ + types: [SomeTypeType] + }); +} +``` \ No newline at end of file diff --git a/src/tests/fixtures/default_values/DefaultArgumentStringLiteralBackticks.ts.expected b/src/tests/fixtures/default_values/DefaultArgumentStringLiteralBackticks.ts.expected deleted file mode 100644 index 2980e922..00000000 --- a/src/tests/fixtures/default_values/DefaultArgumentStringLiteralBackticks.ts.expected +++ /dev/null @@ -1,42 +0,0 @@ ------------------ -INPUT ------------------ -/** @gqlType */ -export default class SomeType { - /** @gqlField */ - hello({ greeting = `hello` }: { greeting: string }): string { - return `${greeting} world!`; - } -} - ------------------ -OUTPUT ------------------ --- SDL -- -type SomeType { - hello(greeting: String! = "hello"): String -} --- TypeScript -- -import { GraphQLSchema, GraphQLObjectType, GraphQLString, GraphQLNonNull } from "graphql"; -export function getSchema(): GraphQLSchema { - const SomeTypeType: GraphQLObjectType = new GraphQLObjectType({ - name: "SomeType", - fields() { - return { - hello: { - name: "hello", - type: GraphQLString, - args: { - greeting: { - type: new GraphQLNonNull(GraphQLString), - defaultValue: "hello" - } - } - } - }; - } - }); - return new GraphQLSchema({ - types: [SomeTypeType] - }); -} diff --git a/src/tests/fixtures/default_values/DefaultArgumentStringLiteralBackticks.ts.expected.md b/src/tests/fixtures/default_values/DefaultArgumentStringLiteralBackticks.ts.expected.md new file mode 100644 index 00000000..06cb347f --- /dev/null +++ b/src/tests/fixtures/default_values/DefaultArgumentStringLiteralBackticks.ts.expected.md @@ -0,0 +1,49 @@ +## input + +```ts title="default_values/DefaultArgumentStringLiteralBackticks.ts" +/** @gqlType */ +export default class SomeType { + /** @gqlField */ + hello({ greeting = `hello` }: { greeting: string }): string { + return `${greeting} world!`; + } +} +``` + +## Output + +### SDL + +```graphql +type SomeType { + hello(greeting: String! = "hello"): String +} +``` + +### TypeScript + +```ts +import { GraphQLSchema, GraphQLObjectType, GraphQLString, GraphQLNonNull } from "graphql"; +export function getSchema(): GraphQLSchema { + const SomeTypeType: GraphQLObjectType = new GraphQLObjectType({ + name: "SomeType", + fields() { + return { + hello: { + name: "hello", + type: GraphQLString, + args: { + greeting: { + type: new GraphQLNonNull(GraphQLString), + defaultValue: "hello" + } + } + } + }; + } + }); + return new GraphQLSchema({ + types: [SomeTypeType] + }); +} +``` \ No newline at end of file diff --git a/src/tests/fixtures/default_values/DefaultArgumentStringLiteralBackticksInterpolated.invalid.ts.expected b/src/tests/fixtures/default_values/DefaultArgumentStringLiteralBackticksInterpolated.invalid.ts.expected deleted file mode 100644 index ddc85853..00000000 --- a/src/tests/fixtures/default_values/DefaultArgumentStringLiteralBackticksInterpolated.invalid.ts.expected +++ /dev/null @@ -1,22 +0,0 @@ ------------------ -INPUT ------------------ -const CONSTANT = "constant"; - -/** @gqlType */ -export default class SomeType { - /** @gqlField */ - hello({ greeting = `hello ${CONSTANT}` }: { greeting: string }): string { - return `${greeting} world!`; - } -} - ------------------ -OUTPUT ------------------ -src/tests/fixtures/default_values/DefaultArgumentStringLiteralBackticksInterpolated.invalid.ts:6:22 - error: Expected GraphQL field argument default values to be a literal. Grats interprets argument defaults as GraphQL default values, which must be literals. For example: `10` or `"foo"`. - -If you think Grats should be able to infer this constant value, please report an issue at https://github.com/captbaritone/grats/issues. - -6 hello({ greeting = `hello ${CONSTANT}` }: { greeting: string }): string { - ~~~~~~~~~~~~~~~~~~~ diff --git a/src/tests/fixtures/default_values/DefaultArgumentStringLiteralBackticksInterpolated.invalid.ts.expected.md b/src/tests/fixtures/default_values/DefaultArgumentStringLiteralBackticksInterpolated.invalid.ts.expected.md new file mode 100644 index 00000000..1d9d6702 --- /dev/null +++ b/src/tests/fixtures/default_values/DefaultArgumentStringLiteralBackticksInterpolated.invalid.ts.expected.md @@ -0,0 +1,26 @@ +## input + +```ts title="default_values/DefaultArgumentStringLiteralBackticksInterpolated.invalid.ts" +const CONSTANT = "constant"; + +/** @gqlType */ +export default class SomeType { + /** @gqlField */ + hello({ greeting = `hello ${CONSTANT}` }: { greeting: string }): string { + return `${greeting} world!`; + } +} +``` + +## Output + +### Error Report + +```text +src/tests/fixtures/default_values/DefaultArgumentStringLiteralBackticksInterpolated.invalid.ts:6:22 - error: Expected GraphQL field argument default values to be a literal. Grats interprets argument defaults as GraphQL default values, which must be literals. For example: `10` or `"foo"`. + +If you think Grats should be able to infer this constant value, please report an issue at https://github.com/captbaritone/grats/issues. + +6 hello({ greeting = `hello ${CONSTANT}` }: { greeting: string }): string { + ~~~~~~~~~~~~~~~~~~~ +``` \ No newline at end of file diff --git a/src/tests/fixtures/default_values/NonLiteralDefaultValue.invalid.ts.expected b/src/tests/fixtures/default_values/NonLiteralDefaultValue.invalid.ts.expected deleted file mode 100644 index 8218a6f5..00000000 --- a/src/tests/fixtures/default_values/NonLiteralDefaultValue.invalid.ts.expected +++ /dev/null @@ -1,20 +0,0 @@ ------------------ -INPUT ------------------ -/** @gqlType */ -export default class SomeType { - /** @gqlField */ - hello({ greeting = String(Math.random()) }: { greeting: string }): string { - return `${greeting} world!`; - } -} - ------------------ -OUTPUT ------------------ -src/tests/fixtures/default_values/NonLiteralDefaultValue.invalid.ts:4:22 - error: Expected GraphQL field argument default values to be a literal. Grats interprets argument defaults as GraphQL default values, which must be literals. For example: `10` or `"foo"`. - -If you think Grats should be able to infer this constant value, please report an issue at https://github.com/captbaritone/grats/issues. - -4 hello({ greeting = String(Math.random()) }: { greeting: string }): string { - ~~~~~~~~~~~~~~~~~~~~~ diff --git a/src/tests/fixtures/default_values/NonLiteralDefaultValue.invalid.ts.expected.md b/src/tests/fixtures/default_values/NonLiteralDefaultValue.invalid.ts.expected.md new file mode 100644 index 00000000..17952c63 --- /dev/null +++ b/src/tests/fixtures/default_values/NonLiteralDefaultValue.invalid.ts.expected.md @@ -0,0 +1,24 @@ +## input + +```ts title="default_values/NonLiteralDefaultValue.invalid.ts" +/** @gqlType */ +export default class SomeType { + /** @gqlField */ + hello({ greeting = String(Math.random()) }: { greeting: string }): string { + return `${greeting} world!`; + } +} +``` + +## Output + +### Error Report + +```text +src/tests/fixtures/default_values/NonLiteralDefaultValue.invalid.ts:4:22 - error: Expected GraphQL field argument default values to be a literal. Grats interprets argument defaults as GraphQL default values, which must be literals. For example: `10` or `"foo"`. + +If you think Grats should be able to infer this constant value, please report an issue at https://github.com/captbaritone/grats/issues. + +4 hello({ greeting = String(Math.random()) }: { greeting: string }): string { + ~~~~~~~~~~~~~~~~~~~~~ +``` \ No newline at end of file diff --git a/src/tests/fixtures/derived_context/cyclicContextDependency.invalid.ts.expected b/src/tests/fixtures/derived_context/cyclicContextDependency.invalid.ts.expected deleted file mode 100644 index bba94fbe..00000000 --- a/src/tests/fixtures/derived_context/cyclicContextDependency.invalid.ts.expected +++ /dev/null @@ -1,40 +0,0 @@ ------------------ -INPUT ------------------ -/** @gqlContext */ -type RootContext = { - userName: string; -}; - -type DerivedContext = { - greeting: string; -}; - -/** @gqlContext */ -export function createDerivedContext( - ctx: RootContext, - oops: DerivedContext, -): DerivedContext { - return { greeting: `Hello, ${ctx.userName}!` }; -} - -/** @gqlType */ -type Query = unknown; - -/** @gqlField */ -export function greeting(_: Query, ctx: DerivedContext): string { - return ctx.greeting; -} - ------------------ -OUTPUT ------------------ -src/tests/fixtures/derived_context/cyclicContextDependency.invalid.ts:10:5 - error: Cyclic dependency detected in derived context. This derived context value depends upon itself. - -10 /** @gqlContext */ - ~~~~~~~~~~~~ - - src/tests/fixtures/derived_context/cyclicContextDependency.invalid.ts:13:3 - 13 oops: DerivedContext, - ~~~~~~~~~~~~~~~~~~~~ - This derived context depends on itself diff --git a/src/tests/fixtures/derived_context/cyclicContextDependency.invalid.ts.expected.md b/src/tests/fixtures/derived_context/cyclicContextDependency.invalid.ts.expected.md new file mode 100644 index 00000000..d743727c --- /dev/null +++ b/src/tests/fixtures/derived_context/cyclicContextDependency.invalid.ts.expected.md @@ -0,0 +1,44 @@ +## input + +```ts title="derived_context/cyclicContextDependency.invalid.ts" +/** @gqlContext */ +type RootContext = { + userName: string; +}; + +type DerivedContext = { + greeting: string; +}; + +/** @gqlContext */ +export function createDerivedContext( + ctx: RootContext, + oops: DerivedContext, +): DerivedContext { + return { greeting: `Hello, ${ctx.userName}!` }; +} + +/** @gqlType */ +type Query = unknown; + +/** @gqlField */ +export function greeting(_: Query, ctx: DerivedContext): string { + return ctx.greeting; +} +``` + +## Output + +### Error Report + +```text +src/tests/fixtures/derived_context/cyclicContextDependency.invalid.ts:10:5 - error: Cyclic dependency detected in derived context. This derived context value depends upon itself. + +10 /** @gqlContext */ + ~~~~~~~~~~~~ + + src/tests/fixtures/derived_context/cyclicContextDependency.invalid.ts:13:3 + 13 oops: DerivedContext, + ~~~~~~~~~~~~~~~~~~~~ + This derived context depends on itself +``` \ No newline at end of file diff --git a/src/tests/fixtures/derived_context/cyclicContextDependencyWithChain.invalid.ts.expected b/src/tests/fixtures/derived_context/cyclicContextDependencyWithChain.invalid.ts.expected deleted file mode 100644 index 18e441f9..00000000 --- a/src/tests/fixtures/derived_context/cyclicContextDependencyWithChain.invalid.ts.expected +++ /dev/null @@ -1,63 +0,0 @@ ------------------ -INPUT ------------------ -/** @gqlContext */ -type RootContext = { - userName: string; -}; - -type A = { - greeting: string; -}; - -/** @gqlContext */ -export function a(ctx: RootContext, b: B): A { - return { greeting: `Hello, ${ctx.userName}!` }; -} - -type B = { - greeting: string; -}; - -/** @gqlContext */ -export function b(ctx: RootContext, c: C): B { - return { greeting: `Hello, ${ctx.userName}!` }; -} - -type C = { - greeting: string; -}; - -/** @gqlContext */ -export function c(ctx: RootContext, a: A): C { - return { greeting: `Hello, ${ctx.userName}!` }; -} - -/** @gqlType */ -type Query = unknown; - -/** @gqlField */ -export function greeting(_: Query, ctx: A): string { - return ctx.greeting; -} - ------------------ -OUTPUT ------------------ -src/tests/fixtures/derived_context/cyclicContextDependencyWithChain.invalid.ts:10:5 - error: Cyclic dependency detected in derived context. This derived context value depends upon itself. - -10 /** @gqlContext */ - ~~~~~~~~~~~~ - - src/tests/fixtures/derived_context/cyclicContextDependencyWithChain.invalid.ts:11:37 - 11 export function a(ctx: RootContext, b: B): A { - ~~~~ - This derived context depends on - src/tests/fixtures/derived_context/cyclicContextDependencyWithChain.invalid.ts:20:37 - 20 export function b(ctx: RootContext, c: C): B { - ~~~~ - Which in turn depends on - src/tests/fixtures/derived_context/cyclicContextDependencyWithChain.invalid.ts:29:37 - 29 export function c(ctx: RootContext, a: A): C { - ~~~~ - Which ultimately creates a cycle back to the initial derived context diff --git a/src/tests/fixtures/derived_context/cyclicContextDependencyWithChain.invalid.ts.expected.md b/src/tests/fixtures/derived_context/cyclicContextDependencyWithChain.invalid.ts.expected.md new file mode 100644 index 00000000..ffbe3337 --- /dev/null +++ b/src/tests/fixtures/derived_context/cyclicContextDependencyWithChain.invalid.ts.expected.md @@ -0,0 +1,67 @@ +## input + +```ts title="derived_context/cyclicContextDependencyWithChain.invalid.ts" +/** @gqlContext */ +type RootContext = { + userName: string; +}; + +type A = { + greeting: string; +}; + +/** @gqlContext */ +export function a(ctx: RootContext, b: B): A { + return { greeting: `Hello, ${ctx.userName}!` }; +} + +type B = { + greeting: string; +}; + +/** @gqlContext */ +export function b(ctx: RootContext, c: C): B { + return { greeting: `Hello, ${ctx.userName}!` }; +} + +type C = { + greeting: string; +}; + +/** @gqlContext */ +export function c(ctx: RootContext, a: A): C { + return { greeting: `Hello, ${ctx.userName}!` }; +} + +/** @gqlType */ +type Query = unknown; + +/** @gqlField */ +export function greeting(_: Query, ctx: A): string { + return ctx.greeting; +} +``` + +## Output + +### Error Report + +```text +src/tests/fixtures/derived_context/cyclicContextDependencyWithChain.invalid.ts:10:5 - error: Cyclic dependency detected in derived context. This derived context value depends upon itself. + +10 /** @gqlContext */ + ~~~~~~~~~~~~ + + src/tests/fixtures/derived_context/cyclicContextDependencyWithChain.invalid.ts:11:37 + 11 export function a(ctx: RootContext, b: B): A { + ~~~~ + This derived context depends on + src/tests/fixtures/derived_context/cyclicContextDependencyWithChain.invalid.ts:20:37 + 20 export function b(ctx: RootContext, c: C): B { + ~~~~ + Which in turn depends on + src/tests/fixtures/derived_context/cyclicContextDependencyWithChain.invalid.ts:29:37 + 29 export function c(ctx: RootContext, a: A): C { + ~~~~ + Which ultimately creates a cycle back to the initial derived context +``` \ No newline at end of file diff --git a/src/tests/fixtures/derived_context/derivedContextChain.invalid.ts.expected b/src/tests/fixtures/derived_context/derivedContextChain.invalid.ts.expected deleted file mode 100644 index bfb3c944..00000000 --- a/src/tests/fixtures/derived_context/derivedContextChain.invalid.ts.expected +++ /dev/null @@ -1,87 +0,0 @@ ------------------ -INPUT ------------------ -/** @gqlContext */ -type RootContext = { userName: string }; - -type DerivedContextA = { greeting: string }; - -/** @gqlContext */ -export function createDerivedContextA(ctx: RootContext): DerivedContextA { - return { greeting: `Hello, ${ctx.userName}!` }; -} - -type DerivedContextB = { greeting: string }; - -/** @gqlContext */ -export function createDerivedContextB(ctx: DerivedContextA): DerivedContextB { - return { greeting: ctx.greeting.toUpperCase() }; -} - -type EverythingContext = { greeting: string }; - -/** @gqlContext */ -export function allTheContexts( - root: RootContext, - a: DerivedContextA, - b: DerivedContextB, -): EverythingContext { - return { greeting: `${root.userName} ${a.greeting} ${b.greeting}` }; -} - -/** @gqlType */ -type Query = unknown; - -/** @gqlField */ -export function greeting(_: Query, ctx: EverythingContext): string { - return ctx.greeting; -} - -/** @gqlField */ -export function consumingMultipleContexts( - _: Query, - root: RootContext, - a: DerivedContextA, - b: DerivedContextB, - everything: EverythingContext, -): string { - return `${root.userName} ${a.greeting} ${b.greeting} ${everything.greeting}`; -} - ------------------ -OUTPUT ------------------ -src/tests/fixtures/derived_context/derivedContextChain.invalid.ts:6:5 - error: Cyclic dependency detected in derived context. This derived context value depends upon itself. - -6 /** @gqlContext */ - ~~~~~~~~~~~~ - - src/tests/fixtures/derived_context/derivedContextChain.invalid.ts:23:3 - 23 a: DerivedContextA, - ~~~~~~~~~~~~~~~~~~ - This derived context depends on - src/tests/fixtures/derived_context/derivedContextChain.invalid.ts:24:3 - 24 b: DerivedContextB, - ~~~~~~~~~~~~~~~~~~ - Which in turn depends on - src/tests/fixtures/derived_context/derivedContextChain.invalid.ts:14:39 - 14 export function createDerivedContextB(ctx: DerivedContextA): DerivedContextB { - ~~~~~~~~~~~~~~~~~~~~ - Which ultimately creates a cycle back to the initial derived context -src/tests/fixtures/derived_context/derivedContextChain.invalid.ts:6:5 - error: Cyclic dependency detected in derived context. This derived context value depends upon itself. - -6 /** @gqlContext */ - ~~~~~~~~~~~~ - - src/tests/fixtures/derived_context/derivedContextChain.invalid.ts:23:3 - 23 a: DerivedContextA, - ~~~~~~~~~~~~~~~~~~ - This derived context depends on - src/tests/fixtures/derived_context/derivedContextChain.invalid.ts:24:3 - 24 b: DerivedContextB, - ~~~~~~~~~~~~~~~~~~ - Which in turn depends on - src/tests/fixtures/derived_context/derivedContextChain.invalid.ts:14:39 - 14 export function createDerivedContextB(ctx: DerivedContextA): DerivedContextB { - ~~~~~~~~~~~~~~~~~~~~ - Which ultimately creates a cycle back to the initial derived context diff --git a/src/tests/fixtures/derived_context/derivedContextChain.invalid.ts.expected.md b/src/tests/fixtures/derived_context/derivedContextChain.invalid.ts.expected.md new file mode 100644 index 00000000..6c8165f5 --- /dev/null +++ b/src/tests/fixtures/derived_context/derivedContextChain.invalid.ts.expected.md @@ -0,0 +1,91 @@ +## input + +```ts title="derived_context/derivedContextChain.invalid.ts" +/** @gqlContext */ +type RootContext = { userName: string }; + +type DerivedContextA = { greeting: string }; + +/** @gqlContext */ +export function createDerivedContextA(ctx: RootContext): DerivedContextA { + return { greeting: `Hello, ${ctx.userName}!` }; +} + +type DerivedContextB = { greeting: string }; + +/** @gqlContext */ +export function createDerivedContextB(ctx: DerivedContextA): DerivedContextB { + return { greeting: ctx.greeting.toUpperCase() }; +} + +type EverythingContext = { greeting: string }; + +/** @gqlContext */ +export function allTheContexts( + root: RootContext, + a: DerivedContextA, + b: DerivedContextB, +): EverythingContext { + return { greeting: `${root.userName} ${a.greeting} ${b.greeting}` }; +} + +/** @gqlType */ +type Query = unknown; + +/** @gqlField */ +export function greeting(_: Query, ctx: EverythingContext): string { + return ctx.greeting; +} + +/** @gqlField */ +export function consumingMultipleContexts( + _: Query, + root: RootContext, + a: DerivedContextA, + b: DerivedContextB, + everything: EverythingContext, +): string { + return `${root.userName} ${a.greeting} ${b.greeting} ${everything.greeting}`; +} +``` + +## Output + +### Error Report + +```text +src/tests/fixtures/derived_context/derivedContextChain.invalid.ts:6:5 - error: Cyclic dependency detected in derived context. This derived context value depends upon itself. + +6 /** @gqlContext */ + ~~~~~~~~~~~~ + + src/tests/fixtures/derived_context/derivedContextChain.invalid.ts:23:3 + 23 a: DerivedContextA, + ~~~~~~~~~~~~~~~~~~ + This derived context depends on + src/tests/fixtures/derived_context/derivedContextChain.invalid.ts:24:3 + 24 b: DerivedContextB, + ~~~~~~~~~~~~~~~~~~ + Which in turn depends on + src/tests/fixtures/derived_context/derivedContextChain.invalid.ts:14:39 + 14 export function createDerivedContextB(ctx: DerivedContextA): DerivedContextB { + ~~~~~~~~~~~~~~~~~~~~ + Which ultimately creates a cycle back to the initial derived context +src/tests/fixtures/derived_context/derivedContextChain.invalid.ts:6:5 - error: Cyclic dependency detected in derived context. This derived context value depends upon itself. + +6 /** @gqlContext */ + ~~~~~~~~~~~~ + + src/tests/fixtures/derived_context/derivedContextChain.invalid.ts:23:3 + 23 a: DerivedContextA, + ~~~~~~~~~~~~~~~~~~ + This derived context depends on + src/tests/fixtures/derived_context/derivedContextChain.invalid.ts:24:3 + 24 b: DerivedContextB, + ~~~~~~~~~~~~~~~~~~ + Which in turn depends on + src/tests/fixtures/derived_context/derivedContextChain.invalid.ts:14:39 + 14 export function createDerivedContextB(ctx: DerivedContextA): DerivedContextB { + ~~~~~~~~~~~~~~~~~~~~ + Which ultimately creates a cycle back to the initial derived context +``` \ No newline at end of file diff --git a/src/tests/fixtures/derived_context/derivedContextNoReturnType.invalid.ts.expected b/src/tests/fixtures/derived_context/derivedContextNoReturnType.invalid.ts.expected deleted file mode 100644 index 2de2078e..00000000 --- a/src/tests/fixtures/derived_context/derivedContextNoReturnType.invalid.ts.expected +++ /dev/null @@ -1,36 +0,0 @@ ------------------ -INPUT ------------------ -/** @gqlContext */ -type RootContext = { - userName: string; -}; - -type DerivedContext = { - greeting: string; -}; - -/** @gqlContext */ -export function createDerivedContext(ctx: RootContext) { - return { greeting: `Hello, ${ctx.userName}!` }; -} - -/** @gqlType */ -type Query = unknown; - -/** @gqlField */ -export function greeting(_: Query, ctx: DerivedContext): string { - return ctx.greeting; -} - ------------------ -OUTPUT ------------------ -src/tests/fixtures/derived_context/derivedContextNoReturnType.invalid.ts:11:1 - error: Expected derived resolver to have an explicit return type. This is needed to allow Grats to "see" which type to treat as a derived context type. - -11 export function createDerivedContext(ctx: RootContext) { - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -12 return { greeting: `Hello, ${ctx.userName}!` }; - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -13 } - ~ diff --git a/src/tests/fixtures/derived_context/derivedContextNoReturnType.invalid.ts.expected.md b/src/tests/fixtures/derived_context/derivedContextNoReturnType.invalid.ts.expected.md new file mode 100644 index 00000000..0582e48f --- /dev/null +++ b/src/tests/fixtures/derived_context/derivedContextNoReturnType.invalid.ts.expected.md @@ -0,0 +1,40 @@ +## input + +```ts title="derived_context/derivedContextNoReturnType.invalid.ts" +/** @gqlContext */ +type RootContext = { + userName: string; +}; + +type DerivedContext = { + greeting: string; +}; + +/** @gqlContext */ +export function createDerivedContext(ctx: RootContext) { + return { greeting: `Hello, ${ctx.userName}!` }; +} + +/** @gqlType */ +type Query = unknown; + +/** @gqlField */ +export function greeting(_: Query, ctx: DerivedContext): string { + return ctx.greeting; +} +``` + +## Output + +### Error Report + +```text +src/tests/fixtures/derived_context/derivedContextNoReturnType.invalid.ts:11:1 - error: Expected derived resolver to have an explicit return type. This is needed to allow Grats to "see" which type to treat as a derived context type. + +11 export function createDerivedContext(ctx: RootContext) { + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +12 return { greeting: `Hello, ${ctx.userName}!` }; + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +13 } + ~ +``` \ No newline at end of file diff --git a/src/tests/fixtures/derived_context/derivedContextNonNamedReturnType.invalid.ts.expected b/src/tests/fixtures/derived_context/derivedContextNonNamedReturnType.invalid.ts.expected deleted file mode 100644 index 1a068831..00000000 --- a/src/tests/fixtures/derived_context/derivedContextNonNamedReturnType.invalid.ts.expected +++ /dev/null @@ -1,32 +0,0 @@ ------------------ -INPUT ------------------ -/** @gqlContext */ -type RootContext = { - userName: string; -}; - -type DerivedContext = { - greeting: string; -}; - -/** @gqlContext */ -export function createDerivedContext(ctx: RootContext): { greeting: string } { - return { greeting: `Hello, ${ctx.userName}!` }; -} - -/** @gqlType */ -type Query = unknown; - -/** @gqlField */ -export function greeting(_: Query, ctx: DerivedContext): string { - return ctx.greeting; -} - ------------------ -OUTPUT ------------------ -src/tests/fixtures/derived_context/derivedContextNonNamedReturnType.invalid.ts:11:57 - error: Expected derived resolver to have an explicit return type. This is needed to allow Grats to "see" which type to treat as a derived context type. - -11 export function createDerivedContext(ctx: RootContext): { greeting: string } { - ~~~~~~~~~~~~~~~~~~~~ diff --git a/src/tests/fixtures/derived_context/derivedContextNonNamedReturnType.invalid.ts.expected.md b/src/tests/fixtures/derived_context/derivedContextNonNamedReturnType.invalid.ts.expected.md new file mode 100644 index 00000000..f3c3fd53 --- /dev/null +++ b/src/tests/fixtures/derived_context/derivedContextNonNamedReturnType.invalid.ts.expected.md @@ -0,0 +1,36 @@ +## input + +```ts title="derived_context/derivedContextNonNamedReturnType.invalid.ts" +/** @gqlContext */ +type RootContext = { + userName: string; +}; + +type DerivedContext = { + greeting: string; +}; + +/** @gqlContext */ +export function createDerivedContext(ctx: RootContext): { greeting: string } { + return { greeting: `Hello, ${ctx.userName}!` }; +} + +/** @gqlType */ +type Query = unknown; + +/** @gqlField */ +export function greeting(_: Query, ctx: DerivedContext): string { + return ctx.greeting; +} +``` + +## Output + +### Error Report + +```text +src/tests/fixtures/derived_context/derivedContextNonNamedReturnType.invalid.ts:11:57 - error: Expected derived resolver to have an explicit return type. This is needed to allow Grats to "see" which type to treat as a derived context type. + +11 export function createDerivedContext(ctx: RootContext): { greeting: string } { + ~~~~~~~~~~~~~~~~~~~~ +``` \ No newline at end of file diff --git a/src/tests/fixtures/derived_context/derivedContextUsedMultipleTimes.ts.expected b/src/tests/fixtures/derived_context/derivedContextUsedMultipleTimes.ts.expected deleted file mode 100644 index 2b538984..00000000 --- a/src/tests/fixtures/derived_context/derivedContextUsedMultipleTimes.ts.expected +++ /dev/null @@ -1,68 +0,0 @@ ------------------ -INPUT ------------------ -/** @gqlContext */ -type RootContext = { - userName: string; -}; - -type DerivedContext = { - greeting: string; -}; - -/** @gqlContext */ -export function greetingContext(ctx: RootContext): DerivedContext { - return { greeting: `Hello, ${ctx.userName}!` }; -} - -/** @gqlType */ -type Query = unknown; - -/** @gqlField */ -export function greeting(_: Query, ctx: DerivedContext): string { - return ctx.greeting; -} - -/** @gqlField */ -export function farewell(_: Query, ctx: DerivedContext): string { - return `${ctx.greeting}... NOT!`; -} - ------------------ -OUTPUT ------------------ --- SDL -- -type Query { - farewell: String - greeting: String -} --- TypeScript -- -import { GraphQLSchema, GraphQLObjectType, GraphQLString } from "graphql"; -import { farewell as queryFarewellResolver, greetingContext, greeting as queryGreetingResolver } from "./derivedContextUsedMultipleTimes"; -export function getSchema(): GraphQLSchema { - const QueryType: GraphQLObjectType = new GraphQLObjectType({ - name: "Query", - fields() { - return { - farewell: { - name: "farewell", - type: GraphQLString, - resolve(source, _args, context) { - return queryFarewellResolver(source, greetingContext(context)); - } - }, - greeting: { - name: "greeting", - type: GraphQLString, - resolve(source, _args, context) { - return queryGreetingResolver(source, greetingContext(context)); - } - } - }; - } - }); - return new GraphQLSchema({ - query: QueryType, - types: [QueryType] - }); -} diff --git a/src/tests/fixtures/derived_context/derivedContextUsedMultipleTimes.ts.expected.md b/src/tests/fixtures/derived_context/derivedContextUsedMultipleTimes.ts.expected.md new file mode 100644 index 00000000..e27e7061 --- /dev/null +++ b/src/tests/fixtures/derived_context/derivedContextUsedMultipleTimes.ts.expected.md @@ -0,0 +1,75 @@ +## input + +```ts title="derived_context/derivedContextUsedMultipleTimes.ts" +/** @gqlContext */ +type RootContext = { + userName: string; +}; + +type DerivedContext = { + greeting: string; +}; + +/** @gqlContext */ +export function greetingContext(ctx: RootContext): DerivedContext { + return { greeting: `Hello, ${ctx.userName}!` }; +} + +/** @gqlType */ +type Query = unknown; + +/** @gqlField */ +export function greeting(_: Query, ctx: DerivedContext): string { + return ctx.greeting; +} + +/** @gqlField */ +export function farewell(_: Query, ctx: DerivedContext): string { + return `${ctx.greeting}... NOT!`; +} +``` + +## Output + +### SDL + +```graphql +type Query { + farewell: String + greeting: String +} +``` + +### TypeScript + +```ts +import { GraphQLSchema, GraphQLObjectType, GraphQLString } from "graphql"; +import { farewell as queryFarewellResolver, greetingContext, greeting as queryGreetingResolver } from "./derivedContextUsedMultipleTimes"; +export function getSchema(): GraphQLSchema { + const QueryType: GraphQLObjectType = new GraphQLObjectType({ + name: "Query", + fields() { + return { + farewell: { + name: "farewell", + type: GraphQLString, + resolve(source, _args, context) { + return queryFarewellResolver(source, greetingContext(context)); + } + }, + greeting: { + name: "greeting", + type: GraphQLString, + resolve(source, _args, context) { + return queryGreetingResolver(source, greetingContext(context)); + } + } + }; + } + }); + return new GraphQLSchema({ + query: QueryType, + types: [QueryType] + }); +} +``` \ No newline at end of file diff --git a/src/tests/fixtures/derived_context/multipleDerivedContextsSameType.invalid.ts.expected b/src/tests/fixtures/derived_context/multipleDerivedContextsSameType.invalid.ts.expected deleted file mode 100644 index c1295530..00000000 --- a/src/tests/fixtures/derived_context/multipleDerivedContextsSameType.invalid.ts.expected +++ /dev/null @@ -1,50 +0,0 @@ ------------------ -INPUT ------------------ -/** @gqlContext */ -type RootContext = { - userName: string; -}; - -type DerivedContext = { - greeting: string; -}; - -/** @gqlContext */ -export function createDerivedContext(ctx: RootContext): DerivedContext { - return { greeting: `Hello, ${ctx.userName}!` }; -} - -/** @gqlContext */ -export function createAnotherDerivedContext(ctx: RootContext): DerivedContext { - return { greeting: `Goodbye!, ${ctx.userName}!` }; -} - -/** @gqlType */ -type Query = unknown; - -/** @gqlField */ -export function greeting(_: Query, ctx: DerivedContext): string { - return ctx.greeting; -} - ------------------ -OUTPUT ------------------ -src/tests/fixtures/derived_context/multipleDerivedContextsSameType.invalid.ts:6:1 - error: Multiple derived contexts defined for given type - -6 type DerivedContext = { - ~~~~~~~~~~~~~~~~~~~~~~~ -7 greeting: string; - ~~~~~~~~~~~~~~~~~~~ -8 }; - ~~ - - src/tests/fixtures/derived_context/multipleDerivedContextsSameType.invalid.ts:15:5 - 15 /** @gqlContext */ - ~~~~~~~~~~~~ - One was defined here - src/tests/fixtures/derived_context/multipleDerivedContextsSameType.invalid.ts:10:5 - 10 /** @gqlContext */ - ~~~~~~~~~~~~ - Another here diff --git a/src/tests/fixtures/derived_context/multipleDerivedContextsSameType.invalid.ts.expected.md b/src/tests/fixtures/derived_context/multipleDerivedContextsSameType.invalid.ts.expected.md new file mode 100644 index 00000000..2f191ff8 --- /dev/null +++ b/src/tests/fixtures/derived_context/multipleDerivedContextsSameType.invalid.ts.expected.md @@ -0,0 +1,54 @@ +## input + +```ts title="derived_context/multipleDerivedContextsSameType.invalid.ts" +/** @gqlContext */ +type RootContext = { + userName: string; +}; + +type DerivedContext = { + greeting: string; +}; + +/** @gqlContext */ +export function createDerivedContext(ctx: RootContext): DerivedContext { + return { greeting: `Hello, ${ctx.userName}!` }; +} + +/** @gqlContext */ +export function createAnotherDerivedContext(ctx: RootContext): DerivedContext { + return { greeting: `Goodbye!, ${ctx.userName}!` }; +} + +/** @gqlType */ +type Query = unknown; + +/** @gqlField */ +export function greeting(_: Query, ctx: DerivedContext): string { + return ctx.greeting; +} +``` + +## Output + +### Error Report + +```text +src/tests/fixtures/derived_context/multipleDerivedContextsSameType.invalid.ts:6:1 - error: Multiple derived contexts defined for given type + +6 type DerivedContext = { + ~~~~~~~~~~~~~~~~~~~~~~~ +7 greeting: string; + ~~~~~~~~~~~~~~~~~~~ +8 }; + ~~ + + src/tests/fixtures/derived_context/multipleDerivedContextsSameType.invalid.ts:15:5 + 15 /** @gqlContext */ + ~~~~~~~~~~~~ + One was defined here + src/tests/fixtures/derived_context/multipleDerivedContextsSameType.invalid.ts:10:5 + 10 /** @gqlContext */ + ~~~~~~~~~~~~ + Another here +``` \ No newline at end of file diff --git a/src/tests/fixtures/derived_context/simpleDerivedContext.ts.expected b/src/tests/fixtures/derived_context/simpleDerivedContext.ts.expected deleted file mode 100644 index 451f5f1e..00000000 --- a/src/tests/fixtures/derived_context/simpleDerivedContext.ts.expected +++ /dev/null @@ -1,55 +0,0 @@ ------------------ -INPUT ------------------ -/** @gqlContext */ -type RootContext = { - userName: string; -}; - -type DerivedContext = { - greeting: string; -}; - -/** @gqlContext */ -export function createDerivedContext(ctx: RootContext): DerivedContext { - return { greeting: `Hello, ${ctx.userName}!` }; -} - -/** @gqlType */ -type Query = unknown; - -/** @gqlField */ -export function greeting(_: Query, ctx: DerivedContext): string { - return ctx.greeting; -} - ------------------ -OUTPUT ------------------ --- SDL -- -type Query { - greeting: String -} --- TypeScript -- -import { GraphQLSchema, GraphQLObjectType, GraphQLString } from "graphql"; -import { greeting as queryGreetingResolver, createDerivedContext } from "./simpleDerivedContext"; -export function getSchema(): GraphQLSchema { - const QueryType: GraphQLObjectType = new GraphQLObjectType({ - name: "Query", - fields() { - return { - greeting: { - name: "greeting", - type: GraphQLString, - resolve(source, _args, context) { - return queryGreetingResolver(source, createDerivedContext(context)); - } - } - }; - } - }); - return new GraphQLSchema({ - query: QueryType, - types: [QueryType] - }); -} diff --git a/src/tests/fixtures/derived_context/simpleDerivedContext.ts.expected.md b/src/tests/fixtures/derived_context/simpleDerivedContext.ts.expected.md new file mode 100644 index 00000000..95b1cd0b --- /dev/null +++ b/src/tests/fixtures/derived_context/simpleDerivedContext.ts.expected.md @@ -0,0 +1,62 @@ +## input + +```ts title="derived_context/simpleDerivedContext.ts" +/** @gqlContext */ +type RootContext = { + userName: string; +}; + +type DerivedContext = { + greeting: string; +}; + +/** @gqlContext */ +export function createDerivedContext(ctx: RootContext): DerivedContext { + return { greeting: `Hello, ${ctx.userName}!` }; +} + +/** @gqlType */ +type Query = unknown; + +/** @gqlField */ +export function greeting(_: Query, ctx: DerivedContext): string { + return ctx.greeting; +} +``` + +## Output + +### SDL + +```graphql +type Query { + greeting: String +} +``` + +### TypeScript + +```ts +import { GraphQLSchema, GraphQLObjectType, GraphQLString } from "graphql"; +import { greeting as queryGreetingResolver, createDerivedContext } from "./simpleDerivedContext"; +export function getSchema(): GraphQLSchema { + const QueryType: GraphQLObjectType = new GraphQLObjectType({ + name: "Query", + fields() { + return { + greeting: { + name: "greeting", + type: GraphQLString, + resolve(source, _args, context) { + return queryGreetingResolver(source, createDerivedContext(context)); + } + } + }; + } + }); + return new GraphQLSchema({ + query: QueryType, + types: [QueryType] + }); +} +``` \ No newline at end of file diff --git a/src/tests/fixtures/derived_context/simpleDerivedContextNoArgs.ts.expected b/src/tests/fixtures/derived_context/simpleDerivedContextNoArgs.ts.expected deleted file mode 100644 index 55f71108..00000000 --- a/src/tests/fixtures/derived_context/simpleDerivedContextNoArgs.ts.expected +++ /dev/null @@ -1,55 +0,0 @@ ------------------ -INPUT ------------------ -/** @gqlContext */ -type RootContext = { - userName: string; -}; - -type DerivedContext = { - greeting: string; -}; - -/** @gqlContext */ -export function createDerivedContext(): DerivedContext { - return { greeting: `Hello!` }; -} - -/** @gqlType */ -type Query = unknown; - -/** @gqlField */ -export function greeting(_: Query, ctx: DerivedContext): string { - return ctx.greeting; -} - ------------------ -OUTPUT ------------------ --- SDL -- -type Query { - greeting: String -} --- TypeScript -- -import { GraphQLSchema, GraphQLObjectType, GraphQLString } from "graphql"; -import { greeting as queryGreetingResolver, createDerivedContext } from "./simpleDerivedContextNoArgs"; -export function getSchema(): GraphQLSchema { - const QueryType: GraphQLObjectType = new GraphQLObjectType({ - name: "Query", - fields() { - return { - greeting: { - name: "greeting", - type: GraphQLString, - resolve(source) { - return queryGreetingResolver(source, createDerivedContext()); - } - } - }; - } - }); - return new GraphQLSchema({ - query: QueryType, - types: [QueryType] - }); -} diff --git a/src/tests/fixtures/derived_context/simpleDerivedContextNoArgs.ts.expected.md b/src/tests/fixtures/derived_context/simpleDerivedContextNoArgs.ts.expected.md new file mode 100644 index 00000000..61cc56d6 --- /dev/null +++ b/src/tests/fixtures/derived_context/simpleDerivedContextNoArgs.ts.expected.md @@ -0,0 +1,62 @@ +## input + +```ts title="derived_context/simpleDerivedContextNoArgs.ts" +/** @gqlContext */ +type RootContext = { + userName: string; +}; + +type DerivedContext = { + greeting: string; +}; + +/** @gqlContext */ +export function createDerivedContext(): DerivedContext { + return { greeting: `Hello!` }; +} + +/** @gqlType */ +type Query = unknown; + +/** @gqlField */ +export function greeting(_: Query, ctx: DerivedContext): string { + return ctx.greeting; +} +``` + +## Output + +### SDL + +```graphql +type Query { + greeting: String +} +``` + +### TypeScript + +```ts +import { GraphQLSchema, GraphQLObjectType, GraphQLString } from "graphql"; +import { greeting as queryGreetingResolver, createDerivedContext } from "./simpleDerivedContextNoArgs"; +export function getSchema(): GraphQLSchema { + const QueryType: GraphQLObjectType = new GraphQLObjectType({ + name: "Query", + fields() { + return { + greeting: { + name: "greeting", + type: GraphQLString, + resolve(source) { + return queryGreetingResolver(source, createDerivedContext()); + } + } + }; + } + }); + return new GraphQLSchema({ + query: QueryType, + types: [QueryType] + }); +} +``` \ No newline at end of file diff --git a/src/tests/fixtures/derived_context/simpleDerivedContextReadsRandomType.invalid.ts.expected b/src/tests/fixtures/derived_context/simpleDerivedContextReadsRandomType.invalid.ts.expected deleted file mode 100644 index c571a491..00000000 --- a/src/tests/fixtures/derived_context/simpleDerivedContextReadsRandomType.invalid.ts.expected +++ /dev/null @@ -1,35 +0,0 @@ ------------------ -INPUT ------------------ -/** @gqlContext */ -type RootContext = { - userName: string; -}; - -type DerivedContext = { - greeting: string; -}; - -/** @gqlContext */ -export function createDerivedContext( - ctx: RootContext, - oops: string, -): DerivedContext { - return { greeting: `Hello, ${ctx.userName}!` }; -} - -/** @gqlType */ -type Query = unknown; - -/** @gqlField */ -export function greeting(_: Query, ctx: DerivedContext): string { - return ctx.greeting; -} - ------------------ -OUTPUT ------------------ -src/tests/fixtures/derived_context/simpleDerivedContextReadsRandomType.invalid.ts:13:3 - error: Invalid type for derived context function argument. Derived context functions may only accept other `@gqlContext` types as arguments. - -13 oops: string, - ~~~~~~~~~~~~ diff --git a/src/tests/fixtures/derived_context/simpleDerivedContextReadsRandomType.invalid.ts.expected.md b/src/tests/fixtures/derived_context/simpleDerivedContextReadsRandomType.invalid.ts.expected.md new file mode 100644 index 00000000..54c15d9d --- /dev/null +++ b/src/tests/fixtures/derived_context/simpleDerivedContextReadsRandomType.invalid.ts.expected.md @@ -0,0 +1,39 @@ +## input + +```ts title="derived_context/simpleDerivedContextReadsRandomType.invalid.ts" +/** @gqlContext */ +type RootContext = { + userName: string; +}; + +type DerivedContext = { + greeting: string; +}; + +/** @gqlContext */ +export function createDerivedContext( + ctx: RootContext, + oops: string, +): DerivedContext { + return { greeting: `Hello, ${ctx.userName}!` }; +} + +/** @gqlType */ +type Query = unknown; + +/** @gqlField */ +export function greeting(_: Query, ctx: DerivedContext): string { + return ctx.greeting; +} +``` + +## Output + +### Error Report + +```text +src/tests/fixtures/derived_context/simpleDerivedContextReadsRandomType.invalid.ts:13:3 - error: Invalid type for derived context function argument. Derived context functions may only accept other `@gqlContext` types as arguments. + +13 oops: string, + ~~~~~~~~~~~~ +``` \ No newline at end of file diff --git a/src/tests/fixtures/derived_context/simpleDerivedContextUndefinedType.invalid.ts.expected b/src/tests/fixtures/derived_context/simpleDerivedContextUndefinedType.invalid.ts.expected deleted file mode 100644 index 62c18bbe..00000000 --- a/src/tests/fixtures/derived_context/simpleDerivedContextUndefinedType.invalid.ts.expected +++ /dev/null @@ -1,32 +0,0 @@ ------------------ -INPUT ------------------ -/** @gqlContext */ -type RootContext = { - userName: string; -}; - -// type DerivedContext = { -// greeting: string; -// }; - -/** @gqlContext */ -export function createDerivedContext(ctx: RootContext): DerivedContext { - return { greeting: `Hello, ${ctx.userName}!` }; -} - -/** @gqlType */ -type Query = unknown; - -/** @gqlField */ -export function greeting(_: Query, ctx: DerivedContext): string { - return ctx.greeting; -} - ------------------ -OUTPUT ------------------ -src/tests/fixtures/derived_context/simpleDerivedContextUndefinedType.invalid.ts:11:57 - error: Unable to resolve type reference. In order to generate a GraphQL schema, Grats needs to determine which GraphQL type is being referenced. This requires being able to resolve type references to their `@gql` annotated declaration. However this reference could not be resolved. Is it possible that this type is not defined in this file? - -11 export function createDerivedContext(ctx: RootContext): DerivedContext { - ~~~~~~~~~~~~~~ diff --git a/src/tests/fixtures/derived_context/simpleDerivedContextUndefinedType.invalid.ts.expected.md b/src/tests/fixtures/derived_context/simpleDerivedContextUndefinedType.invalid.ts.expected.md new file mode 100644 index 00000000..36a64fd1 --- /dev/null +++ b/src/tests/fixtures/derived_context/simpleDerivedContextUndefinedType.invalid.ts.expected.md @@ -0,0 +1,36 @@ +## input + +```ts title="derived_context/simpleDerivedContextUndefinedType.invalid.ts" +/** @gqlContext */ +type RootContext = { + userName: string; +}; + +// type DerivedContext = { +// greeting: string; +// }; + +/** @gqlContext */ +export function createDerivedContext(ctx: RootContext): DerivedContext { + return { greeting: `Hello, ${ctx.userName}!` }; +} + +/** @gqlType */ +type Query = unknown; + +/** @gqlField */ +export function greeting(_: Query, ctx: DerivedContext): string { + return ctx.greeting; +} +``` + +## Output + +### Error Report + +```text +src/tests/fixtures/derived_context/simpleDerivedContextUndefinedType.invalid.ts:11:57 - error: Unable to resolve type reference. In order to generate a GraphQL schema, Grats needs to determine which GraphQL type is being referenced. This requires being able to resolve type references to their `@gql` annotated declaration. However this reference could not be resolved. Is it possible that this type is not defined in this file? + +11 export function createDerivedContext(ctx: RootContext): DerivedContext { + ~~~~~~~~~~~~~~ +``` \ No newline at end of file diff --git a/src/tests/fixtures/descriptions/BlankLinesAroundDescription.ts.expected b/src/tests/fixtures/descriptions/BlankLinesAroundDescription.ts.expected deleted file mode 100644 index 87c2568d..00000000 --- a/src/tests/fixtures/descriptions/BlankLinesAroundDescription.ts.expected +++ /dev/null @@ -1,56 +0,0 @@ ------------------ -INPUT ------------------ -/** - * - * - * - * - * - * - * - * - * - * Sup - * - * - * - * - * - * - * - * - * @gqlType - */ -class SomeType { - /** @gqlField */ - name: string; -} - ------------------ -OUTPUT ------------------ --- SDL -- -"""Sup""" -type SomeType { - name: String -} --- TypeScript -- -import { GraphQLSchema, GraphQLObjectType, GraphQLString } from "graphql"; -export function getSchema(): GraphQLSchema { - const SomeTypeType: GraphQLObjectType = new GraphQLObjectType({ - name: "SomeType", - description: "Sup", - fields() { - return { - name: { - name: "name", - type: GraphQLString - } - }; - } - }); - return new GraphQLSchema({ - types: [SomeTypeType] - }); -} diff --git a/src/tests/fixtures/descriptions/BlankLinesAroundDescription.ts.expected.md b/src/tests/fixtures/descriptions/BlankLinesAroundDescription.ts.expected.md new file mode 100644 index 00000000..cba4ffeb --- /dev/null +++ b/src/tests/fixtures/descriptions/BlankLinesAroundDescription.ts.expected.md @@ -0,0 +1,63 @@ +## input + +```ts title="descriptions/BlankLinesAroundDescription.ts" +/** + * + * + * + * + * + * + * + * + * + * Sup + * + * + * + * + * + * + * + * + * @gqlType + */ +class SomeType { + /** @gqlField */ + name: string; +} +``` + +## Output + +### SDL + +```graphql +"""Sup""" +type SomeType { + name: String +} +``` + +### TypeScript + +```ts +import { GraphQLSchema, GraphQLObjectType, GraphQLString } from "graphql"; +export function getSchema(): GraphQLSchema { + const SomeTypeType: GraphQLObjectType = new GraphQLObjectType({ + name: "SomeType", + description: "Sup", + fields() { + return { + name: { + name: "name", + type: GraphQLString + } + }; + } + }); + return new GraphQLSchema({ + types: [SomeTypeType] + }); +} +``` \ No newline at end of file diff --git a/src/tests/fixtures/descriptions/BlankLinesFollowTypeTag.ts.expected b/src/tests/fixtures/descriptions/BlankLinesFollowTypeTag.ts.expected deleted file mode 100644 index d6743ec7..00000000 --- a/src/tests/fixtures/descriptions/BlankLinesFollowTypeTag.ts.expected +++ /dev/null @@ -1,41 +0,0 @@ ------------------ -INPUT ------------------ -/** - * @gqlType - * - * - * - * - * - */ -class SomeType { - /** @gqlField */ - name: string; -} - ------------------ -OUTPUT ------------------ --- SDL -- -type SomeType { - name: String -} --- TypeScript -- -import { GraphQLSchema, GraphQLObjectType, GraphQLString } from "graphql"; -export function getSchema(): GraphQLSchema { - const SomeTypeType: GraphQLObjectType = new GraphQLObjectType({ - name: "SomeType", - fields() { - return { - name: { - name: "name", - type: GraphQLString - } - }; - } - }); - return new GraphQLSchema({ - types: [SomeTypeType] - }); -} diff --git a/src/tests/fixtures/descriptions/BlankLinesFollowTypeTag.ts.expected.md b/src/tests/fixtures/descriptions/BlankLinesFollowTypeTag.ts.expected.md new file mode 100644 index 00000000..2391dd5f --- /dev/null +++ b/src/tests/fixtures/descriptions/BlankLinesFollowTypeTag.ts.expected.md @@ -0,0 +1,48 @@ +## input + +```ts title="descriptions/BlankLinesFollowTypeTag.ts" +/** + * @gqlType + * + * + * + * + * + */ +class SomeType { + /** @gqlField */ + name: string; +} +``` + +## Output + +### SDL + +```graphql +type SomeType { + name: String +} +``` + +### TypeScript + +```ts +import { GraphQLSchema, GraphQLObjectType, GraphQLString } from "graphql"; +export function getSchema(): GraphQLSchema { + const SomeTypeType: GraphQLObjectType = new GraphQLObjectType({ + name: "SomeType", + fields() { + return { + name: { + name: "name", + type: GraphQLString + } + }; + } + }); + return new GraphQLSchema({ + types: [SomeTypeType] + }); +} +``` \ No newline at end of file diff --git a/src/tests/fixtures/descriptions/DescriptionFollowsTypeTag.invalid.ts.expected b/src/tests/fixtures/descriptions/DescriptionFollowsTypeTag.invalid.ts.expected deleted file mode 100644 index 11c04eb4..00000000 --- a/src/tests/fixtures/descriptions/DescriptionFollowsTypeTag.invalid.ts.expected +++ /dev/null @@ -1,28 +0,0 @@ ------------------ -INPUT ------------------ -/** - * @gqlType - * - * This is a note for myself - */ -export type Query = unknown; - -/** @gqlField */ -export function queryField(_: Query): string { - return ""; -} - ------------------ -OUTPUT ------------------ -src/tests/fixtures/descriptions/DescriptionFollowsTypeTag.invalid.ts:2:4 - error: Expected text following a `@gqlType` tag to be a GraphQL name. If you intended this text to be a description, place it at the top of the docblock before any `@tags`. - -2 * @gqlType - ~~~~~~~~ -3 * - ~~ -4 * This is a note for myself - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -5 */ - ~ diff --git a/src/tests/fixtures/descriptions/DescriptionFollowsTypeTag.invalid.ts.expected.md b/src/tests/fixtures/descriptions/DescriptionFollowsTypeTag.invalid.ts.expected.md new file mode 100644 index 00000000..56143905 --- /dev/null +++ b/src/tests/fixtures/descriptions/DescriptionFollowsTypeTag.invalid.ts.expected.md @@ -0,0 +1,32 @@ +## input + +```ts title="descriptions/DescriptionFollowsTypeTag.invalid.ts" +/** + * @gqlType + * + * This is a note for myself + */ +export type Query = unknown; + +/** @gqlField */ +export function queryField(_: Query): string { + return ""; +} +``` + +## Output + +### Error Report + +```text +src/tests/fixtures/descriptions/DescriptionFollowsTypeTag.invalid.ts:2:4 - error: Expected text following a `@gqlType` tag to be a GraphQL name. If you intended this text to be a description, place it at the top of the docblock before any `@tags`. + +2 * @gqlType + ~~~~~~~~ +3 * + ~~ +4 * This is a note for myself + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +5 */ + ~ +``` \ No newline at end of file diff --git a/src/tests/fixtures/descriptions/DescriptionOnLineOfTypeTag.invalid.ts.expected b/src/tests/fixtures/descriptions/DescriptionOnLineOfTypeTag.invalid.ts.expected deleted file mode 100644 index aaba20d4..00000000 --- a/src/tests/fixtures/descriptions/DescriptionOnLineOfTypeTag.invalid.ts.expected +++ /dev/null @@ -1,22 +0,0 @@ ------------------ -INPUT ------------------ -/** - * @gqlType This is a note for myself - */ -export type Query = unknown; - -/** @gqlField */ -export function queryField(_: Query): string { - return ""; -} - ------------------ -OUTPUT ------------------ -src/tests/fixtures/descriptions/DescriptionOnLineOfTypeTag.invalid.ts:2:4 - error: Expected text following a `@gqlType` tag to be a GraphQL name. If you intended this text to be a description, place it at the top of the docblock before any `@tags`. - -2 * @gqlType This is a note for myself - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -3 */ - ~ diff --git a/src/tests/fixtures/descriptions/DescriptionOnLineOfTypeTag.invalid.ts.expected.md b/src/tests/fixtures/descriptions/DescriptionOnLineOfTypeTag.invalid.ts.expected.md new file mode 100644 index 00000000..db0c37cd --- /dev/null +++ b/src/tests/fixtures/descriptions/DescriptionOnLineOfTypeTag.invalid.ts.expected.md @@ -0,0 +1,26 @@ +## input + +```ts title="descriptions/DescriptionOnLineOfTypeTag.invalid.ts" +/** + * @gqlType This is a note for myself + */ +export type Query = unknown; + +/** @gqlField */ +export function queryField(_: Query): string { + return ""; +} +``` + +## Output + +### Error Report + +```text +src/tests/fixtures/descriptions/DescriptionOnLineOfTypeTag.invalid.ts:2:4 - error: Expected text following a `@gqlType` tag to be a GraphQL name. If you intended this text to be a description, place it at the top of the docblock before any `@tags`. + +2 * @gqlType This is a note for myself + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +3 */ + ~ +``` \ No newline at end of file diff --git a/src/tests/fixtures/descriptions/DescriptionWithGitHubHandle.ts.expected b/src/tests/fixtures/descriptions/DescriptionWithGitHubHandle.ts.expected deleted file mode 100644 index 273f50ef..00000000 --- a/src/tests/fixtures/descriptions/DescriptionWithGitHubHandle.ts.expected +++ /dev/null @@ -1,40 +0,0 @@ ------------------ -INPUT ------------------ -// { "tsVersion": "5.0.2" } -/** - * This type was added by @captbaritone! - * @gqlType - */ -class SomeType { - /** @gqlField */ - name: string; -} - ------------------ -OUTPUT ------------------ --- SDL -- -"""This type was added by @captbaritone!""" -type SomeType { - name: String @metadata -} --- TypeScript -- -import { GraphQLSchema, GraphQLObjectType, GraphQLString } from "graphql"; -export function getSchema(): GraphQLSchema { - const SomeTypeType: GraphQLObjectType = new GraphQLObjectType({ - name: "SomeType", - description: "This type was added by @captbaritone!", - fields() { - return { - name: { - name: "name", - type: GraphQLString - } - }; - } - }); - return new GraphQLSchema({ - types: [SomeTypeType] - }); -} diff --git a/src/tests/fixtures/descriptions/DescriptionWithGitHubHandle.ts.expected.md b/src/tests/fixtures/descriptions/DescriptionWithGitHubHandle.ts.expected.md new file mode 100644 index 00000000..e69de29b diff --git a/src/tests/fixtures/descriptions/MultilineDescription.ts.expected b/src/tests/fixtures/descriptions/MultilineDescription.ts.expected deleted file mode 100644 index f1146a2a..00000000 --- a/src/tests/fixtures/descriptions/MultilineDescription.ts.expected +++ /dev/null @@ -1,48 +0,0 @@ ------------------ -INPUT ------------------ -/** - * ’Twas brillig, and the slithy toves - * Did gyre and gimble in the wabe: - * All mimsy were the borogoves, - * And the mome raths outgrabe. - * - * @gqlType - */ -class SomeType { - /** @gqlField */ - name: string; -} - ------------------ -OUTPUT ------------------ --- SDL -- -""" -’Twas brillig, and the slithy toves - Did gyre and gimble in the wabe: -All mimsy were the borogoves, - And the mome raths outgrabe. -""" -type SomeType { - name: String -} --- TypeScript -- -import { GraphQLSchema, GraphQLObjectType, GraphQLString } from "graphql"; -export function getSchema(): GraphQLSchema { - const SomeTypeType: GraphQLObjectType = new GraphQLObjectType({ - name: "SomeType", - description: "\u2019Twas brillig, and the slithy toves\n Did gyre and gimble in the wabe:\nAll mimsy were the borogoves,\n And the mome raths outgrabe.", - fields() { - return { - name: { - name: "name", - type: GraphQLString - } - }; - } - }); - return new GraphQLSchema({ - types: [SomeTypeType] - }); -} diff --git a/src/tests/fixtures/descriptions/MultilineDescription.ts.expected.md b/src/tests/fixtures/descriptions/MultilineDescription.ts.expected.md new file mode 100644 index 00000000..c51920a6 --- /dev/null +++ b/src/tests/fixtures/descriptions/MultilineDescription.ts.expected.md @@ -0,0 +1,55 @@ +## input + +```ts title="descriptions/MultilineDescription.ts" +/** + * ’Twas brillig, and the slithy toves + * Did gyre and gimble in the wabe: + * All mimsy were the borogoves, + * And the mome raths outgrabe. + * + * @gqlType + */ +class SomeType { + /** @gqlField */ + name: string; +} +``` + +## Output + +### SDL + +```graphql +""" +’Twas brillig, and the slithy toves + Did gyre and gimble in the wabe: +All mimsy were the borogoves, + And the mome raths outgrabe. +""" +type SomeType { + name: String +} +``` + +### TypeScript + +```ts +import { GraphQLSchema, GraphQLObjectType, GraphQLString } from "graphql"; +export function getSchema(): GraphQLSchema { + const SomeTypeType: GraphQLObjectType = new GraphQLObjectType({ + name: "SomeType", + description: "\u2019Twas brillig, and the slithy toves\n Did gyre and gimble in the wabe:\nAll mimsy were the borogoves,\n And the mome raths outgrabe.", + fields() { + return { + name: { + name: "name", + type: GraphQLString + } + }; + } + }); + return new GraphQLSchema({ + types: [SomeTypeType] + }); +} +``` \ No newline at end of file diff --git a/src/tests/fixtures/descriptions/RenameFollowedByDescription.invalid.ts.expected b/src/tests/fixtures/descriptions/RenameFollowedByDescription.invalid.ts.expected deleted file mode 100644 index e67117f6..00000000 --- a/src/tests/fixtures/descriptions/RenameFollowedByDescription.invalid.ts.expected +++ /dev/null @@ -1,26 +0,0 @@ ------------------ -INPUT ------------------ -/** - * @gqlType User - * - * The user (oops, this should go up above!) - */ -class SomeType { - /** @gqlField */ - name: string; -} - ------------------ -OUTPUT ------------------ -src/tests/fixtures/descriptions/RenameFollowedByDescription.invalid.ts:2:4 - error: Expected text following a `@gqlType` tag to be a GraphQL name. If you intended this text to be a description, place it at the top of the docblock before any `@tags`. - -2 * @gqlType User - ~~~~~~~~~~~~~ -3 * - ~~ -4 * The user (oops, this should go up above!) - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -5 */ - ~ diff --git a/src/tests/fixtures/descriptions/RenameFollowedByDescription.invalid.ts.expected.md b/src/tests/fixtures/descriptions/RenameFollowedByDescription.invalid.ts.expected.md new file mode 100644 index 00000000..a7435daf --- /dev/null +++ b/src/tests/fixtures/descriptions/RenameFollowedByDescription.invalid.ts.expected.md @@ -0,0 +1,30 @@ +## input + +```ts title="descriptions/RenameFollowedByDescription.invalid.ts" +/** + * @gqlType User + * + * The user (oops, this should go up above!) + */ +class SomeType { + /** @gqlField */ + name: string; +} +``` + +## Output + +### Error Report + +```text +src/tests/fixtures/descriptions/RenameFollowedByDescription.invalid.ts:2:4 - error: Expected text following a `@gqlType` tag to be a GraphQL name. If you intended this text to be a description, place it at the top of the docblock before any `@tags`. + +2 * @gqlType User + ~~~~~~~~~~~~~ +3 * + ~~ +4 * The user (oops, this should go up above!) + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +5 */ + ~ +``` \ No newline at end of file diff --git a/src/tests/fixtures/directives/defineCustomDirective.ts.expected b/src/tests/fixtures/directives/defineCustomDirective.ts.expected deleted file mode 100644 index 39167bbe..00000000 --- a/src/tests/fixtures/directives/defineCustomDirective.ts.expected +++ /dev/null @@ -1,27 +0,0 @@ ------------------ -INPUT ------------------ -/** - * This is my custom directive. - * @gqlDirective on FIELD_DEFINITION - */ -export function customDirective() {} - ------------------ -OUTPUT ------------------ --- SDL -- -"""This is my custom directive.""" -directive @customDirective on FIELD_DEFINITION --- TypeScript -- -import { GraphQLSchema, GraphQLDirective, DirectiveLocation, specifiedDirectives } from "graphql"; -export function getSchema(): GraphQLSchema { - return new GraphQLSchema({ - directives: [...specifiedDirectives, new GraphQLDirective({ - name: "customDirective", - locations: [DirectiveLocation.FIELD_DEFINITION], - description: "This is my custom directive." - })], - types: [] - }); -} diff --git a/src/tests/fixtures/directives/defineCustomDirective.ts.expected.md b/src/tests/fixtures/directives/defineCustomDirective.ts.expected.md new file mode 100644 index 00000000..7f5e7c32 --- /dev/null +++ b/src/tests/fixtures/directives/defineCustomDirective.ts.expected.md @@ -0,0 +1,34 @@ +## input + +```ts title="directives/defineCustomDirective.ts" +/** + * This is my custom directive. + * @gqlDirective on FIELD_DEFINITION + */ +export function customDirective() {} +``` + +## Output + +### SDL + +```graphql +"""This is my custom directive.""" +directive @customDirective on FIELD_DEFINITION +``` + +### TypeScript + +```ts +import { GraphQLSchema, GraphQLDirective, DirectiveLocation, specifiedDirectives } from "graphql"; +export function getSchema(): GraphQLSchema { + return new GraphQLSchema({ + directives: [...specifiedDirectives, new GraphQLDirective({ + name: "customDirective", + locations: [DirectiveLocation.FIELD_DEFINITION], + description: "This is my custom directive." + })], + types: [] + }); +} +``` \ No newline at end of file diff --git a/src/tests/fixtures/directives/defineCustomDirectiveAdditionalArgsAreIgnored.ts.expected b/src/tests/fixtures/directives/defineCustomDirectiveAdditionalArgsAreIgnored.ts.expected deleted file mode 100644 index 3464763b..00000000 --- a/src/tests/fixtures/directives/defineCustomDirectiveAdditionalArgsAreIgnored.ts.expected +++ /dev/null @@ -1,39 +0,0 @@ ------------------ -INPUT ------------------ -import { GraphQLFieldResolver } from "graphql"; - -/** - * This is my custom directive. - * @gqlDirective on FIELD_DEFINITION - */ -export function customDirective( - args: { someArg: string }, - _someArg: GraphQLFieldResolver, -) { - // -} - ------------------ -OUTPUT ------------------ --- SDL -- -"""This is my custom directive.""" -directive @customDirective(someArg: String!) on FIELD_DEFINITION --- TypeScript -- -import { GraphQLSchema, GraphQLDirective, DirectiveLocation, GraphQLNonNull, GraphQLString, specifiedDirectives } from "graphql"; -export function getSchema(): GraphQLSchema { - return new GraphQLSchema({ - directives: [...specifiedDirectives, new GraphQLDirective({ - name: "customDirective", - locations: [DirectiveLocation.FIELD_DEFINITION], - description: "This is my custom directive.", - args: { - someArg: { - type: new GraphQLNonNull(GraphQLString) - } - } - })], - types: [] - }); -} diff --git a/src/tests/fixtures/directives/defineCustomDirectiveAdditionalArgsAreIgnored.ts.expected.md b/src/tests/fixtures/directives/defineCustomDirectiveAdditionalArgsAreIgnored.ts.expected.md new file mode 100644 index 00000000..93951d27 --- /dev/null +++ b/src/tests/fixtures/directives/defineCustomDirectiveAdditionalArgsAreIgnored.ts.expected.md @@ -0,0 +1,46 @@ +## input + +```ts title="directives/defineCustomDirectiveAdditionalArgsAreIgnored.ts" +import { GraphQLFieldResolver } from "graphql"; + +/** + * This is my custom directive. + * @gqlDirective on FIELD_DEFINITION + */ +export function customDirective( + args: { someArg: string }, + _someArg: GraphQLFieldResolver, +) { + // +} +``` + +## Output + +### SDL + +```graphql +"""This is my custom directive.""" +directive @customDirective(someArg: String!) on FIELD_DEFINITION +``` + +### TypeScript + +```ts +import { GraphQLSchema, GraphQLDirective, DirectiveLocation, GraphQLNonNull, GraphQLString, specifiedDirectives } from "graphql"; +export function getSchema(): GraphQLSchema { + return new GraphQLSchema({ + directives: [...specifiedDirectives, new GraphQLDirective({ + name: "customDirective", + locations: [DirectiveLocation.FIELD_DEFINITION], + description: "This is my custom directive.", + args: { + someArg: { + type: new GraphQLNonNull(GraphQLString) + } + } + })], + types: [] + }); +} +``` \ No newline at end of file diff --git a/src/tests/fixtures/directives/defineCustomDirectiveArgsIsNever.ts.expected b/src/tests/fixtures/directives/defineCustomDirectiveArgsIsNever.ts.expected deleted file mode 100644 index ae3ba157..00000000 --- a/src/tests/fixtures/directives/defineCustomDirectiveArgsIsNever.ts.expected +++ /dev/null @@ -1,34 +0,0 @@ ------------------ -INPUT ------------------ -import { GraphQLFieldResolver } from "graphql"; - -/** - * This is my custom directive. - * @gqlDirective on FIELD_DEFINITION - */ -export function customDirective( - _: never, - _someArg: GraphQLFieldResolver, -) { - // -} - ------------------ -OUTPUT ------------------ --- SDL -- -"""This is my custom directive.""" -directive @customDirective on FIELD_DEFINITION --- TypeScript -- -import { GraphQLSchema, GraphQLDirective, DirectiveLocation, specifiedDirectives } from "graphql"; -export function getSchema(): GraphQLSchema { - return new GraphQLSchema({ - directives: [...specifiedDirectives, new GraphQLDirective({ - name: "customDirective", - locations: [DirectiveLocation.FIELD_DEFINITION], - description: "This is my custom directive." - })], - types: [] - }); -} diff --git a/src/tests/fixtures/directives/defineCustomDirectiveArgsIsNever.ts.expected.md b/src/tests/fixtures/directives/defineCustomDirectiveArgsIsNever.ts.expected.md new file mode 100644 index 00000000..ce09bd0c --- /dev/null +++ b/src/tests/fixtures/directives/defineCustomDirectiveArgsIsNever.ts.expected.md @@ -0,0 +1,41 @@ +## input + +```ts title="directives/defineCustomDirectiveArgsIsNever.ts" +import { GraphQLFieldResolver } from "graphql"; + +/** + * This is my custom directive. + * @gqlDirective on FIELD_DEFINITION + */ +export function customDirective( + _: never, + _someArg: GraphQLFieldResolver, +) { + // +} +``` + +## Output + +### SDL + +```graphql +"""This is my custom directive.""" +directive @customDirective on FIELD_DEFINITION +``` + +### TypeScript + +```ts +import { GraphQLSchema, GraphQLDirective, DirectiveLocation, specifiedDirectives } from "graphql"; +export function getSchema(): GraphQLSchema { + return new GraphQLSchema({ + directives: [...specifiedDirectives, new GraphQLDirective({ + name: "customDirective", + locations: [DirectiveLocation.FIELD_DEFINITION], + description: "This is my custom directive." + })], + types: [] + }); +} +``` \ No newline at end of file diff --git a/src/tests/fixtures/directives/defineCustomDirectiveCustomName.ts.expected b/src/tests/fixtures/directives/defineCustomDirectiveCustomName.ts.expected deleted file mode 100644 index 0f4af4fd..00000000 --- a/src/tests/fixtures/directives/defineCustomDirectiveCustomName.ts.expected +++ /dev/null @@ -1,27 +0,0 @@ ------------------ -INPUT ------------------ -/** - * This is my custom directive. - * @gqlDirective aBetterName on FIELD_DEFINITION - */ -export function customDirective() {} - ------------------ -OUTPUT ------------------ --- SDL -- -"""This is my custom directive.""" -directive @aBetterName on FIELD_DEFINITION --- TypeScript -- -import { GraphQLSchema, GraphQLDirective, DirectiveLocation, specifiedDirectives } from "graphql"; -export function getSchema(): GraphQLSchema { - return new GraphQLSchema({ - directives: [...specifiedDirectives, new GraphQLDirective({ - name: "aBetterName", - locations: [DirectiveLocation.FIELD_DEFINITION], - description: "This is my custom directive." - })], - types: [] - }); -} diff --git a/src/tests/fixtures/directives/defineCustomDirectiveCustomName.ts.expected.md b/src/tests/fixtures/directives/defineCustomDirectiveCustomName.ts.expected.md new file mode 100644 index 00000000..c68e3f30 --- /dev/null +++ b/src/tests/fixtures/directives/defineCustomDirectiveCustomName.ts.expected.md @@ -0,0 +1,34 @@ +## input + +```ts title="directives/defineCustomDirectiveCustomName.ts" +/** + * This is my custom directive. + * @gqlDirective aBetterName on FIELD_DEFINITION + */ +export function customDirective() {} +``` + +## Output + +### SDL + +```graphql +"""This is my custom directive.""" +directive @aBetterName on FIELD_DEFINITION +``` + +### TypeScript + +```ts +import { GraphQLSchema, GraphQLDirective, DirectiveLocation, specifiedDirectives } from "graphql"; +export function getSchema(): GraphQLSchema { + return new GraphQLSchema({ + directives: [...specifiedDirectives, new GraphQLDirective({ + name: "aBetterName", + locations: [DirectiveLocation.FIELD_DEFINITION], + description: "This is my custom directive." + })], + types: [] + }); +} +``` \ No newline at end of file diff --git a/src/tests/fixtures/directives/defineCustomDirectiveLocationInvalid.invalid.ts.expected b/src/tests/fixtures/directives/defineCustomDirectiveLocationInvalid.invalid.ts.expected deleted file mode 100644 index 972de720..00000000 --- a/src/tests/fixtures/directives/defineCustomDirectiveLocationInvalid.invalid.ts.expected +++ /dev/null @@ -1,18 +0,0 @@ ------------------ -INPUT ------------------ -/** - * This is my custom directive. - * @gqlDirective on WHOOPS - */ -export function customDirective() {} - ------------------ -OUTPUT ------------------ -src/tests/fixtures/directives/defineCustomDirectiveLocationInvalid.invalid.ts:3:4 - error: Syntax Error: Unexpected Name "WHOOPS". - -3 * @gqlDirective on WHOOPS - ~~~~~~~~~~~~~~~~~~~~~~~ -4 */ - ~ diff --git a/src/tests/fixtures/directives/defineCustomDirectiveLocationInvalid.invalid.ts.expected.md b/src/tests/fixtures/directives/defineCustomDirectiveLocationInvalid.invalid.ts.expected.md new file mode 100644 index 00000000..b62a3557 --- /dev/null +++ b/src/tests/fixtures/directives/defineCustomDirectiveLocationInvalid.invalid.ts.expected.md @@ -0,0 +1,22 @@ +## input + +```ts title="directives/defineCustomDirectiveLocationInvalid.invalid.ts" +/** + * This is my custom directive. + * @gqlDirective on WHOOPS + */ +export function customDirective() {} +``` + +## Output + +### Error Report + +```text +src/tests/fixtures/directives/defineCustomDirectiveLocationInvalid.invalid.ts:3:4 - error: Syntax Error: Unexpected Name "WHOOPS". + +3 * @gqlDirective on WHOOPS + ~~~~~~~~~~~~~~~~~~~~~~~ +4 */ + ~ +``` \ No newline at end of file diff --git a/src/tests/fixtures/directives/defineCustomDirectiveMultipleLocations.ts.expected b/src/tests/fixtures/directives/defineCustomDirectiveMultipleLocations.ts.expected deleted file mode 100644 index e6d15985..00000000 --- a/src/tests/fixtures/directives/defineCustomDirectiveMultipleLocations.ts.expected +++ /dev/null @@ -1,27 +0,0 @@ ------------------ -INPUT ------------------ -/** - * This is my custom directive. - * @gqlDirective on FIELD_DEFINITION | ARGUMENT_DEFINITION - */ -function customDirective() {} - ------------------ -OUTPUT ------------------ --- SDL -- -"""This is my custom directive.""" -directive @customDirective on FIELD_DEFINITION | ARGUMENT_DEFINITION --- TypeScript -- -import { GraphQLSchema, GraphQLDirective, DirectiveLocation, specifiedDirectives } from "graphql"; -export function getSchema(): GraphQLSchema { - return new GraphQLSchema({ - directives: [...specifiedDirectives, new GraphQLDirective({ - name: "customDirective", - locations: [DirectiveLocation.FIELD_DEFINITION, DirectiveLocation.ARGUMENT_DEFINITION], - description: "This is my custom directive." - })], - types: [] - }); -} diff --git a/src/tests/fixtures/directives/defineCustomDirectiveMultipleLocations.ts.expected.md b/src/tests/fixtures/directives/defineCustomDirectiveMultipleLocations.ts.expected.md new file mode 100644 index 00000000..b724491c --- /dev/null +++ b/src/tests/fixtures/directives/defineCustomDirectiveMultipleLocations.ts.expected.md @@ -0,0 +1,34 @@ +## input + +```ts title="directives/defineCustomDirectiveMultipleLocations.ts" +/** + * This is my custom directive. + * @gqlDirective on FIELD_DEFINITION | ARGUMENT_DEFINITION + */ +function customDirective() {} +``` + +## Output + +### SDL + +```graphql +"""This is my custom directive.""" +directive @customDirective on FIELD_DEFINITION | ARGUMENT_DEFINITION +``` + +### TypeScript + +```ts +import { GraphQLSchema, GraphQLDirective, DirectiveLocation, specifiedDirectives } from "graphql"; +export function getSchema(): GraphQLSchema { + return new GraphQLSchema({ + directives: [...specifiedDirectives, new GraphQLDirective({ + name: "customDirective", + locations: [DirectiveLocation.FIELD_DEFINITION, DirectiveLocation.ARGUMENT_DEFINITION], + description: "This is my custom directive." + })], + types: [] + }); +} +``` \ No newline at end of file diff --git a/src/tests/fixtures/directives/defineCustomDirectiveNoLocation.invalid.ts.expected b/src/tests/fixtures/directives/defineCustomDirectiveNoLocation.invalid.ts.expected deleted file mode 100644 index 7437bde8..00000000 --- a/src/tests/fixtures/directives/defineCustomDirectiveNoLocation.invalid.ts.expected +++ /dev/null @@ -1,18 +0,0 @@ ------------------ -INPUT ------------------ -/** - * This is my custom directive. - * @gqlDirective - */ -function customDirective() {} - ------------------ -OUTPUT ------------------ -src/tests/fixtures/directives/defineCustomDirectiveNoLocation.invalid.ts:3:4 - error: Expected `@gqlDirective` tag to specify at least one location. - -3 * @gqlDirective - ~~~~~~~~~~~~~ -4 */ - ~ diff --git a/src/tests/fixtures/directives/defineCustomDirectiveNoLocation.invalid.ts.expected.md b/src/tests/fixtures/directives/defineCustomDirectiveNoLocation.invalid.ts.expected.md new file mode 100644 index 00000000..319c0922 --- /dev/null +++ b/src/tests/fixtures/directives/defineCustomDirectiveNoLocation.invalid.ts.expected.md @@ -0,0 +1,22 @@ +## input + +```ts title="directives/defineCustomDirectiveNoLocation.invalid.ts" +/** + * This is my custom directive. + * @gqlDirective + */ +function customDirective() {} +``` + +## Output + +### Error Report + +```text +src/tests/fixtures/directives/defineCustomDirectiveNoLocation.invalid.ts:3:4 - error: Expected `@gqlDirective` tag to specify at least one location. + +3 * @gqlDirective + ~~~~~~~~~~~~~ +4 */ + ~ +``` \ No newline at end of file diff --git a/src/tests/fixtures/directives/defineCustomDirectiveOnIsNotString.invalid.ts.expected b/src/tests/fixtures/directives/defineCustomDirectiveOnIsNotString.invalid.ts.expected deleted file mode 100644 index 4c05aec8..00000000 --- a/src/tests/fixtures/directives/defineCustomDirectiveOnIsNotString.invalid.ts.expected +++ /dev/null @@ -1,17 +0,0 @@ ------------------ -INPUT ------------------ -/** - * This is my custom directive. - * @gqlDirective on FIELD_DEFINITION This is a description with {@link https://example.com some link} - * and `inline code` to demonstrate structured comments. - */ -function customDirective() {} - ------------------ -OUTPUT ------------------ -src/tests/fixtures/directives/defineCustomDirectiveOnIsNotString.invalid.ts:3:65 - error: Expected Grats JSDoc tag value to be simple text. - -3 * @gqlDirective on FIELD_DEFINITION This is a description with {@link https://example.com some link} - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/src/tests/fixtures/directives/defineCustomDirectiveOnIsNotString.invalid.ts.expected.md b/src/tests/fixtures/directives/defineCustomDirectiveOnIsNotString.invalid.ts.expected.md new file mode 100644 index 00000000..557dde25 --- /dev/null +++ b/src/tests/fixtures/directives/defineCustomDirectiveOnIsNotString.invalid.ts.expected.md @@ -0,0 +1,21 @@ +## input + +```ts title="directives/defineCustomDirectiveOnIsNotString.invalid.ts" +/** + * This is my custom directive. + * @gqlDirective on FIELD_DEFINITION This is a description with {@link https://example.com some link} + * and `inline code` to demonstrate structured comments. + */ +function customDirective() {} +``` + +## Output + +### Error Report + +```text +src/tests/fixtures/directives/defineCustomDirectiveOnIsNotString.invalid.ts:3:65 - error: Expected Grats JSDoc tag value to be simple text. + +3 * @gqlDirective on FIELD_DEFINITION This is a description with {@link https://example.com some link} + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` \ No newline at end of file diff --git a/src/tests/fixtures/directives/defineCustomDirectiveReadsContext.invalid.ts.expected b/src/tests/fixtures/directives/defineCustomDirectiveReadsContext.invalid.ts.expected deleted file mode 100644 index 4083a280..00000000 --- a/src/tests/fixtures/directives/defineCustomDirectiveReadsContext.invalid.ts.expected +++ /dev/null @@ -1,19 +0,0 @@ ------------------ -INPUT ------------------ -/** @gqlContext */ -type Ctx = {}; - -/** - * This is my custom directive. - * @gqlDirective on FIELD_DEFINITION - */ -export function customDirective(oops: Ctx) {} - ------------------ -OUTPUT ------------------ -src/tests/fixtures/directives/defineCustomDirectiveReadsContext.invalid.ts:8:33 - error: Expected first argument of a `@gqlDirective` function to be typed using an inline object literal. - -8 export function customDirective(oops: Ctx) {} - ~~~~~~~~~ diff --git a/src/tests/fixtures/directives/defineCustomDirectiveReadsContext.invalid.ts.expected.md b/src/tests/fixtures/directives/defineCustomDirectiveReadsContext.invalid.ts.expected.md new file mode 100644 index 00000000..c6526e48 --- /dev/null +++ b/src/tests/fixtures/directives/defineCustomDirectiveReadsContext.invalid.ts.expected.md @@ -0,0 +1,23 @@ +## input + +```ts title="directives/defineCustomDirectiveReadsContext.invalid.ts" +/** @gqlContext */ +type Ctx = {}; + +/** + * This is my custom directive. + * @gqlDirective on FIELD_DEFINITION + */ +export function customDirective(oops: Ctx) {} +``` + +## Output + +### Error Report + +```text +src/tests/fixtures/directives/defineCustomDirectiveReadsContext.invalid.ts:8:33 - error: Expected first argument of a `@gqlDirective` function to be typed using an inline object literal. + +8 export function customDirective(oops: Ctx) {} + ~~~~~~~~~ +``` \ No newline at end of file diff --git a/src/tests/fixtures/directives/defineCustomDirectiveRepeatable.ts.expected b/src/tests/fixtures/directives/defineCustomDirectiveRepeatable.ts.expected deleted file mode 100644 index 0c8b28ac..00000000 --- a/src/tests/fixtures/directives/defineCustomDirectiveRepeatable.ts.expected +++ /dev/null @@ -1,28 +0,0 @@ ------------------ -INPUT ------------------ -/** - * This is my custom directive. - * @gqlDirective repeatable on FIELD_DEFINITION - */ -function customDirective() {} - ------------------ -OUTPUT ------------------ --- SDL -- -"""This is my custom directive.""" -directive @customDirective repeatable on FIELD_DEFINITION --- TypeScript -- -import { GraphQLSchema, GraphQLDirective, DirectiveLocation, specifiedDirectives } from "graphql"; -export function getSchema(): GraphQLSchema { - return new GraphQLSchema({ - directives: [...specifiedDirectives, new GraphQLDirective({ - name: "customDirective", - locations: [DirectiveLocation.FIELD_DEFINITION], - description: "This is my custom directive.", - isRepeatable: true - })], - types: [] - }); -} diff --git a/src/tests/fixtures/directives/defineCustomDirectiveRepeatable.ts.expected.md b/src/tests/fixtures/directives/defineCustomDirectiveRepeatable.ts.expected.md new file mode 100644 index 00000000..0b771165 --- /dev/null +++ b/src/tests/fixtures/directives/defineCustomDirectiveRepeatable.ts.expected.md @@ -0,0 +1,35 @@ +## input + +```ts title="directives/defineCustomDirectiveRepeatable.ts" +/** + * This is my custom directive. + * @gqlDirective repeatable on FIELD_DEFINITION + */ +function customDirective() {} +``` + +## Output + +### SDL + +```graphql +"""This is my custom directive.""" +directive @customDirective repeatable on FIELD_DEFINITION +``` + +### TypeScript + +```ts +import { GraphQLSchema, GraphQLDirective, DirectiveLocation, specifiedDirectives } from "graphql"; +export function getSchema(): GraphQLSchema { + return new GraphQLSchema({ + directives: [...specifiedDirectives, new GraphQLDirective({ + name: "customDirective", + locations: [DirectiveLocation.FIELD_DEFINITION], + description: "This is my custom directive.", + isRepeatable: true + })], + types: [] + }); +} +``` \ No newline at end of file diff --git a/src/tests/fixtures/directives/defineCustomDirectiveWithArgs.ts.expected b/src/tests/fixtures/directives/defineCustomDirectiveWithArgs.ts.expected deleted file mode 100644 index 987efa38..00000000 --- a/src/tests/fixtures/directives/defineCustomDirectiveWithArgs.ts.expected +++ /dev/null @@ -1,32 +0,0 @@ ------------------ -INPUT ------------------ -/** - * This is my custom directive. - * @gqlDirective on FIELD_DEFINITION - */ -export function customDirective(arg: { someArg: string }) {} - ------------------ -OUTPUT ------------------ --- SDL -- -"""This is my custom directive.""" -directive @customDirective(someArg: String!) on FIELD_DEFINITION --- TypeScript -- -import { GraphQLSchema, GraphQLDirective, DirectiveLocation, GraphQLNonNull, GraphQLString, specifiedDirectives } from "graphql"; -export function getSchema(): GraphQLSchema { - return new GraphQLSchema({ - directives: [...specifiedDirectives, new GraphQLDirective({ - name: "customDirective", - locations: [DirectiveLocation.FIELD_DEFINITION], - description: "This is my custom directive.", - args: { - someArg: { - type: new GraphQLNonNull(GraphQLString) - } - } - })], - types: [] - }); -} diff --git a/src/tests/fixtures/directives/defineCustomDirectiveWithArgs.ts.expected.md b/src/tests/fixtures/directives/defineCustomDirectiveWithArgs.ts.expected.md new file mode 100644 index 00000000..5474a732 --- /dev/null +++ b/src/tests/fixtures/directives/defineCustomDirectiveWithArgs.ts.expected.md @@ -0,0 +1,39 @@ +## input + +```ts title="directives/defineCustomDirectiveWithArgs.ts" +/** + * This is my custom directive. + * @gqlDirective on FIELD_DEFINITION + */ +export function customDirective(arg: { someArg: string }) {} +``` + +## Output + +### SDL + +```graphql +"""This is my custom directive.""" +directive @customDirective(someArg: String!) on FIELD_DEFINITION +``` + +### TypeScript + +```ts +import { GraphQLSchema, GraphQLDirective, DirectiveLocation, GraphQLNonNull, GraphQLString, specifiedDirectives } from "graphql"; +export function getSchema(): GraphQLSchema { + return new GraphQLSchema({ + directives: [...specifiedDirectives, new GraphQLDirective({ + name: "customDirective", + locations: [DirectiveLocation.FIELD_DEFINITION], + description: "This is my custom directive.", + args: { + someArg: { + type: new GraphQLNonNull(GraphQLString) + } + } + })], + types: [] + }); +} +``` \ No newline at end of file diff --git a/src/tests/fixtures/directives/defineCustomDirectiveWithArgsNonScalar.ts.expected b/src/tests/fixtures/directives/defineCustomDirectiveWithArgsNonScalar.ts.expected deleted file mode 100644 index 226d4ceb..00000000 --- a/src/tests/fixtures/directives/defineCustomDirectiveWithArgsNonScalar.ts.expected +++ /dev/null @@ -1,52 +0,0 @@ ------------------ -INPUT ------------------ -/** @gqlInput */ -type SomeInput = { - someField: string; -}; - -/** - * This is my custom directive. - * @gqlDirective on FIELD_DEFINITION - */ -export function customDirective(args: { someArg: SomeInput }) {} - ------------------ -OUTPUT ------------------ --- SDL -- -"""This is my custom directive.""" -directive @customDirective(someArg: SomeInput!) on FIELD_DEFINITION - -input SomeInput { - someField: String! -} --- TypeScript -- -import { GraphQLSchema, GraphQLDirective, DirectiveLocation, GraphQLNonNull, GraphQLInputObjectType, GraphQLString, specifiedDirectives } from "graphql"; -export function getSchema(): GraphQLSchema { - const SomeInputType: GraphQLInputObjectType = new GraphQLInputObjectType({ - name: "SomeInput", - fields() { - return { - someField: { - name: "someField", - type: new GraphQLNonNull(GraphQLString) - } - }; - } - }); - return new GraphQLSchema({ - directives: [...specifiedDirectives, new GraphQLDirective({ - name: "customDirective", - locations: [DirectiveLocation.FIELD_DEFINITION], - description: "This is my custom directive.", - args: { - someArg: { - type: new GraphQLNonNull(SomeInputType) - } - } - })], - types: [SomeInputType] - }); -} diff --git a/src/tests/fixtures/directives/defineCustomDirectiveWithArgsNonScalar.ts.expected.md b/src/tests/fixtures/directives/defineCustomDirectiveWithArgsNonScalar.ts.expected.md new file mode 100644 index 00000000..99f861c6 --- /dev/null +++ b/src/tests/fixtures/directives/defineCustomDirectiveWithArgsNonScalar.ts.expected.md @@ -0,0 +1,59 @@ +## input + +```ts title="directives/defineCustomDirectiveWithArgsNonScalar.ts" +/** @gqlInput */ +type SomeInput = { + someField: string; +}; + +/** + * This is my custom directive. + * @gqlDirective on FIELD_DEFINITION + */ +export function customDirective(args: { someArg: SomeInput }) {} +``` + +## Output + +### SDL + +```graphql +"""This is my custom directive.""" +directive @customDirective(someArg: SomeInput!) on FIELD_DEFINITION + +input SomeInput { + someField: String! +} +``` + +### TypeScript + +```ts +import { GraphQLSchema, GraphQLDirective, DirectiveLocation, GraphQLNonNull, GraphQLInputObjectType, GraphQLString, specifiedDirectives } from "graphql"; +export function getSchema(): GraphQLSchema { + const SomeInputType: GraphQLInputObjectType = new GraphQLInputObjectType({ + name: "SomeInput", + fields() { + return { + someField: { + name: "someField", + type: new GraphQLNonNull(GraphQLString) + } + }; + } + }); + return new GraphQLSchema({ + directives: [...specifiedDirectives, new GraphQLDirective({ + name: "customDirective", + locations: [DirectiveLocation.FIELD_DEFINITION], + description: "This is my custom directive.", + args: { + someArg: { + type: new GraphQLNonNull(SomeInputType) + } + } + })], + types: [SomeInputType] + }); +} +``` \ No newline at end of file diff --git a/src/tests/fixtures/directives/defineCustomDirectiveWithArgsWithDefault.ts.expected b/src/tests/fixtures/directives/defineCustomDirectiveWithArgsWithDefault.ts.expected deleted file mode 100644 index 8d969714..00000000 --- a/src/tests/fixtures/directives/defineCustomDirectiveWithArgsWithDefault.ts.expected +++ /dev/null @@ -1,33 +0,0 @@ ------------------ -INPUT ------------------ -/** - * This is my custom directive. - * @gqlDirective on FIELD_DEFINITION - */ -export function customDirective({ someArg = "Hello" }: { someArg: string }) {} - ------------------ -OUTPUT ------------------ --- SDL -- -"""This is my custom directive.""" -directive @customDirective(someArg: String! = "Hello") on FIELD_DEFINITION --- TypeScript -- -import { GraphQLSchema, GraphQLDirective, DirectiveLocation, GraphQLNonNull, GraphQLString, specifiedDirectives } from "graphql"; -export function getSchema(): GraphQLSchema { - return new GraphQLSchema({ - directives: [...specifiedDirectives, new GraphQLDirective({ - name: "customDirective", - locations: [DirectiveLocation.FIELD_DEFINITION], - description: "This is my custom directive.", - args: { - someArg: { - type: new GraphQLNonNull(GraphQLString), - defaultValue: "Hello" - } - } - })], - types: [] - }); -} diff --git a/src/tests/fixtures/directives/defineCustomDirectiveWithArgsWithDefault.ts.expected.md b/src/tests/fixtures/directives/defineCustomDirectiveWithArgsWithDefault.ts.expected.md new file mode 100644 index 00000000..b630c5d7 --- /dev/null +++ b/src/tests/fixtures/directives/defineCustomDirectiveWithArgsWithDefault.ts.expected.md @@ -0,0 +1,40 @@ +## input + +```ts title="directives/defineCustomDirectiveWithArgsWithDefault.ts" +/** + * This is my custom directive. + * @gqlDirective on FIELD_DEFINITION + */ +export function customDirective({ someArg = "Hello" }: { someArg: string }) {} +``` + +## Output + +### SDL + +```graphql +"""This is my custom directive.""" +directive @customDirective(someArg: String! = "Hello") on FIELD_DEFINITION +``` + +### TypeScript + +```ts +import { GraphQLSchema, GraphQLDirective, DirectiveLocation, GraphQLNonNull, GraphQLString, specifiedDirectives } from "graphql"; +export function getSchema(): GraphQLSchema { + return new GraphQLSchema({ + directives: [...specifiedDirectives, new GraphQLDirective({ + name: "customDirective", + locations: [DirectiveLocation.FIELD_DEFINITION], + description: "This is my custom directive.", + args: { + someArg: { + type: new GraphQLNonNull(GraphQLString), + defaultValue: "Hello" + } + } + })], + types: [] + }); +} +``` \ No newline at end of file diff --git a/src/tests/fixtures/directives/directiveArgFieldInvalid.invalid.ts.expected b/src/tests/fixtures/directives/directiveArgFieldInvalid.invalid.ts.expected deleted file mode 100644 index d2c46397..00000000 --- a/src/tests/fixtures/directives/directiveArgFieldInvalid.invalid.ts.expected +++ /dev/null @@ -1,33 +0,0 @@ ------------------ -INPUT ------------------ -/** - * @gqlInput - */ -type MyInput = { a: string }; -/** - * This is my custom directive. - * @gqlDirective on FIELD_DEFINITION - */ -export function customDirective(args: { foo: MyInput }) {} - -/** - * @gqlQueryField - * @gqlAnnotate customDirective(foo: {a: 10}) - */ -export function myQueryField(): string { - return "myQueryField"; -} - ------------------ -OUTPUT ------------------ -GraphQL request:1:27 - error: String cannot represent a non string value: 10 - -1 @customDirective(foo: {a: 10}) - ~~ - - src/tests/fixtures/directives/directiveArgFieldInvalid.invalid.ts:4:1 - 4 type MyInput = { a: string }; - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - Parent input type defined here diff --git a/src/tests/fixtures/directives/directiveArgFieldInvalid.invalid.ts.expected.md b/src/tests/fixtures/directives/directiveArgFieldInvalid.invalid.ts.expected.md new file mode 100644 index 00000000..b10cc676 --- /dev/null +++ b/src/tests/fixtures/directives/directiveArgFieldInvalid.invalid.ts.expected.md @@ -0,0 +1,37 @@ +## input + +```ts title="directives/directiveArgFieldInvalid.invalid.ts" +/** + * @gqlInput + */ +type MyInput = { a: string }; +/** + * This is my custom directive. + * @gqlDirective on FIELD_DEFINITION + */ +export function customDirective(args: { foo: MyInput }) {} + +/** + * @gqlQueryField + * @gqlAnnotate customDirective(foo: {a: 10}) + */ +export function myQueryField(): string { + return "myQueryField"; +} +``` + +## Output + +### Error Report + +```text +GraphQL request:1:27 - error: String cannot represent a non string value: 10 + +1 @customDirective(foo: {a: 10}) + ~~ + + src/tests/fixtures/directives/directiveArgFieldInvalid.invalid.ts:4:1 + 4 type MyInput = { a: string }; + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + Parent input type defined here +``` \ No newline at end of file diff --git a/src/tests/fixtures/directives/directiveArgInvalidOneOf.invalid.ts.expected b/src/tests/fixtures/directives/directiveArgInvalidOneOf.invalid.ts.expected deleted file mode 100644 index 1695ecc3..00000000 --- a/src/tests/fixtures/directives/directiveArgInvalidOneOf.invalid.ts.expected +++ /dev/null @@ -1,33 +0,0 @@ ------------------ -INPUT ------------------ -/** - * @gqlInput - */ -type MyInput = { a: string } | { b: string }; -/** - * This is my custom directive. - * @gqlDirective on FIELD_DEFINITION - */ -export function customDirective(args: { foo: MyInput }) {} - -/** - * @gqlQueryField - * @gqlAnnotate customDirective(foo: {a: "a", b: "b"}) - */ -export function myQueryField(): string { - return "myQueryField"; -} - ------------------ -OUTPUT ------------------ -GraphQL request:1:23 - error: OneOf Input Object "MyInput" must specify exactly one key. - -1 @customDirective(foo: {a: "a", b: "b"}) - ~~~~~~~~~~~~~~~~ - - src/tests/fixtures/directives/directiveArgInvalidOneOf.invalid.ts:4:1 - 4 type MyInput = { a: string } | { b: string }; - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - Input type defined here diff --git a/src/tests/fixtures/directives/directiveArgInvalidOneOf.invalid.ts.expected.md b/src/tests/fixtures/directives/directiveArgInvalidOneOf.invalid.ts.expected.md new file mode 100644 index 00000000..4c01b641 --- /dev/null +++ b/src/tests/fixtures/directives/directiveArgInvalidOneOf.invalid.ts.expected.md @@ -0,0 +1,37 @@ +## input + +```ts title="directives/directiveArgInvalidOneOf.invalid.ts" +/** + * @gqlInput + */ +type MyInput = { a: string } | { b: string }; +/** + * This is my custom directive. + * @gqlDirective on FIELD_DEFINITION + */ +export function customDirective(args: { foo: MyInput }) {} + +/** + * @gqlQueryField + * @gqlAnnotate customDirective(foo: {a: "a", b: "b"}) + */ +export function myQueryField(): string { + return "myQueryField"; +} +``` + +## Output + +### Error Report + +```text +GraphQL request:1:23 - error: OneOf Input Object "MyInput" must specify exactly one key. + +1 @customDirective(foo: {a: "a", b: "b"}) + ~~~~~~~~~~~~~~~~ + + src/tests/fixtures/directives/directiveArgInvalidOneOf.invalid.ts:4:1 + 4 type MyInput = { a: string } | { b: string }; + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + Input type defined here +``` \ No newline at end of file diff --git a/src/tests/fixtures/directives/directiveArgumentNameIsStringLiteralWithDefault.ts.expected b/src/tests/fixtures/directives/directiveArgumentNameIsStringLiteralWithDefault.ts.expected deleted file mode 100644 index 65553e51..00000000 --- a/src/tests/fixtures/directives/directiveArgumentNameIsStringLiteralWithDefault.ts.expected +++ /dev/null @@ -1,41 +0,0 @@ ------------------ -INPUT ------------------ -// https://github.com/captbaritone/grats/issues/166#issuecomment-2753130827 - -/** - * @gqlDirective on FRAGMENT_SPREAD | INLINE_FRAGMENT - */ -function defer({ - label, - if: _ = true, // anonymous alias -}: { - label: string; - if?: boolean | null; -}): void {} - ------------------ -OUTPUT ------------------ --- SDL -- -directive @defer(label: String!, if: Boolean = true) on FRAGMENT_SPREAD | INLINE_FRAGMENT --- TypeScript -- -import { GraphQLSchema, GraphQLDirective, DirectiveLocation, GraphQLNonNull, GraphQLString, GraphQLBoolean, specifiedDirectives } from "graphql"; -export function getSchema(): GraphQLSchema { - return new GraphQLSchema({ - directives: [...specifiedDirectives, new GraphQLDirective({ - name: "defer", - locations: [DirectiveLocation.FRAGMENT_SPREAD, DirectiveLocation.INLINE_FRAGMENT], - args: { - label: { - type: new GraphQLNonNull(GraphQLString) - }, - if: { - type: GraphQLBoolean, - defaultValue: true - } - } - })], - types: [] - }); -} diff --git a/src/tests/fixtures/directives/directiveArgumentNameIsStringLiteralWithDefault.ts.expected.md b/src/tests/fixtures/directives/directiveArgumentNameIsStringLiteralWithDefault.ts.expected.md new file mode 100644 index 00000000..e11bd23c --- /dev/null +++ b/src/tests/fixtures/directives/directiveArgumentNameIsStringLiteralWithDefault.ts.expected.md @@ -0,0 +1,48 @@ +## input + +```ts title="directives/directiveArgumentNameIsStringLiteralWithDefault.ts" +// https://github.com/captbaritone/grats/issues/166#issuecomment-2753130827 + +/** + * @gqlDirective on FRAGMENT_SPREAD | INLINE_FRAGMENT + */ +function defer({ + label, + if: _ = true, // anonymous alias +}: { + label: string; + if?: boolean | null; +}): void {} +``` + +## Output + +### SDL + +```graphql +directive @defer(label: String!, if: Boolean = true) on FRAGMENT_SPREAD | INLINE_FRAGMENT +``` + +### TypeScript + +```ts +import { GraphQLSchema, GraphQLDirective, DirectiveLocation, GraphQLNonNull, GraphQLString, GraphQLBoolean, specifiedDirectives } from "graphql"; +export function getSchema(): GraphQLSchema { + return new GraphQLSchema({ + directives: [...specifiedDirectives, new GraphQLDirective({ + name: "defer", + locations: [DirectiveLocation.FRAGMENT_SPREAD, DirectiveLocation.INLINE_FRAGMENT], + args: { + label: { + type: new GraphQLNonNull(GraphQLString) + }, + if: { + type: GraphQLBoolean, + defaultValue: true + } + } + })], + types: [] + }); +} +``` \ No newline at end of file diff --git a/src/tests/fixtures/directives/directiveNotConst.invalid.ts.expected b/src/tests/fixtures/directives/directiveNotConst.invalid.ts.expected deleted file mode 100644 index bca41772..00000000 --- a/src/tests/fixtures/directives/directiveNotConst.invalid.ts.expected +++ /dev/null @@ -1,23 +0,0 @@ ------------------ -INPUT ------------------ -// Because @myDirective is followed by `(` we assume it's expected to be parsed -// as a directive even though it's not defined. - -/** - * @gqlQueryField - * @gqlAnnotate myDirective(someArg: $foo) - */ -export function myQueryField(): string { - return "myQueryField"; -} - ------------------ -OUTPUT ------------------ -src/tests/fixtures/directives/directiveNotConst.invalid.ts:6:4 - error: Syntax Error: Unexpected variable "$foo" in constant value. - -6 * @gqlAnnotate myDirective(someArg: $foo) - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -7 */ - ~ diff --git a/src/tests/fixtures/directives/directiveNotConst.invalid.ts.expected.md b/src/tests/fixtures/directives/directiveNotConst.invalid.ts.expected.md new file mode 100644 index 00000000..ad801478 --- /dev/null +++ b/src/tests/fixtures/directives/directiveNotConst.invalid.ts.expected.md @@ -0,0 +1,27 @@ +## input + +```ts title="directives/directiveNotConst.invalid.ts" +// Because @myDirective is followed by `(` we assume it's expected to be parsed +// as a directive even though it's not defined. + +/** + * @gqlQueryField + * @gqlAnnotate myDirective(someArg: $foo) + */ +export function myQueryField(): string { + return "myQueryField"; +} +``` + +## Output + +### Error Report + +```text +src/tests/fixtures/directives/directiveNotConst.invalid.ts:6:4 - error: Syntax Error: Unexpected variable "$foo" in constant value. + +6 * @gqlAnnotate myDirective(someArg: $foo) + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +7 */ + ~ +``` \ No newline at end of file diff --git a/src/tests/fixtures/directives/directiveOnArgumentDefinition.ts.expected b/src/tests/fixtures/directives/directiveOnArgumentDefinition.ts.expected deleted file mode 100644 index 5d4e31f9..00000000 --- a/src/tests/fixtures/directives/directiveOnArgumentDefinition.ts.expected +++ /dev/null @@ -1,80 +0,0 @@ ------------------ -INPUT ------------------ -import { Int } from "../../../Types"; -/** - * This is my custom directive. - * @gqlDirective on ARGUMENT_DEFINITION - */ -export function max(args: { foo: Int }) {} - -/** - * All likes in the system. Note that there is no guarantee of order. - * @gqlQueryField */ -export function likes(args: { - /** @gqlAnnotate max(foo: 10) */ - first?: Int | null; -}): string { - return "hello"; -} - ------------------ -OUTPUT ------------------ --- SDL -- -"""This is my custom directive.""" -directive @max(foo: Int!) on ARGUMENT_DEFINITION - -type Query { - """All likes in the system. Note that there is no guarantee of order.""" - likes(first: Int @max(foo: 10)): String -} --- TypeScript -- -import { GraphQLSchema, GraphQLDirective, DirectiveLocation, GraphQLNonNull, GraphQLInt, specifiedDirectives, GraphQLObjectType, GraphQLString } from "graphql"; -import { likes as queryLikesResolver } from "./directiveOnArgumentDefinition"; -export function getSchema(): GraphQLSchema { - const QueryType: GraphQLObjectType = new GraphQLObjectType({ - name: "Query", - fields() { - return { - likes: { - description: "All likes in the system. Note that there is no guarantee of order.", - name: "likes", - type: GraphQLString, - args: { - first: { - type: GraphQLInt, - extensions: { - grats: { - directives: [{ - name: "max", - args: { - foo: 10 - } - }] - } - } - } - }, - resolve(_source, args) { - return queryLikesResolver(args); - } - } - }; - } - }); - return new GraphQLSchema({ - directives: [...specifiedDirectives, new GraphQLDirective({ - name: "max", - locations: [DirectiveLocation.ARGUMENT_DEFINITION], - description: "This is my custom directive.", - args: { - foo: { - type: new GraphQLNonNull(GraphQLInt) - } - } - })], - query: QueryType, - types: [QueryType] - }); -} diff --git a/src/tests/fixtures/directives/directiveOnArgumentDefinition.ts.expected.md b/src/tests/fixtures/directives/directiveOnArgumentDefinition.ts.expected.md new file mode 100644 index 00000000..75795b5d --- /dev/null +++ b/src/tests/fixtures/directives/directiveOnArgumentDefinition.ts.expected.md @@ -0,0 +1,87 @@ +## input + +```ts title="directives/directiveOnArgumentDefinition.ts" +import { Int } from "../../../Types"; +/** + * This is my custom directive. + * @gqlDirective on ARGUMENT_DEFINITION + */ +export function max(args: { foo: Int }) {} + +/** + * All likes in the system. Note that there is no guarantee of order. + * @gqlQueryField */ +export function likes(args: { + /** @gqlAnnotate max(foo: 10) */ + first?: Int | null; +}): string { + return "hello"; +} +``` + +## Output + +### SDL + +```graphql +"""This is my custom directive.""" +directive @max(foo: Int!) on ARGUMENT_DEFINITION + +type Query { + """All likes in the system. Note that there is no guarantee of order.""" + likes(first: Int @max(foo: 10)): String +} +``` + +### TypeScript + +```ts +import { GraphQLSchema, GraphQLDirective, DirectiveLocation, GraphQLNonNull, GraphQLInt, specifiedDirectives, GraphQLObjectType, GraphQLString } from "graphql"; +import { likes as queryLikesResolver } from "./directiveOnArgumentDefinition"; +export function getSchema(): GraphQLSchema { + const QueryType: GraphQLObjectType = new GraphQLObjectType({ + name: "Query", + fields() { + return { + likes: { + description: "All likes in the system. Note that there is no guarantee of order.", + name: "likes", + type: GraphQLString, + args: { + first: { + type: GraphQLInt, + extensions: { + grats: { + directives: [{ + name: "max", + args: { + foo: 10 + } + }] + } + } + } + }, + resolve(_source, args) { + return queryLikesResolver(args); + } + } + }; + } + }); + return new GraphQLSchema({ + directives: [...specifiedDirectives, new GraphQLDirective({ + name: "max", + locations: [DirectiveLocation.ARGUMENT_DEFINITION], + description: "This is my custom directive.", + args: { + foo: { + type: new GraphQLNonNull(GraphQLInt) + } + } + })], + query: QueryType, + types: [QueryType] + }); +} +``` \ No newline at end of file diff --git a/src/tests/fixtures/directives/directiveOnEnum.ts.expected b/src/tests/fixtures/directives/directiveOnEnum.ts.expected deleted file mode 100644 index ebbbd407..00000000 --- a/src/tests/fixtures/directives/directiveOnEnum.ts.expected +++ /dev/null @@ -1,65 +0,0 @@ ------------------ -INPUT ------------------ -import { Int } from "../../../Types"; -/** - * This is my custom directive. - * @gqlDirective on ENUM - */ -export function max(args: { foo: Int }) {} - -/** - * @gqlEnum - * @gqlAnnotate max(foo: 10) - */ -type MyEnum = "A" | "B"; - ------------------ -OUTPUT ------------------ --- SDL -- -"""This is my custom directive.""" -directive @max(foo: Int!) on ENUM - -enum MyEnum @max(foo: 10) { - A - B -} --- TypeScript -- -import { GraphQLSchema, GraphQLDirective, DirectiveLocation, GraphQLNonNull, GraphQLInt, specifiedDirectives, GraphQLEnumType } from "graphql"; -export function getSchema(): GraphQLSchema { - const MyEnumType: GraphQLEnumType = new GraphQLEnumType({ - name: "MyEnum", - values: { - A: { - value: "A" - }, - B: { - value: "B" - } - }, - extensions: { - grats: { - directives: [{ - name: "max", - args: { - foo: 10 - } - }] - } - } - }); - return new GraphQLSchema({ - directives: [...specifiedDirectives, new GraphQLDirective({ - name: "max", - locations: [DirectiveLocation.ENUM], - description: "This is my custom directive.", - args: { - foo: { - type: new GraphQLNonNull(GraphQLInt) - } - } - })], - types: [MyEnumType] - }); -} diff --git a/src/tests/fixtures/directives/directiveOnEnum.ts.expected.md b/src/tests/fixtures/directives/directiveOnEnum.ts.expected.md new file mode 100644 index 00000000..9f2236e5 --- /dev/null +++ b/src/tests/fixtures/directives/directiveOnEnum.ts.expected.md @@ -0,0 +1,72 @@ +## input + +```ts title="directives/directiveOnEnum.ts" +import { Int } from "../../../Types"; +/** + * This is my custom directive. + * @gqlDirective on ENUM + */ +export function max(args: { foo: Int }) {} + +/** + * @gqlEnum + * @gqlAnnotate max(foo: 10) + */ +type MyEnum = "A" | "B"; +``` + +## Output + +### SDL + +```graphql +"""This is my custom directive.""" +directive @max(foo: Int!) on ENUM + +enum MyEnum @max(foo: 10) { + A + B +} +``` + +### TypeScript + +```ts +import { GraphQLSchema, GraphQLDirective, DirectiveLocation, GraphQLNonNull, GraphQLInt, specifiedDirectives, GraphQLEnumType } from "graphql"; +export function getSchema(): GraphQLSchema { + const MyEnumType: GraphQLEnumType = new GraphQLEnumType({ + name: "MyEnum", + values: { + A: { + value: "A" + }, + B: { + value: "B" + } + }, + extensions: { + grats: { + directives: [{ + name: "max", + args: { + foo: 10 + } + }] + } + } + }); + return new GraphQLSchema({ + directives: [...specifiedDirectives, new GraphQLDirective({ + name: "max", + locations: [DirectiveLocation.ENUM], + description: "This is my custom directive.", + args: { + foo: { + type: new GraphQLNonNull(GraphQLInt) + } + } + })], + types: [MyEnumType] + }); +} +``` \ No newline at end of file diff --git a/src/tests/fixtures/directives/directiveOnEnumValue.ts.expected b/src/tests/fixtures/directives/directiveOnEnumValue.ts.expected deleted file mode 100644 index 9ae22d10..00000000 --- a/src/tests/fixtures/directives/directiveOnEnumValue.ts.expected +++ /dev/null @@ -1,68 +0,0 @@ ------------------ -INPUT ------------------ -import { Int } from "../../../Types"; -/** - * This is my custom directive. - * @gqlDirective on ENUM_VALUE - */ -export function max(args: { foo: Int }) {} - -/** - * @gqlEnum - */ -enum MyEnum { - /** @gqlAnnotate max(foo: 10) */ - a = "A", - b = "B", -} - ------------------ -OUTPUT ------------------ --- SDL -- -"""This is my custom directive.""" -directive @max(foo: Int!) on ENUM_VALUE - -enum MyEnum { - A @max(foo: 10) - B -} --- TypeScript -- -import { GraphQLSchema, GraphQLDirective, DirectiveLocation, GraphQLNonNull, GraphQLInt, specifiedDirectives, GraphQLEnumType } from "graphql"; -export function getSchema(): GraphQLSchema { - const MyEnumType: GraphQLEnumType = new GraphQLEnumType({ - name: "MyEnum", - values: { - A: { - value: "A", - extensions: { - grats: { - directives: [{ - name: "max", - args: { - foo: 10 - } - }] - } - } - }, - B: { - value: "B" - } - } - }); - return new GraphQLSchema({ - directives: [...specifiedDirectives, new GraphQLDirective({ - name: "max", - locations: [DirectiveLocation.ENUM_VALUE], - description: "This is my custom directive.", - args: { - foo: { - type: new GraphQLNonNull(GraphQLInt) - } - } - })], - types: [MyEnumType] - }); -} diff --git a/src/tests/fixtures/directives/directiveOnEnumValue.ts.expected.md b/src/tests/fixtures/directives/directiveOnEnumValue.ts.expected.md new file mode 100644 index 00000000..4e0029b0 --- /dev/null +++ b/src/tests/fixtures/directives/directiveOnEnumValue.ts.expected.md @@ -0,0 +1,75 @@ +## input + +```ts title="directives/directiveOnEnumValue.ts" +import { Int } from "../../../Types"; +/** + * This is my custom directive. + * @gqlDirective on ENUM_VALUE + */ +export function max(args: { foo: Int }) {} + +/** + * @gqlEnum + */ +enum MyEnum { + /** @gqlAnnotate max(foo: 10) */ + a = "A", + b = "B", +} +``` + +## Output + +### SDL + +```graphql +"""This is my custom directive.""" +directive @max(foo: Int!) on ENUM_VALUE + +enum MyEnum { + A @max(foo: 10) + B +} +``` + +### TypeScript + +```ts +import { GraphQLSchema, GraphQLDirective, DirectiveLocation, GraphQLNonNull, GraphQLInt, specifiedDirectives, GraphQLEnumType } from "graphql"; +export function getSchema(): GraphQLSchema { + const MyEnumType: GraphQLEnumType = new GraphQLEnumType({ + name: "MyEnum", + values: { + A: { + value: "A", + extensions: { + grats: { + directives: [{ + name: "max", + args: { + foo: 10 + } + }] + } + } + }, + B: { + value: "B" + } + } + }); + return new GraphQLSchema({ + directives: [...specifiedDirectives, new GraphQLDirective({ + name: "max", + locations: [DirectiveLocation.ENUM_VALUE], + description: "This is my custom directive.", + args: { + foo: { + type: new GraphQLNonNull(GraphQLInt) + } + } + })], + types: [MyEnumType] + }); +} +``` \ No newline at end of file diff --git a/src/tests/fixtures/directives/directiveOnFieldDefinition.ts.expected b/src/tests/fixtures/directives/directiveOnFieldDefinition.ts.expected deleted file mode 100644 index 6a6dc216..00000000 --- a/src/tests/fixtures/directives/directiveOnFieldDefinition.ts.expected +++ /dev/null @@ -1,79 +0,0 @@ ------------------ -INPUT ------------------ -import { Int } from "../../../Types"; -/** - * This is my custom directive. - * @gqlDirective on FIELD_DEFINITION - */ -export function max(args: { foo: Int }) {} - -/** - * All likes in the system. Note that there is no guarantee of order. - * @gqlQueryField - * @gqlAnnotate max(foo: 10) - */ -export function likes(args: { first?: Int | null }): string { - return "hello"; -} - ------------------ -OUTPUT ------------------ --- SDL -- -"""This is my custom directive.""" -directive @max(foo: Int!) on FIELD_DEFINITION - -type Query { - """All likes in the system. Note that there is no guarantee of order.""" - likes(first: Int): String @max(foo: 10) -} --- TypeScript -- -import { GraphQLSchema, GraphQLDirective, DirectiveLocation, GraphQLNonNull, GraphQLInt, specifiedDirectives, GraphQLObjectType, GraphQLString } from "graphql"; -import { likes as queryLikesResolver } from "./directiveOnFieldDefinition"; -export function getSchema(): GraphQLSchema { - const QueryType: GraphQLObjectType = new GraphQLObjectType({ - name: "Query", - fields() { - return { - likes: { - description: "All likes in the system. Note that there is no guarantee of order.", - name: "likes", - type: GraphQLString, - args: { - first: { - type: GraphQLInt - } - }, - extensions: { - grats: { - directives: [{ - name: "max", - args: { - foo: 10 - } - }] - } - }, - resolve(_source, args) { - return queryLikesResolver(args); - } - } - }; - } - }); - return new GraphQLSchema({ - directives: [...specifiedDirectives, new GraphQLDirective({ - name: "max", - locations: [DirectiveLocation.FIELD_DEFINITION], - description: "This is my custom directive.", - args: { - foo: { - type: new GraphQLNonNull(GraphQLInt) - } - } - })], - query: QueryType, - types: [QueryType] - }); -} diff --git a/src/tests/fixtures/directives/directiveOnFieldDefinition.ts.expected.md b/src/tests/fixtures/directives/directiveOnFieldDefinition.ts.expected.md new file mode 100644 index 00000000..9451b13e --- /dev/null +++ b/src/tests/fixtures/directives/directiveOnFieldDefinition.ts.expected.md @@ -0,0 +1,86 @@ +## input + +```ts title="directives/directiveOnFieldDefinition.ts" +import { Int } from "../../../Types"; +/** + * This is my custom directive. + * @gqlDirective on FIELD_DEFINITION + */ +export function max(args: { foo: Int }) {} + +/** + * All likes in the system. Note that there is no guarantee of order. + * @gqlQueryField + * @gqlAnnotate max(foo: 10) + */ +export function likes(args: { first?: Int | null }): string { + return "hello"; +} +``` + +## Output + +### SDL + +```graphql +"""This is my custom directive.""" +directive @max(foo: Int!) on FIELD_DEFINITION + +type Query { + """All likes in the system. Note that there is no guarantee of order.""" + likes(first: Int): String @max(foo: 10) +} +``` + +### TypeScript + +```ts +import { GraphQLSchema, GraphQLDirective, DirectiveLocation, GraphQLNonNull, GraphQLInt, specifiedDirectives, GraphQLObjectType, GraphQLString } from "graphql"; +import { likes as queryLikesResolver } from "./directiveOnFieldDefinition"; +export function getSchema(): GraphQLSchema { + const QueryType: GraphQLObjectType = new GraphQLObjectType({ + name: "Query", + fields() { + return { + likes: { + description: "All likes in the system. Note that there is no guarantee of order.", + name: "likes", + type: GraphQLString, + args: { + first: { + type: GraphQLInt + } + }, + extensions: { + grats: { + directives: [{ + name: "max", + args: { + foo: 10 + } + }] + } + }, + resolve(_source, args) { + return queryLikesResolver(args); + } + } + }; + } + }); + return new GraphQLSchema({ + directives: [...specifiedDirectives, new GraphQLDirective({ + name: "max", + locations: [DirectiveLocation.FIELD_DEFINITION], + description: "This is my custom directive.", + args: { + foo: { + type: new GraphQLNonNull(GraphQLInt) + } + } + })], + query: QueryType, + types: [QueryType] + }); +} +``` \ No newline at end of file diff --git a/src/tests/fixtures/directives/directiveOnInputFieldDefinition.ts.expected b/src/tests/fixtures/directives/directiveOnInputFieldDefinition.ts.expected deleted file mode 100644 index b2076498..00000000 --- a/src/tests/fixtures/directives/directiveOnInputFieldDefinition.ts.expected +++ /dev/null @@ -1,66 +0,0 @@ ------------------ -INPUT ------------------ -import { Int } from "../../../Types"; -/** - * This is my custom directive. - * @gqlDirective on INPUT_FIELD_DEFINITION - */ -export function max(args: { foo: Int }) {} - -/** - * @gqlInput - */ -type MyType = { - /** @gqlAnnotate max(foo: 10) */ - myField: string; -}; - ------------------ -OUTPUT ------------------ --- SDL -- -"""This is my custom directive.""" -directive @max(foo: Int!) on INPUT_FIELD_DEFINITION - -input MyType { - myField: String! @max(foo: 10) -} --- TypeScript -- -import { GraphQLSchema, GraphQLDirective, DirectiveLocation, GraphQLNonNull, GraphQLInt, specifiedDirectives, GraphQLInputObjectType, GraphQLString } from "graphql"; -export function getSchema(): GraphQLSchema { - const MyTypeType: GraphQLInputObjectType = new GraphQLInputObjectType({ - name: "MyType", - fields() { - return { - myField: { - name: "myField", - type: new GraphQLNonNull(GraphQLString), - extensions: { - grats: { - directives: [{ - name: "max", - args: { - foo: 10 - } - }] - } - } - } - }; - } - }); - return new GraphQLSchema({ - directives: [...specifiedDirectives, new GraphQLDirective({ - name: "max", - locations: [DirectiveLocation.INPUT_FIELD_DEFINITION], - description: "This is my custom directive.", - args: { - foo: { - type: new GraphQLNonNull(GraphQLInt) - } - } - })], - types: [MyTypeType] - }); -} diff --git a/src/tests/fixtures/directives/directiveOnInputFieldDefinition.ts.expected.md b/src/tests/fixtures/directives/directiveOnInputFieldDefinition.ts.expected.md new file mode 100644 index 00000000..01aa6e6f --- /dev/null +++ b/src/tests/fixtures/directives/directiveOnInputFieldDefinition.ts.expected.md @@ -0,0 +1,73 @@ +## input + +```ts title="directives/directiveOnInputFieldDefinition.ts" +import { Int } from "../../../Types"; +/** + * This is my custom directive. + * @gqlDirective on INPUT_FIELD_DEFINITION + */ +export function max(args: { foo: Int }) {} + +/** + * @gqlInput + */ +type MyType = { + /** @gqlAnnotate max(foo: 10) */ + myField: string; +}; +``` + +## Output + +### SDL + +```graphql +"""This is my custom directive.""" +directive @max(foo: Int!) on INPUT_FIELD_DEFINITION + +input MyType { + myField: String! @max(foo: 10) +} +``` + +### TypeScript + +```ts +import { GraphQLSchema, GraphQLDirective, DirectiveLocation, GraphQLNonNull, GraphQLInt, specifiedDirectives, GraphQLInputObjectType, GraphQLString } from "graphql"; +export function getSchema(): GraphQLSchema { + const MyTypeType: GraphQLInputObjectType = new GraphQLInputObjectType({ + name: "MyType", + fields() { + return { + myField: { + name: "myField", + type: new GraphQLNonNull(GraphQLString), + extensions: { + grats: { + directives: [{ + name: "max", + args: { + foo: 10 + } + }] + } + } + } + }; + } + }); + return new GraphQLSchema({ + directives: [...specifiedDirectives, new GraphQLDirective({ + name: "max", + locations: [DirectiveLocation.INPUT_FIELD_DEFINITION], + description: "This is my custom directive.", + args: { + foo: { + type: new GraphQLNonNull(GraphQLInt) + } + } + })], + types: [MyTypeType] + }); +} +``` \ No newline at end of file diff --git a/src/tests/fixtures/directives/directiveOnInputObjectType.ts.expected b/src/tests/fixtures/directives/directiveOnInputObjectType.ts.expected deleted file mode 100644 index fcf07951..00000000 --- a/src/tests/fixtures/directives/directiveOnInputObjectType.ts.expected +++ /dev/null @@ -1,66 +0,0 @@ ------------------ -INPUT ------------------ -import { Int } from "../../../Types"; -/** - * This is my custom directive. - * @gqlDirective on INPUT_OBJECT - */ -export function max(args: { foo: Int }) {} - -/** - * @gqlInput - * @gqlAnnotate max(foo: 10) - */ -type MyType = { - myField: string; -}; - ------------------ -OUTPUT ------------------ --- SDL -- -"""This is my custom directive.""" -directive @max(foo: Int!) on INPUT_OBJECT - -input MyType @max(foo: 10) { - myField: String! -} --- TypeScript -- -import { GraphQLSchema, GraphQLDirective, DirectiveLocation, GraphQLNonNull, GraphQLInt, specifiedDirectives, GraphQLInputObjectType, GraphQLString } from "graphql"; -export function getSchema(): GraphQLSchema { - const MyTypeType: GraphQLInputObjectType = new GraphQLInputObjectType({ - name: "MyType", - fields() { - return { - myField: { - name: "myField", - type: new GraphQLNonNull(GraphQLString) - } - }; - }, - extensions: { - grats: { - directives: [{ - name: "max", - args: { - foo: 10 - } - }] - } - } - }); - return new GraphQLSchema({ - directives: [...specifiedDirectives, new GraphQLDirective({ - name: "max", - locations: [DirectiveLocation.INPUT_OBJECT], - description: "This is my custom directive.", - args: { - foo: { - type: new GraphQLNonNull(GraphQLInt) - } - } - })], - types: [MyTypeType] - }); -} diff --git a/src/tests/fixtures/directives/directiveOnInputObjectType.ts.expected.md b/src/tests/fixtures/directives/directiveOnInputObjectType.ts.expected.md new file mode 100644 index 00000000..37f19ea8 --- /dev/null +++ b/src/tests/fixtures/directives/directiveOnInputObjectType.ts.expected.md @@ -0,0 +1,73 @@ +## input + +```ts title="directives/directiveOnInputObjectType.ts" +import { Int } from "../../../Types"; +/** + * This is my custom directive. + * @gqlDirective on INPUT_OBJECT + */ +export function max(args: { foo: Int }) {} + +/** + * @gqlInput + * @gqlAnnotate max(foo: 10) + */ +type MyType = { + myField: string; +}; +``` + +## Output + +### SDL + +```graphql +"""This is my custom directive.""" +directive @max(foo: Int!) on INPUT_OBJECT + +input MyType @max(foo: 10) { + myField: String! +} +``` + +### TypeScript + +```ts +import { GraphQLSchema, GraphQLDirective, DirectiveLocation, GraphQLNonNull, GraphQLInt, specifiedDirectives, GraphQLInputObjectType, GraphQLString } from "graphql"; +export function getSchema(): GraphQLSchema { + const MyTypeType: GraphQLInputObjectType = new GraphQLInputObjectType({ + name: "MyType", + fields() { + return { + myField: { + name: "myField", + type: new GraphQLNonNull(GraphQLString) + } + }; + }, + extensions: { + grats: { + directives: [{ + name: "max", + args: { + foo: 10 + } + }] + } + } + }); + return new GraphQLSchema({ + directives: [...specifiedDirectives, new GraphQLDirective({ + name: "max", + locations: [DirectiveLocation.INPUT_OBJECT], + description: "This is my custom directive.", + args: { + foo: { + type: new GraphQLNonNull(GraphQLInt) + } + } + })], + types: [MyTypeType] + }); +} +``` \ No newline at end of file diff --git a/src/tests/fixtures/directives/directiveOnInterface.ts.expected b/src/tests/fixtures/directives/directiveOnInterface.ts.expected deleted file mode 100644 index c48a98cb..00000000 --- a/src/tests/fixtures/directives/directiveOnInterface.ts.expected +++ /dev/null @@ -1,67 +0,0 @@ ------------------ -INPUT ------------------ -import { Int } from "../../../Types"; -/** - * This is my custom directive. - * @gqlDirective on INTERFACE - */ -export function max(args: { foo: Int }) {} - -/** - * @gqlInterface - * @gqlAnnotate max(foo: 10) - */ -interface MyInterface { - /** @gqlField */ - myField: string; -} - ------------------ -OUTPUT ------------------ --- SDL -- -"""This is my custom directive.""" -directive @max(foo: Int!) on INTERFACE - -interface MyInterface @max(foo: 10) { - myField: String -} --- TypeScript -- -import { GraphQLSchema, GraphQLDirective, DirectiveLocation, GraphQLNonNull, GraphQLInt, specifiedDirectives, GraphQLInterfaceType, GraphQLString } from "graphql"; -export function getSchema(): GraphQLSchema { - const MyInterfaceType: GraphQLInterfaceType = new GraphQLInterfaceType({ - name: "MyInterface", - fields() { - return { - myField: { - name: "myField", - type: GraphQLString - } - }; - }, - extensions: { - grats: { - directives: [{ - name: "max", - args: { - foo: 10 - } - }] - } - } - }); - return new GraphQLSchema({ - directives: [...specifiedDirectives, new GraphQLDirective({ - name: "max", - locations: [DirectiveLocation.INTERFACE], - description: "This is my custom directive.", - args: { - foo: { - type: new GraphQLNonNull(GraphQLInt) - } - } - })], - types: [MyInterfaceType] - }); -} diff --git a/src/tests/fixtures/directives/directiveOnInterface.ts.expected.md b/src/tests/fixtures/directives/directiveOnInterface.ts.expected.md new file mode 100644 index 00000000..d14ca95a --- /dev/null +++ b/src/tests/fixtures/directives/directiveOnInterface.ts.expected.md @@ -0,0 +1,74 @@ +## input + +```ts title="directives/directiveOnInterface.ts" +import { Int } from "../../../Types"; +/** + * This is my custom directive. + * @gqlDirective on INTERFACE + */ +export function max(args: { foo: Int }) {} + +/** + * @gqlInterface + * @gqlAnnotate max(foo: 10) + */ +interface MyInterface { + /** @gqlField */ + myField: string; +} +``` + +## Output + +### SDL + +```graphql +"""This is my custom directive.""" +directive @max(foo: Int!) on INTERFACE + +interface MyInterface @max(foo: 10) { + myField: String +} +``` + +### TypeScript + +```ts +import { GraphQLSchema, GraphQLDirective, DirectiveLocation, GraphQLNonNull, GraphQLInt, specifiedDirectives, GraphQLInterfaceType, GraphQLString } from "graphql"; +export function getSchema(): GraphQLSchema { + const MyInterfaceType: GraphQLInterfaceType = new GraphQLInterfaceType({ + name: "MyInterface", + fields() { + return { + myField: { + name: "myField", + type: GraphQLString + } + }; + }, + extensions: { + grats: { + directives: [{ + name: "max", + args: { + foo: 10 + } + }] + } + } + }); + return new GraphQLSchema({ + directives: [...specifiedDirectives, new GraphQLDirective({ + name: "max", + locations: [DirectiveLocation.INTERFACE], + description: "This is my custom directive.", + args: { + foo: { + type: new GraphQLNonNull(GraphQLInt) + } + } + })], + types: [MyInterfaceType] + }); +} +``` \ No newline at end of file diff --git a/src/tests/fixtures/directives/directiveOnObjectType.ts.expected b/src/tests/fixtures/directives/directiveOnObjectType.ts.expected deleted file mode 100644 index 0d2570d3..00000000 --- a/src/tests/fixtures/directives/directiveOnObjectType.ts.expected +++ /dev/null @@ -1,67 +0,0 @@ ------------------ -INPUT ------------------ -import { Int } from "../../../Types"; -/** - * This is my custom directive. - * @gqlDirective on OBJECT - */ -export function max(args: { foo: Int }) {} - -/** - * @gqlType - * @gqlAnnotate max(foo: 10) - */ -type MyType = { - /** @gqlField */ - myField: string; -}; - ------------------ -OUTPUT ------------------ --- SDL -- -"""This is my custom directive.""" -directive @max(foo: Int!) on OBJECT - -type MyType @max(foo: 10) { - myField: String -} --- TypeScript -- -import { GraphQLSchema, GraphQLDirective, DirectiveLocation, GraphQLNonNull, GraphQLInt, specifiedDirectives, GraphQLObjectType, GraphQLString } from "graphql"; -export function getSchema(): GraphQLSchema { - const MyTypeType: GraphQLObjectType = new GraphQLObjectType({ - name: "MyType", - fields() { - return { - myField: { - name: "myField", - type: GraphQLString - } - }; - }, - extensions: { - grats: { - directives: [{ - name: "max", - args: { - foo: 10 - } - }] - } - } - }); - return new GraphQLSchema({ - directives: [...specifiedDirectives, new GraphQLDirective({ - name: "max", - locations: [DirectiveLocation.OBJECT], - description: "This is my custom directive.", - args: { - foo: { - type: new GraphQLNonNull(GraphQLInt) - } - } - })], - types: [MyTypeType] - }); -} diff --git a/src/tests/fixtures/directives/directiveOnObjectType.ts.expected.md b/src/tests/fixtures/directives/directiveOnObjectType.ts.expected.md new file mode 100644 index 00000000..51a1c2ba --- /dev/null +++ b/src/tests/fixtures/directives/directiveOnObjectType.ts.expected.md @@ -0,0 +1,74 @@ +## input + +```ts title="directives/directiveOnObjectType.ts" +import { Int } from "../../../Types"; +/** + * This is my custom directive. + * @gqlDirective on OBJECT + */ +export function max(args: { foo: Int }) {} + +/** + * @gqlType + * @gqlAnnotate max(foo: 10) + */ +type MyType = { + /** @gqlField */ + myField: string; +}; +``` + +## Output + +### SDL + +```graphql +"""This is my custom directive.""" +directive @max(foo: Int!) on OBJECT + +type MyType @max(foo: 10) { + myField: String +} +``` + +### TypeScript + +```ts +import { GraphQLSchema, GraphQLDirective, DirectiveLocation, GraphQLNonNull, GraphQLInt, specifiedDirectives, GraphQLObjectType, GraphQLString } from "graphql"; +export function getSchema(): GraphQLSchema { + const MyTypeType: GraphQLObjectType = new GraphQLObjectType({ + name: "MyType", + fields() { + return { + myField: { + name: "myField", + type: GraphQLString + } + }; + }, + extensions: { + grats: { + directives: [{ + name: "max", + args: { + foo: 10 + } + }] + } + } + }); + return new GraphQLSchema({ + directives: [...specifiedDirectives, new GraphQLDirective({ + name: "max", + locations: [DirectiveLocation.OBJECT], + description: "This is my custom directive.", + args: { + foo: { + type: new GraphQLNonNull(GraphQLInt) + } + } + })], + types: [MyTypeType] + }); +} +``` \ No newline at end of file diff --git a/src/tests/fixtures/directives/directiveOnScalar.ts.expected b/src/tests/fixtures/directives/directiveOnScalar.ts.expected deleted file mode 100644 index 3311d2f3..00000000 --- a/src/tests/fixtures/directives/directiveOnScalar.ts.expected +++ /dev/null @@ -1,62 +0,0 @@ ------------------ -INPUT ------------------ -import { Int } from "../../../Types"; -/** - * This is my custom directive. - * @gqlDirective on SCALAR - */ -export function max(args: { foo: Int }) {} - -/** - * @gqlScalar - * @gqlAnnotate max(foo: 10) - */ -export type MyScalar = string; - ------------------ -OUTPUT ------------------ --- SDL -- -"""This is my custom directive.""" -directive @max(foo: Int!) on SCALAR - -scalar MyScalar @max(foo: 10) --- TypeScript -- -import type { GqlScalar } from "grats"; -import type { MyScalar as MyScalarInternal } from "./directiveOnScalar"; -import { GraphQLSchema, GraphQLDirective, DirectiveLocation, GraphQLNonNull, GraphQLInt, specifiedDirectives, GraphQLScalarType } from "graphql"; -export type SchemaConfig = { - scalars: { - MyScalar: GqlScalar; - }; -}; -export function getSchema(config: SchemaConfig): GraphQLSchema { - const MyScalarType: GraphQLScalarType = new GraphQLScalarType({ - name: "MyScalar", - extensions: { - grats: { - directives: [{ - name: "max", - args: { - foo: 10 - } - }] - } - }, - ...config.scalars.MyScalar - }); - return new GraphQLSchema({ - directives: [...specifiedDirectives, new GraphQLDirective({ - name: "max", - locations: [DirectiveLocation.SCALAR], - description: "This is my custom directive.", - args: { - foo: { - type: new GraphQLNonNull(GraphQLInt) - } - } - })], - types: [MyScalarType] - }); -} diff --git a/src/tests/fixtures/directives/directiveOnScalar.ts.expected.md b/src/tests/fixtures/directives/directiveOnScalar.ts.expected.md new file mode 100644 index 00000000..91e25e51 --- /dev/null +++ b/src/tests/fixtures/directives/directiveOnScalar.ts.expected.md @@ -0,0 +1,69 @@ +## input + +```ts title="directives/directiveOnScalar.ts" +import { Int } from "../../../Types"; +/** + * This is my custom directive. + * @gqlDirective on SCALAR + */ +export function max(args: { foo: Int }) {} + +/** + * @gqlScalar + * @gqlAnnotate max(foo: 10) + */ +export type MyScalar = string; +``` + +## Output + +### SDL + +```graphql +"""This is my custom directive.""" +directive @max(foo: Int!) on SCALAR + +scalar MyScalar @max(foo: 10) +``` + +### TypeScript + +```ts +import type { GqlScalar } from "grats"; +import type { MyScalar as MyScalarInternal } from "./directiveOnScalar"; +import { GraphQLSchema, GraphQLDirective, DirectiveLocation, GraphQLNonNull, GraphQLInt, specifiedDirectives, GraphQLScalarType } from "graphql"; +export type SchemaConfig = { + scalars: { + MyScalar: GqlScalar; + }; +}; +export function getSchema(config: SchemaConfig): GraphQLSchema { + const MyScalarType: GraphQLScalarType = new GraphQLScalarType({ + name: "MyScalar", + extensions: { + grats: { + directives: [{ + name: "max", + args: { + foo: 10 + } + }] + } + }, + ...config.scalars.MyScalar + }); + return new GraphQLSchema({ + directives: [...specifiedDirectives, new GraphQLDirective({ + name: "max", + locations: [DirectiveLocation.SCALAR], + description: "This is my custom directive.", + args: { + foo: { + type: new GraphQLNonNull(GraphQLInt) + } + } + })], + types: [MyScalarType] + }); +} +``` \ No newline at end of file diff --git a/src/tests/fixtures/directives/directiveOnUnion.ts.expected b/src/tests/fixtures/directives/directiveOnUnion.ts.expected deleted file mode 100644 index ff7a62e9..00000000 --- a/src/tests/fixtures/directives/directiveOnUnion.ts.expected +++ /dev/null @@ -1,105 +0,0 @@ ------------------ -INPUT ------------------ -import { Int } from "../../../Types"; -/** - * This is my custom directive. - * @gqlDirective on UNION - */ -export function max(args: { foo: Int }) {} - -/** - * @gqlUnion - * @gqlAnnotate max(foo: 10) - */ -type MyUnion = A | B; - -/** - * @gqlType - */ -type A = { - __typename: "A"; - /** @gqlField */ - myField: string; -}; - -/** - * @gqlType - */ -type B = { - __typename: "B"; - /** @gqlField */ - myField: string; -}; - ------------------ -OUTPUT ------------------ --- SDL -- -"""This is my custom directive.""" -directive @max(foo: Int!) on UNION - -union MyUnion @max(foo: 10) = A | B - -type A { - myField: String -} - -type B { - myField: String -} --- TypeScript -- -import { GraphQLSchema, GraphQLDirective, DirectiveLocation, GraphQLNonNull, GraphQLInt, specifiedDirectives, GraphQLUnionType, GraphQLObjectType, GraphQLString } from "graphql"; -export function getSchema(): GraphQLSchema { - const AType: GraphQLObjectType = new GraphQLObjectType({ - name: "A", - fields() { - return { - myField: { - name: "myField", - type: GraphQLString - } - }; - } - }); - const BType: GraphQLObjectType = new GraphQLObjectType({ - name: "B", - fields() { - return { - myField: { - name: "myField", - type: GraphQLString - } - }; - } - }); - const MyUnionType: GraphQLUnionType = new GraphQLUnionType({ - name: "MyUnion", - types() { - return [AType, BType]; - }, - extensions: { - grats: { - directives: [{ - name: "max", - args: { - foo: 10 - } - }] - } - } - }); - return new GraphQLSchema({ - directives: [...specifiedDirectives, new GraphQLDirective({ - name: "max", - locations: [DirectiveLocation.UNION], - description: "This is my custom directive.", - args: { - foo: { - type: new GraphQLNonNull(GraphQLInt) - } - } - })], - types: [MyUnionType, AType, BType] - }); -} diff --git a/src/tests/fixtures/directives/directiveOnUnion.ts.expected.md b/src/tests/fixtures/directives/directiveOnUnion.ts.expected.md new file mode 100644 index 00000000..1fc2c020 --- /dev/null +++ b/src/tests/fixtures/directives/directiveOnUnion.ts.expected.md @@ -0,0 +1,112 @@ +## input + +```ts title="directives/directiveOnUnion.ts" +import { Int } from "../../../Types"; +/** + * This is my custom directive. + * @gqlDirective on UNION + */ +export function max(args: { foo: Int }) {} + +/** + * @gqlUnion + * @gqlAnnotate max(foo: 10) + */ +type MyUnion = A | B; + +/** + * @gqlType + */ +type A = { + __typename: "A"; + /** @gqlField */ + myField: string; +}; + +/** + * @gqlType + */ +type B = { + __typename: "B"; + /** @gqlField */ + myField: string; +}; +``` + +## Output + +### SDL + +```graphql +"""This is my custom directive.""" +directive @max(foo: Int!) on UNION + +union MyUnion @max(foo: 10) = A | B + +type A { + myField: String +} + +type B { + myField: String +} +``` + +### TypeScript + +```ts +import { GraphQLSchema, GraphQLDirective, DirectiveLocation, GraphQLNonNull, GraphQLInt, specifiedDirectives, GraphQLUnionType, GraphQLObjectType, GraphQLString } from "graphql"; +export function getSchema(): GraphQLSchema { + const AType: GraphQLObjectType = new GraphQLObjectType({ + name: "A", + fields() { + return { + myField: { + name: "myField", + type: GraphQLString + } + }; + } + }); + const BType: GraphQLObjectType = new GraphQLObjectType({ + name: "B", + fields() { + return { + myField: { + name: "myField", + type: GraphQLString + } + }; + } + }); + const MyUnionType: GraphQLUnionType = new GraphQLUnionType({ + name: "MyUnion", + types() { + return [AType, BType]; + }, + extensions: { + grats: { + directives: [{ + name: "max", + args: { + foo: 10 + } + }] + } + } + }); + return new GraphQLSchema({ + directives: [...specifiedDirectives, new GraphQLDirective({ + name: "max", + locations: [DirectiveLocation.UNION], + description: "This is my custom directive.", + args: { + foo: { + type: new GraphQLNonNull(GraphQLInt) + } + } + })], + types: [MyUnionType, AType, BType] + }); +} +``` \ No newline at end of file diff --git a/src/tests/fixtures/directives/directiveUsedWithInvalidArgs.invalid.ts.expected b/src/tests/fixtures/directives/directiveUsedWithInvalidArgs.invalid.ts.expected deleted file mode 100644 index 74356889..00000000 --- a/src/tests/fixtures/directives/directiveUsedWithInvalidArgs.invalid.ts.expected +++ /dev/null @@ -1,25 +0,0 @@ ------------------ -INPUT ------------------ -/** - * This is my custom directive. - * @gqlDirective on FIELD_DEFINITION - */ -export function customDirective(args: { foo: string }) {} - -/** - * @gqlQueryField - * @gqlAnnotate customDirective(foo: 10) - */ -export function myQueryField(): string { - return "myQueryField"; -} - ------------------ -OUTPUT ------------------ -GraphQL request:1:23 - error: String cannot represent a non string value: 10 - -1 @customDirective(foo: 10) - ~~ - diff --git a/src/tests/fixtures/directives/directiveUsedWithInvalidArgs.invalid.ts.expected.md b/src/tests/fixtures/directives/directiveUsedWithInvalidArgs.invalid.ts.expected.md new file mode 100644 index 00000000..c1ebc328 --- /dev/null +++ b/src/tests/fixtures/directives/directiveUsedWithInvalidArgs.invalid.ts.expected.md @@ -0,0 +1,28 @@ +## input + +```ts title="directives/directiveUsedWithInvalidArgs.invalid.ts" +/** + * This is my custom directive. + * @gqlDirective on FIELD_DEFINITION + */ +export function customDirective(args: { foo: string }) {} + +/** + * @gqlQueryField + * @gqlAnnotate customDirective(foo: 10) + */ +export function myQueryField(): string { + return "myQueryField"; +} +``` + +## Output + +### Error Report + +```text +GraphQL request:1:23 - error: String cannot represent a non string value: 10 + +1 @customDirective(foo: 10) + ~~ +``` \ No newline at end of file diff --git a/src/tests/fixtures/directives/directiveWithSyntaxError.invalid.ts.expected b/src/tests/fixtures/directives/directiveWithSyntaxError.invalid.ts.expected deleted file mode 100644 index 5d2e7718..00000000 --- a/src/tests/fixtures/directives/directiveWithSyntaxError.invalid.ts.expected +++ /dev/null @@ -1,23 +0,0 @@ ------------------ -INPUT ------------------ -// Because @myDirective is followed by `(` we assume it's expected to be parsed -// as a directive even though it's not defined. - -/** - * @gqlQueryField - * @gqlAnnotate myDirective(someArg: --oops) - */ -export function myQueryField(): string { - return "myQueryField"; -} - ------------------ -OUTPUT ------------------ -src/tests/fixtures/directives/directiveWithSyntaxError.invalid.ts:6:4 - error: Syntax Error: Invalid number, expected digit but got: "-". - -6 * @gqlAnnotate myDirective(someArg: --oops) - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -7 */ - ~ diff --git a/src/tests/fixtures/directives/directiveWithSyntaxError.invalid.ts.expected.md b/src/tests/fixtures/directives/directiveWithSyntaxError.invalid.ts.expected.md new file mode 100644 index 00000000..fc1931dd --- /dev/null +++ b/src/tests/fixtures/directives/directiveWithSyntaxError.invalid.ts.expected.md @@ -0,0 +1,27 @@ +## input + +```ts title="directives/directiveWithSyntaxError.invalid.ts" +// Because @myDirective is followed by `(` we assume it's expected to be parsed +// as a directive even though it's not defined. + +/** + * @gqlQueryField + * @gqlAnnotate myDirective(someArg: --oops) + */ +export function myQueryField(): string { + return "myQueryField"; +} +``` + +## Output + +### Error Report + +```text +src/tests/fixtures/directives/directiveWithSyntaxError.invalid.ts:6:4 - error: Syntax Error: Invalid number, expected digit but got: "-". + +6 * @gqlAnnotate myDirective(someArg: --oops) + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +7 */ + ~ +``` \ No newline at end of file diff --git a/src/tests/fixtures/directives/gqlAnnotateOnNonGqlDocblock.ts.expected b/src/tests/fixtures/directives/gqlAnnotateOnNonGqlDocblock.ts.expected deleted file mode 100644 index ca9a4325..00000000 --- a/src/tests/fixtures/directives/gqlAnnotateOnNonGqlDocblock.ts.expected +++ /dev/null @@ -1,23 +0,0 @@ ------------------ -INPUT ------------------ -// Because @gqlAnnotate can go on argument definitions which don't have any -// `@gql` tag, we can't report this as an error for now. - -/** - * @gqlAnnotate max(foo: ["a", "b"]) - */ -export function foo() {} - ------------------ -OUTPUT ------------------ --- SDL -- - --- TypeScript -- -import { GraphQLSchema } from "graphql"; -export function getSchema(): GraphQLSchema { - return new GraphQLSchema({ - types: [] - }); -} diff --git a/src/tests/fixtures/directives/gqlAnnotateOnNonGqlDocblock.ts.expected.md b/src/tests/fixtures/directives/gqlAnnotateOnNonGqlDocblock.ts.expected.md new file mode 100644 index 00000000..9e1d6359 --- /dev/null +++ b/src/tests/fixtures/directives/gqlAnnotateOnNonGqlDocblock.ts.expected.md @@ -0,0 +1,30 @@ +## input + +```ts title="directives/gqlAnnotateOnNonGqlDocblock.ts" +// Because @gqlAnnotate can go on argument definitions which don't have any +// `@gql` tag, we can't report this as an error for now. + +/** + * @gqlAnnotate max(foo: ["a", "b"]) + */ +export function foo() {} +``` + +## Output + +### SDL + +```graphql + +``` + +### TypeScript + +```ts +import { GraphQLSchema } from "graphql"; +export function getSchema(): GraphQLSchema { + return new GraphQLSchema({ + types: [] + }); +} +``` \ No newline at end of file diff --git a/src/tests/fixtures/directives/undefinedDirectiveWithArgs.invalid.ts.expected b/src/tests/fixtures/directives/undefinedDirectiveWithArgs.invalid.ts.expected deleted file mode 100644 index de4c82b4..00000000 --- a/src/tests/fixtures/directives/undefinedDirectiveWithArgs.invalid.ts.expected +++ /dev/null @@ -1,20 +0,0 @@ ------------------ -INPUT ------------------ -/** - * @gqlQueryField - * @gqlAnnotate myDirective(someArg: "someValue") - */ -export function myQueryField(): string { - return "myQueryField"; -} - ------------------ -OUTPUT ------------------ -src/tests/fixtures/directives/undefinedDirectiveWithArgs.invalid.ts:3:4 - error: Unknown directive "@myDirective". - -3 * @gqlAnnotate myDirective(someArg: "someValue") - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -4 */ - ~ diff --git a/src/tests/fixtures/directives/undefinedDirectiveWithArgs.invalid.ts.expected.md b/src/tests/fixtures/directives/undefinedDirectiveWithArgs.invalid.ts.expected.md new file mode 100644 index 00000000..941177dc --- /dev/null +++ b/src/tests/fixtures/directives/undefinedDirectiveWithArgs.invalid.ts.expected.md @@ -0,0 +1,24 @@ +## input + +```ts title="directives/undefinedDirectiveWithArgs.invalid.ts" +/** + * @gqlQueryField + * @gqlAnnotate myDirective(someArg: "someValue") + */ +export function myQueryField(): string { + return "myQueryField"; +} +``` + +## Output + +### Error Report + +```text +src/tests/fixtures/directives/undefinedDirectiveWithArgs.invalid.ts:3:4 - error: Unknown directive "@myDirective". + +3 * @gqlAnnotate myDirective(someArg: "someValue") + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +4 */ + ~ +``` \ No newline at end of file diff --git a/src/tests/fixtures/directives/undefinedDirectiveWithoutArgs.ts.expected b/src/tests/fixtures/directives/undefinedDirectiveWithoutArgs.ts.expected deleted file mode 100644 index aa18461c..00000000 --- a/src/tests/fixtures/directives/undefinedDirectiveWithoutArgs.ts.expected +++ /dev/null @@ -1,41 +0,0 @@ ------------------ -INPUT ------------------ -/** - * @gqlQueryField - * @myDirective This will be ignored and assumed to be a TypeScript tag - */ -export function myQueryField(): string { - return "myQueryField"; -} - ------------------ -OUTPUT ------------------ --- SDL -- -type Query { - myQueryField: String -} --- TypeScript -- -import { GraphQLSchema, GraphQLObjectType, GraphQLString } from "graphql"; -import { myQueryField as queryMyQueryFieldResolver } from "./undefinedDirectiveWithoutArgs"; -export function getSchema(): GraphQLSchema { - const QueryType: GraphQLObjectType = new GraphQLObjectType({ - name: "Query", - fields() { - return { - myQueryField: { - name: "myQueryField", - type: GraphQLString, - resolve() { - return queryMyQueryFieldResolver(); - } - } - }; - } - }); - return new GraphQLSchema({ - query: QueryType, - types: [QueryType] - }); -} diff --git a/src/tests/fixtures/directives/undefinedDirectiveWithoutArgs.ts.expected.md b/src/tests/fixtures/directives/undefinedDirectiveWithoutArgs.ts.expected.md new file mode 100644 index 00000000..690e8110 --- /dev/null +++ b/src/tests/fixtures/directives/undefinedDirectiveWithoutArgs.ts.expected.md @@ -0,0 +1,48 @@ +## input + +```ts title="directives/undefinedDirectiveWithoutArgs.ts" +/** + * @gqlQueryField + * @myDirective This will be ignored and assumed to be a TypeScript tag + */ +export function myQueryField(): string { + return "myQueryField"; +} +``` + +## Output + +### SDL + +```graphql +type Query { + myQueryField: String +} +``` + +### TypeScript + +```ts +import { GraphQLSchema, GraphQLObjectType, GraphQLString } from "graphql"; +import { myQueryField as queryMyQueryFieldResolver } from "./undefinedDirectiveWithoutArgs"; +export function getSchema(): GraphQLSchema { + const QueryType: GraphQLObjectType = new GraphQLObjectType({ + name: "Query", + fields() { + return { + myQueryField: { + name: "myQueryField", + type: GraphQLString, + resolve() { + return queryMyQueryFieldResolver(); + } + } + }; + } + }); + return new GraphQLSchema({ + query: QueryType, + types: [QueryType] + }); +} +``` \ No newline at end of file diff --git a/src/tests/fixtures/enums/DeprecatedEnumVariant.ts.expected b/src/tests/fixtures/enums/DeprecatedEnumVariant.ts.expected deleted file mode 100644 index 785bdcd5..00000000 --- a/src/tests/fixtures/enums/DeprecatedEnumVariant.ts.expected +++ /dev/null @@ -1,66 +0,0 @@ ------------------ -INPUT ------------------ -/** @gqlType */ -class SomeType { - /** @gqlField */ - hello: string; -} - -/** @gqlEnum */ -enum Enum { - /** - * Valid enum value. - * @deprecated Use something else. - */ - VALID = "VALID", - /** Invalid enum value. */ - INVALID = "INVALID", -} - ------------------ -OUTPUT ------------------ --- SDL -- -enum Enum { - """Invalid enum value.""" - INVALID - """Valid enum value.""" - VALID @deprecated(reason: "Use something else.") -} - -type SomeType { - hello: String -} --- TypeScript -- -import { GraphQLSchema, GraphQLEnumType, GraphQLObjectType, GraphQLString } from "graphql"; -export function getSchema(): GraphQLSchema { - const EnumType: GraphQLEnumType = new GraphQLEnumType({ - name: "Enum", - values: { - INVALID: { - description: "Invalid enum value.", - value: "INVALID" - }, - VALID: { - description: "Valid enum value.", - deprecationReason: "Use something else.", - value: "VALID" - } - } - }); - const SomeTypeType: GraphQLObjectType = new GraphQLObjectType({ - name: "SomeType", - fields() { - return { - hello: { - name: "hello", - type: GraphQLString - } - }; - } - }); - return new GraphQLSchema({ - types: [EnumType, SomeTypeType] - }); -} diff --git a/src/tests/fixtures/enums/DeprecatedEnumVariant.ts.expected.md b/src/tests/fixtures/enums/DeprecatedEnumVariant.ts.expected.md new file mode 100644 index 00000000..831763b7 --- /dev/null +++ b/src/tests/fixtures/enums/DeprecatedEnumVariant.ts.expected.md @@ -0,0 +1,73 @@ +## input + +```ts title="enums/DeprecatedEnumVariant.ts" +/** @gqlType */ +class SomeType { + /** @gqlField */ + hello: string; +} + +/** @gqlEnum */ +enum Enum { + /** + * Valid enum value. + * @deprecated Use something else. + */ + VALID = "VALID", + /** Invalid enum value. */ + INVALID = "INVALID", +} +``` + +## Output + +### SDL + +```graphql +enum Enum { + """Invalid enum value.""" + INVALID + """Valid enum value.""" + VALID @deprecated(reason: "Use something else.") +} + +type SomeType { + hello: String +} +``` + +### TypeScript + +```ts +import { GraphQLSchema, GraphQLEnumType, GraphQLObjectType, GraphQLString } from "graphql"; +export function getSchema(): GraphQLSchema { + const EnumType: GraphQLEnumType = new GraphQLEnumType({ + name: "Enum", + values: { + INVALID: { + description: "Invalid enum value.", + value: "INVALID" + }, + VALID: { + description: "Valid enum value.", + deprecationReason: "Use something else.", + value: "VALID" + } + } + }); + const SomeTypeType: GraphQLObjectType = new GraphQLObjectType({ + name: "SomeType", + fields() { + return { + hello: { + name: "hello", + type: GraphQLString + } + }; + } + }); + return new GraphQLSchema({ + types: [EnumType, SomeTypeType] + }); +} +``` \ No newline at end of file diff --git a/src/tests/fixtures/enums/Enum.ts.expected b/src/tests/fixtures/enums/Enum.ts.expected deleted file mode 100644 index c3d38093..00000000 --- a/src/tests/fixtures/enums/Enum.ts.expected +++ /dev/null @@ -1,56 +0,0 @@ ------------------ -INPUT ------------------ -/** @gqlType */ -class SomeType { - /** @gqlField */ - hello: string; -} - -/** @gqlEnum */ -enum Enum { - VALID = "VALID", - INVALID = "INVALID", -} - ------------------ -OUTPUT ------------------ --- SDL -- -enum Enum { - INVALID - VALID -} - -type SomeType { - hello: String -} --- TypeScript -- -import { GraphQLSchema, GraphQLEnumType, GraphQLObjectType, GraphQLString } from "graphql"; -export function getSchema(): GraphQLSchema { - const EnumType: GraphQLEnumType = new GraphQLEnumType({ - name: "Enum", - values: { - INVALID: { - value: "INVALID" - }, - VALID: { - value: "VALID" - } - } - }); - const SomeTypeType: GraphQLObjectType = new GraphQLObjectType({ - name: "SomeType", - fields() { - return { - hello: { - name: "hello", - type: GraphQLString - } - }; - } - }); - return new GraphQLSchema({ - types: [EnumType, SomeTypeType] - }); -} diff --git a/src/tests/fixtures/enums/Enum.ts.expected.md b/src/tests/fixtures/enums/Enum.ts.expected.md new file mode 100644 index 00000000..6dbac6ee --- /dev/null +++ b/src/tests/fixtures/enums/Enum.ts.expected.md @@ -0,0 +1,63 @@ +## input + +```ts title="enums/Enum.ts" +/** @gqlType */ +class SomeType { + /** @gqlField */ + hello: string; +} + +/** @gqlEnum */ +enum Enum { + VALID = "VALID", + INVALID = "INVALID", +} +``` + +## Output + +### SDL + +```graphql +enum Enum { + INVALID + VALID +} + +type SomeType { + hello: String +} +``` + +### TypeScript + +```ts +import { GraphQLSchema, GraphQLEnumType, GraphQLObjectType, GraphQLString } from "graphql"; +export function getSchema(): GraphQLSchema { + const EnumType: GraphQLEnumType = new GraphQLEnumType({ + name: "Enum", + values: { + INVALID: { + value: "INVALID" + }, + VALID: { + value: "VALID" + } + } + }); + const SomeTypeType: GraphQLObjectType = new GraphQLObjectType({ + name: "SomeType", + fields() { + return { + hello: { + name: "hello", + type: GraphQLString + } + }; + } + }); + return new GraphQLSchema({ + types: [EnumType, SomeTypeType] + }); +} +``` \ No newline at end of file diff --git a/src/tests/fixtures/enums/EnumFromUnionType.ts.expected b/src/tests/fixtures/enums/EnumFromUnionType.ts.expected deleted file mode 100644 index 7542ed7d..00000000 --- a/src/tests/fixtures/enums/EnumFromUnionType.ts.expected +++ /dev/null @@ -1,53 +0,0 @@ ------------------ -INPUT ------------------ -/** @gqlType */ -class SomeType { - /** @gqlField */ - hello: MyEnum; -} - -/** @gqlEnum */ -type MyEnum = "VALID" | "INVALID"; - ------------------ -OUTPUT ------------------ --- SDL -- -enum MyEnum { - INVALID - VALID -} - -type SomeType { - hello: MyEnum -} --- TypeScript -- -import { GraphQLSchema, GraphQLEnumType, GraphQLObjectType } from "graphql"; -export function getSchema(): GraphQLSchema { - const MyEnumType: GraphQLEnumType = new GraphQLEnumType({ - name: "MyEnum", - values: { - INVALID: { - value: "INVALID" - }, - VALID: { - value: "VALID" - } - } - }); - const SomeTypeType: GraphQLObjectType = new GraphQLObjectType({ - name: "SomeType", - fields() { - return { - hello: { - name: "hello", - type: MyEnumType - } - }; - } - }); - return new GraphQLSchema({ - types: [MyEnumType, SomeTypeType] - }); -} diff --git a/src/tests/fixtures/enums/EnumFromUnionType.ts.expected.md b/src/tests/fixtures/enums/EnumFromUnionType.ts.expected.md new file mode 100644 index 00000000..7c66b4bc --- /dev/null +++ b/src/tests/fixtures/enums/EnumFromUnionType.ts.expected.md @@ -0,0 +1,60 @@ +## input + +```ts title="enums/EnumFromUnionType.ts" +/** @gqlType */ +class SomeType { + /** @gqlField */ + hello: MyEnum; +} + +/** @gqlEnum */ +type MyEnum = "VALID" | "INVALID"; +``` + +## Output + +### SDL + +```graphql +enum MyEnum { + INVALID + VALID +} + +type SomeType { + hello: MyEnum +} +``` + +### TypeScript + +```ts +import { GraphQLSchema, GraphQLEnumType, GraphQLObjectType } from "graphql"; +export function getSchema(): GraphQLSchema { + const MyEnumType: GraphQLEnumType = new GraphQLEnumType({ + name: "MyEnum", + values: { + INVALID: { + value: "INVALID" + }, + VALID: { + value: "VALID" + } + } + }); + const SomeTypeType: GraphQLObjectType = new GraphQLObjectType({ + name: "SomeType", + fields() { + return { + hello: { + name: "hello", + type: MyEnumType + } + }; + } + }); + return new GraphQLSchema({ + types: [MyEnumType, SomeTypeType] + }); +} +``` \ No newline at end of file diff --git a/src/tests/fixtures/enums/EnumFromUnionTypeNotLiteral.invalid.ts.expected b/src/tests/fixtures/enums/EnumFromUnionTypeNotLiteral.invalid.ts.expected deleted file mode 100644 index dd7564fc..00000000 --- a/src/tests/fixtures/enums/EnumFromUnionTypeNotLiteral.invalid.ts.expected +++ /dev/null @@ -1,21 +0,0 @@ ------------------ -INPUT ------------------ -/** @gqlType */ -class SomeType { - /** @gqlField */ - hello: MyEnum; -} - -/** @gqlEnum */ -type MyEnum = "VALID" | number; - ------------------ -OUTPUT ------------------ -src/tests/fixtures/enums/EnumFromUnionTypeNotLiteral.invalid.ts:8:25 - error: Expected `@gqlEnum` enum members to be string literal types. For example: `'foo'`. Grats needs to be able to see the concrete value of the enum member to generate the GraphQL schema. - -If you think Grats should be able to infer this union member, please report an issue at https://github.com/captbaritone/grats/issues. - -8 type MyEnum = "VALID" | number; - ~~~~~~ diff --git a/src/tests/fixtures/enums/EnumFromUnionTypeNotLiteral.invalid.ts.expected.md b/src/tests/fixtures/enums/EnumFromUnionTypeNotLiteral.invalid.ts.expected.md new file mode 100644 index 00000000..6b3416f3 --- /dev/null +++ b/src/tests/fixtures/enums/EnumFromUnionTypeNotLiteral.invalid.ts.expected.md @@ -0,0 +1,25 @@ +## input + +```ts title="enums/EnumFromUnionTypeNotLiteral.invalid.ts" +/** @gqlType */ +class SomeType { + /** @gqlField */ + hello: MyEnum; +} + +/** @gqlEnum */ +type MyEnum = "VALID" | number; +``` + +## Output + +### Error Report + +```text +src/tests/fixtures/enums/EnumFromUnionTypeNotLiteral.invalid.ts:8:25 - error: Expected `@gqlEnum` enum members to be string literal types. For example: `'foo'`. Grats needs to be able to see the concrete value of the enum member to generate the GraphQL schema. + +If you think Grats should be able to infer this union member, please report an issue at https://github.com/captbaritone/grats/issues. + +8 type MyEnum = "VALID" | number; + ~~~~~~ +``` \ No newline at end of file diff --git a/src/tests/fixtures/enums/EnumFromUnionTypeNotStringLiteral.invalid.ts.expected b/src/tests/fixtures/enums/EnumFromUnionTypeNotStringLiteral.invalid.ts.expected deleted file mode 100644 index ad024694..00000000 --- a/src/tests/fixtures/enums/EnumFromUnionTypeNotStringLiteral.invalid.ts.expected +++ /dev/null @@ -1,21 +0,0 @@ ------------------ -INPUT ------------------ -/** @gqlType */ -class SomeType { - /** @gqlField */ - hello: MyEnum; -} - -/** @gqlEnum */ -type MyEnum = "VALID" | 1; - ------------------ -OUTPUT ------------------ -src/tests/fixtures/enums/EnumFromUnionTypeNotStringLiteral.invalid.ts:8:25 - error: Expected `@gqlEnum` enum members to be string literal types. For example: `'foo'`. Grats needs to be able to see the concrete value of the enum member to generate the GraphQL schema. - -If you think Grats should be able to infer this union member, please report an issue at https://github.com/captbaritone/grats/issues. - -8 type MyEnum = "VALID" | 1; - ~ diff --git a/src/tests/fixtures/enums/EnumFromUnionTypeNotStringLiteral.invalid.ts.expected.md b/src/tests/fixtures/enums/EnumFromUnionTypeNotStringLiteral.invalid.ts.expected.md new file mode 100644 index 00000000..805054a0 --- /dev/null +++ b/src/tests/fixtures/enums/EnumFromUnionTypeNotStringLiteral.invalid.ts.expected.md @@ -0,0 +1,25 @@ +## input + +```ts title="enums/EnumFromUnionTypeNotStringLiteral.invalid.ts" +/** @gqlType */ +class SomeType { + /** @gqlField */ + hello: MyEnum; +} + +/** @gqlEnum */ +type MyEnum = "VALID" | 1; +``` + +## Output + +### Error Report + +```text +src/tests/fixtures/enums/EnumFromUnionTypeNotStringLiteral.invalid.ts:8:25 - error: Expected `@gqlEnum` enum members to be string literal types. For example: `'foo'`. Grats needs to be able to see the concrete value of the enum member to generate the GraphQL schema. + +If you think Grats should be able to infer this union member, please report an issue at https://github.com/captbaritone/grats/issues. + +8 type MyEnum = "VALID" | 1; + ~ +``` \ No newline at end of file diff --git a/src/tests/fixtures/enums/EnumFromUnionTypeOfStringLiteral.ts.expected b/src/tests/fixtures/enums/EnumFromUnionTypeOfStringLiteral.ts.expected deleted file mode 100644 index 1d08f1fb..00000000 --- a/src/tests/fixtures/enums/EnumFromUnionTypeOfStringLiteral.ts.expected +++ /dev/null @@ -1,49 +0,0 @@ ------------------ -INPUT ------------------ -/** @gqlType */ -class SomeType { - /** @gqlField */ - hello: MyEnum; -} - -/** @gqlEnum */ -type MyEnum = "VALID"; - ------------------ -OUTPUT ------------------ --- SDL -- -enum MyEnum { - VALID -} - -type SomeType { - hello: MyEnum -} --- TypeScript -- -import { GraphQLSchema, GraphQLEnumType, GraphQLObjectType } from "graphql"; -export function getSchema(): GraphQLSchema { - const MyEnumType: GraphQLEnumType = new GraphQLEnumType({ - name: "MyEnum", - values: { - VALID: { - value: "VALID" - } - } - }); - const SomeTypeType: GraphQLObjectType = new GraphQLObjectType({ - name: "SomeType", - fields() { - return { - hello: { - name: "hello", - type: MyEnumType - } - }; - } - }); - return new GraphQLSchema({ - types: [MyEnumType, SomeTypeType] - }); -} diff --git a/src/tests/fixtures/enums/EnumFromUnionTypeOfStringLiteral.ts.expected.md b/src/tests/fixtures/enums/EnumFromUnionTypeOfStringLiteral.ts.expected.md new file mode 100644 index 00000000..a8b36796 --- /dev/null +++ b/src/tests/fixtures/enums/EnumFromUnionTypeOfStringLiteral.ts.expected.md @@ -0,0 +1,56 @@ +## input + +```ts title="enums/EnumFromUnionTypeOfStringLiteral.ts" +/** @gqlType */ +class SomeType { + /** @gqlField */ + hello: MyEnum; +} + +/** @gqlEnum */ +type MyEnum = "VALID"; +``` + +## Output + +### SDL + +```graphql +enum MyEnum { + VALID +} + +type SomeType { + hello: MyEnum +} +``` + +### TypeScript + +```ts +import { GraphQLSchema, GraphQLEnumType, GraphQLObjectType } from "graphql"; +export function getSchema(): GraphQLSchema { + const MyEnumType: GraphQLEnumType = new GraphQLEnumType({ + name: "MyEnum", + values: { + VALID: { + value: "VALID" + } + } + }); + const SomeTypeType: GraphQLObjectType = new GraphQLObjectType({ + name: "SomeType", + fields() { + return { + hello: { + name: "hello", + type: MyEnumType + } + }; + } + }); + return new GraphQLSchema({ + types: [MyEnumType, SomeTypeType] + }); +} +``` \ No newline at end of file diff --git a/src/tests/fixtures/enums/EnumFromUnionTypeWithDescription.ts.expected b/src/tests/fixtures/enums/EnumFromUnionTypeWithDescription.ts.expected deleted file mode 100644 index 3c0a9a66..00000000 --- a/src/tests/fixtures/enums/EnumFromUnionTypeWithDescription.ts.expected +++ /dev/null @@ -1,58 +0,0 @@ ------------------ -INPUT ------------------ -/** @gqlType */ -class SomeType { - /** @gqlField */ - hello: MyEnum; -} - -/** - * Hello! - * @gqlEnum - */ -type MyEnum = "VALID" | "INVALID"; - ------------------ -OUTPUT ------------------ --- SDL -- -"""Hello!""" -enum MyEnum { - INVALID - VALID -} - -type SomeType { - hello: MyEnum -} --- TypeScript -- -import { GraphQLSchema, GraphQLEnumType, GraphQLObjectType } from "graphql"; -export function getSchema(): GraphQLSchema { - const MyEnumType: GraphQLEnumType = new GraphQLEnumType({ - description: "Hello!", - name: "MyEnum", - values: { - INVALID: { - value: "INVALID" - }, - VALID: { - value: "VALID" - } - } - }); - const SomeTypeType: GraphQLObjectType = new GraphQLObjectType({ - name: "SomeType", - fields() { - return { - hello: { - name: "hello", - type: MyEnumType - } - }; - } - }); - return new GraphQLSchema({ - types: [MyEnumType, SomeTypeType] - }); -} diff --git a/src/tests/fixtures/enums/EnumFromUnionTypeWithDescription.ts.expected.md b/src/tests/fixtures/enums/EnumFromUnionTypeWithDescription.ts.expected.md new file mode 100644 index 00000000..2e0797e8 --- /dev/null +++ b/src/tests/fixtures/enums/EnumFromUnionTypeWithDescription.ts.expected.md @@ -0,0 +1,65 @@ +## input + +```ts title="enums/EnumFromUnionTypeWithDescription.ts" +/** @gqlType */ +class SomeType { + /** @gqlField */ + hello: MyEnum; +} + +/** + * Hello! + * @gqlEnum + */ +type MyEnum = "VALID" | "INVALID"; +``` + +## Output + +### SDL + +```graphql +"""Hello!""" +enum MyEnum { + INVALID + VALID +} + +type SomeType { + hello: MyEnum +} +``` + +### TypeScript + +```ts +import { GraphQLSchema, GraphQLEnumType, GraphQLObjectType } from "graphql"; +export function getSchema(): GraphQLSchema { + const MyEnumType: GraphQLEnumType = new GraphQLEnumType({ + description: "Hello!", + name: "MyEnum", + values: { + INVALID: { + value: "INVALID" + }, + VALID: { + value: "VALID" + } + } + }); + const SomeTypeType: GraphQLObjectType = new GraphQLObjectType({ + name: "SomeType", + fields() { + return { + hello: { + name: "hello", + type: MyEnumType + } + }; + } + }); + return new GraphQLSchema({ + types: [MyEnumType, SomeTypeType] + }); +} +``` \ No newline at end of file diff --git a/src/tests/fixtures/enums/EnumNotExportedWithEmitEnumsConfig.invalid.ts.expected b/src/tests/fixtures/enums/EnumNotExportedWithEmitEnumsConfig.invalid.ts.expected deleted file mode 100644 index aceac09b..00000000 --- a/src/tests/fixtures/enums/EnumNotExportedWithEmitEnumsConfig.invalid.ts.expected +++ /dev/null @@ -1,67 +0,0 @@ ------------------ -INPUT ------------------ -// {"tsClientEnums": "enums.ts"} - -/** @gqlEnum */ -enum Color { - RED = "red", - GREEN = "green", - BLUE = "blue", -} - -/** @gqlType */ -type Query = unknown; - -/** @gqlField */ -export function favoriteColor(_: Query): Color { - return Color.RED; -} - ------------------ -OUTPUT ------------------ --- Error Report -- -src/tests/fixtures/enums/EnumNotExportedWithEmitEnumsConfig.invalid.ts:4:1 - error: Expected enum to be exported when `tsClientEnums` is configured. Grats needs to import enum types to build the enums module. - - 4 enum Color { - ~~~~~~~~~~~~ - 5 RED = "red", - ~~~~~~~~~~~~~~ -... - 7 BLUE = "blue", - ~~~~~~~~~~~~~~~~ - 8 } - ~ - - --- Code Action: "Add export keyword to enum with @gqlEnum" (add-export-keyword-to-enum) -- -- Original -+ Fixed - -@@ -3,3 +3,3 @@ - /** @gqlEnum */ -- enum Color { -+ export enum Color { - RED = "red", - --- Applied Fixes -- - * Applied fix "Add export keyword to enum with @gqlEnum" in grats/src/tests/fixtures/enums/EnumNotExportedWithEmitEnumsConfig.invalid.ts - --- Fixed Text -- -// {"tsClientEnums": "enums.ts"} - -/** @gqlEnum */ -export enum Color { - RED = "red", - GREEN = "green", - BLUE = "blue", -} - -/** @gqlType */ -type Query = unknown; - -/** @gqlField */ -export function favoriteColor(_: Query): Color { - return Color.RED; -} diff --git a/src/tests/fixtures/enums/EnumNotExportedWithEmitEnumsConfig.invalid.ts.expected.md b/src/tests/fixtures/enums/EnumNotExportedWithEmitEnumsConfig.invalid.ts.expected.md new file mode 100644 index 00000000..28fdad96 --- /dev/null +++ b/src/tests/fixtures/enums/EnumNotExportedWithEmitEnumsConfig.invalid.ts.expected.md @@ -0,0 +1,78 @@ +## input + +```ts title="enums/EnumNotExportedWithEmitEnumsConfig.invalid.ts" +// {"tsClientEnums": "enums.ts"} + +/** @gqlEnum */ +enum Color { + RED = "red", + GREEN = "green", + BLUE = "blue", +} + +/** @gqlType */ +type Query = unknown; + +/** @gqlField */ +export function favoriteColor(_: Query): Color { + return Color.RED; +} +``` + +## Output + +### Error Report + +```text +src/tests/fixtures/enums/EnumNotExportedWithEmitEnumsConfig.invalid.ts:4:1 - error: Expected enum to be exported when `tsClientEnums` is configured. Grats needs to import enum types to build the enums module. + + 4 enum Color { + ~~~~~~~~~~~~ + 5 RED = "red", + ~~~~~~~~~~~~~~ +... + 7 BLUE = "blue", + ~~~~~~~~~~~~~~~~ + 8 } + ~ +``` + +#### Code Action: "Add export keyword to enum with @gqlEnum" (add-export-keyword-to-enum) + +```diff +- Original ++ Fixed + +@@ -3,3 +3,3 @@ + /** @gqlEnum */ +- enum Color { ++ export enum Color { + RED = "red", +``` + +#### Applied Fixes + +```text + * Applied fix "Add export keyword to enum with @gqlEnum" in grats/src/tests/fixtures/enums/EnumNotExportedWithEmitEnumsConfig.invalid.ts +``` + +#### Fixed Text + +```typescript +// {"tsClientEnums": "enums.ts"} + +/** @gqlEnum */ +export enum Color { + RED = "red", + GREEN = "green", + BLUE = "blue", +} + +/** @gqlType */ +type Query = unknown; + +/** @gqlField */ +export function favoriteColor(_: Query): Color { + return Color.RED; +} +``` \ No newline at end of file diff --git a/src/tests/fixtures/enums/EnumNotValidIdentifier.invalid.ts.expected b/src/tests/fixtures/enums/EnumNotValidIdentifier.invalid.ts.expected deleted file mode 100644 index 759f7f55..00000000 --- a/src/tests/fixtures/enums/EnumNotValidIdentifier.invalid.ts.expected +++ /dev/null @@ -1,22 +0,0 @@ ------------------ -INPUT ------------------ -/** @gqlType */ -class SomeType { - /** @gqlField */ - hello: string; -} - -/** @gqlEnum */ -export enum Enum { - VALID = "VALID", - INVALID = "NOT AT ALL VALID", -} - ------------------ -OUTPUT ------------------ -src/tests/fixtures/enums/EnumNotValidIdentifier.invalid.ts:10:13 - error: Names must only contain [_a-zA-Z0-9] but "NOT AT ALL VALID" does not. - -10 INVALID = "NOT AT ALL VALID", - ~~~~~~~~~~~~~~~~~~ diff --git a/src/tests/fixtures/enums/EnumNotValidIdentifier.invalid.ts.expected.md b/src/tests/fixtures/enums/EnumNotValidIdentifier.invalid.ts.expected.md new file mode 100644 index 00000000..3763c521 --- /dev/null +++ b/src/tests/fixtures/enums/EnumNotValidIdentifier.invalid.ts.expected.md @@ -0,0 +1,26 @@ +## input + +```ts title="enums/EnumNotValidIdentifier.invalid.ts" +/** @gqlType */ +class SomeType { + /** @gqlField */ + hello: string; +} + +/** @gqlEnum */ +export enum Enum { + VALID = "VALID", + INVALID = "NOT AT ALL VALID", +} +``` + +## Output + +### Error Report + +```text +src/tests/fixtures/enums/EnumNotValidIdentifier.invalid.ts:10:13 - error: Names must only contain [_a-zA-Z0-9] but "NOT AT ALL VALID" does not. + +10 INVALID = "NOT AT ALL VALID", + ~~~~~~~~~~~~~~~~~~ +``` \ No newline at end of file diff --git a/src/tests/fixtures/enums/EnumValuesDifferentThanNames.ts.expected b/src/tests/fixtures/enums/EnumValuesDifferentThanNames.ts.expected deleted file mode 100644 index 84adb34b..00000000 --- a/src/tests/fixtures/enums/EnumValuesDifferentThanNames.ts.expected +++ /dev/null @@ -1,56 +0,0 @@ ------------------ -INPUT ------------------ -/** @gqlType */ -class SomeType { - /** @gqlField */ - hello: string; -} - -/** @gqlEnum */ -enum Enum { - ABC = "VALID", - DEF = "INVALID", -} - ------------------ -OUTPUT ------------------ --- SDL -- -enum Enum { - INVALID - VALID -} - -type SomeType { - hello: String -} --- TypeScript -- -import { GraphQLSchema, GraphQLEnumType, GraphQLObjectType, GraphQLString } from "graphql"; -export function getSchema(): GraphQLSchema { - const EnumType: GraphQLEnumType = new GraphQLEnumType({ - name: "Enum", - values: { - INVALID: { - value: "INVALID" - }, - VALID: { - value: "VALID" - } - } - }); - const SomeTypeType: GraphQLObjectType = new GraphQLObjectType({ - name: "SomeType", - fields() { - return { - hello: { - name: "hello", - type: GraphQLString - } - }; - } - }); - return new GraphQLSchema({ - types: [EnumType, SomeTypeType] - }); -} diff --git a/src/tests/fixtures/enums/EnumValuesDifferentThanNames.ts.expected.md b/src/tests/fixtures/enums/EnumValuesDifferentThanNames.ts.expected.md new file mode 100644 index 00000000..124a5002 --- /dev/null +++ b/src/tests/fixtures/enums/EnumValuesDifferentThanNames.ts.expected.md @@ -0,0 +1,63 @@ +## input + +```ts title="enums/EnumValuesDifferentThanNames.ts" +/** @gqlType */ +class SomeType { + /** @gqlField */ + hello: string; +} + +/** @gqlEnum */ +enum Enum { + ABC = "VALID", + DEF = "INVALID", +} +``` + +## Output + +### SDL + +```graphql +enum Enum { + INVALID + VALID +} + +type SomeType { + hello: String +} +``` + +### TypeScript + +```ts +import { GraphQLSchema, GraphQLEnumType, GraphQLObjectType, GraphQLString } from "graphql"; +export function getSchema(): GraphQLSchema { + const EnumType: GraphQLEnumType = new GraphQLEnumType({ + name: "Enum", + values: { + INVALID: { + value: "INVALID" + }, + VALID: { + value: "VALID" + } + } + }); + const SomeTypeType: GraphQLObjectType = new GraphQLObjectType({ + name: "SomeType", + fields() { + return { + hello: { + name: "hello", + type: GraphQLString + } + }; + } + }); + return new GraphQLSchema({ + types: [EnumType, SomeTypeType] + }); +} +``` \ No newline at end of file diff --git a/src/tests/fixtures/enums/EnumWithDescription.ts.expected b/src/tests/fixtures/enums/EnumWithDescription.ts.expected deleted file mode 100644 index 9df6f389..00000000 --- a/src/tests/fixtures/enums/EnumWithDescription.ts.expected +++ /dev/null @@ -1,62 +0,0 @@ ------------------ -INPUT ------------------ -/** @gqlType */ -class SomeType { - /** @gqlField */ - hello: string; -} - -/** - * World's best enum. - * - * @gqlEnum - */ -enum Enum { - VALID = "VALID", - INVALID = "INVALID", -} - ------------------ -OUTPUT ------------------ --- SDL -- -"""World's best enum.""" -enum Enum { - INVALID - VALID -} - -type SomeType { - hello: String -} --- TypeScript -- -import { GraphQLSchema, GraphQLEnumType, GraphQLObjectType, GraphQLString } from "graphql"; -export function getSchema(): GraphQLSchema { - const EnumType: GraphQLEnumType = new GraphQLEnumType({ - description: "World's best enum.", - name: "Enum", - values: { - INVALID: { - value: "INVALID" - }, - VALID: { - value: "VALID" - } - } - }); - const SomeTypeType: GraphQLObjectType = new GraphQLObjectType({ - name: "SomeType", - fields() { - return { - hello: { - name: "hello", - type: GraphQLString - } - }; - } - }); - return new GraphQLSchema({ - types: [EnumType, SomeTypeType] - }); -} diff --git a/src/tests/fixtures/enums/EnumWithDescription.ts.expected.md b/src/tests/fixtures/enums/EnumWithDescription.ts.expected.md new file mode 100644 index 00000000..f6c48db7 --- /dev/null +++ b/src/tests/fixtures/enums/EnumWithDescription.ts.expected.md @@ -0,0 +1,69 @@ +## input + +```ts title="enums/EnumWithDescription.ts" +/** @gqlType */ +class SomeType { + /** @gqlField */ + hello: string; +} + +/** + * World's best enum. + * + * @gqlEnum + */ +enum Enum { + VALID = "VALID", + INVALID = "INVALID", +} +``` + +## Output + +### SDL + +```graphql +"""World's best enum.""" +enum Enum { + INVALID + VALID +} + +type SomeType { + hello: String +} +``` + +### TypeScript + +```ts +import { GraphQLSchema, GraphQLEnumType, GraphQLObjectType, GraphQLString } from "graphql"; +export function getSchema(): GraphQLSchema { + const EnumType: GraphQLEnumType = new GraphQLEnumType({ + description: "World's best enum.", + name: "Enum", + values: { + INVALID: { + value: "INVALID" + }, + VALID: { + value: "VALID" + } + } + }); + const SomeTypeType: GraphQLObjectType = new GraphQLObjectType({ + name: "SomeType", + fields() { + return { + hello: { + name: "hello", + type: GraphQLString + } + }; + } + }); + return new GraphQLSchema({ + types: [EnumType, SomeTypeType] + }); +} +``` \ No newline at end of file diff --git a/src/tests/fixtures/enums/EnumWithVariantWithDescription.ts.expected b/src/tests/fixtures/enums/EnumWithVariantWithDescription.ts.expected deleted file mode 100644 index 644eee6d..00000000 --- a/src/tests/fixtures/enums/EnumWithVariantWithDescription.ts.expected +++ /dev/null @@ -1,62 +0,0 @@ ------------------ -INPUT ------------------ -/** @gqlType */ -class SomeType { - /** @gqlField */ - hello: string; -} - -/** @gqlEnum */ -enum Enum { - /** Valid enum value. */ - VALID = "VALID", - /** Invalid enum value. */ - INVALID = "INVALID", -} - ------------------ -OUTPUT ------------------ --- SDL -- -enum Enum { - """Invalid enum value.""" - INVALID - """Valid enum value.""" - VALID -} - -type SomeType { - hello: String -} --- TypeScript -- -import { GraphQLSchema, GraphQLEnumType, GraphQLObjectType, GraphQLString } from "graphql"; -export function getSchema(): GraphQLSchema { - const EnumType: GraphQLEnumType = new GraphQLEnumType({ - name: "Enum", - values: { - INVALID: { - description: "Invalid enum value.", - value: "INVALID" - }, - VALID: { - description: "Valid enum value.", - value: "VALID" - } - } - }); - const SomeTypeType: GraphQLObjectType = new GraphQLObjectType({ - name: "SomeType", - fields() { - return { - hello: { - name: "hello", - type: GraphQLString - } - }; - } - }); - return new GraphQLSchema({ - types: [EnumType, SomeTypeType] - }); -} diff --git a/src/tests/fixtures/enums/EnumWithVariantWithDescription.ts.expected.md b/src/tests/fixtures/enums/EnumWithVariantWithDescription.ts.expected.md new file mode 100644 index 00000000..03577c0a --- /dev/null +++ b/src/tests/fixtures/enums/EnumWithVariantWithDescription.ts.expected.md @@ -0,0 +1,69 @@ +## input + +```ts title="enums/EnumWithVariantWithDescription.ts" +/** @gqlType */ +class SomeType { + /** @gqlField */ + hello: string; +} + +/** @gqlEnum */ +enum Enum { + /** Valid enum value. */ + VALID = "VALID", + /** Invalid enum value. */ + INVALID = "INVALID", +} +``` + +## Output + +### SDL + +```graphql +enum Enum { + """Invalid enum value.""" + INVALID + """Valid enum value.""" + VALID +} + +type SomeType { + hello: String +} +``` + +### TypeScript + +```ts +import { GraphQLSchema, GraphQLEnumType, GraphQLObjectType, GraphQLString } from "graphql"; +export function getSchema(): GraphQLSchema { + const EnumType: GraphQLEnumType = new GraphQLEnumType({ + name: "Enum", + values: { + INVALID: { + description: "Invalid enum value.", + value: "INVALID" + }, + VALID: { + description: "Valid enum value.", + value: "VALID" + } + } + }); + const SomeTypeType: GraphQLObjectType = new GraphQLObjectType({ + name: "SomeType", + fields() { + return { + hello: { + name: "hello", + type: GraphQLString + } + }; + } + }); + return new GraphQLSchema({ + types: [EnumType, SomeTypeType] + }); +} +``` \ No newline at end of file diff --git a/src/tests/fixtures/enums/ExplicitlyNumericEnum.invalid.ts.expected b/src/tests/fixtures/enums/ExplicitlyNumericEnum.invalid.ts.expected deleted file mode 100644 index 2baf9083..00000000 --- a/src/tests/fixtures/enums/ExplicitlyNumericEnum.invalid.ts.expected +++ /dev/null @@ -1,24 +0,0 @@ ------------------ -INPUT ------------------ -/** @gqlEnum */ -enum Enum { - VALID = 1, - INVALID = 2, -} - ------------------ -OUTPUT ------------------ -src/tests/fixtures/enums/ExplicitlyNumericEnum.invalid.ts:3:3 - error: Expected `@gqlEnum` enum members to have string literal initializers. For example: `FOO = 'foo'`. In GraphQL enum values are strings, and Grats needs to be able to see the concrete value of the enum member to generate the GraphQL schema. - -If you think Grats should be able to infer this enum value, please report an issue at https://github.com/captbaritone/grats/issues. - -3 VALID = 1, - ~~~~~~~~~ -src/tests/fixtures/enums/ExplicitlyNumericEnum.invalid.ts:4:3 - error: Expected `@gqlEnum` enum members to have string literal initializers. For example: `FOO = 'foo'`. In GraphQL enum values are strings, and Grats needs to be able to see the concrete value of the enum member to generate the GraphQL schema. - -If you think Grats should be able to infer this enum value, please report an issue at https://github.com/captbaritone/grats/issues. - -4 INVALID = 2, - ~~~~~~~~~~~ diff --git a/src/tests/fixtures/enums/ExplicitlyNumericEnum.invalid.ts.expected.md b/src/tests/fixtures/enums/ExplicitlyNumericEnum.invalid.ts.expected.md new file mode 100644 index 00000000..89c1a36d --- /dev/null +++ b/src/tests/fixtures/enums/ExplicitlyNumericEnum.invalid.ts.expected.md @@ -0,0 +1,28 @@ +## input + +```ts title="enums/ExplicitlyNumericEnum.invalid.ts" +/** @gqlEnum */ +enum Enum { + VALID = 1, + INVALID = 2, +} +``` + +## Output + +### Error Report + +```text +src/tests/fixtures/enums/ExplicitlyNumericEnum.invalid.ts:3:3 - error: Expected `@gqlEnum` enum members to have string literal initializers. For example: `FOO = 'foo'`. In GraphQL enum values are strings, and Grats needs to be able to see the concrete value of the enum member to generate the GraphQL schema. + +If you think Grats should be able to infer this enum value, please report an issue at https://github.com/captbaritone/grats/issues. + +3 VALID = 1, + ~~~~~~~~~ +src/tests/fixtures/enums/ExplicitlyNumericEnum.invalid.ts:4:3 - error: Expected `@gqlEnum` enum members to have string literal initializers. For example: `FOO = 'foo'`. In GraphQL enum values are strings, and Grats needs to be able to see the concrete value of the enum member to generate the GraphQL schema. + +If you think Grats should be able to infer this enum value, please report an issue at https://github.com/captbaritone/grats/issues. + +4 INVALID = 2, + ~~~~~~~~~~~ +``` \ No newline at end of file diff --git a/src/tests/fixtures/enums/ExportedEnumsWithEmitEnumsConfig.invalid.ts.expected b/src/tests/fixtures/enums/ExportedEnumsWithEmitEnumsConfig.invalid.ts.expected deleted file mode 100644 index 9bd9da35..00000000 --- a/src/tests/fixtures/enums/ExportedEnumsWithEmitEnumsConfig.invalid.ts.expected +++ /dev/null @@ -1,35 +0,0 @@ ------------------ -INPUT ------------------ -// {"tsClientEnums": "enums.ts"} - -/** @gqlEnum */ -export enum Color { - RED = "red", - GREEN = "green", - BLUE = "blue", -} - -/** @gqlEnum */ -export type Status = "PENDING" | "COMPLETE" | "CANCELLED"; - -/** @gqlType */ -type Query = unknown; - -/** @gqlField */ -export function favoriteColor(_: Query): Color { - return Color.RED; -} - -/** @gqlField */ -export function status(_: Query): Status { - return "PENDING"; -} - ------------------ -OUTPUT ------------------ -src/tests/fixtures/enums/ExportedEnumsWithEmitEnumsConfig.invalid.ts:11:1 - error: Type alias enums are not supported when `tsClientEnums` is configured. Use `enum` declarations instead. For example: `export enum Status { PENDING = "pending" }`. - -11 export type Status = "PENDING" | "COMPLETE" | "CANCELLED"; - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/src/tests/fixtures/enums/ExportedEnumsWithEmitEnumsConfig.invalid.ts.expected.md b/src/tests/fixtures/enums/ExportedEnumsWithEmitEnumsConfig.invalid.ts.expected.md new file mode 100644 index 00000000..5f7d6496 --- /dev/null +++ b/src/tests/fixtures/enums/ExportedEnumsWithEmitEnumsConfig.invalid.ts.expected.md @@ -0,0 +1,39 @@ +## input + +```ts title="enums/ExportedEnumsWithEmitEnumsConfig.invalid.ts" +// {"tsClientEnums": "enums.ts"} + +/** @gqlEnum */ +export enum Color { + RED = "red", + GREEN = "green", + BLUE = "blue", +} + +/** @gqlEnum */ +export type Status = "PENDING" | "COMPLETE" | "CANCELLED"; + +/** @gqlType */ +type Query = unknown; + +/** @gqlField */ +export function favoriteColor(_: Query): Color { + return Color.RED; +} + +/** @gqlField */ +export function status(_: Query): Status { + return "PENDING"; +} +``` + +## Output + +### Error Report + +```text +src/tests/fixtures/enums/ExportedEnumsWithEmitEnumsConfig.invalid.ts:11:1 - error: Type alias enums are not supported when `tsClientEnums` is configured. Use `enum` declarations instead. For example: `export enum Status { PENDING = "pending" }`. + +11 export type Status = "PENDING" | "COMPLETE" | "CANCELLED"; + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` \ No newline at end of file diff --git a/src/tests/fixtures/enums/ImplicitlyNumericEnum.invalid.ts.expected b/src/tests/fixtures/enums/ImplicitlyNumericEnum.invalid.ts.expected deleted file mode 100644 index 00620450..00000000 --- a/src/tests/fixtures/enums/ImplicitlyNumericEnum.invalid.ts.expected +++ /dev/null @@ -1,24 +0,0 @@ ------------------ -INPUT ------------------ -/** @gqlEnum */ -enum Enum { - VALID, - INVALID, -} - ------------------ -OUTPUT ------------------ -src/tests/fixtures/enums/ImplicitlyNumericEnum.invalid.ts:3:3 - error: Expected `@gqlEnum` enum members to have string literal initializers. For example: `FOO = 'foo'`. In GraphQL enum values are strings, and Grats needs to be able to see the concrete value of the enum member to generate the GraphQL schema. - -If you think Grats should be able to infer this enum value, please report an issue at https://github.com/captbaritone/grats/issues. - -3 VALID, - ~~~~~ -src/tests/fixtures/enums/ImplicitlyNumericEnum.invalid.ts:4:3 - error: Expected `@gqlEnum` enum members to have string literal initializers. For example: `FOO = 'foo'`. In GraphQL enum values are strings, and Grats needs to be able to see the concrete value of the enum member to generate the GraphQL schema. - -If you think Grats should be able to infer this enum value, please report an issue at https://github.com/captbaritone/grats/issues. - -4 INVALID, - ~~~~~~~ diff --git a/src/tests/fixtures/enums/ImplicitlyNumericEnum.invalid.ts.expected.md b/src/tests/fixtures/enums/ImplicitlyNumericEnum.invalid.ts.expected.md new file mode 100644 index 00000000..6c8f6b0e --- /dev/null +++ b/src/tests/fixtures/enums/ImplicitlyNumericEnum.invalid.ts.expected.md @@ -0,0 +1,28 @@ +## input + +```ts title="enums/ImplicitlyNumericEnum.invalid.ts" +/** @gqlEnum */ +enum Enum { + VALID, + INVALID, +} +``` + +## Output + +### Error Report + +```text +src/tests/fixtures/enums/ImplicitlyNumericEnum.invalid.ts:3:3 - error: Expected `@gqlEnum` enum members to have string literal initializers. For example: `FOO = 'foo'`. In GraphQL enum values are strings, and Grats needs to be able to see the concrete value of the enum member to generate the GraphQL schema. + +If you think Grats should be able to infer this enum value, please report an issue at https://github.com/captbaritone/grats/issues. + +3 VALID, + ~~~~~ +src/tests/fixtures/enums/ImplicitlyNumericEnum.invalid.ts:4:3 - error: Expected `@gqlEnum` enum members to have string literal initializers. For example: `FOO = 'foo'`. In GraphQL enum values are strings, and Grats needs to be able to see the concrete value of the enum member to generate the GraphQL schema. + +If you think Grats should be able to infer this enum value, please report an issue at https://github.com/captbaritone/grats/issues. + +4 INVALID, + ~~~~~~~ +``` \ No newline at end of file diff --git a/src/tests/fixtures/enums/NonNullEnumDefault.ts.expected b/src/tests/fixtures/enums/NonNullEnumDefault.ts.expected deleted file mode 100644 index 95c86f6e..00000000 --- a/src/tests/fixtures/enums/NonNullEnumDefault.ts.expected +++ /dev/null @@ -1,69 +0,0 @@ ------------------ -INPUT ------------------ -// https://github.com/captbaritone/grats/issues/174 - -/** @gqlEnum */ -type GreetingOptions = "Hello" | "Greetings" | "Sup"; - -/** @gqlQueryField */ -export function hello(greeting: GreetingOptions = "Greetings"): string { - return `${greeting} World`; -} - ------------------ -OUTPUT ------------------ --- SDL -- -enum GreetingOptions { - Greetings - Hello - Sup -} - -type Query { - hello(greeting: GreetingOptions! = Greetings): String -} --- TypeScript -- -import { GraphQLSchema, GraphQLObjectType, GraphQLString, GraphQLNonNull, GraphQLEnumType } from "graphql"; -import { hello as queryHelloResolver } from "./NonNullEnumDefault"; -export function getSchema(): GraphQLSchema { - const GreetingOptionsType: GraphQLEnumType = new GraphQLEnumType({ - name: "GreetingOptions", - values: { - Greetings: { - value: "Greetings" - }, - Hello: { - value: "Hello" - }, - Sup: { - value: "Sup" - } - } - }); - const QueryType: GraphQLObjectType = new GraphQLObjectType({ - name: "Query", - fields() { - return { - hello: { - name: "hello", - type: GraphQLString, - args: { - greeting: { - type: new GraphQLNonNull(GreetingOptionsType), - defaultValue: "Greetings" - } - }, - resolve(_source, args) { - return queryHelloResolver(args.greeting); - } - } - }; - } - }); - return new GraphQLSchema({ - query: QueryType, - types: [GreetingOptionsType, QueryType] - }); -} diff --git a/src/tests/fixtures/enums/NonNullEnumDefault.ts.expected.md b/src/tests/fixtures/enums/NonNullEnumDefault.ts.expected.md new file mode 100644 index 00000000..655cd8aa --- /dev/null +++ b/src/tests/fixtures/enums/NonNullEnumDefault.ts.expected.md @@ -0,0 +1,76 @@ +## input + +```ts title="enums/NonNullEnumDefault.ts" +// https://github.com/captbaritone/grats/issues/174 + +/** @gqlEnum */ +type GreetingOptions = "Hello" | "Greetings" | "Sup"; + +/** @gqlQueryField */ +export function hello(greeting: GreetingOptions = "Greetings"): string { + return `${greeting} World`; +} +``` + +## Output + +### SDL + +```graphql +enum GreetingOptions { + Greetings + Hello + Sup +} + +type Query { + hello(greeting: GreetingOptions! = Greetings): String +} +``` + +### TypeScript + +```ts +import { GraphQLSchema, GraphQLObjectType, GraphQLString, GraphQLNonNull, GraphQLEnumType } from "graphql"; +import { hello as queryHelloResolver } from "./NonNullEnumDefault"; +export function getSchema(): GraphQLSchema { + const GreetingOptionsType: GraphQLEnumType = new GraphQLEnumType({ + name: "GreetingOptions", + values: { + Greetings: { + value: "Greetings" + }, + Hello: { + value: "Hello" + }, + Sup: { + value: "Sup" + } + } + }); + const QueryType: GraphQLObjectType = new GraphQLObjectType({ + name: "Query", + fields() { + return { + hello: { + name: "hello", + type: GraphQLString, + args: { + greeting: { + type: new GraphQLNonNull(GreetingOptionsType), + defaultValue: "Greetings" + } + }, + resolve(_source, args) { + return queryHelloResolver(args.greeting); + } + } + }; + } + }); + return new GraphQLSchema({ + query: QueryType, + types: [GreetingOptionsType, QueryType] + }); +} +``` \ No newline at end of file diff --git a/src/tests/fixtures/enums/NonNullEnumDefaultInInputObject.ts.expected b/src/tests/fixtures/enums/NonNullEnumDefaultInInputObject.ts.expected deleted file mode 100644 index 6b6fc188..00000000 --- a/src/tests/fixtures/enums/NonNullEnumDefaultInInputObject.ts.expected +++ /dev/null @@ -1,93 +0,0 @@ ------------------ -INPUT ------------------ -// https://github.com/captbaritone/grats/issues/174 - -/** @gqlEnum */ -type GreetingOptions = "Hello" | "Greetings" | "Sup"; - -/** @gqlInput */ -type GreetingInput = { - greeting: GreetingOptions; -}; - -/** @gqlQueryField */ -export function hello( - input: GreetingInput = { greeting: "Greetings" }, -): string { - return `${input.greeting} World`; -} - ------------------ -OUTPUT ------------------ --- SDL -- -enum GreetingOptions { - Greetings - Hello - Sup -} - -input GreetingInput { - greeting: GreetingOptions! -} - -type Query { - hello(input: GreetingInput! = {greeting: Greetings}): String -} --- TypeScript -- -import { GraphQLSchema, GraphQLObjectType, GraphQLString, GraphQLNonNull, GraphQLInputObjectType, GraphQLEnumType } from "graphql"; -import { hello as queryHelloResolver } from "./NonNullEnumDefaultInInputObject"; -export function getSchema(): GraphQLSchema { - const GreetingOptionsType: GraphQLEnumType = new GraphQLEnumType({ - name: "GreetingOptions", - values: { - Greetings: { - value: "Greetings" - }, - Hello: { - value: "Hello" - }, - Sup: { - value: "Sup" - } - } - }); - const GreetingInputType: GraphQLInputObjectType = new GraphQLInputObjectType({ - name: "GreetingInput", - fields() { - return { - greeting: { - name: "greeting", - type: new GraphQLNonNull(GreetingOptionsType) - } - }; - } - }); - const QueryType: GraphQLObjectType = new GraphQLObjectType({ - name: "Query", - fields() { - return { - hello: { - name: "hello", - type: GraphQLString, - args: { - input: { - type: new GraphQLNonNull(GreetingInputType), - defaultValue: { - greeting: "Greetings" - } - } - }, - resolve(_source, args) { - return queryHelloResolver(args.input); - } - } - }; - } - }); - return new GraphQLSchema({ - query: QueryType, - types: [GreetingOptionsType, GreetingInputType, QueryType] - }); -} diff --git a/src/tests/fixtures/enums/NonNullEnumDefaultInInputObject.ts.expected.md b/src/tests/fixtures/enums/NonNullEnumDefaultInInputObject.ts.expected.md new file mode 100644 index 00000000..c3a69432 --- /dev/null +++ b/src/tests/fixtures/enums/NonNullEnumDefaultInInputObject.ts.expected.md @@ -0,0 +1,100 @@ +## input + +```ts title="enums/NonNullEnumDefaultInInputObject.ts" +// https://github.com/captbaritone/grats/issues/174 + +/** @gqlEnum */ +type GreetingOptions = "Hello" | "Greetings" | "Sup"; + +/** @gqlInput */ +type GreetingInput = { + greeting: GreetingOptions; +}; + +/** @gqlQueryField */ +export function hello( + input: GreetingInput = { greeting: "Greetings" }, +): string { + return `${input.greeting} World`; +} +``` + +## Output + +### SDL + +```graphql +enum GreetingOptions { + Greetings + Hello + Sup +} + +input GreetingInput { + greeting: GreetingOptions! +} + +type Query { + hello(input: GreetingInput! = {greeting: Greetings}): String +} +``` + +### TypeScript + +```ts +import { GraphQLSchema, GraphQLObjectType, GraphQLString, GraphQLNonNull, GraphQLInputObjectType, GraphQLEnumType } from "graphql"; +import { hello as queryHelloResolver } from "./NonNullEnumDefaultInInputObject"; +export function getSchema(): GraphQLSchema { + const GreetingOptionsType: GraphQLEnumType = new GraphQLEnumType({ + name: "GreetingOptions", + values: { + Greetings: { + value: "Greetings" + }, + Hello: { + value: "Hello" + }, + Sup: { + value: "Sup" + } + } + }); + const GreetingInputType: GraphQLInputObjectType = new GraphQLInputObjectType({ + name: "GreetingInput", + fields() { + return { + greeting: { + name: "greeting", + type: new GraphQLNonNull(GreetingOptionsType) + } + }; + } + }); + const QueryType: GraphQLObjectType = new GraphQLObjectType({ + name: "Query", + fields() { + return { + hello: { + name: "hello", + type: GraphQLString, + args: { + input: { + type: new GraphQLNonNull(GreetingInputType), + defaultValue: { + greeting: "Greetings" + } + } + }, + resolve(_source, args) { + return queryHelloResolver(args.input); + } + } + }; + } + }); + return new GraphQLSchema({ + query: QueryType, + types: [GreetingOptionsType, GreetingInputType, QueryType] + }); +} +``` \ No newline at end of file diff --git a/src/tests/fixtures/enums/NonNullPluralEnumDefaults.ts.expected b/src/tests/fixtures/enums/NonNullPluralEnumDefaults.ts.expected deleted file mode 100644 index ece8985e..00000000 --- a/src/tests/fixtures/enums/NonNullPluralEnumDefaults.ts.expected +++ /dev/null @@ -1,74 +0,0 @@ ------------------ -INPUT ------------------ -// https://github.com/captbaritone/grats/issues/174 - -/** @gqlEnum */ -type GreetingOptions = "Hello" | "Greetings" | "Sup"; - -/** @gqlQueryField */ -export function hello( - greeting: GreetingOptions[] = ["Greetings", "Hello"], -): string { - return `${greeting.join(", ")} World`; -} - ------------------ -OUTPUT ------------------ --- SDL -- -enum GreetingOptions { - Greetings - Hello - Sup -} - -type Query { - hello(greeting: [GreetingOptions!]! = [Greetings, Hello]): String -} --- TypeScript -- -import { GraphQLSchema, GraphQLObjectType, GraphQLString, GraphQLNonNull, GraphQLList, GraphQLEnumType } from "graphql"; -import { hello as queryHelloResolver } from "./NonNullPluralEnumDefaults"; -export function getSchema(): GraphQLSchema { - const GreetingOptionsType: GraphQLEnumType = new GraphQLEnumType({ - name: "GreetingOptions", - values: { - Greetings: { - value: "Greetings" - }, - Hello: { - value: "Hello" - }, - Sup: { - value: "Sup" - } - } - }); - const QueryType: GraphQLObjectType = new GraphQLObjectType({ - name: "Query", - fields() { - return { - hello: { - name: "hello", - type: GraphQLString, - args: { - greeting: { - type: new GraphQLNonNull(new GraphQLList(new GraphQLNonNull(GreetingOptionsType))), - defaultValue: [ - "Greetings", - "Hello" - ] - } - }, - resolve(_source, args) { - return queryHelloResolver(args.greeting); - } - } - }; - } - }); - return new GraphQLSchema({ - query: QueryType, - types: [GreetingOptionsType, QueryType] - }); -} diff --git a/src/tests/fixtures/enums/NonNullPluralEnumDefaults.ts.expected.md b/src/tests/fixtures/enums/NonNullPluralEnumDefaults.ts.expected.md new file mode 100644 index 00000000..51dc71a4 --- /dev/null +++ b/src/tests/fixtures/enums/NonNullPluralEnumDefaults.ts.expected.md @@ -0,0 +1,81 @@ +## input + +```ts title="enums/NonNullPluralEnumDefaults.ts" +// https://github.com/captbaritone/grats/issues/174 + +/** @gqlEnum */ +type GreetingOptions = "Hello" | "Greetings" | "Sup"; + +/** @gqlQueryField */ +export function hello( + greeting: GreetingOptions[] = ["Greetings", "Hello"], +): string { + return `${greeting.join(", ")} World`; +} +``` + +## Output + +### SDL + +```graphql +enum GreetingOptions { + Greetings + Hello + Sup +} + +type Query { + hello(greeting: [GreetingOptions!]! = [Greetings, Hello]): String +} +``` + +### TypeScript + +```ts +import { GraphQLSchema, GraphQLObjectType, GraphQLString, GraphQLNonNull, GraphQLList, GraphQLEnumType } from "graphql"; +import { hello as queryHelloResolver } from "./NonNullPluralEnumDefaults"; +export function getSchema(): GraphQLSchema { + const GreetingOptionsType: GraphQLEnumType = new GraphQLEnumType({ + name: "GreetingOptions", + values: { + Greetings: { + value: "Greetings" + }, + Hello: { + value: "Hello" + }, + Sup: { + value: "Sup" + } + } + }); + const QueryType: GraphQLObjectType = new GraphQLObjectType({ + name: "Query", + fields() { + return { + hello: { + name: "hello", + type: GraphQLString, + args: { + greeting: { + type: new GraphQLNonNull(new GraphQLList(new GraphQLNonNull(GreetingOptionsType))), + defaultValue: [ + "Greetings", + "Hello" + ] + } + }, + resolve(_source, args) { + return queryHelloResolver(args.greeting); + } + } + }; + } + }); + return new GraphQLSchema({ + query: QueryType, + types: [GreetingOptionsType, QueryType] + }); +} +``` \ No newline at end of file diff --git a/src/tests/fixtures/enums/NonNullTsEnumDefault.ts.expected b/src/tests/fixtures/enums/NonNullTsEnumDefault.ts.expected deleted file mode 100644 index cb33380c..00000000 --- a/src/tests/fixtures/enums/NonNullTsEnumDefault.ts.expected +++ /dev/null @@ -1,76 +0,0 @@ ------------------ -INPUT ------------------ -// https://github.com/captbaritone/grats/issues/174 - -/** @gqlEnum */ -enum GreetingOptions { - Hello = "HELLO", - // Note that the casing between the variant name and the value is different. - Greetings = "GREETING", - Sup = "SUP", -} - -/** @gqlQueryField */ -export function hello( - greeting: GreetingOptions = GreetingOptions.Greetings, -): string { - return `${greeting} World`; -} - ------------------ -OUTPUT ------------------ --- SDL -- -enum GreetingOptions { - GREETING - HELLO - SUP -} - -type Query { - hello(greeting: GreetingOptions! = GREETING): String -} --- TypeScript -- -import { GraphQLSchema, GraphQLObjectType, GraphQLString, GraphQLNonNull, GraphQLEnumType } from "graphql"; -import { hello as queryHelloResolver } from "./NonNullTsEnumDefault"; -export function getSchema(): GraphQLSchema { - const GreetingOptionsType: GraphQLEnumType = new GraphQLEnumType({ - name: "GreetingOptions", - values: { - GREETING: { - value: "GREETING" - }, - HELLO: { - value: "HELLO" - }, - SUP: { - value: "SUP" - } - } - }); - const QueryType: GraphQLObjectType = new GraphQLObjectType({ - name: "Query", - fields() { - return { - hello: { - name: "hello", - type: GraphQLString, - args: { - greeting: { - type: new GraphQLNonNull(GreetingOptionsType), - defaultValue: "GREETING" - } - }, - resolve(_source, args) { - return queryHelloResolver(args.greeting); - } - } - }; - } - }); - return new GraphQLSchema({ - query: QueryType, - types: [GreetingOptionsType, QueryType] - }); -} diff --git a/src/tests/fixtures/enums/NonNullTsEnumDefault.ts.expected.md b/src/tests/fixtures/enums/NonNullTsEnumDefault.ts.expected.md new file mode 100644 index 00000000..823b696b --- /dev/null +++ b/src/tests/fixtures/enums/NonNullTsEnumDefault.ts.expected.md @@ -0,0 +1,83 @@ +## input + +```ts title="enums/NonNullTsEnumDefault.ts" +// https://github.com/captbaritone/grats/issues/174 + +/** @gqlEnum */ +enum GreetingOptions { + Hello = "HELLO", + // Note that the casing between the variant name and the value is different. + Greetings = "GREETING", + Sup = "SUP", +} + +/** @gqlQueryField */ +export function hello( + greeting: GreetingOptions = GreetingOptions.Greetings, +): string { + return `${greeting} World`; +} +``` + +## Output + +### SDL + +```graphql +enum GreetingOptions { + GREETING + HELLO + SUP +} + +type Query { + hello(greeting: GreetingOptions! = GREETING): String +} +``` + +### TypeScript + +```ts +import { GraphQLSchema, GraphQLObjectType, GraphQLString, GraphQLNonNull, GraphQLEnumType } from "graphql"; +import { hello as queryHelloResolver } from "./NonNullTsEnumDefault"; +export function getSchema(): GraphQLSchema { + const GreetingOptionsType: GraphQLEnumType = new GraphQLEnumType({ + name: "GreetingOptions", + values: { + GREETING: { + value: "GREETING" + }, + HELLO: { + value: "HELLO" + }, + SUP: { + value: "SUP" + } + } + }); + const QueryType: GraphQLObjectType = new GraphQLObjectType({ + name: "Query", + fields() { + return { + hello: { + name: "hello", + type: GraphQLString, + args: { + greeting: { + type: new GraphQLNonNull(GreetingOptionsType), + defaultValue: "GREETING" + } + }, + resolve(_source, args) { + return queryHelloResolver(args.greeting); + } + } + }; + } + }); + return new GraphQLSchema({ + query: QueryType, + types: [GreetingOptionsType, QueryType] + }); +} +``` \ No newline at end of file diff --git a/src/tests/fixtures/enums/NonNullTsEnumDefaultStringLiteral.ts.expected b/src/tests/fixtures/enums/NonNullTsEnumDefaultStringLiteral.ts.expected deleted file mode 100644 index be34463a..00000000 --- a/src/tests/fixtures/enums/NonNullTsEnumDefaultStringLiteral.ts.expected +++ /dev/null @@ -1,76 +0,0 @@ ------------------ -INPUT ------------------ -// https://github.com/captbaritone/grats/issues/174 - -/** @gqlEnum */ -enum GreetingOptions { - Hello = "HELLO", - // Note that the casing between the variant name and the value is different. - Greetings = "GREETING", - Sup = "SUP", -} - -/** @gqlQueryField */ -export function hello( - greeting: GreetingOptions = GreetingOptions.Greetings, -): string { - return `${greeting} World`; -} - ------------------ -OUTPUT ------------------ --- SDL -- -enum GreetingOptions { - GREETING - HELLO - SUP -} - -type Query { - hello(greeting: GreetingOptions! = GREETING): String -} --- TypeScript -- -import { GraphQLSchema, GraphQLObjectType, GraphQLString, GraphQLNonNull, GraphQLEnumType } from "graphql"; -import { hello as queryHelloResolver } from "./NonNullTsEnumDefaultStringLiteral"; -export function getSchema(): GraphQLSchema { - const GreetingOptionsType: GraphQLEnumType = new GraphQLEnumType({ - name: "GreetingOptions", - values: { - GREETING: { - value: "GREETING" - }, - HELLO: { - value: "HELLO" - }, - SUP: { - value: "SUP" - } - } - }); - const QueryType: GraphQLObjectType = new GraphQLObjectType({ - name: "Query", - fields() { - return { - hello: { - name: "hello", - type: GraphQLString, - args: { - greeting: { - type: new GraphQLNonNull(GreetingOptionsType), - defaultValue: "GREETING" - } - }, - resolve(_source, args) { - return queryHelloResolver(args.greeting); - } - } - }; - } - }); - return new GraphQLSchema({ - query: QueryType, - types: [GreetingOptionsType, QueryType] - }); -} diff --git a/src/tests/fixtures/enums/NonNullTsEnumDefaultStringLiteral.ts.expected.md b/src/tests/fixtures/enums/NonNullTsEnumDefaultStringLiteral.ts.expected.md new file mode 100644 index 00000000..88d3da52 --- /dev/null +++ b/src/tests/fixtures/enums/NonNullTsEnumDefaultStringLiteral.ts.expected.md @@ -0,0 +1,83 @@ +## input + +```ts title="enums/NonNullTsEnumDefaultStringLiteral.ts" +// https://github.com/captbaritone/grats/issues/174 + +/** @gqlEnum */ +enum GreetingOptions { + Hello = "HELLO", + // Note that the casing between the variant name and the value is different. + Greetings = "GREETING", + Sup = "SUP", +} + +/** @gqlQueryField */ +export function hello( + greeting: GreetingOptions = GreetingOptions.Greetings, +): string { + return `${greeting} World`; +} +``` + +## Output + +### SDL + +```graphql +enum GreetingOptions { + GREETING + HELLO + SUP +} + +type Query { + hello(greeting: GreetingOptions! = GREETING): String +} +``` + +### TypeScript + +```ts +import { GraphQLSchema, GraphQLObjectType, GraphQLString, GraphQLNonNull, GraphQLEnumType } from "graphql"; +import { hello as queryHelloResolver } from "./NonNullTsEnumDefaultStringLiteral"; +export function getSchema(): GraphQLSchema { + const GreetingOptionsType: GraphQLEnumType = new GraphQLEnumType({ + name: "GreetingOptions", + values: { + GREETING: { + value: "GREETING" + }, + HELLO: { + value: "HELLO" + }, + SUP: { + value: "SUP" + } + } + }); + const QueryType: GraphQLObjectType = new GraphQLObjectType({ + name: "Query", + fields() { + return { + hello: { + name: "hello", + type: GraphQLString, + args: { + greeting: { + type: new GraphQLNonNull(GreetingOptionsType), + defaultValue: "GREETING" + } + }, + resolve(_source, args) { + return queryHelloResolver(args.greeting); + } + } + }; + } + }); + return new GraphQLSchema({ + query: QueryType, + types: [GreetingOptionsType, QueryType] + }); +} +``` \ No newline at end of file diff --git a/src/tests/fixtures/enums/TypeAliasEnumNotAllowedWithEmitEnums.invalid.ts.expected b/src/tests/fixtures/enums/TypeAliasEnumNotAllowedWithEmitEnums.invalid.ts.expected deleted file mode 100644 index 00eb158f..00000000 --- a/src/tests/fixtures/enums/TypeAliasEnumNotAllowedWithEmitEnums.invalid.ts.expected +++ /dev/null @@ -1,23 +0,0 @@ ------------------ -INPUT ------------------ -// {"tsClientEnums": "enums.ts"} - -/** @gqlEnum */ -export type Status = "PENDING" | "COMPLETE" | "CANCELLED"; - -/** @gqlType */ -type Query = unknown; - -/** @gqlField */ -export function status(_: Query): Status { - return "PENDING"; -} - ------------------ -OUTPUT ------------------ -src/tests/fixtures/enums/TypeAliasEnumNotAllowedWithEmitEnums.invalid.ts:4:1 - error: Type alias enums are not supported when `tsClientEnums` is configured. Use `enum` declarations instead. For example: `export enum Status { PENDING = "pending" }`. - -4 export type Status = "PENDING" | "COMPLETE" | "CANCELLED"; - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/src/tests/fixtures/enums/TypeAliasEnumNotAllowedWithEmitEnums.invalid.ts.expected.md b/src/tests/fixtures/enums/TypeAliasEnumNotAllowedWithEmitEnums.invalid.ts.expected.md new file mode 100644 index 00000000..5fe6dc50 --- /dev/null +++ b/src/tests/fixtures/enums/TypeAliasEnumNotAllowedWithEmitEnums.invalid.ts.expected.md @@ -0,0 +1,27 @@ +## input + +```ts title="enums/TypeAliasEnumNotAllowedWithEmitEnums.invalid.ts" +// {"tsClientEnums": "enums.ts"} + +/** @gqlEnum */ +export type Status = "PENDING" | "COMPLETE" | "CANCELLED"; + +/** @gqlType */ +type Query = unknown; + +/** @gqlField */ +export function status(_: Query): Status { + return "PENDING"; +} +``` + +## Output + +### Error Report + +```text +src/tests/fixtures/enums/TypeAliasEnumNotAllowedWithEmitEnums.invalid.ts:4:1 - error: Type alias enums are not supported when `tsClientEnums` is configured. Use `enum` declarations instead. For example: `export enum Status { PENDING = "pending" }`. + +4 export type Status = "PENDING" | "COMPLETE" | "CANCELLED"; + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` \ No newline at end of file diff --git a/src/tests/fixtures/examples/playground.ts.expected b/src/tests/fixtures/examples/playground.ts.expected deleted file mode 100644 index b5601591..00000000 --- a/src/tests/fixtures/examples/playground.ts.expected +++ /dev/null @@ -1,104 +0,0 @@ ------------------ -INPUT ------------------ -/** @gqlType */ -export default class SomeType { - /** @gqlField */ - me(): UserResolver { - return new UserResolver(); - } - /** - * @gqlField - * @deprecated Please use `me` instead. - */ - viewer(): UserResolver { - return new UserResolver(); - } -} - -/** - * A user in our kick-ass system! - * @gqlType User - */ -class UserResolver { - /** @gqlField */ - name: string = "Alice"; - - /** @gqlField */ - greeting(args: { salutation: string }): string { - return `${args.salutation}, ${this.name}`; - } -} - -/** @gqlField */ -export function getUser(_: SomeType): UserResolver { - return new UserResolver(); -} - ------------------ -OUTPUT ------------------ --- SDL -- -type SomeType { - getUser: User - me: User - viewer: User @deprecated(reason: "Please use `me` instead.") -} - -"""A user in our kick-ass system!""" -type User { - greeting(salutation: String!): String - name: String -} --- TypeScript -- -import { GraphQLSchema, GraphQLObjectType, GraphQLString, GraphQLNonNull } from "graphql"; -import { getUser as someTypeGetUserResolver } from "./playground"; -export function getSchema(): GraphQLSchema { - const UserType: GraphQLObjectType = new GraphQLObjectType({ - name: "User", - description: "A user in our kick-ass system!", - fields() { - return { - greeting: { - name: "greeting", - type: GraphQLString, - args: { - salutation: { - type: new GraphQLNonNull(GraphQLString) - } - } - }, - name: { - name: "name", - type: GraphQLString - } - }; - } - }); - const SomeTypeType: GraphQLObjectType = new GraphQLObjectType({ - name: "SomeType", - fields() { - return { - getUser: { - name: "getUser", - type: UserType, - resolve(source) { - return someTypeGetUserResolver(source); - } - }, - me: { - name: "me", - type: UserType - }, - viewer: { - deprecationReason: "Please use `me` instead.", - name: "viewer", - type: UserType - } - }; - } - }); - return new GraphQLSchema({ - types: [SomeTypeType, UserType] - }); -} diff --git a/src/tests/fixtures/examples/playground.ts.expected.md b/src/tests/fixtures/examples/playground.ts.expected.md new file mode 100644 index 00000000..09395dbf --- /dev/null +++ b/src/tests/fixtures/examples/playground.ts.expected.md @@ -0,0 +1,111 @@ +## input + +```ts title="examples/playground.ts" +/** @gqlType */ +export default class SomeType { + /** @gqlField */ + me(): UserResolver { + return new UserResolver(); + } + /** + * @gqlField + * @deprecated Please use `me` instead. + */ + viewer(): UserResolver { + return new UserResolver(); + } +} + +/** + * A user in our kick-ass system! + * @gqlType User + */ +class UserResolver { + /** @gqlField */ + name: string = "Alice"; + + /** @gqlField */ + greeting(args: { salutation: string }): string { + return `${args.salutation}, ${this.name}`; + } +} + +/** @gqlField */ +export function getUser(_: SomeType): UserResolver { + return new UserResolver(); +} +``` + +## Output + +### SDL + +```graphql +type SomeType { + getUser: User + me: User + viewer: User @deprecated(reason: "Please use `me` instead.") +} + +"""A user in our kick-ass system!""" +type User { + greeting(salutation: String!): String + name: String +} +``` + +### TypeScript + +```ts +import { GraphQLSchema, GraphQLObjectType, GraphQLString, GraphQLNonNull } from "graphql"; +import { getUser as someTypeGetUserResolver } from "./playground"; +export function getSchema(): GraphQLSchema { + const UserType: GraphQLObjectType = new GraphQLObjectType({ + name: "User", + description: "A user in our kick-ass system!", + fields() { + return { + greeting: { + name: "greeting", + type: GraphQLString, + args: { + salutation: { + type: new GraphQLNonNull(GraphQLString) + } + } + }, + name: { + name: "name", + type: GraphQLString + } + }; + } + }); + const SomeTypeType: GraphQLObjectType = new GraphQLObjectType({ + name: "SomeType", + fields() { + return { + getUser: { + name: "getUser", + type: UserType, + resolve(source) { + return someTypeGetUserResolver(source); + } + }, + me: { + name: "me", + type: UserType + }, + viewer: { + deprecationReason: "Please use `me` instead.", + name: "viewer", + type: UserType + } + }; + } + }); + return new GraphQLSchema({ + types: [SomeTypeType, UserType] + }); +} +``` \ No newline at end of file diff --git a/src/tests/fixtures/examples/readme.ts.expected b/src/tests/fixtures/examples/readme.ts.expected deleted file mode 100644 index 1d93f1fd..00000000 --- a/src/tests/fixtures/examples/readme.ts.expected +++ /dev/null @@ -1,98 +0,0 @@ ------------------ -INPUT ------------------ -/** @gqlType */ -type Query = unknown; - -/** @gqlField */ -export function me(_: Query): UserResolver { - return new UserResolver(); -} -/** - * @gqlField - * @deprecated Please use `me` instead. - */ -export function viewer(_: Query): UserResolver { - return new UserResolver(); -} - -/** - * A user in our kick-ass system! - * @gqlType User - */ -class UserResolver { - /** @gqlField */ - name: string = "Alice"; - - /** @gqlField */ - greeting(args: { salutation: string }): string { - return `${args.salutation}, ${this.name}`; - } -} - ------------------ -OUTPUT ------------------ --- SDL -- -type Query { - me: User - viewer: User @deprecated(reason: "Please use `me` instead.") -} - -"""A user in our kick-ass system!""" -type User { - greeting(salutation: String!): String - name: String -} --- TypeScript -- -import { GraphQLSchema, GraphQLObjectType, GraphQLString, GraphQLNonNull } from "graphql"; -import { me as queryMeResolver, viewer as queryViewerResolver } from "./readme"; -export function getSchema(): GraphQLSchema { - const UserType: GraphQLObjectType = new GraphQLObjectType({ - name: "User", - description: "A user in our kick-ass system!", - fields() { - return { - greeting: { - name: "greeting", - type: GraphQLString, - args: { - salutation: { - type: new GraphQLNonNull(GraphQLString) - } - } - }, - name: { - name: "name", - type: GraphQLString - } - }; - } - }); - const QueryType: GraphQLObjectType = new GraphQLObjectType({ - name: "Query", - fields() { - return { - me: { - name: "me", - type: UserType, - resolve(source) { - return queryMeResolver(source); - } - }, - viewer: { - deprecationReason: "Please use `me` instead.", - name: "viewer", - type: UserType, - resolve(source) { - return queryViewerResolver(source); - } - } - }; - } - }); - return new GraphQLSchema({ - query: QueryType, - types: [QueryType, UserType] - }); -} diff --git a/src/tests/fixtures/examples/readme.ts.expected.md b/src/tests/fixtures/examples/readme.ts.expected.md new file mode 100644 index 00000000..709de8ea --- /dev/null +++ b/src/tests/fixtures/examples/readme.ts.expected.md @@ -0,0 +1,105 @@ +## input + +```ts title="examples/readme.ts" +/** @gqlType */ +type Query = unknown; + +/** @gqlField */ +export function me(_: Query): UserResolver { + return new UserResolver(); +} +/** + * @gqlField + * @deprecated Please use `me` instead. + */ +export function viewer(_: Query): UserResolver { + return new UserResolver(); +} + +/** + * A user in our kick-ass system! + * @gqlType User + */ +class UserResolver { + /** @gqlField */ + name: string = "Alice"; + + /** @gqlField */ + greeting(args: { salutation: string }): string { + return `${args.salutation}, ${this.name}`; + } +} +``` + +## Output + +### SDL + +```graphql +type Query { + me: User + viewer: User @deprecated(reason: "Please use `me` instead.") +} + +"""A user in our kick-ass system!""" +type User { + greeting(salutation: String!): String + name: String +} +``` + +### TypeScript + +```ts +import { GraphQLSchema, GraphQLObjectType, GraphQLString, GraphQLNonNull } from "graphql"; +import { me as queryMeResolver, viewer as queryViewerResolver } from "./readme"; +export function getSchema(): GraphQLSchema { + const UserType: GraphQLObjectType = new GraphQLObjectType({ + name: "User", + description: "A user in our kick-ass system!", + fields() { + return { + greeting: { + name: "greeting", + type: GraphQLString, + args: { + salutation: { + type: new GraphQLNonNull(GraphQLString) + } + } + }, + name: { + name: "name", + type: GraphQLString + } + }; + } + }); + const QueryType: GraphQLObjectType = new GraphQLObjectType({ + name: "Query", + fields() { + return { + me: { + name: "me", + type: UserType, + resolve(source) { + return queryMeResolver(source); + } + }, + viewer: { + deprecationReason: "Please use `me` instead.", + name: "viewer", + type: UserType, + resolve(source) { + return queryViewerResolver(source); + } + } + }; + } + }); + return new GraphQLSchema({ + query: QueryType, + types: [QueryType, UserType] + }); +} +``` \ No newline at end of file diff --git a/src/tests/fixtures/extend_interface/addStringFieldToEnum.invalid.ts.expected b/src/tests/fixtures/extend_interface/addStringFieldToEnum.invalid.ts.expected deleted file mode 100644 index c88a89de..00000000 --- a/src/tests/fixtures/extend_interface/addStringFieldToEnum.invalid.ts.expected +++ /dev/null @@ -1,23 +0,0 @@ ------------------ -INPUT ------------------ -/** @gqlEnum */ -type MyEnum = "Foo" | "Bar"; - -/** @gqlField */ -export function greeting(myEnum: MyEnum): string { - return `Hello ${myEnum}!`; -} - ------------------ -OUTPUT ------------------ -src/tests/fixtures/extend_interface/addStringFieldToEnum.invalid.ts:5:34 - error: Unexpected type passed to `@gqlField` function. `@gqlField` functions can only be used to extend `@gqlType` and `@gqlInterface` types. - -5 export function greeting(myEnum: MyEnum): string { - ~~~~~~ - - src/tests/fixtures/extend_interface/addStringFieldToEnum.invalid.ts:2:6 - 2 type MyEnum = "Foo" | "Bar"; - ~~~~~~ - This is the type that was passed to `@gqlField`. diff --git a/src/tests/fixtures/extend_interface/addStringFieldToEnum.invalid.ts.expected.md b/src/tests/fixtures/extend_interface/addStringFieldToEnum.invalid.ts.expected.md new file mode 100644 index 00000000..05815fae --- /dev/null +++ b/src/tests/fixtures/extend_interface/addStringFieldToEnum.invalid.ts.expected.md @@ -0,0 +1,27 @@ +## input + +```ts title="extend_interface/addStringFieldToEnum.invalid.ts" +/** @gqlEnum */ +type MyEnum = "Foo" | "Bar"; + +/** @gqlField */ +export function greeting(myEnum: MyEnum): string { + return `Hello ${myEnum}!`; +} +``` + +## Output + +### Error Report + +```text +src/tests/fixtures/extend_interface/addStringFieldToEnum.invalid.ts:5:34 - error: Unexpected type passed to `@gqlField` function. `@gqlField` functions can only be used to extend `@gqlType` and `@gqlInterface` types. + +5 export function greeting(myEnum: MyEnum): string { + ~~~~~~ + + src/tests/fixtures/extend_interface/addStringFieldToEnum.invalid.ts:2:6 + 2 type MyEnum = "Foo" | "Bar"; + ~~~~~~ + This is the type that was passed to `@gqlField`. +``` \ No newline at end of file diff --git a/src/tests/fixtures/extend_interface/addStringFieldToInterface.ts.expected b/src/tests/fixtures/extend_interface/addStringFieldToInterface.ts.expected deleted file mode 100644 index b0c5f020..00000000 --- a/src/tests/fixtures/extend_interface/addStringFieldToInterface.ts.expected +++ /dev/null @@ -1,114 +0,0 @@ ------------------ -INPUT ------------------ -/** @gqlInterface */ -interface IPerson { - name: string; - /** @gqlField */ - hello: string; -} - -/** @gqlField */ -export function greeting(person: IPerson): string { - return `Hello ${person.name}!`; -} - -/** @gqlType */ -class User implements IPerson { - __typename: "User"; - name: string; - /** @gqlField */ - hello: string; -} - -/** @gqlType */ -class Admin implements IPerson { - __typename: "Admin"; - name: string; - /** @gqlField */ - hello: string; -} - ------------------ -OUTPUT ------------------ --- SDL -- -interface IPerson { - greeting: String - hello: String -} - -type Admin implements IPerson { - greeting: String - hello: String -} - -type User implements IPerson { - greeting: String - hello: String -} --- TypeScript -- -import { GraphQLSchema, GraphQLInterfaceType, GraphQLString, GraphQLObjectType } from "graphql"; -import { greeting as adminGreetingResolver, greeting as userGreetingResolver } from "./addStringFieldToInterface"; -export function getSchema(): GraphQLSchema { - const IPersonType: GraphQLInterfaceType = new GraphQLInterfaceType({ - name: "IPerson", - fields() { - return { - greeting: { - name: "greeting", - type: GraphQLString - }, - hello: { - name: "hello", - type: GraphQLString - } - }; - } - }); - const AdminType: GraphQLObjectType = new GraphQLObjectType({ - name: "Admin", - fields() { - return { - greeting: { - name: "greeting", - type: GraphQLString, - resolve(source) { - return adminGreetingResolver(source); - } - }, - hello: { - name: "hello", - type: GraphQLString - } - }; - }, - interfaces() { - return [IPersonType]; - } - }); - const UserType: GraphQLObjectType = new GraphQLObjectType({ - name: "User", - fields() { - return { - greeting: { - name: "greeting", - type: GraphQLString, - resolve(source) { - return userGreetingResolver(source); - } - }, - hello: { - name: "hello", - type: GraphQLString - } - }; - }, - interfaces() { - return [IPersonType]; - } - }); - return new GraphQLSchema({ - types: [IPersonType, AdminType, UserType] - }); -} diff --git a/src/tests/fixtures/extend_interface/addStringFieldToInterface.ts.expected.md b/src/tests/fixtures/extend_interface/addStringFieldToInterface.ts.expected.md new file mode 100644 index 00000000..406bf211 --- /dev/null +++ b/src/tests/fixtures/extend_interface/addStringFieldToInterface.ts.expected.md @@ -0,0 +1,121 @@ +## input + +```ts title="extend_interface/addStringFieldToInterface.ts" +/** @gqlInterface */ +interface IPerson { + name: string; + /** @gqlField */ + hello: string; +} + +/** @gqlField */ +export function greeting(person: IPerson): string { + return `Hello ${person.name}!`; +} + +/** @gqlType */ +class User implements IPerson { + __typename: "User"; + name: string; + /** @gqlField */ + hello: string; +} + +/** @gqlType */ +class Admin implements IPerson { + __typename: "Admin"; + name: string; + /** @gqlField */ + hello: string; +} +``` + +## Output + +### SDL + +```graphql +interface IPerson { + greeting: String + hello: String +} + +type Admin implements IPerson { + greeting: String + hello: String +} + +type User implements IPerson { + greeting: String + hello: String +} +``` + +### TypeScript + +```ts +import { GraphQLSchema, GraphQLInterfaceType, GraphQLString, GraphQLObjectType } from "graphql"; +import { greeting as adminGreetingResolver, greeting as userGreetingResolver } from "./addStringFieldToInterface"; +export function getSchema(): GraphQLSchema { + const IPersonType: GraphQLInterfaceType = new GraphQLInterfaceType({ + name: "IPerson", + fields() { + return { + greeting: { + name: "greeting", + type: GraphQLString + }, + hello: { + name: "hello", + type: GraphQLString + } + }; + } + }); + const AdminType: GraphQLObjectType = new GraphQLObjectType({ + name: "Admin", + fields() { + return { + greeting: { + name: "greeting", + type: GraphQLString, + resolve(source) { + return adminGreetingResolver(source); + } + }, + hello: { + name: "hello", + type: GraphQLString + } + }; + }, + interfaces() { + return [IPersonType]; + } + }); + const UserType: GraphQLObjectType = new GraphQLObjectType({ + name: "User", + fields() { + return { + greeting: { + name: "greeting", + type: GraphQLString, + resolve(source) { + return userGreetingResolver(source); + } + }, + hello: { + name: "hello", + type: GraphQLString + } + }; + }, + interfaces() { + return [IPersonType]; + } + }); + return new GraphQLSchema({ + types: [IPersonType, AdminType, UserType] + }); +} +``` \ No newline at end of file diff --git a/src/tests/fixtures/extend_interface/addStringFieldToInterfaceImplementedByInterface.ts.expected b/src/tests/fixtures/extend_interface/addStringFieldToInterfaceImplementedByInterface.ts.expected deleted file mode 100644 index 7f1bf7f5..00000000 --- a/src/tests/fixtures/extend_interface/addStringFieldToInterfaceImplementedByInterface.ts.expected +++ /dev/null @@ -1,122 +0,0 @@ ------------------ -INPUT ------------------ -/** @gqlField */ -export function greeting(thing: IThing): string { - return `Hello ${thing.name}!`; -} - -/** @gqlInterface */ -interface IThing { - name: string; - // Should have greeting added -} - -/** - * @gqlInterface - */ -interface IPerson extends IThing { - name: string; - // Should have greeting added -} - -/** @gqlType */ -class User implements IPerson, IThing { - __typename: "User"; - name: string; - // Should have greeting added -} - -/** @gqlType */ -class Admin implements IPerson, IThing { - __typename: "Admin"; - name: string; - // Should have greeting added -} - ------------------ -OUTPUT ------------------ --- SDL -- -interface IPerson implements IThing { - greeting: String -} - -interface IThing { - greeting: String -} - -type Admin implements IPerson & IThing { - greeting: String -} - -type User implements IPerson & IThing { - greeting: String -} --- TypeScript -- -import { GraphQLSchema, GraphQLInterfaceType, GraphQLString, GraphQLObjectType } from "graphql"; -import { greeting as adminGreetingResolver, greeting as userGreetingResolver } from "./addStringFieldToInterfaceImplementedByInterface"; -export function getSchema(): GraphQLSchema { - const IThingType: GraphQLInterfaceType = new GraphQLInterfaceType({ - name: "IThing", - fields() { - return { - greeting: { - name: "greeting", - type: GraphQLString - } - }; - } - }); - const IPersonType: GraphQLInterfaceType = new GraphQLInterfaceType({ - name: "IPerson", - fields() { - return { - greeting: { - name: "greeting", - type: GraphQLString - } - }; - }, - interfaces() { - return [IThingType]; - } - }); - const AdminType: GraphQLObjectType = new GraphQLObjectType({ - name: "Admin", - fields() { - return { - greeting: { - name: "greeting", - type: GraphQLString, - resolve(source) { - return adminGreetingResolver(source); - } - } - }; - }, - interfaces() { - return [IPersonType, IThingType]; - } - }); - const UserType: GraphQLObjectType = new GraphQLObjectType({ - name: "User", - fields() { - return { - greeting: { - name: "greeting", - type: GraphQLString, - resolve(source) { - return userGreetingResolver(source); - } - } - }; - }, - interfaces() { - return [IPersonType, IThingType]; - } - }); - return new GraphQLSchema({ - types: [IPersonType, IThingType, AdminType, UserType] - }); -} diff --git a/src/tests/fixtures/extend_interface/addStringFieldToInterfaceImplementedByInterface.ts.expected.md b/src/tests/fixtures/extend_interface/addStringFieldToInterfaceImplementedByInterface.ts.expected.md new file mode 100644 index 00000000..d1100b04 --- /dev/null +++ b/src/tests/fixtures/extend_interface/addStringFieldToInterfaceImplementedByInterface.ts.expected.md @@ -0,0 +1,129 @@ +## input + +```ts title="extend_interface/addStringFieldToInterfaceImplementedByInterface.ts" +/** @gqlField */ +export function greeting(thing: IThing): string { + return `Hello ${thing.name}!`; +} + +/** @gqlInterface */ +interface IThing { + name: string; + // Should have greeting added +} + +/** + * @gqlInterface + */ +interface IPerson extends IThing { + name: string; + // Should have greeting added +} + +/** @gqlType */ +class User implements IPerson, IThing { + __typename: "User"; + name: string; + // Should have greeting added +} + +/** @gqlType */ +class Admin implements IPerson, IThing { + __typename: "Admin"; + name: string; + // Should have greeting added +} +``` + +## Output + +### SDL + +```graphql +interface IPerson implements IThing { + greeting: String +} + +interface IThing { + greeting: String +} + +type Admin implements IPerson & IThing { + greeting: String +} + +type User implements IPerson & IThing { + greeting: String +} +``` + +### TypeScript + +```ts +import { GraphQLSchema, GraphQLInterfaceType, GraphQLString, GraphQLObjectType } from "graphql"; +import { greeting as adminGreetingResolver, greeting as userGreetingResolver } from "./addStringFieldToInterfaceImplementedByInterface"; +export function getSchema(): GraphQLSchema { + const IThingType: GraphQLInterfaceType = new GraphQLInterfaceType({ + name: "IThing", + fields() { + return { + greeting: { + name: "greeting", + type: GraphQLString + } + }; + } + }); + const IPersonType: GraphQLInterfaceType = new GraphQLInterfaceType({ + name: "IPerson", + fields() { + return { + greeting: { + name: "greeting", + type: GraphQLString + } + }; + }, + interfaces() { + return [IThingType]; + } + }); + const AdminType: GraphQLObjectType = new GraphQLObjectType({ + name: "Admin", + fields() { + return { + greeting: { + name: "greeting", + type: GraphQLString, + resolve(source) { + return adminGreetingResolver(source); + } + } + }; + }, + interfaces() { + return [IPersonType, IThingType]; + } + }); + const UserType: GraphQLObjectType = new GraphQLObjectType({ + name: "User", + fields() { + return { + greeting: { + name: "greeting", + type: GraphQLString, + resolve(source) { + return userGreetingResolver(source); + } + } + }; + }, + interfaces() { + return [IPersonType, IThingType]; + } + }); + return new GraphQLSchema({ + types: [IPersonType, IThingType, AdminType, UserType] + }); +} +``` \ No newline at end of file diff --git a/src/tests/fixtures/extend_interface/addStringFieldToInterfaceTwice.invalid.ts.expected b/src/tests/fixtures/extend_interface/addStringFieldToInterfaceTwice.invalid.ts.expected deleted file mode 100644 index 3b898e1a..00000000 --- a/src/tests/fixtures/extend_interface/addStringFieldToInterfaceTwice.invalid.ts.expected +++ /dev/null @@ -1,66 +0,0 @@ ------------------ -INPUT ------------------ -/** @gqlInterface */ -interface IPerson { - name: string; - /** @gqlField */ - hello: string; -} - -/** @gqlField */ -export function greeting(person: IPerson): string { - return `Hello ${person.name}!`; -} - -/** @gqlField greeting */ -export function alsoGreeting(person: IPerson): string { - return `Hello ${person.name}!`; -} - -/** @gqlType */ -class User implements IPerson { - __typename: "User"; - name: string; - /** @gqlField */ - hello: string; -} - -/** @gqlType */ -class Admin implements IPerson { - __typename: "Admin"; - name: string; - /** @gqlField */ - hello: string; -} - ------------------ -OUTPUT ------------------ -src/tests/fixtures/extend_interface/addStringFieldToInterfaceTwice.invalid.ts:9:17 - error: Field "IPerson.greeting" can only be defined once. - -9 export function greeting(person: IPerson): string { - ~~~~~~~~ - - src/tests/fixtures/extend_interface/addStringFieldToInterfaceTwice.invalid.ts:13:5 - 13 /** @gqlField greeting */ - ~~~~~~~~~~~~~~~~~~~ - Related location -src/tests/fixtures/extend_interface/addStringFieldToInterfaceTwice.invalid.ts:9:17 - error: Field "Admin.greeting" can only be defined once. - -9 export function greeting(person: IPerson): string { - ~~~~~~~~ - - src/tests/fixtures/extend_interface/addStringFieldToInterfaceTwice.invalid.ts:13:5 - 13 /** @gqlField greeting */ - ~~~~~~~~~~~~~~~~~~~ - Related location -src/tests/fixtures/extend_interface/addStringFieldToInterfaceTwice.invalid.ts:9:17 - error: Field "User.greeting" can only be defined once. - -9 export function greeting(person: IPerson): string { - ~~~~~~~~ - - src/tests/fixtures/extend_interface/addStringFieldToInterfaceTwice.invalid.ts:13:5 - 13 /** @gqlField greeting */ - ~~~~~~~~~~~~~~~~~~~ - Related location diff --git a/src/tests/fixtures/extend_interface/addStringFieldToInterfaceTwice.invalid.ts.expected.md b/src/tests/fixtures/extend_interface/addStringFieldToInterfaceTwice.invalid.ts.expected.md new file mode 100644 index 00000000..c081aa94 --- /dev/null +++ b/src/tests/fixtures/extend_interface/addStringFieldToInterfaceTwice.invalid.ts.expected.md @@ -0,0 +1,70 @@ +## input + +```ts title="extend_interface/addStringFieldToInterfaceTwice.invalid.ts" +/** @gqlInterface */ +interface IPerson { + name: string; + /** @gqlField */ + hello: string; +} + +/** @gqlField */ +export function greeting(person: IPerson): string { + return `Hello ${person.name}!`; +} + +/** @gqlField greeting */ +export function alsoGreeting(person: IPerson): string { + return `Hello ${person.name}!`; +} + +/** @gqlType */ +class User implements IPerson { + __typename: "User"; + name: string; + /** @gqlField */ + hello: string; +} + +/** @gqlType */ +class Admin implements IPerson { + __typename: "Admin"; + name: string; + /** @gqlField */ + hello: string; +} +``` + +## Output + +### Error Report + +```text +src/tests/fixtures/extend_interface/addStringFieldToInterfaceTwice.invalid.ts:9:17 - error: Field "IPerson.greeting" can only be defined once. + +9 export function greeting(person: IPerson): string { + ~~~~~~~~ + + src/tests/fixtures/extend_interface/addStringFieldToInterfaceTwice.invalid.ts:13:5 + 13 /** @gqlField greeting */ + ~~~~~~~~~~~~~~~~~~~ + Related location +src/tests/fixtures/extend_interface/addStringFieldToInterfaceTwice.invalid.ts:9:17 - error: Field "Admin.greeting" can only be defined once. + +9 export function greeting(person: IPerson): string { + ~~~~~~~~ + + src/tests/fixtures/extend_interface/addStringFieldToInterfaceTwice.invalid.ts:13:5 + 13 /** @gqlField greeting */ + ~~~~~~~~~~~~~~~~~~~ + Related location +src/tests/fixtures/extend_interface/addStringFieldToInterfaceTwice.invalid.ts:9:17 - error: Field "User.greeting" can only be defined once. + +9 export function greeting(person: IPerson): string { + ~~~~~~~~ + + src/tests/fixtures/extend_interface/addStringFieldToInterfaceTwice.invalid.ts:13:5 + 13 /** @gqlField greeting */ + ~~~~~~~~~~~~~~~~~~~ + Related location +``` \ No newline at end of file diff --git a/src/tests/fixtures/extend_interface/addStringFieldToNonGrats.invalid.ts.expected b/src/tests/fixtures/extend_interface/addStringFieldToNonGrats.invalid.ts.expected deleted file mode 100644 index 070f7877..00000000 --- a/src/tests/fixtures/extend_interface/addStringFieldToNonGrats.invalid.ts.expected +++ /dev/null @@ -1,17 +0,0 @@ ------------------ -INPUT ------------------ -type SomeNonGratsType = string; - -/** @gqlField */ -export function greeting(someType: SomeNonGratsType): string { - return `Hello ${someType}!`; -} - ------------------ -OUTPUT ------------------ -src/tests/fixtures/extend_interface/addStringFieldToNonGrats.invalid.ts:4:36 - error: Unable to resolve type reference. In order to generate a GraphQL schema, Grats needs to determine which GraphQL type is being referenced. This requires being able to resolve type references to their `@gql` annotated declaration. However this reference could not be resolved. Is it possible that this type is not defined in this file? - -4 export function greeting(someType: SomeNonGratsType): string { - ~~~~~~~~~~~~~~~~ diff --git a/src/tests/fixtures/extend_interface/addStringFieldToNonGrats.invalid.ts.expected.md b/src/tests/fixtures/extend_interface/addStringFieldToNonGrats.invalid.ts.expected.md new file mode 100644 index 00000000..b4b955aa --- /dev/null +++ b/src/tests/fixtures/extend_interface/addStringFieldToNonGrats.invalid.ts.expected.md @@ -0,0 +1,21 @@ +## input + +```ts title="extend_interface/addStringFieldToNonGrats.invalid.ts" +type SomeNonGratsType = string; + +/** @gqlField */ +export function greeting(someType: SomeNonGratsType): string { + return `Hello ${someType}!`; +} +``` + +## Output + +### Error Report + +```text +src/tests/fixtures/extend_interface/addStringFieldToNonGrats.invalid.ts:4:36 - error: Unable to resolve type reference. In order to generate a GraphQL schema, Grats needs to determine which GraphQL type is being referenced. This requires being able to resolve type references to their `@gql` annotated declaration. However this reference could not be resolved. Is it possible that this type is not defined in this file? + +4 export function greeting(someType: SomeNonGratsType): string { + ~~~~~~~~~~~~~~~~ +``` \ No newline at end of file diff --git a/src/tests/fixtures/extend_interface/redefineFiledThatExistsOnConcreteType.invalid.ts.expected b/src/tests/fixtures/extend_interface/redefineFiledThatExistsOnConcreteType.invalid.ts.expected deleted file mode 100644 index ec598487..00000000 --- a/src/tests/fixtures/extend_interface/redefineFiledThatExistsOnConcreteType.invalid.ts.expected +++ /dev/null @@ -1,40 +0,0 @@ ------------------ -INPUT ------------------ -/** @gqlInterface */ -interface IPerson { - name: string; - /** @gqlField */ - hello: string; -} - -/** @gqlField */ -export function greeting(person: IPerson): string { - return `Hello ${person.name}!`; -} - -/** @gqlType */ -class User implements IPerson { - __typename: "User"; - name: string; - /** @gqlField */ - hello: string; - - /** @gqlField */ - greeting(): string { - return `Hello ${this.name}!`; - } -} - ------------------ -OUTPUT ------------------ -src/tests/fixtures/extend_interface/redefineFiledThatExistsOnConcreteType.invalid.ts:21:3 - error: Field "User.greeting" can only be defined once. - -21 greeting(): string { - ~~~~~~~~ - - src/tests/fixtures/extend_interface/redefineFiledThatExistsOnConcreteType.invalid.ts:9:17 - 9 export function greeting(person: IPerson): string { - ~~~~~~~~ - Related location diff --git a/src/tests/fixtures/extend_interface/redefineFiledThatExistsOnConcreteType.invalid.ts.expected.md b/src/tests/fixtures/extend_interface/redefineFiledThatExistsOnConcreteType.invalid.ts.expected.md new file mode 100644 index 00000000..b7699eac --- /dev/null +++ b/src/tests/fixtures/extend_interface/redefineFiledThatExistsOnConcreteType.invalid.ts.expected.md @@ -0,0 +1,44 @@ +## input + +```ts title="extend_interface/redefineFiledThatExistsOnConcreteType.invalid.ts" +/** @gqlInterface */ +interface IPerson { + name: string; + /** @gqlField */ + hello: string; +} + +/** @gqlField */ +export function greeting(person: IPerson): string { + return `Hello ${person.name}!`; +} + +/** @gqlType */ +class User implements IPerson { + __typename: "User"; + name: string; + /** @gqlField */ + hello: string; + + /** @gqlField */ + greeting(): string { + return `Hello ${this.name}!`; + } +} +``` + +## Output + +### Error Report + +```text +src/tests/fixtures/extend_interface/redefineFiledThatExistsOnConcreteType.invalid.ts:21:3 - error: Field "User.greeting" can only be defined once. + +21 greeting(): string { + ~~~~~~~~ + + src/tests/fixtures/extend_interface/redefineFiledThatExistsOnConcreteType.invalid.ts:9:17 + 9 export function greeting(person: IPerson): string { + ~~~~~~~~ + Related location +``` \ No newline at end of file diff --git a/src/tests/fixtures/extend_interface/redefineFiledThatExistsOnImplementingInterface.invalid.ts.expected b/src/tests/fixtures/extend_interface/redefineFiledThatExistsOnImplementingInterface.invalid.ts.expected deleted file mode 100644 index 21db8a89..00000000 --- a/src/tests/fixtures/extend_interface/redefineFiledThatExistsOnImplementingInterface.invalid.ts.expected +++ /dev/null @@ -1,38 +0,0 @@ ------------------ -INPUT ------------------ -/** @gqlInterface */ -interface IPerson { - name: string; - /** @gqlField */ - hello: string; -} - -/** @gqlField */ -export function greeting(person: IPerson): string { - return `Hello ${person.name}!`; -} - -/** @gqlInterface */ -interface User extends IPerson { - __typename: "User"; - name: string; - /** @gqlField */ - hello: string; - - /** @gqlField */ - greeting(): string; -} - ------------------ -OUTPUT ------------------ -src/tests/fixtures/extend_interface/redefineFiledThatExistsOnImplementingInterface.invalid.ts:21:3 - error: Field "User.greeting" can only be defined once. - -21 greeting(): string; - ~~~~~~~~ - - src/tests/fixtures/extend_interface/redefineFiledThatExistsOnImplementingInterface.invalid.ts:9:17 - 9 export function greeting(person: IPerson): string { - ~~~~~~~~ - Related location diff --git a/src/tests/fixtures/extend_interface/redefineFiledThatExistsOnImplementingInterface.invalid.ts.expected.md b/src/tests/fixtures/extend_interface/redefineFiledThatExistsOnImplementingInterface.invalid.ts.expected.md new file mode 100644 index 00000000..084a21a2 --- /dev/null +++ b/src/tests/fixtures/extend_interface/redefineFiledThatExistsOnImplementingInterface.invalid.ts.expected.md @@ -0,0 +1,42 @@ +## input + +```ts title="extend_interface/redefineFiledThatExistsOnImplementingInterface.invalid.ts" +/** @gqlInterface */ +interface IPerson { + name: string; + /** @gqlField */ + hello: string; +} + +/** @gqlField */ +export function greeting(person: IPerson): string { + return `Hello ${person.name}!`; +} + +/** @gqlInterface */ +interface User extends IPerson { + __typename: "User"; + name: string; + /** @gqlField */ + hello: string; + + /** @gqlField */ + greeting(): string; +} +``` + +## Output + +### Error Report + +```text +src/tests/fixtures/extend_interface/redefineFiledThatExistsOnImplementingInterface.invalid.ts:21:3 - error: Field "User.greeting" can only be defined once. + +21 greeting(): string; + ~~~~~~~~ + + src/tests/fixtures/extend_interface/redefineFiledThatExistsOnImplementingInterface.invalid.ts:9:17 + 9 export function greeting(person: IPerson): string { + ~~~~~~~~ + Related location +``` \ No newline at end of file diff --git a/src/tests/fixtures/extend_type/addDeprecatedField.ts.expected b/src/tests/fixtures/extend_type/addDeprecatedField.ts.expected deleted file mode 100644 index ff18709b..00000000 --- a/src/tests/fixtures/extend_type/addDeprecatedField.ts.expected +++ /dev/null @@ -1,46 +0,0 @@ ------------------ -INPUT ------------------ -/** @gqlType */ -class SomeType { - // No fields -} - -/** - * @gqlField - * @deprecated Because reasons - */ -export function greeting(query: SomeType): string { - return "Hello world!"; -} - ------------------ -OUTPUT ------------------ --- SDL -- -type SomeType { - greeting: String @deprecated(reason: "Because reasons") -} --- TypeScript -- -import { GraphQLSchema, GraphQLObjectType, GraphQLString } from "graphql"; -import { greeting as someTypeGreetingResolver } from "./addDeprecatedField"; -export function getSchema(): GraphQLSchema { - const SomeTypeType: GraphQLObjectType = new GraphQLObjectType({ - name: "SomeType", - fields() { - return { - greeting: { - deprecationReason: "Because reasons", - name: "greeting", - type: GraphQLString, - resolve(source) { - return someTypeGreetingResolver(source); - } - } - }; - } - }); - return new GraphQLSchema({ - types: [SomeTypeType] - }); -} diff --git a/src/tests/fixtures/extend_type/addDeprecatedField.ts.expected.md b/src/tests/fixtures/extend_type/addDeprecatedField.ts.expected.md new file mode 100644 index 00000000..c50b25bc --- /dev/null +++ b/src/tests/fixtures/extend_type/addDeprecatedField.ts.expected.md @@ -0,0 +1,53 @@ +## input + +```ts title="extend_type/addDeprecatedField.ts" +/** @gqlType */ +class SomeType { + // No fields +} + +/** + * @gqlField + * @deprecated Because reasons + */ +export function greeting(query: SomeType): string { + return "Hello world!"; +} +``` + +## Output + +### SDL + +```graphql +type SomeType { + greeting: String @deprecated(reason: "Because reasons") +} +``` + +### TypeScript + +```ts +import { GraphQLSchema, GraphQLObjectType, GraphQLString } from "graphql"; +import { greeting as someTypeGreetingResolver } from "./addDeprecatedField"; +export function getSchema(): GraphQLSchema { + const SomeTypeType: GraphQLObjectType = new GraphQLObjectType({ + name: "SomeType", + fields() { + return { + greeting: { + deprecationReason: "Because reasons", + name: "greeting", + type: GraphQLString, + resolve(source) { + return someTypeGreetingResolver(source); + } + } + }; + } + }); + return new GraphQLSchema({ + types: [SomeTypeType] + }); +} +``` \ No newline at end of file diff --git a/src/tests/fixtures/extend_type/addFieldWithArguments.ts.expected b/src/tests/fixtures/extend_type/addFieldWithArguments.ts.expected deleted file mode 100644 index e08f3861..00000000 --- a/src/tests/fixtures/extend_type/addFieldWithArguments.ts.expected +++ /dev/null @@ -1,47 +0,0 @@ ------------------ -INPUT ------------------ -/** @gqlType */ -class SomeType { - // No fields -} - -/** @gqlField */ -export function greeting(_: SomeType, args: { name: string }): string { - return `Hello ${args.name}!`; -} - ------------------ -OUTPUT ------------------ --- SDL -- -type SomeType { - greeting(name: String!): String -} --- TypeScript -- -import { GraphQLSchema, GraphQLObjectType, GraphQLString, GraphQLNonNull } from "graphql"; -import { greeting as someTypeGreetingResolver } from "./addFieldWithArguments"; -export function getSchema(): GraphQLSchema { - const SomeTypeType: GraphQLObjectType = new GraphQLObjectType({ - name: "SomeType", - fields() { - return { - greeting: { - name: "greeting", - type: GraphQLString, - args: { - name: { - type: new GraphQLNonNull(GraphQLString) - } - }, - resolve(source, args) { - return someTypeGreetingResolver(source, args); - } - } - }; - } - }); - return new GraphQLSchema({ - types: [SomeTypeType] - }); -} diff --git a/src/tests/fixtures/extend_type/addFieldWithArguments.ts.expected.md b/src/tests/fixtures/extend_type/addFieldWithArguments.ts.expected.md new file mode 100644 index 00000000..42dab08d --- /dev/null +++ b/src/tests/fixtures/extend_type/addFieldWithArguments.ts.expected.md @@ -0,0 +1,54 @@ +## input + +```ts title="extend_type/addFieldWithArguments.ts" +/** @gqlType */ +class SomeType { + // No fields +} + +/** @gqlField */ +export function greeting(_: SomeType, args: { name: string }): string { + return `Hello ${args.name}!`; +} +``` + +## Output + +### SDL + +```graphql +type SomeType { + greeting(name: String!): String +} +``` + +### TypeScript + +```ts +import { GraphQLSchema, GraphQLObjectType, GraphQLString, GraphQLNonNull } from "graphql"; +import { greeting as someTypeGreetingResolver } from "./addFieldWithArguments"; +export function getSchema(): GraphQLSchema { + const SomeTypeType: GraphQLObjectType = new GraphQLObjectType({ + name: "SomeType", + fields() { + return { + greeting: { + name: "greeting", + type: GraphQLString, + args: { + name: { + type: new GraphQLNonNull(GraphQLString) + } + }, + resolve(source, args) { + return someTypeGreetingResolver(source, args); + } + } + }; + } + }); + return new GraphQLSchema({ + types: [SomeTypeType] + }); +} +``` \ No newline at end of file diff --git a/src/tests/fixtures/extend_type/addFieldWithDescription.ts.expected b/src/tests/fixtures/extend_type/addFieldWithDescription.ts.expected deleted file mode 100644 index e71cffcb..00000000 --- a/src/tests/fixtures/extend_type/addFieldWithDescription.ts.expected +++ /dev/null @@ -1,47 +0,0 @@ ------------------ -INPUT ------------------ -/** @gqlType */ -class SomeType { - // No fields -} - -/** - * Best field ever! - * @gqlField - */ -export function greeting(_: SomeType): string { - return "Hello world!"; -} - ------------------ -OUTPUT ------------------ --- SDL -- -type SomeType { - """Best field ever!""" - greeting: String -} --- TypeScript -- -import { GraphQLSchema, GraphQLObjectType, GraphQLString } from "graphql"; -import { greeting as someTypeGreetingResolver } from "./addFieldWithDescription"; -export function getSchema(): GraphQLSchema { - const SomeTypeType: GraphQLObjectType = new GraphQLObjectType({ - name: "SomeType", - fields() { - return { - greeting: { - description: "Best field ever!", - name: "greeting", - type: GraphQLString, - resolve(source) { - return someTypeGreetingResolver(source); - } - } - }; - } - }); - return new GraphQLSchema({ - types: [SomeTypeType] - }); -} diff --git a/src/tests/fixtures/extend_type/addFieldWithDescription.ts.expected.md b/src/tests/fixtures/extend_type/addFieldWithDescription.ts.expected.md new file mode 100644 index 00000000..b5f72761 --- /dev/null +++ b/src/tests/fixtures/extend_type/addFieldWithDescription.ts.expected.md @@ -0,0 +1,54 @@ +## input + +```ts title="extend_type/addFieldWithDescription.ts" +/** @gqlType */ +class SomeType { + // No fields +} + +/** + * Best field ever! + * @gqlField + */ +export function greeting(_: SomeType): string { + return "Hello world!"; +} +``` + +## Output + +### SDL + +```graphql +type SomeType { + """Best field ever!""" + greeting: String +} +``` + +### TypeScript + +```ts +import { GraphQLSchema, GraphQLObjectType, GraphQLString } from "graphql"; +import { greeting as someTypeGreetingResolver } from "./addFieldWithDescription"; +export function getSchema(): GraphQLSchema { + const SomeTypeType: GraphQLObjectType = new GraphQLObjectType({ + name: "SomeType", + fields() { + return { + greeting: { + description: "Best field ever!", + name: "greeting", + type: GraphQLString, + resolve(source) { + return someTypeGreetingResolver(source); + } + } + }; + } + }); + return new GraphQLSchema({ + types: [SomeTypeType] + }); +} +``` \ No newline at end of file diff --git a/src/tests/fixtures/extend_type/addRenamedFieldToSomeType.ts.expected b/src/tests/fixtures/extend_type/addRenamedFieldToSomeType.ts.expected deleted file mode 100644 index a6ccb371..00000000 --- a/src/tests/fixtures/extend_type/addRenamedFieldToSomeType.ts.expected +++ /dev/null @@ -1,42 +0,0 @@ ------------------ -INPUT ------------------ -/** @gqlType */ -class SomeType { - // No fields -} - -/** @gqlField hello */ -export function greeting(_: SomeType): string { - return "Hello world!"; -} - ------------------ -OUTPUT ------------------ --- SDL -- -type SomeType { - hello: String -} --- TypeScript -- -import { GraphQLSchema, GraphQLObjectType, GraphQLString } from "graphql"; -import { greeting as someTypeHelloResolver } from "./addRenamedFieldToSomeType"; -export function getSchema(): GraphQLSchema { - const SomeTypeType: GraphQLObjectType = new GraphQLObjectType({ - name: "SomeType", - fields() { - return { - hello: { - name: "hello", - type: GraphQLString, - resolve(source) { - return someTypeHelloResolver(source); - } - } - }; - } - }); - return new GraphQLSchema({ - types: [SomeTypeType] - }); -} diff --git a/src/tests/fixtures/extend_type/addRenamedFieldToSomeType.ts.expected.md b/src/tests/fixtures/extend_type/addRenamedFieldToSomeType.ts.expected.md new file mode 100644 index 00000000..d3533754 --- /dev/null +++ b/src/tests/fixtures/extend_type/addRenamedFieldToSomeType.ts.expected.md @@ -0,0 +1,49 @@ +## input + +```ts title="extend_type/addRenamedFieldToSomeType.ts" +/** @gqlType */ +class SomeType { + // No fields +} + +/** @gqlField hello */ +export function greeting(_: SomeType): string { + return "Hello world!"; +} +``` + +## Output + +### SDL + +```graphql +type SomeType { + hello: String +} +``` + +### TypeScript + +```ts +import { GraphQLSchema, GraphQLObjectType, GraphQLString } from "graphql"; +import { greeting as someTypeHelloResolver } from "./addRenamedFieldToSomeType"; +export function getSchema(): GraphQLSchema { + const SomeTypeType: GraphQLObjectType = new GraphQLObjectType({ + name: "SomeType", + fields() { + return { + hello: { + name: "hello", + type: GraphQLString, + resolve(source) { + return someTypeHelloResolver(source); + } + } + }; + } + }); + return new GraphQLSchema({ + types: [SomeTypeType] + }); +} +``` \ No newline at end of file diff --git a/src/tests/fixtures/extend_type/addStringFieldToSomeType.ts.expected b/src/tests/fixtures/extend_type/addStringFieldToSomeType.ts.expected deleted file mode 100644 index 7316efeb..00000000 --- a/src/tests/fixtures/extend_type/addStringFieldToSomeType.ts.expected +++ /dev/null @@ -1,42 +0,0 @@ ------------------ -INPUT ------------------ -/** @gqlType */ -class SomeType { - // No fields -} - -/** @gqlField */ -export function greeting(_: SomeType): string { - return "Hello world!"; -} - ------------------ -OUTPUT ------------------ --- SDL -- -type SomeType { - greeting: String -} --- TypeScript -- -import { GraphQLSchema, GraphQLObjectType, GraphQLString } from "graphql"; -import { greeting as someTypeGreetingResolver } from "./addStringFieldToSomeType"; -export function getSchema(): GraphQLSchema { - const SomeTypeType: GraphQLObjectType = new GraphQLObjectType({ - name: "SomeType", - fields() { - return { - greeting: { - name: "greeting", - type: GraphQLString, - resolve(source) { - return someTypeGreetingResolver(source); - } - } - }; - } - }); - return new GraphQLSchema({ - types: [SomeTypeType] - }); -} diff --git a/src/tests/fixtures/extend_type/addStringFieldToSomeType.ts.expected.md b/src/tests/fixtures/extend_type/addStringFieldToSomeType.ts.expected.md new file mode 100644 index 00000000..61b65962 --- /dev/null +++ b/src/tests/fixtures/extend_type/addStringFieldToSomeType.ts.expected.md @@ -0,0 +1,49 @@ +## input + +```ts title="extend_type/addStringFieldToSomeType.ts" +/** @gqlType */ +class SomeType { + // No fields +} + +/** @gqlField */ +export function greeting(_: SomeType): string { + return "Hello world!"; +} +``` + +## Output + +### SDL + +```graphql +type SomeType { + greeting: String +} +``` + +### TypeScript + +```ts +import { GraphQLSchema, GraphQLObjectType, GraphQLString } from "graphql"; +import { greeting as someTypeGreetingResolver } from "./addStringFieldToSomeType"; +export function getSchema(): GraphQLSchema { + const SomeTypeType: GraphQLObjectType = new GraphQLObjectType({ + name: "SomeType", + fields() { + return { + greeting: { + name: "greeting", + type: GraphQLString, + resolve(source) { + return someTypeGreetingResolver(source); + } + } + }; + } + }); + return new GraphQLSchema({ + types: [SomeTypeType] + }); +} +``` \ No newline at end of file diff --git a/src/tests/fixtures/extend_type/defaultExport.ts.expected b/src/tests/fixtures/extend_type/defaultExport.ts.expected deleted file mode 100644 index f9b8f1f1..00000000 --- a/src/tests/fixtures/extend_type/defaultExport.ts.expected +++ /dev/null @@ -1,42 +0,0 @@ ------------------ -INPUT ------------------ -/** @gqlType */ -class SomeType { - // No fields -} - -/** @gqlField */ -export default function greeting(_: SomeType): string { - return `Hello World`; -} - ------------------ -OUTPUT ------------------ --- SDL -- -type SomeType { - greeting: String -} --- TypeScript -- -import someTypeGreetingResolver from "./defaultExport"; -import { GraphQLSchema, GraphQLObjectType, GraphQLString } from "graphql"; -export function getSchema(): GraphQLSchema { - const SomeTypeType: GraphQLObjectType = new GraphQLObjectType({ - name: "SomeType", - fields() { - return { - greeting: { - name: "greeting", - type: GraphQLString, - resolve(source) { - return someTypeGreetingResolver(source); - } - } - }; - } - }); - return new GraphQLSchema({ - types: [SomeTypeType] - }); -} diff --git a/src/tests/fixtures/extend_type/defaultExport.ts.expected.md b/src/tests/fixtures/extend_type/defaultExport.ts.expected.md new file mode 100644 index 00000000..3b5322c7 --- /dev/null +++ b/src/tests/fixtures/extend_type/defaultExport.ts.expected.md @@ -0,0 +1,49 @@ +## input + +```ts title="extend_type/defaultExport.ts" +/** @gqlType */ +class SomeType { + // No fields +} + +/** @gqlField */ +export default function greeting(_: SomeType): string { + return `Hello World`; +} +``` + +## Output + +### SDL + +```graphql +type SomeType { + greeting: String +} +``` + +### TypeScript + +```ts +import someTypeGreetingResolver from "./defaultExport"; +import { GraphQLSchema, GraphQLObjectType, GraphQLString } from "graphql"; +export function getSchema(): GraphQLSchema { + const SomeTypeType: GraphQLObjectType = new GraphQLObjectType({ + name: "SomeType", + fields() { + return { + greeting: { + name: "greeting", + type: GraphQLString, + resolve(source) { + return someTypeGreetingResolver(source); + } + } + }; + } + }); + return new GraphQLSchema({ + types: [SomeTypeType] + }); +} +``` \ No newline at end of file diff --git a/src/tests/fixtures/extend_type/fieldAsArrowFunctionLet.invalid.ts.expected b/src/tests/fixtures/extend_type/fieldAsArrowFunctionLet.invalid.ts.expected deleted file mode 100644 index bb150250..00000000 --- a/src/tests/fixtures/extend_type/fieldAsArrowFunctionLet.invalid.ts.expected +++ /dev/null @@ -1,24 +0,0 @@ ------------------ -INPUT ------------------ -/** @gqlType */ -class SomeType { - // No fields -} - -/** @gqlField */ -export let greeting = (_: SomeType): string => { - return `Hello World`; -}; - ------------------ -OUTPUT ------------------ -src/tests/fixtures/extend_type/fieldAsArrowFunctionLet.invalid.ts:7:8 - error: Expected `@gqlField` arrow function to be declared as `const`. - -7 export let greeting = (_: SomeType): string => { - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -8 return `Hello World`; - ~~~~~~~~~~~~~~~~~~~~~~~ -9 }; - ~ diff --git a/src/tests/fixtures/extend_type/fieldAsArrowFunctionLet.invalid.ts.expected.md b/src/tests/fixtures/extend_type/fieldAsArrowFunctionLet.invalid.ts.expected.md new file mode 100644 index 00000000..080f1980 --- /dev/null +++ b/src/tests/fixtures/extend_type/fieldAsArrowFunctionLet.invalid.ts.expected.md @@ -0,0 +1,28 @@ +## input + +```ts title="extend_type/fieldAsArrowFunctionLet.invalid.ts" +/** @gqlType */ +class SomeType { + // No fields +} + +/** @gqlField */ +export let greeting = (_: SomeType): string => { + return `Hello World`; +}; +``` + +## Output + +### Error Report + +```text +src/tests/fixtures/extend_type/fieldAsArrowFunctionLet.invalid.ts:7:8 - error: Expected `@gqlField` arrow function to be declared as `const`. + +7 export let greeting = (_: SomeType): string => { + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +8 return `Hello World`; + ~~~~~~~~~~~~~~~~~~~~~~~ +9 }; + ~ +``` \ No newline at end of file diff --git a/src/tests/fixtures/extend_type/fieldAsArrowFunctionNotExported.invalid.ts.expected b/src/tests/fixtures/extend_type/fieldAsArrowFunctionNotExported.invalid.ts.expected deleted file mode 100644 index 8bc05a4c..00000000 --- a/src/tests/fixtures/extend_type/fieldAsArrowFunctionNotExported.invalid.ts.expected +++ /dev/null @@ -1,46 +0,0 @@ ------------------ -INPUT ------------------ -/** @gqlType */ -class SomeType { - // No fields -} - -/** @gqlField */ -const greeting = (_: SomeType): string => { - return `Hello World`; -}; - ------------------ -OUTPUT ------------------ --- Error Report -- -src/tests/fixtures/extend_type/fieldAsArrowFunctionNotExported.invalid.ts:7:7 - error: Expected `@gqlField` to be an exported top-level declaration. Grats needs to import resolver functions into its generated schema module, so the resolver function must be exported from the module. - -7 const greeting = (_: SomeType): string => { - ~~~~~~~~ - - --- Code Action: "Add export keyword to exported arrow function with @gqlField" (add-export-keyword-to-arrow-function) -- -- Original -+ Fixed - -@@ -6,3 +6,3 @@ - /** @gqlField */ -- const greeting = (_: SomeType): string => { -+ export const greeting = (_: SomeType): string => { - return `Hello World`; - --- Applied Fixes -- - * Applied fix "Add export keyword to exported arrow function with @gqlField" in grats/src/tests/fixtures/extend_type/fieldAsArrowFunctionNotExported.invalid.ts - --- Fixed Text -- -/** @gqlType */ -class SomeType { - // No fields -} - -/** @gqlField */ -export const greeting = (_: SomeType): string => { - return `Hello World`; -}; diff --git a/src/tests/fixtures/extend_type/fieldAsArrowFunctionNotExported.invalid.ts.expected.md b/src/tests/fixtures/extend_type/fieldAsArrowFunctionNotExported.invalid.ts.expected.md new file mode 100644 index 00000000..7bd9505d --- /dev/null +++ b/src/tests/fixtures/extend_type/fieldAsArrowFunctionNotExported.invalid.ts.expected.md @@ -0,0 +1,57 @@ +## input + +```ts title="extend_type/fieldAsArrowFunctionNotExported.invalid.ts" +/** @gqlType */ +class SomeType { + // No fields +} + +/** @gqlField */ +const greeting = (_: SomeType): string => { + return `Hello World`; +}; +``` + +## Output + +### Error Report + +```text +src/tests/fixtures/extend_type/fieldAsArrowFunctionNotExported.invalid.ts:7:7 - error: Expected `@gqlField` to be an exported top-level declaration. Grats needs to import resolver functions into its generated schema module, so the resolver function must be exported from the module. + +7 const greeting = (_: SomeType): string => { + ~~~~~~~~ +``` + +#### Code Action: "Add export keyword to exported arrow function with @gqlField" (add-export-keyword-to-arrow-function) + +```diff +- Original ++ Fixed + +@@ -6,3 +6,3 @@ + /** @gqlField */ +- const greeting = (_: SomeType): string => { ++ export const greeting = (_: SomeType): string => { + return `Hello World`; +``` + +#### Applied Fixes + +```text + * Applied fix "Add export keyword to exported arrow function with @gqlField" in grats/src/tests/fixtures/extend_type/fieldAsArrowFunctionNotExported.invalid.ts +``` + +#### Fixed Text + +```typescript +/** @gqlType */ +class SomeType { + // No fields +} + +/** @gqlField */ +export const greeting = (_: SomeType): string => { + return `Hello World`; +}; +``` \ No newline at end of file diff --git a/src/tests/fixtures/extend_type/fieldAsArrowFunctionVar.invalid.ts.expected b/src/tests/fixtures/extend_type/fieldAsArrowFunctionVar.invalid.ts.expected deleted file mode 100644 index 5b9983d1..00000000 --- a/src/tests/fixtures/extend_type/fieldAsArrowFunctionVar.invalid.ts.expected +++ /dev/null @@ -1,24 +0,0 @@ ------------------ -INPUT ------------------ -/** @gqlType */ -class SomeType { - // No fields -} - -/** @gqlField */ -var greeting = (_: SomeType): string => { - return `Hello World`; -}; - ------------------ -OUTPUT ------------------ -src/tests/fixtures/extend_type/fieldAsArrowFunctionVar.invalid.ts:7:1 - error: Expected `@gqlField` arrow function to be declared as `const`. - -7 var greeting = (_: SomeType): string => { - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -8 return `Hello World`; - ~~~~~~~~~~~~~~~~~~~~~~~ -9 }; - ~ diff --git a/src/tests/fixtures/extend_type/fieldAsArrowFunctionVar.invalid.ts.expected.md b/src/tests/fixtures/extend_type/fieldAsArrowFunctionVar.invalid.ts.expected.md new file mode 100644 index 00000000..368dbf55 --- /dev/null +++ b/src/tests/fixtures/extend_type/fieldAsArrowFunctionVar.invalid.ts.expected.md @@ -0,0 +1,28 @@ +## input + +```ts title="extend_type/fieldAsArrowFunctionVar.invalid.ts" +/** @gqlType */ +class SomeType { + // No fields +} + +/** @gqlField */ +var greeting = (_: SomeType): string => { + return `Hello World`; +}; +``` + +## Output + +### Error Report + +```text +src/tests/fixtures/extend_type/fieldAsArrowFunctionVar.invalid.ts:7:1 - error: Expected `@gqlField` arrow function to be declared as `const`. + +7 var greeting = (_: SomeType): string => { + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +8 return `Hello World`; + ~~~~~~~~~~~~~~~~~~~~~~~ +9 }; + ~ +``` \ No newline at end of file diff --git a/src/tests/fixtures/extend_type/fieldAsExportedArrowFunction.ts.expected b/src/tests/fixtures/extend_type/fieldAsExportedArrowFunction.ts.expected deleted file mode 100644 index c1a4b130..00000000 --- a/src/tests/fixtures/extend_type/fieldAsExportedArrowFunction.ts.expected +++ /dev/null @@ -1,42 +0,0 @@ ------------------ -INPUT ------------------ -/** @gqlType */ -class SomeType { - // No fields -} - -/** @gqlField */ -export const greeting = (_: SomeType): string => { - return `Hello World`; -}; - ------------------ -OUTPUT ------------------ --- SDL -- -type SomeType { - greeting: String -} --- TypeScript -- -import { GraphQLSchema, GraphQLObjectType, GraphQLString } from "graphql"; -import { greeting as someTypeGreetingResolver } from "./fieldAsExportedArrowFunction"; -export function getSchema(): GraphQLSchema { - const SomeTypeType: GraphQLObjectType = new GraphQLObjectType({ - name: "SomeType", - fields() { - return { - greeting: { - name: "greeting", - type: GraphQLString, - resolve(source) { - return someTypeGreetingResolver(source); - } - } - }; - } - }); - return new GraphQLSchema({ - types: [SomeTypeType] - }); -} diff --git a/src/tests/fixtures/extend_type/fieldAsExportedArrowFunction.ts.expected.md b/src/tests/fixtures/extend_type/fieldAsExportedArrowFunction.ts.expected.md new file mode 100644 index 00000000..22ded29c --- /dev/null +++ b/src/tests/fixtures/extend_type/fieldAsExportedArrowFunction.ts.expected.md @@ -0,0 +1,49 @@ +## input + +```ts title="extend_type/fieldAsExportedArrowFunction.ts" +/** @gqlType */ +class SomeType { + // No fields +} + +/** @gqlField */ +export const greeting = (_: SomeType): string => { + return `Hello World`; +}; +``` + +## Output + +### SDL + +```graphql +type SomeType { + greeting: String +} +``` + +### TypeScript + +```ts +import { GraphQLSchema, GraphQLObjectType, GraphQLString } from "graphql"; +import { greeting as someTypeGreetingResolver } from "./fieldAsExportedArrowFunction"; +export function getSchema(): GraphQLSchema { + const SomeTypeType: GraphQLObjectType = new GraphQLObjectType({ + name: "SomeType", + fields() { + return { + greeting: { + name: "greeting", + type: GraphQLString, + resolve(source) { + return someTypeGreetingResolver(source); + } + } + }; + } + }); + return new GraphQLSchema({ + types: [SomeTypeType] + }); +} +``` \ No newline at end of file diff --git a/src/tests/fixtures/extend_type/fieldAsExportedArrowFunctionPositionalArgs.ts.expected b/src/tests/fixtures/extend_type/fieldAsExportedArrowFunctionPositionalArgs.ts.expected deleted file mode 100644 index 747d9ba7..00000000 --- a/src/tests/fixtures/extend_type/fieldAsExportedArrowFunctionPositionalArgs.ts.expected +++ /dev/null @@ -1,47 +0,0 @@ ------------------ -INPUT ------------------ -/** @gqlType */ -class SomeType { - // No fields -} - -/** @gqlField */ -export const greeting = (_: SomeType, name: string): string => { - return `Hello ${name}`; -}; - ------------------ -OUTPUT ------------------ --- SDL -- -type SomeType { - greeting(name: String!): String -} --- TypeScript -- -import { GraphQLSchema, GraphQLObjectType, GraphQLString, GraphQLNonNull } from "graphql"; -import { greeting as someTypeGreetingResolver } from "./fieldAsExportedArrowFunctionPositionalArgs"; -export function getSchema(): GraphQLSchema { - const SomeTypeType: GraphQLObjectType = new GraphQLObjectType({ - name: "SomeType", - fields() { - return { - greeting: { - name: "greeting", - type: GraphQLString, - args: { - name: { - type: new GraphQLNonNull(GraphQLString) - } - }, - resolve(source, args) { - return someTypeGreetingResolver(source, args.name); - } - } - }; - } - }); - return new GraphQLSchema({ - types: [SomeTypeType] - }); -} diff --git a/src/tests/fixtures/extend_type/fieldAsExportedArrowFunctionPositionalArgs.ts.expected.md b/src/tests/fixtures/extend_type/fieldAsExportedArrowFunctionPositionalArgs.ts.expected.md new file mode 100644 index 00000000..5db5ac34 --- /dev/null +++ b/src/tests/fixtures/extend_type/fieldAsExportedArrowFunctionPositionalArgs.ts.expected.md @@ -0,0 +1,54 @@ +## input + +```ts title="extend_type/fieldAsExportedArrowFunctionPositionalArgs.ts" +/** @gqlType */ +class SomeType { + // No fields +} + +/** @gqlField */ +export const greeting = (_: SomeType, name: string): string => { + return `Hello ${name}`; +}; +``` + +## Output + +### SDL + +```graphql +type SomeType { + greeting(name: String!): String +} +``` + +### TypeScript + +```ts +import { GraphQLSchema, GraphQLObjectType, GraphQLString, GraphQLNonNull } from "graphql"; +import { greeting as someTypeGreetingResolver } from "./fieldAsExportedArrowFunctionPositionalArgs"; +export function getSchema(): GraphQLSchema { + const SomeTypeType: GraphQLObjectType = new GraphQLObjectType({ + name: "SomeType", + fields() { + return { + greeting: { + name: "greeting", + type: GraphQLString, + args: { + name: { + type: new GraphQLNonNull(GraphQLString) + } + }, + resolve(source, args) { + return someTypeGreetingResolver(source, args.name); + } + } + }; + } + }); + return new GraphQLSchema({ + types: [SomeTypeType] + }); +} +``` \ No newline at end of file diff --git a/src/tests/fixtures/extend_type/fieldAsExportedAsyncArrowFunction.ts.expected b/src/tests/fixtures/extend_type/fieldAsExportedAsyncArrowFunction.ts.expected deleted file mode 100644 index cb036e89..00000000 --- a/src/tests/fixtures/extend_type/fieldAsExportedAsyncArrowFunction.ts.expected +++ /dev/null @@ -1,42 +0,0 @@ ------------------ -INPUT ------------------ -/** @gqlType */ -class SomeType { - // No fields -} - -/** @gqlField */ -export const greeting = async (_: SomeType): Promise => { - return `Hello World`; -}; - ------------------ -OUTPUT ------------------ --- SDL -- -type SomeType { - greeting: String -} --- TypeScript -- -import { GraphQLSchema, GraphQLObjectType, GraphQLString } from "graphql"; -import { greeting as someTypeGreetingResolver } from "./fieldAsExportedAsyncArrowFunction"; -export function getSchema(): GraphQLSchema { - const SomeTypeType: GraphQLObjectType = new GraphQLObjectType({ - name: "SomeType", - fields() { - return { - greeting: { - name: "greeting", - type: GraphQLString, - resolve(source) { - return someTypeGreetingResolver(source); - } - } - }; - } - }); - return new GraphQLSchema({ - types: [SomeTypeType] - }); -} diff --git a/src/tests/fixtures/extend_type/fieldAsExportedAsyncArrowFunction.ts.expected.md b/src/tests/fixtures/extend_type/fieldAsExportedAsyncArrowFunction.ts.expected.md new file mode 100644 index 00000000..864cf2df --- /dev/null +++ b/src/tests/fixtures/extend_type/fieldAsExportedAsyncArrowFunction.ts.expected.md @@ -0,0 +1,49 @@ +## input + +```ts title="extend_type/fieldAsExportedAsyncArrowFunction.ts" +/** @gqlType */ +class SomeType { + // No fields +} + +/** @gqlField */ +export const greeting = async (_: SomeType): Promise => { + return `Hello World`; +}; +``` + +## Output + +### SDL + +```graphql +type SomeType { + greeting: String +} +``` + +### TypeScript + +```ts +import { GraphQLSchema, GraphQLObjectType, GraphQLString } from "graphql"; +import { greeting as someTypeGreetingResolver } from "./fieldAsExportedAsyncArrowFunction"; +export function getSchema(): GraphQLSchema { + const SomeTypeType: GraphQLObjectType = new GraphQLObjectType({ + name: "SomeType", + fields() { + return { + greeting: { + name: "greeting", + type: GraphQLString, + resolve(source) { + return someTypeGreetingResolver(source); + } + } + }; + } + }); + return new GraphQLSchema({ + types: [SomeTypeType] + }); +} +``` \ No newline at end of file diff --git a/src/tests/fixtures/extend_type/fieldAsExportedMultipleVariables.invalid.ts.expected b/src/tests/fixtures/extend_type/fieldAsExportedMultipleVariables.invalid.ts.expected deleted file mode 100644 index 0d710db9..00000000 --- a/src/tests/fixtures/extend_type/fieldAsExportedMultipleVariables.invalid.ts.expected +++ /dev/null @@ -1,30 +0,0 @@ ------------------ -INPUT ------------------ -/** @gqlType */ -class SomeType { - // No fields -} - -/** @gqlField */ -export const greeting = (_: SomeType): string => { - return `Hello World`; - }, - anotherGreeting = (_: SomeType): string => { - return `Hello World`; - }; - ------------------ -OUTPUT ------------------ -src/tests/fixtures/extend_type/fieldAsExportedMultipleVariables.invalid.ts:7:1 - error: Expected only one declaration when defining a `@gqlField`, found 2. - - 7 export const greeting = (_: SomeType): string => { - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - 8 return `Hello World`; - ~~~~~~~~~~~~~~~~~~~~~~~~~ -... - 11 return `Hello World`; - ~~~~~~~~~~~~~~~~~~~~~~~~~ - 12 }; - ~~~~ diff --git a/src/tests/fixtures/extend_type/fieldAsExportedMultipleVariables.invalid.ts.expected.md b/src/tests/fixtures/extend_type/fieldAsExportedMultipleVariables.invalid.ts.expected.md new file mode 100644 index 00000000..c003b9da --- /dev/null +++ b/src/tests/fixtures/extend_type/fieldAsExportedMultipleVariables.invalid.ts.expected.md @@ -0,0 +1,34 @@ +## input + +```ts title="extend_type/fieldAsExportedMultipleVariables.invalid.ts" +/** @gqlType */ +class SomeType { + // No fields +} + +/** @gqlField */ +export const greeting = (_: SomeType): string => { + return `Hello World`; + }, + anotherGreeting = (_: SomeType): string => { + return `Hello World`; + }; +``` + +## Output + +### Error Report + +```text +src/tests/fixtures/extend_type/fieldAsExportedMultipleVariables.invalid.ts:7:1 - error: Expected only one declaration when defining a `@gqlField`, found 2. + + 7 export const greeting = (_: SomeType): string => { + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + 8 return `Hello World`; + ~~~~~~~~~~~~~~~~~~~~~~~~~ +... + 11 return `Hello World`; + ~~~~~~~~~~~~~~~~~~~~~~~~~ + 12 }; + ~~~~ +``` \ No newline at end of file diff --git a/src/tests/fixtures/extend_type/fieldAsExportedNothing.invalid.ts.expected b/src/tests/fixtures/extend_type/fieldAsExportedNothing.invalid.ts.expected deleted file mode 100644 index 2090f506..00000000 --- a/src/tests/fixtures/extend_type/fieldAsExportedNothing.invalid.ts.expected +++ /dev/null @@ -1,18 +0,0 @@ ------------------ -INPUT ------------------ -/** @gqlType */ -class SomeType { - // No fields -} - -/** @gqlField */ -export const greeting; - ------------------ -OUTPUT ------------------ -src/tests/fixtures/extend_type/fieldAsExportedNothing.invalid.ts:7:1 - error: Expected `@gqlField` on variable declaration to be attached to an arrow function. - -7 export const greeting; - ~~~~~~~~~~~~~~~~~~~~~~ diff --git a/src/tests/fixtures/extend_type/fieldAsExportedNothing.invalid.ts.expected.md b/src/tests/fixtures/extend_type/fieldAsExportedNothing.invalid.ts.expected.md new file mode 100644 index 00000000..a289ddc8 --- /dev/null +++ b/src/tests/fixtures/extend_type/fieldAsExportedNothing.invalid.ts.expected.md @@ -0,0 +1,22 @@ +## input + +```ts title="extend_type/fieldAsExportedNothing.invalid.ts" +/** @gqlType */ +class SomeType { + // No fields +} + +/** @gqlField */ +export const greeting; +``` + +## Output + +### Error Report + +```text +src/tests/fixtures/extend_type/fieldAsExportedNothing.invalid.ts:7:1 - error: Expected `@gqlField` on variable declaration to be attached to an arrow function. + +7 export const greeting; + ~~~~~~~~~~~~~~~~~~~~~~ +``` \ No newline at end of file diff --git a/src/tests/fixtures/extend_type/fieldAsExportedNumber.invalid.ts.expected b/src/tests/fixtures/extend_type/fieldAsExportedNumber.invalid.ts.expected deleted file mode 100644 index 642186c6..00000000 --- a/src/tests/fixtures/extend_type/fieldAsExportedNumber.invalid.ts.expected +++ /dev/null @@ -1,18 +0,0 @@ ------------------ -INPUT ------------------ -/** @gqlType */ -class SomeType { - // No fields -} - -/** @gqlField */ -export const greeting = 10; - ------------------ -OUTPUT ------------------ -src/tests/fixtures/extend_type/fieldAsExportedNumber.invalid.ts:7:1 - error: Expected `@gqlField` on variable declaration to be attached to an arrow function. - -7 export const greeting = 10; - ~~~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/src/tests/fixtures/extend_type/fieldAsExportedNumber.invalid.ts.expected.md b/src/tests/fixtures/extend_type/fieldAsExportedNumber.invalid.ts.expected.md new file mode 100644 index 00000000..f8b11b4a --- /dev/null +++ b/src/tests/fixtures/extend_type/fieldAsExportedNumber.invalid.ts.expected.md @@ -0,0 +1,22 @@ +## input + +```ts title="extend_type/fieldAsExportedNumber.invalid.ts" +/** @gqlType */ +class SomeType { + // No fields +} + +/** @gqlField */ +export const greeting = 10; +``` + +## Output + +### Error Report + +```text +src/tests/fixtures/extend_type/fieldAsExportedNumber.invalid.ts:7:1 - error: Expected `@gqlField` on variable declaration to be attached to an arrow function. + +7 export const greeting = 10; + ~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` \ No newline at end of file diff --git a/src/tests/fixtures/extend_type/functionFieldOnTypeDefinedWithInterface.ts.expected b/src/tests/fixtures/extend_type/functionFieldOnTypeDefinedWithInterface.ts.expected deleted file mode 100644 index 90342751..00000000 --- a/src/tests/fixtures/extend_type/functionFieldOnTypeDefinedWithInterface.ts.expected +++ /dev/null @@ -1,42 +0,0 @@ ------------------ -INPUT ------------------ -// https://twitter.com/edvinwennerdahl/status/1748436186840904103 - -/** @gqlType */ -interface Cat {} - -/** @gqlField */ -export function catSound(obj: Cat): string { - return "meow"; -} - ------------------ -OUTPUT ------------------ --- SDL -- -type Cat { - catSound: String -} --- TypeScript -- -import { GraphQLSchema, GraphQLObjectType, GraphQLString } from "graphql"; -import { catSound as catCatSoundResolver } from "./functionFieldOnTypeDefinedWithInterface"; -export function getSchema(): GraphQLSchema { - const CatType: GraphQLObjectType = new GraphQLObjectType({ - name: "Cat", - fields() { - return { - catSound: { - name: "catSound", - type: GraphQLString, - resolve(source) { - return catCatSoundResolver(source); - } - } - }; - } - }); - return new GraphQLSchema({ - types: [CatType] - }); -} diff --git a/src/tests/fixtures/extend_type/functionFieldOnTypeDefinedWithInterface.ts.expected.md b/src/tests/fixtures/extend_type/functionFieldOnTypeDefinedWithInterface.ts.expected.md new file mode 100644 index 00000000..8daba666 --- /dev/null +++ b/src/tests/fixtures/extend_type/functionFieldOnTypeDefinedWithInterface.ts.expected.md @@ -0,0 +1,49 @@ +## input + +```ts title="extend_type/functionFieldOnTypeDefinedWithInterface.ts" +// https://twitter.com/edvinwennerdahl/status/1748436186840904103 + +/** @gqlType */ +interface Cat {} + +/** @gqlField */ +export function catSound(obj: Cat): string { + return "meow"; +} +``` + +## Output + +### SDL + +```graphql +type Cat { + catSound: String +} +``` + +### TypeScript + +```ts +import { GraphQLSchema, GraphQLObjectType, GraphQLString } from "graphql"; +import { catSound as catCatSoundResolver } from "./functionFieldOnTypeDefinedWithInterface"; +export function getSchema(): GraphQLSchema { + const CatType: GraphQLObjectType = new GraphQLObjectType({ + name: "Cat", + fields() { + return { + catSound: { + name: "catSound", + type: GraphQLString, + resolve(source) { + return catCatSoundResolver(source); + } + } + }; + } + }); + return new GraphQLSchema({ + types: [CatType] + }); +} +``` \ No newline at end of file diff --git a/src/tests/fixtures/extend_type/interfaceFirstArgumentType.ts.expected b/src/tests/fixtures/extend_type/interfaceFirstArgumentType.ts.expected deleted file mode 100644 index 859324eb..00000000 --- a/src/tests/fixtures/extend_type/interfaceFirstArgumentType.ts.expected +++ /dev/null @@ -1,65 +0,0 @@ ------------------ -INPUT ------------------ -/** @gqlType */ -class SomeType { - /** @gqlField */ - foo: string; -} - -/** @gqlInterface */ -interface IFoo { - /** @gqlField */ - bar: string; -} - -/** @gqlField */ -export function greeting(iFoo: IFoo): string { - return "Hello world!"; -} - ------------------ -OUTPUT ------------------ --- SDL -- -interface IFoo { - bar: String - greeting: String -} - -type SomeType { - foo: String -} --- TypeScript -- -import { GraphQLSchema, GraphQLInterfaceType, GraphQLString, GraphQLObjectType } from "graphql"; -export function getSchema(): GraphQLSchema { - const IFooType: GraphQLInterfaceType = new GraphQLInterfaceType({ - name: "IFoo", - fields() { - return { - bar: { - name: "bar", - type: GraphQLString - }, - greeting: { - name: "greeting", - type: GraphQLString - } - }; - } - }); - const SomeTypeType: GraphQLObjectType = new GraphQLObjectType({ - name: "SomeType", - fields() { - return { - foo: { - name: "foo", - type: GraphQLString - } - }; - } - }); - return new GraphQLSchema({ - types: [IFooType, SomeTypeType] - }); -} diff --git a/src/tests/fixtures/extend_type/interfaceFirstArgumentType.ts.expected.md b/src/tests/fixtures/extend_type/interfaceFirstArgumentType.ts.expected.md new file mode 100644 index 00000000..b95ebfcc --- /dev/null +++ b/src/tests/fixtures/extend_type/interfaceFirstArgumentType.ts.expected.md @@ -0,0 +1,72 @@ +## input + +```ts title="extend_type/interfaceFirstArgumentType.ts" +/** @gqlType */ +class SomeType { + /** @gqlField */ + foo: string; +} + +/** @gqlInterface */ +interface IFoo { + /** @gqlField */ + bar: string; +} + +/** @gqlField */ +export function greeting(iFoo: IFoo): string { + return "Hello world!"; +} +``` + +## Output + +### SDL + +```graphql +interface IFoo { + bar: String + greeting: String +} + +type SomeType { + foo: String +} +``` + +### TypeScript + +```ts +import { GraphQLSchema, GraphQLInterfaceType, GraphQLString, GraphQLObjectType } from "graphql"; +export function getSchema(): GraphQLSchema { + const IFooType: GraphQLInterfaceType = new GraphQLInterfaceType({ + name: "IFoo", + fields() { + return { + bar: { + name: "bar", + type: GraphQLString + }, + greeting: { + name: "greeting", + type: GraphQLString + } + }; + } + }); + const SomeTypeType: GraphQLObjectType = new GraphQLObjectType({ + name: "SomeType", + fields() { + return { + foo: { + name: "foo", + type: GraphQLString + } + }; + } + }); + return new GraphQLSchema({ + types: [IFooType, SomeTypeType] + }); +} +``` \ No newline at end of file diff --git a/src/tests/fixtures/extend_type/missingFirstArgument.invalid.ts.expected b/src/tests/fixtures/extend_type/missingFirstArgument.invalid.ts.expected deleted file mode 100644 index 5651ba8f..00000000 --- a/src/tests/fixtures/extend_type/missingFirstArgument.invalid.ts.expected +++ /dev/null @@ -1,20 +0,0 @@ ------------------ -INPUT ------------------ -/** @gqlType */ -class SomeType { - // No fields -} - -/** @gqlField */ -export function greeting(/* Without an arg we can't infer the type! */): string { - return "Hello world!"; -} - ------------------ -OUTPUT ------------------ -src/tests/fixtures/extend_type/missingFirstArgument.invalid.ts:7:17 - error: Expected `@gqlField` function to have a first argument representing the type to extend. If you don't need access to the parent object in the function, you can name the variable `_` to indicate that it is unused. e.g. `function myField(_: ParentType) {}` - -7 export function greeting(/* Without an arg we can't infer the type! */): string { - ~~~~~~~~ diff --git a/src/tests/fixtures/extend_type/missingFirstArgument.invalid.ts.expected.md b/src/tests/fixtures/extend_type/missingFirstArgument.invalid.ts.expected.md new file mode 100644 index 00000000..0926660a --- /dev/null +++ b/src/tests/fixtures/extend_type/missingFirstArgument.invalid.ts.expected.md @@ -0,0 +1,24 @@ +## input + +```ts title="extend_type/missingFirstArgument.invalid.ts" +/** @gqlType */ +class SomeType { + // No fields +} + +/** @gqlField */ +export function greeting(/* Without an arg we can't infer the type! */): string { + return "Hello world!"; +} +``` + +## Output + +### Error Report + +```text +src/tests/fixtures/extend_type/missingFirstArgument.invalid.ts:7:17 - error: Expected `@gqlField` function to have a first argument representing the type to extend. If you don't need access to the parent object in the function, you can name the variable `_` to indicate that it is unused. e.g. `function myField(_: ParentType) {}` + +7 export function greeting(/* Without an arg we can't infer the type! */): string { + ~~~~~~~~ +``` \ No newline at end of file diff --git a/src/tests/fixtures/extend_type/missingFirstArgumentType.invalid.ts.expected b/src/tests/fixtures/extend_type/missingFirstArgumentType.invalid.ts.expected deleted file mode 100644 index 23702991..00000000 --- a/src/tests/fixtures/extend_type/missingFirstArgumentType.invalid.ts.expected +++ /dev/null @@ -1,22 +0,0 @@ ------------------ -INPUT ------------------ -/** @gqlType */ -class SomeType { - // No fields -} - -/** @gqlField */ -export function greeting( - query /* Without an arg type we can't infer the GraphQL type to extend! */, -): string { - return "Hello world!"; -} - ------------------ -OUTPUT ------------------ -src/tests/fixtures/extend_type/missingFirstArgumentType.invalid.ts:8:3 - error: Expected first argument of a `@gqlField` function to have an explicit type annotation. Grats treats the first argument as the parent object of the field. Therefore Grats needs to see the _type_ of the first argument in order to know to which type/interface this field should be added. - -8 query /* Without an arg type we can't infer the GraphQL type to extend! */, - ~~~~~ diff --git a/src/tests/fixtures/extend_type/missingFirstArgumentType.invalid.ts.expected.md b/src/tests/fixtures/extend_type/missingFirstArgumentType.invalid.ts.expected.md new file mode 100644 index 00000000..964360d6 --- /dev/null +++ b/src/tests/fixtures/extend_type/missingFirstArgumentType.invalid.ts.expected.md @@ -0,0 +1,26 @@ +## input + +```ts title="extend_type/missingFirstArgumentType.invalid.ts" +/** @gqlType */ +class SomeType { + // No fields +} + +/** @gqlField */ +export function greeting( + query /* Without an arg type we can't infer the GraphQL type to extend! */, +): string { + return "Hello world!"; +} +``` + +## Output + +### Error Report + +```text +src/tests/fixtures/extend_type/missingFirstArgumentType.invalid.ts:8:3 - error: Expected first argument of a `@gqlField` function to have an explicit type annotation. Grats treats the first argument as the parent object of the field. Therefore Grats needs to see the _type_ of the first argument in order to know to which type/interface this field should be added. + +8 query /* Without an arg type we can't infer the GraphQL type to extend! */, + ~~~~~ +``` \ No newline at end of file diff --git a/src/tests/fixtures/extend_type/nonAliasFirstArgumentType.invalid.ts.expected b/src/tests/fixtures/extend_type/nonAliasFirstArgumentType.invalid.ts.expected deleted file mode 100644 index e21ea41b..00000000 --- a/src/tests/fixtures/extend_type/nonAliasFirstArgumentType.invalid.ts.expected +++ /dev/null @@ -1,20 +0,0 @@ ------------------ -INPUT ------------------ -/** @gqlType */ -class SomeType { - // No fields -} - -/** @gqlField */ -export function greeting(query: { name: string }): string { - return "Hello world!"; -} - ------------------ -OUTPUT ------------------ -src/tests/fixtures/extend_type/nonAliasFirstArgumentType.invalid.ts:7:33 - error: Expected first argument of a `@gqlField` function to be typed as a type reference. Grats treats the first argument as the parent object of the field. Therefore Grats needs to see the _type_ of the first argument in order to know to which type/interface this field should be added. - -7 export function greeting(query: { name: string }): string { - ~~~~~~~~~~~~~~~~ diff --git a/src/tests/fixtures/extend_type/nonAliasFirstArgumentType.invalid.ts.expected.md b/src/tests/fixtures/extend_type/nonAliasFirstArgumentType.invalid.ts.expected.md new file mode 100644 index 00000000..6cbfdb0d --- /dev/null +++ b/src/tests/fixtures/extend_type/nonAliasFirstArgumentType.invalid.ts.expected.md @@ -0,0 +1,24 @@ +## input + +```ts title="extend_type/nonAliasFirstArgumentType.invalid.ts" +/** @gqlType */ +class SomeType { + // No fields +} + +/** @gqlField */ +export function greeting(query: { name: string }): string { + return "Hello world!"; +} +``` + +## Output + +### Error Report + +```text +src/tests/fixtures/extend_type/nonAliasFirstArgumentType.invalid.ts:7:33 - error: Expected first argument of a `@gqlField` function to be typed as a type reference. Grats treats the first argument as the parent object of the field. Therefore Grats needs to see the _type_ of the first argument in order to know to which type/interface this field should be added. + +7 export function greeting(query: { name: string }): string { + ~~~~~~~~~~~~~~~~ +``` \ No newline at end of file diff --git a/src/tests/fixtures/extend_type/nonGQLFirstArgumentType.invalid.ts.expected b/src/tests/fixtures/extend_type/nonGQLFirstArgumentType.invalid.ts.expected deleted file mode 100644 index a9e8abeb..00000000 --- a/src/tests/fixtures/extend_type/nonGQLFirstArgumentType.invalid.ts.expected +++ /dev/null @@ -1,22 +0,0 @@ ------------------ -INPUT ------------------ -/** @gqlType */ -class SomeType { - // No fields -} - -class Foo {} - -/** @gqlField */ -export function greeting(query: Foo): string { - return "Hello world!"; -} - ------------------ -OUTPUT ------------------ -src/tests/fixtures/extend_type/nonGQLFirstArgumentType.invalid.ts:9:33 - error: Unable to resolve type reference. In order to generate a GraphQL schema, Grats needs to determine which GraphQL type is being referenced. This requires being able to resolve type references to their `@gql` annotated declaration. However this reference could not be resolved. Is it possible that this type is not defined in this file? - -9 export function greeting(query: Foo): string { - ~~~ diff --git a/src/tests/fixtures/extend_type/nonGQLFirstArgumentType.invalid.ts.expected.md b/src/tests/fixtures/extend_type/nonGQLFirstArgumentType.invalid.ts.expected.md new file mode 100644 index 00000000..fb6dfef8 --- /dev/null +++ b/src/tests/fixtures/extend_type/nonGQLFirstArgumentType.invalid.ts.expected.md @@ -0,0 +1,26 @@ +## input + +```ts title="extend_type/nonGQLFirstArgumentType.invalid.ts" +/** @gqlType */ +class SomeType { + // No fields +} + +class Foo {} + +/** @gqlField */ +export function greeting(query: Foo): string { + return "Hello world!"; +} +``` + +## Output + +### Error Report + +```text +src/tests/fixtures/extend_type/nonGQLFirstArgumentType.invalid.ts:9:33 - error: Unable to resolve type reference. In order to generate a GraphQL schema, Grats needs to determine which GraphQL type is being referenced. This requires being able to resolve type references to their `@gql` annotated declaration. However this reference could not be resolved. Is it possible that this type is not defined in this file? + +9 export function greeting(query: Foo): string { + ~~~ +``` \ No newline at end of file diff --git a/src/tests/fixtures/extend_type/notExported.invalid.ts.expected b/src/tests/fixtures/extend_type/notExported.invalid.ts.expected deleted file mode 100644 index 70742b25..00000000 --- a/src/tests/fixtures/extend_type/notExported.invalid.ts.expected +++ /dev/null @@ -1,46 +0,0 @@ ------------------ -INPUT ------------------ -/** @gqlType */ -class SomeType { - // No fields -} - -/** @gqlField */ -function greeting(_: Query): string { - return `Hello World`; -} - ------------------ -OUTPUT ------------------ --- Error Report -- -src/tests/fixtures/extend_type/notExported.invalid.ts:7:10 - error: Expected a `@gqlField` function to be a named export. Grats needs to import resolver functions into its generated schema module, so the resolver function must be a named export. - -7 function greeting(_: Query): string { - ~~~~~~~~ - - --- Code Action: "Add export keyword to function with @gqlField" (add-export-keyword-to-function) -- -- Original -+ Fixed - -@@ -6,3 +6,3 @@ - /** @gqlField */ -- function greeting(_: Query): string { -+ export function greeting(_: Query): string { - return `Hello World`; - --- Applied Fixes -- - * Applied fix "Add export keyword to function with @gqlField" in grats/src/tests/fixtures/extend_type/notExported.invalid.ts - --- Fixed Text -- -/** @gqlType */ -class SomeType { - // No fields -} - -/** @gqlField */ -export function greeting(_: Query): string { - return `Hello World`; -} diff --git a/src/tests/fixtures/extend_type/notExported.invalid.ts.expected.md b/src/tests/fixtures/extend_type/notExported.invalid.ts.expected.md new file mode 100644 index 00000000..bab85f74 --- /dev/null +++ b/src/tests/fixtures/extend_type/notExported.invalid.ts.expected.md @@ -0,0 +1,57 @@ +## input + +```ts title="extend_type/notExported.invalid.ts" +/** @gqlType */ +class SomeType { + // No fields +} + +/** @gqlField */ +function greeting(_: Query): string { + return `Hello World`; +} +``` + +## Output + +### Error Report + +```text +src/tests/fixtures/extend_type/notExported.invalid.ts:7:10 - error: Expected a `@gqlField` function to be a named export. Grats needs to import resolver functions into its generated schema module, so the resolver function must be a named export. + +7 function greeting(_: Query): string { + ~~~~~~~~ +``` + +#### Code Action: "Add export keyword to function with @gqlField" (add-export-keyword-to-function) + +```diff +- Original ++ Fixed + +@@ -6,3 +6,3 @@ + /** @gqlField */ +- function greeting(_: Query): string { ++ export function greeting(_: Query): string { + return `Hello World`; +``` + +#### Applied Fixes + +```text + * Applied fix "Add export keyword to function with @gqlField" in grats/src/tests/fixtures/extend_type/notExported.invalid.ts +``` + +#### Fixed Text + +```typescript +/** @gqlType */ +class SomeType { + // No fields +} + +/** @gqlField */ +export function greeting(_: Query): string { + return `Hello World`; +} +``` \ No newline at end of file diff --git a/src/tests/fixtures/extend_type/optionalModelType.ts.expected b/src/tests/fixtures/extend_type/optionalModelType.ts.expected deleted file mode 100644 index 5afd85ff..00000000 --- a/src/tests/fixtures/extend_type/optionalModelType.ts.expected +++ /dev/null @@ -1,49 +0,0 @@ ------------------ -INPUT ------------------ -/** @gqlType */ -class SomeType { - // No fields -} - -/** @gqlField */ -export function greeting( - // A bit odd that this is optional, but it's fine, since we will always call - // it with a non-null value - q?: SomeType, -): string { - if (q == null) { - return "Out!"; - } - return "Hello world!"; -} - ------------------ -OUTPUT ------------------ --- SDL -- -type SomeType { - greeting: String -} --- TypeScript -- -import { GraphQLSchema, GraphQLObjectType, GraphQLString } from "graphql"; -import { greeting as someTypeGreetingResolver } from "./optionalModelType"; -export function getSchema(): GraphQLSchema { - const SomeTypeType: GraphQLObjectType = new GraphQLObjectType({ - name: "SomeType", - fields() { - return { - greeting: { - name: "greeting", - type: GraphQLString, - resolve(source) { - return someTypeGreetingResolver(source); - } - } - }; - } - }); - return new GraphQLSchema({ - types: [SomeTypeType] - }); -} diff --git a/src/tests/fixtures/extend_type/optionalModelType.ts.expected.md b/src/tests/fixtures/extend_type/optionalModelType.ts.expected.md new file mode 100644 index 00000000..783f2558 --- /dev/null +++ b/src/tests/fixtures/extend_type/optionalModelType.ts.expected.md @@ -0,0 +1,56 @@ +## input + +```ts title="extend_type/optionalModelType.ts" +/** @gqlType */ +class SomeType { + // No fields +} + +/** @gqlField */ +export function greeting( + // A bit odd that this is optional, but it's fine, since we will always call + // it with a non-null value + q?: SomeType, +): string { + if (q == null) { + return "Out!"; + } + return "Hello world!"; +} +``` + +## Output + +### SDL + +```graphql +type SomeType { + greeting: String +} +``` + +### TypeScript + +```ts +import { GraphQLSchema, GraphQLObjectType, GraphQLString } from "graphql"; +import { greeting as someTypeGreetingResolver } from "./optionalModelType"; +export function getSchema(): GraphQLSchema { + const SomeTypeType: GraphQLObjectType = new GraphQLObjectType({ + name: "SomeType", + fields() { + return { + greeting: { + name: "greeting", + type: GraphQLString, + resolve(source) { + return someTypeGreetingResolver(source); + } + } + }; + } + }); + return new GraphQLSchema({ + types: [SomeTypeType] + }); +} +``` \ No newline at end of file diff --git a/src/tests/fixtures/field_definitions/DeprecatedMethodField.ts.expected b/src/tests/fixtures/field_definitions/DeprecatedMethodField.ts.expected deleted file mode 100644 index 71c4c7bc..00000000 --- a/src/tests/fixtures/field_definitions/DeprecatedMethodField.ts.expected +++ /dev/null @@ -1,40 +0,0 @@ ------------------ -INPUT ------------------ -/** @gqlType */ -export default class SomeType { - /** - * @gqlField - * @deprecated Use something else. - */ - hello(): string { - return "Hello world!"; - } -} - ------------------ -OUTPUT ------------------ --- SDL -- -type SomeType { - hello: String @deprecated(reason: "Use something else.") -} --- TypeScript -- -import { GraphQLSchema, GraphQLObjectType, GraphQLString } from "graphql"; -export function getSchema(): GraphQLSchema { - const SomeTypeType: GraphQLObjectType = new GraphQLObjectType({ - name: "SomeType", - fields() { - return { - hello: { - deprecationReason: "Use something else.", - name: "hello", - type: GraphQLString - } - }; - } - }); - return new GraphQLSchema({ - types: [SomeTypeType] - }); -} diff --git a/src/tests/fixtures/field_definitions/DeprecatedMethodField.ts.expected.md b/src/tests/fixtures/field_definitions/DeprecatedMethodField.ts.expected.md new file mode 100644 index 00000000..775bfaf9 --- /dev/null +++ b/src/tests/fixtures/field_definitions/DeprecatedMethodField.ts.expected.md @@ -0,0 +1,47 @@ +## input + +```ts title="field_definitions/DeprecatedMethodField.ts" +/** @gqlType */ +export default class SomeType { + /** + * @gqlField + * @deprecated Use something else. + */ + hello(): string { + return "Hello world!"; + } +} +``` + +## Output + +### SDL + +```graphql +type SomeType { + hello: String @deprecated(reason: "Use something else.") +} +``` + +### TypeScript + +```ts +import { GraphQLSchema, GraphQLObjectType, GraphQLString } from "graphql"; +export function getSchema(): GraphQLSchema { + const SomeTypeType: GraphQLObjectType = new GraphQLObjectType({ + name: "SomeType", + fields() { + return { + hello: { + deprecationReason: "Use something else.", + name: "hello", + type: GraphQLString + } + }; + } + }); + return new GraphQLSchema({ + types: [SomeTypeType] + }); +} +``` \ No newline at end of file diff --git a/src/tests/fixtures/field_definitions/DeprecatedPropertyField.ts.expected b/src/tests/fixtures/field_definitions/DeprecatedPropertyField.ts.expected deleted file mode 100644 index 944c38f4..00000000 --- a/src/tests/fixtures/field_definitions/DeprecatedPropertyField.ts.expected +++ /dev/null @@ -1,38 +0,0 @@ ------------------ -INPUT ------------------ -/** @gqlType */ -export default class SomeType { - /** - * @gqlField - * @deprecated Use something else. - */ - hello: string; -} - ------------------ -OUTPUT ------------------ --- SDL -- -type SomeType { - hello: String @deprecated(reason: "Use something else.") -} --- TypeScript -- -import { GraphQLSchema, GraphQLObjectType, GraphQLString } from "graphql"; -export function getSchema(): GraphQLSchema { - const SomeTypeType: GraphQLObjectType = new GraphQLObjectType({ - name: "SomeType", - fields() { - return { - hello: { - deprecationReason: "Use something else.", - name: "hello", - type: GraphQLString - } - }; - } - }); - return new GraphQLSchema({ - types: [SomeTypeType] - }); -} diff --git a/src/tests/fixtures/field_definitions/DeprecatedPropertyField.ts.expected.md b/src/tests/fixtures/field_definitions/DeprecatedPropertyField.ts.expected.md new file mode 100644 index 00000000..662c43e4 --- /dev/null +++ b/src/tests/fixtures/field_definitions/DeprecatedPropertyField.ts.expected.md @@ -0,0 +1,45 @@ +## input + +```ts title="field_definitions/DeprecatedPropertyField.ts" +/** @gqlType */ +export default class SomeType { + /** + * @gqlField + * @deprecated Use something else. + */ + hello: string; +} +``` + +## Output + +### SDL + +```graphql +type SomeType { + hello: String @deprecated(reason: "Use something else.") +} +``` + +### TypeScript + +```ts +import { GraphQLSchema, GraphQLObjectType, GraphQLString } from "graphql"; +export function getSchema(): GraphQLSchema { + const SomeTypeType: GraphQLObjectType = new GraphQLObjectType({ + name: "SomeType", + fields() { + return { + hello: { + deprecationReason: "Use something else.", + name: "hello", + type: GraphQLString + } + }; + } + }); + return new GraphQLSchema({ + types: [SomeTypeType] + }); +} +``` \ No newline at end of file diff --git a/src/tests/fixtures/field_definitions/FieldAsSetter.invalid.ts.expected b/src/tests/fixtures/field_definitions/FieldAsSetter.invalid.ts.expected deleted file mode 100644 index c5343809..00000000 --- a/src/tests/fixtures/field_definitions/FieldAsSetter.invalid.ts.expected +++ /dev/null @@ -1,24 +0,0 @@ ------------------ -INPUT ------------------ -/** @gqlType */ -export class User { - /** @gqlField */ - set getUser(args: never) { - // - } -} - ------------------ -OUTPUT ------------------ -src/tests/fixtures/field_definitions/FieldAsSetter.invalid.ts:4:3 - error: `@gqlField` can only be used on method/property declarations, signatures, function or static method declarations. - -If you think Grats should be able to infer this field, please report an issue at https://github.com/captbaritone/grats/issues. - -4 set getUser(args: never) { - ~~~~~~~~~~~~~~~~~~~~~~~~~~ -5 // - ~~~~~~ -6 } - ~~~ diff --git a/src/tests/fixtures/field_definitions/FieldAsSetter.invalid.ts.expected.md b/src/tests/fixtures/field_definitions/FieldAsSetter.invalid.ts.expected.md new file mode 100644 index 00000000..6b2e6926 --- /dev/null +++ b/src/tests/fixtures/field_definitions/FieldAsSetter.invalid.ts.expected.md @@ -0,0 +1,28 @@ +## input + +```ts title="field_definitions/FieldAsSetter.invalid.ts" +/** @gqlType */ +export class User { + /** @gqlField */ + set getUser(args: never) { + // + } +} +``` + +## Output + +### Error Report + +```text +src/tests/fixtures/field_definitions/FieldAsSetter.invalid.ts:4:3 - error: `@gqlField` can only be used on method/property declarations, signatures, function or static method declarations. + +If you think Grats should be able to infer this field, please report an issue at https://github.com/captbaritone/grats/issues. + +4 set getUser(args: never) { + ~~~~~~~~~~~~~~~~~~~~~~~~~~ +5 // + ~~~~~~ +6 } + ~~~ +``` \ No newline at end of file diff --git a/src/tests/fixtures/field_definitions/FieldAsStaticClassMethod.ts.expected b/src/tests/fixtures/field_definitions/FieldAsStaticClassMethod.ts.expected deleted file mode 100644 index 8899d648..00000000 --- a/src/tests/fixtures/field_definitions/FieldAsStaticClassMethod.ts.expected +++ /dev/null @@ -1,62 +0,0 @@ ------------------ -INPUT ------------------ -/** @gqlType */ -export class User { - /** @gqlField */ - name: string; - - /** @gqlField */ - static getUser(_: Query): User { - return new User(); - } -} - -/** @gqlType */ -type Query = unknown; - ------------------ -OUTPUT ------------------ --- SDL -- -type Query { - getUser: User -} - -type User { - name: String -} --- TypeScript -- -import { GraphQLSchema, GraphQLObjectType, GraphQLString } from "graphql"; -import { User as queryGetUserResolver } from "./FieldAsStaticClassMethod"; -export function getSchema(): GraphQLSchema { - const UserType: GraphQLObjectType = new GraphQLObjectType({ - name: "User", - fields() { - return { - name: { - name: "name", - type: GraphQLString - } - }; - } - }); - const QueryType: GraphQLObjectType = new GraphQLObjectType({ - name: "Query", - fields() { - return { - getUser: { - name: "getUser", - type: UserType, - resolve(source) { - return queryGetUserResolver.getUser(source); - } - } - }; - } - }); - return new GraphQLSchema({ - query: QueryType, - types: [QueryType, UserType] - }); -} diff --git a/src/tests/fixtures/field_definitions/FieldAsStaticClassMethod.ts.expected.md b/src/tests/fixtures/field_definitions/FieldAsStaticClassMethod.ts.expected.md new file mode 100644 index 00000000..36dcb724 --- /dev/null +++ b/src/tests/fixtures/field_definitions/FieldAsStaticClassMethod.ts.expected.md @@ -0,0 +1,69 @@ +## input + +```ts title="field_definitions/FieldAsStaticClassMethod.ts" +/** @gqlType */ +export class User { + /** @gqlField */ + name: string; + + /** @gqlField */ + static getUser(_: Query): User { + return new User(); + } +} + +/** @gqlType */ +type Query = unknown; +``` + +## Output + +### SDL + +```graphql +type Query { + getUser: User +} + +type User { + name: String +} +``` + +### TypeScript + +```ts +import { GraphQLSchema, GraphQLObjectType, GraphQLString } from "graphql"; +import { User as queryGetUserResolver } from "./FieldAsStaticClassMethod"; +export function getSchema(): GraphQLSchema { + const UserType: GraphQLObjectType = new GraphQLObjectType({ + name: "User", + fields() { + return { + name: { + name: "name", + type: GraphQLString + } + }; + } + }); + const QueryType: GraphQLObjectType = new GraphQLObjectType({ + name: "Query", + fields() { + return { + getUser: { + name: "getUser", + type: UserType, + resolve(source) { + return queryGetUserResolver.getUser(source); + } + } + }; + } + }); + return new GraphQLSchema({ + query: QueryType, + types: [QueryType, UserType] + }); +} +``` \ No newline at end of file diff --git a/src/tests/fixtures/field_definitions/FieldAsStaticClassMethodInNestedScope.invalid.ts.expected b/src/tests/fixtures/field_definitions/FieldAsStaticClassMethodInNestedScope.invalid.ts.expected deleted file mode 100644 index 1d2c99f3..00000000 --- a/src/tests/fixtures/field_definitions/FieldAsStaticClassMethodInNestedScope.invalid.ts.expected +++ /dev/null @@ -1,31 +0,0 @@ ------------------ -INPUT ------------------ -function main() { - /** @gqlType */ - class User { - /** @gqlField */ - name: string; - - /** @gqlField */ - static getUser(_: Query): User { - return new User(); - } - } -} - -/** @gqlType */ -type Query = unknown; - ------------------ -OUTPUT ------------------ -src/tests/fixtures/field_definitions/FieldAsStaticClassMethodInNestedScope.invalid.ts:3:9 - error: Expected class with a static `@gqlField` method to be a top-level declaration. Grats needs to import resolver methods into its generated schema module, so the resolver's class must be an exported. - -3 class User { - ~~~~ - - src/tests/fixtures/field_definitions/FieldAsStaticClassMethodInNestedScope.invalid.ts:7:9 - 7 /** @gqlField */ - ~~~~~~~~~~ - Field defined here diff --git a/src/tests/fixtures/field_definitions/FieldAsStaticClassMethodInNestedScope.invalid.ts.expected.md b/src/tests/fixtures/field_definitions/FieldAsStaticClassMethodInNestedScope.invalid.ts.expected.md new file mode 100644 index 00000000..dbcb575d --- /dev/null +++ b/src/tests/fixtures/field_definitions/FieldAsStaticClassMethodInNestedScope.invalid.ts.expected.md @@ -0,0 +1,35 @@ +## input + +```ts title="field_definitions/FieldAsStaticClassMethodInNestedScope.invalid.ts" +function main() { + /** @gqlType */ + class User { + /** @gqlField */ + name: string; + + /** @gqlField */ + static getUser(_: Query): User { + return new User(); + } + } +} + +/** @gqlType */ +type Query = unknown; +``` + +## Output + +### Error Report + +```text +src/tests/fixtures/field_definitions/FieldAsStaticClassMethodInNestedScope.invalid.ts:3:9 - error: Expected class with a static `@gqlField` method to be a top-level declaration. Grats needs to import resolver methods into its generated schema module, so the resolver's class must be an exported. + +3 class User { + ~~~~ + + src/tests/fixtures/field_definitions/FieldAsStaticClassMethodInNestedScope.invalid.ts:7:9 + 7 /** @gqlField */ + ~~~~~~~~~~ + Field defined here +``` \ No newline at end of file diff --git a/src/tests/fixtures/field_definitions/FieldAsStaticClassMethodInNestedScopeButExported.invalid.ts.expected b/src/tests/fixtures/field_definitions/FieldAsStaticClassMethodInNestedScopeButExported.invalid.ts.expected deleted file mode 100644 index 3e6bdf34..00000000 --- a/src/tests/fixtures/field_definitions/FieldAsStaticClassMethodInNestedScopeButExported.invalid.ts.expected +++ /dev/null @@ -1,31 +0,0 @@ ------------------ -INPUT ------------------ -function main() { - /** @gqlType */ - export class User { - /** @gqlField */ - name: string; - - /** @gqlField */ - static getUser(_: Query): User { - return new User(); - } - } -} - -/** @gqlType */ -type Query = unknown; - ------------------ -OUTPUT ------------------ -src/tests/fixtures/field_definitions/FieldAsStaticClassMethodInNestedScopeButExported.invalid.ts:3:16 - error: Expected class with a static `@gqlField` method to be a top-level declaration. Grats needs to import resolver methods into its generated schema module, so the resolver's class must be an exported. - -3 export class User { - ~~~~ - - src/tests/fixtures/field_definitions/FieldAsStaticClassMethodInNestedScopeButExported.invalid.ts:7:9 - 7 /** @gqlField */ - ~~~~~~~~~~ - Field defined here diff --git a/src/tests/fixtures/field_definitions/FieldAsStaticClassMethodInNestedScopeButExported.invalid.ts.expected.md b/src/tests/fixtures/field_definitions/FieldAsStaticClassMethodInNestedScopeButExported.invalid.ts.expected.md new file mode 100644 index 00000000..7c996228 --- /dev/null +++ b/src/tests/fixtures/field_definitions/FieldAsStaticClassMethodInNestedScopeButExported.invalid.ts.expected.md @@ -0,0 +1,35 @@ +## input + +```ts title="field_definitions/FieldAsStaticClassMethodInNestedScopeButExported.invalid.ts" +function main() { + /** @gqlType */ + export class User { + /** @gqlField */ + name: string; + + /** @gqlField */ + static getUser(_: Query): User { + return new User(); + } + } +} + +/** @gqlType */ +type Query = unknown; +``` + +## Output + +### Error Report + +```text +src/tests/fixtures/field_definitions/FieldAsStaticClassMethodInNestedScopeButExported.invalid.ts:3:16 - error: Expected class with a static `@gqlField` method to be a top-level declaration. Grats needs to import resolver methods into its generated schema module, so the resolver's class must be an exported. + +3 export class User { + ~~~~ + + src/tests/fixtures/field_definitions/FieldAsStaticClassMethodInNestedScopeButExported.invalid.ts:7:9 + 7 /** @gqlField */ + ~~~~~~~~~~ + Field defined here +``` \ No newline at end of file diff --git a/src/tests/fixtures/field_definitions/FieldAsStaticClassMethodNotExported.invalid.ts.expected b/src/tests/fixtures/field_definitions/FieldAsStaticClassMethodNotExported.invalid.ts.expected deleted file mode 100644 index 90950677..00000000 --- a/src/tests/fixtures/field_definitions/FieldAsStaticClassMethodNotExported.invalid.ts.expected +++ /dev/null @@ -1,58 +0,0 @@ ------------------ -INPUT ------------------ -/** @gqlType */ -class User { - /** @gqlField */ - name: string; - - /** @gqlField */ - static getUser(_: Query): User { - return new User(); - } -} - -/** @gqlType */ -type Query = unknown; - ------------------ -OUTPUT ------------------ --- Error Report -- -src/tests/fixtures/field_definitions/FieldAsStaticClassMethodNotExported.invalid.ts:2:7 - error: Expected `@gqlField` static method's class to be exported. Grats needs to import resolvers into its generated schema module, so the resolver class must be an exported. - -2 class User { - ~~~~ - - src/tests/fixtures/field_definitions/FieldAsStaticClassMethodNotExported.invalid.ts:6:7 - 6 /** @gqlField */ - ~~~~~~~~~~ - Field defined here - --- Code Action: "Add export keyword to class with static @gqlField" (add-export-keyword-to-class) -- -- Original -+ Fixed - -@@ -1,3 +1,3 @@ - /** @gqlType */ -- class User { -+ export class User { - /** @gqlField */ - --- Applied Fixes -- - * Applied fix "Add export keyword to class with static @gqlField" in grats/src/tests/fixtures/field_definitions/FieldAsStaticClassMethodNotExported.invalid.ts - --- Fixed Text -- -/** @gqlType */ -export class User { - /** @gqlField */ - name: string; - - /** @gqlField */ - static getUser(_: Query): User { - return new User(); - } -} - -/** @gqlType */ -type Query = unknown; diff --git a/src/tests/fixtures/field_definitions/FieldAsStaticClassMethodNotExported.invalid.ts.expected.md b/src/tests/fixtures/field_definitions/FieldAsStaticClassMethodNotExported.invalid.ts.expected.md new file mode 100644 index 00000000..22593d8a --- /dev/null +++ b/src/tests/fixtures/field_definitions/FieldAsStaticClassMethodNotExported.invalid.ts.expected.md @@ -0,0 +1,70 @@ +## input + +```ts title="field_definitions/FieldAsStaticClassMethodNotExported.invalid.ts" +/** @gqlType */ +class User { + /** @gqlField */ + name: string; + + /** @gqlField */ + static getUser(_: Query): User { + return new User(); + } +} + +/** @gqlType */ +type Query = unknown; +``` + +## Output + +### Error Report + +```text +src/tests/fixtures/field_definitions/FieldAsStaticClassMethodNotExported.invalid.ts:2:7 - error: Expected `@gqlField` static method's class to be exported. Grats needs to import resolvers into its generated schema module, so the resolver class must be an exported. + +2 class User { + ~~~~ + + src/tests/fixtures/field_definitions/FieldAsStaticClassMethodNotExported.invalid.ts:6:7 + 6 /** @gqlField */ + ~~~~~~~~~~ + Field defined here +``` + +#### Code Action: "Add export keyword to class with static @gqlField" (add-export-keyword-to-class) + +```diff +- Original ++ Fixed + +@@ -1,3 +1,3 @@ + /** @gqlType */ +- class User { ++ export class User { + /** @gqlField */ +``` + +#### Applied Fixes + +```text + * Applied fix "Add export keyword to class with static @gqlField" in grats/src/tests/fixtures/field_definitions/FieldAsStaticClassMethodNotExported.invalid.ts +``` + +#### Fixed Text + +```typescript +/** @gqlType */ +export class User { + /** @gqlField */ + name: string; + + /** @gqlField */ + static getUser(_: Query): User { + return new User(); + } +} + +/** @gqlType */ +type Query = unknown; +``` \ No newline at end of file diff --git a/src/tests/fixtures/field_definitions/FieldAsStaticClassMethodOnNonGqlClass.ts.expected b/src/tests/fixtures/field_definitions/FieldAsStaticClassMethodOnNonGqlClass.ts.expected deleted file mode 100644 index 34426b2b..00000000 --- a/src/tests/fixtures/field_definitions/FieldAsStaticClassMethodOnNonGqlClass.ts.expected +++ /dev/null @@ -1,43 +0,0 @@ ------------------ -INPUT ------------------ -export class SomeClass { - /** @gqlField */ - static greet(_: Query): string { - return "Hello, world!"; - } -} - -/** @gqlType */ -type Query = unknown; - ------------------ -OUTPUT ------------------ --- SDL -- -type Query { - greet: String -} --- TypeScript -- -import { GraphQLSchema, GraphQLObjectType, GraphQLString } from "graphql"; -import { SomeClass as queryGreetResolver } from "./FieldAsStaticClassMethodOnNonGqlClass"; -export function getSchema(): GraphQLSchema { - const QueryType: GraphQLObjectType = new GraphQLObjectType({ - name: "Query", - fields() { - return { - greet: { - name: "greet", - type: GraphQLString, - resolve(source) { - return queryGreetResolver.greet(source); - } - } - }; - } - }); - return new GraphQLSchema({ - query: QueryType, - types: [QueryType] - }); -} diff --git a/src/tests/fixtures/field_definitions/FieldAsStaticClassMethodOnNonGqlClass.ts.expected.md b/src/tests/fixtures/field_definitions/FieldAsStaticClassMethodOnNonGqlClass.ts.expected.md new file mode 100644 index 00000000..ca5b5bb3 --- /dev/null +++ b/src/tests/fixtures/field_definitions/FieldAsStaticClassMethodOnNonGqlClass.ts.expected.md @@ -0,0 +1,50 @@ +## input + +```ts title="field_definitions/FieldAsStaticClassMethodOnNonGqlClass.ts" +export class SomeClass { + /** @gqlField */ + static greet(_: Query): string { + return "Hello, world!"; + } +} + +/** @gqlType */ +type Query = unknown; +``` + +## Output + +### SDL + +```graphql +type Query { + greet: String +} +``` + +### TypeScript + +```ts +import { GraphQLSchema, GraphQLObjectType, GraphQLString } from "graphql"; +import { SomeClass as queryGreetResolver } from "./FieldAsStaticClassMethodOnNonGqlClass"; +export function getSchema(): GraphQLSchema { + const QueryType: GraphQLObjectType = new GraphQLObjectType({ + name: "Query", + fields() { + return { + greet: { + name: "greet", + type: GraphQLString, + resolve(source) { + return queryGreetResolver.greet(source); + } + } + }; + } + }); + return new GraphQLSchema({ + query: QueryType, + types: [QueryType] + }); +} +``` \ No newline at end of file diff --git a/src/tests/fixtures/field_definitions/FieldAsStaticClassMethodOnUnnamedNonGqlClass.ts.expected b/src/tests/fixtures/field_definitions/FieldAsStaticClassMethodOnUnnamedNonGqlClass.ts.expected deleted file mode 100644 index 2017754c..00000000 --- a/src/tests/fixtures/field_definitions/FieldAsStaticClassMethodOnUnnamedNonGqlClass.ts.expected +++ /dev/null @@ -1,43 +0,0 @@ ------------------ -INPUT ------------------ -export default class { - /** @gqlField */ - static greet(_: Query): string { - return "Hello, world!"; - } -} - -/** @gqlType */ -type Query = unknown; - ------------------ -OUTPUT ------------------ --- SDL -- -type Query { - greet: String -} --- TypeScript -- -import queryGreetResolver from "./FieldAsStaticClassMethodOnUnnamedNonGqlClass"; -import { GraphQLSchema, GraphQLObjectType, GraphQLString } from "graphql"; -export function getSchema(): GraphQLSchema { - const QueryType: GraphQLObjectType = new GraphQLObjectType({ - name: "Query", - fields() { - return { - greet: { - name: "greet", - type: GraphQLString, - resolve(source) { - return queryGreetResolver.greet(source); - } - } - }; - } - }); - return new GraphQLSchema({ - query: QueryType, - types: [QueryType] - }); -} diff --git a/src/tests/fixtures/field_definitions/FieldAsStaticClassMethodOnUnnamedNonGqlClass.ts.expected.md b/src/tests/fixtures/field_definitions/FieldAsStaticClassMethodOnUnnamedNonGqlClass.ts.expected.md new file mode 100644 index 00000000..3a457161 --- /dev/null +++ b/src/tests/fixtures/field_definitions/FieldAsStaticClassMethodOnUnnamedNonGqlClass.ts.expected.md @@ -0,0 +1,50 @@ +## input + +```ts title="field_definitions/FieldAsStaticClassMethodOnUnnamedNonGqlClass.ts" +export default class { + /** @gqlField */ + static greet(_: Query): string { + return "Hello, world!"; + } +} + +/** @gqlType */ +type Query = unknown; +``` + +## Output + +### SDL + +```graphql +type Query { + greet: String +} +``` + +### TypeScript + +```ts +import queryGreetResolver from "./FieldAsStaticClassMethodOnUnnamedNonGqlClass"; +import { GraphQLSchema, GraphQLObjectType, GraphQLString } from "graphql"; +export function getSchema(): GraphQLSchema { + const QueryType: GraphQLObjectType = new GraphQLObjectType({ + name: "Query", + fields() { + return { + greet: { + name: "greet", + type: GraphQLString, + resolve(source) { + return queryGreetResolver.greet(source); + } + } + }; + } + }); + return new GraphQLSchema({ + query: QueryType, + types: [QueryType] + }); +} +``` \ No newline at end of file diff --git a/src/tests/fixtures/field_definitions/FieldAsStaticClassMethodWithClassAsDefaultExport.ts.expected b/src/tests/fixtures/field_definitions/FieldAsStaticClassMethodWithClassAsDefaultExport.ts.expected deleted file mode 100644 index 16364980..00000000 --- a/src/tests/fixtures/field_definitions/FieldAsStaticClassMethodWithClassAsDefaultExport.ts.expected +++ /dev/null @@ -1,62 +0,0 @@ ------------------ -INPUT ------------------ -/** @gqlType */ -export default class User { - /** @gqlField */ - name: string; - - /** @gqlField */ - static getUser(_: Query): User { - return new User(); - } -} - -/** @gqlType */ -type Query = unknown; - ------------------ -OUTPUT ------------------ --- SDL -- -type Query { - getUser: User -} - -type User { - name: String -} --- TypeScript -- -import queryGetUserResolver from "./FieldAsStaticClassMethodWithClassAsDefaultExport"; -import { GraphQLSchema, GraphQLObjectType, GraphQLString } from "graphql"; -export function getSchema(): GraphQLSchema { - const UserType: GraphQLObjectType = new GraphQLObjectType({ - name: "User", - fields() { - return { - name: { - name: "name", - type: GraphQLString - } - }; - } - }); - const QueryType: GraphQLObjectType = new GraphQLObjectType({ - name: "Query", - fields() { - return { - getUser: { - name: "getUser", - type: UserType, - resolve(source) { - return queryGetUserResolver.getUser(source); - } - } - }; - } - }); - return new GraphQLSchema({ - query: QueryType, - types: [QueryType, UserType] - }); -} diff --git a/src/tests/fixtures/field_definitions/FieldAsStaticClassMethodWithClassAsDefaultExport.ts.expected.md b/src/tests/fixtures/field_definitions/FieldAsStaticClassMethodWithClassAsDefaultExport.ts.expected.md new file mode 100644 index 00000000..b01bfc0f --- /dev/null +++ b/src/tests/fixtures/field_definitions/FieldAsStaticClassMethodWithClassAsDefaultExport.ts.expected.md @@ -0,0 +1,69 @@ +## input + +```ts title="field_definitions/FieldAsStaticClassMethodWithClassAsDefaultExport.ts" +/** @gqlType */ +export default class User { + /** @gqlField */ + name: string; + + /** @gqlField */ + static getUser(_: Query): User { + return new User(); + } +} + +/** @gqlType */ +type Query = unknown; +``` + +## Output + +### SDL + +```graphql +type Query { + getUser: User +} + +type User { + name: String +} +``` + +### TypeScript + +```ts +import queryGetUserResolver from "./FieldAsStaticClassMethodWithClassAsDefaultExport"; +import { GraphQLSchema, GraphQLObjectType, GraphQLString } from "graphql"; +export function getSchema(): GraphQLSchema { + const UserType: GraphQLObjectType = new GraphQLObjectType({ + name: "User", + fields() { + return { + name: { + name: "name", + type: GraphQLString + } + }; + } + }); + const QueryType: GraphQLObjectType = new GraphQLObjectType({ + name: "Query", + fields() { + return { + getUser: { + name: "getUser", + type: UserType, + resolve(source) { + return queryGetUserResolver.getUser(source); + } + } + }; + } + }); + return new GraphQLSchema({ + query: QueryType, + types: [QueryType, UserType] + }); +} +``` \ No newline at end of file diff --git a/src/tests/fixtures/field_definitions/FieldDefinedOnNonGqlType.invalid.ts.expected b/src/tests/fixtures/field_definitions/FieldDefinedOnNonGqlType.invalid.ts.expected deleted file mode 100644 index 853bcf85..00000000 --- a/src/tests/fixtures/field_definitions/FieldDefinedOnNonGqlType.invalid.ts.expected +++ /dev/null @@ -1,15 +0,0 @@ ------------------ -INPUT ------------------ -class Foo { - /** @gqlField */ - field: string; -} - ------------------ -OUTPUT ------------------ -src/tests/fixtures/field_definitions/FieldDefinedOnNonGqlType.invalid.ts:2:8 - error: Unexpected `@gqlField`. The parent construct must be either a `@gqlType` or `@gqlInterface` tag. Are you missing one of these tags? - -2 /** @gqlField */ - ~~~~~~~~ diff --git a/src/tests/fixtures/field_definitions/FieldDefinedOnNonGqlType.invalid.ts.expected.md b/src/tests/fixtures/field_definitions/FieldDefinedOnNonGqlType.invalid.ts.expected.md new file mode 100644 index 00000000..353e5a08 --- /dev/null +++ b/src/tests/fixtures/field_definitions/FieldDefinedOnNonGqlType.invalid.ts.expected.md @@ -0,0 +1,19 @@ +## input + +```ts title="field_definitions/FieldDefinedOnNonGqlType.invalid.ts" +class Foo { + /** @gqlField */ + field: string; +} +``` + +## Output + +### Error Report + +```text +src/tests/fixtures/field_definitions/FieldDefinedOnNonGqlType.invalid.ts:2:8 - error: Unexpected `@gqlField`. The parent construct must be either a `@gqlType` or `@gqlInterface` tag. Are you missing one of these tags? + +2 /** @gqlField */ + ~~~~~~~~ +``` \ No newline at end of file diff --git a/src/tests/fixtures/field_definitions/FieldOnArbitraryParam.invalid.ts.expected b/src/tests/fixtures/field_definitions/FieldOnArbitraryParam.invalid.ts.expected deleted file mode 100644 index bfea2dc1..00000000 --- a/src/tests/fixtures/field_definitions/FieldOnArbitraryParam.invalid.ts.expected +++ /dev/null @@ -1,19 +0,0 @@ ------------------ -INPUT ------------------ -class Foo { - someMethod( - /** @gqlField */ - foo: string, - ): void {} -} - ------------------ -OUTPUT ------------------ -src/tests/fixtures/field_definitions/FieldOnArbitraryParam.invalid.ts:4:5 - error: `@gqlField` can only be used on method/property declarations, signatures, function or static method declarations. - -If you think Grats should be able to infer this field, please report an issue at https://github.com/captbaritone/grats/issues. - -4 foo: string, - ~~~~~~~~~~~ diff --git a/src/tests/fixtures/field_definitions/FieldOnArbitraryParam.invalid.ts.expected.md b/src/tests/fixtures/field_definitions/FieldOnArbitraryParam.invalid.ts.expected.md new file mode 100644 index 00000000..111d3446 --- /dev/null +++ b/src/tests/fixtures/field_definitions/FieldOnArbitraryParam.invalid.ts.expected.md @@ -0,0 +1,23 @@ +## input + +```ts title="field_definitions/FieldOnArbitraryParam.invalid.ts" +class Foo { + someMethod( + /** @gqlField */ + foo: string, + ): void {} +} +``` + +## Output + +### Error Report + +```text +src/tests/fixtures/field_definitions/FieldOnArbitraryParam.invalid.ts:4:5 - error: `@gqlField` can only be used on method/property declarations, signatures, function or static method declarations. + +If you think Grats should be able to infer this field, please report an issue at https://github.com/captbaritone/grats/issues. + +4 foo: string, + ~~~~~~~~~~~ +``` \ No newline at end of file diff --git a/src/tests/fixtures/field_definitions/FieldTagOnIncorrectNode.invalid.ts.expected b/src/tests/fixtures/field_definitions/FieldTagOnIncorrectNode.invalid.ts.expected deleted file mode 100644 index 54cf688a..00000000 --- a/src/tests/fixtures/field_definitions/FieldTagOnIncorrectNode.invalid.ts.expected +++ /dev/null @@ -1,23 +0,0 @@ ------------------ -INPUT ------------------ -class SomeType { - /** @gqlField */ - constructor() { - // - } -} - ------------------ -OUTPUT ------------------ -src/tests/fixtures/field_definitions/FieldTagOnIncorrectNode.invalid.ts:3:3 - error: `@gqlField` can only be used on method/property declarations, signatures, function or static method declarations. - -If you think Grats should be able to infer this field, please report an issue at https://github.com/captbaritone/grats/issues. - -3 constructor() { - ~~~~~~~~~~~~~~~ -4 // - ~~~~~~ -5 } - ~~~ diff --git a/src/tests/fixtures/field_definitions/FieldTagOnIncorrectNode.invalid.ts.expected.md b/src/tests/fixtures/field_definitions/FieldTagOnIncorrectNode.invalid.ts.expected.md new file mode 100644 index 00000000..39298822 --- /dev/null +++ b/src/tests/fixtures/field_definitions/FieldTagOnIncorrectNode.invalid.ts.expected.md @@ -0,0 +1,27 @@ +## input + +```ts title="field_definitions/FieldTagOnIncorrectNode.invalid.ts" +class SomeType { + /** @gqlField */ + constructor() { + // + } +} +``` + +## Output + +### Error Report + +```text +src/tests/fixtures/field_definitions/FieldTagOnIncorrectNode.invalid.ts:3:3 - error: `@gqlField` can only be used on method/property declarations, signatures, function or static method declarations. + +If you think Grats should be able to infer this field, please report an issue at https://github.com/captbaritone/grats/issues. + +3 constructor() { + ~~~~~~~~~~~~~~~ +4 // + ~~~~~~ +5 } + ~~~ +``` \ No newline at end of file diff --git a/src/tests/fixtures/field_definitions/FiledWithUnionOfMultipleTypes.invalid.ts.expected b/src/tests/fixtures/field_definitions/FiledWithUnionOfMultipleTypes.invalid.ts.expected deleted file mode 100644 index 5d0ff12c..00000000 --- a/src/tests/fixtures/field_definitions/FiledWithUnionOfMultipleTypes.invalid.ts.expected +++ /dev/null @@ -1,23 +0,0 @@ ------------------ -INPUT ------------------ -/** @gqlType */ -export default class SomeType { - /** @gqlField */ - hello(): string | boolean { - return "Hello world!"; - } -} - ------------------ -OUTPUT ------------------ -src/tests/fixtures/field_definitions/FiledWithUnionOfMultipleTypes.invalid.ts:4:12 - error: Expected exactly one non-nullish type. GraphQL does not support fields returning an arbitrary union of types. Consider defining an explicit `@gqlUnion` union type and returning that. - -4 hello(): string | boolean { - ~~~~~~ - - src/tests/fixtures/field_definitions/FiledWithUnionOfMultipleTypes.invalid.ts:4:21 - 4 hello(): string | boolean { - ~~~~~~~ - Other non-nullish type diff --git a/src/tests/fixtures/field_definitions/FiledWithUnionOfMultipleTypes.invalid.ts.expected.md b/src/tests/fixtures/field_definitions/FiledWithUnionOfMultipleTypes.invalid.ts.expected.md new file mode 100644 index 00000000..120695c4 --- /dev/null +++ b/src/tests/fixtures/field_definitions/FiledWithUnionOfMultipleTypes.invalid.ts.expected.md @@ -0,0 +1,27 @@ +## input + +```ts title="field_definitions/FiledWithUnionOfMultipleTypes.invalid.ts" +/** @gqlType */ +export default class SomeType { + /** @gqlField */ + hello(): string | boolean { + return "Hello world!"; + } +} +``` + +## Output + +### Error Report + +```text +src/tests/fixtures/field_definitions/FiledWithUnionOfMultipleTypes.invalid.ts:4:12 - error: Expected exactly one non-nullish type. GraphQL does not support fields returning an arbitrary union of types. Consider defining an explicit `@gqlUnion` union type and returning that. + +4 hello(): string | boolean { + ~~~~~~ + + src/tests/fixtures/field_definitions/FiledWithUnionOfMultipleTypes.invalid.ts:4:21 + 4 hello(): string | boolean { + ~~~~~~~ + Other non-nullish type +``` \ No newline at end of file diff --git a/src/tests/fixtures/field_definitions/GetAcessorField.ts.expected b/src/tests/fixtures/field_definitions/GetAcessorField.ts.expected deleted file mode 100644 index d7377ce5..00000000 --- a/src/tests/fixtures/field_definitions/GetAcessorField.ts.expected +++ /dev/null @@ -1,36 +0,0 @@ ------------------ -INPUT ------------------ -/** @gqlType */ -export default class SomeType { - /** @gqlField */ - get hello(): string { - return "Hello world!"; - } -} - ------------------ -OUTPUT ------------------ --- SDL -- -type SomeType { - hello: String -} --- TypeScript -- -import { GraphQLSchema, GraphQLObjectType, GraphQLString } from "graphql"; -export function getSchema(): GraphQLSchema { - const SomeTypeType: GraphQLObjectType = new GraphQLObjectType({ - name: "SomeType", - fields() { - return { - hello: { - name: "hello", - type: GraphQLString - } - }; - } - }); - return new GraphQLSchema({ - types: [SomeTypeType] - }); -} diff --git a/src/tests/fixtures/field_definitions/GetAcessorField.ts.expected.md b/src/tests/fixtures/field_definitions/GetAcessorField.ts.expected.md new file mode 100644 index 00000000..fadb43b3 --- /dev/null +++ b/src/tests/fixtures/field_definitions/GetAcessorField.ts.expected.md @@ -0,0 +1,43 @@ +## input + +```ts title="field_definitions/GetAcessorField.ts" +/** @gqlType */ +export default class SomeType { + /** @gqlField */ + get hello(): string { + return "Hello world!"; + } +} +``` + +## Output + +### SDL + +```graphql +type SomeType { + hello: String +} +``` + +### TypeScript + +```ts +import { GraphQLSchema, GraphQLObjectType, GraphQLString } from "graphql"; +export function getSchema(): GraphQLSchema { + const SomeTypeType: GraphQLObjectType = new GraphQLObjectType({ + name: "SomeType", + fields() { + return { + hello: { + name: "hello", + type: GraphQLString + } + }; + } + }); + return new GraphQLSchema({ + types: [SomeTypeType] + }); +} +``` \ No newline at end of file diff --git a/src/tests/fixtures/field_definitions/MethodFieldMissingType.invalid.ts.expected b/src/tests/fixtures/field_definitions/MethodFieldMissingType.invalid.ts.expected deleted file mode 100644 index 9b3d6070..00000000 --- a/src/tests/fixtures/field_definitions/MethodFieldMissingType.invalid.ts.expected +++ /dev/null @@ -1,18 +0,0 @@ ------------------ -INPUT ------------------ -/** @gqlType */ -class SomeType { - /** @gqlField */ - someMethodField() { - return "Hello world!"; - } -} - ------------------ -OUTPUT ------------------ -src/tests/fixtures/field_definitions/MethodFieldMissingType.invalid.ts:4:3 - error: Expected GraphQL field methods to have an explicitly defined return type. Grats needs to be able to see the type of the field to generate its type in the GraphQL schema. - -4 someMethodField() { - ~~~~~~~~~~~~~~~ diff --git a/src/tests/fixtures/field_definitions/MethodFieldMissingType.invalid.ts.expected.md b/src/tests/fixtures/field_definitions/MethodFieldMissingType.invalid.ts.expected.md new file mode 100644 index 00000000..99fa9159 --- /dev/null +++ b/src/tests/fixtures/field_definitions/MethodFieldMissingType.invalid.ts.expected.md @@ -0,0 +1,22 @@ +## input + +```ts title="field_definitions/MethodFieldMissingType.invalid.ts" +/** @gqlType */ +class SomeType { + /** @gqlField */ + someMethodField() { + return "Hello world!"; + } +} +``` + +## Output + +### Error Report + +```text +src/tests/fixtures/field_definitions/MethodFieldMissingType.invalid.ts:4:3 - error: Expected GraphQL field methods to have an explicitly defined return type. Grats needs to be able to see the type of the field to generate its type in the GraphQL schema. + +4 someMethodField() { + ~~~~~~~~~~~~~~~ +``` \ No newline at end of file diff --git a/src/tests/fixtures/field_definitions/MethodSignatureOnInterface.ts.expected b/src/tests/fixtures/field_definitions/MethodSignatureOnInterface.ts.expected deleted file mode 100644 index 2137e0aa..00000000 --- a/src/tests/fixtures/field_definitions/MethodSignatureOnInterface.ts.expected +++ /dev/null @@ -1,34 +0,0 @@ ------------------ -INPUT ------------------ -/** @gqlInterface */ -interface ICarly { - /** @gqlField */ - name(): string; -} - ------------------ -OUTPUT ------------------ --- SDL -- -interface ICarly { - name: String -} --- TypeScript -- -import { GraphQLSchema, GraphQLInterfaceType, GraphQLString } from "graphql"; -export function getSchema(): GraphQLSchema { - const ICarlyType: GraphQLInterfaceType = new GraphQLInterfaceType({ - name: "ICarly", - fields() { - return { - name: { - name: "name", - type: GraphQLString - } - }; - } - }); - return new GraphQLSchema({ - types: [ICarlyType] - }); -} diff --git a/src/tests/fixtures/field_definitions/MethodSignatureOnInterface.ts.expected.md b/src/tests/fixtures/field_definitions/MethodSignatureOnInterface.ts.expected.md new file mode 100644 index 00000000..078e56cd --- /dev/null +++ b/src/tests/fixtures/field_definitions/MethodSignatureOnInterface.ts.expected.md @@ -0,0 +1,41 @@ +## input + +```ts title="field_definitions/MethodSignatureOnInterface.ts" +/** @gqlInterface */ +interface ICarly { + /** @gqlField */ + name(): string; +} +``` + +## Output + +### SDL + +```graphql +interface ICarly { + name: String +} +``` + +### TypeScript + +```ts +import { GraphQLSchema, GraphQLInterfaceType, GraphQLString } from "graphql"; +export function getSchema(): GraphQLSchema { + const ICarlyType: GraphQLInterfaceType = new GraphQLInterfaceType({ + name: "ICarly", + fields() { + return { + name: { + name: "name", + type: GraphQLString + } + }; + } + }); + return new GraphQLSchema({ + types: [ICarlyType] + }); +} +``` \ No newline at end of file diff --git a/src/tests/fixtures/field_definitions/MultipleFieldsAsStaticClassMethods.ts.expected b/src/tests/fixtures/field_definitions/MultipleFieldsAsStaticClassMethods.ts.expected deleted file mode 100644 index c31e50c7..00000000 --- a/src/tests/fixtures/field_definitions/MultipleFieldsAsStaticClassMethods.ts.expected +++ /dev/null @@ -1,75 +0,0 @@ ------------------ -INPUT ------------------ -/** @gqlType */ -export class User { - /** @gqlField */ - name: string; - - /** @gqlField */ - static getUser(_: Query): User { - return new User(); - } - - /** @gqlField */ - static getUsers(_: Query): User[] { - return [new User()]; - } -} - -/** @gqlType */ -type Query = unknown; - ------------------ -OUTPUT ------------------ --- SDL -- -type Query { - getUser: User - getUsers: [User!] -} - -type User { - name: String -} --- TypeScript -- -import { GraphQLSchema, GraphQLObjectType, GraphQLString, GraphQLList, GraphQLNonNull } from "graphql"; -import { User as queryGetUserResolver, User as queryGetUsersResolver } from "./MultipleFieldsAsStaticClassMethods"; -export function getSchema(): GraphQLSchema { - const UserType: GraphQLObjectType = new GraphQLObjectType({ - name: "User", - fields() { - return { - name: { - name: "name", - type: GraphQLString - } - }; - } - }); - const QueryType: GraphQLObjectType = new GraphQLObjectType({ - name: "Query", - fields() { - return { - getUser: { - name: "getUser", - type: UserType, - resolve(source) { - return queryGetUserResolver.getUser(source); - } - }, - getUsers: { - name: "getUsers", - type: new GraphQLList(new GraphQLNonNull(UserType)), - resolve(source) { - return queryGetUsersResolver.getUsers(source); - } - } - }; - } - }); - return new GraphQLSchema({ - query: QueryType, - types: [QueryType, UserType] - }); -} diff --git a/src/tests/fixtures/field_definitions/MultipleFieldsAsStaticClassMethods.ts.expected.md b/src/tests/fixtures/field_definitions/MultipleFieldsAsStaticClassMethods.ts.expected.md new file mode 100644 index 00000000..bbbae0fb --- /dev/null +++ b/src/tests/fixtures/field_definitions/MultipleFieldsAsStaticClassMethods.ts.expected.md @@ -0,0 +1,82 @@ +## input + +```ts title="field_definitions/MultipleFieldsAsStaticClassMethods.ts" +/** @gqlType */ +export class User { + /** @gqlField */ + name: string; + + /** @gqlField */ + static getUser(_: Query): User { + return new User(); + } + + /** @gqlField */ + static getUsers(_: Query): User[] { + return [new User()]; + } +} + +/** @gqlType */ +type Query = unknown; +``` + +## Output + +### SDL + +```graphql +type Query { + getUser: User + getUsers: [User!] +} + +type User { + name: String +} +``` + +### TypeScript + +```ts +import { GraphQLSchema, GraphQLObjectType, GraphQLString, GraphQLList, GraphQLNonNull } from "graphql"; +import { User as queryGetUserResolver, User as queryGetUsersResolver } from "./MultipleFieldsAsStaticClassMethods"; +export function getSchema(): GraphQLSchema { + const UserType: GraphQLObjectType = new GraphQLObjectType({ + name: "User", + fields() { + return { + name: { + name: "name", + type: GraphQLString + } + }; + } + }); + const QueryType: GraphQLObjectType = new GraphQLObjectType({ + name: "Query", + fields() { + return { + getUser: { + name: "getUser", + type: UserType, + resolve(source) { + return queryGetUserResolver.getUser(source); + } + }, + getUsers: { + name: "getUsers", + type: new GraphQLList(new GraphQLNonNull(UserType)), + resolve(source) { + return queryGetUsersResolver.getUsers(source); + } + } + }; + } + }); + return new GraphQLSchema({ + query: QueryType, + types: [QueryType, UserType] + }); +} +``` \ No newline at end of file diff --git a/src/tests/fixtures/field_definitions/ParameterPropertyField.ts.expected b/src/tests/fixtures/field_definitions/ParameterPropertyField.ts.expected deleted file mode 100644 index 13ddc8d2..00000000 --- a/src/tests/fixtures/field_definitions/ParameterPropertyField.ts.expected +++ /dev/null @@ -1,36 +0,0 @@ ------------------ -INPUT ------------------ -/** @gqlType */ -export default class SomeType { - constructor( - /** @gqlField */ - public hello: string, - ) {} -} - ------------------ -OUTPUT ------------------ --- SDL -- -type SomeType { - hello: String -} --- TypeScript -- -import { GraphQLSchema, GraphQLObjectType, GraphQLString } from "graphql"; -export function getSchema(): GraphQLSchema { - const SomeTypeType: GraphQLObjectType = new GraphQLObjectType({ - name: "SomeType", - fields() { - return { - hello: { - name: "hello", - type: GraphQLString - } - }; - } - }); - return new GraphQLSchema({ - types: [SomeTypeType] - }); -} diff --git a/src/tests/fixtures/field_definitions/ParameterPropertyField.ts.expected.md b/src/tests/fixtures/field_definitions/ParameterPropertyField.ts.expected.md new file mode 100644 index 00000000..a35b1acb --- /dev/null +++ b/src/tests/fixtures/field_definitions/ParameterPropertyField.ts.expected.md @@ -0,0 +1,43 @@ +## input + +```ts title="field_definitions/ParameterPropertyField.ts" +/** @gqlType */ +export default class SomeType { + constructor( + /** @gqlField */ + public hello: string, + ) {} +} +``` + +## Output + +### SDL + +```graphql +type SomeType { + hello: String +} +``` + +### TypeScript + +```ts +import { GraphQLSchema, GraphQLObjectType, GraphQLString } from "graphql"; +export function getSchema(): GraphQLSchema { + const SomeTypeType: GraphQLObjectType = new GraphQLObjectType({ + name: "SomeType", + fields() { + return { + hello: { + name: "hello", + type: GraphQLString + } + }; + } + }); + return new GraphQLSchema({ + types: [SomeTypeType] + }); +} +``` \ No newline at end of file diff --git a/src/tests/fixtures/field_definitions/ParameterPropertyFieldBindingPattern.invalid.ts.expected b/src/tests/fixtures/field_definitions/ParameterPropertyFieldBindingPattern.invalid.ts.expected deleted file mode 100644 index abefc439..00000000 --- a/src/tests/fixtures/field_definitions/ParameterPropertyFieldBindingPattern.invalid.ts.expected +++ /dev/null @@ -1,18 +0,0 @@ ------------------ -INPUT ------------------ -/** @gqlType */ -export default class SomeType { - constructor( - /** @gqlField */ - public [foo]: string, - ) {} -} - ------------------ -OUTPUT ------------------ -src/tests/fixtures/field_definitions/ParameterPropertyFieldBindingPattern.invalid.ts:5:12 - error: Expected a name identifier. Grats expected to find a name here which it could use to derive the GraphQL name. - -5 public [foo]: string, - ~~~~~ diff --git a/src/tests/fixtures/field_definitions/ParameterPropertyFieldBindingPattern.invalid.ts.expected.md b/src/tests/fixtures/field_definitions/ParameterPropertyFieldBindingPattern.invalid.ts.expected.md new file mode 100644 index 00000000..8f00a532 --- /dev/null +++ b/src/tests/fixtures/field_definitions/ParameterPropertyFieldBindingPattern.invalid.ts.expected.md @@ -0,0 +1,22 @@ +## input + +```ts title="field_definitions/ParameterPropertyFieldBindingPattern.invalid.ts" +/** @gqlType */ +export default class SomeType { + constructor( + /** @gqlField */ + public [foo]: string, + ) {} +} +``` + +## Output + +### Error Report + +```text +src/tests/fixtures/field_definitions/ParameterPropertyFieldBindingPattern.invalid.ts:5:12 - error: Expected a name identifier. Grats expected to find a name here which it could use to derive the GraphQL name. + +5 public [foo]: string, + ~~~~~ +``` \ No newline at end of file diff --git a/src/tests/fixtures/field_definitions/ParameterPropertyFieldDeprecated.ts.expected b/src/tests/fixtures/field_definitions/ParameterPropertyFieldDeprecated.ts.expected deleted file mode 100644 index 3ef64623..00000000 --- a/src/tests/fixtures/field_definitions/ParameterPropertyFieldDeprecated.ts.expected +++ /dev/null @@ -1,40 +0,0 @@ ------------------ -INPUT ------------------ -/** @gqlType */ -export default class SomeType { - constructor( - /** - * @gqlField - * @deprecated Don't use this - */ - public hello: string, - ) {} -} - ------------------ -OUTPUT ------------------ --- SDL -- -type SomeType { - hello: String @deprecated(reason: "Don't use this") -} --- TypeScript -- -import { GraphQLSchema, GraphQLObjectType, GraphQLString } from "graphql"; -export function getSchema(): GraphQLSchema { - const SomeTypeType: GraphQLObjectType = new GraphQLObjectType({ - name: "SomeType", - fields() { - return { - hello: { - deprecationReason: "Don't use this", - name: "hello", - type: GraphQLString - } - }; - } - }); - return new GraphQLSchema({ - types: [SomeTypeType] - }); -} diff --git a/src/tests/fixtures/field_definitions/ParameterPropertyFieldDeprecated.ts.expected.md b/src/tests/fixtures/field_definitions/ParameterPropertyFieldDeprecated.ts.expected.md new file mode 100644 index 00000000..ae07634b --- /dev/null +++ b/src/tests/fixtures/field_definitions/ParameterPropertyFieldDeprecated.ts.expected.md @@ -0,0 +1,47 @@ +## input + +```ts title="field_definitions/ParameterPropertyFieldDeprecated.ts" +/** @gqlType */ +export default class SomeType { + constructor( + /** + * @gqlField + * @deprecated Don't use this + */ + public hello: string, + ) {} +} +``` + +## Output + +### SDL + +```graphql +type SomeType { + hello: String @deprecated(reason: "Don't use this") +} +``` + +### TypeScript + +```ts +import { GraphQLSchema, GraphQLObjectType, GraphQLString } from "graphql"; +export function getSchema(): GraphQLSchema { + const SomeTypeType: GraphQLObjectType = new GraphQLObjectType({ + name: "SomeType", + fields() { + return { + hello: { + deprecationReason: "Don't use this", + name: "hello", + type: GraphQLString + } + }; + } + }); + return new GraphQLSchema({ + types: [SomeTypeType] + }); +} +``` \ No newline at end of file diff --git a/src/tests/fixtures/field_definitions/ParameterPropertyFieldNoModifier.invalid.ts.expected b/src/tests/fixtures/field_definitions/ParameterPropertyFieldNoModifier.invalid.ts.expected deleted file mode 100644 index 1e82397a..00000000 --- a/src/tests/fixtures/field_definitions/ParameterPropertyFieldNoModifier.invalid.ts.expected +++ /dev/null @@ -1,48 +0,0 @@ ------------------ -INPUT ------------------ -/** @gqlType */ -export default class SomeType { - constructor( - /** @gqlField */ - hello: string, - ) { - console.log(hello); - } -} - ------------------ -OUTPUT ------------------ --- Error Report -- -src/tests/fixtures/field_definitions/ParameterPropertyFieldNoModifier.invalid.ts:5:5 - error: Expected `@gqlField` constructor parameter to be a parameter property. This requires a modifier such as `public` or `readonly` before the parameter name. - -Learn more: https://grats.capt.dev/docs/docblock-tags/fields#class-based-fields - -5 hello: string, - ~~~~~~~~~~~~~ - - --- Code Action: "Add 'public' modifier" (add-public-modifier) -- -- Original -+ Fixed - -@@ -4,3 +4,3 @@ - /** @gqlField */ -- hello: string, -+ public hello: string, - ) { - --- Applied Fixes -- - * Applied fix "Add 'public' modifier" in grats/src/tests/fixtures/field_definitions/ParameterPropertyFieldNoModifier.invalid.ts - --- Fixed Text -- -/** @gqlType */ -export default class SomeType { - constructor( - /** @gqlField */ - public hello: string, - ) { - console.log(hello); - } -} diff --git a/src/tests/fixtures/field_definitions/ParameterPropertyFieldNoModifier.invalid.ts.expected.md b/src/tests/fixtures/field_definitions/ParameterPropertyFieldNoModifier.invalid.ts.expected.md new file mode 100644 index 00000000..41ed6ef8 --- /dev/null +++ b/src/tests/fixtures/field_definitions/ParameterPropertyFieldNoModifier.invalid.ts.expected.md @@ -0,0 +1,59 @@ +## input + +```ts title="field_definitions/ParameterPropertyFieldNoModifier.invalid.ts" +/** @gqlType */ +export default class SomeType { + constructor( + /** @gqlField */ + hello: string, + ) { + console.log(hello); + } +} +``` + +## Output + +### Error Report + +```text +src/tests/fixtures/field_definitions/ParameterPropertyFieldNoModifier.invalid.ts:5:5 - error: Expected `@gqlField` constructor parameter to be a parameter property. This requires a modifier such as `public` or `readonly` before the parameter name. + +Learn more: https://grats.capt.dev/docs/docblock-tags/fields#class-based-fields + +5 hello: string, + ~~~~~~~~~~~~~ +``` + +#### Code Action: "Add 'public' modifier" (add-public-modifier) + +```diff +- Original ++ Fixed + +@@ -4,3 +4,3 @@ + /** @gqlField */ +- hello: string, ++ public hello: string, + ) { +``` + +#### Applied Fixes + +```text + * Applied fix "Add 'public' modifier" in grats/src/tests/fixtures/field_definitions/ParameterPropertyFieldNoModifier.invalid.ts +``` + +#### Fixed Text + +```typescript +/** @gqlType */ +export default class SomeType { + constructor( + /** @gqlField */ + public hello: string, + ) { + console.log(hello); + } +} +``` \ No newline at end of file diff --git a/src/tests/fixtures/field_definitions/ParameterPropertyFieldNoType.invalid.ts.expected b/src/tests/fixtures/field_definitions/ParameterPropertyFieldNoType.invalid.ts.expected deleted file mode 100644 index d12bbfa0..00000000 --- a/src/tests/fixtures/field_definitions/ParameterPropertyFieldNoType.invalid.ts.expected +++ /dev/null @@ -1,18 +0,0 @@ ------------------ -INPUT ------------------ -/** @gqlType */ -export default class SomeType { - constructor( - /** @gqlField */ - public hello, - ) {} -} - ------------------ -OUTPUT ------------------ -src/tests/fixtures/field_definitions/ParameterPropertyFieldNoType.invalid.ts:5:5 - error: Expected `@gqlField` parameter property to have an explicit type annotation. Grats needs to be able to see the type of the parameter property to generate a GraphQL schema. - -5 public hello, - ~~~~~~~~~~~~ diff --git a/src/tests/fixtures/field_definitions/ParameterPropertyFieldNoType.invalid.ts.expected.md b/src/tests/fixtures/field_definitions/ParameterPropertyFieldNoType.invalid.ts.expected.md new file mode 100644 index 00000000..6c0b499c --- /dev/null +++ b/src/tests/fixtures/field_definitions/ParameterPropertyFieldNoType.invalid.ts.expected.md @@ -0,0 +1,22 @@ +## input + +```ts title="field_definitions/ParameterPropertyFieldNoType.invalid.ts" +/** @gqlType */ +export default class SomeType { + constructor( + /** @gqlField */ + public hello, + ) {} +} +``` + +## Output + +### Error Report + +```text +src/tests/fixtures/field_definitions/ParameterPropertyFieldNoType.invalid.ts:5:5 - error: Expected `@gqlField` parameter property to have an explicit type annotation. Grats needs to be able to see the type of the parameter property to generate a GraphQL schema. + +5 public hello, + ~~~~~~~~~~~~ +``` \ No newline at end of file diff --git a/src/tests/fixtures/field_definitions/ParameterPropertyFieldReadOnly.ts.expected b/src/tests/fixtures/field_definitions/ParameterPropertyFieldReadOnly.ts.expected deleted file mode 100644 index 8ad67d2a..00000000 --- a/src/tests/fixtures/field_definitions/ParameterPropertyFieldReadOnly.ts.expected +++ /dev/null @@ -1,36 +0,0 @@ ------------------ -INPUT ------------------ -/** @gqlType */ -export default class SomeType { - constructor( - /** @gqlField */ - readonly hello: string, - ) {} -} - ------------------ -OUTPUT ------------------ --- SDL -- -type SomeType { - hello: String -} --- TypeScript -- -import { GraphQLSchema, GraphQLObjectType, GraphQLString } from "graphql"; -export function getSchema(): GraphQLSchema { - const SomeTypeType: GraphQLObjectType = new GraphQLObjectType({ - name: "SomeType", - fields() { - return { - hello: { - name: "hello", - type: GraphQLString - } - }; - } - }); - return new GraphQLSchema({ - types: [SomeTypeType] - }); -} diff --git a/src/tests/fixtures/field_definitions/ParameterPropertyFieldReadOnly.ts.expected.md b/src/tests/fixtures/field_definitions/ParameterPropertyFieldReadOnly.ts.expected.md new file mode 100644 index 00000000..83b249bc --- /dev/null +++ b/src/tests/fixtures/field_definitions/ParameterPropertyFieldReadOnly.ts.expected.md @@ -0,0 +1,43 @@ +## input + +```ts title="field_definitions/ParameterPropertyFieldReadOnly.ts" +/** @gqlType */ +export default class SomeType { + constructor( + /** @gqlField */ + readonly hello: string, + ) {} +} +``` + +## Output + +### SDL + +```graphql +type SomeType { + hello: String +} +``` + +### TypeScript + +```ts +import { GraphQLSchema, GraphQLObjectType, GraphQLString } from "graphql"; +export function getSchema(): GraphQLSchema { + const SomeTypeType: GraphQLObjectType = new GraphQLObjectType({ + name: "SomeType", + fields() { + return { + hello: { + name: "hello", + type: GraphQLString + } + }; + } + }); + return new GraphQLSchema({ + types: [SomeTypeType] + }); +} +``` \ No newline at end of file diff --git a/src/tests/fixtures/field_definitions/ParameterPropertyFieldReadOnlyPrivate.invalid.ts.expected b/src/tests/fixtures/field_definitions/ParameterPropertyFieldReadOnlyPrivate.invalid.ts.expected deleted file mode 100644 index abbaa059..00000000 --- a/src/tests/fixtures/field_definitions/ParameterPropertyFieldReadOnlyPrivate.invalid.ts.expected +++ /dev/null @@ -1,50 +0,0 @@ ------------------ -INPUT ------------------ -/** @gqlType */ -export default class SomeType { - constructor( - /** - * Greet the world! - * @gqlField - */ - private readonly hello: string, - ) {} -} - ------------------ -OUTPUT ------------------ --- Error Report -- -src/tests/fixtures/field_definitions/ParameterPropertyFieldReadOnlyPrivate.invalid.ts:8:5 - error: Expected `@gqlField` parameter property to be public. Valid modifiers for `@gqlField` parameter properties are `public` and `readonly`. - -Learn more: https://grats.capt.dev/docs/docblock-tags/fields#class-based-fields - -8 private readonly hello: string, - ~~~~~~~ - - --- Code Action: "Make parameter property public" (make-parameter-property-public) -- -- Original -+ Fixed - -@@ -7,3 +7,3 @@ - */ -- private readonly hello: string, -+ public readonly hello: string, - ) {} - --- Applied Fixes -- - * Applied fix "Make parameter property public" in grats/src/tests/fixtures/field_definitions/ParameterPropertyFieldReadOnlyPrivate.invalid.ts - --- Fixed Text -- -/** @gqlType */ -export default class SomeType { - constructor( - /** - * Greet the world! - * @gqlField - */ - public readonly hello: string, - ) {} -} diff --git a/src/tests/fixtures/field_definitions/ParameterPropertyFieldReadOnlyPrivate.invalid.ts.expected.md b/src/tests/fixtures/field_definitions/ParameterPropertyFieldReadOnlyPrivate.invalid.ts.expected.md new file mode 100644 index 00000000..ad4db917 --- /dev/null +++ b/src/tests/fixtures/field_definitions/ParameterPropertyFieldReadOnlyPrivate.invalid.ts.expected.md @@ -0,0 +1,61 @@ +## input + +```ts title="field_definitions/ParameterPropertyFieldReadOnlyPrivate.invalid.ts" +/** @gqlType */ +export default class SomeType { + constructor( + /** + * Greet the world! + * @gqlField + */ + private readonly hello: string, + ) {} +} +``` + +## Output + +### Error Report + +```text +src/tests/fixtures/field_definitions/ParameterPropertyFieldReadOnlyPrivate.invalid.ts:8:5 - error: Expected `@gqlField` parameter property to be public. Valid modifiers for `@gqlField` parameter properties are `public` and `readonly`. + +Learn more: https://grats.capt.dev/docs/docblock-tags/fields#class-based-fields + +8 private readonly hello: string, + ~~~~~~~ +``` + +#### Code Action: "Make parameter property public" (make-parameter-property-public) + +```diff +- Original ++ Fixed + +@@ -7,3 +7,3 @@ + */ +- private readonly hello: string, ++ public readonly hello: string, + ) {} +``` + +#### Applied Fixes + +```text + * Applied fix "Make parameter property public" in grats/src/tests/fixtures/field_definitions/ParameterPropertyFieldReadOnlyPrivate.invalid.ts +``` + +#### Fixed Text + +```typescript +/** @gqlType */ +export default class SomeType { + constructor( + /** + * Greet the world! + * @gqlField + */ + public readonly hello: string, + ) {} +} +``` \ No newline at end of file diff --git a/src/tests/fixtures/field_definitions/ParameterPropertyFieldRenamed.ts.expected b/src/tests/fixtures/field_definitions/ParameterPropertyFieldRenamed.ts.expected deleted file mode 100644 index 4d7af756..00000000 --- a/src/tests/fixtures/field_definitions/ParameterPropertyFieldRenamed.ts.expected +++ /dev/null @@ -1,39 +0,0 @@ ------------------ -INPUT ------------------ -/** @gqlType */ -export default class SomeType { - constructor( - /** @gqlField hello */ - public foo: string, - ) {} -} - ------------------ -OUTPUT ------------------ --- SDL -- -type SomeType { - hello: String -} --- TypeScript -- -import { GraphQLSchema, GraphQLObjectType, GraphQLString } from "graphql"; -export function getSchema(): GraphQLSchema { - const SomeTypeType: GraphQLObjectType = new GraphQLObjectType({ - name: "SomeType", - fields() { - return { - hello: { - name: "hello", - type: GraphQLString, - resolve(source) { - return source.foo; - } - } - }; - } - }); - return new GraphQLSchema({ - types: [SomeTypeType] - }); -} diff --git a/src/tests/fixtures/field_definitions/ParameterPropertyFieldRenamed.ts.expected.md b/src/tests/fixtures/field_definitions/ParameterPropertyFieldRenamed.ts.expected.md new file mode 100644 index 00000000..d954c0f6 --- /dev/null +++ b/src/tests/fixtures/field_definitions/ParameterPropertyFieldRenamed.ts.expected.md @@ -0,0 +1,46 @@ +## input + +```ts title="field_definitions/ParameterPropertyFieldRenamed.ts" +/** @gqlType */ +export default class SomeType { + constructor( + /** @gqlField hello */ + public foo: string, + ) {} +} +``` + +## Output + +### SDL + +```graphql +type SomeType { + hello: String +} +``` + +### TypeScript + +```ts +import { GraphQLSchema, GraphQLObjectType, GraphQLString } from "graphql"; +export function getSchema(): GraphQLSchema { + const SomeTypeType: GraphQLObjectType = new GraphQLObjectType({ + name: "SomeType", + fields() { + return { + hello: { + name: "hello", + type: GraphQLString, + resolve(source) { + return source.foo; + } + } + }; + } + }); + return new GraphQLSchema({ + types: [SomeTypeType] + }); +} +``` \ No newline at end of file diff --git a/src/tests/fixtures/field_definitions/ParameterPropertyFieldWithDescription.ts.expected b/src/tests/fixtures/field_definitions/ParameterPropertyFieldWithDescription.ts.expected deleted file mode 100644 index af7c8620..00000000 --- a/src/tests/fixtures/field_definitions/ParameterPropertyFieldWithDescription.ts.expected +++ /dev/null @@ -1,41 +0,0 @@ ------------------ -INPUT ------------------ -/** @gqlType */ -export default class SomeType { - constructor( - /** - * Greet the world! - * @gqlField - */ - public hello: string, - ) {} -} - ------------------ -OUTPUT ------------------ --- SDL -- -type SomeType { - """Greet the world!""" - hello: String -} --- TypeScript -- -import { GraphQLSchema, GraphQLObjectType, GraphQLString } from "graphql"; -export function getSchema(): GraphQLSchema { - const SomeTypeType: GraphQLObjectType = new GraphQLObjectType({ - name: "SomeType", - fields() { - return { - hello: { - description: "Greet the world!", - name: "hello", - type: GraphQLString - } - }; - } - }); - return new GraphQLSchema({ - types: [SomeTypeType] - }); -} diff --git a/src/tests/fixtures/field_definitions/ParameterPropertyFieldWithDescription.ts.expected.md b/src/tests/fixtures/field_definitions/ParameterPropertyFieldWithDescription.ts.expected.md new file mode 100644 index 00000000..117791c5 --- /dev/null +++ b/src/tests/fixtures/field_definitions/ParameterPropertyFieldWithDescription.ts.expected.md @@ -0,0 +1,48 @@ +## input + +```ts title="field_definitions/ParameterPropertyFieldWithDescription.ts" +/** @gqlType */ +export default class SomeType { + constructor( + /** + * Greet the world! + * @gqlField + */ + public hello: string, + ) {} +} +``` + +## Output + +### SDL + +```graphql +type SomeType { + """Greet the world!""" + hello: String +} +``` + +### TypeScript + +```ts +import { GraphQLSchema, GraphQLObjectType, GraphQLString } from "graphql"; +export function getSchema(): GraphQLSchema { + const SomeTypeType: GraphQLObjectType = new GraphQLObjectType({ + name: "SomeType", + fields() { + return { + hello: { + description: "Greet the world!", + name: "hello", + type: GraphQLString + } + }; + } + }); + return new GraphQLSchema({ + types: [SomeTypeType] + }); +} +``` \ No newline at end of file diff --git a/src/tests/fixtures/field_definitions/PrivateAndProtectedFieldMethods.invalid.ts.expected b/src/tests/fixtures/field_definitions/PrivateAndProtectedFieldMethods.invalid.ts.expected deleted file mode 100644 index 6ef5bfb8..00000000 --- a/src/tests/fixtures/field_definitions/PrivateAndProtectedFieldMethods.invalid.ts.expected +++ /dev/null @@ -1,26 +0,0 @@ ------------------ -INPUT ------------------ -/** @gqlType */ -export class User { - /** @gqlField */ - private greet(): string { - return "Hello"; - } - /** @gqlField */ - protected greet2(): string { - return "Hello"; - } -} - ------------------ -OUTPUT ------------------ -src/tests/fixtures/field_definitions/PrivateAndProtectedFieldMethods.invalid.ts:4:3 - error: Unexpected access modifier on `@gqlField` method. GraphQL fields must be able to be called by the GraphQL executor. - -4 private greet(): string { - ~~~~~~~ -src/tests/fixtures/field_definitions/PrivateAndProtectedFieldMethods.invalid.ts:8:3 - error: Unexpected access modifier on `@gqlField` method. GraphQL fields must be able to be called by the GraphQL executor. - -8 protected greet2(): string { - ~~~~~~~~~ diff --git a/src/tests/fixtures/field_definitions/PrivateAndProtectedFieldMethods.invalid.ts.expected.md b/src/tests/fixtures/field_definitions/PrivateAndProtectedFieldMethods.invalid.ts.expected.md new file mode 100644 index 00000000..72b366d3 --- /dev/null +++ b/src/tests/fixtures/field_definitions/PrivateAndProtectedFieldMethods.invalid.ts.expected.md @@ -0,0 +1,30 @@ +## input + +```ts title="field_definitions/PrivateAndProtectedFieldMethods.invalid.ts" +/** @gqlType */ +export class User { + /** @gqlField */ + private greet(): string { + return "Hello"; + } + /** @gqlField */ + protected greet2(): string { + return "Hello"; + } +} +``` + +## Output + +### Error Report + +```text +src/tests/fixtures/field_definitions/PrivateAndProtectedFieldMethods.invalid.ts:4:3 - error: Unexpected access modifier on `@gqlField` method. GraphQL fields must be able to be called by the GraphQL executor. + +4 private greet(): string { + ~~~~~~~ +src/tests/fixtures/field_definitions/PrivateAndProtectedFieldMethods.invalid.ts:8:3 - error: Unexpected access modifier on `@gqlField` method. GraphQL fields must be able to be called by the GraphQL executor. + +8 protected greet2(): string { + ~~~~~~~~~ +``` \ No newline at end of file diff --git a/src/tests/fixtures/field_definitions/PropertyFieldMissingType.invalid.ts.expected b/src/tests/fixtures/field_definitions/PropertyFieldMissingType.invalid.ts.expected deleted file mode 100644 index b227f3ab..00000000 --- a/src/tests/fixtures/field_definitions/PropertyFieldMissingType.invalid.ts.expected +++ /dev/null @@ -1,16 +0,0 @@ ------------------ -INPUT ------------------ -/** @gqlType */ -class SomeType { - /** @gqlField */ - someProp; -} - ------------------ -OUTPUT ------------------ -src/tests/fixtures/field_definitions/PropertyFieldMissingType.invalid.ts:4:3 - error: Expected GraphQL field to have an explicitly defined type annotation. Grats needs to be able to see the type of the field to generate a field's type in the GraphQL schema. - -4 someProp; - ~~~~~~~~ diff --git a/src/tests/fixtures/field_definitions/PropertyFieldMissingType.invalid.ts.expected.md b/src/tests/fixtures/field_definitions/PropertyFieldMissingType.invalid.ts.expected.md new file mode 100644 index 00000000..213daad9 --- /dev/null +++ b/src/tests/fixtures/field_definitions/PropertyFieldMissingType.invalid.ts.expected.md @@ -0,0 +1,20 @@ +## input + +```ts title="field_definitions/PropertyFieldMissingType.invalid.ts" +/** @gqlType */ +class SomeType { + /** @gqlField */ + someProp; +} +``` + +## Output + +### Error Report + +```text +src/tests/fixtures/field_definitions/PropertyFieldMissingType.invalid.ts:4:3 - error: Expected GraphQL field to have an explicitly defined type annotation. Grats needs to be able to see the type of the field to generate a field's type in the GraphQL schema. + +4 someProp; + ~~~~~~~~ +``` \ No newline at end of file diff --git a/src/tests/fixtures/field_definitions/PublicFieldMethod.ts.expected b/src/tests/fixtures/field_definitions/PublicFieldMethod.ts.expected deleted file mode 100644 index a1bc6d96..00000000 --- a/src/tests/fixtures/field_definitions/PublicFieldMethod.ts.expected +++ /dev/null @@ -1,36 +0,0 @@ ------------------ -INPUT ------------------ -/** @gqlType */ -export class User { - /** @gqlField */ - public greet(): string { - return "Hello"; - } -} - ------------------ -OUTPUT ------------------ --- SDL -- -type User { - greet: String -} --- TypeScript -- -import { GraphQLSchema, GraphQLObjectType, GraphQLString } from "graphql"; -export function getSchema(): GraphQLSchema { - const UserType: GraphQLObjectType = new GraphQLObjectType({ - name: "User", - fields() { - return { - greet: { - name: "greet", - type: GraphQLString - } - }; - } - }); - return new GraphQLSchema({ - types: [UserType] - }); -} diff --git a/src/tests/fixtures/field_definitions/PublicFieldMethod.ts.expected.md b/src/tests/fixtures/field_definitions/PublicFieldMethod.ts.expected.md new file mode 100644 index 00000000..0bd0834b --- /dev/null +++ b/src/tests/fixtures/field_definitions/PublicFieldMethod.ts.expected.md @@ -0,0 +1,43 @@ +## input + +```ts title="field_definitions/PublicFieldMethod.ts" +/** @gqlType */ +export class User { + /** @gqlField */ + public greet(): string { + return "Hello"; + } +} +``` + +## Output + +### SDL + +```graphql +type User { + greet: String +} +``` + +### TypeScript + +```ts +import { GraphQLSchema, GraphQLObjectType, GraphQLString } from "graphql"; +export function getSchema(): GraphQLSchema { + const UserType: GraphQLObjectType = new GraphQLObjectType({ + name: "User", + fields() { + return { + greet: { + name: "greet", + type: GraphQLString + } + }; + } + }); + return new GraphQLSchema({ + types: [UserType] + }); +} +``` \ No newline at end of file diff --git a/src/tests/fixtures/field_definitions/ReferenceNonGraphQLType.invalid.ts.expected b/src/tests/fixtures/field_definitions/ReferenceNonGraphQLType.invalid.ts.expected deleted file mode 100644 index 1fd7ce38..00000000 --- a/src/tests/fixtures/field_definitions/ReferenceNonGraphQLType.invalid.ts.expected +++ /dev/null @@ -1,18 +0,0 @@ ------------------ -INPUT ------------------ -type SomeUndefienedType = string; - -/** @gqlType */ -class SomeType { - /** @gqlField */ - somePropertyField: SomeUndefienedType; -} - ------------------ -OUTPUT ------------------ -src/tests/fixtures/field_definitions/ReferenceNonGraphQLType.invalid.ts:6:22 - error: Unable to resolve type reference. In order to generate a GraphQL schema, Grats needs to determine which GraphQL type is being referenced. This requires being able to resolve type references to their `@gql` annotated declaration. However this reference could not be resolved. Is it possible that this type is not defined in this file? - -6 somePropertyField: SomeUndefienedType; - ~~~~~~~~~~~~~~~~~~ diff --git a/src/tests/fixtures/field_definitions/ReferenceNonGraphQLType.invalid.ts.expected.md b/src/tests/fixtures/field_definitions/ReferenceNonGraphQLType.invalid.ts.expected.md new file mode 100644 index 00000000..09e26796 --- /dev/null +++ b/src/tests/fixtures/field_definitions/ReferenceNonGraphQLType.invalid.ts.expected.md @@ -0,0 +1,22 @@ +## input + +```ts title="field_definitions/ReferenceNonGraphQLType.invalid.ts" +type SomeUndefienedType = string; + +/** @gqlType */ +class SomeType { + /** @gqlField */ + somePropertyField: SomeUndefienedType; +} +``` + +## Output + +### Error Report + +```text +src/tests/fixtures/field_definitions/ReferenceNonGraphQLType.invalid.ts:6:22 - error: Unable to resolve type reference. In order to generate a GraphQL schema, Grats needs to determine which GraphQL type is being referenced. This requires being able to resolve type references to their `@gql` annotated declaration. However this reference could not be resolved. Is it possible that this type is not defined in this file? + +6 somePropertyField: SomeUndefienedType; + ~~~~~~~~~~~~~~~~~~ +``` \ No newline at end of file diff --git a/src/tests/fixtures/field_definitions/ReferenceUndefinedType.invalid.ts.expected b/src/tests/fixtures/field_definitions/ReferenceUndefinedType.invalid.ts.expected deleted file mode 100644 index fcc320f0..00000000 --- a/src/tests/fixtures/field_definitions/ReferenceUndefinedType.invalid.ts.expected +++ /dev/null @@ -1,16 +0,0 @@ ------------------ -INPUT ------------------ -/** @gqlType */ -class SomeType { - /** @gqlField */ - somePropertyField: SomeUndefienedType; -} - ------------------ -OUTPUT ------------------ -src/tests/fixtures/field_definitions/ReferenceUndefinedType.invalid.ts:4:22 - error: Unable to resolve type reference. In order to generate a GraphQL schema, Grats needs to determine which GraphQL type is being referenced. This requires being able to resolve type references to their `@gql` annotated declaration. However this reference could not be resolved. Is it possible that this type is not defined in this file? - -4 somePropertyField: SomeUndefienedType; - ~~~~~~~~~~~~~~~~~~ diff --git a/src/tests/fixtures/field_definitions/ReferenceUndefinedType.invalid.ts.expected.md b/src/tests/fixtures/field_definitions/ReferenceUndefinedType.invalid.ts.expected.md new file mode 100644 index 00000000..4cee59f8 --- /dev/null +++ b/src/tests/fixtures/field_definitions/ReferenceUndefinedType.invalid.ts.expected.md @@ -0,0 +1,20 @@ +## input + +```ts title="field_definitions/ReferenceUndefinedType.invalid.ts" +/** @gqlType */ +class SomeType { + /** @gqlField */ + somePropertyField: SomeUndefienedType; +} +``` + +## Output + +### Error Report + +```text +src/tests/fixtures/field_definitions/ReferenceUndefinedType.invalid.ts:4:22 - error: Unable to resolve type reference. In order to generate a GraphQL schema, Grats needs to determine which GraphQL type is being referenced. This requires being able to resolve type references to their `@gql` annotated declaration. However this reference could not be resolved. Is it possible that this type is not defined in this file? + +4 somePropertyField: SomeUndefienedType; + ~~~~~~~~~~~~~~~~~~ +``` \ No newline at end of file diff --git a/src/tests/fixtures/field_definitions/RenamedField.ts.expected b/src/tests/fixtures/field_definitions/RenamedField.ts.expected deleted file mode 100644 index 14986629..00000000 --- a/src/tests/fixtures/field_definitions/RenamedField.ts.expected +++ /dev/null @@ -1,50 +0,0 @@ ------------------ -INPUT ------------------ -/** @gqlType */ -class SomeType { - /** @gqlField greeting */ - somePropertyField: string; - - /** @gqlField salutaion */ - someMethodField(): string { - return "Hello world!"; - } -} - ------------------ -OUTPUT ------------------ --- SDL -- -type SomeType { - greeting: String - salutaion: String -} --- TypeScript -- -import { GraphQLSchema, GraphQLObjectType, GraphQLString } from "graphql"; -export function getSchema(): GraphQLSchema { - const SomeTypeType: GraphQLObjectType = new GraphQLObjectType({ - name: "SomeType", - fields() { - return { - greeting: { - name: "greeting", - type: GraphQLString, - resolve(source) { - return source.somePropertyField; - } - }, - salutaion: { - name: "salutaion", - type: GraphQLString, - resolve(source) { - return source.someMethodField(); - } - } - }; - } - }); - return new GraphQLSchema({ - types: [SomeTypeType] - }); -} diff --git a/src/tests/fixtures/field_definitions/RenamedField.ts.expected.md b/src/tests/fixtures/field_definitions/RenamedField.ts.expected.md new file mode 100644 index 00000000..eba8f9f2 --- /dev/null +++ b/src/tests/fixtures/field_definitions/RenamedField.ts.expected.md @@ -0,0 +1,57 @@ +## input + +```ts title="field_definitions/RenamedField.ts" +/** @gqlType */ +class SomeType { + /** @gqlField greeting */ + somePropertyField: string; + + /** @gqlField salutaion */ + someMethodField(): string { + return "Hello world!"; + } +} +``` + +## Output + +### SDL + +```graphql +type SomeType { + greeting: String + salutaion: String +} +``` + +### TypeScript + +```ts +import { GraphQLSchema, GraphQLObjectType, GraphQLString } from "graphql"; +export function getSchema(): GraphQLSchema { + const SomeTypeType: GraphQLObjectType = new GraphQLObjectType({ + name: "SomeType", + fields() { + return { + greeting: { + name: "greeting", + type: GraphQLString, + resolve(source) { + return source.somePropertyField; + } + }, + salutaion: { + name: "salutaion", + type: GraphQLString, + resolve(source) { + return source.someMethodField(); + } + } + }; + } + }); + return new GraphQLSchema({ + types: [SomeTypeType] + }); +} +``` \ No newline at end of file diff --git a/src/tests/fixtures/field_definitions/RenamedFieldWithArgs.ts.expected b/src/tests/fixtures/field_definitions/RenamedFieldWithArgs.ts.expected deleted file mode 100644 index 9657cca3..00000000 --- a/src/tests/fixtures/field_definitions/RenamedFieldWithArgs.ts.expected +++ /dev/null @@ -1,44 +0,0 @@ ------------------ -INPUT ------------------ -/** @gqlType */ -export default class SomeType { - /** @gqlField greetz */ - hello(args: { greeting: string }): string { - return `${args.greeting} world!`; - } -} - ------------------ -OUTPUT ------------------ --- SDL -- -type SomeType { - greetz(greeting: String!): String -} --- TypeScript -- -import { GraphQLSchema, GraphQLObjectType, GraphQLString, GraphQLNonNull } from "graphql"; -export function getSchema(): GraphQLSchema { - const SomeTypeType: GraphQLObjectType = new GraphQLObjectType({ - name: "SomeType", - fields() { - return { - greetz: { - name: "greetz", - type: GraphQLString, - args: { - greeting: { - type: new GraphQLNonNull(GraphQLString) - } - }, - resolve(source, args) { - return source.hello(args); - } - } - }; - } - }); - return new GraphQLSchema({ - types: [SomeTypeType] - }); -} diff --git a/src/tests/fixtures/field_definitions/RenamedFieldWithArgs.ts.expected.md b/src/tests/fixtures/field_definitions/RenamedFieldWithArgs.ts.expected.md new file mode 100644 index 00000000..ad7c1187 --- /dev/null +++ b/src/tests/fixtures/field_definitions/RenamedFieldWithArgs.ts.expected.md @@ -0,0 +1,51 @@ +## input + +```ts title="field_definitions/RenamedFieldWithArgs.ts" +/** @gqlType */ +export default class SomeType { + /** @gqlField greetz */ + hello(args: { greeting: string }): string { + return `${args.greeting} world!`; + } +} +``` + +## Output + +### SDL + +```graphql +type SomeType { + greetz(greeting: String!): String +} +``` + +### TypeScript + +```ts +import { GraphQLSchema, GraphQLObjectType, GraphQLString, GraphQLNonNull } from "graphql"; +export function getSchema(): GraphQLSchema { + const SomeTypeType: GraphQLObjectType = new GraphQLObjectType({ + name: "SomeType", + fields() { + return { + greetz: { + name: "greetz", + type: GraphQLString, + args: { + greeting: { + type: new GraphQLNonNull(GraphQLString) + } + }, + resolve(source, args) { + return source.hello(args); + } + } + }; + } + }); + return new GraphQLSchema({ + types: [SomeTypeType] + }); +} +``` \ No newline at end of file diff --git a/src/tests/fixtures/field_definitions/RenamedFieldWithDescription.ts.expected b/src/tests/fixtures/field_definitions/RenamedFieldWithDescription.ts.expected deleted file mode 100644 index 8f92f183..00000000 --- a/src/tests/fixtures/field_definitions/RenamedFieldWithDescription.ts.expected +++ /dev/null @@ -1,62 +0,0 @@ ------------------ -INPUT ------------------ -/** @gqlType */ -class SomeType { - /** - * Number 1 greeting. - * - * @gqlField greeting - */ - somePropertyField: string; - - /** - * Number 1 salutation. - * - * @gqlField salutaion - */ - someMethodField(): string { - return "Hello world!"; - } -} - ------------------ -OUTPUT ------------------ --- SDL -- -type SomeType { - """Number 1 greeting.""" - greeting: String - """Number 1 salutation.""" - salutaion: String -} --- TypeScript -- -import { GraphQLSchema, GraphQLObjectType, GraphQLString } from "graphql"; -export function getSchema(): GraphQLSchema { - const SomeTypeType: GraphQLObjectType = new GraphQLObjectType({ - name: "SomeType", - fields() { - return { - greeting: { - description: "Number 1 greeting.", - name: "greeting", - type: GraphQLString, - resolve(source) { - return source.somePropertyField; - } - }, - salutaion: { - description: "Number 1 salutation.", - name: "salutaion", - type: GraphQLString, - resolve(source) { - return source.someMethodField(); - } - } - }; - } - }); - return new GraphQLSchema({ - types: [SomeTypeType] - }); -} diff --git a/src/tests/fixtures/field_definitions/RenamedFieldWithDescription.ts.expected.md b/src/tests/fixtures/field_definitions/RenamedFieldWithDescription.ts.expected.md new file mode 100644 index 00000000..d9652572 --- /dev/null +++ b/src/tests/fixtures/field_definitions/RenamedFieldWithDescription.ts.expected.md @@ -0,0 +1,69 @@ +## input + +```ts title="field_definitions/RenamedFieldWithDescription.ts" +/** @gqlType */ +class SomeType { + /** + * Number 1 greeting. + * + * @gqlField greeting + */ + somePropertyField: string; + + /** + * Number 1 salutation. + * + * @gqlField salutaion + */ + someMethodField(): string { + return "Hello world!"; + } +} +``` + +## Output + +### SDL + +```graphql +type SomeType { + """Number 1 greeting.""" + greeting: String + """Number 1 salutation.""" + salutaion: String +} +``` + +### TypeScript + +```ts +import { GraphQLSchema, GraphQLObjectType, GraphQLString } from "graphql"; +export function getSchema(): GraphQLSchema { + const SomeTypeType: GraphQLObjectType = new GraphQLObjectType({ + name: "SomeType", + fields() { + return { + greeting: { + description: "Number 1 greeting.", + name: "greeting", + type: GraphQLString, + resolve(source) { + return source.somePropertyField; + } + }, + salutaion: { + description: "Number 1 salutation.", + name: "salutaion", + type: GraphQLString, + resolve(source) { + return source.someMethodField(); + } + } + }; + } + }); + return new GraphQLSchema({ + types: [SomeTypeType] + }); +} +``` \ No newline at end of file diff --git a/src/tests/fixtures/field_definitions/StringFieldWithDescription.ts.expected b/src/tests/fixtures/field_definitions/StringFieldWithDescription.ts.expected deleted file mode 100644 index 956c1052..00000000 --- a/src/tests/fixtures/field_definitions/StringFieldWithDescription.ts.expected +++ /dev/null @@ -1,41 +0,0 @@ ------------------ -INPUT ------------------ -/** @gqlType */ -export default class SomeType { - /** - * Greet the world! - * @gqlField - */ - hello(): string { - return "Hello world!"; - } -} - ------------------ -OUTPUT ------------------ --- SDL -- -type SomeType { - """Greet the world!""" - hello: String -} --- TypeScript -- -import { GraphQLSchema, GraphQLObjectType, GraphQLString } from "graphql"; -export function getSchema(): GraphQLSchema { - const SomeTypeType: GraphQLObjectType = new GraphQLObjectType({ - name: "SomeType", - fields() { - return { - hello: { - description: "Greet the world!", - name: "hello", - type: GraphQLString - } - }; - } - }); - return new GraphQLSchema({ - types: [SomeTypeType] - }); -} diff --git a/src/tests/fixtures/field_definitions/StringFieldWithDescription.ts.expected.md b/src/tests/fixtures/field_definitions/StringFieldWithDescription.ts.expected.md new file mode 100644 index 00000000..6635b167 --- /dev/null +++ b/src/tests/fixtures/field_definitions/StringFieldWithDescription.ts.expected.md @@ -0,0 +1,48 @@ +## input + +```ts title="field_definitions/StringFieldWithDescription.ts" +/** @gqlType */ +export default class SomeType { + /** + * Greet the world! + * @gqlField + */ + hello(): string { + return "Hello world!"; + } +} +``` + +## Output + +### SDL + +```graphql +type SomeType { + """Greet the world!""" + hello: String +} +``` + +### TypeScript + +```ts +import { GraphQLSchema, GraphQLObjectType, GraphQLString } from "graphql"; +export function getSchema(): GraphQLSchema { + const SomeTypeType: GraphQLObjectType = new GraphQLObjectType({ + name: "SomeType", + fields() { + return { + hello: { + description: "Greet the world!", + name: "hello", + type: GraphQLString + } + }; + } + }); + return new GraphQLSchema({ + types: [SomeTypeType] + }); +} +``` \ No newline at end of file diff --git a/src/tests/fixtures/field_definitions/asyncFunctionFieldNotExported.invalid.ts.expected b/src/tests/fixtures/field_definitions/asyncFunctionFieldNotExported.invalid.ts.expected deleted file mode 100644 index c51da05d..00000000 --- a/src/tests/fixtures/field_definitions/asyncFunctionFieldNotExported.invalid.ts.expected +++ /dev/null @@ -1,42 +0,0 @@ ------------------ -INPUT ------------------ -/** @gqlField */ -async function greet(_: Query): Promise { - return "Hello, World!"; -} - -/** @gqlType */ -type Query = unknown; - ------------------ -OUTPUT ------------------ --- Error Report -- -src/tests/fixtures/field_definitions/asyncFunctionFieldNotExported.invalid.ts:2:16 - error: Expected a `@gqlField` function to be a named export. Grats needs to import resolver functions into its generated schema module, so the resolver function must be a named export. - -2 async function greet(_: Query): Promise { - ~~~~~ - - --- Code Action: "Add export keyword to function with @gqlField" (add-export-keyword-to-function) -- -- Original -+ Fixed - -@@ -1,3 +1,3 @@ - /** @gqlField */ -- async function greet(_: Query): Promise { -+ export async function greet(_: Query): Promise { - return "Hello, World!"; - --- Applied Fixes -- - * Applied fix "Add export keyword to function with @gqlField" in grats/src/tests/fixtures/field_definitions/asyncFunctionFieldNotExported.invalid.ts - --- Fixed Text -- -/** @gqlField */ -export async function greet(_: Query): Promise { - return "Hello, World!"; -} - -/** @gqlType */ -type Query = unknown; diff --git a/src/tests/fixtures/field_definitions/asyncFunctionFieldNotExported.invalid.ts.expected.md b/src/tests/fixtures/field_definitions/asyncFunctionFieldNotExported.invalid.ts.expected.md new file mode 100644 index 00000000..9f95de8c --- /dev/null +++ b/src/tests/fixtures/field_definitions/asyncFunctionFieldNotExported.invalid.ts.expected.md @@ -0,0 +1,53 @@ +## input + +```ts title="field_definitions/asyncFunctionFieldNotExported.invalid.ts" +/** @gqlField */ +async function greet(_: Query): Promise { + return "Hello, World!"; +} + +/** @gqlType */ +type Query = unknown; +``` + +## Output + +### Error Report + +```text +src/tests/fixtures/field_definitions/asyncFunctionFieldNotExported.invalid.ts:2:16 - error: Expected a `@gqlField` function to be a named export. Grats needs to import resolver functions into its generated schema module, so the resolver function must be a named export. + +2 async function greet(_: Query): Promise { + ~~~~~ +``` + +#### Code Action: "Add export keyword to function with @gqlField" (add-export-keyword-to-function) + +```diff +- Original ++ Fixed + +@@ -1,3 +1,3 @@ + /** @gqlField */ +- async function greet(_: Query): Promise { ++ export async function greet(_: Query): Promise { + return "Hello, World!"; +``` + +#### Applied Fixes + +```text + * Applied fix "Add export keyword to function with @gqlField" in grats/src/tests/fixtures/field_definitions/asyncFunctionFieldNotExported.invalid.ts +``` + +#### Fixed Text + +```typescript +/** @gqlField */ +export async function greet(_: Query): Promise { + return "Hello, World!"; +} + +/** @gqlType */ +type Query = unknown; +``` \ No newline at end of file diff --git a/src/tests/fixtures/field_values/ArrayField.ts.expected b/src/tests/fixtures/field_values/ArrayField.ts.expected deleted file mode 100644 index 3ba4d47d..00000000 --- a/src/tests/fixtures/field_values/ArrayField.ts.expected +++ /dev/null @@ -1,36 +0,0 @@ ------------------ -INPUT ------------------ -/** @gqlType */ -export default class SomeType { - /** @gqlField */ - hello(): Array { - return ["Hello world!"]; - } -} - ------------------ -OUTPUT ------------------ --- SDL -- -type SomeType { - hello: [String!] -} --- TypeScript -- -import { GraphQLSchema, GraphQLObjectType, GraphQLList, GraphQLNonNull, GraphQLString } from "graphql"; -export function getSchema(): GraphQLSchema { - const SomeTypeType: GraphQLObjectType = new GraphQLObjectType({ - name: "SomeType", - fields() { - return { - hello: { - name: "hello", - type: new GraphQLList(new GraphQLNonNull(GraphQLString)) - } - }; - } - }); - return new GraphQLSchema({ - types: [SomeTypeType] - }); -} diff --git a/src/tests/fixtures/field_values/ArrayField.ts.expected.md b/src/tests/fixtures/field_values/ArrayField.ts.expected.md new file mode 100644 index 00000000..807a82bc --- /dev/null +++ b/src/tests/fixtures/field_values/ArrayField.ts.expected.md @@ -0,0 +1,43 @@ +## input + +```ts title="field_values/ArrayField.ts" +/** @gqlType */ +export default class SomeType { + /** @gqlField */ + hello(): Array { + return ["Hello world!"]; + } +} +``` + +## Output + +### SDL + +```graphql +type SomeType { + hello: [String!] +} +``` + +### TypeScript + +```ts +import { GraphQLSchema, GraphQLObjectType, GraphQLList, GraphQLNonNull, GraphQLString } from "graphql"; +export function getSchema(): GraphQLSchema { + const SomeTypeType: GraphQLObjectType = new GraphQLObjectType({ + name: "SomeType", + fields() { + return { + hello: { + name: "hello", + type: new GraphQLList(new GraphQLNonNull(GraphQLString)) + } + }; + } + }); + return new GraphQLSchema({ + types: [SomeTypeType] + }); +} +``` \ No newline at end of file diff --git a/src/tests/fixtures/field_values/ArrayOfPromises.ts.expected b/src/tests/fixtures/field_values/ArrayOfPromises.ts.expected deleted file mode 100644 index b930798b..00000000 --- a/src/tests/fixtures/field_values/ArrayOfPromises.ts.expected +++ /dev/null @@ -1,41 +0,0 @@ ------------------ -INPUT ------------------ -/** @gqlType */ -export default class SomeType { - /** @gqlField */ - b: Promise[]; - /** @gqlField */ - c: Array>; -} - ------------------ -OUTPUT ------------------ --- SDL -- -type SomeType { - b: [String!] - c: [String!] -} --- TypeScript -- -import { GraphQLSchema, GraphQLObjectType, GraphQLList, GraphQLNonNull, GraphQLString } from "graphql"; -export function getSchema(): GraphQLSchema { - const SomeTypeType: GraphQLObjectType = new GraphQLObjectType({ - name: "SomeType", - fields() { - return { - b: { - name: "b", - type: new GraphQLList(new GraphQLNonNull(GraphQLString)) - }, - c: { - name: "c", - type: new GraphQLList(new GraphQLNonNull(GraphQLString)) - } - }; - } - }); - return new GraphQLSchema({ - types: [SomeTypeType] - }); -} diff --git a/src/tests/fixtures/field_values/ArrayOfPromises.ts.expected.md b/src/tests/fixtures/field_values/ArrayOfPromises.ts.expected.md new file mode 100644 index 00000000..97058eaa --- /dev/null +++ b/src/tests/fixtures/field_values/ArrayOfPromises.ts.expected.md @@ -0,0 +1,48 @@ +## input + +```ts title="field_values/ArrayOfPromises.ts" +/** @gqlType */ +export default class SomeType { + /** @gqlField */ + b: Promise[]; + /** @gqlField */ + c: Array>; +} +``` + +## Output + +### SDL + +```graphql +type SomeType { + b: [String!] + c: [String!] +} +``` + +### TypeScript + +```ts +import { GraphQLSchema, GraphQLObjectType, GraphQLList, GraphQLNonNull, GraphQLString } from "graphql"; +export function getSchema(): GraphQLSchema { + const SomeTypeType: GraphQLObjectType = new GraphQLObjectType({ + name: "SomeType", + fields() { + return { + b: { + name: "b", + type: new GraphQLList(new GraphQLNonNull(GraphQLString)) + }, + c: { + name: "c", + type: new GraphQLList(new GraphQLNonNull(GraphQLString)) + } + }; + } + }); + return new GraphQLSchema({ + types: [SomeTypeType] + }); +} +``` \ No newline at end of file diff --git a/src/tests/fixtures/field_values/ArrayShorthandField.ts.expected b/src/tests/fixtures/field_values/ArrayShorthandField.ts.expected deleted file mode 100644 index 6b611ee5..00000000 --- a/src/tests/fixtures/field_values/ArrayShorthandField.ts.expected +++ /dev/null @@ -1,36 +0,0 @@ ------------------ -INPUT ------------------ -/** @gqlType */ -export default class SomeType { - /** @gqlField */ - hello(): string[] { - return ["Hello world!"]; - } -} - ------------------ -OUTPUT ------------------ --- SDL -- -type SomeType { - hello: [String!] -} --- TypeScript -- -import { GraphQLSchema, GraphQLObjectType, GraphQLList, GraphQLNonNull, GraphQLString } from "graphql"; -export function getSchema(): GraphQLSchema { - const SomeTypeType: GraphQLObjectType = new GraphQLObjectType({ - name: "SomeType", - fields() { - return { - hello: { - name: "hello", - type: new GraphQLList(new GraphQLNonNull(GraphQLString)) - } - }; - } - }); - return new GraphQLSchema({ - types: [SomeTypeType] - }); -} diff --git a/src/tests/fixtures/field_values/ArrayShorthandField.ts.expected.md b/src/tests/fixtures/field_values/ArrayShorthandField.ts.expected.md new file mode 100644 index 00000000..45c8bd81 --- /dev/null +++ b/src/tests/fixtures/field_values/ArrayShorthandField.ts.expected.md @@ -0,0 +1,43 @@ +## input + +```ts title="field_values/ArrayShorthandField.ts" +/** @gqlType */ +export default class SomeType { + /** @gqlField */ + hello(): string[] { + return ["Hello world!"]; + } +} +``` + +## Output + +### SDL + +```graphql +type SomeType { + hello: [String!] +} +``` + +### TypeScript + +```ts +import { GraphQLSchema, GraphQLObjectType, GraphQLList, GraphQLNonNull, GraphQLString } from "graphql"; +export function getSchema(): GraphQLSchema { + const SomeTypeType: GraphQLObjectType = new GraphQLObjectType({ + name: "SomeType", + fields() { + return { + hello: { + name: "hello", + type: new GraphQLList(new GraphQLNonNull(GraphQLString)) + } + }; + } + }); + return new GraphQLSchema({ + types: [SomeTypeType] + }); +} +``` \ No newline at end of file diff --git a/src/tests/fixtures/field_values/ArrayWithNullableItems.ts.expected b/src/tests/fixtures/field_values/ArrayWithNullableItems.ts.expected deleted file mode 100644 index 015a63d5..00000000 --- a/src/tests/fixtures/field_values/ArrayWithNullableItems.ts.expected +++ /dev/null @@ -1,36 +0,0 @@ ------------------ -INPUT ------------------ -/** @gqlType */ -export default class SomeType { - /** @gqlField */ - hello(): Array { - return ["Hello world!", null]; - } -} - ------------------ -OUTPUT ------------------ --- SDL -- -type SomeType { - hello: [String] -} --- TypeScript -- -import { GraphQLSchema, GraphQLObjectType, GraphQLList, GraphQLString } from "graphql"; -export function getSchema(): GraphQLSchema { - const SomeTypeType: GraphQLObjectType = new GraphQLObjectType({ - name: "SomeType", - fields() { - return { - hello: { - name: "hello", - type: new GraphQLList(GraphQLString) - } - }; - } - }); - return new GraphQLSchema({ - types: [SomeTypeType] - }); -} diff --git a/src/tests/fixtures/field_values/ArrayWithNullableItems.ts.expected.md b/src/tests/fixtures/field_values/ArrayWithNullableItems.ts.expected.md new file mode 100644 index 00000000..495a538e --- /dev/null +++ b/src/tests/fixtures/field_values/ArrayWithNullableItems.ts.expected.md @@ -0,0 +1,43 @@ +## input + +```ts title="field_values/ArrayWithNullableItems.ts" +/** @gqlType */ +export default class SomeType { + /** @gqlField */ + hello(): Array { + return ["Hello world!", null]; + } +} +``` + +## Output + +### SDL + +```graphql +type SomeType { + hello: [String] +} +``` + +### TypeScript + +```ts +import { GraphQLSchema, GraphQLObjectType, GraphQLList, GraphQLString } from "graphql"; +export function getSchema(): GraphQLSchema { + const SomeTypeType: GraphQLObjectType = new GraphQLObjectType({ + name: "SomeType", + fields() { + return { + hello: { + name: "hello", + type: new GraphQLList(GraphQLString) + } + }; + } + }); + return new GraphQLSchema({ + types: [SomeTypeType] + }); +} +``` \ No newline at end of file diff --git a/src/tests/fixtures/field_values/AsyncPromiseField.ts.expected b/src/tests/fixtures/field_values/AsyncPromiseField.ts.expected deleted file mode 100644 index e20460f1..00000000 --- a/src/tests/fixtures/field_values/AsyncPromiseField.ts.expected +++ /dev/null @@ -1,36 +0,0 @@ ------------------ -INPUT ------------------ -/** @gqlType */ -export default class SomeType { - /** @gqlField */ - async hello(): Promise { - return "Hello world!"; - } -} - ------------------ -OUTPUT ------------------ --- SDL -- -type SomeType { - hello: String -} --- TypeScript -- -import { GraphQLSchema, GraphQLObjectType, GraphQLString } from "graphql"; -export function getSchema(): GraphQLSchema { - const SomeTypeType: GraphQLObjectType = new GraphQLObjectType({ - name: "SomeType", - fields() { - return { - hello: { - name: "hello", - type: GraphQLString - } - }; - } - }); - return new GraphQLSchema({ - types: [SomeTypeType] - }); -} diff --git a/src/tests/fixtures/field_values/AsyncPromiseField.ts.expected.md b/src/tests/fixtures/field_values/AsyncPromiseField.ts.expected.md new file mode 100644 index 00000000..8d7b006d --- /dev/null +++ b/src/tests/fixtures/field_values/AsyncPromiseField.ts.expected.md @@ -0,0 +1,43 @@ +## input + +```ts title="field_values/AsyncPromiseField.ts" +/** @gqlType */ +export default class SomeType { + /** @gqlField */ + async hello(): Promise { + return "Hello world!"; + } +} +``` + +## Output + +### SDL + +```graphql +type SomeType { + hello: String +} +``` + +### TypeScript + +```ts +import { GraphQLSchema, GraphQLObjectType, GraphQLString } from "graphql"; +export function getSchema(): GraphQLSchema { + const SomeTypeType: GraphQLObjectType = new GraphQLObjectType({ + name: "SomeType", + fields() { + return { + hello: { + name: "hello", + type: GraphQLString + } + }; + } + }); + return new GraphQLSchema({ + types: [SomeTypeType] + }); +} +``` \ No newline at end of file diff --git a/src/tests/fixtures/field_values/BooleanField.ts.expected b/src/tests/fixtures/field_values/BooleanField.ts.expected deleted file mode 100644 index 95d13592..00000000 --- a/src/tests/fixtures/field_values/BooleanField.ts.expected +++ /dev/null @@ -1,36 +0,0 @@ ------------------ -INPUT ------------------ -/** @gqlType */ -export default class SomeType { - /** @gqlField */ - haveBeenGreeted(): boolean { - return false; - } -} - ------------------ -OUTPUT ------------------ --- SDL -- -type SomeType { - haveBeenGreeted: Boolean -} --- TypeScript -- -import { GraphQLSchema, GraphQLObjectType, GraphQLBoolean } from "graphql"; -export function getSchema(): GraphQLSchema { - const SomeTypeType: GraphQLObjectType = new GraphQLObjectType({ - name: "SomeType", - fields() { - return { - haveBeenGreeted: { - name: "haveBeenGreeted", - type: GraphQLBoolean - } - }; - } - }); - return new GraphQLSchema({ - types: [SomeTypeType] - }); -} diff --git a/src/tests/fixtures/field_values/BooleanField.ts.expected.md b/src/tests/fixtures/field_values/BooleanField.ts.expected.md new file mode 100644 index 00000000..e04287fa --- /dev/null +++ b/src/tests/fixtures/field_values/BooleanField.ts.expected.md @@ -0,0 +1,43 @@ +## input + +```ts title="field_values/BooleanField.ts" +/** @gqlType */ +export default class SomeType { + /** @gqlField */ + haveBeenGreeted(): boolean { + return false; + } +} +``` + +## Output + +### SDL + +```graphql +type SomeType { + haveBeenGreeted: Boolean +} +``` + +### TypeScript + +```ts +import { GraphQLSchema, GraphQLObjectType, GraphQLBoolean } from "graphql"; +export function getSchema(): GraphQLSchema { + const SomeTypeType: GraphQLObjectType = new GraphQLObjectType({ + name: "SomeType", + fields() { + return { + haveBeenGreeted: { + name: "haveBeenGreeted", + type: GraphQLBoolean + } + }; + } + }); + return new GraphQLSchema({ + types: [SomeTypeType] + }); +} +``` \ No newline at end of file diff --git a/src/tests/fixtures/field_values/CustomScalar.ts.expected b/src/tests/fixtures/field_values/CustomScalar.ts.expected deleted file mode 100644 index b64b8459..00000000 --- a/src/tests/fixtures/field_values/CustomScalar.ts.expected +++ /dev/null @@ -1,52 +0,0 @@ ------------------ -INPUT ------------------ -/** @gqlScalar */ -export type MyString = string; - -/** @gqlType */ -export default class SomeType { - /** @gqlField */ - hello(): MyString { - return "Hello world!"; - } -} - ------------------ -OUTPUT ------------------ --- SDL -- -scalar MyString - -type SomeType { - hello: MyString -} --- TypeScript -- -import type { GqlScalar } from "grats"; -import type { MyString as MyStringInternal } from "./CustomScalar"; -import { GraphQLSchema, GraphQLScalarType, GraphQLObjectType } from "graphql"; -export type SchemaConfig = { - scalars: { - MyString: GqlScalar; - }; -}; -export function getSchema(config: SchemaConfig): GraphQLSchema { - const MyStringType: GraphQLScalarType = new GraphQLScalarType({ - name: "MyString", - ...config.scalars.MyString - }); - const SomeTypeType: GraphQLObjectType = new GraphQLObjectType({ - name: "SomeType", - fields() { - return { - hello: { - name: "hello", - type: MyStringType - } - }; - } - }); - return new GraphQLSchema({ - types: [MyStringType, SomeTypeType] - }); -} diff --git a/src/tests/fixtures/field_values/CustomScalar.ts.expected.md b/src/tests/fixtures/field_values/CustomScalar.ts.expected.md new file mode 100644 index 00000000..f0fec75f --- /dev/null +++ b/src/tests/fixtures/field_values/CustomScalar.ts.expected.md @@ -0,0 +1,59 @@ +## input + +```ts title="field_values/CustomScalar.ts" +/** @gqlScalar */ +export type MyString = string; + +/** @gqlType */ +export default class SomeType { + /** @gqlField */ + hello(): MyString { + return "Hello world!"; + } +} +``` + +## Output + +### SDL + +```graphql +scalar MyString + +type SomeType { + hello: MyString +} +``` + +### TypeScript + +```ts +import type { GqlScalar } from "grats"; +import type { MyString as MyStringInternal } from "./CustomScalar"; +import { GraphQLSchema, GraphQLScalarType, GraphQLObjectType } from "graphql"; +export type SchemaConfig = { + scalars: { + MyString: GqlScalar; + }; +}; +export function getSchema(config: SchemaConfig): GraphQLSchema { + const MyStringType: GraphQLScalarType = new GraphQLScalarType({ + name: "MyString", + ...config.scalars.MyString + }); + const SomeTypeType: GraphQLObjectType = new GraphQLObjectType({ + name: "SomeType", + fields() { + return { + hello: { + name: "hello", + type: MyStringType + } + }; + } + }); + return new GraphQLSchema({ + types: [MyStringType, SomeTypeType] + }); +} +``` \ No newline at end of file diff --git a/src/tests/fixtures/field_values/DuplicateFields.invalid.ts.expected b/src/tests/fixtures/field_values/DuplicateFields.invalid.ts.expected deleted file mode 100644 index 9c0db34b..00000000 --- a/src/tests/fixtures/field_values/DuplicateFields.invalid.ts.expected +++ /dev/null @@ -1,29 +0,0 @@ ------------------ -INPUT ------------------ -// @ts-nocheck - -/** @gqlType */ -export default class SomeType { - /** @gqlField */ - hello(): string { - return "Hello world!"; - } - /** @gqlField */ - hello(): Array { - return ["Hello world!"]; - } -} - ------------------ -OUTPUT ------------------ -src/tests/fixtures/field_values/DuplicateFields.invalid.ts:6:3 - error: Field "SomeType.hello" can only be defined once. - -6 hello(): string { - ~~~~~ - - src/tests/fixtures/field_values/DuplicateFields.invalid.ts:10:3 - 10 hello(): Array { - ~~~~~ - Related location diff --git a/src/tests/fixtures/field_values/DuplicateFields.invalid.ts.expected.md b/src/tests/fixtures/field_values/DuplicateFields.invalid.ts.expected.md new file mode 100644 index 00000000..ed132ecb --- /dev/null +++ b/src/tests/fixtures/field_values/DuplicateFields.invalid.ts.expected.md @@ -0,0 +1,33 @@ +## input + +```ts title="field_values/DuplicateFields.invalid.ts" +// @ts-nocheck + +/** @gqlType */ +export default class SomeType { + /** @gqlField */ + hello(): string { + return "Hello world!"; + } + /** @gqlField */ + hello(): Array { + return ["Hello world!"]; + } +} +``` + +## Output + +### Error Report + +```text +src/tests/fixtures/field_values/DuplicateFields.invalid.ts:6:3 - error: Field "SomeType.hello" can only be defined once. + +6 hello(): string { + ~~~~~ + + src/tests/fixtures/field_values/DuplicateFields.invalid.ts:10:3 + 10 hello(): Array { + ~~~~~ + Related location +``` \ No newline at end of file diff --git a/src/tests/fixtures/field_values/KillsParentOnExceptionDoesNotMatchInterface.invalid.ts.expected b/src/tests/fixtures/field_values/KillsParentOnExceptionDoesNotMatchInterface.invalid.ts.expected deleted file mode 100644 index 617b862e..00000000 --- a/src/tests/fixtures/field_values/KillsParentOnExceptionDoesNotMatchInterface.invalid.ts.expected +++ /dev/null @@ -1,37 +0,0 @@ ------------------ -INPUT ------------------ -/** @gqlInterface */ -interface IPerson { - /** - * @killsParentOnException - * @gqlField - */ - name(): string; -} - -/** @gqlType */ -export class User implements IPerson { - __typename = "User" as const; - /** @gqlField */ - // @ts-ignore - name(): string | null { - if (Math.random() < 0.5) { - return null; - } - return "Alice"; - } -} - ------------------ -OUTPUT ------------------ -src/tests/fixtures/field_values/KillsParentOnExceptionDoesNotMatchInterface.invalid.ts:4:7 - error: Interface field IPerson.name expects type String! but User.name is type String. - -4 * @killsParentOnException - ~~~~~~~~~~~~~~~~~~~~~~ - - src/tests/fixtures/field_values/KillsParentOnExceptionDoesNotMatchInterface.invalid.ts:15:11 - 15 name(): string | null { - ~~~~~~~~~~~~~ - Related location diff --git a/src/tests/fixtures/field_values/KillsParentOnExceptionDoesNotMatchInterface.invalid.ts.expected.md b/src/tests/fixtures/field_values/KillsParentOnExceptionDoesNotMatchInterface.invalid.ts.expected.md new file mode 100644 index 00000000..9bc116b3 --- /dev/null +++ b/src/tests/fixtures/field_values/KillsParentOnExceptionDoesNotMatchInterface.invalid.ts.expected.md @@ -0,0 +1,41 @@ +## input + +```ts title="field_values/KillsParentOnExceptionDoesNotMatchInterface.invalid.ts" +/** @gqlInterface */ +interface IPerson { + /** + * @killsParentOnException + * @gqlField + */ + name(): string; +} + +/** @gqlType */ +export class User implements IPerson { + __typename = "User" as const; + /** @gqlField */ + // @ts-ignore + name(): string | null { + if (Math.random() < 0.5) { + return null; + } + return "Alice"; + } +} +``` + +## Output + +### Error Report + +```text +src/tests/fixtures/field_values/KillsParentOnExceptionDoesNotMatchInterface.invalid.ts:4:7 - error: Interface field IPerson.name expects type String! but User.name is type String. + +4 * @killsParentOnException + ~~~~~~~~~~~~~~~~~~~~~~ + + src/tests/fixtures/field_values/KillsParentOnExceptionDoesNotMatchInterface.invalid.ts:15:11 + 15 name(): string | null { + ~~~~~~~~~~~~~ + Related location +``` \ No newline at end of file diff --git a/src/tests/fixtures/field_values/KitchenSink.ts.expected b/src/tests/fixtures/field_values/KitchenSink.ts.expected deleted file mode 100644 index b20d679e..00000000 --- a/src/tests/fixtures/field_values/KitchenSink.ts.expected +++ /dev/null @@ -1,170 +0,0 @@ ------------------ -INPUT ------------------ -/** @gqlType */ -export default class SomeType { - /** @gqlField */ - hello(args: { greeting: string }): string { - return `${args.greeting ?? "Hello"} world!`; - } - - /** @gqlField */ - greetings(args: { greeting: string }): string[] { - return [`${args.greeting ?? "Hello"} world!`]; - } - /** @gqlField */ - greetings1(args: { greeting: string }): Array { - return [`${args.greeting ?? "Hello"} world!`]; - } - /** @gqlField */ - greetings2(args: { greeting: string }): ReadonlyArray { - return [`${args.greeting ?? "Hello"} world!`]; - } - - /** @gqlField */ - me(): User { - return new User(); - } -} - -/** @gqlType */ -class User { - /** @gqlField */ - name(): string { - return "Alice"; - } - /** @gqlField */ - groups(): Group[] { - return [new Group()]; - } -} - -/** @gqlType */ -class Group { - /** @gqlField */ - description: string; - - constructor() { - this.description = "A group of people"; - } - - /** @gqlField */ - name(): string { - return "Pal's Club"; - } - /** @gqlField */ - async members(): Promise { - return [new User()]; - } -} - ------------------ -OUTPUT ------------------ --- SDL -- -type Group { - description: String - members: [User!] - name: String -} - -type SomeType { - greetings(greeting: String!): [String!] - greetings1(greeting: String!): [String!] - greetings2(greeting: String!): [String!] - hello(greeting: String!): String - me: User -} - -type User { - groups: [Group!] - name: String -} --- TypeScript -- -import { GraphQLSchema, GraphQLObjectType, GraphQLString, GraphQLList, GraphQLNonNull } from "graphql"; -export function getSchema(): GraphQLSchema { - const UserType: GraphQLObjectType = new GraphQLObjectType({ - name: "User", - fields() { - return { - groups: { - name: "groups", - type: new GraphQLList(new GraphQLNonNull(GroupType)) - }, - name: { - name: "name", - type: GraphQLString - } - }; - } - }); - const GroupType: GraphQLObjectType = new GraphQLObjectType({ - name: "Group", - fields() { - return { - description: { - name: "description", - type: GraphQLString - }, - members: { - name: "members", - type: new GraphQLList(new GraphQLNonNull(UserType)) - }, - name: { - name: "name", - type: GraphQLString - } - }; - } - }); - const SomeTypeType: GraphQLObjectType = new GraphQLObjectType({ - name: "SomeType", - fields() { - return { - greetings: { - name: "greetings", - type: new GraphQLList(new GraphQLNonNull(GraphQLString)), - args: { - greeting: { - type: new GraphQLNonNull(GraphQLString) - } - } - }, - greetings1: { - name: "greetings1", - type: new GraphQLList(new GraphQLNonNull(GraphQLString)), - args: { - greeting: { - type: new GraphQLNonNull(GraphQLString) - } - } - }, - greetings2: { - name: "greetings2", - type: new GraphQLList(new GraphQLNonNull(GraphQLString)), - args: { - greeting: { - type: new GraphQLNonNull(GraphQLString) - } - } - }, - hello: { - name: "hello", - type: GraphQLString, - args: { - greeting: { - type: new GraphQLNonNull(GraphQLString) - } - } - }, - me: { - name: "me", - type: UserType - } - }; - } - }); - return new GraphQLSchema({ - types: [GroupType, SomeTypeType, UserType] - }); -} diff --git a/src/tests/fixtures/field_values/KitchenSink.ts.expected.md b/src/tests/fixtures/field_values/KitchenSink.ts.expected.md new file mode 100644 index 00000000..519295d3 --- /dev/null +++ b/src/tests/fixtures/field_values/KitchenSink.ts.expected.md @@ -0,0 +1,177 @@ +## input + +```ts title="field_values/KitchenSink.ts" +/** @gqlType */ +export default class SomeType { + /** @gqlField */ + hello(args: { greeting: string }): string { + return `${args.greeting ?? "Hello"} world!`; + } + + /** @gqlField */ + greetings(args: { greeting: string }): string[] { + return [`${args.greeting ?? "Hello"} world!`]; + } + /** @gqlField */ + greetings1(args: { greeting: string }): Array { + return [`${args.greeting ?? "Hello"} world!`]; + } + /** @gqlField */ + greetings2(args: { greeting: string }): ReadonlyArray { + return [`${args.greeting ?? "Hello"} world!`]; + } + + /** @gqlField */ + me(): User { + return new User(); + } +} + +/** @gqlType */ +class User { + /** @gqlField */ + name(): string { + return "Alice"; + } + /** @gqlField */ + groups(): Group[] { + return [new Group()]; + } +} + +/** @gqlType */ +class Group { + /** @gqlField */ + description: string; + + constructor() { + this.description = "A group of people"; + } + + /** @gqlField */ + name(): string { + return "Pal's Club"; + } + /** @gqlField */ + async members(): Promise { + return [new User()]; + } +} +``` + +## Output + +### SDL + +```graphql +type Group { + description: String + members: [User!] + name: String +} + +type SomeType { + greetings(greeting: String!): [String!] + greetings1(greeting: String!): [String!] + greetings2(greeting: String!): [String!] + hello(greeting: String!): String + me: User +} + +type User { + groups: [Group!] + name: String +} +``` + +### TypeScript + +```ts +import { GraphQLSchema, GraphQLObjectType, GraphQLString, GraphQLList, GraphQLNonNull } from "graphql"; +export function getSchema(): GraphQLSchema { + const UserType: GraphQLObjectType = new GraphQLObjectType({ + name: "User", + fields() { + return { + groups: { + name: "groups", + type: new GraphQLList(new GraphQLNonNull(GroupType)) + }, + name: { + name: "name", + type: GraphQLString + } + }; + } + }); + const GroupType: GraphQLObjectType = new GraphQLObjectType({ + name: "Group", + fields() { + return { + description: { + name: "description", + type: GraphQLString + }, + members: { + name: "members", + type: new GraphQLList(new GraphQLNonNull(UserType)) + }, + name: { + name: "name", + type: GraphQLString + } + }; + } + }); + const SomeTypeType: GraphQLObjectType = new GraphQLObjectType({ + name: "SomeType", + fields() { + return { + greetings: { + name: "greetings", + type: new GraphQLList(new GraphQLNonNull(GraphQLString)), + args: { + greeting: { + type: new GraphQLNonNull(GraphQLString) + } + } + }, + greetings1: { + name: "greetings1", + type: new GraphQLList(new GraphQLNonNull(GraphQLString)), + args: { + greeting: { + type: new GraphQLNonNull(GraphQLString) + } + } + }, + greetings2: { + name: "greetings2", + type: new GraphQLList(new GraphQLNonNull(GraphQLString)), + args: { + greeting: { + type: new GraphQLNonNull(GraphQLString) + } + } + }, + hello: { + name: "hello", + type: GraphQLString, + args: { + greeting: { + type: new GraphQLNonNull(GraphQLString) + } + } + }, + me: { + name: "me", + type: UserType + } + }; + } + }); + return new GraphQLSchema({ + types: [GroupType, SomeTypeType, UserType] + }); +} +``` \ No newline at end of file diff --git a/src/tests/fixtures/field_values/LinkedField.ts.expected b/src/tests/fixtures/field_values/LinkedField.ts.expected deleted file mode 100644 index d9b4da56..00000000 --- a/src/tests/fixtures/field_values/LinkedField.ts.expected +++ /dev/null @@ -1,68 +0,0 @@ ------------------ -INPUT ------------------ -/** @gqlType */ -class SomeType { - /** @gqlField */ - async me(): Promise { - return new User(); - } -} - -/** @gqlType */ -class User { - /** @gqlField */ - name(): string { - return "Alice"; - } - /** @gqlField */ - friends(): User[] { - return [new User()]; - } -} - ------------------ -OUTPUT ------------------ --- SDL -- -type SomeType { - me: User -} - -type User { - friends: [User!] - name: String -} --- TypeScript -- -import { GraphQLSchema, GraphQLObjectType, GraphQLList, GraphQLNonNull, GraphQLString } from "graphql"; -export function getSchema(): GraphQLSchema { - const UserType: GraphQLObjectType = new GraphQLObjectType({ - name: "User", - fields() { - return { - friends: { - name: "friends", - type: new GraphQLList(new GraphQLNonNull(UserType)) - }, - name: { - name: "name", - type: GraphQLString - } - }; - } - }); - const SomeTypeType: GraphQLObjectType = new GraphQLObjectType({ - name: "SomeType", - fields() { - return { - me: { - name: "me", - type: UserType - } - }; - } - }); - return new GraphQLSchema({ - types: [SomeTypeType, UserType] - }); -} diff --git a/src/tests/fixtures/field_values/LinkedField.ts.expected.md b/src/tests/fixtures/field_values/LinkedField.ts.expected.md new file mode 100644 index 00000000..37b562db --- /dev/null +++ b/src/tests/fixtures/field_values/LinkedField.ts.expected.md @@ -0,0 +1,75 @@ +## input + +```ts title="field_values/LinkedField.ts" +/** @gqlType */ +class SomeType { + /** @gqlField */ + async me(): Promise { + return new User(); + } +} + +/** @gqlType */ +class User { + /** @gqlField */ + name(): string { + return "Alice"; + } + /** @gqlField */ + friends(): User[] { + return [new User()]; + } +} +``` + +## Output + +### SDL + +```graphql +type SomeType { + me: User +} + +type User { + friends: [User!] + name: String +} +``` + +### TypeScript + +```ts +import { GraphQLSchema, GraphQLObjectType, GraphQLList, GraphQLNonNull, GraphQLString } from "graphql"; +export function getSchema(): GraphQLSchema { + const UserType: GraphQLObjectType = new GraphQLObjectType({ + name: "User", + fields() { + return { + friends: { + name: "friends", + type: new GraphQLList(new GraphQLNonNull(UserType)) + }, + name: { + name: "name", + type: GraphQLString + } + }; + } + }); + const SomeTypeType: GraphQLObjectType = new GraphQLObjectType({ + name: "SomeType", + fields() { + return { + me: { + name: "me", + type: UserType + } + }; + } + }); + return new GraphQLSchema({ + types: [SomeTypeType, UserType] + }); +} +``` \ No newline at end of file diff --git a/src/tests/fixtures/field_values/LinkedFieldWithTypeArg.ts.expected b/src/tests/fixtures/field_values/LinkedFieldWithTypeArg.ts.expected deleted file mode 100644 index 45c9e351..00000000 --- a/src/tests/fixtures/field_values/LinkedFieldWithTypeArg.ts.expected +++ /dev/null @@ -1,70 +0,0 @@ ------------------ -INPUT ------------------ -/** @gqlType */ -class SomeType { - /** @gqlField */ - async me(): Promise> { - return new User(); - } -} - -/** @gqlType */ -class User { - /** @gqlField */ - name(): string { - return "Alice"; - } - /** @gqlField */ - friends(): User[] { - return [new User()]; - } - - other: T; -} - ------------------ -OUTPUT ------------------ --- SDL -- -type SomeType { - me: User -} - -type User { - friends: [User!] - name: String -} --- TypeScript -- -import { GraphQLSchema, GraphQLObjectType, GraphQLList, GraphQLNonNull, GraphQLString } from "graphql"; -export function getSchema(): GraphQLSchema { - const UserType: GraphQLObjectType = new GraphQLObjectType({ - name: "User", - fields() { - return { - friends: { - name: "friends", - type: new GraphQLList(new GraphQLNonNull(UserType)) - }, - name: { - name: "name", - type: GraphQLString - } - }; - } - }); - const SomeTypeType: GraphQLObjectType = new GraphQLObjectType({ - name: "SomeType", - fields() { - return { - me: { - name: "me", - type: UserType - } - }; - } - }); - return new GraphQLSchema({ - types: [SomeTypeType, UserType] - }); -} diff --git a/src/tests/fixtures/field_values/LinkedFieldWithTypeArg.ts.expected.md b/src/tests/fixtures/field_values/LinkedFieldWithTypeArg.ts.expected.md new file mode 100644 index 00000000..d0d902f1 --- /dev/null +++ b/src/tests/fixtures/field_values/LinkedFieldWithTypeArg.ts.expected.md @@ -0,0 +1,77 @@ +## input + +```ts title="field_values/LinkedFieldWithTypeArg.ts" +/** @gqlType */ +class SomeType { + /** @gqlField */ + async me(): Promise> { + return new User(); + } +} + +/** @gqlType */ +class User { + /** @gqlField */ + name(): string { + return "Alice"; + } + /** @gqlField */ + friends(): User[] { + return [new User()]; + } + + other: T; +} +``` + +## Output + +### SDL + +```graphql +type SomeType { + me: User +} + +type User { + friends: [User!] + name: String +} +``` + +### TypeScript + +```ts +import { GraphQLSchema, GraphQLObjectType, GraphQLList, GraphQLNonNull, GraphQLString } from "graphql"; +export function getSchema(): GraphQLSchema { + const UserType: GraphQLObjectType = new GraphQLObjectType({ + name: "User", + fields() { + return { + friends: { + name: "friends", + type: new GraphQLList(new GraphQLNonNull(UserType)) + }, + name: { + name: "name", + type: GraphQLString + } + }; + } + }); + const SomeTypeType: GraphQLObjectType = new GraphQLObjectType({ + name: "SomeType", + fields() { + return { + me: { + name: "me", + type: UserType + } + }; + } + }); + return new GraphQLSchema({ + types: [SomeTypeType, UserType] + }); +} +``` \ No newline at end of file diff --git a/src/tests/fixtures/field_values/MaybePromise.ts.expected b/src/tests/fixtures/field_values/MaybePromise.ts.expected deleted file mode 100644 index 4e01479f..00000000 --- a/src/tests/fixtures/field_values/MaybePromise.ts.expected +++ /dev/null @@ -1,34 +0,0 @@ ------------------ -INPUT ------------------ -/** @gqlType */ -export default class SomeType { - /** @gqlField */ - b: Promise | null; -} - ------------------ -OUTPUT ------------------ --- SDL -- -type SomeType { - b: String -} --- TypeScript -- -import { GraphQLSchema, GraphQLObjectType, GraphQLString } from "graphql"; -export function getSchema(): GraphQLSchema { - const SomeTypeType: GraphQLObjectType = new GraphQLObjectType({ - name: "SomeType", - fields() { - return { - b: { - name: "b", - type: GraphQLString - } - }; - } - }); - return new GraphQLSchema({ - types: [SomeTypeType] - }); -} diff --git a/src/tests/fixtures/field_values/MaybePromise.ts.expected.md b/src/tests/fixtures/field_values/MaybePromise.ts.expected.md new file mode 100644 index 00000000..be404024 --- /dev/null +++ b/src/tests/fixtures/field_values/MaybePromise.ts.expected.md @@ -0,0 +1,41 @@ +## input + +```ts title="field_values/MaybePromise.ts" +/** @gqlType */ +export default class SomeType { + /** @gqlField */ + b: Promise | null; +} +``` + +## Output + +### SDL + +```graphql +type SomeType { + b: String +} +``` + +### TypeScript + +```ts +import { GraphQLSchema, GraphQLObjectType, GraphQLString } from "graphql"; +export function getSchema(): GraphQLSchema { + const SomeTypeType: GraphQLObjectType = new GraphQLObjectType({ + name: "SomeType", + fields() { + return { + b: { + name: "b", + type: GraphQLString + } + }; + } + }); + return new GraphQLSchema({ + types: [SomeTypeType] + }); +} +``` \ No newline at end of file diff --git a/src/tests/fixtures/field_values/OptionalFields.ts.expected b/src/tests/fixtures/field_values/OptionalFields.ts.expected deleted file mode 100644 index c1439640..00000000 --- a/src/tests/fixtures/field_values/OptionalFields.ts.expected +++ /dev/null @@ -1,63 +0,0 @@ ------------------ -INPUT ------------------ -/** @gqlType */ -export default class SomeType { - /** @gqlField */ - hello(): string | void { - return "Hello world!"; - } - /** @gqlField */ - goodbye(): string | null { - return "Hello world!"; - } - /** @gqlField */ - farewell(): string | null | void | undefined { - return "Hello world!"; - } - /** @gqlField */ - async adieu(): Promise { - return "Hello world!"; - } -} - ------------------ -OUTPUT ------------------ --- SDL -- -type SomeType { - adieu: String - farewell: String - goodbye: String - hello: String -} --- TypeScript -- -import { GraphQLSchema, GraphQLObjectType, GraphQLString } from "graphql"; -export function getSchema(): GraphQLSchema { - const SomeTypeType: GraphQLObjectType = new GraphQLObjectType({ - name: "SomeType", - fields() { - return { - adieu: { - name: "adieu", - type: GraphQLString - }, - farewell: { - name: "farewell", - type: GraphQLString - }, - goodbye: { - name: "goodbye", - type: GraphQLString - }, - hello: { - name: "hello", - type: GraphQLString - } - }; - } - }); - return new GraphQLSchema({ - types: [SomeTypeType] - }); -} diff --git a/src/tests/fixtures/field_values/OptionalFields.ts.expected.md b/src/tests/fixtures/field_values/OptionalFields.ts.expected.md new file mode 100644 index 00000000..2996f932 --- /dev/null +++ b/src/tests/fixtures/field_values/OptionalFields.ts.expected.md @@ -0,0 +1,70 @@ +## input + +```ts title="field_values/OptionalFields.ts" +/** @gqlType */ +export default class SomeType { + /** @gqlField */ + hello(): string | void { + return "Hello world!"; + } + /** @gqlField */ + goodbye(): string | null { + return "Hello world!"; + } + /** @gqlField */ + farewell(): string | null | void | undefined { + return "Hello world!"; + } + /** @gqlField */ + async adieu(): Promise { + return "Hello world!"; + } +} +``` + +## Output + +### SDL + +```graphql +type SomeType { + adieu: String + farewell: String + goodbye: String + hello: String +} +``` + +### TypeScript + +```ts +import { GraphQLSchema, GraphQLObjectType, GraphQLString } from "graphql"; +export function getSchema(): GraphQLSchema { + const SomeTypeType: GraphQLObjectType = new GraphQLObjectType({ + name: "SomeType", + fields() { + return { + adieu: { + name: "adieu", + type: GraphQLString + }, + farewell: { + name: "farewell", + type: GraphQLString + }, + goodbye: { + name: "goodbye", + type: GraphQLString + }, + hello: { + name: "hello", + type: GraphQLString + } + }; + } + }); + return new GraphQLSchema({ + types: [SomeTypeType] + }); +} +``` \ No newline at end of file diff --git a/src/tests/fixtures/field_values/OptionalProperty.ts.expected b/src/tests/fixtures/field_values/OptionalProperty.ts.expected deleted file mode 100644 index 1ec2c7dd..00000000 --- a/src/tests/fixtures/field_values/OptionalProperty.ts.expected +++ /dev/null @@ -1,34 +0,0 @@ ------------------ -INPUT ------------------ -/** @gqlType */ -export default class SomeType { - /** @gqlField */ - hello?: string; -} - ------------------ -OUTPUT ------------------ --- SDL -- -type SomeType { - hello: String -} --- TypeScript -- -import { GraphQLSchema, GraphQLObjectType, GraphQLString } from "graphql"; -export function getSchema(): GraphQLSchema { - const SomeTypeType: GraphQLObjectType = new GraphQLObjectType({ - name: "SomeType", - fields() { - return { - hello: { - name: "hello", - type: GraphQLString - } - }; - } - }); - return new GraphQLSchema({ - types: [SomeTypeType] - }); -} diff --git a/src/tests/fixtures/field_values/OptionalProperty.ts.expected.md b/src/tests/fixtures/field_values/OptionalProperty.ts.expected.md new file mode 100644 index 00000000..3a1cd09b --- /dev/null +++ b/src/tests/fixtures/field_values/OptionalProperty.ts.expected.md @@ -0,0 +1,41 @@ +## input + +```ts title="field_values/OptionalProperty.ts" +/** @gqlType */ +export default class SomeType { + /** @gqlField */ + hello?: string; +} +``` + +## Output + +### SDL + +```graphql +type SomeType { + hello: String +} +``` + +### TypeScript + +```ts +import { GraphQLSchema, GraphQLObjectType, GraphQLString } from "graphql"; +export function getSchema(): GraphQLSchema { + const SomeTypeType: GraphQLObjectType = new GraphQLObjectType({ + name: "SomeType", + fields() { + return { + hello: { + name: "hello", + type: GraphQLString + } + }; + } + }); + return new GraphQLSchema({ + types: [SomeTypeType] + }); +} +``` \ No newline at end of file diff --git a/src/tests/fixtures/field_values/OptionalStringFieldKillsParentOnException.invalid.ts.expected b/src/tests/fixtures/field_values/OptionalStringFieldKillsParentOnException.invalid.ts.expected deleted file mode 100644 index 2c2bcf8e..00000000 --- a/src/tests/fixtures/field_values/OptionalStringFieldKillsParentOnException.invalid.ts.expected +++ /dev/null @@ -1,21 +0,0 @@ ------------------ -INPUT ------------------ -/** @gqlType */ -export default class SomeType { - /** - * @gqlField - * @killsParentOnException - */ - hello(): string | null { - return "Hello world!"; - } -} - ------------------ -OUTPUT ------------------ -src/tests/fixtures/field_values/OptionalStringFieldKillsParentOnException.invalid.ts:5:7 - error: Unexpected `@killsParentOnException` tag on field typed as nullable. `@killsParentOnException` will force a field to appear as non-nullable in the schema, so its implementation must also be non-nullable. . - -5 * @killsParentOnException - ~~~~~~~~~~~~~~~~~~~~~~ diff --git a/src/tests/fixtures/field_values/OptionalStringFieldKillsParentOnException.invalid.ts.expected.md b/src/tests/fixtures/field_values/OptionalStringFieldKillsParentOnException.invalid.ts.expected.md new file mode 100644 index 00000000..83648d86 --- /dev/null +++ b/src/tests/fixtures/field_values/OptionalStringFieldKillsParentOnException.invalid.ts.expected.md @@ -0,0 +1,25 @@ +## input + +```ts title="field_values/OptionalStringFieldKillsParentOnException.invalid.ts" +/** @gqlType */ +export default class SomeType { + /** + * @gqlField + * @killsParentOnException + */ + hello(): string | null { + return "Hello world!"; + } +} +``` + +## Output + +### Error Report + +```text +src/tests/fixtures/field_values/OptionalStringFieldKillsParentOnException.invalid.ts:5:7 - error: Unexpected `@killsParentOnException` tag on field typed as nullable. `@killsParentOnException` will force a field to appear as non-nullable in the schema, so its implementation must also be non-nullable. . + +5 * @killsParentOnException + ~~~~~~~~~~~~~~~~~~~~~~ +``` \ No newline at end of file diff --git a/src/tests/fixtures/field_values/ParenthesizedType.ts.expected b/src/tests/fixtures/field_values/ParenthesizedType.ts.expected deleted file mode 100644 index acf67fac..00000000 --- a/src/tests/fixtures/field_values/ParenthesizedType.ts.expected +++ /dev/null @@ -1,36 +0,0 @@ ------------------ -INPUT ------------------ -/** @gqlType */ -export default class SomeType { - /** @gqlField */ - hello(): (string | null)[] { - return ["Hello world!"]; - } -} - ------------------ -OUTPUT ------------------ --- SDL -- -type SomeType { - hello: [String] -} --- TypeScript -- -import { GraphQLSchema, GraphQLObjectType, GraphQLList, GraphQLString } from "graphql"; -export function getSchema(): GraphQLSchema { - const SomeTypeType: GraphQLObjectType = new GraphQLObjectType({ - name: "SomeType", - fields() { - return { - hello: { - name: "hello", - type: new GraphQLList(GraphQLString) - } - }; - } - }); - return new GraphQLSchema({ - types: [SomeTypeType] - }); -} diff --git a/src/tests/fixtures/field_values/ParenthesizedType.ts.expected.md b/src/tests/fixtures/field_values/ParenthesizedType.ts.expected.md new file mode 100644 index 00000000..a705c3df --- /dev/null +++ b/src/tests/fixtures/field_values/ParenthesizedType.ts.expected.md @@ -0,0 +1,43 @@ +## input + +```ts title="field_values/ParenthesizedType.ts" +/** @gqlType */ +export default class SomeType { + /** @gqlField */ + hello(): (string | null)[] { + return ["Hello world!"]; + } +} +``` + +## Output + +### SDL + +```graphql +type SomeType { + hello: [String] +} +``` + +### TypeScript + +```ts +import { GraphQLSchema, GraphQLObjectType, GraphQLList, GraphQLString } from "graphql"; +export function getSchema(): GraphQLSchema { + const SomeTypeType: GraphQLObjectType = new GraphQLObjectType({ + name: "SomeType", + fields() { + return { + hello: { + name: "hello", + type: new GraphQLList(GraphQLString) + } + }; + } + }); + return new GraphQLSchema({ + types: [SomeTypeType] + }); +} +``` \ No newline at end of file diff --git a/src/tests/fixtures/field_values/PromiseOfPromise.ts.expected b/src/tests/fixtures/field_values/PromiseOfPromise.ts.expected deleted file mode 100644 index e84ff807..00000000 --- a/src/tests/fixtures/field_values/PromiseOfPromise.ts.expected +++ /dev/null @@ -1,34 +0,0 @@ ------------------ -INPUT ------------------ -/** @gqlType */ -export default class SomeType { - /** @gqlField */ - b: Promise>; -} - ------------------ -OUTPUT ------------------ --- SDL -- -type SomeType { - b: String -} --- TypeScript -- -import { GraphQLSchema, GraphQLObjectType, GraphQLString } from "graphql"; -export function getSchema(): GraphQLSchema { - const SomeTypeType: GraphQLObjectType = new GraphQLObjectType({ - name: "SomeType", - fields() { - return { - b: { - name: "b", - type: GraphQLString - } - }; - } - }); - return new GraphQLSchema({ - types: [SomeTypeType] - }); -} diff --git a/src/tests/fixtures/field_values/PromiseOfPromise.ts.expected.md b/src/tests/fixtures/field_values/PromiseOfPromise.ts.expected.md new file mode 100644 index 00000000..6d1b5224 --- /dev/null +++ b/src/tests/fixtures/field_values/PromiseOfPromise.ts.expected.md @@ -0,0 +1,41 @@ +## input + +```ts title="field_values/PromiseOfPromise.ts" +/** @gqlType */ +export default class SomeType { + /** @gqlField */ + b: Promise>; +} +``` + +## Output + +### SDL + +```graphql +type SomeType { + b: String +} +``` + +### TypeScript + +```ts +import { GraphQLSchema, GraphQLObjectType, GraphQLString } from "graphql"; +export function getSchema(): GraphQLSchema { + const SomeTypeType: GraphQLObjectType = new GraphQLObjectType({ + name: "SomeType", + fields() { + return { + b: { + name: "b", + type: GraphQLString + } + }; + } + }); + return new GraphQLSchema({ + types: [SomeTypeType] + }); +} +``` \ No newline at end of file diff --git a/src/tests/fixtures/field_values/ReadonlyArrayField.ts.expected b/src/tests/fixtures/field_values/ReadonlyArrayField.ts.expected deleted file mode 100644 index f07eadc5..00000000 --- a/src/tests/fixtures/field_values/ReadonlyArrayField.ts.expected +++ /dev/null @@ -1,36 +0,0 @@ ------------------ -INPUT ------------------ -/** @gqlType */ -export default class SomeType { - /** @gqlField */ - hello(): ReadonlyArray { - return ["Hello world!"]; - } -} - ------------------ -OUTPUT ------------------ --- SDL -- -type SomeType { - hello: [String!] -} --- TypeScript -- -import { GraphQLSchema, GraphQLObjectType, GraphQLList, GraphQLNonNull, GraphQLString } from "graphql"; -export function getSchema(): GraphQLSchema { - const SomeTypeType: GraphQLObjectType = new GraphQLObjectType({ - name: "SomeType", - fields() { - return { - hello: { - name: "hello", - type: new GraphQLList(new GraphQLNonNull(GraphQLString)) - } - }; - } - }); - return new GraphQLSchema({ - types: [SomeTypeType] - }); -} diff --git a/src/tests/fixtures/field_values/ReadonlyArrayField.ts.expected.md b/src/tests/fixtures/field_values/ReadonlyArrayField.ts.expected.md new file mode 100644 index 00000000..58095483 --- /dev/null +++ b/src/tests/fixtures/field_values/ReadonlyArrayField.ts.expected.md @@ -0,0 +1,43 @@ +## input + +```ts title="field_values/ReadonlyArrayField.ts" +/** @gqlType */ +export default class SomeType { + /** @gqlField */ + hello(): ReadonlyArray { + return ["Hello world!"]; + } +} +``` + +## Output + +### SDL + +```graphql +type SomeType { + hello: [String!] +} +``` + +### TypeScript + +```ts +import { GraphQLSchema, GraphQLObjectType, GraphQLList, GraphQLNonNull, GraphQLString } from "graphql"; +export function getSchema(): GraphQLSchema { + const SomeTypeType: GraphQLObjectType = new GraphQLObjectType({ + name: "SomeType", + fields() { + return { + hello: { + name: "hello", + type: new GraphQLList(new GraphQLNonNull(GraphQLString)) + } + }; + } + }); + return new GraphQLSchema({ + types: [SomeTypeType] + }); +} +``` \ No newline at end of file diff --git a/src/tests/fixtures/field_values/RenamedType.ts.expected b/src/tests/fixtures/field_values/RenamedType.ts.expected deleted file mode 100644 index e6ed6017..00000000 --- a/src/tests/fixtures/field_values/RenamedType.ts.expected +++ /dev/null @@ -1,55 +0,0 @@ ------------------ -INPUT ------------------ -/** @gqlType User */ -class UserResolver { - /** @gqlField */ - name: string; -} - -/** @gqlType */ -class SomeType { - /** @gqlField */ - me: UserResolver; -} - ------------------ -OUTPUT ------------------ --- SDL -- -type SomeType { - me: User -} - -type User { - name: String -} --- TypeScript -- -import { GraphQLSchema, GraphQLObjectType, GraphQLString } from "graphql"; -export function getSchema(): GraphQLSchema { - const UserType: GraphQLObjectType = new GraphQLObjectType({ - name: "User", - fields() { - return { - name: { - name: "name", - type: GraphQLString - } - }; - } - }); - const SomeTypeType: GraphQLObjectType = new GraphQLObjectType({ - name: "SomeType", - fields() { - return { - me: { - name: "me", - type: UserType - } - }; - } - }); - return new GraphQLSchema({ - types: [SomeTypeType, UserType] - }); -} diff --git a/src/tests/fixtures/field_values/RenamedType.ts.expected.md b/src/tests/fixtures/field_values/RenamedType.ts.expected.md new file mode 100644 index 00000000..b528acfe --- /dev/null +++ b/src/tests/fixtures/field_values/RenamedType.ts.expected.md @@ -0,0 +1,62 @@ +## input + +```ts title="field_values/RenamedType.ts" +/** @gqlType User */ +class UserResolver { + /** @gqlField */ + name: string; +} + +/** @gqlType */ +class SomeType { + /** @gqlField */ + me: UserResolver; +} +``` + +## Output + +### SDL + +```graphql +type SomeType { + me: User +} + +type User { + name: String +} +``` + +### TypeScript + +```ts +import { GraphQLSchema, GraphQLObjectType, GraphQLString } from "graphql"; +export function getSchema(): GraphQLSchema { + const UserType: GraphQLObjectType = new GraphQLObjectType({ + name: "User", + fields() { + return { + name: { + name: "name", + type: GraphQLString + } + }; + } + }); + const SomeTypeType: GraphQLObjectType = new GraphQLObjectType({ + name: "SomeType", + fields() { + return { + me: { + name: "me", + type: UserType + } + }; + } + }); + return new GraphQLSchema({ + types: [SomeTypeType, UserType] + }); +} +``` \ No newline at end of file diff --git a/src/tests/fixtures/field_values/RenamedTypeOutOfOrder.ts.expected b/src/tests/fixtures/field_values/RenamedTypeOutOfOrder.ts.expected deleted file mode 100644 index 0292e546..00000000 --- a/src/tests/fixtures/field_values/RenamedTypeOutOfOrder.ts.expected +++ /dev/null @@ -1,55 +0,0 @@ ------------------ -INPUT ------------------ -/** @gqlType */ -class SomeType { - /** @gqlField */ - me: UserResolver; -} - -/** @gqlType User */ -class UserResolver { - /** @gqlField */ - name: string; -} - ------------------ -OUTPUT ------------------ --- SDL -- -type SomeType { - me: User -} - -type User { - name: String -} --- TypeScript -- -import { GraphQLSchema, GraphQLObjectType, GraphQLString } from "graphql"; -export function getSchema(): GraphQLSchema { - const UserType: GraphQLObjectType = new GraphQLObjectType({ - name: "User", - fields() { - return { - name: { - name: "name", - type: GraphQLString - } - }; - } - }); - const SomeTypeType: GraphQLObjectType = new GraphQLObjectType({ - name: "SomeType", - fields() { - return { - me: { - name: "me", - type: UserType - } - }; - } - }); - return new GraphQLSchema({ - types: [SomeTypeType, UserType] - }); -} diff --git a/src/tests/fixtures/field_values/RenamedTypeOutOfOrder.ts.expected.md b/src/tests/fixtures/field_values/RenamedTypeOutOfOrder.ts.expected.md new file mode 100644 index 00000000..56ac7b17 --- /dev/null +++ b/src/tests/fixtures/field_values/RenamedTypeOutOfOrder.ts.expected.md @@ -0,0 +1,62 @@ +## input + +```ts title="field_values/RenamedTypeOutOfOrder.ts" +/** @gqlType */ +class SomeType { + /** @gqlField */ + me: UserResolver; +} + +/** @gqlType User */ +class UserResolver { + /** @gqlField */ + name: string; +} +``` + +## Output + +### SDL + +```graphql +type SomeType { + me: User +} + +type User { + name: String +} +``` + +### TypeScript + +```ts +import { GraphQLSchema, GraphQLObjectType, GraphQLString } from "graphql"; +export function getSchema(): GraphQLSchema { + const UserType: GraphQLObjectType = new GraphQLObjectType({ + name: "User", + fields() { + return { + name: { + name: "name", + type: GraphQLString + } + }; + } + }); + const SomeTypeType: GraphQLObjectType = new GraphQLObjectType({ + name: "SomeType", + fields() { + return { + me: { + name: "me", + type: UserType + } + }; + } + }); + return new GraphQLSchema({ + types: [SomeTypeType, UserType] + }); +} +``` \ No newline at end of file diff --git a/src/tests/fixtures/field_values/StringField.ts.expected b/src/tests/fixtures/field_values/StringField.ts.expected deleted file mode 100644 index c4a78eab..00000000 --- a/src/tests/fixtures/field_values/StringField.ts.expected +++ /dev/null @@ -1,36 +0,0 @@ ------------------ -INPUT ------------------ -/** @gqlType */ -export default class SomeType { - /** @gqlField */ - hello(): string { - return "Hello world!"; - } -} - ------------------ -OUTPUT ------------------ --- SDL -- -type SomeType { - hello: String -} --- TypeScript -- -import { GraphQLSchema, GraphQLObjectType, GraphQLString } from "graphql"; -export function getSchema(): GraphQLSchema { - const SomeTypeType: GraphQLObjectType = new GraphQLObjectType({ - name: "SomeType", - fields() { - return { - hello: { - name: "hello", - type: GraphQLString - } - }; - } - }); - return new GraphQLSchema({ - types: [SomeTypeType] - }); -} diff --git a/src/tests/fixtures/field_values/StringField.ts.expected.md b/src/tests/fixtures/field_values/StringField.ts.expected.md new file mode 100644 index 00000000..a03f5c2e --- /dev/null +++ b/src/tests/fixtures/field_values/StringField.ts.expected.md @@ -0,0 +1,43 @@ +## input + +```ts title="field_values/StringField.ts" +/** @gqlType */ +export default class SomeType { + /** @gqlField */ + hello(): string { + return "Hello world!"; + } +} +``` + +## Output + +### SDL + +```graphql +type SomeType { + hello: String +} +``` + +### TypeScript + +```ts +import { GraphQLSchema, GraphQLObjectType, GraphQLString } from "graphql"; +export function getSchema(): GraphQLSchema { + const SomeTypeType: GraphQLObjectType = new GraphQLObjectType({ + name: "SomeType", + fields() { + return { + hello: { + name: "hello", + type: GraphQLString + } + }; + } + }); + return new GraphQLSchema({ + types: [SomeTypeType] + }); +} +``` \ No newline at end of file diff --git a/src/tests/fixtures/field_values/StringFieldKillsParentOnException.ts.expected b/src/tests/fixtures/field_values/StringFieldKillsParentOnException.ts.expected deleted file mode 100644 index 69b3feb7..00000000 --- a/src/tests/fixtures/field_values/StringFieldKillsParentOnException.ts.expected +++ /dev/null @@ -1,39 +0,0 @@ ------------------ -INPUT ------------------ -/** @gqlType */ -export default class SomeType { - /** - * @gqlField - * @killsParentOnException - */ - hello(): string { - return "Hello world!"; - } -} - ------------------ -OUTPUT ------------------ --- SDL -- -type SomeType { - hello: String! -} --- TypeScript -- -import { GraphQLSchema, GraphQLObjectType, GraphQLNonNull, GraphQLString } from "graphql"; -export function getSchema(): GraphQLSchema { - const SomeTypeType: GraphQLObjectType = new GraphQLObjectType({ - name: "SomeType", - fields() { - return { - hello: { - name: "hello", - type: new GraphQLNonNull(GraphQLString) - } - }; - } - }); - return new GraphQLSchema({ - types: [SomeTypeType] - }); -} diff --git a/src/tests/fixtures/field_values/StringFieldKillsParentOnException.ts.expected.md b/src/tests/fixtures/field_values/StringFieldKillsParentOnException.ts.expected.md new file mode 100644 index 00000000..74c556f9 --- /dev/null +++ b/src/tests/fixtures/field_values/StringFieldKillsParentOnException.ts.expected.md @@ -0,0 +1,46 @@ +## input + +```ts title="field_values/StringFieldKillsParentOnException.ts" +/** @gqlType */ +export default class SomeType { + /** + * @gqlField + * @killsParentOnException + */ + hello(): string { + return "Hello world!"; + } +} +``` + +## Output + +### SDL + +```graphql +type SomeType { + hello: String! +} +``` + +### TypeScript + +```ts +import { GraphQLSchema, GraphQLObjectType, GraphQLNonNull, GraphQLString } from "graphql"; +export function getSchema(): GraphQLSchema { + const SomeTypeType: GraphQLObjectType = new GraphQLObjectType({ + name: "SomeType", + fields() { + return { + hello: { + name: "hello", + type: new GraphQLNonNull(GraphQLString) + } + }; + } + }); + return new GraphQLSchema({ + types: [SomeTypeType] + }); +} +``` \ No newline at end of file diff --git a/src/tests/fixtures/field_values/StringFieldKillsParentOnExceptionWithoutNullableByDefaultEnables.invalid.ts.expected b/src/tests/fixtures/field_values/StringFieldKillsParentOnExceptionWithoutNullableByDefaultEnables.invalid.ts.expected deleted file mode 100644 index 8340fb97..00000000 --- a/src/tests/fixtures/field_values/StringFieldKillsParentOnExceptionWithoutNullableByDefaultEnables.invalid.ts.expected +++ /dev/null @@ -1,22 +0,0 @@ ------------------ -INPUT ------------------ -// { "nullableByDefault": false } -/** @gqlType */ -export default class SomeType { - /** - * @gqlField - * @killsParentOnException - */ - hello(): string { - return "Hello world!"; - } -} - ------------------ -OUTPUT ------------------ -src/tests/fixtures/field_values/StringFieldKillsParentOnExceptionWithoutNullableByDefaultEnables.invalid.ts:6:7 - error: Unexpected `@killsParentOnException` tag. `@killsParentOnException` is only supported when the Grats config option `nullableByDefault` is enabled in your `tsconfig.json`. - -6 * @killsParentOnException - ~~~~~~~~~~~~~~~~~~~~~~ diff --git a/src/tests/fixtures/field_values/StringFieldKillsParentOnExceptionWithoutNullableByDefaultEnables.invalid.ts.expected.md b/src/tests/fixtures/field_values/StringFieldKillsParentOnExceptionWithoutNullableByDefaultEnables.invalid.ts.expected.md new file mode 100644 index 00000000..d2329f25 --- /dev/null +++ b/src/tests/fixtures/field_values/StringFieldKillsParentOnExceptionWithoutNullableByDefaultEnables.invalid.ts.expected.md @@ -0,0 +1,26 @@ +## input + +```ts title="field_values/StringFieldKillsParentOnExceptionWithoutNullableByDefaultEnables.invalid.ts" +// { "nullableByDefault": false } +/** @gqlType */ +export default class SomeType { + /** + * @gqlField + * @killsParentOnException + */ + hello(): string { + return "Hello world!"; + } +} +``` + +## Output + +### Error Report + +```text +src/tests/fixtures/field_values/StringFieldKillsParentOnExceptionWithoutNullableByDefaultEnables.invalid.ts:6:7 - error: Unexpected `@killsParentOnException` tag. `@killsParentOnException` is only supported when the Grats config option `nullableByDefault` is enabled in your `tsconfig.json`. + +6 * @killsParentOnException + ~~~~~~~~~~~~~~~~~~~~~~ +``` \ No newline at end of file diff --git a/src/tests/fixtures/field_values/UnionField.ts.expected b/src/tests/fixtures/field_values/UnionField.ts.expected deleted file mode 100644 index 5e6dd3c9..00000000 --- a/src/tests/fixtures/field_values/UnionField.ts.expected +++ /dev/null @@ -1,91 +0,0 @@ ------------------ -INPUT ------------------ -/** @gqlType */ -export default class SomeType { - /** @gqlField */ - me: Actor; -} - -/** @gqlType */ -class User { - __typename = "User" as const; - /** @gqlField */ - name: string; -} - -/** @gqlType */ -class Entity { - __typename = "Entity" as const; - /** @gqlField */ - description: string; -} - -/** - * @gqlUnion - */ -type Actor = User | Entity; - ------------------ -OUTPUT ------------------ --- SDL -- -union Actor = Entity | User - -type Entity { - description: String -} - -type SomeType { - me: Actor -} - -type User { - name: String -} --- TypeScript -- -import { GraphQLSchema, GraphQLUnionType, GraphQLObjectType, GraphQLString } from "graphql"; -export function getSchema(): GraphQLSchema { - const EntityType: GraphQLObjectType = new GraphQLObjectType({ - name: "Entity", - fields() { - return { - description: { - name: "description", - type: GraphQLString - } - }; - } - }); - const UserType: GraphQLObjectType = new GraphQLObjectType({ - name: "User", - fields() { - return { - name: { - name: "name", - type: GraphQLString - } - }; - } - }); - const ActorType: GraphQLUnionType = new GraphQLUnionType({ - name: "Actor", - types() { - return [EntityType, UserType]; - } - }); - const SomeTypeType: GraphQLObjectType = new GraphQLObjectType({ - name: "SomeType", - fields() { - return { - me: { - name: "me", - type: ActorType - } - }; - } - }); - return new GraphQLSchema({ - types: [ActorType, EntityType, SomeTypeType, UserType] - }); -} diff --git a/src/tests/fixtures/field_values/UnionField.ts.expected.md b/src/tests/fixtures/field_values/UnionField.ts.expected.md new file mode 100644 index 00000000..6c4004ef --- /dev/null +++ b/src/tests/fixtures/field_values/UnionField.ts.expected.md @@ -0,0 +1,98 @@ +## input + +```ts title="field_values/UnionField.ts" +/** @gqlType */ +export default class SomeType { + /** @gqlField */ + me: Actor; +} + +/** @gqlType */ +class User { + __typename = "User" as const; + /** @gqlField */ + name: string; +} + +/** @gqlType */ +class Entity { + __typename = "Entity" as const; + /** @gqlField */ + description: string; +} + +/** + * @gqlUnion + */ +type Actor = User | Entity; +``` + +## Output + +### SDL + +```graphql +union Actor = Entity | User + +type Entity { + description: String +} + +type SomeType { + me: Actor +} + +type User { + name: String +} +``` + +### TypeScript + +```ts +import { GraphQLSchema, GraphQLUnionType, GraphQLObjectType, GraphQLString } from "graphql"; +export function getSchema(): GraphQLSchema { + const EntityType: GraphQLObjectType = new GraphQLObjectType({ + name: "Entity", + fields() { + return { + description: { + name: "description", + type: GraphQLString + } + }; + } + }); + const UserType: GraphQLObjectType = new GraphQLObjectType({ + name: "User", + fields() { + return { + name: { + name: "name", + type: GraphQLString + } + }; + } + }); + const ActorType: GraphQLUnionType = new GraphQLUnionType({ + name: "Actor", + types() { + return [EntityType, UserType]; + } + }); + const SomeTypeType: GraphQLObjectType = new GraphQLObjectType({ + name: "SomeType", + fields() { + return { + me: { + name: "me", + type: ActorType + } + }; + } + }); + return new GraphQLSchema({ + types: [ActorType, EntityType, SomeTypeType, UserType] + }); +} +``` \ No newline at end of file diff --git a/src/tests/fixtures/field_values/non_default_nullable/NonNullablePromise.ts.expected b/src/tests/fixtures/field_values/non_default_nullable/NonNullablePromise.ts.expected deleted file mode 100644 index 67a6e38b..00000000 --- a/src/tests/fixtures/field_values/non_default_nullable/NonNullablePromise.ts.expected +++ /dev/null @@ -1,37 +0,0 @@ ------------------ -INPUT ------------------ -// { "nullableByDefault": false } -/** @gqlType */ -export default class SomeType { - /** @gqlField */ - hello(): Promise { - return Promise.resolve("Hello world!"); - } -} - ------------------ -OUTPUT ------------------ --- SDL -- -type SomeType { - hello: String! -} --- TypeScript -- -import { GraphQLSchema, GraphQLObjectType, GraphQLNonNull, GraphQLString } from "graphql"; -export function getSchema(): GraphQLSchema { - const SomeTypeType: GraphQLObjectType = new GraphQLObjectType({ - name: "SomeType", - fields() { - return { - hello: { - name: "hello", - type: new GraphQLNonNull(GraphQLString) - } - }; - } - }); - return new GraphQLSchema({ - types: [SomeTypeType] - }); -} diff --git a/src/tests/fixtures/field_values/non_default_nullable/NonNullablePromise.ts.expected.md b/src/tests/fixtures/field_values/non_default_nullable/NonNullablePromise.ts.expected.md new file mode 100644 index 00000000..4ebe2799 --- /dev/null +++ b/src/tests/fixtures/field_values/non_default_nullable/NonNullablePromise.ts.expected.md @@ -0,0 +1,44 @@ +## input + +```ts title="field_values/non_default_nullable/NonNullablePromise.ts" +// { "nullableByDefault": false } +/** @gqlType */ +export default class SomeType { + /** @gqlField */ + hello(): Promise { + return Promise.resolve("Hello world!"); + } +} +``` + +## Output + +### SDL + +```graphql +type SomeType { + hello: String! +} +``` + +### TypeScript + +```ts +import { GraphQLSchema, GraphQLObjectType, GraphQLNonNull, GraphQLString } from "graphql"; +export function getSchema(): GraphQLSchema { + const SomeTypeType: GraphQLObjectType = new GraphQLObjectType({ + name: "SomeType", + fields() { + return { + hello: { + name: "hello", + type: new GraphQLNonNull(GraphQLString) + } + }; + } + }); + return new GraphQLSchema({ + types: [SomeTypeType] + }); +} +``` \ No newline at end of file diff --git a/src/tests/fixtures/field_values/non_default_nullable/NullablePromise.ts.expected b/src/tests/fixtures/field_values/non_default_nullable/NullablePromise.ts.expected deleted file mode 100644 index 05c16424..00000000 --- a/src/tests/fixtures/field_values/non_default_nullable/NullablePromise.ts.expected +++ /dev/null @@ -1,37 +0,0 @@ ------------------ -INPUT ------------------ -// { "nullableByDefault": false } -/** @gqlType */ -export default class SomeType { - /** @gqlField */ - hello(): Promise { - return Promise.resolve("Hello world!"); - } -} - ------------------ -OUTPUT ------------------ --- SDL -- -type SomeType { - hello: String -} --- TypeScript -- -import { GraphQLSchema, GraphQLObjectType, GraphQLString } from "graphql"; -export function getSchema(): GraphQLSchema { - const SomeTypeType: GraphQLObjectType = new GraphQLObjectType({ - name: "SomeType", - fields() { - return { - hello: { - name: "hello", - type: GraphQLString - } - }; - } - }); - return new GraphQLSchema({ - types: [SomeTypeType] - }); -} diff --git a/src/tests/fixtures/field_values/non_default_nullable/NullablePromise.ts.expected.md b/src/tests/fixtures/field_values/non_default_nullable/NullablePromise.ts.expected.md new file mode 100644 index 00000000..ea33b94a --- /dev/null +++ b/src/tests/fixtures/field_values/non_default_nullable/NullablePromise.ts.expected.md @@ -0,0 +1,44 @@ +## input + +```ts title="field_values/non_default_nullable/NullablePromise.ts" +// { "nullableByDefault": false } +/** @gqlType */ +export default class SomeType { + /** @gqlField */ + hello(): Promise { + return Promise.resolve("Hello world!"); + } +} +``` + +## Output + +### SDL + +```graphql +type SomeType { + hello: String +} +``` + +### TypeScript + +```ts +import { GraphQLSchema, GraphQLObjectType, GraphQLString } from "graphql"; +export function getSchema(): GraphQLSchema { + const SomeTypeType: GraphQLObjectType = new GraphQLObjectType({ + name: "SomeType", + fields() { + return { + hello: { + name: "hello", + type: GraphQLString + } + }; + } + }); + return new GraphQLSchema({ + types: [SomeTypeType] + }); +} +``` \ No newline at end of file diff --git a/src/tests/fixtures/generics/arrayPassedToGeneric.invalid.ts.expected b/src/tests/fixtures/generics/arrayPassedToGeneric.invalid.ts.expected deleted file mode 100644 index 2bd22901..00000000 --- a/src/tests/fixtures/generics/arrayPassedToGeneric.invalid.ts.expected +++ /dev/null @@ -1,62 +0,0 @@ ------------------ -INPUT ------------------ -/** @gqlType */ -type Page = { - /** @gqlField */ - name: string; -}; - -/** @gqlType */ -export type SomeType = { - /** @gqlField */ - someField: T; - /** @gqlField */ - cursor: string; -}; - -/** @gqlType */ -type Foo = { - // We should be able to support this eventually - /** @gqlField */ - a: SomeType; - // We should be able to support this eventually - /** @gqlField */ - b: SomeType>; - /** @gqlField */ - c: SomeType; -}; - ------------------ -OUTPUT ------------------ -src/tests/fixtures/generics/arrayPassedToGeneric.invalid.ts:19:15 - error: Expected `SomeType` to be passed a GraphQL type argument for type parameter `T`. - -19 a: SomeType; - ~~~~~~ - - src/tests/fixtures/generics/arrayPassedToGeneric.invalid.ts:8:22 - 8 export type SomeType = { - ~ - Type parameter `T` is defined here - src/tests/fixtures/generics/arrayPassedToGeneric.invalid.ts:10:14 - 10 someField: T; - ~ - and expects a GraphQL type because it was used in a GraphQL position here. -src/tests/fixtures/generics/arrayPassedToGeneric.invalid.ts:22:15 - error: Unable to resolve type reference. In order to generate a GraphQL schema, Grats needs to determine which GraphQL type is being referenced. This requires being able to resolve type references to their `@gql` annotated declaration. However this reference could not be resolved. Is it possible that this type is not defined in this file? - -22 b: SomeType>; - ~~~~~ -src/tests/fixtures/generics/arrayPassedToGeneric.invalid.ts:24:15 - error: Expected `SomeType` to be passed a GraphQL type argument for type parameter `T`. - -24 c: SomeType; - ~~~~~~~~~~~ - - src/tests/fixtures/generics/arrayPassedToGeneric.invalid.ts:8:22 - 8 export type SomeType = { - ~ - Type parameter `T` is defined here - src/tests/fixtures/generics/arrayPassedToGeneric.invalid.ts:10:14 - 10 someField: T; - ~ - and expects a GraphQL type because it was used in a GraphQL position here. diff --git a/src/tests/fixtures/generics/arrayPassedToGeneric.invalid.ts.expected.md b/src/tests/fixtures/generics/arrayPassedToGeneric.invalid.ts.expected.md new file mode 100644 index 00000000..7773059a --- /dev/null +++ b/src/tests/fixtures/generics/arrayPassedToGeneric.invalid.ts.expected.md @@ -0,0 +1,66 @@ +## input + +```ts title="generics/arrayPassedToGeneric.invalid.ts" +/** @gqlType */ +type Page = { + /** @gqlField */ + name: string; +}; + +/** @gqlType */ +export type SomeType = { + /** @gqlField */ + someField: T; + /** @gqlField */ + cursor: string; +}; + +/** @gqlType */ +type Foo = { + // We should be able to support this eventually + /** @gqlField */ + a: SomeType; + // We should be able to support this eventually + /** @gqlField */ + b: SomeType>; + /** @gqlField */ + c: SomeType; +}; +``` + +## Output + +### Error Report + +```text +src/tests/fixtures/generics/arrayPassedToGeneric.invalid.ts:19:15 - error: Expected `SomeType` to be passed a GraphQL type argument for type parameter `T`. + +19 a: SomeType; + ~~~~~~ + + src/tests/fixtures/generics/arrayPassedToGeneric.invalid.ts:8:22 + 8 export type SomeType = { + ~ + Type parameter `T` is defined here + src/tests/fixtures/generics/arrayPassedToGeneric.invalid.ts:10:14 + 10 someField: T; + ~ + and expects a GraphQL type because it was used in a GraphQL position here. +src/tests/fixtures/generics/arrayPassedToGeneric.invalid.ts:22:15 - error: Unable to resolve type reference. In order to generate a GraphQL schema, Grats needs to determine which GraphQL type is being referenced. This requires being able to resolve type references to their `@gql` annotated declaration. However this reference could not be resolved. Is it possible that this type is not defined in this file? + +22 b: SomeType>; + ~~~~~ +src/tests/fixtures/generics/arrayPassedToGeneric.invalid.ts:24:15 - error: Expected `SomeType` to be passed a GraphQL type argument for type parameter `T`. + +24 c: SomeType; + ~~~~~~~~~~~ + + src/tests/fixtures/generics/arrayPassedToGeneric.invalid.ts:8:22 + 8 export type SomeType = { + ~ + Type parameter `T` is defined here + src/tests/fixtures/generics/arrayPassedToGeneric.invalid.ts:10:14 + 10 someField: T; + ~ + and expects a GraphQL type because it was used in a GraphQL position here. +``` \ No newline at end of file diff --git a/src/tests/fixtures/generics/complexMutualReferences.ts.expected b/src/tests/fixtures/generics/complexMutualReferences.ts.expected deleted file mode 100644 index af0b52a7..00000000 --- a/src/tests/fixtures/generics/complexMutualReferences.ts.expected +++ /dev/null @@ -1,83 +0,0 @@ ------------------ -INPUT ------------------ -/** @gqlType */ -type Foo = { - /** @gqlField */ - someField: Bar; - /** @gqlField */ - baz: Baz; -}; - -/** @gqlType */ -type Bar = { - /** @gqlField */ - anotherField: Foo; -}; - -/** @gqlType */ -type Baz = { - /** @gqlField */ - bazField: Bar; -}; - ------------------ -OUTPUT ------------------ --- SDL -- -type Baz { - bazField: BazBar -} - -type BazBar { - anotherField: BazFoo -} - -type BazFoo { - baz: Baz - someField: BazBar -} --- TypeScript -- -import { GraphQLSchema, GraphQLObjectType } from "graphql"; -export function getSchema(): GraphQLSchema { - const BazFooType: GraphQLObjectType = new GraphQLObjectType({ - name: "BazFoo", - fields() { - return { - baz: { - name: "baz", - type: BazType - }, - someField: { - name: "someField", - type: BazBarType - } - }; - } - }); - const BazBarType: GraphQLObjectType = new GraphQLObjectType({ - name: "BazBar", - fields() { - return { - anotherField: { - name: "anotherField", - type: BazFooType - } - }; - } - }); - const BazType: GraphQLObjectType = new GraphQLObjectType({ - name: "Baz", - fields() { - return { - bazField: { - name: "bazField", - type: BazBarType - } - }; - } - }); - return new GraphQLSchema({ - types: [BazType, BazBarType, BazFooType] - }); -} diff --git a/src/tests/fixtures/generics/complexMutualReferences.ts.expected.md b/src/tests/fixtures/generics/complexMutualReferences.ts.expected.md new file mode 100644 index 00000000..6074b448 --- /dev/null +++ b/src/tests/fixtures/generics/complexMutualReferences.ts.expected.md @@ -0,0 +1,90 @@ +## input + +```ts title="generics/complexMutualReferences.ts" +/** @gqlType */ +type Foo = { + /** @gqlField */ + someField: Bar; + /** @gqlField */ + baz: Baz; +}; + +/** @gqlType */ +type Bar = { + /** @gqlField */ + anotherField: Foo; +}; + +/** @gqlType */ +type Baz = { + /** @gqlField */ + bazField: Bar; +}; +``` + +## Output + +### SDL + +```graphql +type Baz { + bazField: BazBar +} + +type BazBar { + anotherField: BazFoo +} + +type BazFoo { + baz: Baz + someField: BazBar +} +``` + +### TypeScript + +```ts +import { GraphQLSchema, GraphQLObjectType } from "graphql"; +export function getSchema(): GraphQLSchema { + const BazFooType: GraphQLObjectType = new GraphQLObjectType({ + name: "BazFoo", + fields() { + return { + baz: { + name: "baz", + type: BazType + }, + someField: { + name: "someField", + type: BazBarType + } + }; + } + }); + const BazBarType: GraphQLObjectType = new GraphQLObjectType({ + name: "BazBar", + fields() { + return { + anotherField: { + name: "anotherField", + type: BazFooType + } + }; + } + }); + const BazType: GraphQLObjectType = new GraphQLObjectType({ + name: "Baz", + fields() { + return { + bazField: { + name: "bazField", + type: BazBarType + } + }; + } + }); + return new GraphQLSchema({ + types: [BazType, BazBarType, BazFooType] + }); +} +``` \ No newline at end of file diff --git a/src/tests/fixtures/generics/connection.ts.expected b/src/tests/fixtures/generics/connection.ts.expected deleted file mode 100644 index 1d3bc501..00000000 --- a/src/tests/fixtures/generics/connection.ts.expected +++ /dev/null @@ -1,153 +0,0 @@ ------------------ -INPUT ------------------ -/** @gqlType */ -export type Page = { - /** @gqlField */ - name: string; -}; - -/** @gqlType */ -type User = { - /** @gqlField */ - pages: Connection; -}; - -/** @gqlType */ -type Edge = { - /** @gqlField */ - node: T; - /** @gqlField */ - cursor: string; -}; - -/** @gqlType */ -type Connection = { - /** @gqlField */ - edges: Edge; - /** @gqlField */ - pageInfo: PageInfo; -}; - -/** @gqlType */ -type PageInfo = { - /** @gqlField */ - hasNextPage: boolean; - /** @gqlField */ - hasPreviousPage: boolean; - /** @gqlField */ - startCursor: string; - /** @gqlField */ - endCursor: string; -}; - ------------------ -OUTPUT ------------------ --- SDL -- -type Page { - name: String -} - -type PageConnection { - edges: PageEdge - pageInfo: PageInfo -} - -type PageEdge { - cursor: String - node: Page -} - -type PageInfo { - endCursor: String - hasNextPage: Boolean - hasPreviousPage: Boolean - startCursor: String -} - -type User { - pages: PageConnection -} --- TypeScript -- -import { GraphQLSchema, GraphQLObjectType, GraphQLString, GraphQLBoolean } from "graphql"; -export function getSchema(): GraphQLSchema { - const PageType: GraphQLObjectType = new GraphQLObjectType({ - name: "Page", - fields() { - return { - name: { - name: "name", - type: GraphQLString - } - }; - } - }); - const PageEdgeType: GraphQLObjectType = new GraphQLObjectType({ - name: "PageEdge", - fields() { - return { - cursor: { - name: "cursor", - type: GraphQLString - }, - node: { - name: "node", - type: PageType - } - }; - } - }); - const PageInfoType: GraphQLObjectType = new GraphQLObjectType({ - name: "PageInfo", - fields() { - return { - endCursor: { - name: "endCursor", - type: GraphQLString - }, - hasNextPage: { - name: "hasNextPage", - type: GraphQLBoolean - }, - hasPreviousPage: { - name: "hasPreviousPage", - type: GraphQLBoolean - }, - startCursor: { - name: "startCursor", - type: GraphQLString - } - }; - } - }); - const PageConnectionType: GraphQLObjectType = new GraphQLObjectType({ - name: "PageConnection", - fields() { - return { - edges: { - name: "edges", - type: PageEdgeType - }, - pageInfo: { - name: "pageInfo", - type: PageInfoType - } - }; - } - }); - const UserType: GraphQLObjectType = new GraphQLObjectType({ - name: "User", - fields() { - return { - pages: { - name: "pages", - type: PageConnectionType - } - }; - } - }); - return new GraphQLSchema({ - types: [PageType, PageConnectionType, PageEdgeType, PageInfoType, UserType] - }); -} diff --git a/src/tests/fixtures/generics/connection.ts.expected.md b/src/tests/fixtures/generics/connection.ts.expected.md new file mode 100644 index 00000000..59e05202 --- /dev/null +++ b/src/tests/fixtures/generics/connection.ts.expected.md @@ -0,0 +1,160 @@ +## input + +```ts title="generics/connection.ts" +/** @gqlType */ +export type Page = { + /** @gqlField */ + name: string; +}; + +/** @gqlType */ +type User = { + /** @gqlField */ + pages: Connection; +}; + +/** @gqlType */ +type Edge = { + /** @gqlField */ + node: T; + /** @gqlField */ + cursor: string; +}; + +/** @gqlType */ +type Connection = { + /** @gqlField */ + edges: Edge; + /** @gqlField */ + pageInfo: PageInfo; +}; + +/** @gqlType */ +type PageInfo = { + /** @gqlField */ + hasNextPage: boolean; + /** @gqlField */ + hasPreviousPage: boolean; + /** @gqlField */ + startCursor: string; + /** @gqlField */ + endCursor: string; +}; +``` + +## Output + +### SDL + +```graphql +type Page { + name: String +} + +type PageConnection { + edges: PageEdge + pageInfo: PageInfo +} + +type PageEdge { + cursor: String + node: Page +} + +type PageInfo { + endCursor: String + hasNextPage: Boolean + hasPreviousPage: Boolean + startCursor: String +} + +type User { + pages: PageConnection +} +``` + +### TypeScript + +```ts +import { GraphQLSchema, GraphQLObjectType, GraphQLString, GraphQLBoolean } from "graphql"; +export function getSchema(): GraphQLSchema { + const PageType: GraphQLObjectType = new GraphQLObjectType({ + name: "Page", + fields() { + return { + name: { + name: "name", + type: GraphQLString + } + }; + } + }); + const PageEdgeType: GraphQLObjectType = new GraphQLObjectType({ + name: "PageEdge", + fields() { + return { + cursor: { + name: "cursor", + type: GraphQLString + }, + node: { + name: "node", + type: PageType + } + }; + } + }); + const PageInfoType: GraphQLObjectType = new GraphQLObjectType({ + name: "PageInfo", + fields() { + return { + endCursor: { + name: "endCursor", + type: GraphQLString + }, + hasNextPage: { + name: "hasNextPage", + type: GraphQLBoolean + }, + hasPreviousPage: { + name: "hasPreviousPage", + type: GraphQLBoolean + }, + startCursor: { + name: "startCursor", + type: GraphQLString + } + }; + } + }); + const PageConnectionType: GraphQLObjectType = new GraphQLObjectType({ + name: "PageConnection", + fields() { + return { + edges: { + name: "edges", + type: PageEdgeType + }, + pageInfo: { + name: "pageInfo", + type: PageInfoType + } + }; + } + }); + const UserType: GraphQLObjectType = new GraphQLObjectType({ + name: "User", + fields() { + return { + pages: { + name: "pages", + type: PageConnectionType + } + }; + } + }); + return new GraphQLSchema({ + types: [PageType, PageConnectionType, PageEdgeType, PageInfoType, UserType] + }); +} +``` \ No newline at end of file diff --git a/src/tests/fixtures/generics/connectionEdgeAsGeneric.ts.expected b/src/tests/fixtures/generics/connectionEdgeAsGeneric.ts.expected deleted file mode 100644 index b4cb4133..00000000 --- a/src/tests/fixtures/generics/connectionEdgeAsGeneric.ts.expected +++ /dev/null @@ -1,153 +0,0 @@ ------------------ -INPUT ------------------ -/** @gqlType */ -export type Page = { - /** @gqlField */ - name: string; -}; - -/** @gqlType */ -type User = { - /** @gqlField */ - pages: Connection>; -}; - -/** @gqlType */ -type Edge = { - /** @gqlField */ - node: T; - /** @gqlField */ - cursor: string; -}; - -/** @gqlType */ -type Connection> = { - /** @gqlField */ - edges: T; - /** @gqlField */ - pageInfo: PageInfo; -}; - -/** @gqlType */ -type PageInfo = { - /** @gqlField */ - hasNextPage: boolean; - /** @gqlField */ - hasPreviousPage: boolean; - /** @gqlField */ - startCursor: string; - /** @gqlField */ - endCursor: string; -}; - ------------------ -OUTPUT ------------------ --- SDL -- -type Page { - name: String -} - -type PageEdge { - cursor: String - node: Page -} - -type PageEdgeConnection { - edges: PageEdge - pageInfo: PageInfo -} - -type PageInfo { - endCursor: String - hasNextPage: Boolean - hasPreviousPage: Boolean - startCursor: String -} - -type User { - pages: PageEdgeConnection -} --- TypeScript -- -import { GraphQLSchema, GraphQLObjectType, GraphQLString, GraphQLBoolean } from "graphql"; -export function getSchema(): GraphQLSchema { - const PageType: GraphQLObjectType = new GraphQLObjectType({ - name: "Page", - fields() { - return { - name: { - name: "name", - type: GraphQLString - } - }; - } - }); - const PageEdgeType: GraphQLObjectType = new GraphQLObjectType({ - name: "PageEdge", - fields() { - return { - cursor: { - name: "cursor", - type: GraphQLString - }, - node: { - name: "node", - type: PageType - } - }; - } - }); - const PageInfoType: GraphQLObjectType = new GraphQLObjectType({ - name: "PageInfo", - fields() { - return { - endCursor: { - name: "endCursor", - type: GraphQLString - }, - hasNextPage: { - name: "hasNextPage", - type: GraphQLBoolean - }, - hasPreviousPage: { - name: "hasPreviousPage", - type: GraphQLBoolean - }, - startCursor: { - name: "startCursor", - type: GraphQLString - } - }; - } - }); - const PageEdgeConnectionType: GraphQLObjectType = new GraphQLObjectType({ - name: "PageEdgeConnection", - fields() { - return { - edges: { - name: "edges", - type: PageEdgeType - }, - pageInfo: { - name: "pageInfo", - type: PageInfoType - } - }; - } - }); - const UserType: GraphQLObjectType = new GraphQLObjectType({ - name: "User", - fields() { - return { - pages: { - name: "pages", - type: PageEdgeConnectionType - } - }; - } - }); - return new GraphQLSchema({ - types: [PageType, PageEdgeType, PageEdgeConnectionType, PageInfoType, UserType] - }); -} diff --git a/src/tests/fixtures/generics/connectionEdgeAsGeneric.ts.expected.md b/src/tests/fixtures/generics/connectionEdgeAsGeneric.ts.expected.md new file mode 100644 index 00000000..8d329903 --- /dev/null +++ b/src/tests/fixtures/generics/connectionEdgeAsGeneric.ts.expected.md @@ -0,0 +1,160 @@ +## input + +```ts title="generics/connectionEdgeAsGeneric.ts" +/** @gqlType */ +export type Page = { + /** @gqlField */ + name: string; +}; + +/** @gqlType */ +type User = { + /** @gqlField */ + pages: Connection>; +}; + +/** @gqlType */ +type Edge = { + /** @gqlField */ + node: T; + /** @gqlField */ + cursor: string; +}; + +/** @gqlType */ +type Connection> = { + /** @gqlField */ + edges: T; + /** @gqlField */ + pageInfo: PageInfo; +}; + +/** @gqlType */ +type PageInfo = { + /** @gqlField */ + hasNextPage: boolean; + /** @gqlField */ + hasPreviousPage: boolean; + /** @gqlField */ + startCursor: string; + /** @gqlField */ + endCursor: string; +}; +``` + +## Output + +### SDL + +```graphql +type Page { + name: String +} + +type PageEdge { + cursor: String + node: Page +} + +type PageEdgeConnection { + edges: PageEdge + pageInfo: PageInfo +} + +type PageInfo { + endCursor: String + hasNextPage: Boolean + hasPreviousPage: Boolean + startCursor: String +} + +type User { + pages: PageEdgeConnection +} +``` + +### TypeScript + +```ts +import { GraphQLSchema, GraphQLObjectType, GraphQLString, GraphQLBoolean } from "graphql"; +export function getSchema(): GraphQLSchema { + const PageType: GraphQLObjectType = new GraphQLObjectType({ + name: "Page", + fields() { + return { + name: { + name: "name", + type: GraphQLString + } + }; + } + }); + const PageEdgeType: GraphQLObjectType = new GraphQLObjectType({ + name: "PageEdge", + fields() { + return { + cursor: { + name: "cursor", + type: GraphQLString + }, + node: { + name: "node", + type: PageType + } + }; + } + }); + const PageInfoType: GraphQLObjectType = new GraphQLObjectType({ + name: "PageInfo", + fields() { + return { + endCursor: { + name: "endCursor", + type: GraphQLString + }, + hasNextPage: { + name: "hasNextPage", + type: GraphQLBoolean + }, + hasPreviousPage: { + name: "hasPreviousPage", + type: GraphQLBoolean + }, + startCursor: { + name: "startCursor", + type: GraphQLString + } + }; + } + }); + const PageEdgeConnectionType: GraphQLObjectType = new GraphQLObjectType({ + name: "PageEdgeConnection", + fields() { + return { + edges: { + name: "edges", + type: PageEdgeType + }, + pageInfo: { + name: "pageInfo", + type: PageInfoType + } + }; + } + }); + const UserType: GraphQLObjectType = new GraphQLObjectType({ + name: "User", + fields() { + return { + pages: { + name: "pages", + type: PageEdgeConnectionType + } + }; + } + }); + return new GraphQLSchema({ + types: [PageType, PageEdgeType, PageEdgeConnectionType, PageInfoType, UserType] + }); +} +``` \ No newline at end of file diff --git a/src/tests/fixtures/generics/defineFieldOnGeneric.ts.expected b/src/tests/fixtures/generics/defineFieldOnGeneric.ts.expected deleted file mode 100644 index 6b65928e..00000000 --- a/src/tests/fixtures/generics/defineFieldOnGeneric.ts.expected +++ /dev/null @@ -1,80 +0,0 @@ ------------------ -INPUT ------------------ -/** @gqlType */ -type Edge = { - /** @gqlField */ - node: T; - /** @gqlField */ - cursor: string; -}; - -/** @gqlType */ -type Page = { - /** @gqlField */ - title: string; -}; - -/** - * Re-expose title directly on the edge - * @gqlField */ -export function title(edge: Edge): string { - return edge.node.title; -} - ------------------ -OUTPUT ------------------ --- SDL -- -type Page { - title: String -} - -type PageEdge { - cursor: String - node: Page - """Re-expose title directly on the edge""" - title: String -} --- TypeScript -- -import { GraphQLSchema, GraphQLObjectType, GraphQLString } from "graphql"; -import { title as pageEdgeTitleResolver } from "./defineFieldOnGeneric"; -export function getSchema(): GraphQLSchema { - const PageType: GraphQLObjectType = new GraphQLObjectType({ - name: "Page", - fields() { - return { - title: { - name: "title", - type: GraphQLString - } - }; - } - }); - const PageEdgeType: GraphQLObjectType = new GraphQLObjectType({ - name: "PageEdge", - fields() { - return { - cursor: { - name: "cursor", - type: GraphQLString - }, - node: { - name: "node", - type: PageType - }, - title: { - description: "Re-expose title directly on the edge", - name: "title", - type: GraphQLString, - resolve(source) { - return pageEdgeTitleResolver(source); - } - } - }; - } - }); - return new GraphQLSchema({ - types: [PageType, PageEdgeType] - }); -} diff --git a/src/tests/fixtures/generics/defineFieldOnGeneric.ts.expected.md b/src/tests/fixtures/generics/defineFieldOnGeneric.ts.expected.md new file mode 100644 index 00000000..8c9ebc5e --- /dev/null +++ b/src/tests/fixtures/generics/defineFieldOnGeneric.ts.expected.md @@ -0,0 +1,87 @@ +## input + +```ts title="generics/defineFieldOnGeneric.ts" +/** @gqlType */ +type Edge = { + /** @gqlField */ + node: T; + /** @gqlField */ + cursor: string; +}; + +/** @gqlType */ +type Page = { + /** @gqlField */ + title: string; +}; + +/** + * Re-expose title directly on the edge + * @gqlField */ +export function title(edge: Edge): string { + return edge.node.title; +} +``` + +## Output + +### SDL + +```graphql +type Page { + title: String +} + +type PageEdge { + cursor: String + node: Page + """Re-expose title directly on the edge""" + title: String +} +``` + +### TypeScript + +```ts +import { GraphQLSchema, GraphQLObjectType, GraphQLString } from "graphql"; +import { title as pageEdgeTitleResolver } from "./defineFieldOnGeneric"; +export function getSchema(): GraphQLSchema { + const PageType: GraphQLObjectType = new GraphQLObjectType({ + name: "Page", + fields() { + return { + title: { + name: "title", + type: GraphQLString + } + }; + } + }); + const PageEdgeType: GraphQLObjectType = new GraphQLObjectType({ + name: "PageEdge", + fields() { + return { + cursor: { + name: "cursor", + type: GraphQLString + }, + node: { + name: "node", + type: PageType + }, + title: { + description: "Re-expose title directly on the edge", + name: "title", + type: GraphQLString, + resolve(source) { + return pageEdgeTitleResolver(source); + } + } + }; + } + }); + return new GraphQLSchema({ + types: [PageType, PageEdgeType] + }); +} +``` \ No newline at end of file diff --git a/src/tests/fixtures/generics/edge.ts.expected b/src/tests/fixtures/generics/edge.ts.expected deleted file mode 100644 index b4ab4a72..00000000 --- a/src/tests/fixtures/generics/edge.ts.expected +++ /dev/null @@ -1,132 +0,0 @@ ------------------ -INPUT ------------------ -/** @gqlType */ -type Page = { - /** @gqlField */ - name: string; -}; - -/** @gqlType */ -type Edge = { - /** @gqlField */ - node: T; - /** @gqlField */ - cursor: string; -}; - -/** @gqlType */ -type PageConnection = { - /** @gqlField */ - edges: Edge[]; - /** @gqlField */ - pageInfo: PageInfo; -}; - -/** @gqlType */ -type PageInfo = { - /** @gqlField */ - hasNextPage: boolean; - /** @gqlField */ - hasPreviousPage: boolean; - /** @gqlField */ - startCursor: string; - /** @gqlField */ - endCursor: string; -}; - ------------------ -OUTPUT ------------------ --- SDL -- -type Page { - name: String -} - -type PageConnection { - edges: [PageEdge!] - pageInfo: PageInfo -} - -type PageEdge { - cursor: String - node: Page -} - -type PageInfo { - endCursor: String - hasNextPage: Boolean - hasPreviousPage: Boolean - startCursor: String -} --- TypeScript -- -import { GraphQLSchema, GraphQLObjectType, GraphQLString, GraphQLList, GraphQLNonNull, GraphQLBoolean } from "graphql"; -export function getSchema(): GraphQLSchema { - const PageType: GraphQLObjectType = new GraphQLObjectType({ - name: "Page", - fields() { - return { - name: { - name: "name", - type: GraphQLString - } - }; - } - }); - const PageEdgeType: GraphQLObjectType = new GraphQLObjectType({ - name: "PageEdge", - fields() { - return { - cursor: { - name: "cursor", - type: GraphQLString - }, - node: { - name: "node", - type: PageType - } - }; - } - }); - const PageInfoType: GraphQLObjectType = new GraphQLObjectType({ - name: "PageInfo", - fields() { - return { - endCursor: { - name: "endCursor", - type: GraphQLString - }, - hasNextPage: { - name: "hasNextPage", - type: GraphQLBoolean - }, - hasPreviousPage: { - name: "hasPreviousPage", - type: GraphQLBoolean - }, - startCursor: { - name: "startCursor", - type: GraphQLString - } - }; - } - }); - const PageConnectionType: GraphQLObjectType = new GraphQLObjectType({ - name: "PageConnection", - fields() { - return { - edges: { - name: "edges", - type: new GraphQLList(new GraphQLNonNull(PageEdgeType)) - }, - pageInfo: { - name: "pageInfo", - type: PageInfoType - } - }; - } - }); - return new GraphQLSchema({ - types: [PageType, PageConnectionType, PageEdgeType, PageInfoType] - }); -} diff --git a/src/tests/fixtures/generics/edge.ts.expected.md b/src/tests/fixtures/generics/edge.ts.expected.md new file mode 100644 index 00000000..d64ad176 --- /dev/null +++ b/src/tests/fixtures/generics/edge.ts.expected.md @@ -0,0 +1,139 @@ +## input + +```ts title="generics/edge.ts" +/** @gqlType */ +type Page = { + /** @gqlField */ + name: string; +}; + +/** @gqlType */ +type Edge = { + /** @gqlField */ + node: T; + /** @gqlField */ + cursor: string; +}; + +/** @gqlType */ +type PageConnection = { + /** @gqlField */ + edges: Edge[]; + /** @gqlField */ + pageInfo: PageInfo; +}; + +/** @gqlType */ +type PageInfo = { + /** @gqlField */ + hasNextPage: boolean; + /** @gqlField */ + hasPreviousPage: boolean; + /** @gqlField */ + startCursor: string; + /** @gqlField */ + endCursor: string; +}; +``` + +## Output + +### SDL + +```graphql +type Page { + name: String +} + +type PageConnection { + edges: [PageEdge!] + pageInfo: PageInfo +} + +type PageEdge { + cursor: String + node: Page +} + +type PageInfo { + endCursor: String + hasNextPage: Boolean + hasPreviousPage: Boolean + startCursor: String +} +``` + +### TypeScript + +```ts +import { GraphQLSchema, GraphQLObjectType, GraphQLString, GraphQLList, GraphQLNonNull, GraphQLBoolean } from "graphql"; +export function getSchema(): GraphQLSchema { + const PageType: GraphQLObjectType = new GraphQLObjectType({ + name: "Page", + fields() { + return { + name: { + name: "name", + type: GraphQLString + } + }; + } + }); + const PageEdgeType: GraphQLObjectType = new GraphQLObjectType({ + name: "PageEdge", + fields() { + return { + cursor: { + name: "cursor", + type: GraphQLString + }, + node: { + name: "node", + type: PageType + } + }; + } + }); + const PageInfoType: GraphQLObjectType = new GraphQLObjectType({ + name: "PageInfo", + fields() { + return { + endCursor: { + name: "endCursor", + type: GraphQLString + }, + hasNextPage: { + name: "hasNextPage", + type: GraphQLBoolean + }, + hasPreviousPage: { + name: "hasPreviousPage", + type: GraphQLBoolean + }, + startCursor: { + name: "startCursor", + type: GraphQLString + } + }; + } + }); + const PageConnectionType: GraphQLObjectType = new GraphQLObjectType({ + name: "PageConnection", + fields() { + return { + edges: { + name: "edges", + type: new GraphQLList(new GraphQLNonNull(PageEdgeType)) + }, + pageInfo: { + name: "pageInfo", + type: PageInfoType + } + }; + } + }); + return new GraphQLSchema({ + types: [PageType, PageConnectionType, PageEdgeType, PageInfoType] + }); +} +``` \ No newline at end of file diff --git a/src/tests/fixtures/generics/enumWithGeneric.invalid.ts.expected b/src/tests/fixtures/generics/enumWithGeneric.invalid.ts.expected deleted file mode 100644 index 2c40e26e..00000000 --- a/src/tests/fixtures/generics/enumWithGeneric.invalid.ts.expected +++ /dev/null @@ -1,15 +0,0 @@ ------------------ -INPUT ------------------ -/** @gqlEnum */ -type MyEnum = T | "someValue"; - ------------------ -OUTPUT ------------------ -src/tests/fixtures/generics/enumWithGeneric.invalid.ts:2:18 - error: Expected `@gqlEnum` enum members to be string literal types. For example: `'foo'`. Grats needs to be able to see the concrete value of the enum member to generate the GraphQL schema. - -If you think Grats should be able to infer this union member, please report an issue at https://github.com/captbaritone/grats/issues. - -2 type MyEnum = T | "someValue"; - ~ diff --git a/src/tests/fixtures/generics/enumWithGeneric.invalid.ts.expected.md b/src/tests/fixtures/generics/enumWithGeneric.invalid.ts.expected.md new file mode 100644 index 00000000..4d4a3e73 --- /dev/null +++ b/src/tests/fixtures/generics/enumWithGeneric.invalid.ts.expected.md @@ -0,0 +1,19 @@ +## input + +```ts title="generics/enumWithGeneric.invalid.ts" +/** @gqlEnum */ +type MyEnum = T | "someValue"; +``` + +## Output + +### Error Report + +```text +src/tests/fixtures/generics/enumWithGeneric.invalid.ts:2:18 - error: Expected `@gqlEnum` enum members to be string literal types. For example: `'foo'`. Grats needs to be able to see the concrete value of the enum member to generate the GraphQL schema. + +If you think Grats should be able to infer this union member, please report an issue at https://github.com/captbaritone/grats/issues. + +2 type MyEnum = T | "someValue"; + ~ +``` \ No newline at end of file diff --git a/src/tests/fixtures/generics/genericInputType.ts.expected b/src/tests/fixtures/generics/genericInputType.ts.expected deleted file mode 100644 index 0d097d54..00000000 --- a/src/tests/fixtures/generics/genericInputType.ts.expected +++ /dev/null @@ -1,81 +0,0 @@ ------------------ -INPUT ------------------ -/** @gqlInput */ -type SomeInput = { - someField: T; -}; - -/** @gqlInput */ -type AnotherInput = { - anotherField: string; -}; - -/** @gqlType */ -class SomeClass { - /** @gqlField */ - someField(args: { someArg: SomeInput }): string { - return args.someArg.someField.anotherField; - } -} - ------------------ -OUTPUT ------------------ --- SDL -- -input AnotherInput { - anotherField: String! -} - -input AnotherInputSomeInput { - someField: AnotherInput! -} - -type SomeClass { - someField(someArg: AnotherInputSomeInput!): String -} --- TypeScript -- -import { GraphQLSchema, GraphQLInputObjectType, GraphQLNonNull, GraphQLString, GraphQLObjectType } from "graphql"; -export function getSchema(): GraphQLSchema { - const AnotherInputType: GraphQLInputObjectType = new GraphQLInputObjectType({ - name: "AnotherInput", - fields() { - return { - anotherField: { - name: "anotherField", - type: new GraphQLNonNull(GraphQLString) - } - }; - } - }); - const AnotherInputSomeInputType: GraphQLInputObjectType = new GraphQLInputObjectType({ - name: "AnotherInputSomeInput", - fields() { - return { - someField: { - name: "someField", - type: new GraphQLNonNull(AnotherInputType) - } - }; - } - }); - const SomeClassType: GraphQLObjectType = new GraphQLObjectType({ - name: "SomeClass", - fields() { - return { - someField: { - name: "someField", - type: GraphQLString, - args: { - someArg: { - type: new GraphQLNonNull(AnotherInputSomeInputType) - } - } - } - }; - } - }); - return new GraphQLSchema({ - types: [AnotherInputType, AnotherInputSomeInputType, SomeClassType] - }); -} diff --git a/src/tests/fixtures/generics/genericInputType.ts.expected.md b/src/tests/fixtures/generics/genericInputType.ts.expected.md new file mode 100644 index 00000000..0d8ed2d3 --- /dev/null +++ b/src/tests/fixtures/generics/genericInputType.ts.expected.md @@ -0,0 +1,88 @@ +## input + +```ts title="generics/genericInputType.ts" +/** @gqlInput */ +type SomeInput = { + someField: T; +}; + +/** @gqlInput */ +type AnotherInput = { + anotherField: string; +}; + +/** @gqlType */ +class SomeClass { + /** @gqlField */ + someField(args: { someArg: SomeInput }): string { + return args.someArg.someField.anotherField; + } +} +``` + +## Output + +### SDL + +```graphql +input AnotherInput { + anotherField: String! +} + +input AnotherInputSomeInput { + someField: AnotherInput! +} + +type SomeClass { + someField(someArg: AnotherInputSomeInput!): String +} +``` + +### TypeScript + +```ts +import { GraphQLSchema, GraphQLInputObjectType, GraphQLNonNull, GraphQLString, GraphQLObjectType } from "graphql"; +export function getSchema(): GraphQLSchema { + const AnotherInputType: GraphQLInputObjectType = new GraphQLInputObjectType({ + name: "AnotherInput", + fields() { + return { + anotherField: { + name: "anotherField", + type: new GraphQLNonNull(GraphQLString) + } + }; + } + }); + const AnotherInputSomeInputType: GraphQLInputObjectType = new GraphQLInputObjectType({ + name: "AnotherInputSomeInput", + fields() { + return { + someField: { + name: "someField", + type: new GraphQLNonNull(AnotherInputType) + } + }; + } + }); + const SomeClassType: GraphQLObjectType = new GraphQLObjectType({ + name: "SomeClass", + fields() { + return { + someField: { + name: "someField", + type: GraphQLString, + args: { + someArg: { + type: new GraphQLNonNull(AnotherInputSomeInputType) + } + } + } + }; + } + }); + return new GraphQLSchema({ + types: [AnotherInputType, AnotherInputSomeInputType, SomeClassType] + }); +} +``` \ No newline at end of file diff --git a/src/tests/fixtures/generics/genericInterface.ts.expected b/src/tests/fixtures/generics/genericInterface.ts.expected deleted file mode 100644 index 596266c0..00000000 --- a/src/tests/fixtures/generics/genericInterface.ts.expected +++ /dev/null @@ -1,94 +0,0 @@ ------------------ -INPUT ------------------ -/** @gqlType */ -class User implements Friendly { - __typename: "User"; - /** @gqlField */ - name: string; - /** @gqlField */ - to: Dog; -} - -/** @gqlInterface */ -interface Friendly { - /** @gqlField */ - to: T; -} - -/** @gqlType */ -class Dog { - /** @gqlField */ - name: string; - /** @gqlField */ - bestFriend: Friendly; -} - ------------------ -OUTPUT ------------------ --- SDL -- -interface DogFriendly { - to: Dog -} - -type Dog { - bestFriend: DogFriendly - name: String -} - -type User implements DogFriendly { - name: String - to: Dog -} --- TypeScript -- -import { GraphQLSchema, GraphQLInterfaceType, GraphQLObjectType, GraphQLString } from "graphql"; -export function getSchema(): GraphQLSchema { - const DogType: GraphQLObjectType = new GraphQLObjectType({ - name: "Dog", - fields() { - return { - bestFriend: { - name: "bestFriend", - type: DogFriendlyType - }, - name: { - name: "name", - type: GraphQLString - } - }; - } - }); - const DogFriendlyType: GraphQLInterfaceType = new GraphQLInterfaceType({ - name: "DogFriendly", - fields() { - return { - to: { - name: "to", - type: DogType - } - }; - } - }); - const UserType: GraphQLObjectType = new GraphQLObjectType({ - name: "User", - fields() { - return { - name: { - name: "name", - type: GraphQLString - }, - to: { - name: "to", - type: DogType - } - }; - }, - interfaces() { - return [DogFriendlyType]; - } - }); - return new GraphQLSchema({ - types: [DogFriendlyType, DogType, UserType] - }); -} diff --git a/src/tests/fixtures/generics/genericInterface.ts.expected.md b/src/tests/fixtures/generics/genericInterface.ts.expected.md new file mode 100644 index 00000000..a8756bcd --- /dev/null +++ b/src/tests/fixtures/generics/genericInterface.ts.expected.md @@ -0,0 +1,101 @@ +## input + +```ts title="generics/genericInterface.ts" +/** @gqlType */ +class User implements Friendly { + __typename: "User"; + /** @gqlField */ + name: string; + /** @gqlField */ + to: Dog; +} + +/** @gqlInterface */ +interface Friendly { + /** @gqlField */ + to: T; +} + +/** @gqlType */ +class Dog { + /** @gqlField */ + name: string; + /** @gqlField */ + bestFriend: Friendly; +} +``` + +## Output + +### SDL + +```graphql +interface DogFriendly { + to: Dog +} + +type Dog { + bestFriend: DogFriendly + name: String +} + +type User implements DogFriendly { + name: String + to: Dog +} +``` + +### TypeScript + +```ts +import { GraphQLSchema, GraphQLInterfaceType, GraphQLObjectType, GraphQLString } from "graphql"; +export function getSchema(): GraphQLSchema { + const DogType: GraphQLObjectType = new GraphQLObjectType({ + name: "Dog", + fields() { + return { + bestFriend: { + name: "bestFriend", + type: DogFriendlyType + }, + name: { + name: "name", + type: GraphQLString + } + }; + } + }); + const DogFriendlyType: GraphQLInterfaceType = new GraphQLInterfaceType({ + name: "DogFriendly", + fields() { + return { + to: { + name: "to", + type: DogType + } + }; + } + }); + const UserType: GraphQLObjectType = new GraphQLObjectType({ + name: "User", + fields() { + return { + name: { + name: "name", + type: GraphQLString + }, + to: { + name: "to", + type: DogType + } + }; + }, + interfaces() { + return [DogFriendlyType]; + } + }); + return new GraphQLSchema({ + types: [DogFriendlyType, DogType, UserType] + }); +} +``` \ No newline at end of file diff --git a/src/tests/fixtures/generics/genericOverArg.ts.expected b/src/tests/fixtures/generics/genericOverArg.ts.expected deleted file mode 100644 index 4b83be89..00000000 --- a/src/tests/fixtures/generics/genericOverArg.ts.expected +++ /dev/null @@ -1,89 +0,0 @@ ------------------ -INPUT ------------------ -/** @gqlType */ -export class SomeClass { - /** @gqlField */ - someField(args: { someArg?: T | null }): string { - return "someField"; - } -} - -/** @gqlInput */ -type SomeInput = { - someField: string; -}; - -/** @gqlType */ -type Query = unknown; - -/** @gqlField */ -export function someField(_: Query): SomeClass { - return new SomeClass(); -} - ------------------ -OUTPUT ------------------ --- SDL -- -input SomeInput { - someField: String! -} - -type Query { - someField: SomeInputSomeClass -} - -type SomeInputSomeClass { - someField(someArg: SomeInput): String -} --- TypeScript -- -import { GraphQLSchema, GraphQLObjectType, GraphQLString, GraphQLInputObjectType, GraphQLNonNull } from "graphql"; -import { someField as querySomeFieldResolver } from "./genericOverArg"; -export function getSchema(): GraphQLSchema { - const SomeInputType: GraphQLInputObjectType = new GraphQLInputObjectType({ - name: "SomeInput", - fields() { - return { - someField: { - name: "someField", - type: new GraphQLNonNull(GraphQLString) - } - }; - } - }); - const SomeInputSomeClassType: GraphQLObjectType = new GraphQLObjectType({ - name: "SomeInputSomeClass", - fields() { - return { - someField: { - name: "someField", - type: GraphQLString, - args: { - someArg: { - type: SomeInputType - } - } - } - }; - } - }); - const QueryType: GraphQLObjectType = new GraphQLObjectType({ - name: "Query", - fields() { - return { - someField: { - name: "someField", - type: SomeInputSomeClassType, - resolve(source) { - return querySomeFieldResolver(source); - } - } - }; - } - }); - return new GraphQLSchema({ - query: QueryType, - types: [SomeInputType, QueryType, SomeInputSomeClassType] - }); -} diff --git a/src/tests/fixtures/generics/genericOverArg.ts.expected.md b/src/tests/fixtures/generics/genericOverArg.ts.expected.md new file mode 100644 index 00000000..caacd5f8 --- /dev/null +++ b/src/tests/fixtures/generics/genericOverArg.ts.expected.md @@ -0,0 +1,96 @@ +## input + +```ts title="generics/genericOverArg.ts" +/** @gqlType */ +export class SomeClass { + /** @gqlField */ + someField(args: { someArg?: T | null }): string { + return "someField"; + } +} + +/** @gqlInput */ +type SomeInput = { + someField: string; +}; + +/** @gqlType */ +type Query = unknown; + +/** @gqlField */ +export function someField(_: Query): SomeClass { + return new SomeClass(); +} +``` + +## Output + +### SDL + +```graphql +input SomeInput { + someField: String! +} + +type Query { + someField: SomeInputSomeClass +} + +type SomeInputSomeClass { + someField(someArg: SomeInput): String +} +``` + +### TypeScript + +```ts +import { GraphQLSchema, GraphQLObjectType, GraphQLString, GraphQLInputObjectType, GraphQLNonNull } from "graphql"; +import { someField as querySomeFieldResolver } from "./genericOverArg"; +export function getSchema(): GraphQLSchema { + const SomeInputType: GraphQLInputObjectType = new GraphQLInputObjectType({ + name: "SomeInput", + fields() { + return { + someField: { + name: "someField", + type: new GraphQLNonNull(GraphQLString) + } + }; + } + }); + const SomeInputSomeClassType: GraphQLObjectType = new GraphQLObjectType({ + name: "SomeInputSomeClass", + fields() { + return { + someField: { + name: "someField", + type: GraphQLString, + args: { + someArg: { + type: SomeInputType + } + } + } + }; + } + }); + const QueryType: GraphQLObjectType = new GraphQLObjectType({ + name: "Query", + fields() { + return { + someField: { + name: "someField", + type: SomeInputSomeClassType, + resolve(source) { + return querySomeFieldResolver(source); + } + } + }; + } + }); + return new GraphQLSchema({ + query: QueryType, + types: [SomeInputType, QueryType, SomeInputSomeClassType] + }); +} +``` \ No newline at end of file diff --git a/src/tests/fixtures/generics/genericReferencedMoreThanOnce.ts.expected b/src/tests/fixtures/generics/genericReferencedMoreThanOnce.ts.expected deleted file mode 100644 index 6981ac97..00000000 --- a/src/tests/fixtures/generics/genericReferencedMoreThanOnce.ts.expected +++ /dev/null @@ -1,96 +0,0 @@ ------------------ -INPUT ------------------ -/** @gqlType */ -type Err = { - __typename: "Err"; - /** @gqlField */ - message: string; -}; - -/** @gqlUnion */ -type Result = T | Err; - -/** @gqlType */ -export type Page = { - __typename: "Page"; - /** @gqlField */ - name: string; -}; - -/** @gqlType */ -export type SomeType = { - /** @gqlField */ - pageResult: Result; - /** @gqlField */ - alsoPageResult: Result; -}; - ------------------ -OUTPUT ------------------ --- SDL -- -union PageResult = Err | Page - -type Err { - message: String -} - -type Page { - name: String -} - -type SomeType { - alsoPageResult: PageResult - pageResult: PageResult -} --- TypeScript -- -import { GraphQLSchema, GraphQLUnionType, GraphQLObjectType, GraphQLString } from "graphql"; -export function getSchema(): GraphQLSchema { - const ErrType: GraphQLObjectType = new GraphQLObjectType({ - name: "Err", - fields() { - return { - message: { - name: "message", - type: GraphQLString - } - }; - } - }); - const PageType: GraphQLObjectType = new GraphQLObjectType({ - name: "Page", - fields() { - return { - name: { - name: "name", - type: GraphQLString - } - }; - } - }); - const PageResultType: GraphQLUnionType = new GraphQLUnionType({ - name: "PageResult", - types() { - return [ErrType, PageType]; - } - }); - const SomeTypeType: GraphQLObjectType = new GraphQLObjectType({ - name: "SomeType", - fields() { - return { - alsoPageResult: { - name: "alsoPageResult", - type: PageResultType - }, - pageResult: { - name: "pageResult", - type: PageResultType - } - }; - } - }); - return new GraphQLSchema({ - types: [PageResultType, ErrType, PageType, SomeTypeType] - }); -} diff --git a/src/tests/fixtures/generics/genericReferencedMoreThanOnce.ts.expected.md b/src/tests/fixtures/generics/genericReferencedMoreThanOnce.ts.expected.md new file mode 100644 index 00000000..1d8ac9e0 --- /dev/null +++ b/src/tests/fixtures/generics/genericReferencedMoreThanOnce.ts.expected.md @@ -0,0 +1,103 @@ +## input + +```ts title="generics/genericReferencedMoreThanOnce.ts" +/** @gqlType */ +type Err = { + __typename: "Err"; + /** @gqlField */ + message: string; +}; + +/** @gqlUnion */ +type Result = T | Err; + +/** @gqlType */ +export type Page = { + __typename: "Page"; + /** @gqlField */ + name: string; +}; + +/** @gqlType */ +export type SomeType = { + /** @gqlField */ + pageResult: Result; + /** @gqlField */ + alsoPageResult: Result; +}; +``` + +## Output + +### SDL + +```graphql +union PageResult = Err | Page + +type Err { + message: String +} + +type Page { + name: String +} + +type SomeType { + alsoPageResult: PageResult + pageResult: PageResult +} +``` + +### TypeScript + +```ts +import { GraphQLSchema, GraphQLUnionType, GraphQLObjectType, GraphQLString } from "graphql"; +export function getSchema(): GraphQLSchema { + const ErrType: GraphQLObjectType = new GraphQLObjectType({ + name: "Err", + fields() { + return { + message: { + name: "message", + type: GraphQLString + } + }; + } + }); + const PageType: GraphQLObjectType = new GraphQLObjectType({ + name: "Page", + fields() { + return { + name: { + name: "name", + type: GraphQLString + } + }; + } + }); + const PageResultType: GraphQLUnionType = new GraphQLUnionType({ + name: "PageResult", + types() { + return [ErrType, PageType]; + } + }); + const SomeTypeType: GraphQLObjectType = new GraphQLObjectType({ + name: "SomeType", + fields() { + return { + alsoPageResult: { + name: "alsoPageResult", + type: PageResultType + }, + pageResult: { + name: "pageResult", + type: PageResultType + } + }; + } + }); + return new GraphQLSchema({ + types: [PageResultType, ErrType, PageType, SomeTypeType] + }); +} +``` \ No newline at end of file diff --git a/src/tests/fixtures/generics/genericTypeUsedAsUnionMember.invalid.ts.expected b/src/tests/fixtures/generics/genericTypeUsedAsUnionMember.invalid.ts.expected deleted file mode 100644 index c18a8eb3..00000000 --- a/src/tests/fixtures/generics/genericTypeUsedAsUnionMember.invalid.ts.expected +++ /dev/null @@ -1,28 +0,0 @@ ------------------ -INPUT ------------------ -/** @gqlType */ -type Page = { - __typename: "Page"; - /** @gqlField */ - name: string; -}; - -/** @gqlType */ -export class Edge { - /** @gqlField */ - node: T; - /** @gqlField */ - cursor: string; -} - -/** @gqlUnion */ -type SomeUnion = Page | Edge; - ------------------ -OUTPUT ------------------ -src/tests/fixtures/generics/genericTypeUsedAsUnionMember.invalid.ts:17:25 - error: Unexpected generic type used as union member. Generic type may not currently be used as members of a union. Grats requires that all union members define a `__typename` field typed as a string literal matching the type's name. Since generic types are synthesized into multiple types with different names, Grats cannot ensure they have a correct `__typename` property and thus cannot be used as members of a union. - -17 type SomeUnion = Page | Edge; - ~~~~~~~~~~ diff --git a/src/tests/fixtures/generics/genericTypeUsedAsUnionMember.invalid.ts.expected.md b/src/tests/fixtures/generics/genericTypeUsedAsUnionMember.invalid.ts.expected.md new file mode 100644 index 00000000..fc330e6b --- /dev/null +++ b/src/tests/fixtures/generics/genericTypeUsedAsUnionMember.invalid.ts.expected.md @@ -0,0 +1,32 @@ +## input + +```ts title="generics/genericTypeUsedAsUnionMember.invalid.ts" +/** @gqlType */ +type Page = { + __typename: "Page"; + /** @gqlField */ + name: string; +}; + +/** @gqlType */ +export class Edge { + /** @gqlField */ + node: T; + /** @gqlField */ + cursor: string; +} + +/** @gqlUnion */ +type SomeUnion = Page | Edge; +``` + +## Output + +### Error Report + +```text +src/tests/fixtures/generics/genericTypeUsedAsUnionMember.invalid.ts:17:25 - error: Unexpected generic type used as union member. Generic type may not currently be used as members of a union. Grats requires that all union members define a `__typename` field typed as a string literal matching the type's name. Since generic types are synthesized into multiple types with different names, Grats cannot ensure they have a correct `__typename` property and thus cannot be used as members of a union. + +17 type SomeUnion = Page | Edge; + ~~~~~~~~~~ +``` \ No newline at end of file diff --git a/src/tests/fixtures/generics/genericTypeUsedAsUnionMemberViaTypeParam.invalid.ts.expected b/src/tests/fixtures/generics/genericTypeUsedAsUnionMemberViaTypeParam.invalid.ts.expected deleted file mode 100644 index 5319c5bd..00000000 --- a/src/tests/fixtures/generics/genericTypeUsedAsUnionMemberViaTypeParam.invalid.ts.expected +++ /dev/null @@ -1,26 +0,0 @@ ------------------ -INPUT ------------------ -/** @gqlType */ -type Page = { - __typename: "Page"; - /** @gqlField */ - foo: SomeUnion>; -}; - -/** @gqlType */ -export class Edge { - /** @gqlField */ - node: T; -} - -/** @gqlUnion */ -type SomeUnion = Page | T; - ------------------ -OUTPUT ------------------ -src/tests/fixtures/generics/genericTypeUsedAsUnionMemberViaTypeParam.invalid.ts:5:18 - error: Unexpected generic type used as union member. Generic type may not currently be used as members of a union. Grats requires that all union members define a `__typename` field typed as a string literal matching the type's name. Since generic types are synthesized into multiple types with different names, Grats cannot ensure they have a correct `__typename` property and thus cannot be used as members of a union. - -5 foo: SomeUnion>; - ~~~~~~~~~~ diff --git a/src/tests/fixtures/generics/genericTypeUsedAsUnionMemberViaTypeParam.invalid.ts.expected.md b/src/tests/fixtures/generics/genericTypeUsedAsUnionMemberViaTypeParam.invalid.ts.expected.md new file mode 100644 index 00000000..50f417af --- /dev/null +++ b/src/tests/fixtures/generics/genericTypeUsedAsUnionMemberViaTypeParam.invalid.ts.expected.md @@ -0,0 +1,30 @@ +## input + +```ts title="generics/genericTypeUsedAsUnionMemberViaTypeParam.invalid.ts" +/** @gqlType */ +type Page = { + __typename: "Page"; + /** @gqlField */ + foo: SomeUnion>; +}; + +/** @gqlType */ +export class Edge { + /** @gqlField */ + node: T; +} + +/** @gqlUnion */ +type SomeUnion = Page | T; +``` + +## Output + +### Error Report + +```text +src/tests/fixtures/generics/genericTypeUsedAsUnionMemberViaTypeParam.invalid.ts:5:18 - error: Unexpected generic type used as union member. Generic type may not currently be used as members of a union. Grats requires that all union members define a `__typename` field typed as a string literal matching the type's name. Since generic types are synthesized into multiple types with different names, Grats cannot ensure they have a correct `__typename` property and thus cannot be used as members of a union. + +5 foo: SomeUnion>; + ~~~~~~~~~~ +``` \ No newline at end of file diff --git a/src/tests/fixtures/generics/genericTypeUsingClass.ts.expected b/src/tests/fixtures/generics/genericTypeUsingClass.ts.expected deleted file mode 100644 index e458848d..00000000 --- a/src/tests/fixtures/generics/genericTypeUsingClass.ts.expected +++ /dev/null @@ -1,90 +0,0 @@ ------------------ -INPUT ------------------ -/** @gqlType */ -type Page = { - /** @gqlField */ - name: string; -}; - -/** @gqlType */ -export class Edge { - /** @gqlField */ - node: T; - /** @gqlField */ - cursor: string; -} - -/** @gqlType */ -type Query = unknown; - -/** @gqlField */ -export function createEdge(_: Query): Edge { - return { node: { name: "My Page" }, cursor: "cursor" }; -} - ------------------ -OUTPUT ------------------ --- SDL -- -type Page { - name: String -} - -type PageEdge { - cursor: String - node: Page -} - -type Query { - createEdge: PageEdge -} --- TypeScript -- -import { GraphQLSchema, GraphQLObjectType, GraphQLString } from "graphql"; -import { createEdge as queryCreateEdgeResolver } from "./genericTypeUsingClass"; -export function getSchema(): GraphQLSchema { - const PageType: GraphQLObjectType = new GraphQLObjectType({ - name: "Page", - fields() { - return { - name: { - name: "name", - type: GraphQLString - } - }; - } - }); - const PageEdgeType: GraphQLObjectType = new GraphQLObjectType({ - name: "PageEdge", - fields() { - return { - cursor: { - name: "cursor", - type: GraphQLString - }, - node: { - name: "node", - type: PageType - } - }; - } - }); - const QueryType: GraphQLObjectType = new GraphQLObjectType({ - name: "Query", - fields() { - return { - createEdge: { - name: "createEdge", - type: PageEdgeType, - resolve(source) { - return queryCreateEdgeResolver(source); - } - } - }; - } - }); - return new GraphQLSchema({ - query: QueryType, - types: [PageType, PageEdgeType, QueryType] - }); -} diff --git a/src/tests/fixtures/generics/genericTypeUsingClass.ts.expected.md b/src/tests/fixtures/generics/genericTypeUsingClass.ts.expected.md new file mode 100644 index 00000000..805fde4e --- /dev/null +++ b/src/tests/fixtures/generics/genericTypeUsingClass.ts.expected.md @@ -0,0 +1,97 @@ +## input + +```ts title="generics/genericTypeUsingClass.ts" +/** @gqlType */ +type Page = { + /** @gqlField */ + name: string; +}; + +/** @gqlType */ +export class Edge { + /** @gqlField */ + node: T; + /** @gqlField */ + cursor: string; +} + +/** @gqlType */ +type Query = unknown; + +/** @gqlField */ +export function createEdge(_: Query): Edge { + return { node: { name: "My Page" }, cursor: "cursor" }; +} +``` + +## Output + +### SDL + +```graphql +type Page { + name: String +} + +type PageEdge { + cursor: String + node: Page +} + +type Query { + createEdge: PageEdge +} +``` + +### TypeScript + +```ts +import { GraphQLSchema, GraphQLObjectType, GraphQLString } from "graphql"; +import { createEdge as queryCreateEdgeResolver } from "./genericTypeUsingClass"; +export function getSchema(): GraphQLSchema { + const PageType: GraphQLObjectType = new GraphQLObjectType({ + name: "Page", + fields() { + return { + name: { + name: "name", + type: GraphQLString + } + }; + } + }); + const PageEdgeType: GraphQLObjectType = new GraphQLObjectType({ + name: "PageEdge", + fields() { + return { + cursor: { + name: "cursor", + type: GraphQLString + }, + node: { + name: "node", + type: PageType + } + }; + } + }); + const QueryType: GraphQLObjectType = new GraphQLObjectType({ + name: "Query", + fields() { + return { + createEdge: { + name: "createEdge", + type: PageEdgeType, + resolve(source) { + return queryCreateEdgeResolver(source); + } + } + }; + } + }); + return new GraphQLSchema({ + query: QueryType, + types: [PageType, PageEdgeType, QueryType] + }); +} +``` \ No newline at end of file diff --git a/src/tests/fixtures/generics/genericTypeUsingInterface.ts.expected b/src/tests/fixtures/generics/genericTypeUsingInterface.ts.expected deleted file mode 100644 index 7f38f421..00000000 --- a/src/tests/fixtures/generics/genericTypeUsingInterface.ts.expected +++ /dev/null @@ -1,90 +0,0 @@ ------------------ -INPUT ------------------ -/** @gqlType */ -type Page = { - /** @gqlField */ - name: string; -}; - -/** @gqlType */ -export interface Edge { - /** @gqlField */ - node: T; - /** @gqlField */ - cursor: string; -} - -/** @gqlType */ -type Query = unknown; - -/** @gqlField */ -export function createEdge(_: Query): Edge { - return { node: { name: "My Page" }, cursor: "cursor" }; -} - ------------------ -OUTPUT ------------------ --- SDL -- -type Page { - name: String -} - -type PageEdge { - cursor: String - node: Page -} - -type Query { - createEdge: PageEdge -} --- TypeScript -- -import { GraphQLSchema, GraphQLObjectType, GraphQLString } from "graphql"; -import { createEdge as queryCreateEdgeResolver } from "./genericTypeUsingInterface"; -export function getSchema(): GraphQLSchema { - const PageType: GraphQLObjectType = new GraphQLObjectType({ - name: "Page", - fields() { - return { - name: { - name: "name", - type: GraphQLString - } - }; - } - }); - const PageEdgeType: GraphQLObjectType = new GraphQLObjectType({ - name: "PageEdge", - fields() { - return { - cursor: { - name: "cursor", - type: GraphQLString - }, - node: { - name: "node", - type: PageType - } - }; - } - }); - const QueryType: GraphQLObjectType = new GraphQLObjectType({ - name: "Query", - fields() { - return { - createEdge: { - name: "createEdge", - type: PageEdgeType, - resolve(source) { - return queryCreateEdgeResolver(source); - } - } - }; - } - }); - return new GraphQLSchema({ - query: QueryType, - types: [PageType, PageEdgeType, QueryType] - }); -} diff --git a/src/tests/fixtures/generics/genericTypeUsingInterface.ts.expected.md b/src/tests/fixtures/generics/genericTypeUsingInterface.ts.expected.md new file mode 100644 index 00000000..d2e66308 --- /dev/null +++ b/src/tests/fixtures/generics/genericTypeUsingInterface.ts.expected.md @@ -0,0 +1,97 @@ +## input + +```ts title="generics/genericTypeUsingInterface.ts" +/** @gqlType */ +type Page = { + /** @gqlField */ + name: string; +}; + +/** @gqlType */ +export interface Edge { + /** @gqlField */ + node: T; + /** @gqlField */ + cursor: string; +} + +/** @gqlType */ +type Query = unknown; + +/** @gqlField */ +export function createEdge(_: Query): Edge { + return { node: { name: "My Page" }, cursor: "cursor" }; +} +``` + +## Output + +### SDL + +```graphql +type Page { + name: String +} + +type PageEdge { + cursor: String + node: Page +} + +type Query { + createEdge: PageEdge +} +``` + +### TypeScript + +```ts +import { GraphQLSchema, GraphQLObjectType, GraphQLString } from "graphql"; +import { createEdge as queryCreateEdgeResolver } from "./genericTypeUsingInterface"; +export function getSchema(): GraphQLSchema { + const PageType: GraphQLObjectType = new GraphQLObjectType({ + name: "Page", + fields() { + return { + name: { + name: "name", + type: GraphQLString + } + }; + } + }); + const PageEdgeType: GraphQLObjectType = new GraphQLObjectType({ + name: "PageEdge", + fields() { + return { + cursor: { + name: "cursor", + type: GraphQLString + }, + node: { + name: "node", + type: PageType + } + }; + } + }); + const QueryType: GraphQLObjectType = new GraphQLObjectType({ + name: "Query", + fields() { + return { + createEdge: { + name: "createEdge", + type: PageEdgeType, + resolve(source) { + return queryCreateEdgeResolver(source); + } + } + }; + } + }); + return new GraphQLSchema({ + query: QueryType, + types: [PageType, PageEdgeType, QueryType] + }); +} +``` \ No newline at end of file diff --git a/src/tests/fixtures/generics/missingGqlGenericTypeArg.invalid.ts.expected b/src/tests/fixtures/generics/missingGqlGenericTypeArg.invalid.ts.expected deleted file mode 100644 index 72252cee..00000000 --- a/src/tests/fixtures/generics/missingGqlGenericTypeArg.invalid.ts.expected +++ /dev/null @@ -1,33 +0,0 @@ ------------------ -INPUT ------------------ -/** @gqlType */ -type Edge = { - /** @gqlField */ - node: T; - /** @gqlField */ - cursor: string; -}; - -/** @gqlType */ -export type PageConnection = { - /** @gqlField */ - edges: Edge[]; -}; - ------------------ -OUTPUT ------------------ -src/tests/fixtures/generics/missingGqlGenericTypeArg.invalid.ts:12:10 - error: Missing type argument for generic GraphQL type. Expected `Edge` to be passed a GraphQL type argument for type parameter `T`. - -12 edges: Edge[]; - ~~~~~~~~~~~~~~~~~ - - src/tests/fixtures/generics/missingGqlGenericTypeArg.invalid.ts:2:11 - 2 type Edge = { - ~ - Type parameter `T` is defined here - src/tests/fixtures/generics/missingGqlGenericTypeArg.invalid.ts:4:9 - 4 node: T; - ~ - and expects a GraphQL type because it was used in a GraphQL position here. diff --git a/src/tests/fixtures/generics/missingGqlGenericTypeArg.invalid.ts.expected.md b/src/tests/fixtures/generics/missingGqlGenericTypeArg.invalid.ts.expected.md new file mode 100644 index 00000000..b6d95028 --- /dev/null +++ b/src/tests/fixtures/generics/missingGqlGenericTypeArg.invalid.ts.expected.md @@ -0,0 +1,37 @@ +## input + +```ts title="generics/missingGqlGenericTypeArg.invalid.ts" +/** @gqlType */ +type Edge = { + /** @gqlField */ + node: T; + /** @gqlField */ + cursor: string; +}; + +/** @gqlType */ +export type PageConnection = { + /** @gqlField */ + edges: Edge[]; +}; +``` + +## Output + +### Error Report + +```text +src/tests/fixtures/generics/missingGqlGenericTypeArg.invalid.ts:12:10 - error: Missing type argument for generic GraphQL type. Expected `Edge` to be passed a GraphQL type argument for type parameter `T`. + +12 edges: Edge[]; + ~~~~~~~~~~~~~~~~~ + + src/tests/fixtures/generics/missingGqlGenericTypeArg.invalid.ts:2:11 + 2 type Edge = { + ~ + Type parameter `T` is defined here + src/tests/fixtures/generics/missingGqlGenericTypeArg.invalid.ts:4:9 + 4 node: T; + ~ + and expects a GraphQL type because it was used in a GraphQL position here. +``` \ No newline at end of file diff --git a/src/tests/fixtures/generics/multiparamGeneric.ts.expected b/src/tests/fixtures/generics/multiparamGeneric.ts.expected deleted file mode 100644 index 75369444..00000000 --- a/src/tests/fixtures/generics/multiparamGeneric.ts.expected +++ /dev/null @@ -1,96 +0,0 @@ ------------------ -INPUT ------------------ -/** @gqlUnion */ -type Result = V | E; - -/** @gqlType */ -type Err = { - __typename: "Err"; - /** @gqlField */ - error: string; -}; - -/** @gqlType */ -type Page = { - __typename: "Page"; - /** @gqlField */ - title: string; -}; - -/** @gqlType */ -type Query = unknown; - -/** @gqlField */ -export function pageResult(_: Query): Result { - return { title: "Hello", __typename: "Page" }; -} - ------------------ -OUTPUT ------------------ --- SDL -- -union PageErrResult = Err | Page - -type Err { - error: String -} - -type Page { - title: String -} - -type Query { - pageResult: PageErrResult -} --- TypeScript -- -import { GraphQLSchema, GraphQLObjectType, GraphQLUnionType, GraphQLString } from "graphql"; -import { pageResult as queryPageResultResolver } from "./multiparamGeneric"; -export function getSchema(): GraphQLSchema { - const ErrType: GraphQLObjectType = new GraphQLObjectType({ - name: "Err", - fields() { - return { - error: { - name: "error", - type: GraphQLString - } - }; - } - }); - const PageType: GraphQLObjectType = new GraphQLObjectType({ - name: "Page", - fields() { - return { - title: { - name: "title", - type: GraphQLString - } - }; - } - }); - const PageErrResultType: GraphQLUnionType = new GraphQLUnionType({ - name: "PageErrResult", - types() { - return [ErrType, PageType]; - } - }); - const QueryType: GraphQLObjectType = new GraphQLObjectType({ - name: "Query", - fields() { - return { - pageResult: { - name: "pageResult", - type: PageErrResultType, - resolve(source) { - return queryPageResultResolver(source); - } - } - }; - } - }); - return new GraphQLSchema({ - query: QueryType, - types: [PageErrResultType, ErrType, PageType, QueryType] - }); -} diff --git a/src/tests/fixtures/generics/multiparamGeneric.ts.expected.md b/src/tests/fixtures/generics/multiparamGeneric.ts.expected.md new file mode 100644 index 00000000..7c83b23a --- /dev/null +++ b/src/tests/fixtures/generics/multiparamGeneric.ts.expected.md @@ -0,0 +1,103 @@ +## input + +```ts title="generics/multiparamGeneric.ts" +/** @gqlUnion */ +type Result = V | E; + +/** @gqlType */ +type Err = { + __typename: "Err"; + /** @gqlField */ + error: string; +}; + +/** @gqlType */ +type Page = { + __typename: "Page"; + /** @gqlField */ + title: string; +}; + +/** @gqlType */ +type Query = unknown; + +/** @gqlField */ +export function pageResult(_: Query): Result { + return { title: "Hello", __typename: "Page" }; +} +``` + +## Output + +### SDL + +```graphql +union PageErrResult = Err | Page + +type Err { + error: String +} + +type Page { + title: String +} + +type Query { + pageResult: PageErrResult +} +``` + +### TypeScript + +```ts +import { GraphQLSchema, GraphQLObjectType, GraphQLUnionType, GraphQLString } from "graphql"; +import { pageResult as queryPageResultResolver } from "./multiparamGeneric"; +export function getSchema(): GraphQLSchema { + const ErrType: GraphQLObjectType = new GraphQLObjectType({ + name: "Err", + fields() { + return { + error: { + name: "error", + type: GraphQLString + } + }; + } + }); + const PageType: GraphQLObjectType = new GraphQLObjectType({ + name: "Page", + fields() { + return { + title: { + name: "title", + type: GraphQLString + } + }; + } + }); + const PageErrResultType: GraphQLUnionType = new GraphQLUnionType({ + name: "PageErrResult", + types() { + return [ErrType, PageType]; + } + }); + const QueryType: GraphQLObjectType = new GraphQLObjectType({ + name: "Query", + fields() { + return { + pageResult: { + name: "pageResult", + type: PageErrResultType, + resolve(source) { + return queryPageResultResolver(source); + } + } + }; + } + }); + return new GraphQLSchema({ + query: QueryType, + types: [PageErrResultType, ErrType, PageType, QueryType] + }); +} +``` \ No newline at end of file diff --git a/src/tests/fixtures/generics/names/skippedTypeParam.ts.expected b/src/tests/fixtures/generics/names/skippedTypeParam.ts.expected deleted file mode 100644 index f034e98a..00000000 --- a/src/tests/fixtures/generics/names/skippedTypeParam.ts.expected +++ /dev/null @@ -1,105 +0,0 @@ ------------------ -INPUT ------------------ -/** @gqlType */ -type Edge = { - /** @gqlField */ - node: To; -}; - -/** @gqlType */ -type A = { - /** @gqlField */ - a: string; -}; - -/** @gqlType */ -type B = { - /** @gqlField */ - b: string; -}; - -/** @gqlQueryField */ -export function connection(): Edge { - return { - node: { - b: "b", - }, - }; -} - ------------------ -OUTPUT ------------------ --- SDL -- -type A { - a: String -} - -type B { - b: String -} - -type BEdge { - node: B -} - -type Query { - connection: BEdge -} --- TypeScript -- -import { GraphQLSchema, GraphQLObjectType, GraphQLString } from "graphql"; -import { connection as queryConnectionResolver } from "./skippedTypeParam"; -export function getSchema(): GraphQLSchema { - const BType: GraphQLObjectType = new GraphQLObjectType({ - name: "B", - fields() { - return { - b: { - name: "b", - type: GraphQLString - } - }; - } - }); - const BEdgeType: GraphQLObjectType = new GraphQLObjectType({ - name: "BEdge", - fields() { - return { - node: { - name: "node", - type: BType - } - }; - } - }); - const QueryType: GraphQLObjectType = new GraphQLObjectType({ - name: "Query", - fields() { - return { - connection: { - name: "connection", - type: BEdgeType, - resolve() { - return queryConnectionResolver(); - } - } - }; - } - }); - const AType: GraphQLObjectType = new GraphQLObjectType({ - name: "A", - fields() { - return { - a: { - name: "a", - type: GraphQLString - } - }; - } - }); - return new GraphQLSchema({ - query: QueryType, - types: [AType, BType, BEdgeType, QueryType] - }); -} diff --git a/src/tests/fixtures/generics/names/skippedTypeParam.ts.expected.md b/src/tests/fixtures/generics/names/skippedTypeParam.ts.expected.md new file mode 100644 index 00000000..9cf0fe40 --- /dev/null +++ b/src/tests/fixtures/generics/names/skippedTypeParam.ts.expected.md @@ -0,0 +1,112 @@ +## input + +```ts title="generics/names/skippedTypeParam.ts" +/** @gqlType */ +type Edge = { + /** @gqlField */ + node: To; +}; + +/** @gqlType */ +type A = { + /** @gqlField */ + a: string; +}; + +/** @gqlType */ +type B = { + /** @gqlField */ + b: string; +}; + +/** @gqlQueryField */ +export function connection(): Edge { + return { + node: { + b: "b", + }, + }; +} +``` + +## Output + +### SDL + +```graphql +type A { + a: String +} + +type B { + b: String +} + +type BEdge { + node: B +} + +type Query { + connection: BEdge +} +``` + +### TypeScript + +```ts +import { GraphQLSchema, GraphQLObjectType, GraphQLString } from "graphql"; +import { connection as queryConnectionResolver } from "./skippedTypeParam"; +export function getSchema(): GraphQLSchema { + const BType: GraphQLObjectType = new GraphQLObjectType({ + name: "B", + fields() { + return { + b: { + name: "b", + type: GraphQLString + } + }; + } + }); + const BEdgeType: GraphQLObjectType = new GraphQLObjectType({ + name: "BEdge", + fields() { + return { + node: { + name: "node", + type: BType + } + }; + } + }); + const QueryType: GraphQLObjectType = new GraphQLObjectType({ + name: "Query", + fields() { + return { + connection: { + name: "connection", + type: BEdgeType, + resolve() { + return queryConnectionResolver(); + } + } + }; + } + }); + const AType: GraphQLObjectType = new GraphQLObjectType({ + name: "A", + fields() { + return { + a: { + name: "a", + type: GraphQLString + } + }; + } + }); + return new GraphQLSchema({ + query: QueryType, + types: [AType, BType, BEdgeType, QueryType] + }); +} +``` \ No newline at end of file diff --git a/src/tests/fixtures/generics/names/skippedTypeParamPassesLiteral.ts.expected b/src/tests/fixtures/generics/names/skippedTypeParamPassesLiteral.ts.expected deleted file mode 100644 index 06df4b1b..00000000 --- a/src/tests/fixtures/generics/names/skippedTypeParamPassesLiteral.ts.expected +++ /dev/null @@ -1,110 +0,0 @@ ------------------ -INPUT ------------------ -/** @gqlType */ -type Edge = { - /** @gqlField */ - node: To; -}; - -/** @gqlType */ -type A = { - /** @gqlField */ - a: string; -}; - -/** @gqlType */ -type B = { - /** @gqlField */ - b: string; -}; - -/** @gqlQueryField */ -export function connection(): Edge< - // It's okay to pass a non-GQL type parameter here since `From` is not used in a - // GraphQL position. - {}, - B -> { - return { - node: { - b: "b", - }, - }; -} - ------------------ -OUTPUT ------------------ --- SDL -- -type A { - a: String -} - -type B { - b: String -} - -type BEdge { - node: B -} - -type Query { - connection: BEdge -} --- TypeScript -- -import { GraphQLSchema, GraphQLObjectType, GraphQLString } from "graphql"; -import { connection as queryConnectionResolver } from "./skippedTypeParamPassesLiteral"; -export function getSchema(): GraphQLSchema { - const BType: GraphQLObjectType = new GraphQLObjectType({ - name: "B", - fields() { - return { - b: { - name: "b", - type: GraphQLString - } - }; - } - }); - const BEdgeType: GraphQLObjectType = new GraphQLObjectType({ - name: "BEdge", - fields() { - return { - node: { - name: "node", - type: BType - } - }; - } - }); - const QueryType: GraphQLObjectType = new GraphQLObjectType({ - name: "Query", - fields() { - return { - connection: { - name: "connection", - type: BEdgeType, - resolve() { - return queryConnectionResolver(); - } - } - }; - } - }); - const AType: GraphQLObjectType = new GraphQLObjectType({ - name: "A", - fields() { - return { - a: { - name: "a", - type: GraphQLString - } - }; - } - }); - return new GraphQLSchema({ - query: QueryType, - types: [AType, BType, BEdgeType, QueryType] - }); -} diff --git a/src/tests/fixtures/generics/names/skippedTypeParamPassesLiteral.ts.expected.md b/src/tests/fixtures/generics/names/skippedTypeParamPassesLiteral.ts.expected.md new file mode 100644 index 00000000..590c72db --- /dev/null +++ b/src/tests/fixtures/generics/names/skippedTypeParamPassesLiteral.ts.expected.md @@ -0,0 +1,117 @@ +## input + +```ts title="generics/names/skippedTypeParamPassesLiteral.ts" +/** @gqlType */ +type Edge = { + /** @gqlField */ + node: To; +}; + +/** @gqlType */ +type A = { + /** @gqlField */ + a: string; +}; + +/** @gqlType */ +type B = { + /** @gqlField */ + b: string; +}; + +/** @gqlQueryField */ +export function connection(): Edge< + // It's okay to pass a non-GQL type parameter here since `From` is not used in a + // GraphQL position. + {}, + B +> { + return { + node: { + b: "b", + }, + }; +} +``` + +## Output + +### SDL + +```graphql +type A { + a: String +} + +type B { + b: String +} + +type BEdge { + node: B +} + +type Query { + connection: BEdge +} +``` + +### TypeScript + +```ts +import { GraphQLSchema, GraphQLObjectType, GraphQLString } from "graphql"; +import { connection as queryConnectionResolver } from "./skippedTypeParamPassesLiteral"; +export function getSchema(): GraphQLSchema { + const BType: GraphQLObjectType = new GraphQLObjectType({ + name: "B", + fields() { + return { + b: { + name: "b", + type: GraphQLString + } + }; + } + }); + const BEdgeType: GraphQLObjectType = new GraphQLObjectType({ + name: "BEdge", + fields() { + return { + node: { + name: "node", + type: BType + } + }; + } + }); + const QueryType: GraphQLObjectType = new GraphQLObjectType({ + name: "Query", + fields() { + return { + connection: { + name: "connection", + type: BEdgeType, + resolve() { + return queryConnectionResolver(); + } + } + }; + } + }); + const AType: GraphQLObjectType = new GraphQLObjectType({ + name: "A", + fields() { + return { + a: { + name: "a", + type: GraphQLString + } + }; + } + }); + return new GraphQLSchema({ + query: QueryType, + types: [AType, BType, BEdgeType, QueryType] + }); +} +``` \ No newline at end of file diff --git a/src/tests/fixtures/generics/passOuptutTypeToInputType.input.invalid.ts.expected b/src/tests/fixtures/generics/passOuptutTypeToInputType.input.invalid.ts.expected deleted file mode 100644 index f305e171..00000000 --- a/src/tests/fixtures/generics/passOuptutTypeToInputType.input.invalid.ts.expected +++ /dev/null @@ -1,28 +0,0 @@ ------------------ -INPUT ------------------ -/** @gqlInput */ -export type SomeInput = { - someField: T; -}; - -/** @gqlInput */ -type AnotherInput = { - anotherField: string; -}; - -/** @gqlType */ -class SomeClass { - /** @gqlField */ - someField(args: { someArg: SomeInput }): string { - return args.someArg.someField.someField(args); - } -} - ------------------ -OUTPUT ------------------ -src/tests/fixtures/generics/passOuptutTypeToInputType.input.invalid.ts:3:14 - error: The type of SomeClassSomeInput.someField must be Input Type but got: SomeClass!. - -3 someField: T; - ~ diff --git a/src/tests/fixtures/generics/passOuptutTypeToInputType.input.invalid.ts.expected.md b/src/tests/fixtures/generics/passOuptutTypeToInputType.input.invalid.ts.expected.md new file mode 100644 index 00000000..0718d309 --- /dev/null +++ b/src/tests/fixtures/generics/passOuptutTypeToInputType.input.invalid.ts.expected.md @@ -0,0 +1,32 @@ +## input + +```ts title="generics/passOuptutTypeToInputType.input.invalid.ts" +/** @gqlInput */ +export type SomeInput = { + someField: T; +}; + +/** @gqlInput */ +type AnotherInput = { + anotherField: string; +}; + +/** @gqlType */ +class SomeClass { + /** @gqlField */ + someField(args: { someArg: SomeInput }): string { + return args.someArg.someField.someField(args); + } +} +``` + +## Output + +### Error Report + +```text +src/tests/fixtures/generics/passOuptutTypeToInputType.input.invalid.ts:3:14 - error: The type of SomeClassSomeInput.someField must be Input Type but got: SomeClass!. + +3 someField: T; + ~ +``` \ No newline at end of file diff --git a/src/tests/fixtures/generics/referencingMethodGeneric.invalid.ts.expected b/src/tests/fixtures/generics/referencingMethodGeneric.invalid.ts.expected deleted file mode 100644 index 188ad33e..00000000 --- a/src/tests/fixtures/generics/referencingMethodGeneric.invalid.ts.expected +++ /dev/null @@ -1,23 +0,0 @@ ------------------ -INPUT ------------------ -/** @gqlType */ -type Query = unknown; - -/** @gqlField */ -export function greeting(_: Query): T { - return null as any; -} - ------------------ -OUTPUT ------------------ -src/tests/fixtures/generics/referencingMethodGeneric.invalid.ts:5:40 - error: Type parameter not valid - -5 export function greeting(_: Query): T { - ~ - - src/tests/fixtures/generics/referencingMethodGeneric.invalid.ts:5:26 - 5 export function greeting(_: Query): T { - ~ - Defined here diff --git a/src/tests/fixtures/generics/referencingMethodGeneric.invalid.ts.expected.md b/src/tests/fixtures/generics/referencingMethodGeneric.invalid.ts.expected.md new file mode 100644 index 00000000..9b973f61 --- /dev/null +++ b/src/tests/fixtures/generics/referencingMethodGeneric.invalid.ts.expected.md @@ -0,0 +1,27 @@ +## input + +```ts title="generics/referencingMethodGeneric.invalid.ts" +/** @gqlType */ +type Query = unknown; + +/** @gqlField */ +export function greeting(_: Query): T { + return null as any; +} +``` + +## Output + +### Error Report + +```text +src/tests/fixtures/generics/referencingMethodGeneric.invalid.ts:5:40 - error: Type parameter not valid + +5 export function greeting(_: Query): T { + ~ + + src/tests/fixtures/generics/referencingMethodGeneric.invalid.ts:5:26 + 5 export function greeting(_: Query): T { + ~ + Defined here +``` \ No newline at end of file diff --git a/src/tests/fixtures/generics/result.ts.expected b/src/tests/fixtures/generics/result.ts.expected deleted file mode 100644 index 7b89fdfa..00000000 --- a/src/tests/fixtures/generics/result.ts.expected +++ /dev/null @@ -1,89 +0,0 @@ ------------------ -INPUT ------------------ -/** @gqlType */ -type Err = { - __typename: "Err"; - /** @gqlField */ - message: string; -}; - -/** @gqlUnion */ -type Result = T | Err; - -/** @gqlType */ -export type Page = { - __typename: "Page"; - /** @gqlField */ - name: string; -}; - -/** @gqlType */ -export type SomeType = { - /** @gqlField */ - pageResult: Result; -}; - ------------------ -OUTPUT ------------------ --- SDL -- -union PageResult = Err | Page - -type Err { - message: String -} - -type Page { - name: String -} - -type SomeType { - pageResult: PageResult -} --- TypeScript -- -import { GraphQLSchema, GraphQLUnionType, GraphQLObjectType, GraphQLString } from "graphql"; -export function getSchema(): GraphQLSchema { - const ErrType: GraphQLObjectType = new GraphQLObjectType({ - name: "Err", - fields() { - return { - message: { - name: "message", - type: GraphQLString - } - }; - } - }); - const PageType: GraphQLObjectType = new GraphQLObjectType({ - name: "Page", - fields() { - return { - name: { - name: "name", - type: GraphQLString - } - }; - } - }); - const PageResultType: GraphQLUnionType = new GraphQLUnionType({ - name: "PageResult", - types() { - return [ErrType, PageType]; - } - }); - const SomeTypeType: GraphQLObjectType = new GraphQLObjectType({ - name: "SomeType", - fields() { - return { - pageResult: { - name: "pageResult", - type: PageResultType - } - }; - } - }); - return new GraphQLSchema({ - types: [PageResultType, ErrType, PageType, SomeTypeType] - }); -} diff --git a/src/tests/fixtures/generics/result.ts.expected.md b/src/tests/fixtures/generics/result.ts.expected.md new file mode 100644 index 00000000..7380f57b --- /dev/null +++ b/src/tests/fixtures/generics/result.ts.expected.md @@ -0,0 +1,96 @@ +## input + +```ts title="generics/result.ts" +/** @gqlType */ +type Err = { + __typename: "Err"; + /** @gqlField */ + message: string; +}; + +/** @gqlUnion */ +type Result = T | Err; + +/** @gqlType */ +export type Page = { + __typename: "Page"; + /** @gqlField */ + name: string; +}; + +/** @gqlType */ +export type SomeType = { + /** @gqlField */ + pageResult: Result; +}; +``` + +## Output + +### SDL + +```graphql +union PageResult = Err | Page + +type Err { + message: String +} + +type Page { + name: String +} + +type SomeType { + pageResult: PageResult +} +``` + +### TypeScript + +```ts +import { GraphQLSchema, GraphQLUnionType, GraphQLObjectType, GraphQLString } from "graphql"; +export function getSchema(): GraphQLSchema { + const ErrType: GraphQLObjectType = new GraphQLObjectType({ + name: "Err", + fields() { + return { + message: { + name: "message", + type: GraphQLString + } + }; + } + }); + const PageType: GraphQLObjectType = new GraphQLObjectType({ + name: "Page", + fields() { + return { + name: { + name: "name", + type: GraphQLString + } + }; + } + }); + const PageResultType: GraphQLUnionType = new GraphQLUnionType({ + name: "PageResult", + types() { + return [ErrType, PageType]; + } + }); + const SomeTypeType: GraphQLObjectType = new GraphQLObjectType({ + name: "SomeType", + fields() { + return { + pageResult: { + name: "pageResult", + type: PageResultType + } + }; + } + }); + return new GraphQLSchema({ + types: [PageResultType, ErrType, PageType, SomeTypeType] + }); +} +``` \ No newline at end of file diff --git a/src/tests/fixtures/generics/scalarPassedAsGenericArg.invalid.ts.expected b/src/tests/fixtures/generics/scalarPassedAsGenericArg.invalid.ts.expected deleted file mode 100644 index a3cfe1d8..00000000 --- a/src/tests/fixtures/generics/scalarPassedAsGenericArg.invalid.ts.expected +++ /dev/null @@ -1,31 +0,0 @@ ------------------ -INPUT ------------------ -/** @gqlType */ -type Wrapper = { - /** @gqlField */ - value: T; -}; - -/** @gqlType */ -type OtherType = { - /** @gqlField */ - wrapper: Wrapper; -}; - ------------------ -OUTPUT ------------------ -src/tests/fixtures/generics/scalarPassedAsGenericArg.invalid.ts:10:20 - error: Expected `Wrapper` to be passed a GraphQL type argument for type parameter `T`. - -10 wrapper: Wrapper; - ~~~~~~ - - src/tests/fixtures/generics/scalarPassedAsGenericArg.invalid.ts:2:14 - 2 type Wrapper = { - ~ - Type parameter `T` is defined here - src/tests/fixtures/generics/scalarPassedAsGenericArg.invalid.ts:4:10 - 4 value: T; - ~ - and expects a GraphQL type because it was used in a GraphQL position here. diff --git a/src/tests/fixtures/generics/scalarPassedAsGenericArg.invalid.ts.expected.md b/src/tests/fixtures/generics/scalarPassedAsGenericArg.invalid.ts.expected.md new file mode 100644 index 00000000..96ec9d14 --- /dev/null +++ b/src/tests/fixtures/generics/scalarPassedAsGenericArg.invalid.ts.expected.md @@ -0,0 +1,35 @@ +## input + +```ts title="generics/scalarPassedAsGenericArg.invalid.ts" +/** @gqlType */ +type Wrapper = { + /** @gqlField */ + value: T; +}; + +/** @gqlType */ +type OtherType = { + /** @gqlField */ + wrapper: Wrapper; +}; +``` + +## Output + +### Error Report + +```text +src/tests/fixtures/generics/scalarPassedAsGenericArg.invalid.ts:10:20 - error: Expected `Wrapper` to be passed a GraphQL type argument for type parameter `T`. + +10 wrapper: Wrapper; + ~~~~~~ + + src/tests/fixtures/generics/scalarPassedAsGenericArg.invalid.ts:2:14 + 2 type Wrapper = { + ~ + Type parameter `T` is defined here + src/tests/fixtures/generics/scalarPassedAsGenericArg.invalid.ts:4:10 + 4 value: T; + ~ + and expects a GraphQL type because it was used in a GraphQL position here. +``` \ No newline at end of file diff --git a/src/tests/fixtures/generics/scalarPassedAsNonGqlGenericArg.ts.expected b/src/tests/fixtures/generics/scalarPassedAsNonGqlGenericArg.ts.expected deleted file mode 100644 index 21f922d3..00000000 --- a/src/tests/fixtures/generics/scalarPassedAsNonGqlGenericArg.ts.expected +++ /dev/null @@ -1,55 +0,0 @@ ------------------ -INPUT ------------------ -/** @gqlType */ -type Wrapper = { - /** @gqlField */ - value: string; -}; - -/** @gqlType */ -type OtherType = { - /** @gqlField */ - wrapper: Wrapper; -}; - ------------------ -OUTPUT ------------------ --- SDL -- -type OtherType { - wrapper: Wrapper -} - -type Wrapper { - value: String -} --- TypeScript -- -import { GraphQLSchema, GraphQLObjectType, GraphQLString } from "graphql"; -export function getSchema(): GraphQLSchema { - const WrapperType: GraphQLObjectType = new GraphQLObjectType({ - name: "Wrapper", - fields() { - return { - value: { - name: "value", - type: GraphQLString - } - }; - } - }); - const OtherTypeType: GraphQLObjectType = new GraphQLObjectType({ - name: "OtherType", - fields() { - return { - wrapper: { - name: "wrapper", - type: WrapperType - } - }; - } - }); - return new GraphQLSchema({ - types: [OtherTypeType, WrapperType] - }); -} diff --git a/src/tests/fixtures/generics/scalarPassedAsNonGqlGenericArg.ts.expected.md b/src/tests/fixtures/generics/scalarPassedAsNonGqlGenericArg.ts.expected.md new file mode 100644 index 00000000..f4d32853 --- /dev/null +++ b/src/tests/fixtures/generics/scalarPassedAsNonGqlGenericArg.ts.expected.md @@ -0,0 +1,62 @@ +## input + +```ts title="generics/scalarPassedAsNonGqlGenericArg.ts" +/** @gqlType */ +type Wrapper = { + /** @gqlField */ + value: string; +}; + +/** @gqlType */ +type OtherType = { + /** @gqlField */ + wrapper: Wrapper; +}; +``` + +## Output + +### SDL + +```graphql +type OtherType { + wrapper: Wrapper +} + +type Wrapper { + value: String +} +``` + +### TypeScript + +```ts +import { GraphQLSchema, GraphQLObjectType, GraphQLString } from "graphql"; +export function getSchema(): GraphQLSchema { + const WrapperType: GraphQLObjectType = new GraphQLObjectType({ + name: "Wrapper", + fields() { + return { + value: { + name: "value", + type: GraphQLString + } + }; + } + }); + const OtherTypeType: GraphQLObjectType = new GraphQLObjectType({ + name: "OtherType", + fields() { + return { + wrapper: { + name: "wrapper", + type: WrapperType + } + }; + } + }); + return new GraphQLSchema({ + types: [OtherTypeType, WrapperType] + }); +} +``` \ No newline at end of file diff --git a/src/tests/fixtures/generics/scalarWithGeneric.ts.expected b/src/tests/fixtures/generics/scalarWithGeneric.ts.expected deleted file mode 100644 index 71d8e581..00000000 --- a/src/tests/fixtures/generics/scalarWithGeneric.ts.expected +++ /dev/null @@ -1,30 +0,0 @@ ------------------ -INPUT ------------------ -// T is not inspected by Grats, so this is fine. -/** @gqlScalar */ -export type MyScalar = T; - ------------------ -OUTPUT ------------------ --- SDL -- -scalar MyScalar --- TypeScript -- -import type { GqlScalar } from "grats"; -import type { MyScalar as MyScalarInternal } from "./scalarWithGeneric"; -import { GraphQLSchema, GraphQLScalarType } from "graphql"; -export type SchemaConfig = { - scalars: { - MyScalar: GqlScalar; - }; -}; -export function getSchema(config: SchemaConfig): GraphQLSchema { - const MyScalarType: GraphQLScalarType = new GraphQLScalarType({ - name: "MyScalar", - ...config.scalars.MyScalar - }); - return new GraphQLSchema({ - types: [MyScalarType] - }); -} diff --git a/src/tests/fixtures/generics/scalarWithGeneric.ts.expected.md b/src/tests/fixtures/generics/scalarWithGeneric.ts.expected.md new file mode 100644 index 00000000..6a97fb01 --- /dev/null +++ b/src/tests/fixtures/generics/scalarWithGeneric.ts.expected.md @@ -0,0 +1,37 @@ +## input + +```ts title="generics/scalarWithGeneric.ts" +// T is not inspected by Grats, so this is fine. +/** @gqlScalar */ +export type MyScalar = T; +``` + +## Output + +### SDL + +```graphql +scalar MyScalar +``` + +### TypeScript + +```ts +import type { GqlScalar } from "grats"; +import type { MyScalar as MyScalarInternal } from "./scalarWithGeneric"; +import { GraphQLSchema, GraphQLScalarType } from "graphql"; +export type SchemaConfig = { + scalars: { + MyScalar: GqlScalar; + }; +}; +export function getSchema(config: SchemaConfig): GraphQLSchema { + const MyScalarType: GraphQLScalarType = new GraphQLScalarType({ + name: "MyScalar", + ...config.scalars.MyScalar + }); + return new GraphQLSchema({ + types: [MyScalarType] + }); +} +``` \ No newline at end of file diff --git a/src/tests/fixtures/generics/todo/genericInterfaceFromTypeParam.invalid.ts.expected b/src/tests/fixtures/generics/todo/genericInterfaceFromTypeParam.invalid.ts.expected deleted file mode 100644 index 456e5286..00000000 --- a/src/tests/fixtures/generics/todo/genericInterfaceFromTypeParam.invalid.ts.expected +++ /dev/null @@ -1,31 +0,0 @@ ------------------ -INPUT ------------------ -/** @gqlType */ -export class User implements Friendly { - __typename: "User"; - /** @gqlField */ - name: string; -} - -/** @gqlInterface */ -interface Friendly { - /** @gqlField */ - name: string; -} - -/** @gqlType */ -class Dog { - /** @gqlField */ - name: string; - /** @gqlField */ - bestFriend: User; -} - ------------------ -OUTPUT ------------------ -src/tests/fixtures/generics/todo/genericInterfaceFromTypeParam.invalid.ts:2:33 - error: Unexpected `implements` on generic `gqlType`. Generic types may not currently declare themselves as implementing interfaces. Grats requires that all types which implement an interface define a `__typename` field typed as a string literal matching the type's name. Since generic types are synthesized into multiple types with different names, Grats cannot ensure they have a correct `__typename` property and thus declare themselves as interface implementors. - -2 export class User implements Friendly { - ~~~~~~~~ diff --git a/src/tests/fixtures/generics/todo/genericInterfaceFromTypeParam.invalid.ts.expected.md b/src/tests/fixtures/generics/todo/genericInterfaceFromTypeParam.invalid.ts.expected.md new file mode 100644 index 00000000..a1fe6f47 --- /dev/null +++ b/src/tests/fixtures/generics/todo/genericInterfaceFromTypeParam.invalid.ts.expected.md @@ -0,0 +1,35 @@ +## input + +```ts title="generics/todo/genericInterfaceFromTypeParam.invalid.ts" +/** @gqlType */ +export class User implements Friendly { + __typename: "User"; + /** @gqlField */ + name: string; +} + +/** @gqlInterface */ +interface Friendly { + /** @gqlField */ + name: string; +} + +/** @gqlType */ +class Dog { + /** @gqlField */ + name: string; + /** @gqlField */ + bestFriend: User; +} +``` + +## Output + +### Error Report + +```text +src/tests/fixtures/generics/todo/genericInterfaceFromTypeParam.invalid.ts:2:33 - error: Unexpected `implements` on generic `gqlType`. Generic types may not currently declare themselves as implementing interfaces. Grats requires that all types which implement an interface define a `__typename` field typed as a string literal matching the type's name. Since generic types are synthesized into multiple types with different names, Grats cannot ensure they have a correct `__typename` property and thus declare themselves as interface implementors. + +2 export class User implements Friendly { + ~~~~~~~~ +``` \ No newline at end of file diff --git a/src/tests/fixtures/generics/todo/genericTypeImplementsInterface.invalid.ts.expected b/src/tests/fixtures/generics/todo/genericTypeImplementsInterface.invalid.ts.expected deleted file mode 100644 index 11bb181f..00000000 --- a/src/tests/fixtures/generics/todo/genericTypeImplementsInterface.invalid.ts.expected +++ /dev/null @@ -1,34 +0,0 @@ ------------------ -INPUT ------------------ -/** @gqlType */ -export class User implements Friendly { - __typename: "User"; - /** @gqlField */ - name: string; - - /** @gqlField */ - friend: T; -} - -/** @gqlInterface */ -interface Friendly { - /** @gqlField */ - name: string; -} - -/** @gqlType */ -class Dog { - /** @gqlField */ - name: string; - /** @gqlField */ - bestFriend: User; -} - ------------------ -OUTPUT ------------------ -src/tests/fixtures/generics/todo/genericTypeImplementsInterface.invalid.ts:2:33 - error: Unexpected `implements` on generic `gqlType`. Generic types may not currently declare themselves as implementing interfaces. Grats requires that all types which implement an interface define a `__typename` field typed as a string literal matching the type's name. Since generic types are synthesized into multiple types with different names, Grats cannot ensure they have a correct `__typename` property and thus declare themselves as interface implementors. - -2 export class User implements Friendly { - ~~~~~~~~ diff --git a/src/tests/fixtures/generics/todo/genericTypeImplementsInterface.invalid.ts.expected.md b/src/tests/fixtures/generics/todo/genericTypeImplementsInterface.invalid.ts.expected.md new file mode 100644 index 00000000..e9efc570 --- /dev/null +++ b/src/tests/fixtures/generics/todo/genericTypeImplementsInterface.invalid.ts.expected.md @@ -0,0 +1,38 @@ +## input + +```ts title="generics/todo/genericTypeImplementsInterface.invalid.ts" +/** @gqlType */ +export class User implements Friendly { + __typename: "User"; + /** @gqlField */ + name: string; + + /** @gqlField */ + friend: T; +} + +/** @gqlInterface */ +interface Friendly { + /** @gqlField */ + name: string; +} + +/** @gqlType */ +class Dog { + /** @gqlField */ + name: string; + /** @gqlField */ + bestFriend: User; +} +``` + +## Output + +### Error Report + +```text +src/tests/fixtures/generics/todo/genericTypeImplementsInterface.invalid.ts:2:33 - error: Unexpected `implements` on generic `gqlType`. Generic types may not currently declare themselves as implementing interfaces. Grats requires that all types which implement an interface define a `__typename` field typed as a string literal matching the type's name. Since generic types are synthesized into multiple types with different names, Grats cannot ensure they have a correct `__typename` property and thus declare themselves as interface implementors. + +2 export class User implements Friendly { + ~~~~~~~~ +``` \ No newline at end of file diff --git a/src/tests/fixtures/generics/todo/genericTypeMemberOfUnion.ts.expected b/src/tests/fixtures/generics/todo/genericTypeMemberOfUnion.ts.expected deleted file mode 100644 index 17a0a3a2..00000000 --- a/src/tests/fixtures/generics/todo/genericTypeMemberOfUnion.ts.expected +++ /dev/null @@ -1,47 +0,0 @@ ------------------ -INPUT ------------------ -/** @gqlType */ -export class User { - __typename: "User"; - /** @gqlField */ - name: string; - - /** @gqlField */ - friend: T; -} - -/** @gqUnion */ -type Friendly = User; - -/** @gqlType */ -class Dog { - /** @gqlField */ - name: string; -} - ------------------ -OUTPUT ------------------ --- SDL -- -type Dog { - name: String -} --- TypeScript -- -import { GraphQLSchema, GraphQLObjectType, GraphQLString } from "graphql"; -export function getSchema(): GraphQLSchema { - const DogType: GraphQLObjectType = new GraphQLObjectType({ - name: "Dog", - fields() { - return { - name: { - name: "name", - type: GraphQLString - } - }; - } - }); - return new GraphQLSchema({ - types: [DogType] - }); -} diff --git a/src/tests/fixtures/generics/todo/genericTypeMemberOfUnion.ts.expected.md b/src/tests/fixtures/generics/todo/genericTypeMemberOfUnion.ts.expected.md new file mode 100644 index 00000000..9683902a --- /dev/null +++ b/src/tests/fixtures/generics/todo/genericTypeMemberOfUnion.ts.expected.md @@ -0,0 +1,54 @@ +## input + +```ts title="generics/todo/genericTypeMemberOfUnion.ts" +/** @gqlType */ +export class User { + __typename: "User"; + /** @gqlField */ + name: string; + + /** @gqlField */ + friend: T; +} + +/** @gqUnion */ +type Friendly = User; + +/** @gqlType */ +class Dog { + /** @gqlField */ + name: string; +} +``` + +## Output + +### SDL + +```graphql +type Dog { + name: String +} +``` + +### TypeScript + +```ts +import { GraphQLSchema, GraphQLObjectType, GraphQLString } from "graphql"; +export function getSchema(): GraphQLSchema { + const DogType: GraphQLObjectType = new GraphQLObjectType({ + name: "Dog", + fields() { + return { + name: { + name: "name", + type: GraphQLString + } + }; + } + }); + return new GraphQLSchema({ + types: [DogType] + }); +} +``` \ No newline at end of file diff --git a/src/tests/fixtures/generics/undefinedTypeUsedAsGenericTypeArg.invalid.ts.expected b/src/tests/fixtures/generics/undefinedTypeUsedAsGenericTypeArg.invalid.ts.expected deleted file mode 100644 index 8d57c1f7..00000000 --- a/src/tests/fixtures/generics/undefinedTypeUsedAsGenericTypeArg.invalid.ts.expected +++ /dev/null @@ -1,24 +0,0 @@ ------------------ -INPUT ------------------ -/** @gqlType */ -type Edge = { - /** @gqlField */ - node: T; - /** @gqlField */ - cursor: string; -}; - -/** @gqlType */ -export type PageConnection = { - /** @gqlField */ - edges: Edge[]; -}; - ------------------ -OUTPUT ------------------ -src/tests/fixtures/generics/undefinedTypeUsedAsGenericTypeArg.invalid.ts:12:15 - error: Unable to resolve type reference. In order to generate a GraphQL schema, Grats needs to determine which GraphQL type is being referenced. This requires being able to resolve type references to their `@gql` annotated declaration. However this reference could not be resolved. Is it possible that this type is not defined in this file? - -12 edges: Edge[]; - ~~~~ diff --git a/src/tests/fixtures/generics/undefinedTypeUsedAsGenericTypeArg.invalid.ts.expected.md b/src/tests/fixtures/generics/undefinedTypeUsedAsGenericTypeArg.invalid.ts.expected.md new file mode 100644 index 00000000..42703379 --- /dev/null +++ b/src/tests/fixtures/generics/undefinedTypeUsedAsGenericTypeArg.invalid.ts.expected.md @@ -0,0 +1,28 @@ +## input + +```ts title="generics/undefinedTypeUsedAsGenericTypeArg.invalid.ts" +/** @gqlType */ +type Edge = { + /** @gqlField */ + node: T; + /** @gqlField */ + cursor: string; +}; + +/** @gqlType */ +export type PageConnection = { + /** @gqlField */ + edges: Edge[]; +}; +``` + +## Output + +### Error Report + +```text +src/tests/fixtures/generics/undefinedTypeUsedAsGenericTypeArg.invalid.ts:12:15 - error: Unable to resolve type reference. In order to generate a GraphQL schema, Grats needs to determine which GraphQL type is being referenced. This requires being able to resolve type references to their `@gql` annotated declaration. However this reference could not be resolved. Is it possible that this type is not defined in this file? + +12 edges: Edge[]; + ~~~~ +``` \ No newline at end of file diff --git a/src/tests/fixtures/headers/customHeaders.ts.expected b/src/tests/fixtures/headers/customHeaders.ts.expected deleted file mode 100644 index 40b9c3bf..00000000 --- a/src/tests/fixtures/headers/customHeaders.ts.expected +++ /dev/null @@ -1,39 +0,0 @@ ------------------ -INPUT ------------------ -// {"schemaHeader": "# Generated SDL", "tsSchemaHeader": "// Generated TS"} -/** @gqlType */ -export default class SomeType { - /** @gqlField */ - hello: string; -} - ------------------ -OUTPUT ------------------ --- SDL -- -# Generated SDL - -type SomeType { - hello: String -} --- TypeScript -- -// Generated TS - -import { GraphQLSchema, GraphQLObjectType, GraphQLString } from "graphql"; -export function getSchema(): GraphQLSchema { - const SomeTypeType: GraphQLObjectType = new GraphQLObjectType({ - name: "SomeType", - fields() { - return { - hello: { - name: "hello", - type: GraphQLString - } - }; - } - }); - return new GraphQLSchema({ - types: [SomeTypeType] - }); -} diff --git a/src/tests/fixtures/headers/customHeaders.ts.expected.md b/src/tests/fixtures/headers/customHeaders.ts.expected.md new file mode 100644 index 00000000..cdb3e6e0 --- /dev/null +++ b/src/tests/fixtures/headers/customHeaders.ts.expected.md @@ -0,0 +1,46 @@ +## input + +```ts title="headers/customHeaders.ts" +// {"schemaHeader": "# Generated SDL", "tsSchemaHeader": "// Generated TS"} +/** @gqlType */ +export default class SomeType { + /** @gqlField */ + hello: string; +} +``` + +## Output + +### SDL + +```graphql +# Generated SDL + +type SomeType { + hello: String +} +``` + +### TypeScript + +```ts +// Generated TS + +import { GraphQLSchema, GraphQLObjectType, GraphQLString } from "graphql"; +export function getSchema(): GraphQLSchema { + const SomeTypeType: GraphQLObjectType = new GraphQLObjectType({ + name: "SomeType", + fields() { + return { + hello: { + name: "hello", + type: GraphQLString + } + }; + } + }); + return new GraphQLSchema({ + types: [SomeTypeType] + }); +} +``` \ No newline at end of file diff --git a/src/tests/fixtures/headers/multilineHeader.ts.expected b/src/tests/fixtures/headers/multilineHeader.ts.expected deleted file mode 100644 index cd5be9e5..00000000 --- a/src/tests/fixtures/headers/multilineHeader.ts.expected +++ /dev/null @@ -1,43 +0,0 @@ ------------------ -INPUT ------------------ -// {"schemaHeader": ["# Generated SDL\n", "# multi-line"], "tsSchemaHeader": ["// Generated TS\n", "// multi-line"]} -/** @gqlType */ -export default class SomeType { - /** @gqlField */ - hello: string; -} - ------------------ -OUTPUT ------------------ --- SDL -- -# Generated SDL - -# multi-line - -type SomeType { - hello: String -} --- TypeScript -- -// Generated TS - -// multi-line - -import { GraphQLSchema, GraphQLObjectType, GraphQLString } from "graphql"; -export function getSchema(): GraphQLSchema { - const SomeTypeType: GraphQLObjectType = new GraphQLObjectType({ - name: "SomeType", - fields() { - return { - hello: { - name: "hello", - type: GraphQLString - } - }; - } - }); - return new GraphQLSchema({ - types: [SomeTypeType] - }); -} diff --git a/src/tests/fixtures/headers/multilineHeader.ts.expected.md b/src/tests/fixtures/headers/multilineHeader.ts.expected.md new file mode 100644 index 00000000..d3d58d8a --- /dev/null +++ b/src/tests/fixtures/headers/multilineHeader.ts.expected.md @@ -0,0 +1,50 @@ +## input + +```ts title="headers/multilineHeader.ts" +// {"schemaHeader": ["# Generated SDL\n", "# multi-line"], "tsSchemaHeader": ["// Generated TS\n", "// multi-line"]} +/** @gqlType */ +export default class SomeType { + /** @gqlField */ + hello: string; +} +``` + +## Output + +### SDL + +```graphql +# Generated SDL + +# multi-line + +type SomeType { + hello: String +} +``` + +### TypeScript + +```ts +// Generated TS + +// multi-line + +import { GraphQLSchema, GraphQLObjectType, GraphQLString } from "graphql"; +export function getSchema(): GraphQLSchema { + const SomeTypeType: GraphQLObjectType = new GraphQLObjectType({ + name: "SomeType", + fields() { + return { + hello: { + name: "hello", + type: GraphQLString + } + }; + } + }); + return new GraphQLSchema({ + types: [SomeTypeType] + }); +} +``` \ No newline at end of file diff --git a/src/tests/fixtures/input_type_one_of/oneOfDeprecated.invalid.ts.expected b/src/tests/fixtures/input_type_one_of/oneOfDeprecated.invalid.ts.expected deleted file mode 100644 index 86ac1fdd..00000000 --- a/src/tests/fixtures/input_type_one_of/oneOfDeprecated.invalid.ts.expected +++ /dev/null @@ -1,16 +0,0 @@ ------------------ -INPUT ------------------ -/** - * @gqlInput - * @deprecated Don't use this any more - */ -export type Greeting = { firstName: string } | { lastName: string }; - ------------------ -OUTPUT ------------------ -src/tests/fixtures/input_type_one_of/oneOfDeprecated.invalid.ts:3:5 - error: Directive "@deprecated" may not be used on INPUT_OBJECT. - -3 * @deprecated Don't use this any more - ~~~~~~~~~~ diff --git a/src/tests/fixtures/input_type_one_of/oneOfDeprecated.invalid.ts.expected.md b/src/tests/fixtures/input_type_one_of/oneOfDeprecated.invalid.ts.expected.md new file mode 100644 index 00000000..52cbbac9 --- /dev/null +++ b/src/tests/fixtures/input_type_one_of/oneOfDeprecated.invalid.ts.expected.md @@ -0,0 +1,20 @@ +## input + +```ts title="input_type_one_of/oneOfDeprecated.invalid.ts" +/** + * @gqlInput + * @deprecated Don't use this any more + */ +export type Greeting = { firstName: string } | { lastName: string }; +``` + +## Output + +### Error Report + +```text +src/tests/fixtures/input_type_one_of/oneOfDeprecated.invalid.ts:3:5 - error: Directive "@deprecated" may not be used on INPUT_OBJECT. + +3 * @deprecated Don't use this any more + ~~~~~~~~~~ +``` \ No newline at end of file diff --git a/src/tests/fixtures/input_type_one_of/oneOfFieldIsNullable.ts.expected b/src/tests/fixtures/input_type_one_of/oneOfFieldIsNullable.ts.expected deleted file mode 100644 index f266623c..00000000 --- a/src/tests/fixtures/input_type_one_of/oneOfFieldIsNullable.ts.expected +++ /dev/null @@ -1,39 +0,0 @@ ------------------ -INPUT ------------------ -/** - * @gqlInput - */ -export type Greeting = { firstName: string } | { lastName: string | null }; - ------------------ -OUTPUT ------------------ --- SDL -- -input Greeting @oneOf { - firstName: String - lastName: String -} --- TypeScript -- -import { GraphQLSchema, GraphQLInputObjectType, GraphQLString } from "graphql"; -export function getSchema(): GraphQLSchema { - const GreetingType: GraphQLInputObjectType = new GraphQLInputObjectType({ - name: "Greeting", - fields() { - return { - firstName: { - name: "firstName", - type: GraphQLString - }, - lastName: { - name: "lastName", - type: GraphQLString - } - }; - }, - isOneOf: true - }); - return new GraphQLSchema({ - types: [GreetingType] - }); -} diff --git a/src/tests/fixtures/input_type_one_of/oneOfFieldIsNullable.ts.expected.md b/src/tests/fixtures/input_type_one_of/oneOfFieldIsNullable.ts.expected.md new file mode 100644 index 00000000..b3a90aa0 --- /dev/null +++ b/src/tests/fixtures/input_type_one_of/oneOfFieldIsNullable.ts.expected.md @@ -0,0 +1,46 @@ +## input + +```ts title="input_type_one_of/oneOfFieldIsNullable.ts" +/** + * @gqlInput + */ +export type Greeting = { firstName: string } | { lastName: string | null }; +``` + +## Output + +### SDL + +```graphql +input Greeting @oneOf { + firstName: String + lastName: String +} +``` + +### TypeScript + +```ts +import { GraphQLSchema, GraphQLInputObjectType, GraphQLString } from "graphql"; +export function getSchema(): GraphQLSchema { + const GreetingType: GraphQLInputObjectType = new GraphQLInputObjectType({ + name: "Greeting", + fields() { + return { + firstName: { + name: "firstName", + type: GraphQLString + }, + lastName: { + name: "lastName", + type: GraphQLString + } + }; + }, + isOneOf: true + }); + return new GraphQLSchema({ + types: [GreetingType] + }); +} +``` \ No newline at end of file diff --git a/src/tests/fixtures/input_type_one_of/oneOfFieldIsOptional.ts.expected b/src/tests/fixtures/input_type_one_of/oneOfFieldIsOptional.ts.expected deleted file mode 100644 index d948066c..00000000 --- a/src/tests/fixtures/input_type_one_of/oneOfFieldIsOptional.ts.expected +++ /dev/null @@ -1,39 +0,0 @@ ------------------ -INPUT ------------------ -/** - * @gqlInput - */ -export type Greeting = { firstName: string } | { lastName?: string }; - ------------------ -OUTPUT ------------------ --- SDL -- -input Greeting @oneOf { - firstName: String - lastName: String -} --- TypeScript -- -import { GraphQLSchema, GraphQLInputObjectType, GraphQLString } from "graphql"; -export function getSchema(): GraphQLSchema { - const GreetingType: GraphQLInputObjectType = new GraphQLInputObjectType({ - name: "Greeting", - fields() { - return { - firstName: { - name: "firstName", - type: GraphQLString - }, - lastName: { - name: "lastName", - type: GraphQLString - } - }; - }, - isOneOf: true - }); - return new GraphQLSchema({ - types: [GreetingType] - }); -} diff --git a/src/tests/fixtures/input_type_one_of/oneOfFieldIsOptional.ts.expected.md b/src/tests/fixtures/input_type_one_of/oneOfFieldIsOptional.ts.expected.md new file mode 100644 index 00000000..1fd8a2ea --- /dev/null +++ b/src/tests/fixtures/input_type_one_of/oneOfFieldIsOptional.ts.expected.md @@ -0,0 +1,46 @@ +## input + +```ts title="input_type_one_of/oneOfFieldIsOptional.ts" +/** + * @gqlInput + */ +export type Greeting = { firstName: string } | { lastName?: string }; +``` + +## Output + +### SDL + +```graphql +input Greeting @oneOf { + firstName: String + lastName: String +} +``` + +### TypeScript + +```ts +import { GraphQLSchema, GraphQLInputObjectType, GraphQLString } from "graphql"; +export function getSchema(): GraphQLSchema { + const GreetingType: GraphQLInputObjectType = new GraphQLInputObjectType({ + name: "Greeting", + fields() { + return { + firstName: { + name: "firstName", + type: GraphQLString + }, + lastName: { + name: "lastName", + type: GraphQLString + } + }; + }, + isOneOf: true + }); + return new GraphQLSchema({ + types: [GreetingType] + }); +} +``` \ No newline at end of file diff --git a/src/tests/fixtures/input_type_one_of/oneOfFieldMissingTypeAnnotation.invalid.ts.expected b/src/tests/fixtures/input_type_one_of/oneOfFieldMissingTypeAnnotation.invalid.ts.expected deleted file mode 100644 index fc1061a5..00000000 --- a/src/tests/fixtures/input_type_one_of/oneOfFieldMissingTypeAnnotation.invalid.ts.expected +++ /dev/null @@ -1,15 +0,0 @@ ------------------ -INPUT ------------------ -/** - * @gqlInput - */ -export type Greeting = { firstName: string } | { lastName }; - ------------------ -OUTPUT ------------------ -src/tests/fixtures/input_type_one_of/oneOfFieldMissingTypeAnnotation.invalid.ts:4:50 - error: Expected each property of a @oneOf @gqlInput to have a type annotation. - -4 export type Greeting = { firstName: string } | { lastName }; - ~~~~~~~~ diff --git a/src/tests/fixtures/input_type_one_of/oneOfFieldMissingTypeAnnotation.invalid.ts.expected.md b/src/tests/fixtures/input_type_one_of/oneOfFieldMissingTypeAnnotation.invalid.ts.expected.md new file mode 100644 index 00000000..d0f83ce9 --- /dev/null +++ b/src/tests/fixtures/input_type_one_of/oneOfFieldMissingTypeAnnotation.invalid.ts.expected.md @@ -0,0 +1,19 @@ +## input + +```ts title="input_type_one_of/oneOfFieldMissingTypeAnnotation.invalid.ts" +/** + * @gqlInput + */ +export type Greeting = { firstName: string } | { lastName }; +``` + +## Output + +### Error Report + +```text +src/tests/fixtures/input_type_one_of/oneOfFieldMissingTypeAnnotation.invalid.ts:4:50 - error: Expected each property of a @oneOf @gqlInput to have a type annotation. + +4 export type Greeting = { firstName: string } | { lastName }; + ~~~~~~~~ +``` \ No newline at end of file diff --git a/src/tests/fixtures/input_type_one_of/oneOfFieldTypeList.ts.expected b/src/tests/fixtures/input_type_one_of/oneOfFieldTypeList.ts.expected deleted file mode 100644 index fb92a92c..00000000 --- a/src/tests/fixtures/input_type_one_of/oneOfFieldTypeList.ts.expected +++ /dev/null @@ -1,39 +0,0 @@ ------------------ -INPUT ------------------ -/** - * @gqlInput - */ -export type Greeting = { firstName: string } | { lastName: Array }; - ------------------ -OUTPUT ------------------ --- SDL -- -input Greeting @oneOf { - firstName: String - lastName: [String!] -} --- TypeScript -- -import { GraphQLSchema, GraphQLInputObjectType, GraphQLString, GraphQLList, GraphQLNonNull } from "graphql"; -export function getSchema(): GraphQLSchema { - const GreetingType: GraphQLInputObjectType = new GraphQLInputObjectType({ - name: "Greeting", - fields() { - return { - firstName: { - name: "firstName", - type: GraphQLString - }, - lastName: { - name: "lastName", - type: new GraphQLList(new GraphQLNonNull(GraphQLString)) - } - }; - }, - isOneOf: true - }); - return new GraphQLSchema({ - types: [GreetingType] - }); -} diff --git a/src/tests/fixtures/input_type_one_of/oneOfFieldTypeList.ts.expected.md b/src/tests/fixtures/input_type_one_of/oneOfFieldTypeList.ts.expected.md new file mode 100644 index 00000000..ac025b6f --- /dev/null +++ b/src/tests/fixtures/input_type_one_of/oneOfFieldTypeList.ts.expected.md @@ -0,0 +1,46 @@ +## input + +```ts title="input_type_one_of/oneOfFieldTypeList.ts" +/** + * @gqlInput + */ +export type Greeting = { firstName: string } | { lastName: Array }; +``` + +## Output + +### SDL + +```graphql +input Greeting @oneOf { + firstName: String + lastName: [String!] +} +``` + +### TypeScript + +```ts +import { GraphQLSchema, GraphQLInputObjectType, GraphQLString, GraphQLList, GraphQLNonNull } from "graphql"; +export function getSchema(): GraphQLSchema { + const GreetingType: GraphQLInputObjectType = new GraphQLInputObjectType({ + name: "Greeting", + fields() { + return { + firstName: { + name: "firstName", + type: GraphQLString + }, + lastName: { + name: "lastName", + type: new GraphQLList(new GraphQLNonNull(GraphQLString)) + } + }; + }, + isOneOf: true + }); + return new GraphQLSchema({ + types: [GreetingType] + }); +} +``` \ No newline at end of file diff --git a/src/tests/fixtures/input_type_one_of/oneOfFieldTypeListOfNullable.ts.expected b/src/tests/fixtures/input_type_one_of/oneOfFieldTypeListOfNullable.ts.expected deleted file mode 100644 index cac992c1..00000000 --- a/src/tests/fixtures/input_type_one_of/oneOfFieldTypeListOfNullable.ts.expected +++ /dev/null @@ -1,41 +0,0 @@ ------------------ -INPUT ------------------ -/** - * @gqlInput - */ -export type Greeting = - | { firstName: string } - | { lastName: Array }; - ------------------ -OUTPUT ------------------ --- SDL -- -input Greeting @oneOf { - firstName: String - lastName: [String] -} --- TypeScript -- -import { GraphQLSchema, GraphQLInputObjectType, GraphQLString, GraphQLList } from "graphql"; -export function getSchema(): GraphQLSchema { - const GreetingType: GraphQLInputObjectType = new GraphQLInputObjectType({ - name: "Greeting", - fields() { - return { - firstName: { - name: "firstName", - type: GraphQLString - }, - lastName: { - name: "lastName", - type: new GraphQLList(GraphQLString) - } - }; - }, - isOneOf: true - }); - return new GraphQLSchema({ - types: [GreetingType] - }); -} diff --git a/src/tests/fixtures/input_type_one_of/oneOfFieldTypeListOfNullable.ts.expected.md b/src/tests/fixtures/input_type_one_of/oneOfFieldTypeListOfNullable.ts.expected.md new file mode 100644 index 00000000..534ef451 --- /dev/null +++ b/src/tests/fixtures/input_type_one_of/oneOfFieldTypeListOfNullable.ts.expected.md @@ -0,0 +1,48 @@ +## input + +```ts title="input_type_one_of/oneOfFieldTypeListOfNullable.ts" +/** + * @gqlInput + */ +export type Greeting = + | { firstName: string } + | { lastName: Array }; +``` + +## Output + +### SDL + +```graphql +input Greeting @oneOf { + firstName: String + lastName: [String] +} +``` + +### TypeScript + +```ts +import { GraphQLSchema, GraphQLInputObjectType, GraphQLString, GraphQLList } from "graphql"; +export function getSchema(): GraphQLSchema { + const GreetingType: GraphQLInputObjectType = new GraphQLInputObjectType({ + name: "Greeting", + fields() { + return { + firstName: { + name: "firstName", + type: GraphQLString + }, + lastName: { + name: "lastName", + type: new GraphQLList(GraphQLString) + } + }; + }, + isOneOf: true + }); + return new GraphQLSchema({ + types: [GreetingType] + }); +} +``` \ No newline at end of file diff --git a/src/tests/fixtures/input_type_one_of/oneOfFieldTypeNotGraphQL.invalid.ts.expected b/src/tests/fixtures/input_type_one_of/oneOfFieldTypeNotGraphQL.invalid.ts.expected deleted file mode 100644 index d098588a..00000000 --- a/src/tests/fixtures/input_type_one_of/oneOfFieldTypeNotGraphQL.invalid.ts.expected +++ /dev/null @@ -1,15 +0,0 @@ ------------------ -INPUT ------------------ -/** - * @gqlInput - */ -export type Greeting = { firstName: string } | { lastName: Set }; - ------------------ -OUTPUT ------------------ -src/tests/fixtures/input_type_one_of/oneOfFieldTypeNotGraphQL.invalid.ts:4:60 - error: Unable to resolve type reference. In order to generate a GraphQL schema, Grats needs to determine which GraphQL type is being referenced. This requires being able to resolve type references to their `@gql` annotated declaration. However this reference could not be resolved. Is it possible that this type is not defined in this file? - -4 export type Greeting = { firstName: string } | { lastName: Set }; - ~~~ diff --git a/src/tests/fixtures/input_type_one_of/oneOfFieldTypeNotGraphQL.invalid.ts.expected.md b/src/tests/fixtures/input_type_one_of/oneOfFieldTypeNotGraphQL.invalid.ts.expected.md new file mode 100644 index 00000000..0e8b5ebc --- /dev/null +++ b/src/tests/fixtures/input_type_one_of/oneOfFieldTypeNotGraphQL.invalid.ts.expected.md @@ -0,0 +1,19 @@ +## input + +```ts title="input_type_one_of/oneOfFieldTypeNotGraphQL.invalid.ts" +/** + * @gqlInput + */ +export type Greeting = { firstName: string } | { lastName: Set }; +``` + +## Output + +### Error Report + +```text +src/tests/fixtures/input_type_one_of/oneOfFieldTypeNotGraphQL.invalid.ts:4:60 - error: Unable to resolve type reference. In order to generate a GraphQL schema, Grats needs to determine which GraphQL type is being referenced. This requires being able to resolve type references to their `@gql` annotated declaration. However this reference could not be resolved. Is it possible that this type is not defined in this file? + +4 export type Greeting = { firstName: string } | { lastName: Set }; + ~~~ +``` \ No newline at end of file diff --git a/src/tests/fixtures/input_type_one_of/oneOfMemberHasMultipleFields.invalid.ts.expected b/src/tests/fixtures/input_type_one_of/oneOfMemberHasMultipleFields.invalid.ts.expected deleted file mode 100644 index ad17a5f7..00000000 --- a/src/tests/fixtures/input_type_one_of/oneOfMemberHasMultipleFields.invalid.ts.expected +++ /dev/null @@ -1,17 +0,0 @@ ------------------ -INPUT ------------------ -/** - * @gqlInput - */ -export type Greeting = - | { firstName: string } - | { lastName: string; nickName: string }; - ------------------ -OUTPUT ------------------ -src/tests/fixtures/input_type_one_of/oneOfMemberHasMultipleFields.invalid.ts:6:5 - error: Expected each member of a @oneOf @gqlInput to be a TypeScript object literal with exactly one property. - -6 | { lastName: string; nickName: string }; - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/src/tests/fixtures/input_type_one_of/oneOfMemberHasMultipleFields.invalid.ts.expected.md b/src/tests/fixtures/input_type_one_of/oneOfMemberHasMultipleFields.invalid.ts.expected.md new file mode 100644 index 00000000..ebb8336f --- /dev/null +++ b/src/tests/fixtures/input_type_one_of/oneOfMemberHasMultipleFields.invalid.ts.expected.md @@ -0,0 +1,21 @@ +## input + +```ts title="input_type_one_of/oneOfMemberHasMultipleFields.invalid.ts" +/** + * @gqlInput + */ +export type Greeting = + | { firstName: string } + | { lastName: string; nickName: string }; +``` + +## Output + +### Error Report + +```text +src/tests/fixtures/input_type_one_of/oneOfMemberHasMultipleFields.invalid.ts:6:5 - error: Expected each member of a @oneOf @gqlInput to be a TypeScript object literal with exactly one property. + +6 | { lastName: string; nickName: string }; + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` \ No newline at end of file diff --git a/src/tests/fixtures/input_type_one_of/oneOfMemberHasNoField.invalid.ts.expected b/src/tests/fixtures/input_type_one_of/oneOfMemberHasNoField.invalid.ts.expected deleted file mode 100644 index e4ba6456..00000000 --- a/src/tests/fixtures/input_type_one_of/oneOfMemberHasNoField.invalid.ts.expected +++ /dev/null @@ -1,15 +0,0 @@ ------------------ -INPUT ------------------ -/** - * @gqlInput - */ -type Greeting = { firstName: string } | {}; - ------------------ -OUTPUT ------------------ -src/tests/fixtures/input_type_one_of/oneOfMemberHasNoField.invalid.ts:4:41 - error: Expected each member of a @oneOf @gqlInput to be a TypeScript object literal with exactly one property. - -4 type Greeting = { firstName: string } | {}; - ~~ diff --git a/src/tests/fixtures/input_type_one_of/oneOfMemberHasNoField.invalid.ts.expected.md b/src/tests/fixtures/input_type_one_of/oneOfMemberHasNoField.invalid.ts.expected.md new file mode 100644 index 00000000..3c970002 --- /dev/null +++ b/src/tests/fixtures/input_type_one_of/oneOfMemberHasNoField.invalid.ts.expected.md @@ -0,0 +1,19 @@ +## input + +```ts title="input_type_one_of/oneOfMemberHasNoField.invalid.ts" +/** + * @gqlInput + */ +type Greeting = { firstName: string } | {}; +``` + +## Output + +### Error Report + +```text +src/tests/fixtures/input_type_one_of/oneOfMemberHasNoField.invalid.ts:4:41 - error: Expected each member of a @oneOf @gqlInput to be a TypeScript object literal with exactly one property. + +4 type Greeting = { firstName: string } | {}; + ~~ +``` \ No newline at end of file diff --git a/src/tests/fixtures/input_type_one_of/oneOfUnionMemberNotLiteral.invalid.ts.expected b/src/tests/fixtures/input_type_one_of/oneOfUnionMemberNotLiteral.invalid.ts.expected deleted file mode 100644 index b4302d00..00000000 --- a/src/tests/fixtures/input_type_one_of/oneOfUnionMemberNotLiteral.invalid.ts.expected +++ /dev/null @@ -1,15 +0,0 @@ ------------------ -INPUT ------------------ -/** - * @gqlInput - */ -export type Greeting = string | { name: string }; - ------------------ -OUTPUT ------------------ -src/tests/fixtures/input_type_one_of/oneOfUnionMemberNotLiteral.invalid.ts:4:24 - error: Expected each member of a @oneOf @gqlInput to be a TypeScript object literal with exactly one property. - -4 export type Greeting = string | { name: string }; - ~~~~~~ diff --git a/src/tests/fixtures/input_type_one_of/oneOfUnionMemberNotLiteral.invalid.ts.expected.md b/src/tests/fixtures/input_type_one_of/oneOfUnionMemberNotLiteral.invalid.ts.expected.md new file mode 100644 index 00000000..9313bd36 --- /dev/null +++ b/src/tests/fixtures/input_type_one_of/oneOfUnionMemberNotLiteral.invalid.ts.expected.md @@ -0,0 +1,19 @@ +## input + +```ts title="input_type_one_of/oneOfUnionMemberNotLiteral.invalid.ts" +/** + * @gqlInput + */ +export type Greeting = string | { name: string }; +``` + +## Output + +### Error Report + +```text +src/tests/fixtures/input_type_one_of/oneOfUnionMemberNotLiteral.invalid.ts:4:24 - error: Expected each member of a @oneOf @gqlInput to be a TypeScript object literal with exactly one property. + +4 export type Greeting = string | { name: string }; + ~~~~~~ +``` \ No newline at end of file diff --git a/src/tests/fixtures/input_type_one_of/oneOfWithFieldDescription.ts.expected b/src/tests/fixtures/input_type_one_of/oneOfWithFieldDescription.ts.expected deleted file mode 100644 index 75225ffa..00000000 --- a/src/tests/fixtures/input_type_one_of/oneOfWithFieldDescription.ts.expected +++ /dev/null @@ -1,45 +0,0 @@ ------------------ -INPUT ------------------ -// Known issue, descriptions are not parsed? - -/** - * @gqlInput - */ -export type Greeting = - /** First Name */ - | { firstName: string } - /** Last Name */ - | { lastName: string }; - ------------------ -OUTPUT ------------------ --- SDL -- -input Greeting @oneOf { - firstName: String - lastName: String -} --- TypeScript -- -import { GraphQLSchema, GraphQLInputObjectType, GraphQLString } from "graphql"; -export function getSchema(): GraphQLSchema { - const GreetingType: GraphQLInputObjectType = new GraphQLInputObjectType({ - name: "Greeting", - fields() { - return { - firstName: { - name: "firstName", - type: GraphQLString - }, - lastName: { - name: "lastName", - type: GraphQLString - } - }; - }, - isOneOf: true - }); - return new GraphQLSchema({ - types: [GreetingType] - }); -} diff --git a/src/tests/fixtures/input_type_one_of/oneOfWithFieldDescription.ts.expected.md b/src/tests/fixtures/input_type_one_of/oneOfWithFieldDescription.ts.expected.md new file mode 100644 index 00000000..a24495d1 --- /dev/null +++ b/src/tests/fixtures/input_type_one_of/oneOfWithFieldDescription.ts.expected.md @@ -0,0 +1,52 @@ +## input + +```ts title="input_type_one_of/oneOfWithFieldDescription.ts" +// Known issue, descriptions are not parsed? + +/** + * @gqlInput + */ +export type Greeting = + /** First Name */ + | { firstName: string } + /** Last Name */ + | { lastName: string }; +``` + +## Output + +### SDL + +```graphql +input Greeting @oneOf { + firstName: String + lastName: String +} +``` + +### TypeScript + +```ts +import { GraphQLSchema, GraphQLInputObjectType, GraphQLString } from "graphql"; +export function getSchema(): GraphQLSchema { + const GreetingType: GraphQLInputObjectType = new GraphQLInputObjectType({ + name: "Greeting", + fields() { + return { + firstName: { + name: "firstName", + type: GraphQLString + }, + lastName: { + name: "lastName", + type: GraphQLString + } + }; + }, + isOneOf: true + }); + return new GraphQLSchema({ + types: [GreetingType] + }); +} +``` \ No newline at end of file diff --git a/src/tests/fixtures/input_type_one_of/oneOfWithFieldDescriptionInsideObj.ts.expected b/src/tests/fixtures/input_type_one_of/oneOfWithFieldDescriptionInsideObj.ts.expected deleted file mode 100644 index 2ff229f8..00000000 --- a/src/tests/fixtures/input_type_one_of/oneOfWithFieldDescriptionInsideObj.ts.expected +++ /dev/null @@ -1,53 +0,0 @@ ------------------ -INPUT ------------------ -// Known issue, descriptions are not parsed? - -/** - * @gqlInput - */ -export type Greeting = - | { - /** First Name */ - firstName: string; - } - | { - /** Last Name */ - lastName: string; - }; - ------------------ -OUTPUT ------------------ --- SDL -- -input Greeting @oneOf { - """First Name""" - firstName: String - """Last Name""" - lastName: String -} --- TypeScript -- -import { GraphQLSchema, GraphQLInputObjectType, GraphQLString } from "graphql"; -export function getSchema(): GraphQLSchema { - const GreetingType: GraphQLInputObjectType = new GraphQLInputObjectType({ - name: "Greeting", - fields() { - return { - firstName: { - description: "First Name", - name: "firstName", - type: GraphQLString - }, - lastName: { - description: "Last Name", - name: "lastName", - type: GraphQLString - } - }; - }, - isOneOf: true - }); - return new GraphQLSchema({ - types: [GreetingType] - }); -} diff --git a/src/tests/fixtures/input_type_one_of/oneOfWithFieldDescriptionInsideObj.ts.expected.md b/src/tests/fixtures/input_type_one_of/oneOfWithFieldDescriptionInsideObj.ts.expected.md new file mode 100644 index 00000000..5ae2a68f --- /dev/null +++ b/src/tests/fixtures/input_type_one_of/oneOfWithFieldDescriptionInsideObj.ts.expected.md @@ -0,0 +1,60 @@ +## input + +```ts title="input_type_one_of/oneOfWithFieldDescriptionInsideObj.ts" +// Known issue, descriptions are not parsed? + +/** + * @gqlInput + */ +export type Greeting = + | { + /** First Name */ + firstName: string; + } + | { + /** Last Name */ + lastName: string; + }; +``` + +## Output + +### SDL + +```graphql +input Greeting @oneOf { + """First Name""" + firstName: String + """Last Name""" + lastName: String +} +``` + +### TypeScript + +```ts +import { GraphQLSchema, GraphQLInputObjectType, GraphQLString } from "graphql"; +export function getSchema(): GraphQLSchema { + const GreetingType: GraphQLInputObjectType = new GraphQLInputObjectType({ + name: "Greeting", + fields() { + return { + firstName: { + description: "First Name", + name: "firstName", + type: GraphQLString + }, + lastName: { + description: "Last Name", + name: "lastName", + type: GraphQLString + } + }; + }, + isOneOf: true + }); + return new GraphQLSchema({ + types: [GreetingType] + }); +} +``` \ No newline at end of file diff --git a/src/tests/fixtures/input_type_one_of/oneOfWithTypeDescription.ts.expected b/src/tests/fixtures/input_type_one_of/oneOfWithTypeDescription.ts.expected deleted file mode 100644 index b2f5f267..00000000 --- a/src/tests/fixtures/input_type_one_of/oneOfWithTypeDescription.ts.expected +++ /dev/null @@ -1,43 +0,0 @@ ------------------ -INPUT ------------------ -/** - * A popular way to greet someone. - * - * @gqlInput - */ -export type Greeting = { firstName: string } | { lastName: string }; - ------------------ -OUTPUT ------------------ --- SDL -- -"""A popular way to greet someone.""" -input Greeting @oneOf { - firstName: String - lastName: String -} --- TypeScript -- -import { GraphQLSchema, GraphQLInputObjectType, GraphQLString } from "graphql"; -export function getSchema(): GraphQLSchema { - const GreetingType: GraphQLInputObjectType = new GraphQLInputObjectType({ - description: "A popular way to greet someone.", - name: "Greeting", - fields() { - return { - firstName: { - name: "firstName", - type: GraphQLString - }, - lastName: { - name: "lastName", - type: GraphQLString - } - }; - }, - isOneOf: true - }); - return new GraphQLSchema({ - types: [GreetingType] - }); -} diff --git a/src/tests/fixtures/input_type_one_of/oneOfWithTypeDescription.ts.expected.md b/src/tests/fixtures/input_type_one_of/oneOfWithTypeDescription.ts.expected.md new file mode 100644 index 00000000..afd5a240 --- /dev/null +++ b/src/tests/fixtures/input_type_one_of/oneOfWithTypeDescription.ts.expected.md @@ -0,0 +1,50 @@ +## input + +```ts title="input_type_one_of/oneOfWithTypeDescription.ts" +/** + * A popular way to greet someone. + * + * @gqlInput + */ +export type Greeting = { firstName: string } | { lastName: string }; +``` + +## Output + +### SDL + +```graphql +"""A popular way to greet someone.""" +input Greeting @oneOf { + firstName: String + lastName: String +} +``` + +### TypeScript + +```ts +import { GraphQLSchema, GraphQLInputObjectType, GraphQLString } from "graphql"; +export function getSchema(): GraphQLSchema { + const GreetingType: GraphQLInputObjectType = new GraphQLInputObjectType({ + description: "A popular way to greet someone.", + name: "Greeting", + fields() { + return { + firstName: { + name: "firstName", + type: GraphQLString + }, + lastName: { + name: "lastName", + type: GraphQLString + } + }; + }, + isOneOf: true + }); + return new GraphQLSchema({ + types: [GreetingType] + }); +} +``` \ No newline at end of file diff --git a/src/tests/fixtures/input_type_one_of/simpleOneOf.ts.expected b/src/tests/fixtures/input_type_one_of/simpleOneOf.ts.expected deleted file mode 100644 index 9330fcb9..00000000 --- a/src/tests/fixtures/input_type_one_of/simpleOneOf.ts.expected +++ /dev/null @@ -1,39 +0,0 @@ ------------------ -INPUT ------------------ -/** - * @gqlInput - */ -export type Greeting = { firstName: string } | { lastName: string }; - ------------------ -OUTPUT ------------------ --- SDL -- -input Greeting @oneOf { - firstName: String - lastName: String -} --- TypeScript -- -import { GraphQLSchema, GraphQLInputObjectType, GraphQLString } from "graphql"; -export function getSchema(): GraphQLSchema { - const GreetingType: GraphQLInputObjectType = new GraphQLInputObjectType({ - name: "Greeting", - fields() { - return { - firstName: { - name: "firstName", - type: GraphQLString - }, - lastName: { - name: "lastName", - type: GraphQLString - } - }; - }, - isOneOf: true - }); - return new GraphQLSchema({ - types: [GreetingType] - }); -} diff --git a/src/tests/fixtures/input_type_one_of/simpleOneOf.ts.expected.md b/src/tests/fixtures/input_type_one_of/simpleOneOf.ts.expected.md new file mode 100644 index 00000000..53f67b71 --- /dev/null +++ b/src/tests/fixtures/input_type_one_of/simpleOneOf.ts.expected.md @@ -0,0 +1,46 @@ +## input + +```ts title="input_type_one_of/simpleOneOf.ts" +/** + * @gqlInput + */ +export type Greeting = { firstName: string } | { lastName: string }; +``` + +## Output + +### SDL + +```graphql +input Greeting @oneOf { + firstName: String + lastName: String +} +``` + +### TypeScript + +```ts +import { GraphQLSchema, GraphQLInputObjectType, GraphQLString } from "graphql"; +export function getSchema(): GraphQLSchema { + const GreetingType: GraphQLInputObjectType = new GraphQLInputObjectType({ + name: "Greeting", + fields() { + return { + firstName: { + name: "firstName", + type: GraphQLString + }, + lastName: { + name: "lastName", + type: GraphQLString + } + }; + }, + isOneOf: true + }); + return new GraphQLSchema({ + types: [GreetingType] + }); +} +``` \ No newline at end of file diff --git a/src/tests/fixtures/input_type_one_of/simpleOneOfDeprecatedTag.invalid.ts.expected b/src/tests/fixtures/input_type_one_of/simpleOneOfDeprecatedTag.invalid.ts.expected deleted file mode 100644 index 89a58111..00000000 --- a/src/tests/fixtures/input_type_one_of/simpleOneOfDeprecatedTag.invalid.ts.expected +++ /dev/null @@ -1,40 +0,0 @@ ------------------ -INPUT ------------------ -/** - * @gqlInput - * @oneOf - */ -export type Greeting = { firstName: string } | { lastName: string }; - ------------------ -OUTPUT ------------------ --- Error Report -- -src/tests/fixtures/input_type_one_of/simpleOneOfDeprecatedTag.invalid.ts:3:4 - error: The `@oneOf` tag has been deprecated. Grats will now automatically add the `@oneOf` directive if you define your input type as a TypeScript union. You can remove the `@oneOf` tag. - -3 * @oneOf - ~~~~~~ -4 */ - ~ - - --- Code Action: "Remove @oneOf tag" (remove-oneOf-tag) -- -- Original -+ Fixed - -@@ -2,4 +2,3 @@ - * @gqlInput -- * @oneOf -- */ -+ * */ - export type Greeting = { firstName: string } | { lastName: string }; - --- Applied Fixes -- - * Applied fix "Remove @oneOf tag" in grats/src/tests/fixtures/input_type_one_of/simpleOneOfDeprecatedTag.invalid.ts - --- Fixed Text -- -/** - * @gqlInput - * */ -export type Greeting = { firstName: string } | { lastName: string }; diff --git a/src/tests/fixtures/input_type_one_of/simpleOneOfDeprecatedTag.invalid.ts.expected.md b/src/tests/fixtures/input_type_one_of/simpleOneOfDeprecatedTag.invalid.ts.expected.md new file mode 100644 index 00000000..c98df917 --- /dev/null +++ b/src/tests/fixtures/input_type_one_of/simpleOneOfDeprecatedTag.invalid.ts.expected.md @@ -0,0 +1,51 @@ +## input + +```ts title="input_type_one_of/simpleOneOfDeprecatedTag.invalid.ts" +/** + * @gqlInput + * @oneOf + */ +export type Greeting = { firstName: string } | { lastName: string }; +``` + +## Output + +### Error Report + +```text +src/tests/fixtures/input_type_one_of/simpleOneOfDeprecatedTag.invalid.ts:3:4 - error: The `@oneOf` tag has been deprecated. Grats will now automatically add the `@oneOf` directive if you define your input type as a TypeScript union. You can remove the `@oneOf` tag. + +3 * @oneOf + ~~~~~~ +4 */ + ~ +``` + +#### Code Action: "Remove @oneOf tag" (remove-oneOf-tag) + +```diff +- Original ++ Fixed + +@@ -2,4 +2,3 @@ + * @gqlInput +- * @oneOf +- */ ++ * */ + export type Greeting = { firstName: string } | { lastName: string }; +``` + +#### Applied Fixes + +```text + * Applied fix "Remove @oneOf tag" in grats/src/tests/fixtures/input_type_one_of/simpleOneOfDeprecatedTag.invalid.ts +``` + +#### Fixed Text + +```typescript +/** + * @gqlInput + * */ +export type Greeting = { firstName: string } | { lastName: string }; +``` \ No newline at end of file diff --git a/src/tests/fixtures/input_types/ContextReferencedInInputType.invalid.ts.expected b/src/tests/fixtures/input_types/ContextReferencedInInputType.invalid.ts.expected deleted file mode 100644 index d8a77a93..00000000 --- a/src/tests/fixtures/input_types/ContextReferencedInInputType.invalid.ts.expected +++ /dev/null @@ -1,25 +0,0 @@ ------------------ -INPUT ------------------ -/** @gqlContext */ -type SomeType = { - hello: string; -}; - -/** @gqlInput */ -type MyInputType = { - someField: SomeType; -}; - ------------------ -OUTPUT ------------------ -src/tests/fixtures/input_types/ContextReferencedInInputType.invalid.ts:8:14 - error: Cannot use `gqlContext` as a type in GraphQL type position. - -8 someField: SomeType; - ~~~~~~~~ - - src/tests/fixtures/input_types/ContextReferencedInInputType.invalid.ts:1:5 - 1 /** @gqlContext */ - ~~~~~~~~~~~~ - Defined here diff --git a/src/tests/fixtures/input_types/ContextReferencedInInputType.invalid.ts.expected.md b/src/tests/fixtures/input_types/ContextReferencedInInputType.invalid.ts.expected.md new file mode 100644 index 00000000..32d82ca9 --- /dev/null +++ b/src/tests/fixtures/input_types/ContextReferencedInInputType.invalid.ts.expected.md @@ -0,0 +1,29 @@ +## input + +```ts title="input_types/ContextReferencedInInputType.invalid.ts" +/** @gqlContext */ +type SomeType = { + hello: string; +}; + +/** @gqlInput */ +type MyInputType = { + someField: SomeType; +}; +``` + +## Output + +### Error Report + +```text +src/tests/fixtures/input_types/ContextReferencedInInputType.invalid.ts:8:14 - error: Cannot use `gqlContext` as a type in GraphQL type position. + +8 someField: SomeType; + ~~~~~~~~ + + src/tests/fixtures/input_types/ContextReferencedInInputType.invalid.ts:1:5 + 1 /** @gqlContext */ + ~~~~~~~~~~~~ + Defined here +``` \ No newline at end of file diff --git a/src/tests/fixtures/input_types/DeprecatedInputType.invalid.ts.expected b/src/tests/fixtures/input_types/DeprecatedInputType.invalid.ts.expected deleted file mode 100644 index 598c4bfb..00000000 --- a/src/tests/fixtures/input_types/DeprecatedInputType.invalid.ts.expected +++ /dev/null @@ -1,25 +0,0 @@ ------------------ -INPUT ------------------ -/** @gqlType */ -export class SomeType { - /** @gqlField */ - hello: string; -} - -/** - * Check out this great input! - * @gqlInput - * @deprecated This old thing? - */ -type MyInputType = { - someField: string; -}; - ------------------ -OUTPUT ------------------ -src/tests/fixtures/input_types/DeprecatedInputType.invalid.ts:10:5 - error: Directive "@deprecated" may not be used on INPUT_OBJECT. - -10 * @deprecated This old thing? - ~~~~~~~~~~ diff --git a/src/tests/fixtures/input_types/DeprecatedInputType.invalid.ts.expected.md b/src/tests/fixtures/input_types/DeprecatedInputType.invalid.ts.expected.md new file mode 100644 index 00000000..a4974e31 --- /dev/null +++ b/src/tests/fixtures/input_types/DeprecatedInputType.invalid.ts.expected.md @@ -0,0 +1,29 @@ +## input + +```ts title="input_types/DeprecatedInputType.invalid.ts" +/** @gqlType */ +export class SomeType { + /** @gqlField */ + hello: string; +} + +/** + * Check out this great input! + * @gqlInput + * @deprecated This old thing? + */ +type MyInputType = { + someField: string; +}; +``` + +## Output + +### Error Report + +```text +src/tests/fixtures/input_types/DeprecatedInputType.invalid.ts:10:5 - error: Directive "@deprecated" may not be used on INPUT_OBJECT. + +10 * @deprecated This old thing? + ~~~~~~~~~~ +``` \ No newline at end of file diff --git a/src/tests/fixtures/input_types/InputType.ts.expected b/src/tests/fixtures/input_types/InputType.ts.expected deleted file mode 100644 index 01932792..00000000 --- a/src/tests/fixtures/input_types/InputType.ts.expected +++ /dev/null @@ -1,54 +0,0 @@ ------------------ -INPUT ------------------ -/** @gqlType */ -class SomeType { - /** @gqlField */ - hello: string; -} - -/** @gqlInput */ -type MyInputType = { - someField: string; -}; - ------------------ -OUTPUT ------------------ --- SDL -- -input MyInputType { - someField: String! -} - -type SomeType { - hello: String -} --- TypeScript -- -import { GraphQLSchema, GraphQLInputObjectType, GraphQLNonNull, GraphQLString, GraphQLObjectType } from "graphql"; -export function getSchema(): GraphQLSchema { - const MyInputTypeType: GraphQLInputObjectType = new GraphQLInputObjectType({ - name: "MyInputType", - fields() { - return { - someField: { - name: "someField", - type: new GraphQLNonNull(GraphQLString) - } - }; - } - }); - const SomeTypeType: GraphQLObjectType = new GraphQLObjectType({ - name: "SomeType", - fields() { - return { - hello: { - name: "hello", - type: GraphQLString - } - }; - } - }); - return new GraphQLSchema({ - types: [MyInputTypeType, SomeTypeType] - }); -} diff --git a/src/tests/fixtures/input_types/InputType.ts.expected.md b/src/tests/fixtures/input_types/InputType.ts.expected.md new file mode 100644 index 00000000..0ce70f57 --- /dev/null +++ b/src/tests/fixtures/input_types/InputType.ts.expected.md @@ -0,0 +1,61 @@ +## input + +```ts title="input_types/InputType.ts" +/** @gqlType */ +class SomeType { + /** @gqlField */ + hello: string; +} + +/** @gqlInput */ +type MyInputType = { + someField: string; +}; +``` + +## Output + +### SDL + +```graphql +input MyInputType { + someField: String! +} + +type SomeType { + hello: String +} +``` + +### TypeScript + +```ts +import { GraphQLSchema, GraphQLInputObjectType, GraphQLNonNull, GraphQLString, GraphQLObjectType } from "graphql"; +export function getSchema(): GraphQLSchema { + const MyInputTypeType: GraphQLInputObjectType = new GraphQLInputObjectType({ + name: "MyInputType", + fields() { + return { + someField: { + name: "someField", + type: new GraphQLNonNull(GraphQLString) + } + }; + } + }); + const SomeTypeType: GraphQLObjectType = new GraphQLObjectType({ + name: "SomeType", + fields() { + return { + hello: { + name: "hello", + type: GraphQLString + } + }; + } + }); + return new GraphQLSchema({ + types: [MyInputTypeType, SomeTypeType] + }); +} +``` \ No newline at end of file diff --git a/src/tests/fixtures/input_types/InputTypeInterface.ts.expected b/src/tests/fixtures/input_types/InputTypeInterface.ts.expected deleted file mode 100644 index 68ae4fb7..00000000 --- a/src/tests/fixtures/input_types/InputTypeInterface.ts.expected +++ /dev/null @@ -1,61 +0,0 @@ ------------------ -INPUT ------------------ -/** @gqlInput */ -interface MyInputType { - someField: string; -} - -/** @gqlType */ -class User { - /** @gqlField */ - myField(args: { input: MyInputType }): string { - return args.input.someField; - } -} - ------------------ -OUTPUT ------------------ --- SDL -- -input MyInputType { - someField: String! -} - -type User { - myField(input: MyInputType!): String -} --- TypeScript -- -import { GraphQLSchema, GraphQLInputObjectType, GraphQLNonNull, GraphQLString, GraphQLObjectType } from "graphql"; -export function getSchema(): GraphQLSchema { - const MyInputTypeType: GraphQLInputObjectType = new GraphQLInputObjectType({ - name: "MyInputType", - fields() { - return { - someField: { - name: "someField", - type: new GraphQLNonNull(GraphQLString) - } - }; - } - }); - const UserType: GraphQLObjectType = new GraphQLObjectType({ - name: "User", - fields() { - return { - myField: { - name: "myField", - type: GraphQLString, - args: { - input: { - type: new GraphQLNonNull(MyInputTypeType) - } - } - } - }; - } - }); - return new GraphQLSchema({ - types: [MyInputTypeType, UserType] - }); -} diff --git a/src/tests/fixtures/input_types/InputTypeInterface.ts.expected.md b/src/tests/fixtures/input_types/InputTypeInterface.ts.expected.md new file mode 100644 index 00000000..da911ec6 --- /dev/null +++ b/src/tests/fixtures/input_types/InputTypeInterface.ts.expected.md @@ -0,0 +1,68 @@ +## input + +```ts title="input_types/InputTypeInterface.ts" +/** @gqlInput */ +interface MyInputType { + someField: string; +} + +/** @gqlType */ +class User { + /** @gqlField */ + myField(args: { input: MyInputType }): string { + return args.input.someField; + } +} +``` + +## Output + +### SDL + +```graphql +input MyInputType { + someField: String! +} + +type User { + myField(input: MyInputType!): String +} +``` + +### TypeScript + +```ts +import { GraphQLSchema, GraphQLInputObjectType, GraphQLNonNull, GraphQLString, GraphQLObjectType } from "graphql"; +export function getSchema(): GraphQLSchema { + const MyInputTypeType: GraphQLInputObjectType = new GraphQLInputObjectType({ + name: "MyInputType", + fields() { + return { + someField: { + name: "someField", + type: new GraphQLNonNull(GraphQLString) + } + }; + } + }); + const UserType: GraphQLObjectType = new GraphQLObjectType({ + name: "User", + fields() { + return { + myField: { + name: "myField", + type: GraphQLString, + args: { + input: { + type: new GraphQLNonNull(MyInputTypeType) + } + } + } + }; + } + }); + return new GraphQLSchema({ + types: [MyInputTypeType, UserType] + }); +} +``` \ No newline at end of file diff --git a/src/tests/fixtures/input_types/InputTypeInterfaceFunction.invalid.ts.expected b/src/tests/fixtures/input_types/InputTypeInterfaceFunction.invalid.ts.expected deleted file mode 100644 index b04feea7..00000000 --- a/src/tests/fixtures/input_types/InputTypeInterfaceFunction.invalid.ts.expected +++ /dev/null @@ -1,19 +0,0 @@ ------------------ -INPUT ------------------ -/** @gqlInput */ -interface MyInputType { - // TypeScript lets you define functions using interfaces, - // but that makes no sense as a GraphQL input type. - (arg: string): string; -} - ------------------ -OUTPUT ------------------ -src/tests/fixtures/input_types/InputTypeInterfaceFunction.invalid.ts:5:3 - error: `@gqlInput` types only support property signature members. e.g. `type MyInput = { foo: string }` - -If you think Grats should be able to infer this input field, please report an issue at https://github.com/captbaritone/grats/issues. - -5 (arg: string): string; - ~~~~~~~~~~~~~~~~~~~~~~ diff --git a/src/tests/fixtures/input_types/InputTypeInterfaceFunction.invalid.ts.expected.md b/src/tests/fixtures/input_types/InputTypeInterfaceFunction.invalid.ts.expected.md new file mode 100644 index 00000000..e5a3c41e --- /dev/null +++ b/src/tests/fixtures/input_types/InputTypeInterfaceFunction.invalid.ts.expected.md @@ -0,0 +1,23 @@ +## input + +```ts title="input_types/InputTypeInterfaceFunction.invalid.ts" +/** @gqlInput */ +interface MyInputType { + // TypeScript lets you define functions using interfaces, + // but that makes no sense as a GraphQL input type. + (arg: string): string; +} +``` + +## Output + +### Error Report + +```text +src/tests/fixtures/input_types/InputTypeInterfaceFunction.invalid.ts:5:3 - error: `@gqlInput` types only support property signature members. e.g. `type MyInput = { foo: string }` + +If you think Grats should be able to infer this input field, please report an issue at https://github.com/captbaritone/grats/issues. + +5 (arg: string): string; + ~~~~~~~~~~~~~~~~~~~~~~ +``` \ No newline at end of file diff --git a/src/tests/fixtures/input_types/InputTypeInterfaceMethod.invalid.ts.expected b/src/tests/fixtures/input_types/InputTypeInterfaceMethod.invalid.ts.expected deleted file mode 100644 index bd76fc98..00000000 --- a/src/tests/fixtures/input_types/InputTypeInterfaceMethod.invalid.ts.expected +++ /dev/null @@ -1,17 +0,0 @@ ------------------ -INPUT ------------------ -/** @gqlInput */ -interface MyInputType { - someMethod(): string; -} - ------------------ -OUTPUT ------------------ -src/tests/fixtures/input_types/InputTypeInterfaceMethod.invalid.ts:3:3 - error: `@gqlInput` types only support property signature members. e.g. `type MyInput = { foo: string }` - -If you think Grats should be able to infer this input field, please report an issue at https://github.com/captbaritone/grats/issues. - -3 someMethod(): string; - ~~~~~~~~~~~~~~~~~~~~~ diff --git a/src/tests/fixtures/input_types/InputTypeInterfaceMethod.invalid.ts.expected.md b/src/tests/fixtures/input_types/InputTypeInterfaceMethod.invalid.ts.expected.md new file mode 100644 index 00000000..7e5bd030 --- /dev/null +++ b/src/tests/fixtures/input_types/InputTypeInterfaceMethod.invalid.ts.expected.md @@ -0,0 +1,21 @@ +## input + +```ts title="input_types/InputTypeInterfaceMethod.invalid.ts" +/** @gqlInput */ +interface MyInputType { + someMethod(): string; +} +``` + +## Output + +### Error Report + +```text +src/tests/fixtures/input_types/InputTypeInterfaceMethod.invalid.ts:3:3 - error: `@gqlInput` types only support property signature members. e.g. `type MyInput = { foo: string }` + +If you think Grats should be able to infer this input field, please report an issue at https://github.com/captbaritone/grats/issues. + +3 someMethod(): string; + ~~~~~~~~~~~~~~~~~~~~~ +``` \ No newline at end of file diff --git a/src/tests/fixtures/input_types/InputTypeInterfaceOptionalField.ts.expected b/src/tests/fixtures/input_types/InputTypeInterfaceOptionalField.ts.expected deleted file mode 100644 index 4ce12108..00000000 --- a/src/tests/fixtures/input_types/InputTypeInterfaceOptionalField.ts.expected +++ /dev/null @@ -1,33 +0,0 @@ ------------------ -INPUT ------------------ -/** @gqlInput */ -interface MyInputType { - someField?: string; -} - ------------------ -OUTPUT ------------------ --- SDL -- -input MyInputType { - someField: String -} --- TypeScript -- -import { GraphQLSchema, GraphQLInputObjectType, GraphQLString } from "graphql"; -export function getSchema(): GraphQLSchema { - const MyInputTypeType: GraphQLInputObjectType = new GraphQLInputObjectType({ - name: "MyInputType", - fields() { - return { - someField: { - name: "someField", - type: GraphQLString - } - }; - } - }); - return new GraphQLSchema({ - types: [MyInputTypeType] - }); -} diff --git a/src/tests/fixtures/input_types/InputTypeInterfaceOptionalField.ts.expected.md b/src/tests/fixtures/input_types/InputTypeInterfaceOptionalField.ts.expected.md new file mode 100644 index 00000000..c54c1e0f --- /dev/null +++ b/src/tests/fixtures/input_types/InputTypeInterfaceOptionalField.ts.expected.md @@ -0,0 +1,40 @@ +## input + +```ts title="input_types/InputTypeInterfaceOptionalField.ts" +/** @gqlInput */ +interface MyInputType { + someField?: string; +} +``` + +## Output + +### SDL + +```graphql +input MyInputType { + someField: String +} +``` + +### TypeScript + +```ts +import { GraphQLSchema, GraphQLInputObjectType, GraphQLString } from "graphql"; +export function getSchema(): GraphQLSchema { + const MyInputTypeType: GraphQLInputObjectType = new GraphQLInputObjectType({ + name: "MyInputType", + fields() { + return { + someField: { + name: "someField", + type: GraphQLString + } + }; + } + }); + return new GraphQLSchema({ + types: [MyInputTypeType] + }); +} +``` \ No newline at end of file diff --git a/src/tests/fixtures/input_types/InputTypeInterfacePromiseField.invalid.ts.expected b/src/tests/fixtures/input_types/InputTypeInterfacePromiseField.invalid.ts.expected deleted file mode 100644 index 99b44353..00000000 --- a/src/tests/fixtures/input_types/InputTypeInterfacePromiseField.invalid.ts.expected +++ /dev/null @@ -1,15 +0,0 @@ ------------------ -INPUT ------------------ -/** @gqlInput */ -interface MyInputType { - someMethod: Promise; -} - ------------------ -OUTPUT ------------------ -src/tests/fixtures/input_types/InputTypeInterfacePromiseField.invalid.ts:3:15 - error: `Promise` is not a valid as an input type. - -3 someMethod: Promise; - ~~~~~~~~~~~~~~~ diff --git a/src/tests/fixtures/input_types/InputTypeInterfacePromiseField.invalid.ts.expected.md b/src/tests/fixtures/input_types/InputTypeInterfacePromiseField.invalid.ts.expected.md new file mode 100644 index 00000000..a9b1fa39 --- /dev/null +++ b/src/tests/fixtures/input_types/InputTypeInterfacePromiseField.invalid.ts.expected.md @@ -0,0 +1,19 @@ +## input + +```ts title="input_types/InputTypeInterfacePromiseField.invalid.ts" +/** @gqlInput */ +interface MyInputType { + someMethod: Promise; +} +``` + +## Output + +### Error Report + +```text +src/tests/fixtures/input_types/InputTypeInterfacePromiseField.invalid.ts:3:15 - error: `Promise` is not a valid as an input type. + +3 someMethod: Promise; + ~~~~~~~~~~~~~~~ +``` \ No newline at end of file diff --git a/src/tests/fixtures/input_types/InputTypeMergedInterface.invalid.ts.expected b/src/tests/fixtures/input_types/InputTypeMergedInterface.invalid.ts.expected deleted file mode 100644 index 2a7cdd23..00000000 --- a/src/tests/fixtures/input_types/InputTypeMergedInterface.invalid.ts.expected +++ /dev/null @@ -1,26 +0,0 @@ ------------------ -INPUT ------------------ -interface MyInputType { - secretConfusingField: string; -} - -/** @gqlInput */ -interface MyInputType { - someField: string; -} - ------------------ -OUTPUT ------------------ -src/tests/fixtures/input_types/InputTypeMergedInterface.invalid.ts:6:11 - error: Unexpected merged interface. If an interface is declared multiple times in a scope, TypeScript merges them. To avoid ambiguity Grats does not support using merged interfaces as GraphQL definitions. Consider using a unique name for your TypeScript interface and renaming it. - - Learn more: https://grats.capt.dev/docs/docblock-tags/interfaces/#merged-interfaces - -6 interface MyInputType { - ~~~~~~~~~~~ - - src/tests/fixtures/input_types/InputTypeMergedInterface.invalid.ts:1:11 - 1 interface MyInputType { - ~~~~~~~~~~~ - Other declaration diff --git a/src/tests/fixtures/input_types/InputTypeMergedInterface.invalid.ts.expected.md b/src/tests/fixtures/input_types/InputTypeMergedInterface.invalid.ts.expected.md new file mode 100644 index 00000000..e4b50954 --- /dev/null +++ b/src/tests/fixtures/input_types/InputTypeMergedInterface.invalid.ts.expected.md @@ -0,0 +1,30 @@ +## input + +```ts title="input_types/InputTypeMergedInterface.invalid.ts" +interface MyInputType { + secretConfusingField: string; +} + +/** @gqlInput */ +interface MyInputType { + someField: string; +} +``` + +## Output + +### Error Report + +```text +src/tests/fixtures/input_types/InputTypeMergedInterface.invalid.ts:6:11 - error: Unexpected merged interface. If an interface is declared multiple times in a scope, TypeScript merges them. To avoid ambiguity Grats does not support using merged interfaces as GraphQL definitions. Consider using a unique name for your TypeScript interface and renaming it. + + Learn more: https://grats.capt.dev/docs/docblock-tags/interfaces/#merged-interfaces + +6 interface MyInputType { + ~~~~~~~~~~~ + + src/tests/fixtures/input_types/InputTypeMergedInterface.invalid.ts:1:11 + 1 interface MyInputType { + ~~~~~~~~~~~ + Other declaration +``` \ No newline at end of file diff --git a/src/tests/fixtures/input_types/InputTypeOptionalField.ts.expected b/src/tests/fixtures/input_types/InputTypeOptionalField.ts.expected deleted file mode 100644 index 9e6f4488..00000000 --- a/src/tests/fixtures/input_types/InputTypeOptionalField.ts.expected +++ /dev/null @@ -1,54 +0,0 @@ ------------------ -INPUT ------------------ -/** @gqlType */ -class SomeType { - /** @gqlField */ - hello: string; -} - -/** @gqlInput */ -type MyInputType = { - someField?: string; -}; - ------------------ -OUTPUT ------------------ --- SDL -- -input MyInputType { - someField: String -} - -type SomeType { - hello: String -} --- TypeScript -- -import { GraphQLSchema, GraphQLInputObjectType, GraphQLString, GraphQLObjectType } from "graphql"; -export function getSchema(): GraphQLSchema { - const MyInputTypeType: GraphQLInputObjectType = new GraphQLInputObjectType({ - name: "MyInputType", - fields() { - return { - someField: { - name: "someField", - type: GraphQLString - } - }; - } - }); - const SomeTypeType: GraphQLObjectType = new GraphQLObjectType({ - name: "SomeType", - fields() { - return { - hello: { - name: "hello", - type: GraphQLString - } - }; - } - }); - return new GraphQLSchema({ - types: [MyInputTypeType, SomeTypeType] - }); -} diff --git a/src/tests/fixtures/input_types/InputTypeOptionalField.ts.expected.md b/src/tests/fixtures/input_types/InputTypeOptionalField.ts.expected.md new file mode 100644 index 00000000..96a0a98e --- /dev/null +++ b/src/tests/fixtures/input_types/InputTypeOptionalField.ts.expected.md @@ -0,0 +1,61 @@ +## input + +```ts title="input_types/InputTypeOptionalField.ts" +/** @gqlType */ +class SomeType { + /** @gqlField */ + hello: string; +} + +/** @gqlInput */ +type MyInputType = { + someField?: string; +}; +``` + +## Output + +### SDL + +```graphql +input MyInputType { + someField: String +} + +type SomeType { + hello: String +} +``` + +### TypeScript + +```ts +import { GraphQLSchema, GraphQLInputObjectType, GraphQLString, GraphQLObjectType } from "graphql"; +export function getSchema(): GraphQLSchema { + const MyInputTypeType: GraphQLInputObjectType = new GraphQLInputObjectType({ + name: "MyInputType", + fields() { + return { + someField: { + name: "someField", + type: GraphQLString + } + }; + } + }); + const SomeTypeType: GraphQLObjectType = new GraphQLObjectType({ + name: "SomeType", + fields() { + return { + hello: { + name: "hello", + type: GraphQLString + } + }; + } + }); + return new GraphQLSchema({ + types: [MyInputTypeType, SomeTypeType] + }); +} +``` \ No newline at end of file diff --git a/src/tests/fixtures/input_types/InputTypeReferencingOutputType.invalid.ts.expected b/src/tests/fixtures/input_types/InputTypeReferencingOutputType.invalid.ts.expected deleted file mode 100644 index ba85af88..00000000 --- a/src/tests/fixtures/input_types/InputTypeReferencingOutputType.invalid.ts.expected +++ /dev/null @@ -1,21 +0,0 @@ ------------------ -INPUT ------------------ -/** @gqlType */ -class SomeType { - /** @gqlField */ - someField(args: { input: MyInputType }): string; -} - -/** @gqlInput */ -type MyInputType = { - someField: SomeType; -}; - ------------------ -OUTPUT ------------------ -src/tests/fixtures/input_types/InputTypeReferencingOutputType.invalid.ts:9:14 - error: The type of MyInputType.someField must be Input Type but got: SomeType!. - -9 someField: SomeType; - ~~~~~~~~ diff --git a/src/tests/fixtures/input_types/InputTypeReferencingOutputType.invalid.ts.expected.md b/src/tests/fixtures/input_types/InputTypeReferencingOutputType.invalid.ts.expected.md new file mode 100644 index 00000000..9b76c20c --- /dev/null +++ b/src/tests/fixtures/input_types/InputTypeReferencingOutputType.invalid.ts.expected.md @@ -0,0 +1,25 @@ +## input + +```ts title="input_types/InputTypeReferencingOutputType.invalid.ts" +/** @gqlType */ +class SomeType { + /** @gqlField */ + someField(args: { input: MyInputType }): string; +} + +/** @gqlInput */ +type MyInputType = { + someField: SomeType; +}; +``` + +## Output + +### Error Report + +```text +src/tests/fixtures/input_types/InputTypeReferencingOutputType.invalid.ts:9:14 - error: The type of MyInputType.someField must be Input Type but got: SomeType!. + +9 someField: SomeType; + ~~~~~~~~ +``` \ No newline at end of file diff --git a/src/tests/fixtures/input_types/InputTypeReturnedFromField.invalid.ts.expected b/src/tests/fixtures/input_types/InputTypeReturnedFromField.invalid.ts.expected deleted file mode 100644 index bb0e1134..00000000 --- a/src/tests/fixtures/input_types/InputTypeReturnedFromField.invalid.ts.expected +++ /dev/null @@ -1,31 +0,0 @@ ------------------ -INPUT ------------------ -/** @gqlType */ -class SomeType { - /** @gqlField */ - hello: string; -} - -/** @gqlType */ -class MyType { - /** @gqlField */ - someField(): MyInputType; -} - -/** @gqlInput */ -type MyInputType = { - someField: MyType; -}; - ------------------ -OUTPUT ------------------ -src/tests/fixtures/input_types/InputTypeReturnedFromField.invalid.ts:15:14 - error: The type of MyInputType.someField must be Input Type but got: MyType!. - -15 someField: MyType; - ~~~~~~ -src/tests/fixtures/input_types/InputTypeReturnedFromField.invalid.ts:10:16 - error: The type of MyType.someField must be Output Type but got: MyInputType. - -10 someField(): MyInputType; - ~~~~~~~~~~~ diff --git a/src/tests/fixtures/input_types/InputTypeReturnedFromField.invalid.ts.expected.md b/src/tests/fixtures/input_types/InputTypeReturnedFromField.invalid.ts.expected.md new file mode 100644 index 00000000..dbc1e986 --- /dev/null +++ b/src/tests/fixtures/input_types/InputTypeReturnedFromField.invalid.ts.expected.md @@ -0,0 +1,35 @@ +## input + +```ts title="input_types/InputTypeReturnedFromField.invalid.ts" +/** @gqlType */ +class SomeType { + /** @gqlField */ + hello: string; +} + +/** @gqlType */ +class MyType { + /** @gqlField */ + someField(): MyInputType; +} + +/** @gqlInput */ +type MyInputType = { + someField: MyType; +}; +``` + +## Output + +### Error Report + +```text +src/tests/fixtures/input_types/InputTypeReturnedFromField.invalid.ts:15:14 - error: The type of MyInputType.someField must be Input Type but got: MyType!. + +15 someField: MyType; + ~~~~~~ +src/tests/fixtures/input_types/InputTypeReturnedFromField.invalid.ts:10:16 - error: The type of MyType.someField must be Output Type but got: MyInputType. + +10 someField(): MyInputType; + ~~~~~~~~~~~ +``` \ No newline at end of file diff --git a/src/tests/fixtures/input_types/InputTypeWithDeprecatedField.ts.expected b/src/tests/fixtures/input_types/InputTypeWithDeprecatedField.ts.expected deleted file mode 100644 index fe6a8533..00000000 --- a/src/tests/fixtures/input_types/InputTypeWithDeprecatedField.ts.expected +++ /dev/null @@ -1,60 +0,0 @@ ------------------ -INPUT ------------------ -/** @gqlType */ -export default class SomeType { - /** @gqlField */ - hello: string; -} - -/** @gqlInput */ -type MyInputType = { - /** Sweet field! - * @deprecated Sweet, but stale - */ - someField?: string; -}; - ------------------ -OUTPUT ------------------ --- SDL -- -input MyInputType { - """Sweet field!""" - someField: String @deprecated(reason: "Sweet, but stale") -} - -type SomeType { - hello: String -} --- TypeScript -- -import { GraphQLSchema, GraphQLInputObjectType, GraphQLString, GraphQLObjectType } from "graphql"; -export function getSchema(): GraphQLSchema { - const MyInputTypeType: GraphQLInputObjectType = new GraphQLInputObjectType({ - name: "MyInputType", - fields() { - return { - someField: { - description: "Sweet field!", - deprecationReason: "Sweet, but stale", - name: "someField", - type: GraphQLString - } - }; - } - }); - const SomeTypeType: GraphQLObjectType = new GraphQLObjectType({ - name: "SomeType", - fields() { - return { - hello: { - name: "hello", - type: GraphQLString - } - }; - } - }); - return new GraphQLSchema({ - types: [MyInputTypeType, SomeTypeType] - }); -} diff --git a/src/tests/fixtures/input_types/InputTypeWithDeprecatedField.ts.expected.md b/src/tests/fixtures/input_types/InputTypeWithDeprecatedField.ts.expected.md new file mode 100644 index 00000000..0d4fceb9 --- /dev/null +++ b/src/tests/fixtures/input_types/InputTypeWithDeprecatedField.ts.expected.md @@ -0,0 +1,67 @@ +## input + +```ts title="input_types/InputTypeWithDeprecatedField.ts" +/** @gqlType */ +export default class SomeType { + /** @gqlField */ + hello: string; +} + +/** @gqlInput */ +type MyInputType = { + /** Sweet field! + * @deprecated Sweet, but stale + */ + someField?: string; +}; +``` + +## Output + +### SDL + +```graphql +input MyInputType { + """Sweet field!""" + someField: String @deprecated(reason: "Sweet, but stale") +} + +type SomeType { + hello: String +} +``` + +### TypeScript + +```ts +import { GraphQLSchema, GraphQLInputObjectType, GraphQLString, GraphQLObjectType } from "graphql"; +export function getSchema(): GraphQLSchema { + const MyInputTypeType: GraphQLInputObjectType = new GraphQLInputObjectType({ + name: "MyInputType", + fields() { + return { + someField: { + description: "Sweet field!", + deprecationReason: "Sweet, but stale", + name: "someField", + type: GraphQLString + } + }; + } + }); + const SomeTypeType: GraphQLObjectType = new GraphQLObjectType({ + name: "SomeType", + fields() { + return { + hello: { + name: "hello", + type: GraphQLString + } + }; + } + }); + return new GraphQLSchema({ + types: [MyInputTypeType, SomeTypeType] + }); +} +``` \ No newline at end of file diff --git a/src/tests/fixtures/input_types/InputTypeWithDeprecatedRequiredField.invalid.ts.expected b/src/tests/fixtures/input_types/InputTypeWithDeprecatedRequiredField.invalid.ts.expected deleted file mode 100644 index 0e8b5246..00000000 --- a/src/tests/fixtures/input_types/InputTypeWithDeprecatedRequiredField.invalid.ts.expected +++ /dev/null @@ -1,29 +0,0 @@ ------------------ -INPUT ------------------ -/** @gqlType */ -export default class SomeType { - /** @gqlField */ - hello: string; -} - -/** @gqlInput */ -type MyInputType = { - /** Sweet field! - * @deprecated Sweet, but stale - */ - someField: string; -}; - ------------------ -OUTPUT ------------------ -src/tests/fixtures/input_types/InputTypeWithDeprecatedRequiredField.invalid.ts:10:7 - error: Required input field MyInputType.someField cannot be deprecated. - -10 * @deprecated Sweet, but stale - ~~~~~~~~~~ - - src/tests/fixtures/input_types/InputTypeWithDeprecatedRequiredField.invalid.ts:12:14 - 12 someField: string; - ~~~~~~ - Related location diff --git a/src/tests/fixtures/input_types/InputTypeWithDeprecatedRequiredField.invalid.ts.expected.md b/src/tests/fixtures/input_types/InputTypeWithDeprecatedRequiredField.invalid.ts.expected.md new file mode 100644 index 00000000..48d72c49 --- /dev/null +++ b/src/tests/fixtures/input_types/InputTypeWithDeprecatedRequiredField.invalid.ts.expected.md @@ -0,0 +1,33 @@ +## input + +```ts title="input_types/InputTypeWithDeprecatedRequiredField.invalid.ts" +/** @gqlType */ +export default class SomeType { + /** @gqlField */ + hello: string; +} + +/** @gqlInput */ +type MyInputType = { + /** Sweet field! + * @deprecated Sweet, but stale + */ + someField: string; +}; +``` + +## Output + +### Error Report + +```text +src/tests/fixtures/input_types/InputTypeWithDeprecatedRequiredField.invalid.ts:10:7 - error: Required input field MyInputType.someField cannot be deprecated. + +10 * @deprecated Sweet, but stale + ~~~~~~~~~~ + + src/tests/fixtures/input_types/InputTypeWithDeprecatedRequiredField.invalid.ts:12:14 + 12 someField: string; + ~~~~~~ + Related location +``` \ No newline at end of file diff --git a/src/tests/fixtures/input_types/InputTypeWithDescription.ts.expected b/src/tests/fixtures/input_types/InputTypeWithDescription.ts.expected deleted file mode 100644 index 89644248..00000000 --- a/src/tests/fixtures/input_types/InputTypeWithDescription.ts.expected +++ /dev/null @@ -1,59 +0,0 @@ ------------------ -INPUT ------------------ -/** @gqlType */ -class SomeType { - /** @gqlField */ - hello: string; -} - -/** - * Check out this great input! - * @gqlInput - */ -type MyInputType = { - someField: string; -}; - ------------------ -OUTPUT ------------------ --- SDL -- -"""Check out this great input!""" -input MyInputType { - someField: String! -} - -type SomeType { - hello: String -} --- TypeScript -- -import { GraphQLSchema, GraphQLInputObjectType, GraphQLNonNull, GraphQLString, GraphQLObjectType } from "graphql"; -export function getSchema(): GraphQLSchema { - const MyInputTypeType: GraphQLInputObjectType = new GraphQLInputObjectType({ - description: "Check out this great input!", - name: "MyInputType", - fields() { - return { - someField: { - name: "someField", - type: new GraphQLNonNull(GraphQLString) - } - }; - } - }); - const SomeTypeType: GraphQLObjectType = new GraphQLObjectType({ - name: "SomeType", - fields() { - return { - hello: { - name: "hello", - type: GraphQLString - } - }; - } - }); - return new GraphQLSchema({ - types: [MyInputTypeType, SomeTypeType] - }); -} diff --git a/src/tests/fixtures/input_types/InputTypeWithDescription.ts.expected.md b/src/tests/fixtures/input_types/InputTypeWithDescription.ts.expected.md new file mode 100644 index 00000000..077ea7bf --- /dev/null +++ b/src/tests/fixtures/input_types/InputTypeWithDescription.ts.expected.md @@ -0,0 +1,66 @@ +## input + +```ts title="input_types/InputTypeWithDescription.ts" +/** @gqlType */ +class SomeType { + /** @gqlField */ + hello: string; +} + +/** + * Check out this great input! + * @gqlInput + */ +type MyInputType = { + someField: string; +}; +``` + +## Output + +### SDL + +```graphql +"""Check out this great input!""" +input MyInputType { + someField: String! +} + +type SomeType { + hello: String +} +``` + +### TypeScript + +```ts +import { GraphQLSchema, GraphQLInputObjectType, GraphQLNonNull, GraphQLString, GraphQLObjectType } from "graphql"; +export function getSchema(): GraphQLSchema { + const MyInputTypeType: GraphQLInputObjectType = new GraphQLInputObjectType({ + description: "Check out this great input!", + name: "MyInputType", + fields() { + return { + someField: { + name: "someField", + type: new GraphQLNonNull(GraphQLString) + } + }; + } + }); + const SomeTypeType: GraphQLObjectType = new GraphQLObjectType({ + name: "SomeType", + fields() { + return { + hello: { + name: "hello", + type: GraphQLString + } + }; + } + }); + return new GraphQLSchema({ + types: [MyInputTypeType, SomeTypeType] + }); +} +``` \ No newline at end of file diff --git a/src/tests/fixtures/input_types/InputTypeWithFieldDescription.ts.expected b/src/tests/fixtures/input_types/InputTypeWithFieldDescription.ts.expected deleted file mode 100644 index 92bd92cd..00000000 --- a/src/tests/fixtures/input_types/InputTypeWithFieldDescription.ts.expected +++ /dev/null @@ -1,57 +0,0 @@ ------------------ -INPUT ------------------ -/** @gqlType */ -export default class SomeType { - /** @gqlField */ - hello: string; -} - -/** @gqlInput */ -type MyInputType = { - /** Sweet field! */ - someField: string; -}; - ------------------ -OUTPUT ------------------ --- SDL -- -input MyInputType { - """Sweet field!""" - someField: String! -} - -type SomeType { - hello: String -} --- TypeScript -- -import { GraphQLSchema, GraphQLInputObjectType, GraphQLNonNull, GraphQLString, GraphQLObjectType } from "graphql"; -export function getSchema(): GraphQLSchema { - const MyInputTypeType: GraphQLInputObjectType = new GraphQLInputObjectType({ - name: "MyInputType", - fields() { - return { - someField: { - description: "Sweet field!", - name: "someField", - type: new GraphQLNonNull(GraphQLString) - } - }; - } - }); - const SomeTypeType: GraphQLObjectType = new GraphQLObjectType({ - name: "SomeType", - fields() { - return { - hello: { - name: "hello", - type: GraphQLString - } - }; - } - }); - return new GraphQLSchema({ - types: [MyInputTypeType, SomeTypeType] - }); -} diff --git a/src/tests/fixtures/input_types/InputTypeWithFieldDescription.ts.expected.md b/src/tests/fixtures/input_types/InputTypeWithFieldDescription.ts.expected.md new file mode 100644 index 00000000..dbdfa685 --- /dev/null +++ b/src/tests/fixtures/input_types/InputTypeWithFieldDescription.ts.expected.md @@ -0,0 +1,64 @@ +## input + +```ts title="input_types/InputTypeWithFieldDescription.ts" +/** @gqlType */ +export default class SomeType { + /** @gqlField */ + hello: string; +} + +/** @gqlInput */ +type MyInputType = { + /** Sweet field! */ + someField: string; +}; +``` + +## Output + +### SDL + +```graphql +input MyInputType { + """Sweet field!""" + someField: String! +} + +type SomeType { + hello: String +} +``` + +### TypeScript + +```ts +import { GraphQLSchema, GraphQLInputObjectType, GraphQLNonNull, GraphQLString, GraphQLObjectType } from "graphql"; +export function getSchema(): GraphQLSchema { + const MyInputTypeType: GraphQLInputObjectType = new GraphQLInputObjectType({ + name: "MyInputType", + fields() { + return { + someField: { + description: "Sweet field!", + name: "someField", + type: new GraphQLNonNull(GraphQLString) + } + }; + } + }); + const SomeTypeType: GraphQLObjectType = new GraphQLObjectType({ + name: "SomeType", + fields() { + return { + hello: { + name: "hello", + type: GraphQLString + } + }; + } + }); + return new GraphQLSchema({ + types: [MyInputTypeType, SomeTypeType] + }); +} +``` \ No newline at end of file diff --git a/src/tests/fixtures/input_types/RenamedInputType.ts.expected b/src/tests/fixtures/input_types/RenamedInputType.ts.expected deleted file mode 100644 index 9ab5c957..00000000 --- a/src/tests/fixtures/input_types/RenamedInputType.ts.expected +++ /dev/null @@ -1,54 +0,0 @@ ------------------ -INPUT ------------------ -/** @gqlType */ -class SomeType { - /** @gqlField */ - hello: string; -} - -/** @gqlInput OtherName */ -type MyInputType = { - someField: string; -}; - ------------------ -OUTPUT ------------------ --- SDL -- -input OtherName { - someField: String! -} - -type SomeType { - hello: String -} --- TypeScript -- -import { GraphQLSchema, GraphQLInputObjectType, GraphQLNonNull, GraphQLString, GraphQLObjectType } from "graphql"; -export function getSchema(): GraphQLSchema { - const OtherNameType: GraphQLInputObjectType = new GraphQLInputObjectType({ - name: "OtherName", - fields() { - return { - someField: { - name: "someField", - type: new GraphQLNonNull(GraphQLString) - } - }; - } - }); - const SomeTypeType: GraphQLObjectType = new GraphQLObjectType({ - name: "SomeType", - fields() { - return { - hello: { - name: "hello", - type: GraphQLString - } - }; - } - }); - return new GraphQLSchema({ - types: [OtherNameType, SomeTypeType] - }); -} diff --git a/src/tests/fixtures/input_types/RenamedInputType.ts.expected.md b/src/tests/fixtures/input_types/RenamedInputType.ts.expected.md new file mode 100644 index 00000000..36e49d53 --- /dev/null +++ b/src/tests/fixtures/input_types/RenamedInputType.ts.expected.md @@ -0,0 +1,61 @@ +## input + +```ts title="input_types/RenamedInputType.ts" +/** @gqlType */ +class SomeType { + /** @gqlField */ + hello: string; +} + +/** @gqlInput OtherName */ +type MyInputType = { + someField: string; +}; +``` + +## Output + +### SDL + +```graphql +input OtherName { + someField: String! +} + +type SomeType { + hello: String +} +``` + +### TypeScript + +```ts +import { GraphQLSchema, GraphQLInputObjectType, GraphQLNonNull, GraphQLString, GraphQLObjectType } from "graphql"; +export function getSchema(): GraphQLSchema { + const OtherNameType: GraphQLInputObjectType = new GraphQLInputObjectType({ + name: "OtherName", + fields() { + return { + someField: { + name: "someField", + type: new GraphQLNonNull(GraphQLString) + } + }; + } + }); + const SomeTypeType: GraphQLObjectType = new GraphQLObjectType({ + name: "SomeType", + fields() { + return { + hello: { + name: "hello", + type: GraphQLString + } + }; + } + }); + return new GraphQLSchema({ + types: [OtherNameType, SomeTypeType] + }); +} +``` \ No newline at end of file diff --git a/src/tests/fixtures/input_types/inputFieldWithGqlField.invalid.ts.expected b/src/tests/fixtures/input_types/inputFieldWithGqlField.invalid.ts.expected deleted file mode 100644 index 8454ee89..00000000 --- a/src/tests/fixtures/input_types/inputFieldWithGqlField.invalid.ts.expected +++ /dev/null @@ -1,38 +0,0 @@ ------------------ -INPUT ------------------ -/** @gqlInput */ -type Foo = { - /** @gqlField */ - name: string; -}; - ------------------ -OUTPUT ------------------ --- Error Report -- -src/tests/fixtures/input_types/inputFieldWithGqlField.invalid.ts:3:7 - error: The tag `@gqlField` is not needed on fields of input types. All fields are automatically included as part of the input type. This tag can be safely removed. - -3 /** @gqlField */ - ~~~~~~~~~~ - - --- Code Action: "Remove @gqlField tag" (remove-gql-field-from-input) -- -- Original -+ Fixed - -@@ -2,3 +2,3 @@ - type Foo = { -- /** @gqlField */ -+ - name: string; - --- Applied Fixes -- - * Applied fix "Remove @gqlField tag" in grats/src/tests/fixtures/input_types/inputFieldWithGqlField.invalid.ts - --- Fixed Text -- -/** @gqlInput */ -type Foo = { - - name: string; -}; diff --git a/src/tests/fixtures/input_types/inputFieldWithGqlField.invalid.ts.expected.md b/src/tests/fixtures/input_types/inputFieldWithGqlField.invalid.ts.expected.md new file mode 100644 index 00000000..ee6716dc --- /dev/null +++ b/src/tests/fixtures/input_types/inputFieldWithGqlField.invalid.ts.expected.md @@ -0,0 +1,49 @@ +## input + +```ts title="input_types/inputFieldWithGqlField.invalid.ts" +/** @gqlInput */ +type Foo = { + /** @gqlField */ + name: string; +}; +``` + +## Output + +### Error Report + +```text +src/tests/fixtures/input_types/inputFieldWithGqlField.invalid.ts:3:7 - error: The tag `@gqlField` is not needed on fields of input types. All fields are automatically included as part of the input type. This tag can be safely removed. + +3 /** @gqlField */ + ~~~~~~~~~~ +``` + +#### Code Action: "Remove @gqlField tag" (remove-gql-field-from-input) + +```diff +- Original ++ Fixed + +@@ -2,3 +2,3 @@ + type Foo = { +- /** @gqlField */ ++ + name: string; +``` + +#### Applied Fixes + +```text + * Applied fix "Remove @gqlField tag" in grats/src/tests/fixtures/input_types/inputFieldWithGqlField.invalid.ts +``` + +#### Fixed Text + +```typescript +/** @gqlInput */ +type Foo = { + + name: string; +}; +``` \ No newline at end of file diff --git a/src/tests/fixtures/interfaces/FieldReturnsInterface.ts.expected b/src/tests/fixtures/interfaces/FieldReturnsInterface.ts.expected deleted file mode 100644 index c4a86aa5..00000000 --- a/src/tests/fixtures/interfaces/FieldReturnsInterface.ts.expected +++ /dev/null @@ -1,82 +0,0 @@ ------------------ -INPUT ------------------ -/** @gqlType */ -export default class SomeType { - /** @gqlField */ - me(): IPerson { - return new User(); - } -} - -/** @gqlInterface Person */ -interface IPerson { - /** @gqlField */ - name: string; -} - -/** @gqlType */ -class User implements IPerson { - __typename = "User" as const; - /** @gqlField */ - name: string; -} - ------------------ -OUTPUT ------------------ --- SDL -- -interface Person { - name: String -} - -type SomeType { - me: Person -} - -type User implements Person { - name: String -} --- TypeScript -- -import { GraphQLSchema, GraphQLInterfaceType, GraphQLString, GraphQLObjectType } from "graphql"; -export function getSchema(): GraphQLSchema { - const PersonType: GraphQLInterfaceType = new GraphQLInterfaceType({ - name: "Person", - fields() { - return { - name: { - name: "name", - type: GraphQLString - } - }; - } - }); - const SomeTypeType: GraphQLObjectType = new GraphQLObjectType({ - name: "SomeType", - fields() { - return { - me: { - name: "me", - type: PersonType - } - }; - } - }); - const UserType: GraphQLObjectType = new GraphQLObjectType({ - name: "User", - fields() { - return { - name: { - name: "name", - type: GraphQLString - } - }; - }, - interfaces() { - return [PersonType]; - } - }); - return new GraphQLSchema({ - types: [PersonType, SomeTypeType, UserType] - }); -} diff --git a/src/tests/fixtures/interfaces/FieldReturnsInterface.ts.expected.md b/src/tests/fixtures/interfaces/FieldReturnsInterface.ts.expected.md new file mode 100644 index 00000000..bb761d34 --- /dev/null +++ b/src/tests/fixtures/interfaces/FieldReturnsInterface.ts.expected.md @@ -0,0 +1,89 @@ +## input + +```ts title="interfaces/FieldReturnsInterface.ts" +/** @gqlType */ +export default class SomeType { + /** @gqlField */ + me(): IPerson { + return new User(); + } +} + +/** @gqlInterface Person */ +interface IPerson { + /** @gqlField */ + name: string; +} + +/** @gqlType */ +class User implements IPerson { + __typename = "User" as const; + /** @gqlField */ + name: string; +} +``` + +## Output + +### SDL + +```graphql +interface Person { + name: String +} + +type SomeType { + me: Person +} + +type User implements Person { + name: String +} +``` + +### TypeScript + +```ts +import { GraphQLSchema, GraphQLInterfaceType, GraphQLString, GraphQLObjectType } from "graphql"; +export function getSchema(): GraphQLSchema { + const PersonType: GraphQLInterfaceType = new GraphQLInterfaceType({ + name: "Person", + fields() { + return { + name: { + name: "name", + type: GraphQLString + } + }; + } + }); + const SomeTypeType: GraphQLObjectType = new GraphQLObjectType({ + name: "SomeType", + fields() { + return { + me: { + name: "me", + type: PersonType + } + }; + } + }); + const UserType: GraphQLObjectType = new GraphQLObjectType({ + name: "User", + fields() { + return { + name: { + name: "name", + type: GraphQLString + } + }; + }, + interfaces() { + return [PersonType]; + } + }); + return new GraphQLSchema({ + types: [PersonType, SomeTypeType, UserType] + }); +} +``` \ No newline at end of file diff --git a/src/tests/fixtures/interfaces/IgnoresExtendsClause.ts.expected b/src/tests/fixtures/interfaces/IgnoresExtendsClause.ts.expected deleted file mode 100644 index 97e93528..00000000 --- a/src/tests/fixtures/interfaces/IgnoresExtendsClause.ts.expected +++ /dev/null @@ -1,86 +0,0 @@ ------------------ -INPUT ------------------ -/** @gqlType */ -export default class SomeType { - /** @gqlField */ - me(): User { - return new User(); - } -} - -class Person { - name: string; -} - -/** @gqlInterface */ -interface Actor { - /** @gqlField */ - name: string; -} - -/** @gqlType */ -class User extends Person implements Actor { - __typename = "User" as const; - /** @gqlField */ - name: string; -} - ------------------ -OUTPUT ------------------ --- SDL -- -interface Actor { - name: String -} - -type SomeType { - me: User -} - -type User implements Actor { - name: String -} --- TypeScript -- -import { GraphQLSchema, GraphQLInterfaceType, GraphQLString, GraphQLObjectType } from "graphql"; -export function getSchema(): GraphQLSchema { - const ActorType: GraphQLInterfaceType = new GraphQLInterfaceType({ - name: "Actor", - fields() { - return { - name: { - name: "name", - type: GraphQLString - } - }; - } - }); - const UserType: GraphQLObjectType = new GraphQLObjectType({ - name: "User", - fields() { - return { - name: { - name: "name", - type: GraphQLString - } - }; - }, - interfaces() { - return [ActorType]; - } - }); - const SomeTypeType: GraphQLObjectType = new GraphQLObjectType({ - name: "SomeType", - fields() { - return { - me: { - name: "me", - type: UserType - } - }; - } - }); - return new GraphQLSchema({ - types: [ActorType, SomeTypeType, UserType] - }); -} diff --git a/src/tests/fixtures/interfaces/IgnoresExtendsClause.ts.expected.md b/src/tests/fixtures/interfaces/IgnoresExtendsClause.ts.expected.md new file mode 100644 index 00000000..5394683a --- /dev/null +++ b/src/tests/fixtures/interfaces/IgnoresExtendsClause.ts.expected.md @@ -0,0 +1,93 @@ +## input + +```ts title="interfaces/IgnoresExtendsClause.ts" +/** @gqlType */ +export default class SomeType { + /** @gqlField */ + me(): User { + return new User(); + } +} + +class Person { + name: string; +} + +/** @gqlInterface */ +interface Actor { + /** @gqlField */ + name: string; +} + +/** @gqlType */ +class User extends Person implements Actor { + __typename = "User" as const; + /** @gqlField */ + name: string; +} +``` + +## Output + +### SDL + +```graphql +interface Actor { + name: String +} + +type SomeType { + me: User +} + +type User implements Actor { + name: String +} +``` + +### TypeScript + +```ts +import { GraphQLSchema, GraphQLInterfaceType, GraphQLString, GraphQLObjectType } from "graphql"; +export function getSchema(): GraphQLSchema { + const ActorType: GraphQLInterfaceType = new GraphQLInterfaceType({ + name: "Actor", + fields() { + return { + name: { + name: "name", + type: GraphQLString + } + }; + } + }); + const UserType: GraphQLObjectType = new GraphQLObjectType({ + name: "User", + fields() { + return { + name: { + name: "name", + type: GraphQLString + } + }; + }, + interfaces() { + return [ActorType]; + } + }); + const SomeTypeType: GraphQLObjectType = new GraphQLObjectType({ + name: "SomeType", + fields() { + return { + me: { + name: "me", + type: UserType + } + }; + } + }); + return new GraphQLSchema({ + types: [ActorType, SomeTypeType, UserType] + }); +} +``` \ No newline at end of file diff --git a/src/tests/fixtures/interfaces/ImplementsInterface.ts.expected b/src/tests/fixtures/interfaces/ImplementsInterface.ts.expected deleted file mode 100644 index ac482c20..00000000 --- a/src/tests/fixtures/interfaces/ImplementsInterface.ts.expected +++ /dev/null @@ -1,82 +0,0 @@ ------------------ -INPUT ------------------ -/** @gqlType */ -export default class SomeType { - /** @gqlField */ - me(): User { - return new User(); - } -} - -/** @gqlInterface */ -interface Person { - /** @gqlField */ - name: string; -} - -/** @gqlType */ -class User implements Person { - __typename = "User" as const; - /** @gqlField */ - name: string; -} - ------------------ -OUTPUT ------------------ --- SDL -- -interface Person { - name: String -} - -type SomeType { - me: User -} - -type User implements Person { - name: String -} --- TypeScript -- -import { GraphQLSchema, GraphQLInterfaceType, GraphQLString, GraphQLObjectType } from "graphql"; -export function getSchema(): GraphQLSchema { - const PersonType: GraphQLInterfaceType = new GraphQLInterfaceType({ - name: "Person", - fields() { - return { - name: { - name: "name", - type: GraphQLString - } - }; - } - }); - const UserType: GraphQLObjectType = new GraphQLObjectType({ - name: "User", - fields() { - return { - name: { - name: "name", - type: GraphQLString - } - }; - }, - interfaces() { - return [PersonType]; - } - }); - const SomeTypeType: GraphQLObjectType = new GraphQLObjectType({ - name: "SomeType", - fields() { - return { - me: { - name: "me", - type: UserType - } - }; - } - }); - return new GraphQLSchema({ - types: [PersonType, SomeTypeType, UserType] - }); -} diff --git a/src/tests/fixtures/interfaces/ImplementsInterface.ts.expected.md b/src/tests/fixtures/interfaces/ImplementsInterface.ts.expected.md new file mode 100644 index 00000000..5a48a719 --- /dev/null +++ b/src/tests/fixtures/interfaces/ImplementsInterface.ts.expected.md @@ -0,0 +1,89 @@ +## input + +```ts title="interfaces/ImplementsInterface.ts" +/** @gqlType */ +export default class SomeType { + /** @gqlField */ + me(): User { + return new User(); + } +} + +/** @gqlInterface */ +interface Person { + /** @gqlField */ + name: string; +} + +/** @gqlType */ +class User implements Person { + __typename = "User" as const; + /** @gqlField */ + name: string; +} +``` + +## Output + +### SDL + +```graphql +interface Person { + name: String +} + +type SomeType { + me: User +} + +type User implements Person { + name: String +} +``` + +### TypeScript + +```ts +import { GraphQLSchema, GraphQLInterfaceType, GraphQLString, GraphQLObjectType } from "graphql"; +export function getSchema(): GraphQLSchema { + const PersonType: GraphQLInterfaceType = new GraphQLInterfaceType({ + name: "Person", + fields() { + return { + name: { + name: "name", + type: GraphQLString + } + }; + } + }); + const UserType: GraphQLObjectType = new GraphQLObjectType({ + name: "User", + fields() { + return { + name: { + name: "name", + type: GraphQLString + } + }; + }, + interfaces() { + return [PersonType]; + } + }); + const SomeTypeType: GraphQLObjectType = new GraphQLObjectType({ + name: "SomeType", + fields() { + return { + me: { + name: "me", + type: UserType + } + }; + } + }); + return new GraphQLSchema({ + types: [PersonType, SomeTypeType, UserType] + }); +} +``` \ No newline at end of file diff --git a/src/tests/fixtures/interfaces/ImplementsInterfaceWithTypeParam.ts.expected b/src/tests/fixtures/interfaces/ImplementsInterfaceWithTypeParam.ts.expected deleted file mode 100644 index 0c0fbc18..00000000 --- a/src/tests/fixtures/interfaces/ImplementsInterfaceWithTypeParam.ts.expected +++ /dev/null @@ -1,86 +0,0 @@ ------------------ -INPUT ------------------ -/** @gqlType */ -export default class SomeType { - /** @gqlField */ - me(): User { - return new User(); - } -} - -/** @gqlInterface */ -interface Person { - /** @gqlField */ - name: string; - - other: T; -} - -/** @gqlType */ -class User implements Person { - __typename = "User" as const; - /** @gqlField */ - name: string; - - other: string; -} - ------------------ -OUTPUT ------------------ --- SDL -- -interface Person { - name: String -} - -type SomeType { - me: User -} - -type User implements Person { - name: String -} --- TypeScript -- -import { GraphQLSchema, GraphQLInterfaceType, GraphQLString, GraphQLObjectType } from "graphql"; -export function getSchema(): GraphQLSchema { - const PersonType: GraphQLInterfaceType = new GraphQLInterfaceType({ - name: "Person", - fields() { - return { - name: { - name: "name", - type: GraphQLString - } - }; - } - }); - const UserType: GraphQLObjectType = new GraphQLObjectType({ - name: "User", - fields() { - return { - name: { - name: "name", - type: GraphQLString - } - }; - }, - interfaces() { - return [PersonType]; - } - }); - const SomeTypeType: GraphQLObjectType = new GraphQLObjectType({ - name: "SomeType", - fields() { - return { - me: { - name: "me", - type: UserType - } - }; - } - }); - return new GraphQLSchema({ - types: [PersonType, SomeTypeType, UserType] - }); -} diff --git a/src/tests/fixtures/interfaces/ImplementsInterfaceWithTypeParam.ts.expected.md b/src/tests/fixtures/interfaces/ImplementsInterfaceWithTypeParam.ts.expected.md new file mode 100644 index 00000000..8646e357 --- /dev/null +++ b/src/tests/fixtures/interfaces/ImplementsInterfaceWithTypeParam.ts.expected.md @@ -0,0 +1,93 @@ +## input + +```ts title="interfaces/ImplementsInterfaceWithTypeParam.ts" +/** @gqlType */ +export default class SomeType { + /** @gqlField */ + me(): User { + return new User(); + } +} + +/** @gqlInterface */ +interface Person { + /** @gqlField */ + name: string; + + other: T; +} + +/** @gqlType */ +class User implements Person { + __typename = "User" as const; + /** @gqlField */ + name: string; + + other: string; +} +``` + +## Output + +### SDL + +```graphql +interface Person { + name: String +} + +type SomeType { + me: User +} + +type User implements Person { + name: String +} +``` + +### TypeScript + +```ts +import { GraphQLSchema, GraphQLInterfaceType, GraphQLString, GraphQLObjectType } from "graphql"; +export function getSchema(): GraphQLSchema { + const PersonType: GraphQLInterfaceType = new GraphQLInterfaceType({ + name: "Person", + fields() { + return { + name: { + name: "name", + type: GraphQLString + } + }; + } + }); + const UserType: GraphQLObjectType = new GraphQLObjectType({ + name: "User", + fields() { + return { + name: { + name: "name", + type: GraphQLString + } + }; + }, + interfaces() { + return [PersonType]; + } + }); + const SomeTypeType: GraphQLObjectType = new GraphQLObjectType({ + name: "SomeType", + fields() { + return { + me: { + name: "me", + type: UserType + } + }; + } + }); + return new GraphQLSchema({ + types: [PersonType, SomeTypeType, UserType] + }); +} +``` \ No newline at end of file diff --git a/src/tests/fixtures/interfaces/ImplementsMultipleInterfaces.ts.expected b/src/tests/fixtures/interfaces/ImplementsMultipleInterfaces.ts.expected deleted file mode 100644 index 272807f7..00000000 --- a/src/tests/fixtures/interfaces/ImplementsMultipleInterfaces.ts.expected +++ /dev/null @@ -1,103 +0,0 @@ ------------------ -INPUT ------------------ -/** @gqlType */ -export default class SomeType { - /** @gqlField */ - me(): User { - return new User(); - } -} - -/** @gqlInterface */ -interface Person { - /** @gqlField */ - name: string; -} - -/** @gqlInterface */ -interface Actor { - /** @gqlField */ - name: string; -} - -/** @gqlType */ -class User implements Person, Actor { - __typename = "User" as const; - /** @gqlField */ - name: string; -} - ------------------ -OUTPUT ------------------ --- SDL -- -interface Actor { - name: String -} - -interface Person { - name: String -} - -type SomeType { - me: User -} - -type User implements Actor & Person { - name: String -} --- TypeScript -- -import { GraphQLSchema, GraphQLInterfaceType, GraphQLString, GraphQLObjectType } from "graphql"; -export function getSchema(): GraphQLSchema { - const ActorType: GraphQLInterfaceType = new GraphQLInterfaceType({ - name: "Actor", - fields() { - return { - name: { - name: "name", - type: GraphQLString - } - }; - } - }); - const PersonType: GraphQLInterfaceType = new GraphQLInterfaceType({ - name: "Person", - fields() { - return { - name: { - name: "name", - type: GraphQLString - } - }; - } - }); - const UserType: GraphQLObjectType = new GraphQLObjectType({ - name: "User", - fields() { - return { - name: { - name: "name", - type: GraphQLString - } - }; - }, - interfaces() { - return [ActorType, PersonType]; - } - }); - const SomeTypeType: GraphQLObjectType = new GraphQLObjectType({ - name: "SomeType", - fields() { - return { - me: { - name: "me", - type: UserType - } - }; - } - }); - return new GraphQLSchema({ - types: [ActorType, PersonType, SomeTypeType, UserType] - }); -} diff --git a/src/tests/fixtures/interfaces/ImplementsMultipleInterfaces.ts.expected.md b/src/tests/fixtures/interfaces/ImplementsMultipleInterfaces.ts.expected.md new file mode 100644 index 00000000..6db7a2f6 --- /dev/null +++ b/src/tests/fixtures/interfaces/ImplementsMultipleInterfaces.ts.expected.md @@ -0,0 +1,110 @@ +## input + +```ts title="interfaces/ImplementsMultipleInterfaces.ts" +/** @gqlType */ +export default class SomeType { + /** @gqlField */ + me(): User { + return new User(); + } +} + +/** @gqlInterface */ +interface Person { + /** @gqlField */ + name: string; +} + +/** @gqlInterface */ +interface Actor { + /** @gqlField */ + name: string; +} + +/** @gqlType */ +class User implements Person, Actor { + __typename = "User" as const; + /** @gqlField */ + name: string; +} +``` + +## Output + +### SDL + +```graphql +interface Actor { + name: String +} + +interface Person { + name: String +} + +type SomeType { + me: User +} + +type User implements Actor & Person { + name: String +} +``` + +### TypeScript + +```ts +import { GraphQLSchema, GraphQLInterfaceType, GraphQLString, GraphQLObjectType } from "graphql"; +export function getSchema(): GraphQLSchema { + const ActorType: GraphQLInterfaceType = new GraphQLInterfaceType({ + name: "Actor", + fields() { + return { + name: { + name: "name", + type: GraphQLString + } + }; + } + }); + const PersonType: GraphQLInterfaceType = new GraphQLInterfaceType({ + name: "Person", + fields() { + return { + name: { + name: "name", + type: GraphQLString + } + }; + } + }); + const UserType: GraphQLObjectType = new GraphQLObjectType({ + name: "User", + fields() { + return { + name: { + name: "name", + type: GraphQLString + } + }; + }, + interfaces() { + return [ActorType, PersonType]; + } + }); + const SomeTypeType: GraphQLObjectType = new GraphQLObjectType({ + name: "SomeType", + fields() { + return { + me: { + name: "me", + type: UserType + } + }; + } + }); + return new GraphQLSchema({ + types: [ActorType, PersonType, SomeTypeType, UserType] + }); +} +``` \ No newline at end of file diff --git a/src/tests/fixtures/interfaces/ImplementsRenamedInterface.ts.expected b/src/tests/fixtures/interfaces/ImplementsRenamedInterface.ts.expected deleted file mode 100644 index 16852311..00000000 --- a/src/tests/fixtures/interfaces/ImplementsRenamedInterface.ts.expected +++ /dev/null @@ -1,59 +0,0 @@ ------------------ -INPUT ------------------ -/** @gqlInterface Person */ -interface DONT_USE_THIS { - /** @gqlField */ - name: string; -} - -/** @gqlType */ -class User implements DONT_USE_THIS { - __typename = "User" as const; - /** @gqlField */ - name: string; -} - ------------------ -OUTPUT ------------------ --- SDL -- -interface Person { - name: String -} - -type User implements Person { - name: String -} --- TypeScript -- -import { GraphQLSchema, GraphQLInterfaceType, GraphQLString, GraphQLObjectType } from "graphql"; -export function getSchema(): GraphQLSchema { - const PersonType: GraphQLInterfaceType = new GraphQLInterfaceType({ - name: "Person", - fields() { - return { - name: { - name: "name", - type: GraphQLString - } - }; - } - }); - const UserType: GraphQLObjectType = new GraphQLObjectType({ - name: "User", - fields() { - return { - name: { - name: "name", - type: GraphQLString - } - }; - }, - interfaces() { - return [PersonType]; - } - }); - return new GraphQLSchema({ - types: [PersonType, UserType] - }); -} diff --git a/src/tests/fixtures/interfaces/ImplementsRenamedInterface.ts.expected.md b/src/tests/fixtures/interfaces/ImplementsRenamedInterface.ts.expected.md new file mode 100644 index 00000000..7846739c --- /dev/null +++ b/src/tests/fixtures/interfaces/ImplementsRenamedInterface.ts.expected.md @@ -0,0 +1,66 @@ +## input + +```ts title="interfaces/ImplementsRenamedInterface.ts" +/** @gqlInterface Person */ +interface DONT_USE_THIS { + /** @gqlField */ + name: string; +} + +/** @gqlType */ +class User implements DONT_USE_THIS { + __typename = "User" as const; + /** @gqlField */ + name: string; +} +``` + +## Output + +### SDL + +```graphql +interface Person { + name: String +} + +type User implements Person { + name: String +} +``` + +### TypeScript + +```ts +import { GraphQLSchema, GraphQLInterfaceType, GraphQLString, GraphQLObjectType } from "graphql"; +export function getSchema(): GraphQLSchema { + const PersonType: GraphQLInterfaceType = new GraphQLInterfaceType({ + name: "Person", + fields() { + return { + name: { + name: "name", + type: GraphQLString + } + }; + } + }); + const UserType: GraphQLObjectType = new GraphQLObjectType({ + name: "User", + fields() { + return { + name: { + name: "name", + type: GraphQLString + } + }; + }, + interfaces() { + return [PersonType]; + } + }); + return new GraphQLSchema({ + types: [PersonType, UserType] + }); +} +``` \ No newline at end of file diff --git a/src/tests/fixtures/interfaces/InterfaceDefinitionExtendsGqlInterface.ts.expected b/src/tests/fixtures/interfaces/InterfaceDefinitionExtendsGqlInterface.ts.expected deleted file mode 100644 index e77999fa..00000000 --- a/src/tests/fixtures/interfaces/InterfaceDefinitionExtendsGqlInterface.ts.expected +++ /dev/null @@ -1,102 +0,0 @@ ------------------ -INPUT ------------------ -import { Int } from "../../../Types"; - -/** @gqlInterface */ -interface Mammal { - /** @gqlField */ - legs: Int; -} - -/** @gqlInterface */ -export interface Person extends Mammal { - /** @gqlField */ - name: string; - - /** @gqlField */ - legs: Int; -} - -/** @gqlInterface */ -export interface User extends Mammal, Person { - __typename: "User"; - - /** @gqlField */ - name: string; - - /** @gqlField */ - legs: Int; -} - ------------------ -OUTPUT ------------------ --- SDL -- -interface Mammal { - legs: Int -} - -interface Person implements Mammal { - legs: Int - name: String -} - -interface User implements Mammal & Person { - legs: Int - name: String -} --- TypeScript -- -import { GraphQLSchema, GraphQLInterfaceType, GraphQLInt, GraphQLString } from "graphql"; -export function getSchema(): GraphQLSchema { - const MammalType: GraphQLInterfaceType = new GraphQLInterfaceType({ - name: "Mammal", - fields() { - return { - legs: { - name: "legs", - type: GraphQLInt - } - }; - } - }); - const PersonType: GraphQLInterfaceType = new GraphQLInterfaceType({ - name: "Person", - fields() { - return { - legs: { - name: "legs", - type: GraphQLInt - }, - name: { - name: "name", - type: GraphQLString - } - }; - }, - interfaces() { - return [MammalType]; - } - }); - const UserType: GraphQLInterfaceType = new GraphQLInterfaceType({ - name: "User", - fields() { - return { - legs: { - name: "legs", - type: GraphQLInt - }, - name: { - name: "name", - type: GraphQLString - } - }; - }, - interfaces() { - return [MammalType, PersonType]; - } - }); - return new GraphQLSchema({ - types: [MammalType, PersonType, UserType] - }); -} diff --git a/src/tests/fixtures/interfaces/InterfaceDefinitionExtendsGqlInterface.ts.expected.md b/src/tests/fixtures/interfaces/InterfaceDefinitionExtendsGqlInterface.ts.expected.md new file mode 100644 index 00000000..b047c3ef --- /dev/null +++ b/src/tests/fixtures/interfaces/InterfaceDefinitionExtendsGqlInterface.ts.expected.md @@ -0,0 +1,109 @@ +## input + +```ts title="interfaces/InterfaceDefinitionExtendsGqlInterface.ts" +import { Int } from "../../../Types"; + +/** @gqlInterface */ +interface Mammal { + /** @gqlField */ + legs: Int; +} + +/** @gqlInterface */ +export interface Person extends Mammal { + /** @gqlField */ + name: string; + + /** @gqlField */ + legs: Int; +} + +/** @gqlInterface */ +export interface User extends Mammal, Person { + __typename: "User"; + + /** @gqlField */ + name: string; + + /** @gqlField */ + legs: Int; +} +``` + +## Output + +### SDL + +```graphql +interface Mammal { + legs: Int +} + +interface Person implements Mammal { + legs: Int + name: String +} + +interface User implements Mammal & Person { + legs: Int + name: String +} +``` + +### TypeScript + +```ts +import { GraphQLSchema, GraphQLInterfaceType, GraphQLInt, GraphQLString } from "graphql"; +export function getSchema(): GraphQLSchema { + const MammalType: GraphQLInterfaceType = new GraphQLInterfaceType({ + name: "Mammal", + fields() { + return { + legs: { + name: "legs", + type: GraphQLInt + } + }; + } + }); + const PersonType: GraphQLInterfaceType = new GraphQLInterfaceType({ + name: "Person", + fields() { + return { + legs: { + name: "legs", + type: GraphQLInt + }, + name: { + name: "name", + type: GraphQLString + } + }; + }, + interfaces() { + return [MammalType]; + } + }); + const UserType: GraphQLInterfaceType = new GraphQLInterfaceType({ + name: "User", + fields() { + return { + legs: { + name: "legs", + type: GraphQLInt + }, + name: { + name: "name", + type: GraphQLString + } + }; + }, + interfaces() { + return [MammalType, PersonType]; + } + }); + return new GraphQLSchema({ + types: [MammalType, PersonType, UserType] + }); +} +``` \ No newline at end of file diff --git a/src/tests/fixtures/interfaces/InterfaceExtendsInterface.ts.expected b/src/tests/fixtures/interfaces/InterfaceExtendsInterface.ts.expected deleted file mode 100644 index f722ceb9..00000000 --- a/src/tests/fixtures/interfaces/InterfaceExtendsInterface.ts.expected +++ /dev/null @@ -1,86 +0,0 @@ ------------------ -INPUT ------------------ -/** @gqlInterface Node */ -interface GqlNode { - /** @gqlField */ - id: string; -} - -/** @gqlInterface */ -interface Person { - /** @gqlField */ - name: string; -} - -/** @gqlInterface */ -interface Actor extends GqlNode, Person { - /** @gqlField */ - id: string; - /** @gqlField */ - name: string; -} - ------------------ -OUTPUT ------------------ --- SDL -- -interface Actor implements Node & Person { - id: String - name: String -} - -interface Node { - id: String -} - -interface Person { - name: String -} --- TypeScript -- -import { GraphQLSchema, GraphQLInterfaceType, GraphQLString } from "graphql"; -export function getSchema(): GraphQLSchema { - const NodeType: GraphQLInterfaceType = new GraphQLInterfaceType({ - name: "Node", - fields() { - return { - id: { - name: "id", - type: GraphQLString - } - }; - } - }); - const PersonType: GraphQLInterfaceType = new GraphQLInterfaceType({ - name: "Person", - fields() { - return { - name: { - name: "name", - type: GraphQLString - } - }; - } - }); - const ActorType: GraphQLInterfaceType = new GraphQLInterfaceType({ - name: "Actor", - fields() { - return { - id: { - name: "id", - type: GraphQLString - }, - name: { - name: "name", - type: GraphQLString - } - }; - }, - interfaces() { - return [NodeType, PersonType]; - } - }); - return new GraphQLSchema({ - types: [ActorType, NodeType, PersonType] - }); -} diff --git a/src/tests/fixtures/interfaces/InterfaceExtendsInterface.ts.expected.md b/src/tests/fixtures/interfaces/InterfaceExtendsInterface.ts.expected.md new file mode 100644 index 00000000..1cecc6eb --- /dev/null +++ b/src/tests/fixtures/interfaces/InterfaceExtendsInterface.ts.expected.md @@ -0,0 +1,93 @@ +## input + +```ts title="interfaces/InterfaceExtendsInterface.ts" +/** @gqlInterface Node */ +interface GqlNode { + /** @gqlField */ + id: string; +} + +/** @gqlInterface */ +interface Person { + /** @gqlField */ + name: string; +} + +/** @gqlInterface */ +interface Actor extends GqlNode, Person { + /** @gqlField */ + id: string; + /** @gqlField */ + name: string; +} +``` + +## Output + +### SDL + +```graphql +interface Actor implements Node & Person { + id: String + name: String +} + +interface Node { + id: String +} + +interface Person { + name: String +} +``` + +### TypeScript + +```ts +import { GraphQLSchema, GraphQLInterfaceType, GraphQLString } from "graphql"; +export function getSchema(): GraphQLSchema { + const NodeType: GraphQLInterfaceType = new GraphQLInterfaceType({ + name: "Node", + fields() { + return { + id: { + name: "id", + type: GraphQLString + } + }; + } + }); + const PersonType: GraphQLInterfaceType = new GraphQLInterfaceType({ + name: "Person", + fields() { + return { + name: { + name: "name", + type: GraphQLString + } + }; + } + }); + const ActorType: GraphQLInterfaceType = new GraphQLInterfaceType({ + name: "Actor", + fields() { + return { + id: { + name: "id", + type: GraphQLString + }, + name: { + name: "name", + type: GraphQLString + } + }; + }, + interfaces() { + return [NodeType, PersonType]; + } + }); + return new GraphQLSchema({ + types: [ActorType, NodeType, PersonType] + }); +} +``` \ No newline at end of file diff --git a/src/tests/fixtures/interfaces/InterfaceFieldWithDescription.ts.expected b/src/tests/fixtures/interfaces/InterfaceFieldWithDescription.ts.expected deleted file mode 100644 index 483159d3..00000000 --- a/src/tests/fixtures/interfaces/InterfaceFieldWithDescription.ts.expected +++ /dev/null @@ -1,87 +0,0 @@ ------------------ -INPUT ------------------ -/** @gqlType */ -export default class SomeType { - /** @gqlField */ - me(): User { - return new User(); - } -} - -/** @gqlInterface */ -interface IPerson { - /** - * The person's name - * @gqlField - */ - name: string; -} - -/** @gqlType */ -class User implements IPerson { - __typename = "User" as const; - /** @gqlField */ - name: string; -} - ------------------ -OUTPUT ------------------ --- SDL -- -interface IPerson { - """The person's name""" - name: String -} - -type SomeType { - me: User -} - -type User implements IPerson { - name: String -} --- TypeScript -- -import { GraphQLSchema, GraphQLInterfaceType, GraphQLString, GraphQLObjectType } from "graphql"; -export function getSchema(): GraphQLSchema { - const IPersonType: GraphQLInterfaceType = new GraphQLInterfaceType({ - name: "IPerson", - fields() { - return { - name: { - description: "The person's name", - name: "name", - type: GraphQLString - } - }; - } - }); - const UserType: GraphQLObjectType = new GraphQLObjectType({ - name: "User", - fields() { - return { - name: { - name: "name", - type: GraphQLString - } - }; - }, - interfaces() { - return [IPersonType]; - } - }); - const SomeTypeType: GraphQLObjectType = new GraphQLObjectType({ - name: "SomeType", - fields() { - return { - me: { - name: "me", - type: UserType - } - }; - } - }); - return new GraphQLSchema({ - types: [IPersonType, SomeTypeType, UserType] - }); -} diff --git a/src/tests/fixtures/interfaces/InterfaceFieldWithDescription.ts.expected.md b/src/tests/fixtures/interfaces/InterfaceFieldWithDescription.ts.expected.md new file mode 100644 index 00000000..4c299655 --- /dev/null +++ b/src/tests/fixtures/interfaces/InterfaceFieldWithDescription.ts.expected.md @@ -0,0 +1,94 @@ +## input + +```ts title="interfaces/InterfaceFieldWithDescription.ts" +/** @gqlType */ +export default class SomeType { + /** @gqlField */ + me(): User { + return new User(); + } +} + +/** @gqlInterface */ +interface IPerson { + /** + * The person's name + * @gqlField + */ + name: string; +} + +/** @gqlType */ +class User implements IPerson { + __typename = "User" as const; + /** @gqlField */ + name: string; +} +``` + +## Output + +### SDL + +```graphql +interface IPerson { + """The person's name""" + name: String +} + +type SomeType { + me: User +} + +type User implements IPerson { + name: String +} +``` + +### TypeScript + +```ts +import { GraphQLSchema, GraphQLInterfaceType, GraphQLString, GraphQLObjectType } from "graphql"; +export function getSchema(): GraphQLSchema { + const IPersonType: GraphQLInterfaceType = new GraphQLInterfaceType({ + name: "IPerson", + fields() { + return { + name: { + description: "The person's name", + name: "name", + type: GraphQLString + } + }; + } + }); + const UserType: GraphQLObjectType = new GraphQLObjectType({ + name: "User", + fields() { + return { + name: { + name: "name", + type: GraphQLString + } + }; + }, + interfaces() { + return [IPersonType]; + } + }); + const SomeTypeType: GraphQLObjectType = new GraphQLObjectType({ + name: "SomeType", + fields() { + return { + me: { + name: "me", + type: UserType + } + }; + } + }); + return new GraphQLSchema({ + types: [IPersonType, SomeTypeType, UserType] + }); +} +``` \ No newline at end of file diff --git a/src/tests/fixtures/interfaces/InterfaceFieldWithDescriptionThatDiffersFromType.ts.expected b/src/tests/fixtures/interfaces/InterfaceFieldWithDescriptionThatDiffersFromType.ts.expected deleted file mode 100644 index 69795873..00000000 --- a/src/tests/fixtures/interfaces/InterfaceFieldWithDescriptionThatDiffersFromType.ts.expected +++ /dev/null @@ -1,92 +0,0 @@ ------------------ -INPUT ------------------ -/** @gqlType */ -export default class SomeType { - /** @gqlField */ - me(): User { - return new User(); - } -} - -/** @gqlInterface */ -interface IPerson { - /** - * The person's name - * @gqlField - */ - name: string; -} - -/** @gqlType */ -class User implements IPerson { - __typename = "User" as const; - /** - * The user's name - * @gqlField - */ - name: string; -} - ------------------ -OUTPUT ------------------ --- SDL -- -interface IPerson { - """The person's name""" - name: String -} - -type SomeType { - me: User -} - -type User implements IPerson { - """The user's name""" - name: String -} --- TypeScript -- -import { GraphQLSchema, GraphQLInterfaceType, GraphQLString, GraphQLObjectType } from "graphql"; -export function getSchema(): GraphQLSchema { - const IPersonType: GraphQLInterfaceType = new GraphQLInterfaceType({ - name: "IPerson", - fields() { - return { - name: { - description: "The person's name", - name: "name", - type: GraphQLString - } - }; - } - }); - const UserType: GraphQLObjectType = new GraphQLObjectType({ - name: "User", - fields() { - return { - name: { - description: "The user's name", - name: "name", - type: GraphQLString - } - }; - }, - interfaces() { - return [IPersonType]; - } - }); - const SomeTypeType: GraphQLObjectType = new GraphQLObjectType({ - name: "SomeType", - fields() { - return { - me: { - name: "me", - type: UserType - } - }; - } - }); - return new GraphQLSchema({ - types: [IPersonType, SomeTypeType, UserType] - }); -} diff --git a/src/tests/fixtures/interfaces/InterfaceFieldWithDescriptionThatDiffersFromType.ts.expected.md b/src/tests/fixtures/interfaces/InterfaceFieldWithDescriptionThatDiffersFromType.ts.expected.md new file mode 100644 index 00000000..3fda2068 --- /dev/null +++ b/src/tests/fixtures/interfaces/InterfaceFieldWithDescriptionThatDiffersFromType.ts.expected.md @@ -0,0 +1,99 @@ +## input + +```ts title="interfaces/InterfaceFieldWithDescriptionThatDiffersFromType.ts" +/** @gqlType */ +export default class SomeType { + /** @gqlField */ + me(): User { + return new User(); + } +} + +/** @gqlInterface */ +interface IPerson { + /** + * The person's name + * @gqlField + */ + name: string; +} + +/** @gqlType */ +class User implements IPerson { + __typename = "User" as const; + /** + * The user's name + * @gqlField + */ + name: string; +} +``` + +## Output + +### SDL + +```graphql +interface IPerson { + """The person's name""" + name: String +} + +type SomeType { + me: User +} + +type User implements IPerson { + """The user's name""" + name: String +} +``` + +### TypeScript + +```ts +import { GraphQLSchema, GraphQLInterfaceType, GraphQLString, GraphQLObjectType } from "graphql"; +export function getSchema(): GraphQLSchema { + const IPersonType: GraphQLInterfaceType = new GraphQLInterfaceType({ + name: "IPerson", + fields() { + return { + name: { + description: "The person's name", + name: "name", + type: GraphQLString + } + }; + } + }); + const UserType: GraphQLObjectType = new GraphQLObjectType({ + name: "User", + fields() { + return { + name: { + description: "The user's name", + name: "name", + type: GraphQLString + } + }; + }, + interfaces() { + return [IPersonType]; + } + }); + const SomeTypeType: GraphQLObjectType = new GraphQLObjectType({ + name: "SomeType", + fields() { + return { + me: { + name: "me", + type: UserType + } + }; + } + }); + return new GraphQLSchema({ + types: [IPersonType, SomeTypeType, UserType] + }); +} +``` \ No newline at end of file diff --git a/src/tests/fixtures/interfaces/InterfaceImplementsInterface.ts.expected b/src/tests/fixtures/interfaces/InterfaceImplementsInterface.ts.expected deleted file mode 100644 index f722ceb9..00000000 --- a/src/tests/fixtures/interfaces/InterfaceImplementsInterface.ts.expected +++ /dev/null @@ -1,86 +0,0 @@ ------------------ -INPUT ------------------ -/** @gqlInterface Node */ -interface GqlNode { - /** @gqlField */ - id: string; -} - -/** @gqlInterface */ -interface Person { - /** @gqlField */ - name: string; -} - -/** @gqlInterface */ -interface Actor extends GqlNode, Person { - /** @gqlField */ - id: string; - /** @gqlField */ - name: string; -} - ------------------ -OUTPUT ------------------ --- SDL -- -interface Actor implements Node & Person { - id: String - name: String -} - -interface Node { - id: String -} - -interface Person { - name: String -} --- TypeScript -- -import { GraphQLSchema, GraphQLInterfaceType, GraphQLString } from "graphql"; -export function getSchema(): GraphQLSchema { - const NodeType: GraphQLInterfaceType = new GraphQLInterfaceType({ - name: "Node", - fields() { - return { - id: { - name: "id", - type: GraphQLString - } - }; - } - }); - const PersonType: GraphQLInterfaceType = new GraphQLInterfaceType({ - name: "Person", - fields() { - return { - name: { - name: "name", - type: GraphQLString - } - }; - } - }); - const ActorType: GraphQLInterfaceType = new GraphQLInterfaceType({ - name: "Actor", - fields() { - return { - id: { - name: "id", - type: GraphQLString - }, - name: { - name: "name", - type: GraphQLString - } - }; - }, - interfaces() { - return [NodeType, PersonType]; - } - }); - return new GraphQLSchema({ - types: [ActorType, NodeType, PersonType] - }); -} diff --git a/src/tests/fixtures/interfaces/InterfaceImplementsInterface.ts.expected.md b/src/tests/fixtures/interfaces/InterfaceImplementsInterface.ts.expected.md new file mode 100644 index 00000000..de1a1768 --- /dev/null +++ b/src/tests/fixtures/interfaces/InterfaceImplementsInterface.ts.expected.md @@ -0,0 +1,93 @@ +## input + +```ts title="interfaces/InterfaceImplementsInterface.ts" +/** @gqlInterface Node */ +interface GqlNode { + /** @gqlField */ + id: string; +} + +/** @gqlInterface */ +interface Person { + /** @gqlField */ + name: string; +} + +/** @gqlInterface */ +interface Actor extends GqlNode, Person { + /** @gqlField */ + id: string; + /** @gqlField */ + name: string; +} +``` + +## Output + +### SDL + +```graphql +interface Actor implements Node & Person { + id: String + name: String +} + +interface Node { + id: String +} + +interface Person { + name: String +} +``` + +### TypeScript + +```ts +import { GraphQLSchema, GraphQLInterfaceType, GraphQLString } from "graphql"; +export function getSchema(): GraphQLSchema { + const NodeType: GraphQLInterfaceType = new GraphQLInterfaceType({ + name: "Node", + fields() { + return { + id: { + name: "id", + type: GraphQLString + } + }; + } + }); + const PersonType: GraphQLInterfaceType = new GraphQLInterfaceType({ + name: "Person", + fields() { + return { + name: { + name: "name", + type: GraphQLString + } + }; + } + }); + const ActorType: GraphQLInterfaceType = new GraphQLInterfaceType({ + name: "Actor", + fields() { + return { + id: { + name: "id", + type: GraphQLString + }, + name: { + name: "name", + type: GraphQLString + } + }; + }, + interfaces() { + return [NodeType, PersonType]; + } + }); + return new GraphQLSchema({ + types: [ActorType, NodeType, PersonType] + }); +} +``` \ No newline at end of file diff --git a/src/tests/fixtures/interfaces/InterfaceMergedIntoClass.invalid.ts.expected b/src/tests/fixtures/interfaces/InterfaceMergedIntoClass.invalid.ts.expected deleted file mode 100644 index 6b4e9339..00000000 --- a/src/tests/fixtures/interfaces/InterfaceMergedIntoClass.invalid.ts.expected +++ /dev/null @@ -1,27 +0,0 @@ ------------------ -INPUT ------------------ -class Foo { - someField: number; -} - -/** @gqlInterface */ -interface Foo { - /** @gqlField */ - id: string; -} - ------------------ -OUTPUT ------------------ -src/tests/fixtures/interfaces/InterfaceMergedIntoClass.invalid.ts:6:11 - error: Unexpected merged interface. If an interface is declared multiple times in a scope, TypeScript merges them. To avoid ambiguity Grats does not support using merged interfaces as GraphQL definitions. Consider using a unique name for your TypeScript interface and renaming it. - - Learn more: https://grats.capt.dev/docs/docblock-tags/interfaces/#merged-interfaces - -6 interface Foo { - ~~~ - - src/tests/fixtures/interfaces/InterfaceMergedIntoClass.invalid.ts:1:7 - 1 class Foo { - ~~~ - Other declaration diff --git a/src/tests/fixtures/interfaces/InterfaceMergedIntoClass.invalid.ts.expected.md b/src/tests/fixtures/interfaces/InterfaceMergedIntoClass.invalid.ts.expected.md new file mode 100644 index 00000000..0eea4599 --- /dev/null +++ b/src/tests/fixtures/interfaces/InterfaceMergedIntoClass.invalid.ts.expected.md @@ -0,0 +1,31 @@ +## input + +```ts title="interfaces/InterfaceMergedIntoClass.invalid.ts" +class Foo { + someField: number; +} + +/** @gqlInterface */ +interface Foo { + /** @gqlField */ + id: string; +} +``` + +## Output + +### Error Report + +```text +src/tests/fixtures/interfaces/InterfaceMergedIntoClass.invalid.ts:6:11 - error: Unexpected merged interface. If an interface is declared multiple times in a scope, TypeScript merges them. To avoid ambiguity Grats does not support using merged interfaces as GraphQL definitions. Consider using a unique name for your TypeScript interface and renaming it. + + Learn more: https://grats.capt.dev/docs/docblock-tags/interfaces/#merged-interfaces + +6 interface Foo { + ~~~ + + src/tests/fixtures/interfaces/InterfaceMergedIntoClass.invalid.ts:1:7 + 1 class Foo { + ~~~ + Other declaration +``` \ No newline at end of file diff --git a/src/tests/fixtures/interfaces/InterfaceMergedIntoNode.invalid.ts.expected b/src/tests/fixtures/interfaces/InterfaceMergedIntoNode.invalid.ts.expected deleted file mode 100644 index 74250ec3..00000000 --- a/src/tests/fixtures/interfaces/InterfaceMergedIntoNode.invalid.ts.expected +++ /dev/null @@ -1,25 +0,0 @@ ------------------ -INPUT ------------------ -// { "tsVersion": "5.0.2" } -// Note: Node is a built in class. -/** @gqlInterface */ -interface Node { - /** @gqlField */ - id: string; -} - ------------------ -OUTPUT ------------------ -src/tests/fixtures/interfaces/InterfaceMergedIntoNode.invalid.ts:4:11 - error: Unexpected merged interface. If an interface is declared multiple times in a scope, TypeScript merges them. To avoid ambiguity Grats does not support using merged interfaces as GraphQL definitions. Consider using a unique name for your TypeScript interface and renaming it. - - Learn more: https://grats.capt.dev/docs/docblock-tags/interfaces/#merged-interfaces - -4 interface Node { - ~~~~ - - node_modules/.pnpm/typescript@5.0.2/node_modules/typescript/lib/lib.dom.d.ts:10247:11 - 10247 interface Node extends EventTarget { - ~~~~ - Other declaration diff --git a/src/tests/fixtures/interfaces/InterfaceMergedIntoNode.invalid.ts.expected.md b/src/tests/fixtures/interfaces/InterfaceMergedIntoNode.invalid.ts.expected.md new file mode 100644 index 00000000..e69de29b diff --git a/src/tests/fixtures/interfaces/InterfaceMergedIntoObject.ts.expected b/src/tests/fixtures/interfaces/InterfaceMergedIntoObject.ts.expected deleted file mode 100644 index cfc984d8..00000000 --- a/src/tests/fixtures/interfaces/InterfaceMergedIntoObject.ts.expected +++ /dev/null @@ -1,39 +0,0 @@ ------------------ -INPUT ------------------ -declare const Foo: { - prototype: Foo; - new (): Foo; -}; - -/** @gqlInterface */ -interface Foo { - /** @gqlField */ - id: string; -} - ------------------ -OUTPUT ------------------ --- SDL -- -interface Foo { - id: String -} --- TypeScript -- -import { GraphQLSchema, GraphQLInterfaceType, GraphQLString } from "graphql"; -export function getSchema(): GraphQLSchema { - const FooType: GraphQLInterfaceType = new GraphQLInterfaceType({ - name: "Foo", - fields() { - return { - id: { - name: "id", - type: GraphQLString - } - }; - } - }); - return new GraphQLSchema({ - types: [FooType] - }); -} diff --git a/src/tests/fixtures/interfaces/InterfaceMergedIntoObject.ts.expected.md b/src/tests/fixtures/interfaces/InterfaceMergedIntoObject.ts.expected.md new file mode 100644 index 00000000..84aaa1c6 --- /dev/null +++ b/src/tests/fixtures/interfaces/InterfaceMergedIntoObject.ts.expected.md @@ -0,0 +1,46 @@ +## input + +```ts title="interfaces/InterfaceMergedIntoObject.ts" +declare const Foo: { + prototype: Foo; + new (): Foo; +}; + +/** @gqlInterface */ +interface Foo { + /** @gqlField */ + id: string; +} +``` + +## Output + +### SDL + +```graphql +interface Foo { + id: String +} +``` + +### TypeScript + +```ts +import { GraphQLSchema, GraphQLInterfaceType, GraphQLString } from "graphql"; +export function getSchema(): GraphQLSchema { + const FooType: GraphQLInterfaceType = new GraphQLInterfaceType({ + name: "Foo", + fields() { + return { + id: { + name: "id", + type: GraphQLString + } + }; + } + }); + return new GraphQLSchema({ + types: [FooType] + }); +} +``` \ No newline at end of file diff --git a/src/tests/fixtures/interfaces/InterfaceMissingFields.invalid.ts.expected b/src/tests/fixtures/interfaces/InterfaceMissingFields.invalid.ts.expected deleted file mode 100644 index e2528f06..00000000 --- a/src/tests/fixtures/interfaces/InterfaceMissingFields.invalid.ts.expected +++ /dev/null @@ -1,15 +0,0 @@ ------------------ -INPUT ------------------ -/** @gqlInterface */ -interface SomeType {} - ------------------ -OUTPUT ------------------ -src/tests/fixtures/interfaces/InterfaceMissingFields.invalid.ts:2:11 - error: Interface `SomeType` must define one or more fields. - -Define a field by adding `/** @gqlField */` above a field, property, attribute or method of this type, or above a function that has `SomeType` as its first argument. - -2 interface SomeType {} - ~~~~~~~~ diff --git a/src/tests/fixtures/interfaces/InterfaceMissingFields.invalid.ts.expected.md b/src/tests/fixtures/interfaces/InterfaceMissingFields.invalid.ts.expected.md new file mode 100644 index 00000000..658c557b --- /dev/null +++ b/src/tests/fixtures/interfaces/InterfaceMissingFields.invalid.ts.expected.md @@ -0,0 +1,19 @@ +## input + +```ts title="interfaces/InterfaceMissingFields.invalid.ts" +/** @gqlInterface */ +interface SomeType {} +``` + +## Output + +### Error Report + +```text +src/tests/fixtures/interfaces/InterfaceMissingFields.invalid.ts:2:11 - error: Interface `SomeType` must define one or more fields. + +Define a field by adding `/** @gqlField */` above a field, property, attribute or method of this type, or above a function that has `SomeType` as its first argument. + +2 interface SomeType {} + ~~~~~~~~ +``` \ No newline at end of file diff --git a/src/tests/fixtures/interfaces/InterfaceWithCustomName.ts.expected b/src/tests/fixtures/interfaces/InterfaceWithCustomName.ts.expected deleted file mode 100644 index 8ad54388..00000000 --- a/src/tests/fixtures/interfaces/InterfaceWithCustomName.ts.expected +++ /dev/null @@ -1,82 +0,0 @@ ------------------ -INPUT ------------------ -/** @gqlType */ -export default class SomeType { - /** @gqlField */ - me(): User { - return new User(); - } -} - -/** @gqlInterface Person */ -interface IPerson { - /** @gqlField */ - name: string; -} - -/** @gqlType */ -class User implements IPerson { - __typename = "User" as const; - /** @gqlField */ - name: string; -} - ------------------ -OUTPUT ------------------ --- SDL -- -interface Person { - name: String -} - -type SomeType { - me: User -} - -type User implements Person { - name: String -} --- TypeScript -- -import { GraphQLSchema, GraphQLInterfaceType, GraphQLString, GraphQLObjectType } from "graphql"; -export function getSchema(): GraphQLSchema { - const PersonType: GraphQLInterfaceType = new GraphQLInterfaceType({ - name: "Person", - fields() { - return { - name: { - name: "name", - type: GraphQLString - } - }; - } - }); - const UserType: GraphQLObjectType = new GraphQLObjectType({ - name: "User", - fields() { - return { - name: { - name: "name", - type: GraphQLString - } - }; - }, - interfaces() { - return [PersonType]; - } - }); - const SomeTypeType: GraphQLObjectType = new GraphQLObjectType({ - name: "SomeType", - fields() { - return { - me: { - name: "me", - type: UserType - } - }; - } - }); - return new GraphQLSchema({ - types: [PersonType, SomeTypeType, UserType] - }); -} diff --git a/src/tests/fixtures/interfaces/InterfaceWithCustomName.ts.expected.md b/src/tests/fixtures/interfaces/InterfaceWithCustomName.ts.expected.md new file mode 100644 index 00000000..9c4d9420 --- /dev/null +++ b/src/tests/fixtures/interfaces/InterfaceWithCustomName.ts.expected.md @@ -0,0 +1,89 @@ +## input + +```ts title="interfaces/InterfaceWithCustomName.ts" +/** @gqlType */ +export default class SomeType { + /** @gqlField */ + me(): User { + return new User(); + } +} + +/** @gqlInterface Person */ +interface IPerson { + /** @gqlField */ + name: string; +} + +/** @gqlType */ +class User implements IPerson { + __typename = "User" as const; + /** @gqlField */ + name: string; +} +``` + +## Output + +### SDL + +```graphql +interface Person { + name: String +} + +type SomeType { + me: User +} + +type User implements Person { + name: String +} +``` + +### TypeScript + +```ts +import { GraphQLSchema, GraphQLInterfaceType, GraphQLString, GraphQLObjectType } from "graphql"; +export function getSchema(): GraphQLSchema { + const PersonType: GraphQLInterfaceType = new GraphQLInterfaceType({ + name: "Person", + fields() { + return { + name: { + name: "name", + type: GraphQLString + } + }; + } + }); + const UserType: GraphQLObjectType = new GraphQLObjectType({ + name: "User", + fields() { + return { + name: { + name: "name", + type: GraphQLString + } + }; + }, + interfaces() { + return [PersonType]; + } + }); + const SomeTypeType: GraphQLObjectType = new GraphQLObjectType({ + name: "SomeType", + fields() { + return { + me: { + name: "me", + type: UserType + } + }; + } + }); + return new GraphQLSchema({ + types: [PersonType, SomeTypeType, UserType] + }); +} +``` \ No newline at end of file diff --git a/src/tests/fixtures/interfaces/InterfaceWithDeprecatedField.ts.expected b/src/tests/fixtures/interfaces/InterfaceWithDeprecatedField.ts.expected deleted file mode 100644 index 57112ef7..00000000 --- a/src/tests/fixtures/interfaces/InterfaceWithDeprecatedField.ts.expected +++ /dev/null @@ -1,85 +0,0 @@ ------------------ -INPUT ------------------ -/** @gqlType */ -export default class SomeType { - /** @gqlField */ - me(): User { - return new User(); - } -} - -/** @gqlInterface */ -interface IPerson { - /** @gqlField - * @deprecated Not used anymore - */ - name?: string; -} - -/** @gqlType */ -class User implements IPerson { - __typename = "User" as const; - /** @gqlField */ - name?: string; -} - ------------------ -OUTPUT ------------------ --- SDL -- -interface IPerson { - name: String @deprecated(reason: "Not used anymore") -} - -type SomeType { - me: User -} - -type User implements IPerson { - name: String -} --- TypeScript -- -import { GraphQLSchema, GraphQLInterfaceType, GraphQLString, GraphQLObjectType } from "graphql"; -export function getSchema(): GraphQLSchema { - const IPersonType: GraphQLInterfaceType = new GraphQLInterfaceType({ - name: "IPerson", - fields() { - return { - name: { - deprecationReason: "Not used anymore", - name: "name", - type: GraphQLString - } - }; - } - }); - const UserType: GraphQLObjectType = new GraphQLObjectType({ - name: "User", - fields() { - return { - name: { - name: "name", - type: GraphQLString - } - }; - }, - interfaces() { - return [IPersonType]; - } - }); - const SomeTypeType: GraphQLObjectType = new GraphQLObjectType({ - name: "SomeType", - fields() { - return { - me: { - name: "me", - type: UserType - } - }; - } - }); - return new GraphQLSchema({ - types: [IPersonType, SomeTypeType, UserType] - }); -} diff --git a/src/tests/fixtures/interfaces/InterfaceWithDeprecatedField.ts.expected.md b/src/tests/fixtures/interfaces/InterfaceWithDeprecatedField.ts.expected.md new file mode 100644 index 00000000..296cf461 --- /dev/null +++ b/src/tests/fixtures/interfaces/InterfaceWithDeprecatedField.ts.expected.md @@ -0,0 +1,92 @@ +## input + +```ts title="interfaces/InterfaceWithDeprecatedField.ts" +/** @gqlType */ +export default class SomeType { + /** @gqlField */ + me(): User { + return new User(); + } +} + +/** @gqlInterface */ +interface IPerson { + /** @gqlField + * @deprecated Not used anymore + */ + name?: string; +} + +/** @gqlType */ +class User implements IPerson { + __typename = "User" as const; + /** @gqlField */ + name?: string; +} +``` + +## Output + +### SDL + +```graphql +interface IPerson { + name: String @deprecated(reason: "Not used anymore") +} + +type SomeType { + me: User +} + +type User implements IPerson { + name: String +} +``` + +### TypeScript + +```ts +import { GraphQLSchema, GraphQLInterfaceType, GraphQLString, GraphQLObjectType } from "graphql"; +export function getSchema(): GraphQLSchema { + const IPersonType: GraphQLInterfaceType = new GraphQLInterfaceType({ + name: "IPerson", + fields() { + return { + name: { + deprecationReason: "Not used anymore", + name: "name", + type: GraphQLString + } + }; + } + }); + const UserType: GraphQLObjectType = new GraphQLObjectType({ + name: "User", + fields() { + return { + name: { + name: "name", + type: GraphQLString + } + }; + }, + interfaces() { + return [IPersonType]; + } + }); + const SomeTypeType: GraphQLObjectType = new GraphQLObjectType({ + name: "SomeType", + fields() { + return { + me: { + name: "me", + type: UserType + } + }; + } + }); + return new GraphQLSchema({ + types: [IPersonType, SomeTypeType, UserType] + }); +} +``` \ No newline at end of file diff --git a/src/tests/fixtures/interfaces/InterfaceWithDescription.ts.expected b/src/tests/fixtures/interfaces/InterfaceWithDescription.ts.expected deleted file mode 100644 index 722d6717..00000000 --- a/src/tests/fixtures/interfaces/InterfaceWithDescription.ts.expected +++ /dev/null @@ -1,88 +0,0 @@ ------------------ -INPUT ------------------ -/** @gqlType */ -export default class SomeType { - /** @gqlField */ - me(): User { - return new User(); - } -} - -/** - * An interface describing the common elements of all people types. - * - * @gqlInterface - */ -interface IPerson { - /** @gqlField */ - name: string; -} - -/** @gqlType */ -class User implements IPerson { - __typename = "User" as const; - /** @gqlField */ - name: string; -} - ------------------ -OUTPUT ------------------ --- SDL -- -"""An interface describing the common elements of all people types.""" -interface IPerson { - name: String -} - -type SomeType { - me: User -} - -type User implements IPerson { - name: String -} --- TypeScript -- -import { GraphQLSchema, GraphQLInterfaceType, GraphQLString, GraphQLObjectType } from "graphql"; -export function getSchema(): GraphQLSchema { - const IPersonType: GraphQLInterfaceType = new GraphQLInterfaceType({ - description: "An interface describing the common elements of all people types.", - name: "IPerson", - fields() { - return { - name: { - name: "name", - type: GraphQLString - } - }; - } - }); - const UserType: GraphQLObjectType = new GraphQLObjectType({ - name: "User", - fields() { - return { - name: { - name: "name", - type: GraphQLString - } - }; - }, - interfaces() { - return [IPersonType]; - } - }); - const SomeTypeType: GraphQLObjectType = new GraphQLObjectType({ - name: "SomeType", - fields() { - return { - me: { - name: "me", - type: UserType - } - }; - } - }); - return new GraphQLSchema({ - types: [IPersonType, SomeTypeType, UserType] - }); -} diff --git a/src/tests/fixtures/interfaces/InterfaceWithDescription.ts.expected.md b/src/tests/fixtures/interfaces/InterfaceWithDescription.ts.expected.md new file mode 100644 index 00000000..a66b8584 --- /dev/null +++ b/src/tests/fixtures/interfaces/InterfaceWithDescription.ts.expected.md @@ -0,0 +1,95 @@ +## input + +```ts title="interfaces/InterfaceWithDescription.ts" +/** @gqlType */ +export default class SomeType { + /** @gqlField */ + me(): User { + return new User(); + } +} + +/** + * An interface describing the common elements of all people types. + * + * @gqlInterface + */ +interface IPerson { + /** @gqlField */ + name: string; +} + +/** @gqlType */ +class User implements IPerson { + __typename = "User" as const; + /** @gqlField */ + name: string; +} +``` + +## Output + +### SDL + +```graphql +"""An interface describing the common elements of all people types.""" +interface IPerson { + name: String +} + +type SomeType { + me: User +} + +type User implements IPerson { + name: String +} +``` + +### TypeScript + +```ts +import { GraphQLSchema, GraphQLInterfaceType, GraphQLString, GraphQLObjectType } from "graphql"; +export function getSchema(): GraphQLSchema { + const IPersonType: GraphQLInterfaceType = new GraphQLInterfaceType({ + description: "An interface describing the common elements of all people types.", + name: "IPerson", + fields() { + return { + name: { + name: "name", + type: GraphQLString + } + }; + } + }); + const UserType: GraphQLObjectType = new GraphQLObjectType({ + name: "User", + fields() { + return { + name: { + name: "name", + type: GraphQLString + } + }; + }, + interfaces() { + return [IPersonType]; + } + }); + const SomeTypeType: GraphQLObjectType = new GraphQLObjectType({ + name: "SomeType", + fields() { + return { + me: { + name: "me", + type: UserType + } + }; + } + }); + return new GraphQLSchema({ + types: [IPersonType, SomeTypeType, UserType] + }); +} +``` \ No newline at end of file diff --git a/src/tests/fixtures/interfaces/MergedInterfaces.invalid.ts.expected b/src/tests/fixtures/interfaces/MergedInterfaces.invalid.ts.expected deleted file mode 100644 index 7067e8bd..00000000 --- a/src/tests/fixtures/interfaces/MergedInterfaces.invalid.ts.expected +++ /dev/null @@ -1,37 +0,0 @@ ------------------ -INPUT ------------------ -import { ID } from "../../../types"; - -/** @gqlType */ -export default class SomeType { - /** @gqlField */ - me(): Node { - throw new Error("Not implemented"); - } -} - -interface Node { - id: ID; -} - -/** @gqlInterface */ -interface Node { - /** @gqlField */ - id: string; -} - ------------------ -OUTPUT ------------------ -src/tests/fixtures/interfaces/MergedInterfaces.invalid.ts:16:11 - error: Unexpected merged interface. If an interface is declared multiple times in a scope, TypeScript merges them. To avoid ambiguity Grats does not support using merged interfaces as GraphQL definitions. Consider using a unique name for your TypeScript interface and renaming it. - - Learn more: https://grats.capt.dev/docs/docblock-tags/interfaces/#merged-interfaces - -16 interface Node { - ~~~~ - - src/tests/fixtures/interfaces/MergedInterfaces.invalid.ts:11:11 - 11 interface Node { - ~~~~ - Other declaration diff --git a/src/tests/fixtures/interfaces/MergedInterfaces.invalid.ts.expected.md b/src/tests/fixtures/interfaces/MergedInterfaces.invalid.ts.expected.md new file mode 100644 index 00000000..b286e9cf --- /dev/null +++ b/src/tests/fixtures/interfaces/MergedInterfaces.invalid.ts.expected.md @@ -0,0 +1,41 @@ +## input + +```ts title="interfaces/MergedInterfaces.invalid.ts" +import { ID } from "../../../types"; + +/** @gqlType */ +export default class SomeType { + /** @gqlField */ + me(): Node { + throw new Error("Not implemented"); + } +} + +interface Node { + id: ID; +} + +/** @gqlInterface */ +interface Node { + /** @gqlField */ + id: string; +} +``` + +## Output + +### Error Report + +```text +src/tests/fixtures/interfaces/MergedInterfaces.invalid.ts:16:11 - error: Unexpected merged interface. If an interface is declared multiple times in a scope, TypeScript merges them. To avoid ambiguity Grats does not support using merged interfaces as GraphQL definitions. Consider using a unique name for your TypeScript interface and renaming it. + + Learn more: https://grats.capt.dev/docs/docblock-tags/interfaces/#merged-interfaces + +16 interface Node { + ~~~~ + + src/tests/fixtures/interfaces/MergedInterfaces.invalid.ts:11:11 + 11 interface Node { + ~~~~ + Other declaration +``` \ No newline at end of file diff --git a/src/tests/fixtures/interfaces/TagAttachedToWrongNode.invalid.ts.expected b/src/tests/fixtures/interfaces/TagAttachedToWrongNode.invalid.ts.expected deleted file mode 100644 index 6378717b..00000000 --- a/src/tests/fixtures/interfaces/TagAttachedToWrongNode.invalid.ts.expected +++ /dev/null @@ -1,13 +0,0 @@ ------------------ -INPUT ------------------ -/** @gqlInterface Person */ -function Foo() {} - ------------------ -OUTPUT ------------------ -src/tests/fixtures/interfaces/TagAttachedToWrongNode.invalid.ts:1:5 - error: `@gqlInterface` can only be used on interface declarations. e.g. `interface MyInterface {}` - -1 /** @gqlInterface Person */ - ~~~~~~~~~~~~~~~~~~~~~ diff --git a/src/tests/fixtures/interfaces/TagAttachedToWrongNode.invalid.ts.expected.md b/src/tests/fixtures/interfaces/TagAttachedToWrongNode.invalid.ts.expected.md new file mode 100644 index 00000000..558423eb --- /dev/null +++ b/src/tests/fixtures/interfaces/TagAttachedToWrongNode.invalid.ts.expected.md @@ -0,0 +1,17 @@ +## input + +```ts title="interfaces/TagAttachedToWrongNode.invalid.ts" +/** @gqlInterface Person */ +function Foo() {} +``` + +## Output + +### Error Report + +```text +src/tests/fixtures/interfaces/TagAttachedToWrongNode.invalid.ts:1:5 - error: `@gqlInterface` can only be used on interface declarations. e.g. `interface MyInterface {}` + +1 /** @gqlInterface Person */ + ~~~~~~~~~~~~~~~~~~~~~ +``` \ No newline at end of file diff --git a/src/tests/fixtures/interfaces/extendInterfaceWithNonGqlType.ts.expected b/src/tests/fixtures/interfaces/extendInterfaceWithNonGqlType.ts.expected deleted file mode 100644 index 60420596..00000000 --- a/src/tests/fixtures/interfaces/extendInterfaceWithNonGqlType.ts.expected +++ /dev/null @@ -1,40 +0,0 @@ ------------------ -INPUT ------------------ -interface IThing { - name: string; -} - -/** - * @gqlInterface - */ -export interface IPerson extends IThing { - /** @gqlField */ - name: string; -} - ------------------ -OUTPUT ------------------ --- SDL -- -interface IPerson { - name: String -} --- TypeScript -- -import { GraphQLSchema, GraphQLInterfaceType, GraphQLString } from "graphql"; -export function getSchema(): GraphQLSchema { - const IPersonType: GraphQLInterfaceType = new GraphQLInterfaceType({ - name: "IPerson", - fields() { - return { - name: { - name: "name", - type: GraphQLString - } - }; - } - }); - return new GraphQLSchema({ - types: [IPersonType] - }); -} diff --git a/src/tests/fixtures/interfaces/extendInterfaceWithNonGqlType.ts.expected.md b/src/tests/fixtures/interfaces/extendInterfaceWithNonGqlType.ts.expected.md new file mode 100644 index 00000000..92b534d7 --- /dev/null +++ b/src/tests/fixtures/interfaces/extendInterfaceWithNonGqlType.ts.expected.md @@ -0,0 +1,47 @@ +## input + +```ts title="interfaces/extendInterfaceWithNonGqlType.ts" +interface IThing { + name: string; +} + +/** + * @gqlInterface + */ +export interface IPerson extends IThing { + /** @gqlField */ + name: string; +} +``` + +## Output + +### SDL + +```graphql +interface IPerson { + name: String +} +``` + +### TypeScript + +```ts +import { GraphQLSchema, GraphQLInterfaceType, GraphQLString } from "graphql"; +export function getSchema(): GraphQLSchema { + const IPersonType: GraphQLInterfaceType = new GraphQLInterfaceType({ + name: "IPerson", + fields() { + return { + name: { + name: "name", + type: GraphQLString + } + }; + } + }); + return new GraphQLSchema({ + types: [IPersonType] + }); +} +``` \ No newline at end of file diff --git a/src/tests/fixtures/interfaces/tag/ImplementsTagWithoutTypeOrInterface.invalid.ts.expected b/src/tests/fixtures/interfaces/tag/ImplementsTagWithoutTypeOrInterface.invalid.ts.expected deleted file mode 100644 index ffb92716..00000000 --- a/src/tests/fixtures/interfaces/tag/ImplementsTagWithoutTypeOrInterface.invalid.ts.expected +++ /dev/null @@ -1,15 +0,0 @@ ------------------ -INPUT ------------------ -/** @gqlImplements Node */ -function hello() { - return "world"; -} - ------------------ -OUTPUT ------------------ -src/tests/fixtures/interfaces/tag/ImplementsTagWithoutTypeOrInterface.invalid.ts:1:6 - error: `@gqlImplements` has been deprecated. Instead use `class MyType implements MyInterface`. - -1 /** @gqlImplements Node */ - ~~~~~~~~~~~~~ diff --git a/src/tests/fixtures/interfaces/tag/ImplementsTagWithoutTypeOrInterface.invalid.ts.expected.md b/src/tests/fixtures/interfaces/tag/ImplementsTagWithoutTypeOrInterface.invalid.ts.expected.md new file mode 100644 index 00000000..0eaad207 --- /dev/null +++ b/src/tests/fixtures/interfaces/tag/ImplementsTagWithoutTypeOrInterface.invalid.ts.expected.md @@ -0,0 +1,19 @@ +## input + +```ts title="interfaces/tag/ImplementsTagWithoutTypeOrInterface.invalid.ts" +/** @gqlImplements Node */ +function hello() { + return "world"; +} +``` + +## Output + +### Error Report + +```text +src/tests/fixtures/interfaces/tag/ImplementsTagWithoutTypeOrInterface.invalid.ts:1:6 - error: `@gqlImplements` has been deprecated. Instead use `class MyType implements MyInterface`. + +1 /** @gqlImplements Node */ + ~~~~~~~~~~~~~ +``` \ No newline at end of file diff --git a/src/tests/fixtures/locate/fieldOnScalar.invalid.ts.expected b/src/tests/fixtures/locate/fieldOnScalar.invalid.ts.expected deleted file mode 100644 index d8472fa0..00000000 --- a/src/tests/fixtures/locate/fieldOnScalar.invalid.ts.expected +++ /dev/null @@ -1,11 +0,0 @@ ------------------ -INPUT ------------------ -// Locate: Date.name -/** @gqlScalar */ -export type Date = string; - ------------------ -OUTPUT ------------------ -Cannot locate field `name` on type `Date`. Only object types, interfaces, and input objects have fields. \ No newline at end of file diff --git a/src/tests/fixtures/locate/fieldOnScalar.invalid.ts.expected.md b/src/tests/fixtures/locate/fieldOnScalar.invalid.ts.expected.md new file mode 100644 index 00000000..5b40678b --- /dev/null +++ b/src/tests/fixtures/locate/fieldOnScalar.invalid.ts.expected.md @@ -0,0 +1,15 @@ +## input + +```ts title="locate/fieldOnScalar.invalid.ts" +// Locate: Date.name +/** @gqlScalar */ +export type Date = string; +``` + +## Output + +### Error Locating Type + +```text +Cannot locate field `name` on type `Date`. Only object types, interfaces, and input objects have fields. +``` \ No newline at end of file diff --git a/src/tests/fixtures/locate/genericType.invalid.ts.expected b/src/tests/fixtures/locate/genericType.invalid.ts.expected deleted file mode 100644 index 87383ae7..00000000 --- a/src/tests/fixtures/locate/genericType.invalid.ts.expected +++ /dev/null @@ -1,46 +0,0 @@ ------------------ -INPUT ------------------ -// Locate: PageEdge - -/** @gqlType */ -type Page = { - /** @gqlField */ - name: string; -}; - -/** @gqlType */ -type Edge = { - /** @gqlField */ - node: T; - /** @gqlField */ - cursor: string; -}; - -/** @gqlType */ -type PageConnection = { - /** @gqlField */ - edges: Edge[]; - /** @gqlField */ - pageInfo: PageInfo; -}; - -/** @gqlType */ -type PageInfo = { - /** @gqlField */ - hasNextPage: boolean; - /** @gqlField */ - hasPreviousPage: boolean; - /** @gqlField */ - startCursor: string; - /** @gqlField */ - endCursor: string; -}; - ------------------ -OUTPUT ------------------ -src/tests/fixtures/locate/genericType.invalid.ts:20:10 - error: Located here - -20 edges: Edge[]; - ~~~~~~~~~~ diff --git a/src/tests/fixtures/locate/genericType.invalid.ts.expected.md b/src/tests/fixtures/locate/genericType.invalid.ts.expected.md new file mode 100644 index 00000000..13c078a0 --- /dev/null +++ b/src/tests/fixtures/locate/genericType.invalid.ts.expected.md @@ -0,0 +1,50 @@ +## input + +```ts title="locate/genericType.invalid.ts" +// Locate: PageEdge + +/** @gqlType */ +type Page = { + /** @gqlField */ + name: string; +}; + +/** @gqlType */ +type Edge = { + /** @gqlField */ + node: T; + /** @gqlField */ + cursor: string; +}; + +/** @gqlType */ +type PageConnection = { + /** @gqlField */ + edges: Edge[]; + /** @gqlField */ + pageInfo: PageInfo; +}; + +/** @gqlType */ +type PageInfo = { + /** @gqlField */ + hasNextPage: boolean; + /** @gqlField */ + hasPreviousPage: boolean; + /** @gqlField */ + startCursor: string; + /** @gqlField */ + endCursor: string; +}; +``` + +## Output + +### Error Report + +```text +src/tests/fixtures/locate/genericType.invalid.ts:20:10 - error: Located here + +20 edges: Edge[]; + ~~~~~~~~~~ +``` \ No newline at end of file diff --git a/src/tests/fixtures/locate/genericTypeField.invalid.ts.expected b/src/tests/fixtures/locate/genericTypeField.invalid.ts.expected deleted file mode 100644 index 45b05e7d..00000000 --- a/src/tests/fixtures/locate/genericTypeField.invalid.ts.expected +++ /dev/null @@ -1,46 +0,0 @@ ------------------ -INPUT ------------------ -// Locate: PageEdge.cursor - -/** @gqlType */ -export type Page = { - /** @gqlField */ - name: string; -}; - -/** @gqlType */ -type Edge = { - /** @gqlField */ - node: T; - /** @gqlField */ - cursor: string; -}; - -/** @gqlType */ -type PageConnection = { - /** @gqlField */ - edges: Edge[]; - /** @gqlField */ - pageInfo: PageInfo; -}; - -/** @gqlType */ -type PageInfo = { - /** @gqlField */ - hasNextPage: boolean; - /** @gqlField */ - hasPreviousPage: boolean; - /** @gqlField */ - startCursor: string; - /** @gqlField */ - endCursor: string; -}; - ------------------ -OUTPUT ------------------ -src/tests/fixtures/locate/genericTypeField.invalid.ts:14:3 - error: Located here - -14 cursor: string; - ~~~~~~ diff --git a/src/tests/fixtures/locate/genericTypeField.invalid.ts.expected.md b/src/tests/fixtures/locate/genericTypeField.invalid.ts.expected.md new file mode 100644 index 00000000..68d77c0a --- /dev/null +++ b/src/tests/fixtures/locate/genericTypeField.invalid.ts.expected.md @@ -0,0 +1,50 @@ +## input + +```ts title="locate/genericTypeField.invalid.ts" +// Locate: PageEdge.cursor + +/** @gqlType */ +export type Page = { + /** @gqlField */ + name: string; +}; + +/** @gqlType */ +type Edge = { + /** @gqlField */ + node: T; + /** @gqlField */ + cursor: string; +}; + +/** @gqlType */ +type PageConnection = { + /** @gqlField */ + edges: Edge[]; + /** @gqlField */ + pageInfo: PageInfo; +}; + +/** @gqlType */ +type PageInfo = { + /** @gqlField */ + hasNextPage: boolean; + /** @gqlField */ + hasPreviousPage: boolean; + /** @gqlField */ + startCursor: string; + /** @gqlField */ + endCursor: string; +}; +``` + +## Output + +### Error Report + +```text +src/tests/fixtures/locate/genericTypeField.invalid.ts:14:3 - error: Located here + +14 cursor: string; + ~~~~~~ +``` \ No newline at end of file diff --git a/src/tests/fixtures/locate/inputType.invalid.ts.expected b/src/tests/fixtures/locate/inputType.invalid.ts.expected deleted file mode 100644 index 97eb034e..00000000 --- a/src/tests/fixtures/locate/inputType.invalid.ts.expected +++ /dev/null @@ -1,16 +0,0 @@ ------------------ -INPUT ------------------ -// Locate: User -/** @gqlInput */ -type User = { - name: string; -}; - ------------------ -OUTPUT ------------------ -src/tests/fixtures/locate/inputType.invalid.ts:3:6 - error: Located here - -3 type User = { - ~~~~ diff --git a/src/tests/fixtures/locate/inputType.invalid.ts.expected.md b/src/tests/fixtures/locate/inputType.invalid.ts.expected.md new file mode 100644 index 00000000..af6ff66e --- /dev/null +++ b/src/tests/fixtures/locate/inputType.invalid.ts.expected.md @@ -0,0 +1,20 @@ +## input + +```ts title="locate/inputType.invalid.ts" +// Locate: User +/** @gqlInput */ +type User = { + name: string; +}; +``` + +## Output + +### Error Report + +```text +src/tests/fixtures/locate/inputType.invalid.ts:3:6 - error: Located here + +3 type User = { + ~~~~ +``` \ No newline at end of file diff --git a/src/tests/fixtures/locate/inputTypeField.invalid.ts.expected b/src/tests/fixtures/locate/inputTypeField.invalid.ts.expected deleted file mode 100644 index 8ccd0d74..00000000 --- a/src/tests/fixtures/locate/inputTypeField.invalid.ts.expected +++ /dev/null @@ -1,16 +0,0 @@ ------------------ -INPUT ------------------ -// Locate: User.name -/** @gqlInput */ -type User = { - name: string; -}; - ------------------ -OUTPUT ------------------ -src/tests/fixtures/locate/inputTypeField.invalid.ts:4:3 - error: Located here - -4 name: string; - ~~~~ diff --git a/src/tests/fixtures/locate/inputTypeField.invalid.ts.expected.md b/src/tests/fixtures/locate/inputTypeField.invalid.ts.expected.md new file mode 100644 index 00000000..86ced5e6 --- /dev/null +++ b/src/tests/fixtures/locate/inputTypeField.invalid.ts.expected.md @@ -0,0 +1,20 @@ +## input + +```ts title="locate/inputTypeField.invalid.ts" +// Locate: User.name +/** @gqlInput */ +type User = { + name: string; +}; +``` + +## Output + +### Error Report + +```text +src/tests/fixtures/locate/inputTypeField.invalid.ts:4:3 - error: Located here + +4 name: string; + ~~~~ +``` \ No newline at end of file diff --git a/src/tests/fixtures/locate/interface.invalid.ts.expected b/src/tests/fixtures/locate/interface.invalid.ts.expected deleted file mode 100644 index 5df4b484..00000000 --- a/src/tests/fixtures/locate/interface.invalid.ts.expected +++ /dev/null @@ -1,17 +0,0 @@ ------------------ -INPUT ------------------ -// Locate: Person -/** @gqlInterface */ -interface Person { - /** @gqlField */ - name: string; -} - ------------------ -OUTPUT ------------------ -src/tests/fixtures/locate/interface.invalid.ts:3:11 - error: Located here - -3 interface Person { - ~~~~~~ diff --git a/src/tests/fixtures/locate/interface.invalid.ts.expected.md b/src/tests/fixtures/locate/interface.invalid.ts.expected.md new file mode 100644 index 00000000..ab1942a1 --- /dev/null +++ b/src/tests/fixtures/locate/interface.invalid.ts.expected.md @@ -0,0 +1,21 @@ +## input + +```ts title="locate/interface.invalid.ts" +// Locate: Person +/** @gqlInterface */ +interface Person { + /** @gqlField */ + name: string; +} +``` + +## Output + +### Error Report + +```text +src/tests/fixtures/locate/interface.invalid.ts:3:11 - error: Located here + +3 interface Person { + ~~~~~~ +``` \ No newline at end of file diff --git a/src/tests/fixtures/locate/malformedEntitySyntax.invalid.ts.expected b/src/tests/fixtures/locate/malformedEntitySyntax.invalid.ts.expected deleted file mode 100644 index 2606af41..00000000 --- a/src/tests/fixtures/locate/malformedEntitySyntax.invalid.ts.expected +++ /dev/null @@ -1,14 +0,0 @@ ------------------ -INPUT ------------------ -// Locate: User->name -/** @gqlType */ -type User = { - /** @gqlField */ - name: string; -}; - ------------------ -OUTPUT ------------------ -Invalid entity name: `User->name`. Expected `ParentType` or `ParentType.fieldName`. \ No newline at end of file diff --git a/src/tests/fixtures/locate/malformedEntitySyntax.invalid.ts.expected.md b/src/tests/fixtures/locate/malformedEntitySyntax.invalid.ts.expected.md new file mode 100644 index 00000000..717d1864 --- /dev/null +++ b/src/tests/fixtures/locate/malformedEntitySyntax.invalid.ts.expected.md @@ -0,0 +1,18 @@ +## input + +```ts title="locate/malformedEntitySyntax.invalid.ts" +// Locate: User->name +/** @gqlType */ +type User = { + /** @gqlField */ + name: string; +}; +``` + +## Output + +### Error Locating Type + +```text +Invalid entity name: `User->name`. Expected `ParentType` or `ParentType.fieldName`. +``` \ No newline at end of file diff --git a/src/tests/fixtures/locate/notFoundField.invalid.ts.expected b/src/tests/fixtures/locate/notFoundField.invalid.ts.expected deleted file mode 100644 index f5409c94..00000000 --- a/src/tests/fixtures/locate/notFoundField.invalid.ts.expected +++ /dev/null @@ -1,14 +0,0 @@ ------------------ -INPUT ------------------ -// Locate: User.not_a_field -/** @gqlType */ -type User = { - /** @gqlField */ - name: string; -}; - ------------------ -OUTPUT ------------------ -Cannot locate field `not_a_field` on type `User`. \ No newline at end of file diff --git a/src/tests/fixtures/locate/notFoundField.invalid.ts.expected.md b/src/tests/fixtures/locate/notFoundField.invalid.ts.expected.md new file mode 100644 index 00000000..048297d3 --- /dev/null +++ b/src/tests/fixtures/locate/notFoundField.invalid.ts.expected.md @@ -0,0 +1,18 @@ +## input + +```ts title="locate/notFoundField.invalid.ts" +// Locate: User.not_a_field +/** @gqlType */ +type User = { + /** @gqlField */ + name: string; +}; +``` + +## Output + +### Error Locating Type + +```text +Cannot locate field `not_a_field` on type `User`. +``` \ No newline at end of file diff --git a/src/tests/fixtures/locate/notFoundType.invalid.ts.expected b/src/tests/fixtures/locate/notFoundType.invalid.ts.expected deleted file mode 100644 index b4d96713..00000000 --- a/src/tests/fixtures/locate/notFoundType.invalid.ts.expected +++ /dev/null @@ -1,14 +0,0 @@ ------------------ -INPUT ------------------ -// Locate: WhoopsNotARealType -/** @gqlType */ -type User = { - /** @gqlField */ - name: string; -}; - ------------------ -OUTPUT ------------------ -Cannot locate type `WhoopsNotARealType`. \ No newline at end of file diff --git a/src/tests/fixtures/locate/notFoundType.invalid.ts.expected.md b/src/tests/fixtures/locate/notFoundType.invalid.ts.expected.md new file mode 100644 index 00000000..acad6a71 --- /dev/null +++ b/src/tests/fixtures/locate/notFoundType.invalid.ts.expected.md @@ -0,0 +1,18 @@ +## input + +```ts title="locate/notFoundType.invalid.ts" +// Locate: WhoopsNotARealType +/** @gqlType */ +type User = { + /** @gqlField */ + name: string; +}; +``` + +## Output + +### Error Locating Type + +```text +Cannot locate type `WhoopsNotARealType`. +``` \ No newline at end of file diff --git a/src/tests/fixtures/locate/type.invalid.ts.expected b/src/tests/fixtures/locate/type.invalid.ts.expected deleted file mode 100644 index 48822893..00000000 --- a/src/tests/fixtures/locate/type.invalid.ts.expected +++ /dev/null @@ -1,17 +0,0 @@ ------------------ -INPUT ------------------ -// Locate: User -/** @gqlType */ -type User = { - /** @gqlField */ - name: string; -}; - ------------------ -OUTPUT ------------------ -src/tests/fixtures/locate/type.invalid.ts:3:6 - error: Located here - -3 type User = { - ~~~~ diff --git a/src/tests/fixtures/locate/type.invalid.ts.expected.md b/src/tests/fixtures/locate/type.invalid.ts.expected.md new file mode 100644 index 00000000..d8831e2e --- /dev/null +++ b/src/tests/fixtures/locate/type.invalid.ts.expected.md @@ -0,0 +1,21 @@ +## input + +```ts title="locate/type.invalid.ts" +// Locate: User +/** @gqlType */ +type User = { + /** @gqlField */ + name: string; +}; +``` + +## Output + +### Error Report + +```text +src/tests/fixtures/locate/type.invalid.ts:3:6 - error: Located here + +3 type User = { + ~~~~ +``` \ No newline at end of file diff --git a/src/tests/fixtures/locate/typeField.invalid.ts.expected b/src/tests/fixtures/locate/typeField.invalid.ts.expected deleted file mode 100644 index f7e3f654..00000000 --- a/src/tests/fixtures/locate/typeField.invalid.ts.expected +++ /dev/null @@ -1,17 +0,0 @@ ------------------ -INPUT ------------------ -// Locate: User.name -/** @gqlType */ -type User = { - /** @gqlField */ - name: string; -}; - ------------------ -OUTPUT ------------------ -src/tests/fixtures/locate/typeField.invalid.ts:5:3 - error: Located here - -5 name: string; - ~~~~ diff --git a/src/tests/fixtures/locate/typeField.invalid.ts.expected.md b/src/tests/fixtures/locate/typeField.invalid.ts.expected.md new file mode 100644 index 00000000..30ab5e42 --- /dev/null +++ b/src/tests/fixtures/locate/typeField.invalid.ts.expected.md @@ -0,0 +1,21 @@ +## input + +```ts title="locate/typeField.invalid.ts" +// Locate: User.name +/** @gqlType */ +type User = { + /** @gqlField */ + name: string; +}; +``` + +## Output + +### Error Report + +```text +src/tests/fixtures/locate/typeField.invalid.ts:5:3 - error: Located here + +5 name: string; + ~~~~ +``` \ No newline at end of file diff --git a/src/tests/fixtures/regression/fieldFollowedByDeprecated.ts.expected b/src/tests/fixtures/regression/fieldFollowedByDeprecated.ts.expected deleted file mode 100644 index 2140189e..00000000 --- a/src/tests/fixtures/regression/fieldFollowedByDeprecated.ts.expected +++ /dev/null @@ -1,43 +0,0 @@ ------------------ -INPUT ------------------ -/** @gqlType */ -class User { - /** - * @gqlField name - * @deprecated - */ - graphQLName(): string { - return "Sup"; - } -} - ------------------ -OUTPUT ------------------ --- SDL -- -type User { - name: String @deprecated -} --- TypeScript -- -import { GraphQLSchema, GraphQLObjectType, GraphQLString } from "graphql"; -export function getSchema(): GraphQLSchema { - const UserType: GraphQLObjectType = new GraphQLObjectType({ - name: "User", - fields() { - return { - name: { - deprecationReason: "No longer supported", - name: "name", - type: GraphQLString, - resolve(source) { - return source.graphQLName(); - } - } - }; - } - }); - return new GraphQLSchema({ - types: [UserType] - }); -} diff --git a/src/tests/fixtures/regression/fieldFollowedByDeprecated.ts.expected.md b/src/tests/fixtures/regression/fieldFollowedByDeprecated.ts.expected.md new file mode 100644 index 00000000..3d20eea8 --- /dev/null +++ b/src/tests/fixtures/regression/fieldFollowedByDeprecated.ts.expected.md @@ -0,0 +1,50 @@ +## input + +```ts title="regression/fieldFollowedByDeprecated.ts" +/** @gqlType */ +class User { + /** + * @gqlField name + * @deprecated + */ + graphQLName(): string { + return "Sup"; + } +} +``` + +## Output + +### SDL + +```graphql +type User { + name: String @deprecated +} +``` + +### TypeScript + +```ts +import { GraphQLSchema, GraphQLObjectType, GraphQLString } from "graphql"; +export function getSchema(): GraphQLSchema { + const UserType: GraphQLObjectType = new GraphQLObjectType({ + name: "User", + fields() { + return { + name: { + deprecationReason: "No longer supported", + name: "name", + type: GraphQLString, + resolve(source) { + return source.graphQLName(); + } + } + }; + } + }); + return new GraphQLSchema({ + types: [UserType] + }); +} +``` \ No newline at end of file diff --git a/src/tests/fixtures/resolver_context/ClassMethodWithContextValue.ts.expected b/src/tests/fixtures/resolver_context/ClassMethodWithContextValue.ts.expected deleted file mode 100644 index 4ead0dc6..00000000 --- a/src/tests/fixtures/resolver_context/ClassMethodWithContextValue.ts.expected +++ /dev/null @@ -1,44 +0,0 @@ ------------------ -INPUT ------------------ -/** @gqlContext */ -type GratsContext = { - greeting: string; -}; - -/** @gqlType */ -export class SomeType { - /** @gqlField */ - greeting(ctx: GratsContext): string { - return ctx.greeting; - } -} - ------------------ -OUTPUT ------------------ --- SDL -- -type SomeType { - greeting: String -} --- TypeScript -- -import { GraphQLSchema, GraphQLObjectType, GraphQLString } from "graphql"; -export function getSchema(): GraphQLSchema { - const SomeTypeType: GraphQLObjectType = new GraphQLObjectType({ - name: "SomeType", - fields() { - return { - greeting: { - name: "greeting", - type: GraphQLString, - resolve(source, _args, context) { - return source.greeting(context); - } - } - }; - } - }); - return new GraphQLSchema({ - types: [SomeTypeType] - }); -} diff --git a/src/tests/fixtures/resolver_context/ClassMethodWithContextValue.ts.expected.md b/src/tests/fixtures/resolver_context/ClassMethodWithContextValue.ts.expected.md new file mode 100644 index 00000000..41efc453 --- /dev/null +++ b/src/tests/fixtures/resolver_context/ClassMethodWithContextValue.ts.expected.md @@ -0,0 +1,51 @@ +## input + +```ts title="resolver_context/ClassMethodWithContextValue.ts" +/** @gqlContext */ +type GratsContext = { + greeting: string; +}; + +/** @gqlType */ +export class SomeType { + /** @gqlField */ + greeting(ctx: GratsContext): string { + return ctx.greeting; + } +} +``` + +## Output + +### SDL + +```graphql +type SomeType { + greeting: String +} +``` + +### TypeScript + +```ts +import { GraphQLSchema, GraphQLObjectType, GraphQLString } from "graphql"; +export function getSchema(): GraphQLSchema { + const SomeTypeType: GraphQLObjectType = new GraphQLObjectType({ + name: "SomeType", + fields() { + return { + greeting: { + name: "greeting", + type: GraphQLString, + resolve(source, _args, context) { + return source.greeting(context); + } + } + }; + } + }); + return new GraphQLSchema({ + types: [SomeTypeType] + }); +} +``` \ No newline at end of file diff --git a/src/tests/fixtures/resolver_context/ClassMethodWithContextValueExported.ts.expected b/src/tests/fixtures/resolver_context/ClassMethodWithContextValueExported.ts.expected deleted file mode 100644 index 985135e1..00000000 --- a/src/tests/fixtures/resolver_context/ClassMethodWithContextValueExported.ts.expected +++ /dev/null @@ -1,44 +0,0 @@ ------------------ -INPUT ------------------ -/** @gqlContext */ -export type GratsContext = { - greeting: string; -}; - -/** @gqlType */ -export class SomeType { - /** @gqlField */ - greeting(ctx: GratsContext): string { - return ctx.greeting; - } -} - ------------------ -OUTPUT ------------------ --- SDL -- -type SomeType { - greeting: String -} --- TypeScript -- -import { GraphQLSchema, GraphQLObjectType, GraphQLString } from "graphql"; -export function getSchema(): GraphQLSchema { - const SomeTypeType: GraphQLObjectType = new GraphQLObjectType({ - name: "SomeType", - fields() { - return { - greeting: { - name: "greeting", - type: GraphQLString, - resolve(source, _args, context) { - return source.greeting(context); - } - } - }; - } - }); - return new GraphQLSchema({ - types: [SomeTypeType] - }); -} diff --git a/src/tests/fixtures/resolver_context/ClassMethodWithContextValueExported.ts.expected.md b/src/tests/fixtures/resolver_context/ClassMethodWithContextValueExported.ts.expected.md new file mode 100644 index 00000000..740bcb6c --- /dev/null +++ b/src/tests/fixtures/resolver_context/ClassMethodWithContextValueExported.ts.expected.md @@ -0,0 +1,51 @@ +## input + +```ts title="resolver_context/ClassMethodWithContextValueExported.ts" +/** @gqlContext */ +export type GratsContext = { + greeting: string; +}; + +/** @gqlType */ +export class SomeType { + /** @gqlField */ + greeting(ctx: GratsContext): string { + return ctx.greeting; + } +} +``` + +## Output + +### SDL + +```graphql +type SomeType { + greeting: String +} +``` + +### TypeScript + +```ts +import { GraphQLSchema, GraphQLObjectType, GraphQLString } from "graphql"; +export function getSchema(): GraphQLSchema { + const SomeTypeType: GraphQLObjectType = new GraphQLObjectType({ + name: "SomeType", + fields() { + return { + greeting: { + name: "greeting", + type: GraphQLString, + resolve(source, _args, context) { + return source.greeting(context); + } + } + }; + } + }); + return new GraphQLSchema({ + types: [SomeTypeType] + }); +} +``` \ No newline at end of file diff --git a/src/tests/fixtures/resolver_context/ClassMethodWithContextValueInArgsPos.invalid.ts.expected b/src/tests/fixtures/resolver_context/ClassMethodWithContextValueInArgsPos.invalid.ts.expected deleted file mode 100644 index b1954351..00000000 --- a/src/tests/fixtures/resolver_context/ClassMethodWithContextValueInArgsPos.invalid.ts.expected +++ /dev/null @@ -1,22 +0,0 @@ ------------------ -INPUT ------------------ -type GratsContext = { - greeting: string; -}; - -/** @gqlType */ -export class SomeType { - /** @gqlField */ - greeting(ctx: GratsContext): string { - return ctx.greeting; - } -} - ------------------ -OUTPUT ------------------ -src/tests/fixtures/resolver_context/ClassMethodWithContextValueInArgsPos.invalid.ts:8:17 - error: Unable to resolve type reference. In order to generate a GraphQL schema, Grats needs to determine which GraphQL type is being referenced. This requires being able to resolve type references to their `@gql` annotated declaration. However this reference could not be resolved. Is it possible that this type is not defined in this file? - -8 greeting(ctx: GratsContext): string { - ~~~~~~~~~~~~ diff --git a/src/tests/fixtures/resolver_context/ClassMethodWithContextValueInArgsPos.invalid.ts.expected.md b/src/tests/fixtures/resolver_context/ClassMethodWithContextValueInArgsPos.invalid.ts.expected.md new file mode 100644 index 00000000..d227725c --- /dev/null +++ b/src/tests/fixtures/resolver_context/ClassMethodWithContextValueInArgsPos.invalid.ts.expected.md @@ -0,0 +1,26 @@ +## input + +```ts title="resolver_context/ClassMethodWithContextValueInArgsPos.invalid.ts" +type GratsContext = { + greeting: string; +}; + +/** @gqlType */ +export class SomeType { + /** @gqlField */ + greeting(ctx: GratsContext): string { + return ctx.greeting; + } +} +``` + +## Output + +### Error Report + +```text +src/tests/fixtures/resolver_context/ClassMethodWithContextValueInArgsPos.invalid.ts:8:17 - error: Unable to resolve type reference. In order to generate a GraphQL schema, Grats needs to determine which GraphQL type is being referenced. This requires being able to resolve type references to their `@gql` annotated declaration. However this reference could not be resolved. Is it possible that this type is not defined in this file? + +8 greeting(ctx: GratsContext): string { + ~~~~~~~~~~~~ +``` \ No newline at end of file diff --git a/src/tests/fixtures/resolver_context/ContextValueBeforeArgs.ts.expected b/src/tests/fixtures/resolver_context/ContextValueBeforeArgs.ts.expected deleted file mode 100644 index 29263371..00000000 --- a/src/tests/fixtures/resolver_context/ContextValueBeforeArgs.ts.expected +++ /dev/null @@ -1,47 +0,0 @@ ------------------ -INPUT ------------------ -/** @gqlType */ -export class SomeType { - /** @gqlField */ - greeting(ctx: SomeOtherType, args: { fallbackGreeting: string }): string { - return ctx.greeting ?? args.fallbackGreeting; - } -} - -/** @gqlContext */ -type SomeOtherType = { greeting?: string }; - ------------------ -OUTPUT ------------------ --- SDL -- -type SomeType { - greeting(fallbackGreeting: String!): String -} --- TypeScript -- -import { GraphQLSchema, GraphQLObjectType, GraphQLString, GraphQLNonNull } from "graphql"; -export function getSchema(): GraphQLSchema { - const SomeTypeType: GraphQLObjectType = new GraphQLObjectType({ - name: "SomeType", - fields() { - return { - greeting: { - name: "greeting", - type: GraphQLString, - args: { - fallbackGreeting: { - type: new GraphQLNonNull(GraphQLString) - } - }, - resolve(source, args, context) { - return source.greeting(context, args); - } - } - }; - } - }); - return new GraphQLSchema({ - types: [SomeTypeType] - }); -} diff --git a/src/tests/fixtures/resolver_context/ContextValueBeforeArgs.ts.expected.md b/src/tests/fixtures/resolver_context/ContextValueBeforeArgs.ts.expected.md new file mode 100644 index 00000000..474ce90e --- /dev/null +++ b/src/tests/fixtures/resolver_context/ContextValueBeforeArgs.ts.expected.md @@ -0,0 +1,54 @@ +## input + +```ts title="resolver_context/ContextValueBeforeArgs.ts" +/** @gqlType */ +export class SomeType { + /** @gqlField */ + greeting(ctx: SomeOtherType, args: { fallbackGreeting: string }): string { + return ctx.greeting ?? args.fallbackGreeting; + } +} + +/** @gqlContext */ +type SomeOtherType = { greeting?: string }; +``` + +## Output + +### SDL + +```graphql +type SomeType { + greeting(fallbackGreeting: String!): String +} +``` + +### TypeScript + +```ts +import { GraphQLSchema, GraphQLObjectType, GraphQLString, GraphQLNonNull } from "graphql"; +export function getSchema(): GraphQLSchema { + const SomeTypeType: GraphQLObjectType = new GraphQLObjectType({ + name: "SomeType", + fields() { + return { + greeting: { + name: "greeting", + type: GraphQLString, + args: { + fallbackGreeting: { + type: new GraphQLNonNull(GraphQLString) + } + }, + resolve(source, args, context) { + return source.greeting(context, args); + } + } + }; + } + }); + return new GraphQLSchema({ + types: [SomeTypeType] + }); +} +``` \ No newline at end of file diff --git a/src/tests/fixtures/resolver_context/ContextValueMissingTypeAnnotation.invalid.ts.expected b/src/tests/fixtures/resolver_context/ContextValueMissingTypeAnnotation.invalid.ts.expected deleted file mode 100644 index af33b9e0..00000000 --- a/src/tests/fixtures/resolver_context/ContextValueMissingTypeAnnotation.invalid.ts.expected +++ /dev/null @@ -1,18 +0,0 @@ ------------------ -INPUT ------------------ -/** @gqlType */ -export class SomeType { - /** @gqlField */ - greeting(ctx): string { - return ctx.greeting; - } -} - ------------------ -OUTPUT ------------------ -src/tests/fixtures/resolver_context/ContextValueMissingTypeAnnotation.invalid.ts:4:12 - error: Missing type annotation for resolver argument. Expected all resolver arguments to have an explicit type annotation. Grats needs to be able to see the type of the arguments to generate an executable GraphQL schema. - -4 greeting(ctx): string { - ~~~ diff --git a/src/tests/fixtures/resolver_context/ContextValueMissingTypeAnnotation.invalid.ts.expected.md b/src/tests/fixtures/resolver_context/ContextValueMissingTypeAnnotation.invalid.ts.expected.md new file mode 100644 index 00000000..812e14d5 --- /dev/null +++ b/src/tests/fixtures/resolver_context/ContextValueMissingTypeAnnotation.invalid.ts.expected.md @@ -0,0 +1,22 @@ +## input + +```ts title="resolver_context/ContextValueMissingTypeAnnotation.invalid.ts" +/** @gqlType */ +export class SomeType { + /** @gqlField */ + greeting(ctx): string { + return ctx.greeting; + } +} +``` + +## Output + +### Error Report + +```text +src/tests/fixtures/resolver_context/ContextValueMissingTypeAnnotation.invalid.ts:4:12 - error: Missing type annotation for resolver argument. Expected all resolver arguments to have an explicit type annotation. Grats needs to be able to see the type of the arguments to generate an executable GraphQL schema. + +4 greeting(ctx): string { + ~~~ +``` \ No newline at end of file diff --git a/src/tests/fixtures/resolver_context/ContextValueOptional.ts.expected b/src/tests/fixtures/resolver_context/ContextValueOptional.ts.expected deleted file mode 100644 index c3e90748..00000000 --- a/src/tests/fixtures/resolver_context/ContextValueOptional.ts.expected +++ /dev/null @@ -1,45 +0,0 @@ ------------------ -INPUT ------------------ -/** @gqlType */ -export class SomeType { - /** @gqlField */ - greeting(ctx?: SomeOtherType): string { - // This is fine since Grats will always pass ctx. It's fine for - // the resolver to _also_ work _without_ ctx, as long as it's - // safe for Grats to pass ctx. - return ctx?.greeting ?? "Hello, World!"; - } -} - -/** @gqlContext */ -type SomeOtherType = { greeting: string }; - ------------------ -OUTPUT ------------------ --- SDL -- -type SomeType { - greeting: String -} --- TypeScript -- -import { GraphQLSchema, GraphQLObjectType, GraphQLString } from "graphql"; -export function getSchema(): GraphQLSchema { - const SomeTypeType: GraphQLObjectType = new GraphQLObjectType({ - name: "SomeType", - fields() { - return { - greeting: { - name: "greeting", - type: GraphQLString, - resolve(source, _args, context) { - return source.greeting(context); - } - } - }; - } - }); - return new GraphQLSchema({ - types: [SomeTypeType] - }); -} diff --git a/src/tests/fixtures/resolver_context/ContextValueOptional.ts.expected.md b/src/tests/fixtures/resolver_context/ContextValueOptional.ts.expected.md new file mode 100644 index 00000000..89960d2b --- /dev/null +++ b/src/tests/fixtures/resolver_context/ContextValueOptional.ts.expected.md @@ -0,0 +1,52 @@ +## input + +```ts title="resolver_context/ContextValueOptional.ts" +/** @gqlType */ +export class SomeType { + /** @gqlField */ + greeting(ctx?: SomeOtherType): string { + // This is fine since Grats will always pass ctx. It's fine for + // the resolver to _also_ work _without_ ctx, as long as it's + // safe for Grats to pass ctx. + return ctx?.greeting ?? "Hello, World!"; + } +} + +/** @gqlContext */ +type SomeOtherType = { greeting: string }; +``` + +## Output + +### SDL + +```graphql +type SomeType { + greeting: String +} +``` + +### TypeScript + +```ts +import { GraphQLSchema, GraphQLObjectType, GraphQLString } from "graphql"; +export function getSchema(): GraphQLSchema { + const SomeTypeType: GraphQLObjectType = new GraphQLObjectType({ + name: "SomeType", + fields() { + return { + greeting: { + name: "greeting", + type: GraphQLString, + resolve(source, _args, context) { + return source.greeting(context); + } + } + }; + } + }); + return new GraphQLSchema({ + types: [SomeTypeType] + }); +} +``` \ No newline at end of file diff --git a/src/tests/fixtures/resolver_context/ContextValueReadTwice.ts.expected b/src/tests/fixtures/resolver_context/ContextValueReadTwice.ts.expected deleted file mode 100644 index 45b9d893..00000000 --- a/src/tests/fixtures/resolver_context/ContextValueReadTwice.ts.expected +++ /dev/null @@ -1,44 +0,0 @@ ------------------ -INPUT ------------------ -// No valid reason to do this, but just asserting that it works, since it happens to. - -/** @gqlType */ -export class SomeType { - /** @gqlField */ - greeting(ctx: SomeOtherType, alsoContext: SomeOtherType): string { - return ctx.greeting ?? "Hello, world!"; - } -} - -/** @gqlContext */ -type SomeOtherType = { greeting?: string }; - ------------------ -OUTPUT ------------------ --- SDL -- -type SomeType { - greeting: String -} --- TypeScript -- -import { GraphQLSchema, GraphQLObjectType, GraphQLString } from "graphql"; -export function getSchema(): GraphQLSchema { - const SomeTypeType: GraphQLObjectType = new GraphQLObjectType({ - name: "SomeType", - fields() { - return { - greeting: { - name: "greeting", - type: GraphQLString, - resolve(source, _args, context) { - return source.greeting(context, context); - } - } - }; - } - }); - return new GraphQLSchema({ - types: [SomeTypeType] - }); -} diff --git a/src/tests/fixtures/resolver_context/ContextValueReadTwice.ts.expected.md b/src/tests/fixtures/resolver_context/ContextValueReadTwice.ts.expected.md new file mode 100644 index 00000000..876cc808 --- /dev/null +++ b/src/tests/fixtures/resolver_context/ContextValueReadTwice.ts.expected.md @@ -0,0 +1,51 @@ +## input + +```ts title="resolver_context/ContextValueReadTwice.ts" +// No valid reason to do this, but just asserting that it works, since it happens to. + +/** @gqlType */ +export class SomeType { + /** @gqlField */ + greeting(ctx: SomeOtherType, alsoContext: SomeOtherType): string { + return ctx.greeting ?? "Hello, world!"; + } +} + +/** @gqlContext */ +type SomeOtherType = { greeting?: string }; +``` + +## Output + +### SDL + +```graphql +type SomeType { + greeting: String +} +``` + +### TypeScript + +```ts +import { GraphQLSchema, GraphQLObjectType, GraphQLString } from "graphql"; +export function getSchema(): GraphQLSchema { + const SomeTypeType: GraphQLObjectType = new GraphQLObjectType({ + name: "SomeType", + fields() { + return { + greeting: { + name: "greeting", + type: GraphQLString, + resolve(source, _args, context) { + return source.greeting(context, context); + } + } + }; + } + }); + return new GraphQLSchema({ + types: [SomeTypeType] + }); +} +``` \ No newline at end of file diff --git a/src/tests/fixtures/resolver_context/ContextValueSpread.invalid.ts.expected b/src/tests/fixtures/resolver_context/ContextValueSpread.invalid.ts.expected deleted file mode 100644 index 36395eef..00000000 --- a/src/tests/fixtures/resolver_context/ContextValueSpread.invalid.ts.expected +++ /dev/null @@ -1,21 +0,0 @@ ------------------ -INPUT ------------------ -/** @gqlType */ -export class SomeType { - /** @gqlField */ - greeting(...ctx: SomeOtherType[]): string { - return ctx[0].greeting; - } -} - -/** @gqlContext */ -type SomeOtherType = { greeting: string }; - ------------------ -OUTPUT ------------------ -src/tests/fixtures/resolver_context/ContextValueSpread.invalid.ts:4:12 - error: Unexpected spread argument in resolver. Grats expects all resolver arguments to be a single, explicitly-typed argument. - -4 greeting(...ctx: SomeOtherType[]): string { - ~~~ diff --git a/src/tests/fixtures/resolver_context/ContextValueSpread.invalid.ts.expected.md b/src/tests/fixtures/resolver_context/ContextValueSpread.invalid.ts.expected.md new file mode 100644 index 00000000..28b221ef --- /dev/null +++ b/src/tests/fixtures/resolver_context/ContextValueSpread.invalid.ts.expected.md @@ -0,0 +1,25 @@ +## input + +```ts title="resolver_context/ContextValueSpread.invalid.ts" +/** @gqlType */ +export class SomeType { + /** @gqlField */ + greeting(...ctx: SomeOtherType[]): string { + return ctx[0].greeting; + } +} + +/** @gqlContext */ +type SomeOtherType = { greeting: string }; +``` + +## Output + +### Error Report + +```text +src/tests/fixtures/resolver_context/ContextValueSpread.invalid.ts:4:12 - error: Unexpected spread argument in resolver. Grats expects all resolver arguments to be a single, explicitly-typed argument. + +4 greeting(...ctx: SomeOtherType[]): string { + ~~~ +``` \ No newline at end of file diff --git a/src/tests/fixtures/resolver_context/ContextValueTypeNotDefined.invalid.ts.expected b/src/tests/fixtures/resolver_context/ContextValueTypeNotDefined.invalid.ts.expected deleted file mode 100644 index c9b2df03..00000000 --- a/src/tests/fixtures/resolver_context/ContextValueTypeNotDefined.invalid.ts.expected +++ /dev/null @@ -1,18 +0,0 @@ ------------------ -INPUT ------------------ -/** @gqlType */ -export class SomeType { - /** @gqlField */ - greeting(ctx: ThisIsNeverDefined): string { - return ctx.greeting; - } -} - ------------------ -OUTPUT ------------------ -src/tests/fixtures/resolver_context/ContextValueTypeNotDefined.invalid.ts:4:17 - error: Unable to resolve type reference. In order to generate a GraphQL schema, Grats needs to determine which GraphQL type is being referenced. This requires being able to resolve type references to their `@gql` annotated declaration. However this reference could not be resolved. Is it possible that this type is not defined in this file? - -4 greeting(ctx: ThisIsNeverDefined): string { - ~~~~~~~~~~~~~~~~~~ diff --git a/src/tests/fixtures/resolver_context/ContextValueTypeNotDefined.invalid.ts.expected.md b/src/tests/fixtures/resolver_context/ContextValueTypeNotDefined.invalid.ts.expected.md new file mode 100644 index 00000000..351fa12c --- /dev/null +++ b/src/tests/fixtures/resolver_context/ContextValueTypeNotDefined.invalid.ts.expected.md @@ -0,0 +1,22 @@ +## input + +```ts title="resolver_context/ContextValueTypeNotDefined.invalid.ts" +/** @gqlType */ +export class SomeType { + /** @gqlField */ + greeting(ctx: ThisIsNeverDefined): string { + return ctx.greeting; + } +} +``` + +## Output + +### Error Report + +```text +src/tests/fixtures/resolver_context/ContextValueTypeNotDefined.invalid.ts:4:17 - error: Unable to resolve type reference. In order to generate a GraphQL schema, Grats needs to determine which GraphQL type is being referenced. This requires being able to resolve type references to their `@gql` annotated declaration. However this reference could not be resolved. Is it possible that this type is not defined in this file? + +4 greeting(ctx: ThisIsNeverDefined): string { + ~~~~~~~~~~~~~~~~~~ +``` \ No newline at end of file diff --git a/src/tests/fixtures/resolver_context/ContextValueTypedAsAny.invalid.ts.expected b/src/tests/fixtures/resolver_context/ContextValueTypedAsAny.invalid.ts.expected deleted file mode 100644 index 0f6340e4..00000000 --- a/src/tests/fixtures/resolver_context/ContextValueTypedAsAny.invalid.ts.expected +++ /dev/null @@ -1,20 +0,0 @@ ------------------ -INPUT ------------------ -/** @gqlType */ -export class SomeType { - /** @gqlField */ - greeting(ctx: any): string { - return ctx.greeting; - } -} - ------------------ -OUTPUT ------------------ -src/tests/fixtures/resolver_context/ContextValueTypedAsAny.invalid.ts:4:17 - error: Unknown GraphQL type. Grats does not know how to map this type to a GraphQL type. You may want to define a named GraphQL type elsewhere and reference it here. If you think Grats should be able to infer a GraphQL type from this type, please file an issue. - -If you think Grats should be able to infer this type, please report an issue at https://github.com/captbaritone/grats/issues. - -4 greeting(ctx: any): string { - ~~~ diff --git a/src/tests/fixtures/resolver_context/ContextValueTypedAsAny.invalid.ts.expected.md b/src/tests/fixtures/resolver_context/ContextValueTypedAsAny.invalid.ts.expected.md new file mode 100644 index 00000000..c2c0306d --- /dev/null +++ b/src/tests/fixtures/resolver_context/ContextValueTypedAsAny.invalid.ts.expected.md @@ -0,0 +1,24 @@ +## input + +```ts title="resolver_context/ContextValueTypedAsAny.invalid.ts" +/** @gqlType */ +export class SomeType { + /** @gqlField */ + greeting(ctx: any): string { + return ctx.greeting; + } +} +``` + +## Output + +### Error Report + +```text +src/tests/fixtures/resolver_context/ContextValueTypedAsAny.invalid.ts:4:17 - error: Unknown GraphQL type. Grats does not know how to map this type to a GraphQL type. You may want to define a named GraphQL type elsewhere and reference it here. If you think Grats should be able to infer a GraphQL type from this type, please file an issue. + +If you think Grats should be able to infer this type, please report an issue at https://github.com/captbaritone/grats/issues. + +4 greeting(ctx: any): string { + ~~~ +``` \ No newline at end of file diff --git a/src/tests/fixtures/resolver_context/ContextValueTypedAsNever.invalid.ts.expected b/src/tests/fixtures/resolver_context/ContextValueTypedAsNever.invalid.ts.expected deleted file mode 100644 index 7eaf104a..00000000 --- a/src/tests/fixtures/resolver_context/ContextValueTypedAsNever.invalid.ts.expected +++ /dev/null @@ -1,20 +0,0 @@ ------------------ -INPUT ------------------ -/** @gqlType */ -export class SomeType { - /** @gqlField */ - greeting(ctx: never): string { - return ctx.greeting; - } -} - ------------------ -OUTPUT ------------------ -src/tests/fixtures/resolver_context/ContextValueTypedAsNever.invalid.ts:4:17 - error: Unknown GraphQL type. Grats does not know how to map this type to a GraphQL type. You may want to define a named GraphQL type elsewhere and reference it here. If you think Grats should be able to infer a GraphQL type from this type, please file an issue. - -If you think Grats should be able to infer this type, please report an issue at https://github.com/captbaritone/grats/issues. - -4 greeting(ctx: never): string { - ~~~~~ diff --git a/src/tests/fixtures/resolver_context/ContextValueTypedAsNever.invalid.ts.expected.md b/src/tests/fixtures/resolver_context/ContextValueTypedAsNever.invalid.ts.expected.md new file mode 100644 index 00000000..0b1be5f0 --- /dev/null +++ b/src/tests/fixtures/resolver_context/ContextValueTypedAsNever.invalid.ts.expected.md @@ -0,0 +1,24 @@ +## input + +```ts title="resolver_context/ContextValueTypedAsNever.invalid.ts" +/** @gqlType */ +export class SomeType { + /** @gqlField */ + greeting(ctx: never): string { + return ctx.greeting; + } +} +``` + +## Output + +### Error Report + +```text +src/tests/fixtures/resolver_context/ContextValueTypedAsNever.invalid.ts:4:17 - error: Unknown GraphQL type. Grats does not know how to map this type to a GraphQL type. You may want to define a named GraphQL type elsewhere and reference it here. If you think Grats should be able to infer a GraphQL type from this type, please file an issue. + +If you think Grats should be able to infer this type, please report an issue at https://github.com/captbaritone/grats/issues. + +4 greeting(ctx: never): string { + ~~~~~ +``` \ No newline at end of file diff --git a/src/tests/fixtures/resolver_context/ContextValueTypedAsUnknown.invalid.ts.expected b/src/tests/fixtures/resolver_context/ContextValueTypedAsUnknown.invalid.ts.expected deleted file mode 100644 index 4ff5d588..00000000 --- a/src/tests/fixtures/resolver_context/ContextValueTypedAsUnknown.invalid.ts.expected +++ /dev/null @@ -1,20 +0,0 @@ ------------------ -INPUT ------------------ -/** @gqlType */ -export class SomeType { - /** @gqlField */ - greeting(ctx: unknown): string { - return ctx.greeting; - } -} - ------------------ -OUTPUT ------------------ -src/tests/fixtures/resolver_context/ContextValueTypedAsUnknown.invalid.ts:4:17 - error: Unknown GraphQL type. Grats does not know how to map this type to a GraphQL type. You may want to define a named GraphQL type elsewhere and reference it here. If you think Grats should be able to infer a GraphQL type from this type, please file an issue. - -If you think Grats should be able to infer this type, please report an issue at https://github.com/captbaritone/grats/issues. - -4 greeting(ctx: unknown): string { - ~~~~~~~ diff --git a/src/tests/fixtures/resolver_context/ContextValueTypedAsUnknown.invalid.ts.expected.md b/src/tests/fixtures/resolver_context/ContextValueTypedAsUnknown.invalid.ts.expected.md new file mode 100644 index 00000000..39a4e037 --- /dev/null +++ b/src/tests/fixtures/resolver_context/ContextValueTypedAsUnknown.invalid.ts.expected.md @@ -0,0 +1,24 @@ +## input + +```ts title="resolver_context/ContextValueTypedAsUnknown.invalid.ts" +/** @gqlType */ +export class SomeType { + /** @gqlField */ + greeting(ctx: unknown): string { + return ctx.greeting; + } +} +``` + +## Output + +### Error Report + +```text +src/tests/fixtures/resolver_context/ContextValueTypedAsUnknown.invalid.ts:4:17 - error: Unknown GraphQL type. Grats does not know how to map this type to a GraphQL type. You may want to define a named GraphQL type elsewhere and reference it here. If you think Grats should be able to infer a GraphQL type from this type, please file an issue. + +If you think Grats should be able to infer this type, please report an issue at https://github.com/captbaritone/grats/issues. + +4 greeting(ctx: unknown): string { + ~~~~~~~ +``` \ No newline at end of file diff --git a/src/tests/fixtures/resolver_context/FunctionWithContextValue.ts.expected b/src/tests/fixtures/resolver_context/FunctionWithContextValue.ts.expected deleted file mode 100644 index acbb3ed9..00000000 --- a/src/tests/fixtures/resolver_context/FunctionWithContextValue.ts.expected +++ /dev/null @@ -1,45 +0,0 @@ ------------------ -INPUT ------------------ -/** @gqlContext */ -type GratsContext = { - greeting: string; -}; - -/** @gqlType */ -export class User {} - -/** @gqlField */ -export function greeting(_: User, ctx: GratsContext): string { - return ctx.greeting; -} - ------------------ -OUTPUT ------------------ --- SDL -- -type User { - greeting: String -} --- TypeScript -- -import { GraphQLSchema, GraphQLObjectType, GraphQLString } from "graphql"; -import { greeting as userGreetingResolver } from "./FunctionWithContextValue"; -export function getSchema(): GraphQLSchema { - const UserType: GraphQLObjectType = new GraphQLObjectType({ - name: "User", - fields() { - return { - greeting: { - name: "greeting", - type: GraphQLString, - resolve(source, _args, context) { - return userGreetingResolver(source, context); - } - } - }; - } - }); - return new GraphQLSchema({ - types: [UserType] - }); -} diff --git a/src/tests/fixtures/resolver_context/FunctionWithContextValue.ts.expected.md b/src/tests/fixtures/resolver_context/FunctionWithContextValue.ts.expected.md new file mode 100644 index 00000000..f18caed5 --- /dev/null +++ b/src/tests/fixtures/resolver_context/FunctionWithContextValue.ts.expected.md @@ -0,0 +1,52 @@ +## input + +```ts title="resolver_context/FunctionWithContextValue.ts" +/** @gqlContext */ +type GratsContext = { + greeting: string; +}; + +/** @gqlType */ +export class User {} + +/** @gqlField */ +export function greeting(_: User, ctx: GratsContext): string { + return ctx.greeting; +} +``` + +## Output + +### SDL + +```graphql +type User { + greeting: String +} +``` + +### TypeScript + +```ts +import { GraphQLSchema, GraphQLObjectType, GraphQLString } from "graphql"; +import { greeting as userGreetingResolver } from "./FunctionWithContextValue"; +export function getSchema(): GraphQLSchema { + const UserType: GraphQLObjectType = new GraphQLObjectType({ + name: "User", + fields() { + return { + greeting: { + name: "greeting", + type: GraphQLString, + resolve(source, _args, context) { + return userGreetingResolver(source, context); + } + } + }; + } + }); + return new GraphQLSchema({ + types: [UserType] + }); +} +``` \ No newline at end of file diff --git a/src/tests/fixtures/resolver_context/MultipleClassMethodsReferencingContextValue.ts.expected b/src/tests/fixtures/resolver_context/MultipleClassMethodsReferencingContextValue.ts.expected deleted file mode 100644 index 7feaa158..00000000 --- a/src/tests/fixtures/resolver_context/MultipleClassMethodsReferencingContextValue.ts.expected +++ /dev/null @@ -1,57 +0,0 @@ ------------------ -INPUT ------------------ -/** @gqlContext */ -type GratsContext = { - greeting: string; -}; - -/** @gqlType */ -export class SomeType { - /** @gqlField */ - greeting(ctx: GratsContext): string { - return ctx.greeting; - } - - /** @gqlField */ - alsoGreeting(ctx: GratsContext): string { - return ctx.greeting; - } -} - ------------------ -OUTPUT ------------------ --- SDL -- -type SomeType { - alsoGreeting: String - greeting: String -} --- TypeScript -- -import { GraphQLSchema, GraphQLObjectType, GraphQLString } from "graphql"; -export function getSchema(): GraphQLSchema { - const SomeTypeType: GraphQLObjectType = new GraphQLObjectType({ - name: "SomeType", - fields() { - return { - alsoGreeting: { - name: "alsoGreeting", - type: GraphQLString, - resolve(source, _args, context) { - return source.alsoGreeting(context); - } - }, - greeting: { - name: "greeting", - type: GraphQLString, - resolve(source, _args, context) { - return source.greeting(context); - } - } - }; - } - }); - return new GraphQLSchema({ - types: [SomeTypeType] - }); -} diff --git a/src/tests/fixtures/resolver_context/MultipleClassMethodsReferencingContextValue.ts.expected.md b/src/tests/fixtures/resolver_context/MultipleClassMethodsReferencingContextValue.ts.expected.md new file mode 100644 index 00000000..01040d0b --- /dev/null +++ b/src/tests/fixtures/resolver_context/MultipleClassMethodsReferencingContextValue.ts.expected.md @@ -0,0 +1,64 @@ +## input + +```ts title="resolver_context/MultipleClassMethodsReferencingContextValue.ts" +/** @gqlContext */ +type GratsContext = { + greeting: string; +}; + +/** @gqlType */ +export class SomeType { + /** @gqlField */ + greeting(ctx: GratsContext): string { + return ctx.greeting; + } + + /** @gqlField */ + alsoGreeting(ctx: GratsContext): string { + return ctx.greeting; + } +} +``` + +## Output + +### SDL + +```graphql +type SomeType { + alsoGreeting: String + greeting: String +} +``` + +### TypeScript + +```ts +import { GraphQLSchema, GraphQLObjectType, GraphQLString } from "graphql"; +export function getSchema(): GraphQLSchema { + const SomeTypeType: GraphQLObjectType = new GraphQLObjectType({ + name: "SomeType", + fields() { + return { + alsoGreeting: { + name: "alsoGreeting", + type: GraphQLString, + resolve(source, _args, context) { + return source.alsoGreeting(context); + } + }, + greeting: { + name: "greeting", + type: GraphQLString, + resolve(source, _args, context) { + return source.greeting(context); + } + } + }; + } + }); + return new GraphQLSchema({ + types: [SomeTypeType] + }); +} +``` \ No newline at end of file diff --git a/src/tests/fixtures/resolver_context/MultipleContextValuesUsed.invalid.ts.expected b/src/tests/fixtures/resolver_context/MultipleContextValuesUsed.invalid.ts.expected deleted file mode 100644 index 4ec1684b..00000000 --- a/src/tests/fixtures/resolver_context/MultipleContextValuesUsed.invalid.ts.expected +++ /dev/null @@ -1,37 +0,0 @@ ------------------ -INPUT ------------------ -/** @gqlContext */ -type GratsContext = { - greeting: string; -}; - -/** @gqlContext */ -type AlsoGratsContext = { - greeting: string; -}; - -/** @gqlType */ -export class SomeType { - /** @gqlField */ - greeting(ctx: GratsContext): string { - return ctx.greeting; - } - /** @gqlField */ - alsoGreeting(ctx: AlsoGratsContext): string { - return ctx.greeting; - } -} - ------------------ -OUTPUT ------------------ -src/tests/fixtures/resolver_context/MultipleContextValuesUsed.invalid.ts:6:5 - error: Unexpected duplicate `@gqlContext` tag. Only one type in a project may be annotated with the `@gqlContext`. - -6 /** @gqlContext */ - ~~~~~~~~~~~~ - - src/tests/fixtures/resolver_context/MultipleContextValuesUsed.invalid.ts:1:5 - 1 /** @gqlContext */ - ~~~~~~~~~~~~ - `@gqlContext` previously defined here. diff --git a/src/tests/fixtures/resolver_context/MultipleContextValuesUsed.invalid.ts.expected.md b/src/tests/fixtures/resolver_context/MultipleContextValuesUsed.invalid.ts.expected.md new file mode 100644 index 00000000..39d0d3ba --- /dev/null +++ b/src/tests/fixtures/resolver_context/MultipleContextValuesUsed.invalid.ts.expected.md @@ -0,0 +1,41 @@ +## input + +```ts title="resolver_context/MultipleContextValuesUsed.invalid.ts" +/** @gqlContext */ +type GratsContext = { + greeting: string; +}; + +/** @gqlContext */ +type AlsoGratsContext = { + greeting: string; +}; + +/** @gqlType */ +export class SomeType { + /** @gqlField */ + greeting(ctx: GratsContext): string { + return ctx.greeting; + } + /** @gqlField */ + alsoGreeting(ctx: AlsoGratsContext): string { + return ctx.greeting; + } +} +``` + +## Output + +### Error Report + +```text +src/tests/fixtures/resolver_context/MultipleContextValuesUsed.invalid.ts:6:5 - error: Unexpected duplicate `@gqlContext` tag. Only one type in a project may be annotated with the `@gqlContext`. + +6 /** @gqlContext */ + ~~~~~~~~~~~~ + + src/tests/fixtures/resolver_context/MultipleContextValuesUsed.invalid.ts:1:5 + 1 /** @gqlContext */ + ~~~~~~~~~~~~ + `@gqlContext` previously defined here. +``` \ No newline at end of file diff --git a/src/tests/fixtures/resolver_info/ClassMethodWithInfoValue.ts.expected b/src/tests/fixtures/resolver_info/ClassMethodWithInfoValue.ts.expected deleted file mode 100644 index 985c2d9f..00000000 --- a/src/tests/fixtures/resolver_info/ClassMethodWithInfoValue.ts.expected +++ /dev/null @@ -1,41 +0,0 @@ ------------------ -INPUT ------------------ -import { GqlInfo } from "../../../Types"; - -/** @gqlType */ -export class SomeType { - /** @gqlField greeting */ - greetz(info: GqlInfo): string { - return "Hello"; - } -} - ------------------ -OUTPUT ------------------ --- SDL -- -type SomeType { - greeting: String -} --- TypeScript -- -import { GraphQLSchema, GraphQLObjectType, GraphQLString } from "graphql"; -export function getSchema(): GraphQLSchema { - const SomeTypeType: GraphQLObjectType = new GraphQLObjectType({ - name: "SomeType", - fields() { - return { - greeting: { - name: "greeting", - type: GraphQLString, - resolve(source, _args, _context, info) { - return source.greetz(info); - } - } - }; - } - }); - return new GraphQLSchema({ - types: [SomeTypeType] - }); -} diff --git a/src/tests/fixtures/resolver_info/ClassMethodWithInfoValue.ts.expected.md b/src/tests/fixtures/resolver_info/ClassMethodWithInfoValue.ts.expected.md new file mode 100644 index 00000000..5348db0e --- /dev/null +++ b/src/tests/fixtures/resolver_info/ClassMethodWithInfoValue.ts.expected.md @@ -0,0 +1,48 @@ +## input + +```ts title="resolver_info/ClassMethodWithInfoValue.ts" +import { GqlInfo } from "../../../Types"; + +/** @gqlType */ +export class SomeType { + /** @gqlField greeting */ + greetz(info: GqlInfo): string { + return "Hello"; + } +} +``` + +## Output + +### SDL + +```graphql +type SomeType { + greeting: String +} +``` + +### TypeScript + +```ts +import { GraphQLSchema, GraphQLObjectType, GraphQLString } from "graphql"; +export function getSchema(): GraphQLSchema { + const SomeTypeType: GraphQLObjectType = new GraphQLObjectType({ + name: "SomeType", + fields() { + return { + greeting: { + name: "greeting", + type: GraphQLString, + resolve(source, _args, _context, info) { + return source.greetz(info); + } + } + }; + } + }); + return new GraphQLSchema({ + types: [SomeTypeType] + }); +} +``` \ No newline at end of file diff --git a/src/tests/fixtures/resolver_info/FunctionWithInfoValue.ts.expected b/src/tests/fixtures/resolver_info/FunctionWithInfoValue.ts.expected deleted file mode 100644 index 8f9a0c23..00000000 --- a/src/tests/fixtures/resolver_info/FunctionWithInfoValue.ts.expected +++ /dev/null @@ -1,43 +0,0 @@ ------------------ -INPUT ------------------ -import { GqlInfo } from "../../../Types"; - -/** @gqlField */ -export function greetz(_: Query, info: GqlInfo): string { - return "Hello"; -} - -/** @gqlType */ -type Query = unknown; - ------------------ -OUTPUT ------------------ --- SDL -- -type Query { - greetz: String -} --- TypeScript -- -import { GraphQLSchema, GraphQLObjectType, GraphQLString } from "graphql"; -import { greetz as queryGreetzResolver } from "./FunctionWithInfoValue"; -export function getSchema(): GraphQLSchema { - const QueryType: GraphQLObjectType = new GraphQLObjectType({ - name: "Query", - fields() { - return { - greetz: { - name: "greetz", - type: GraphQLString, - resolve(source, _args, _context, info) { - return queryGreetzResolver(source, info); - } - } - }; - } - }); - return new GraphQLSchema({ - query: QueryType, - types: [QueryType] - }); -} diff --git a/src/tests/fixtures/resolver_info/FunctionWithInfoValue.ts.expected.md b/src/tests/fixtures/resolver_info/FunctionWithInfoValue.ts.expected.md new file mode 100644 index 00000000..47c90823 --- /dev/null +++ b/src/tests/fixtures/resolver_info/FunctionWithInfoValue.ts.expected.md @@ -0,0 +1,50 @@ +## input + +```ts title="resolver_info/FunctionWithInfoValue.ts" +import { GqlInfo } from "../../../Types"; + +/** @gqlField */ +export function greetz(_: Query, info: GqlInfo): string { + return "Hello"; +} + +/** @gqlType */ +type Query = unknown; +``` + +## Output + +### SDL + +```graphql +type Query { + greetz: String +} +``` + +### TypeScript + +```ts +import { GraphQLSchema, GraphQLObjectType, GraphQLString } from "graphql"; +import { greetz as queryGreetzResolver } from "./FunctionWithInfoValue"; +export function getSchema(): GraphQLSchema { + const QueryType: GraphQLObjectType = new GraphQLObjectType({ + name: "Query", + fields() { + return { + greetz: { + name: "greetz", + type: GraphQLString, + resolve(source, _args, _context, info) { + return queryGreetzResolver(source, info); + } + } + }; + } + }); + return new GraphQLSchema({ + query: QueryType, + types: [QueryType] + }); +} +``` \ No newline at end of file diff --git a/src/tests/fixtures/resolver_info/StaticMethodWithInfoValue.ts.expected b/src/tests/fixtures/resolver_info/StaticMethodWithInfoValue.ts.expected deleted file mode 100644 index 79f78ae6..00000000 --- a/src/tests/fixtures/resolver_info/StaticMethodWithInfoValue.ts.expected +++ /dev/null @@ -1,64 +0,0 @@ ------------------ -INPUT ------------------ -import { GqlInfo } from "../../../Types"; - -/** @gqlType */ -export class SomeType { - /** @gqlField */ - someField: string; - - /** @gqlField greeting */ - static greetz(_: Query, info: GqlInfo): string { - return "Hello"; - } -} - -/** @gqlType */ -type Query = unknown; - ------------------ -OUTPUT ------------------ --- SDL -- -type Query { - greeting: String -} - -type SomeType { - someField: String -} --- TypeScript -- -import { GraphQLSchema, GraphQLObjectType, GraphQLString } from "graphql"; -import { SomeType as queryGreetingResolver } from "./StaticMethodWithInfoValue"; -export function getSchema(): GraphQLSchema { - const QueryType: GraphQLObjectType = new GraphQLObjectType({ - name: "Query", - fields() { - return { - greeting: { - name: "greeting", - type: GraphQLString, - resolve(source, _args, _context, info) { - return queryGreetingResolver.greetz(source, info); - } - } - }; - } - }); - const SomeTypeType: GraphQLObjectType = new GraphQLObjectType({ - name: "SomeType", - fields() { - return { - someField: { - name: "someField", - type: GraphQLString - } - }; - } - }); - return new GraphQLSchema({ - query: QueryType, - types: [QueryType, SomeTypeType] - }); -} diff --git a/src/tests/fixtures/resolver_info/StaticMethodWithInfoValue.ts.expected.md b/src/tests/fixtures/resolver_info/StaticMethodWithInfoValue.ts.expected.md new file mode 100644 index 00000000..67d7255f --- /dev/null +++ b/src/tests/fixtures/resolver_info/StaticMethodWithInfoValue.ts.expected.md @@ -0,0 +1,71 @@ +## input + +```ts title="resolver_info/StaticMethodWithInfoValue.ts" +import { GqlInfo } from "../../../Types"; + +/** @gqlType */ +export class SomeType { + /** @gqlField */ + someField: string; + + /** @gqlField greeting */ + static greetz(_: Query, info: GqlInfo): string { + return "Hello"; + } +} + +/** @gqlType */ +type Query = unknown; +``` + +## Output + +### SDL + +```graphql +type Query { + greeting: String +} + +type SomeType { + someField: String +} +``` + +### TypeScript + +```ts +import { GraphQLSchema, GraphQLObjectType, GraphQLString } from "graphql"; +import { SomeType as queryGreetingResolver } from "./StaticMethodWithInfoValue"; +export function getSchema(): GraphQLSchema { + const QueryType: GraphQLObjectType = new GraphQLObjectType({ + name: "Query", + fields() { + return { + greeting: { + name: "greeting", + type: GraphQLString, + resolve(source, _args, _context, info) { + return queryGreetingResolver.greetz(source, info); + } + } + }; + } + }); + const SomeTypeType: GraphQLObjectType = new GraphQLObjectType({ + name: "SomeType", + fields() { + return { + someField: { + name: "someField", + type: GraphQLString + } + }; + } + }); + return new GraphQLSchema({ + query: QueryType, + types: [QueryType, SomeTypeType] + }); +} +``` \ No newline at end of file diff --git a/src/tests/fixtures/semantic_nullability/nonNullDoesNotMatchInterface.invalid.ts.expected b/src/tests/fixtures/semantic_nullability/nonNullDoesNotMatchInterface.invalid.ts.expected deleted file mode 100644 index d5ef309c..00000000 --- a/src/tests/fixtures/semantic_nullability/nonNullDoesNotMatchInterface.invalid.ts.expected +++ /dev/null @@ -1,37 +0,0 @@ ------------------ -INPUT ------------------ -/** @gqlInterface */ -interface IPerson { - /** - * @killsParentOnException - * @gqlField - */ - name(): string; -} - -/** @gqlType */ -export class User implements IPerson { - __typename = "User" as const; - /** @gqlField */ - // @ts-ignore - name(): string | null { - if (Math.random() < 0.5) { - return null; - } - return "Alice"; - } -} - ------------------ -OUTPUT ------------------ -src/tests/fixtures/semantic_nullability/nonNullDoesNotMatchInterface.invalid.ts:4:7 - error: Interface field IPerson.name expects type String! but User.name is type String. - -4 * @killsParentOnException - ~~~~~~~~~~~~~~~~~~~~~~ - - src/tests/fixtures/semantic_nullability/nonNullDoesNotMatchInterface.invalid.ts:15:11 - 15 name(): string | null { - ~~~~~~~~~~~~~ - Related location diff --git a/src/tests/fixtures/semantic_nullability/nonNullDoesNotMatchInterface.invalid.ts.expected.md b/src/tests/fixtures/semantic_nullability/nonNullDoesNotMatchInterface.invalid.ts.expected.md new file mode 100644 index 00000000..93af175e --- /dev/null +++ b/src/tests/fixtures/semantic_nullability/nonNullDoesNotMatchInterface.invalid.ts.expected.md @@ -0,0 +1,41 @@ +## input + +```ts title="semantic_nullability/nonNullDoesNotMatchInterface.invalid.ts" +/** @gqlInterface */ +interface IPerson { + /** + * @killsParentOnException + * @gqlField + */ + name(): string; +} + +/** @gqlType */ +export class User implements IPerson { + __typename = "User" as const; + /** @gqlField */ + // @ts-ignore + name(): string | null { + if (Math.random() < 0.5) { + return null; + } + return "Alice"; + } +} +``` + +## Output + +### Error Report + +```text +src/tests/fixtures/semantic_nullability/nonNullDoesNotMatchInterface.invalid.ts:4:7 - error: Interface field IPerson.name expects type String! but User.name is type String. + +4 * @killsParentOnException + ~~~~~~~~~~~~~~~~~~~~~~ + + src/tests/fixtures/semantic_nullability/nonNullDoesNotMatchInterface.invalid.ts:15:11 + 15 name(): string | null { + ~~~~~~~~~~~~~ + Related location +``` \ No newline at end of file diff --git a/src/tests/fixtures/semantic_nullability/semanticNonNull.ts.expected b/src/tests/fixtures/semantic_nullability/semanticNonNull.ts.expected deleted file mode 100644 index 0a5b0fa2..00000000 --- a/src/tests/fixtures/semantic_nullability/semanticNonNull.ts.expected +++ /dev/null @@ -1,94 +0,0 @@ ------------------ -INPUT ------------------ -// { "strictSemanticNullability": true } - -/** @gqlType */ -export class User { - /** @gqlField */ - name(): string { - if (Math.random() < 0.5) { - throw new Error("Stuff happens..."); - } - return "Alice"; - } -} - ------------------ -OUTPUT ------------------ --- SDL -- -""" -Indicates that a position is semantically non null: it is only null if there is a matching error in the `errors` array. -In all other cases, the position is non-null. - -Tools doing code generation may use this information to generate the position as non-null if field errors are handled out of band: - -```graphql -type User { - # email is semantically non-null and can be generated as non-null by error-handling clients. - email: String @semanticNonNull -} -``` - -The `levels` argument indicates what levels are semantically non null in case of lists: - -```graphql -type User { - # friends is semantically non null - friends: [User] @semanticNonNull # same as @semanticNonNull(levels: [0]) - - # every friends[k] is semantically non null - friends: [User] @semanticNonNull(levels: [1]) - - # friends as well as every friends[k] is semantically non null - friends: [User] @semanticNonNull(levels: [0, 1]) -} -``` - -`levels` are zero indexed. -Passing a negative level or a level greater than the list dimension is an error. -""" -directive @semanticNonNull(levels: [Int] = [0]) on FIELD_DEFINITION - -type User { - name: String @semanticNonNull -} --- TypeScript -- -import { GraphQLSchema, GraphQLDirective, DirectiveLocation, GraphQLList, GraphQLInt, specifiedDirectives, GraphQLObjectType, GraphQLString, defaultFieldResolver } from "graphql"; -async function assertNonNull(value: T | Promise): Promise { - const awaited = await value; - if (awaited == null) - throw new Error("Cannot return null for semantically non-nullable field."); - return awaited; -} -export function getSchema(): GraphQLSchema { - const UserType: GraphQLObjectType = new GraphQLObjectType({ - name: "User", - fields() { - return { - name: { - name: "name", - type: GraphQLString, - resolve(source, args, context, info) { - return assertNonNull(defaultFieldResolver(source, args, context, info)); - } - } - }; - } - }); - return new GraphQLSchema({ - directives: [...specifiedDirectives, new GraphQLDirective({ - name: "semanticNonNull", - locations: [DirectiveLocation.FIELD_DEFINITION], - description: "Indicates that a position is semantically non null: it is only null if there is a matching error in the `errors` array.\nIn all other cases, the position is non-null.\n\nTools doing code generation may use this information to generate the position as non-null if field errors are handled out of band:\n\n```graphql\ntype User {\n # email is semantically non-null and can be generated as non-null by error-handling clients.\n email: String @semanticNonNull\n}\n```\n\nThe `levels` argument indicates what levels are semantically non null in case of lists:\n\n```graphql\ntype User {\n # friends is semantically non null\n friends: [User] @semanticNonNull # same as @semanticNonNull(levels: [0])\n\n # every friends[k] is semantically non null\n friends: [User] @semanticNonNull(levels: [1])\n\n # friends as well as every friends[k] is semantically non null\n friends: [User] @semanticNonNull(levels: [0, 1])\n}\n```\n\n`levels` are zero indexed.\nPassing a negative level or a level greater than the list dimension is an error.", - args: { - levels: { - type: new GraphQLList(GraphQLInt), - defaultValue: [0] - } - } - })], - types: [UserType] - }); -} diff --git a/src/tests/fixtures/semantic_nullability/semanticNonNull.ts.expected.md b/src/tests/fixtures/semantic_nullability/semanticNonNull.ts.expected.md new file mode 100644 index 00000000..8ab645eb --- /dev/null +++ b/src/tests/fixtures/semantic_nullability/semanticNonNull.ts.expected.md @@ -0,0 +1,101 @@ +## input + +```ts title="semantic_nullability/semanticNonNull.ts" +// { "strictSemanticNullability": true } + +/** @gqlType */ +export class User { + /** @gqlField */ + name(): string { + if (Math.random() < 0.5) { + throw new Error("Stuff happens..."); + } + return "Alice"; + } +} +``` + +## Output + +### SDL + +```graphql +""" +Indicates that a position is semantically non null: it is only null if there is a matching error in the `errors` array. +In all other cases, the position is non-null. + +Tools doing code generation may use this information to generate the position as non-null if field errors are handled out of band: + +```graphql +type User { + # email is semantically non-null and can be generated as non-null by error-handling clients. + email: String @semanticNonNull +} +``` + +The `levels` argument indicates what levels are semantically non null in case of lists: + +```graphql +type User { + # friends is semantically non null + friends: [User] @semanticNonNull # same as @semanticNonNull(levels: [0]) + + # every friends[k] is semantically non null + friends: [User] @semanticNonNull(levels: [1]) + + # friends as well as every friends[k] is semantically non null + friends: [User] @semanticNonNull(levels: [0, 1]) +} +``` + +`levels` are zero indexed. +Passing a negative level or a level greater than the list dimension is an error. +""" +directive @semanticNonNull(levels: [Int] = [0]) on FIELD_DEFINITION + +type User { + name: String @semanticNonNull +} +``` + +### TypeScript + +```ts +import { GraphQLSchema, GraphQLDirective, DirectiveLocation, GraphQLList, GraphQLInt, specifiedDirectives, GraphQLObjectType, GraphQLString, defaultFieldResolver } from "graphql"; +async function assertNonNull(value: T | Promise): Promise { + const awaited = await value; + if (awaited == null) + throw new Error("Cannot return null for semantically non-nullable field."); + return awaited; +} +export function getSchema(): GraphQLSchema { + const UserType: GraphQLObjectType = new GraphQLObjectType({ + name: "User", + fields() { + return { + name: { + name: "name", + type: GraphQLString, + resolve(source, args, context, info) { + return assertNonNull(defaultFieldResolver(source, args, context, info)); + } + } + }; + } + }); + return new GraphQLSchema({ + directives: [...specifiedDirectives, new GraphQLDirective({ + name: "semanticNonNull", + locations: [DirectiveLocation.FIELD_DEFINITION], + description: "Indicates that a position is semantically non null: it is only null if there is a matching error in the `errors` array.\nIn all other cases, the position is non-null.\n\nTools doing code generation may use this information to generate the position as non-null if field errors are handled out of band:\n\n```graphql\ntype User {\n # email is semantically non-null and can be generated as non-null by error-handling clients.\n email: String @semanticNonNull\n}\n```\n\nThe `levels` argument indicates what levels are semantically non null in case of lists:\n\n```graphql\ntype User {\n # friends is semantically non null\n friends: [User] @semanticNonNull # same as @semanticNonNull(levels: [0])\n\n # every friends[k] is semantically non null\n friends: [User] @semanticNonNull(levels: [1])\n\n # friends as well as every friends[k] is semantically non null\n friends: [User] @semanticNonNull(levels: [0, 1])\n}\n```\n\n`levels` are zero indexed.\nPassing a negative level or a level greater than the list dimension is an error.", + args: { + levels: { + type: new GraphQLList(GraphQLInt), + defaultValue: [0] + } + } + })], + types: [UserType] + }); +} +``` \ No newline at end of file diff --git a/src/tests/fixtures/semantic_nullability/semanticNonNullDoesNotMatchInterface.invalid.ts.expected b/src/tests/fixtures/semantic_nullability/semanticNonNullDoesNotMatchInterface.invalid.ts.expected deleted file mode 100644 index b81f66c7..00000000 --- a/src/tests/fixtures/semantic_nullability/semanticNonNullDoesNotMatchInterface.invalid.ts.expected +++ /dev/null @@ -1,36 +0,0 @@ ------------------ -INPUT ------------------ -// { "strictSemanticNullability": true } - -/** @gqlInterface */ -interface IPerson { - /** @gqlField */ - name(): string; -} - -/** @gqlType */ -export class User implements IPerson { - __typename = "User" as const; - /** @gqlField */ - // @ts-ignore - name(): string | null { - if (Math.random() < 0.5) { - throw new Error("Stuff happens..."); - } - return "Alice"; - } -} - ------------------ -OUTPUT ------------------ -src/tests/fixtures/semantic_nullability/semanticNonNullDoesNotMatchInterface.invalid.ts:6:11 - error: Interface field `User.name` expects a non-nullable type but `IPerson.name` is nullable. - -6 name(): string; - ~~~~~~ - - src/tests/fixtures/semantic_nullability/semanticNonNullDoesNotMatchInterface.invalid.ts:14:11 - 14 name(): string | null { - ~~~~~~~~~~~~~ - Related location diff --git a/src/tests/fixtures/semantic_nullability/semanticNonNullDoesNotMatchInterface.invalid.ts.expected.md b/src/tests/fixtures/semantic_nullability/semanticNonNullDoesNotMatchInterface.invalid.ts.expected.md new file mode 100644 index 00000000..cc5354d7 --- /dev/null +++ b/src/tests/fixtures/semantic_nullability/semanticNonNullDoesNotMatchInterface.invalid.ts.expected.md @@ -0,0 +1,40 @@ +## input + +```ts title="semantic_nullability/semanticNonNullDoesNotMatchInterface.invalid.ts" +// { "strictSemanticNullability": true } + +/** @gqlInterface */ +interface IPerson { + /** @gqlField */ + name(): string; +} + +/** @gqlType */ +export class User implements IPerson { + __typename = "User" as const; + /** @gqlField */ + // @ts-ignore + name(): string | null { + if (Math.random() < 0.5) { + throw new Error("Stuff happens..."); + } + return "Alice"; + } +} +``` + +## Output + +### Error Report + +```text +src/tests/fixtures/semantic_nullability/semanticNonNullDoesNotMatchInterface.invalid.ts:6:11 - error: Interface field `User.name` expects a non-nullable type but `IPerson.name` is nullable. + +6 name(): string; + ~~~~~~ + + src/tests/fixtures/semantic_nullability/semanticNonNullDoesNotMatchInterface.invalid.ts:14:11 + 14 name(): string | null { + ~~~~~~~~~~~~~ + Related location +``` \ No newline at end of file diff --git a/src/tests/fixtures/semantic_nullability/semanticNonNullMatchesInterface.ts.expected b/src/tests/fixtures/semantic_nullability/semanticNonNullMatchesInterface.ts.expected deleted file mode 100644 index 0fa9407e..00000000 --- a/src/tests/fixtures/semantic_nullability/semanticNonNullMatchesInterface.ts.expected +++ /dev/null @@ -1,119 +0,0 @@ ------------------ -INPUT ------------------ -// { "strictSemanticNullability": true } - -/** @gqlInterface */ -interface IPerson { - /** @gqlField */ - name(): string; -} - -/** @gqlType */ -export class User implements IPerson { - __typename = "User" as const; - /** @gqlField */ - name(): string { - if (Math.random() < 0.5) { - throw new Error("Stuff happens..."); - } - return "Alice"; - } -} - ------------------ -OUTPUT ------------------ --- SDL -- -""" -Indicates that a position is semantically non null: it is only null if there is a matching error in the `errors` array. -In all other cases, the position is non-null. - -Tools doing code generation may use this information to generate the position as non-null if field errors are handled out of band: - -```graphql -type User { - # email is semantically non-null and can be generated as non-null by error-handling clients. - email: String @semanticNonNull -} -``` - -The `levels` argument indicates what levels are semantically non null in case of lists: - -```graphql -type User { - # friends is semantically non null - friends: [User] @semanticNonNull # same as @semanticNonNull(levels: [0]) - - # every friends[k] is semantically non null - friends: [User] @semanticNonNull(levels: [1]) - - # friends as well as every friends[k] is semantically non null - friends: [User] @semanticNonNull(levels: [0, 1]) -} -``` - -`levels` are zero indexed. -Passing a negative level or a level greater than the list dimension is an error. -""" -directive @semanticNonNull(levels: [Int] = [0]) on FIELD_DEFINITION - -interface IPerson { - name: String @semanticNonNull -} - -type User implements IPerson { - name: String @semanticNonNull -} --- TypeScript -- -import { GraphQLSchema, GraphQLDirective, DirectiveLocation, GraphQLList, GraphQLInt, specifiedDirectives, GraphQLInterfaceType, GraphQLString, GraphQLObjectType, defaultFieldResolver } from "graphql"; -async function assertNonNull(value: T | Promise): Promise { - const awaited = await value; - if (awaited == null) - throw new Error("Cannot return null for semantically non-nullable field."); - return awaited; -} -export function getSchema(): GraphQLSchema { - const IPersonType: GraphQLInterfaceType = new GraphQLInterfaceType({ - name: "IPerson", - fields() { - return { - name: { - name: "name", - type: GraphQLString - } - }; - } - }); - const UserType: GraphQLObjectType = new GraphQLObjectType({ - name: "User", - fields() { - return { - name: { - name: "name", - type: GraphQLString, - resolve(source, args, context, info) { - return assertNonNull(defaultFieldResolver(source, args, context, info)); - } - } - }; - }, - interfaces() { - return [IPersonType]; - } - }); - return new GraphQLSchema({ - directives: [...specifiedDirectives, new GraphQLDirective({ - name: "semanticNonNull", - locations: [DirectiveLocation.FIELD_DEFINITION], - description: "Indicates that a position is semantically non null: it is only null if there is a matching error in the `errors` array.\nIn all other cases, the position is non-null.\n\nTools doing code generation may use this information to generate the position as non-null if field errors are handled out of band:\n\n```graphql\ntype User {\n # email is semantically non-null and can be generated as non-null by error-handling clients.\n email: String @semanticNonNull\n}\n```\n\nThe `levels` argument indicates what levels are semantically non null in case of lists:\n\n```graphql\ntype User {\n # friends is semantically non null\n friends: [User] @semanticNonNull # same as @semanticNonNull(levels: [0])\n\n # every friends[k] is semantically non null\n friends: [User] @semanticNonNull(levels: [1])\n\n # friends as well as every friends[k] is semantically non null\n friends: [User] @semanticNonNull(levels: [0, 1])\n}\n```\n\n`levels` are zero indexed.\nPassing a negative level or a level greater than the list dimension is an error.", - args: { - levels: { - type: new GraphQLList(GraphQLInt), - defaultValue: [0] - } - } - })], - types: [IPersonType, UserType] - }); -} diff --git a/src/tests/fixtures/semantic_nullability/semanticNonNullMatchesInterface.ts.expected.md b/src/tests/fixtures/semantic_nullability/semanticNonNullMatchesInterface.ts.expected.md new file mode 100644 index 00000000..d636c5c7 --- /dev/null +++ b/src/tests/fixtures/semantic_nullability/semanticNonNullMatchesInterface.ts.expected.md @@ -0,0 +1,126 @@ +## input + +```ts title="semantic_nullability/semanticNonNullMatchesInterface.ts" +// { "strictSemanticNullability": true } + +/** @gqlInterface */ +interface IPerson { + /** @gqlField */ + name(): string; +} + +/** @gqlType */ +export class User implements IPerson { + __typename = "User" as const; + /** @gqlField */ + name(): string { + if (Math.random() < 0.5) { + throw new Error("Stuff happens..."); + } + return "Alice"; + } +} +``` + +## Output + +### SDL + +```graphql +""" +Indicates that a position is semantically non null: it is only null if there is a matching error in the `errors` array. +In all other cases, the position is non-null. + +Tools doing code generation may use this information to generate the position as non-null if field errors are handled out of band: + +```graphql +type User { + # email is semantically non-null and can be generated as non-null by error-handling clients. + email: String @semanticNonNull +} +``` + +The `levels` argument indicates what levels are semantically non null in case of lists: + +```graphql +type User { + # friends is semantically non null + friends: [User] @semanticNonNull # same as @semanticNonNull(levels: [0]) + + # every friends[k] is semantically non null + friends: [User] @semanticNonNull(levels: [1]) + + # friends as well as every friends[k] is semantically non null + friends: [User] @semanticNonNull(levels: [0, 1]) +} +``` + +`levels` are zero indexed. +Passing a negative level or a level greater than the list dimension is an error. +""" +directive @semanticNonNull(levels: [Int] = [0]) on FIELD_DEFINITION + +interface IPerson { + name: String @semanticNonNull +} + +type User implements IPerson { + name: String @semanticNonNull +} +``` + +### TypeScript + +```ts +import { GraphQLSchema, GraphQLDirective, DirectiveLocation, GraphQLList, GraphQLInt, specifiedDirectives, GraphQLInterfaceType, GraphQLString, GraphQLObjectType, defaultFieldResolver } from "graphql"; +async function assertNonNull(value: T | Promise): Promise { + const awaited = await value; + if (awaited == null) + throw new Error("Cannot return null for semantically non-nullable field."); + return awaited; +} +export function getSchema(): GraphQLSchema { + const IPersonType: GraphQLInterfaceType = new GraphQLInterfaceType({ + name: "IPerson", + fields() { + return { + name: { + name: "name", + type: GraphQLString + } + }; + } + }); + const UserType: GraphQLObjectType = new GraphQLObjectType({ + name: "User", + fields() { + return { + name: { + name: "name", + type: GraphQLString, + resolve(source, args, context, info) { + return assertNonNull(defaultFieldResolver(source, args, context, info)); + } + } + }; + }, + interfaces() { + return [IPersonType]; + } + }); + return new GraphQLSchema({ + directives: [...specifiedDirectives, new GraphQLDirective({ + name: "semanticNonNull", + locations: [DirectiveLocation.FIELD_DEFINITION], + description: "Indicates that a position is semantically non null: it is only null if there is a matching error in the `errors` array.\nIn all other cases, the position is non-null.\n\nTools doing code generation may use this information to generate the position as non-null if field errors are handled out of band:\n\n```graphql\ntype User {\n # email is semantically non-null and can be generated as non-null by error-handling clients.\n email: String @semanticNonNull\n}\n```\n\nThe `levels` argument indicates what levels are semantically non null in case of lists:\n\n```graphql\ntype User {\n # friends is semantically non null\n friends: [User] @semanticNonNull # same as @semanticNonNull(levels: [0])\n\n # every friends[k] is semantically non null\n friends: [User] @semanticNonNull(levels: [1])\n\n # friends as well as every friends[k] is semantically non null\n friends: [User] @semanticNonNull(levels: [0, 1])\n}\n```\n\n`levels` are zero indexed.\nPassing a negative level or a level greater than the list dimension is an error.", + args: { + levels: { + type: new GraphQLList(GraphQLInt), + defaultValue: [0] + } + } + })], + types: [IPersonType, UserType] + }); +} +``` \ No newline at end of file diff --git a/src/tests/fixtures/semantic_nullability/semanticNull.ts.expected b/src/tests/fixtures/semantic_nullability/semanticNull.ts.expected deleted file mode 100644 index 9e02461f..00000000 --- a/src/tests/fixtures/semantic_nullability/semanticNull.ts.expected +++ /dev/null @@ -1,88 +0,0 @@ ------------------ -INPUT ------------------ -// { "strictSemanticNullability": true } - -/** @gqlType */ -export class User { - /** @gqlField */ - name(): string | null { - if (Math.random() < 0.25) { - return null; - } - if (Math.random() < 0.5) { - throw new Error("Stuff happens..."); - } - return "Alice"; - } -} - ------------------ -OUTPUT ------------------ --- SDL -- -""" -Indicates that a position is semantically non null: it is only null if there is a matching error in the `errors` array. -In all other cases, the position is non-null. - -Tools doing code generation may use this information to generate the position as non-null if field errors are handled out of band: - -```graphql -type User { - # email is semantically non-null and can be generated as non-null by error-handling clients. - email: String @semanticNonNull -} -``` - -The `levels` argument indicates what levels are semantically non null in case of lists: - -```graphql -type User { - # friends is semantically non null - friends: [User] @semanticNonNull # same as @semanticNonNull(levels: [0]) - - # every friends[k] is semantically non null - friends: [User] @semanticNonNull(levels: [1]) - - # friends as well as every friends[k] is semantically non null - friends: [User] @semanticNonNull(levels: [0, 1]) -} -``` - -`levels` are zero indexed. -Passing a negative level or a level greater than the list dimension is an error. -""" -directive @semanticNonNull(levels: [Int] = [0]) on FIELD_DEFINITION - -type User { - name: String -} --- TypeScript -- -import { GraphQLSchema, GraphQLDirective, DirectiveLocation, GraphQLList, GraphQLInt, specifiedDirectives, GraphQLObjectType, GraphQLString } from "graphql"; -export function getSchema(): GraphQLSchema { - const UserType: GraphQLObjectType = new GraphQLObjectType({ - name: "User", - fields() { - return { - name: { - name: "name", - type: GraphQLString - } - }; - } - }); - return new GraphQLSchema({ - directives: [...specifiedDirectives, new GraphQLDirective({ - name: "semanticNonNull", - locations: [DirectiveLocation.FIELD_DEFINITION], - description: "Indicates that a position is semantically non null: it is only null if there is a matching error in the `errors` array.\nIn all other cases, the position is non-null.\n\nTools doing code generation may use this information to generate the position as non-null if field errors are handled out of band:\n\n```graphql\ntype User {\n # email is semantically non-null and can be generated as non-null by error-handling clients.\n email: String @semanticNonNull\n}\n```\n\nThe `levels` argument indicates what levels are semantically non null in case of lists:\n\n```graphql\ntype User {\n # friends is semantically non null\n friends: [User] @semanticNonNull # same as @semanticNonNull(levels: [0])\n\n # every friends[k] is semantically non null\n friends: [User] @semanticNonNull(levels: [1])\n\n # friends as well as every friends[k] is semantically non null\n friends: [User] @semanticNonNull(levels: [0, 1])\n}\n```\n\n`levels` are zero indexed.\nPassing a negative level or a level greater than the list dimension is an error.", - args: { - levels: { - type: new GraphQLList(GraphQLInt), - defaultValue: [0] - } - } - })], - types: [UserType] - }); -} diff --git a/src/tests/fixtures/semantic_nullability/semanticNull.ts.expected.md b/src/tests/fixtures/semantic_nullability/semanticNull.ts.expected.md new file mode 100644 index 00000000..3ebd0c88 --- /dev/null +++ b/src/tests/fixtures/semantic_nullability/semanticNull.ts.expected.md @@ -0,0 +1,95 @@ +## input + +```ts title="semantic_nullability/semanticNull.ts" +// { "strictSemanticNullability": true } + +/** @gqlType */ +export class User { + /** @gqlField */ + name(): string | null { + if (Math.random() < 0.25) { + return null; + } + if (Math.random() < 0.5) { + throw new Error("Stuff happens..."); + } + return "Alice"; + } +} +``` + +## Output + +### SDL + +```graphql +""" +Indicates that a position is semantically non null: it is only null if there is a matching error in the `errors` array. +In all other cases, the position is non-null. + +Tools doing code generation may use this information to generate the position as non-null if field errors are handled out of band: + +```graphql +type User { + # email is semantically non-null and can be generated as non-null by error-handling clients. + email: String @semanticNonNull +} +``` + +The `levels` argument indicates what levels are semantically non null in case of lists: + +```graphql +type User { + # friends is semantically non null + friends: [User] @semanticNonNull # same as @semanticNonNull(levels: [0]) + + # every friends[k] is semantically non null + friends: [User] @semanticNonNull(levels: [1]) + + # friends as well as every friends[k] is semantically non null + friends: [User] @semanticNonNull(levels: [0, 1]) +} +``` + +`levels` are zero indexed. +Passing a negative level or a level greater than the list dimension is an error. +""" +directive @semanticNonNull(levels: [Int] = [0]) on FIELD_DEFINITION + +type User { + name: String +} +``` + +### TypeScript + +```ts +import { GraphQLSchema, GraphQLDirective, DirectiveLocation, GraphQLList, GraphQLInt, specifiedDirectives, GraphQLObjectType, GraphQLString } from "graphql"; +export function getSchema(): GraphQLSchema { + const UserType: GraphQLObjectType = new GraphQLObjectType({ + name: "User", + fields() { + return { + name: { + name: "name", + type: GraphQLString + } + }; + } + }); + return new GraphQLSchema({ + directives: [...specifiedDirectives, new GraphQLDirective({ + name: "semanticNonNull", + locations: [DirectiveLocation.FIELD_DEFINITION], + description: "Indicates that a position is semantically non null: it is only null if there is a matching error in the `errors` array.\nIn all other cases, the position is non-null.\n\nTools doing code generation may use this information to generate the position as non-null if field errors are handled out of band:\n\n```graphql\ntype User {\n # email is semantically non-null and can be generated as non-null by error-handling clients.\n email: String @semanticNonNull\n}\n```\n\nThe `levels` argument indicates what levels are semantically non null in case of lists:\n\n```graphql\ntype User {\n # friends is semantically non null\n friends: [User] @semanticNonNull # same as @semanticNonNull(levels: [0])\n\n # every friends[k] is semantically non null\n friends: [User] @semanticNonNull(levels: [1])\n\n # friends as well as every friends[k] is semantically non null\n friends: [User] @semanticNonNull(levels: [0, 1])\n}\n```\n\n`levels` are zero indexed.\nPassing a negative level or a level greater than the list dimension is an error.", + args: { + levels: { + type: new GraphQLList(GraphQLInt), + defaultValue: [0] + } + } + })], + types: [UserType] + }); +} +``` \ No newline at end of file diff --git a/src/tests/fixtures/subscriptions/InputTypeWithAsyncIterable.invalid.ts.expected b/src/tests/fixtures/subscriptions/InputTypeWithAsyncIterable.invalid.ts.expected deleted file mode 100644 index 968af335..00000000 --- a/src/tests/fixtures/subscriptions/InputTypeWithAsyncIterable.invalid.ts.expected +++ /dev/null @@ -1,15 +0,0 @@ ------------------ -INPUT ------------------ -/** @gqlInput */ -export type NotSubscription = { - greetings: AsyncIterable; -}; - ------------------ -OUTPUT ------------------ -src/tests/fixtures/subscriptions/InputTypeWithAsyncIterable.invalid.ts:3:14 - error: `AsyncIterable` is not a valid as an input type. - -3 greetings: AsyncIterable; - ~~~~~~~~~~~~~~~~~~~~~ diff --git a/src/tests/fixtures/subscriptions/InputTypeWithAsyncIterable.invalid.ts.expected.md b/src/tests/fixtures/subscriptions/InputTypeWithAsyncIterable.invalid.ts.expected.md new file mode 100644 index 00000000..e0b5bff1 --- /dev/null +++ b/src/tests/fixtures/subscriptions/InputTypeWithAsyncIterable.invalid.ts.expected.md @@ -0,0 +1,19 @@ +## input + +```ts title="subscriptions/InputTypeWithAsyncIterable.invalid.ts" +/** @gqlInput */ +export type NotSubscription = { + greetings: AsyncIterable; +}; +``` + +## Output + +### Error Report + +```text +src/tests/fixtures/subscriptions/InputTypeWithAsyncIterable.invalid.ts:3:14 - error: `AsyncIterable` is not a valid as an input type. + +3 greetings: AsyncIterable; + ~~~~~~~~~~~~~~~~~~~~~ +``` \ No newline at end of file diff --git a/src/tests/fixtures/subscriptions/InterfaceWithAsyncIterable.ts.expected b/src/tests/fixtures/subscriptions/InterfaceWithAsyncIterable.ts.expected deleted file mode 100644 index ce1827bb..00000000 --- a/src/tests/fixtures/subscriptions/InterfaceWithAsyncIterable.ts.expected +++ /dev/null @@ -1,34 +0,0 @@ ------------------ -INPUT ------------------ -/** @gqlInterface */ -export interface NotSubscription { - /** @gqlField */ - greetings(): AsyncIterable; -} - ------------------ -OUTPUT ------------------ --- SDL -- -interface NotSubscription { - greetings: [String!] -} --- TypeScript -- -import { GraphQLSchema, GraphQLInterfaceType, GraphQLList, GraphQLNonNull, GraphQLString } from "graphql"; -export function getSchema(): GraphQLSchema { - const NotSubscriptionType: GraphQLInterfaceType = new GraphQLInterfaceType({ - name: "NotSubscription", - fields() { - return { - greetings: { - name: "greetings", - type: new GraphQLList(new GraphQLNonNull(GraphQLString)) - } - }; - } - }); - return new GraphQLSchema({ - types: [NotSubscriptionType] - }); -} diff --git a/src/tests/fixtures/subscriptions/InterfaceWithAsyncIterable.ts.expected.md b/src/tests/fixtures/subscriptions/InterfaceWithAsyncIterable.ts.expected.md new file mode 100644 index 00000000..b2592cb3 --- /dev/null +++ b/src/tests/fixtures/subscriptions/InterfaceWithAsyncIterable.ts.expected.md @@ -0,0 +1,41 @@ +## input + +```ts title="subscriptions/InterfaceWithAsyncIterable.ts" +/** @gqlInterface */ +export interface NotSubscription { + /** @gqlField */ + greetings(): AsyncIterable; +} +``` + +## Output + +### SDL + +```graphql +interface NotSubscription { + greetings: [String!] +} +``` + +### TypeScript + +```ts +import { GraphQLSchema, GraphQLInterfaceType, GraphQLList, GraphQLNonNull, GraphQLString } from "graphql"; +export function getSchema(): GraphQLSchema { + const NotSubscriptionType: GraphQLInterfaceType = new GraphQLInterfaceType({ + name: "NotSubscription", + fields() { + return { + greetings: { + name: "greetings", + type: new GraphQLList(new GraphQLNonNull(GraphQLString)) + } + }; + } + }); + return new GraphQLSchema({ + types: [NotSubscriptionType] + }); +} +``` \ No newline at end of file diff --git a/src/tests/fixtures/subscriptions/NonSubscriptionClassWithAsyncIterable.ts.expected b/src/tests/fixtures/subscriptions/NonSubscriptionClassWithAsyncIterable.ts.expected deleted file mode 100644 index 01b29426..00000000 --- a/src/tests/fixtures/subscriptions/NonSubscriptionClassWithAsyncIterable.ts.expected +++ /dev/null @@ -1,67 +0,0 @@ ------------------ -INPUT ------------------ -// { "nullableByDefault": false } -/** @gqlType */ -export class User { - /** @gqlField */ - async *greetings(): AsyncIterable { - yield "Hello"; - yield "World"; - } - - /** @gqlField */ - async *maybeGreetings(): AsyncIterable | null { - null; - } - /** @gqlField */ - async *greetingsMaybe(): AsyncIterable { - null; - } - - /** @gqlField */ - async *maybeGreetingsMaybe(): AsyncIterable | null { - null; - } -} - ------------------ -OUTPUT ------------------ --- SDL -- -type User { - greetings: [String!]! - greetingsMaybe: [String]! - maybeGreetings: [String!] - maybeGreetingsMaybe: [String] -} --- TypeScript -- -import { GraphQLSchema, GraphQLObjectType, GraphQLNonNull, GraphQLList, GraphQLString } from "graphql"; -export function getSchema(): GraphQLSchema { - const UserType: GraphQLObjectType = new GraphQLObjectType({ - name: "User", - fields() { - return { - greetings: { - name: "greetings", - type: new GraphQLNonNull(new GraphQLList(new GraphQLNonNull(GraphQLString))) - }, - greetingsMaybe: { - name: "greetingsMaybe", - type: new GraphQLNonNull(new GraphQLList(GraphQLString)) - }, - maybeGreetings: { - name: "maybeGreetings", - type: new GraphQLList(new GraphQLNonNull(GraphQLString)) - }, - maybeGreetingsMaybe: { - name: "maybeGreetingsMaybe", - type: new GraphQLList(GraphQLString) - } - }; - } - }); - return new GraphQLSchema({ - types: [UserType] - }); -} diff --git a/src/tests/fixtures/subscriptions/NonSubscriptionClassWithAsyncIterable.ts.expected.md b/src/tests/fixtures/subscriptions/NonSubscriptionClassWithAsyncIterable.ts.expected.md new file mode 100644 index 00000000..31bde12f --- /dev/null +++ b/src/tests/fixtures/subscriptions/NonSubscriptionClassWithAsyncIterable.ts.expected.md @@ -0,0 +1,74 @@ +## input + +```ts title="subscriptions/NonSubscriptionClassWithAsyncIterable.ts" +// { "nullableByDefault": false } +/** @gqlType */ +export class User { + /** @gqlField */ + async *greetings(): AsyncIterable { + yield "Hello"; + yield "World"; + } + + /** @gqlField */ + async *maybeGreetings(): AsyncIterable | null { + null; + } + /** @gqlField */ + async *greetingsMaybe(): AsyncIterable { + null; + } + + /** @gqlField */ + async *maybeGreetingsMaybe(): AsyncIterable | null { + null; + } +} +``` + +## Output + +### SDL + +```graphql +type User { + greetings: [String!]! + greetingsMaybe: [String]! + maybeGreetings: [String!] + maybeGreetingsMaybe: [String] +} +``` + +### TypeScript + +```ts +import { GraphQLSchema, GraphQLObjectType, GraphQLNonNull, GraphQLList, GraphQLString } from "graphql"; +export function getSchema(): GraphQLSchema { + const UserType: GraphQLObjectType = new GraphQLObjectType({ + name: "User", + fields() { + return { + greetings: { + name: "greetings", + type: new GraphQLNonNull(new GraphQLList(new GraphQLNonNull(GraphQLString))) + }, + greetingsMaybe: { + name: "greetingsMaybe", + type: new GraphQLNonNull(new GraphQLList(GraphQLString)) + }, + maybeGreetings: { + name: "maybeGreetings", + type: new GraphQLList(new GraphQLNonNull(GraphQLString)) + }, + maybeGreetingsMaybe: { + name: "maybeGreetingsMaybe", + type: new GraphQLList(GraphQLString) + } + }; + } + }); + return new GraphQLSchema({ + types: [UserType] + }); +} +``` \ No newline at end of file diff --git a/src/tests/fixtures/subscriptions/SubscriptionClassWithAsyncIterable.invalid.ts.expected b/src/tests/fixtures/subscriptions/SubscriptionClassWithAsyncIterable.invalid.ts.expected deleted file mode 100644 index c51fd9d9..00000000 --- a/src/tests/fixtures/subscriptions/SubscriptionClassWithAsyncIterable.invalid.ts.expected +++ /dev/null @@ -1,19 +0,0 @@ ------------------ -INPUT ------------------ -/** @gqlType */ -export class Subscription { - /** @gqlField */ - async *greetings(): AsyncIterable { - yield "Hello"; - yield "World"; - } -} - ------------------ -OUTPUT ------------------ -src/tests/fixtures/subscriptions/SubscriptionClassWithAsyncIterable.invalid.ts:2:14 - error: Operation types `Query`, `Mutation`, and `Subscription` must be defined as type aliases of `unknown`. E.g. `type Query = unknown`. This is because GraphQL servers do not have an agreed upon way to produce root values, and Grats errs on the side of safety. If you are trying to implement dependency injection, consider using the `context` argument passed to each resolver instead. If you have a strong use case for a concrete root value, please file an issue. - -2 export class Subscription { - ~~~~~~~~~~~~ diff --git a/src/tests/fixtures/subscriptions/SubscriptionClassWithAsyncIterable.invalid.ts.expected.md b/src/tests/fixtures/subscriptions/SubscriptionClassWithAsyncIterable.invalid.ts.expected.md new file mode 100644 index 00000000..2134fcf6 --- /dev/null +++ b/src/tests/fixtures/subscriptions/SubscriptionClassWithAsyncIterable.invalid.ts.expected.md @@ -0,0 +1,23 @@ +## input + +```ts title="subscriptions/SubscriptionClassWithAsyncIterable.invalid.ts" +/** @gqlType */ +export class Subscription { + /** @gqlField */ + async *greetings(): AsyncIterable { + yield "Hello"; + yield "World"; + } +} +``` + +## Output + +### Error Report + +```text +src/tests/fixtures/subscriptions/SubscriptionClassWithAsyncIterable.invalid.ts:2:14 - error: Operation types `Query`, `Mutation`, and `Subscription` must be defined as type aliases of `unknown`. E.g. `type Query = unknown`. This is because GraphQL servers do not have an agreed upon way to produce root values, and Grats errs on the side of safety. If you are trying to implement dependency injection, consider using the `context` argument passed to each resolver instead. If you have a strong use case for a concrete root value, please file an issue. + +2 export class Subscription { + ~~~~~~~~~~~~ +``` \ No newline at end of file diff --git a/src/tests/fixtures/subscriptions/SubscriptionFunctionFieldWithAsyncIterable.ts.expected b/src/tests/fixtures/subscriptions/SubscriptionFunctionFieldWithAsyncIterable.ts.expected deleted file mode 100644 index 9d339077..00000000 --- a/src/tests/fixtures/subscriptions/SubscriptionFunctionFieldWithAsyncIterable.ts.expected +++ /dev/null @@ -1,103 +0,0 @@ ------------------ -INPUT ------------------ -// { "nullableByDefault": false } -/** @gqlType */ -export type Subscription = unknown; - -/** @gqlField */ -export async function* greetings(_: Subscription): AsyncIterable { - yield "Hello"; - yield "World"; -} - -/** @gqlField */ -export async function* maybeGreetings( - _: Subscription, -): AsyncIterable | null { - yield "Hello"; - yield "World"; -} - -/** @gqlField */ -export async function* greetingsMaybe( - _: Subscription, -): AsyncIterable { - yield "Hello"; - yield null; - yield "World"; -} - -/** @gqlField */ -export async function* maybeGreetingsMaybe( - _: Subscription, -): AsyncIterable | null { - return null; -} - ------------------ -OUTPUT ------------------ --- SDL -- -type Subscription { - greetings: String! - greetingsMaybe: String - maybeGreetings: String - maybeGreetingsMaybe: String -} --- TypeScript -- -import { GraphQLSchema, GraphQLObjectType, GraphQLNonNull, GraphQLString } from "graphql"; -import { greetings as subscriptionGreetingsResolver, greetingsMaybe as subscriptionGreetingsMaybeResolver, maybeGreetings as subscriptionMaybeGreetingsResolver, maybeGreetingsMaybe as subscriptionMaybeGreetingsMaybeResolver } from "./SubscriptionFunctionFieldWithAsyncIterable"; -export function getSchema(): GraphQLSchema { - const SubscriptionType: GraphQLObjectType = new GraphQLObjectType({ - name: "Subscription", - fields() { - return { - greetings: { - name: "greetings", - type: new GraphQLNonNull(GraphQLString), - subscribe(source) { - return subscriptionGreetingsResolver(source); - }, - resolve(payload) { - return payload; - } - }, - greetingsMaybe: { - name: "greetingsMaybe", - type: GraphQLString, - subscribe(source) { - return subscriptionGreetingsMaybeResolver(source); - }, - resolve(payload) { - return payload; - } - }, - maybeGreetings: { - name: "maybeGreetings", - type: GraphQLString, - subscribe(source) { - return subscriptionMaybeGreetingsResolver(source); - }, - resolve(payload) { - return payload; - } - }, - maybeGreetingsMaybe: { - name: "maybeGreetingsMaybe", - type: GraphQLString, - subscribe(source) { - return subscriptionMaybeGreetingsMaybeResolver(source); - }, - resolve(payload) { - return payload; - } - } - }; - } - }); - return new GraphQLSchema({ - subscription: SubscriptionType, - types: [SubscriptionType] - }); -} diff --git a/src/tests/fixtures/subscriptions/SubscriptionFunctionFieldWithAsyncIterable.ts.expected.md b/src/tests/fixtures/subscriptions/SubscriptionFunctionFieldWithAsyncIterable.ts.expected.md new file mode 100644 index 00000000..a9c9f854 --- /dev/null +++ b/src/tests/fixtures/subscriptions/SubscriptionFunctionFieldWithAsyncIterable.ts.expected.md @@ -0,0 +1,110 @@ +## input + +```ts title="subscriptions/SubscriptionFunctionFieldWithAsyncIterable.ts" +// { "nullableByDefault": false } +/** @gqlType */ +export type Subscription = unknown; + +/** @gqlField */ +export async function* greetings(_: Subscription): AsyncIterable { + yield "Hello"; + yield "World"; +} + +/** @gqlField */ +export async function* maybeGreetings( + _: Subscription, +): AsyncIterable | null { + yield "Hello"; + yield "World"; +} + +/** @gqlField */ +export async function* greetingsMaybe( + _: Subscription, +): AsyncIterable { + yield "Hello"; + yield null; + yield "World"; +} + +/** @gqlField */ +export async function* maybeGreetingsMaybe( + _: Subscription, +): AsyncIterable | null { + return null; +} +``` + +## Output + +### SDL + +```graphql +type Subscription { + greetings: String! + greetingsMaybe: String + maybeGreetings: String + maybeGreetingsMaybe: String +} +``` + +### TypeScript + +```ts +import { GraphQLSchema, GraphQLObjectType, GraphQLNonNull, GraphQLString } from "graphql"; +import { greetings as subscriptionGreetingsResolver, greetingsMaybe as subscriptionGreetingsMaybeResolver, maybeGreetings as subscriptionMaybeGreetingsResolver, maybeGreetingsMaybe as subscriptionMaybeGreetingsMaybeResolver } from "./SubscriptionFunctionFieldWithAsyncIterable"; +export function getSchema(): GraphQLSchema { + const SubscriptionType: GraphQLObjectType = new GraphQLObjectType({ + name: "Subscription", + fields() { + return { + greetings: { + name: "greetings", + type: new GraphQLNonNull(GraphQLString), + subscribe(source) { + return subscriptionGreetingsResolver(source); + }, + resolve(payload) { + return payload; + } + }, + greetingsMaybe: { + name: "greetingsMaybe", + type: GraphQLString, + subscribe(source) { + return subscriptionGreetingsMaybeResolver(source); + }, + resolve(payload) { + return payload; + } + }, + maybeGreetings: { + name: "maybeGreetings", + type: GraphQLString, + subscribe(source) { + return subscriptionMaybeGreetingsResolver(source); + }, + resolve(payload) { + return payload; + } + }, + maybeGreetingsMaybe: { + name: "maybeGreetingsMaybe", + type: GraphQLString, + subscribe(source) { + return subscriptionMaybeGreetingsMaybeResolver(source); + }, + resolve(payload) { + return payload; + } + } + }; + } + }); + return new GraphQLSchema({ + subscription: SubscriptionType, + types: [SubscriptionType] + }); +} +``` \ No newline at end of file diff --git a/src/tests/fixtures/todo/EnumFromUnionTypeWithVariantWithDescription.ts.expected b/src/tests/fixtures/todo/EnumFromUnionTypeWithVariantWithDescription.ts.expected deleted file mode 100644 index b6dd02ea..00000000 --- a/src/tests/fixtures/todo/EnumFromUnionTypeWithVariantWithDescription.ts.expected +++ /dev/null @@ -1,57 +0,0 @@ ------------------ -INPUT ------------------ -/** @gqlType */ -export default class SomeType { - /** @gqlField */ - hello: MyEnum; -} - -/** @gqlEnum */ -type MyEnum = - /** VALIDATED! */ - | "VALID" - /** INVALIDATED! */ - | "INVALID"; - ------------------ -OUTPUT ------------------ --- SDL -- -enum MyEnum { - INVALID - VALID -} - -type SomeType { - hello: MyEnum -} --- TypeScript -- -import { GraphQLSchema, GraphQLEnumType, GraphQLObjectType } from "graphql"; -export function getSchema(): GraphQLSchema { - const MyEnumType: GraphQLEnumType = new GraphQLEnumType({ - name: "MyEnum", - values: { - INVALID: { - value: "INVALID" - }, - VALID: { - value: "VALID" - } - } - }); - const SomeTypeType: GraphQLObjectType = new GraphQLObjectType({ - name: "SomeType", - fields() { - return { - hello: { - name: "hello", - type: MyEnumType - } - }; - } - }); - return new GraphQLSchema({ - types: [MyEnumType, SomeTypeType] - }); -} diff --git a/src/tests/fixtures/todo/EnumFromUnionTypeWithVariantWithDescription.ts.expected.md b/src/tests/fixtures/todo/EnumFromUnionTypeWithVariantWithDescription.ts.expected.md new file mode 100644 index 00000000..190cb305 --- /dev/null +++ b/src/tests/fixtures/todo/EnumFromUnionTypeWithVariantWithDescription.ts.expected.md @@ -0,0 +1,64 @@ +## input + +```ts title="todo/EnumFromUnionTypeWithVariantWithDescription.ts" +/** @gqlType */ +export default class SomeType { + /** @gqlField */ + hello: MyEnum; +} + +/** @gqlEnum */ +type MyEnum = + /** VALIDATED! */ + | "VALID" + /** INVALIDATED! */ + | "INVALID"; +``` + +## Output + +### SDL + +```graphql +enum MyEnum { + INVALID + VALID +} + +type SomeType { + hello: MyEnum +} +``` + +### TypeScript + +```ts +import { GraphQLSchema, GraphQLEnumType, GraphQLObjectType } from "graphql"; +export function getSchema(): GraphQLSchema { + const MyEnumType: GraphQLEnumType = new GraphQLEnumType({ + name: "MyEnum", + values: { + INVALID: { + value: "INVALID" + }, + VALID: { + value: "VALID" + } + } + }); + const SomeTypeType: GraphQLObjectType = new GraphQLObjectType({ + name: "SomeType", + fields() { + return { + hello: { + name: "hello", + type: MyEnumType + } + }; + } + }); + return new GraphQLSchema({ + types: [MyEnumType, SomeTypeType] + }); +} +``` \ No newline at end of file diff --git a/src/tests/fixtures/todo/RedefineBuiltinScalar.ts.expected b/src/tests/fixtures/todo/RedefineBuiltinScalar.ts.expected deleted file mode 100644 index 3f410dac..00000000 --- a/src/tests/fixtures/todo/RedefineBuiltinScalar.ts.expected +++ /dev/null @@ -1,18 +0,0 @@ ------------------ -INPUT ------------------ -/** @gqlScalar String */ -export type MyUrl = string; - ------------------ -OUTPUT ------------------ --- SDL -- - --- TypeScript -- -import { GraphQLSchema } from "graphql"; -export function getSchema(): GraphQLSchema { - return new GraphQLSchema({ - types: [] - }); -} diff --git a/src/tests/fixtures/todo/RedefineBuiltinScalar.ts.expected.md b/src/tests/fixtures/todo/RedefineBuiltinScalar.ts.expected.md new file mode 100644 index 00000000..a0380126 --- /dev/null +++ b/src/tests/fixtures/todo/RedefineBuiltinScalar.ts.expected.md @@ -0,0 +1,25 @@ +## input + +```ts title="todo/RedefineBuiltinScalar.ts" +/** @gqlScalar String */ +export type MyUrl = string; +``` + +## Output + +### SDL + +```graphql + +``` + +### TypeScript + +```ts +import { GraphQLSchema } from "graphql"; +export function getSchema(): GraphQLSchema { + return new GraphQLSchema({ + types: [] + }); +} +``` \ No newline at end of file diff --git a/src/tests/fixtures/todo/userExample.ts.expected b/src/tests/fixtures/todo/userExample.ts.expected deleted file mode 100644 index e820b983..00000000 --- a/src/tests/fixtures/todo/userExample.ts.expected +++ /dev/null @@ -1,81 +0,0 @@ ------------------ -INPUT ------------------ -/** @gqlType */ -type SomeType = {}; - -/** @gqlField */ -export function me(_: SomeType): User { - return { firstName: "John", lastName: "Doe" }; -} - -/** @gqlType */ -type User = { - /** @gqlField */ - firstName: string; - /** @gqlField */ - lastName: string; -}; - -/** @gqlField */ -export function fullName(user: User): string { - return `${user.firstName} ${user.lastName}`; -} - ------------------ -OUTPUT ------------------ --- SDL -- -type SomeType { - me: User -} - -type User { - firstName: String - fullName: String - lastName: String -} --- TypeScript -- -import { GraphQLSchema, GraphQLObjectType, GraphQLString } from "graphql"; -import { fullName as userFullNameResolver, me as someTypeMeResolver } from "./userExample"; -export function getSchema(): GraphQLSchema { - const UserType: GraphQLObjectType = new GraphQLObjectType({ - name: "User", - fields() { - return { - firstName: { - name: "firstName", - type: GraphQLString - }, - fullName: { - name: "fullName", - type: GraphQLString, - resolve(source) { - return userFullNameResolver(source); - } - }, - lastName: { - name: "lastName", - type: GraphQLString - } - }; - } - }); - const SomeTypeType: GraphQLObjectType = new GraphQLObjectType({ - name: "SomeType", - fields() { - return { - me: { - name: "me", - type: UserType, - resolve(source) { - return someTypeMeResolver(source); - } - } - }; - } - }); - return new GraphQLSchema({ - types: [SomeTypeType, UserType] - }); -} diff --git a/src/tests/fixtures/todo/userExample.ts.expected.md b/src/tests/fixtures/todo/userExample.ts.expected.md new file mode 100644 index 00000000..70882891 --- /dev/null +++ b/src/tests/fixtures/todo/userExample.ts.expected.md @@ -0,0 +1,88 @@ +## input + +```ts title="todo/userExample.ts" +/** @gqlType */ +type SomeType = {}; + +/** @gqlField */ +export function me(_: SomeType): User { + return { firstName: "John", lastName: "Doe" }; +} + +/** @gqlType */ +type User = { + /** @gqlField */ + firstName: string; + /** @gqlField */ + lastName: string; +}; + +/** @gqlField */ +export function fullName(user: User): string { + return `${user.firstName} ${user.lastName}`; +} +``` + +## Output + +### SDL + +```graphql +type SomeType { + me: User +} + +type User { + firstName: String + fullName: String + lastName: String +} +``` + +### TypeScript + +```ts +import { GraphQLSchema, GraphQLObjectType, GraphQLString } from "graphql"; +import { fullName as userFullNameResolver, me as someTypeMeResolver } from "./userExample"; +export function getSchema(): GraphQLSchema { + const UserType: GraphQLObjectType = new GraphQLObjectType({ + name: "User", + fields() { + return { + firstName: { + name: "firstName", + type: GraphQLString + }, + fullName: { + name: "fullName", + type: GraphQLString, + resolve(source) { + return userFullNameResolver(source); + } + }, + lastName: { + name: "lastName", + type: GraphQLString + } + }; + } + }); + const SomeTypeType: GraphQLObjectType = new GraphQLObjectType({ + name: "SomeType", + fields() { + return { + me: { + name: "me", + type: UserType, + resolve(source) { + return someTypeMeResolver(source); + } + } + }; + } + }); + return new GraphQLSchema({ + types: [SomeTypeType, UserType] + }); +} +``` \ No newline at end of file diff --git a/src/tests/fixtures/top_level_fields/queryField.ts.expected b/src/tests/fixtures/top_level_fields/queryField.ts.expected deleted file mode 100644 index 985cfd92..00000000 --- a/src/tests/fixtures/top_level_fields/queryField.ts.expected +++ /dev/null @@ -1,38 +0,0 @@ ------------------ -INPUT ------------------ -/** @gqlQueryField */ -export function greeting(): string { - return "Hello world"; -} - ------------------ -OUTPUT ------------------ --- SDL -- -type Query { - greeting: String -} --- TypeScript -- -import { GraphQLSchema, GraphQLObjectType, GraphQLString } from "graphql"; -import { greeting as queryGreetingResolver } from "./queryField"; -export function getSchema(): GraphQLSchema { - const QueryType: GraphQLObjectType = new GraphQLObjectType({ - name: "Query", - fields() { - return { - greeting: { - name: "greeting", - type: GraphQLString, - resolve() { - return queryGreetingResolver(); - } - } - }; - } - }); - return new GraphQLSchema({ - query: QueryType, - types: [QueryType] - }); -} diff --git a/src/tests/fixtures/top_level_fields/queryField.ts.expected.md b/src/tests/fixtures/top_level_fields/queryField.ts.expected.md new file mode 100644 index 00000000..ec7d2514 --- /dev/null +++ b/src/tests/fixtures/top_level_fields/queryField.ts.expected.md @@ -0,0 +1,45 @@ +## input + +```ts title="top_level_fields/queryField.ts" +/** @gqlQueryField */ +export function greeting(): string { + return "Hello world"; +} +``` + +## Output + +### SDL + +```graphql +type Query { + greeting: String +} +``` + +### TypeScript + +```ts +import { GraphQLSchema, GraphQLObjectType, GraphQLString } from "graphql"; +import { greeting as queryGreetingResolver } from "./queryField"; +export function getSchema(): GraphQLSchema { + const QueryType: GraphQLObjectType = new GraphQLObjectType({ + name: "Query", + fields() { + return { + greeting: { + name: "greeting", + type: GraphQLString, + resolve() { + return queryGreetingResolver(); + } + } + }; + } + }); + return new GraphQLSchema({ + query: QueryType, + types: [QueryType] + }); +} +``` \ No newline at end of file diff --git a/src/tests/fixtures/top_level_fields/queryFieldOnMethod.invalid.ts.expected b/src/tests/fixtures/top_level_fields/queryFieldOnMethod.invalid.ts.expected deleted file mode 100644 index 67f57ae3..00000000 --- a/src/tests/fixtures/top_level_fields/queryFieldOnMethod.invalid.ts.expected +++ /dev/null @@ -1,17 +0,0 @@ ------------------ -INPUT ------------------ -export class SomeNonGraphQLClass { - /** @gqlQueryField */ - greeting(): string { - return "Hello world"; - } -} - ------------------ -OUTPUT ------------------ -src/tests/fixtures/top_level_fields/queryFieldOnMethod.invalid.ts:2:7 - error: `@gqlQueryField` can only be used on function or static method declarations. - -2 /** @gqlQueryField */ - ~~~~~~~~~~~~~~~ diff --git a/src/tests/fixtures/top_level_fields/queryFieldOnMethod.invalid.ts.expected.md b/src/tests/fixtures/top_level_fields/queryFieldOnMethod.invalid.ts.expected.md new file mode 100644 index 00000000..7fe5564e --- /dev/null +++ b/src/tests/fixtures/top_level_fields/queryFieldOnMethod.invalid.ts.expected.md @@ -0,0 +1,21 @@ +## input + +```ts title="top_level_fields/queryFieldOnMethod.invalid.ts" +export class SomeNonGraphQLClass { + /** @gqlQueryField */ + greeting(): string { + return "Hello world"; + } +} +``` + +## Output + +### Error Report + +```text +src/tests/fixtures/top_level_fields/queryFieldOnMethod.invalid.ts:2:7 - error: `@gqlQueryField` can only be used on function or static method declarations. + +2 /** @gqlQueryField */ + ~~~~~~~~~~~~~~~ +``` \ No newline at end of file diff --git a/src/tests/fixtures/top_level_fields/queryFieldOnStaticMethod.ts.expected b/src/tests/fixtures/top_level_fields/queryFieldOnStaticMethod.ts.expected deleted file mode 100644 index 3cc3d846..00000000 --- a/src/tests/fixtures/top_level_fields/queryFieldOnStaticMethod.ts.expected +++ /dev/null @@ -1,40 +0,0 @@ ------------------ -INPUT ------------------ -export class SomeNonGraphQLClass { - /** @gqlQueryField */ - static greeting(): string { - return "Hello world"; - } -} - ------------------ -OUTPUT ------------------ --- SDL -- -type Query { - greeting: String -} --- TypeScript -- -import { GraphQLSchema, GraphQLObjectType, GraphQLString } from "graphql"; -import { SomeNonGraphQLClass as queryGreetingResolver } from "./queryFieldOnStaticMethod"; -export function getSchema(): GraphQLSchema { - const QueryType: GraphQLObjectType = new GraphQLObjectType({ - name: "Query", - fields() { - return { - greeting: { - name: "greeting", - type: GraphQLString, - resolve() { - return queryGreetingResolver.greeting(); - } - } - }; - } - }); - return new GraphQLSchema({ - query: QueryType, - types: [QueryType] - }); -} diff --git a/src/tests/fixtures/top_level_fields/queryFieldOnStaticMethod.ts.expected.md b/src/tests/fixtures/top_level_fields/queryFieldOnStaticMethod.ts.expected.md new file mode 100644 index 00000000..3bb27e64 --- /dev/null +++ b/src/tests/fixtures/top_level_fields/queryFieldOnStaticMethod.ts.expected.md @@ -0,0 +1,47 @@ +## input + +```ts title="top_level_fields/queryFieldOnStaticMethod.ts" +export class SomeNonGraphQLClass { + /** @gqlQueryField */ + static greeting(): string { + return "Hello world"; + } +} +``` + +## Output + +### SDL + +```graphql +type Query { + greeting: String +} +``` + +### TypeScript + +```ts +import { GraphQLSchema, GraphQLObjectType, GraphQLString } from "graphql"; +import { SomeNonGraphQLClass as queryGreetingResolver } from "./queryFieldOnStaticMethod"; +export function getSchema(): GraphQLSchema { + const QueryType: GraphQLObjectType = new GraphQLObjectType({ + name: "Query", + fields() { + return { + greeting: { + name: "greeting", + type: GraphQLString, + resolve() { + return queryGreetingResolver.greeting(); + } + } + }; + } + }); + return new GraphQLSchema({ + query: QueryType, + types: [QueryType] + }); +} +``` \ No newline at end of file diff --git a/src/tests/fixtures/top_level_fields/queryFieldRenamed.ts.expected b/src/tests/fixtures/top_level_fields/queryFieldRenamed.ts.expected deleted file mode 100644 index 9f484193..00000000 --- a/src/tests/fixtures/top_level_fields/queryFieldRenamed.ts.expected +++ /dev/null @@ -1,38 +0,0 @@ ------------------ -INPUT ------------------ -/** @gqlQueryField greeting */ -export function greetz(): string { - return "Hello world"; -} - ------------------ -OUTPUT ------------------ --- SDL -- -type Query { - greeting: String -} --- TypeScript -- -import { GraphQLSchema, GraphQLObjectType, GraphQLString } from "graphql"; -import { greetz as queryGreetingResolver } from "./queryFieldRenamed"; -export function getSchema(): GraphQLSchema { - const QueryType: GraphQLObjectType = new GraphQLObjectType({ - name: "Query", - fields() { - return { - greeting: { - name: "greeting", - type: GraphQLString, - resolve() { - return queryGreetingResolver(); - } - } - }; - } - }); - return new GraphQLSchema({ - query: QueryType, - types: [QueryType] - }); -} diff --git a/src/tests/fixtures/top_level_fields/queryFieldRenamed.ts.expected.md b/src/tests/fixtures/top_level_fields/queryFieldRenamed.ts.expected.md new file mode 100644 index 00000000..cdb30197 --- /dev/null +++ b/src/tests/fixtures/top_level_fields/queryFieldRenamed.ts.expected.md @@ -0,0 +1,45 @@ +## input + +```ts title="top_level_fields/queryFieldRenamed.ts" +/** @gqlQueryField greeting */ +export function greetz(): string { + return "Hello world"; +} +``` + +## Output + +### SDL + +```graphql +type Query { + greeting: String +} +``` + +### TypeScript + +```ts +import { GraphQLSchema, GraphQLObjectType, GraphQLString } from "graphql"; +import { greetz as queryGreetingResolver } from "./queryFieldRenamed"; +export function getSchema(): GraphQLSchema { + const QueryType: GraphQLObjectType = new GraphQLObjectType({ + name: "Query", + fields() { + return { + greeting: { + name: "greeting", + type: GraphQLString, + resolve() { + return queryGreetingResolver(); + } + } + }; + } + }); + return new GraphQLSchema({ + query: QueryType, + types: [QueryType] + }); +} +``` \ No newline at end of file diff --git a/src/tests/fixtures/top_level_fields/queryFieldWithExplicitlyDefinedQuery.ts.expected b/src/tests/fixtures/top_level_fields/queryFieldWithExplicitlyDefinedQuery.ts.expected deleted file mode 100644 index d4b1beec..00000000 --- a/src/tests/fixtures/top_level_fields/queryFieldWithExplicitlyDefinedQuery.ts.expected +++ /dev/null @@ -1,48 +0,0 @@ ------------------ -INPUT ------------------ -/** @gqlQueryField */ -export function greeting(): string { - return "Hello world"; -} - -/** - * I might want to explicitly define a type here to provide a description. - * - * @gqlType */ -export type Query = unknown; - ------------------ -OUTPUT ------------------ --- SDL -- -""" -I might want to explicitly define a type here to provide a description. -""" -type Query { - greeting: String -} --- TypeScript -- -import { GraphQLSchema, GraphQLObjectType, GraphQLString } from "graphql"; -import { greeting as queryGreetingResolver } from "./queryFieldWithExplicitlyDefinedQuery"; -export function getSchema(): GraphQLSchema { - const QueryType: GraphQLObjectType = new GraphQLObjectType({ - name: "Query", - description: "I might want to explicitly define a type here to provide a description.", - fields() { - return { - greeting: { - name: "greeting", - type: GraphQLString, - resolve() { - return queryGreetingResolver(); - } - } - }; - } - }); - return new GraphQLSchema({ - query: QueryType, - types: [QueryType] - }); -} diff --git a/src/tests/fixtures/top_level_fields/queryFieldWithExplicitlyDefinedQuery.ts.expected.md b/src/tests/fixtures/top_level_fields/queryFieldWithExplicitlyDefinedQuery.ts.expected.md new file mode 100644 index 00000000..9c8cb35a --- /dev/null +++ b/src/tests/fixtures/top_level_fields/queryFieldWithExplicitlyDefinedQuery.ts.expected.md @@ -0,0 +1,55 @@ +## input + +```ts title="top_level_fields/queryFieldWithExplicitlyDefinedQuery.ts" +/** @gqlQueryField */ +export function greeting(): string { + return "Hello world"; +} + +/** + * I might want to explicitly define a type here to provide a description. + * + * @gqlType */ +export type Query = unknown; +``` + +## Output + +### SDL + +```graphql +""" +I might want to explicitly define a type here to provide a description. +""" +type Query { + greeting: String +} +``` + +### TypeScript + +```ts +import { GraphQLSchema, GraphQLObjectType, GraphQLString } from "graphql"; +import { greeting as queryGreetingResolver } from "./queryFieldWithExplicitlyDefinedQuery"; +export function getSchema(): GraphQLSchema { + const QueryType: GraphQLObjectType = new GraphQLObjectType({ + name: "Query", + description: "I might want to explicitly define a type here to provide a description.", + fields() { + return { + greeting: { + name: "greeting", + type: GraphQLString, + resolve() { + return queryGreetingResolver(); + } + } + }; + } + }); + return new GraphQLSchema({ + query: QueryType, + types: [QueryType] + }); +} +``` \ No newline at end of file diff --git a/src/tests/fixtures/top_level_fields/queryFieldWithFirstArgParentType.invalid.ts.expected b/src/tests/fixtures/top_level_fields/queryFieldWithFirstArgParentType.invalid.ts.expected deleted file mode 100644 index 80230fef..00000000 --- a/src/tests/fixtures/top_level_fields/queryFieldWithFirstArgParentType.invalid.ts.expected +++ /dev/null @@ -1,18 +0,0 @@ ------------------ -INPUT ------------------ -/** @gqlType */ -type Query = unknown; - -/** @gqlQueryField */ -export function greeting(_: Query): string { - return "Hello world"; -} - ------------------ -OUTPUT ------------------ -src/tests/fixtures/top_level_fields/queryFieldWithFirstArgParentType.invalid.ts:5:29 - error: The type of Query.greeting(_:) must be Input Type but got: Query!. - -5 export function greeting(_: Query): string { - ~~~~~ diff --git a/src/tests/fixtures/top_level_fields/queryFieldWithFirstArgParentType.invalid.ts.expected.md b/src/tests/fixtures/top_level_fields/queryFieldWithFirstArgParentType.invalid.ts.expected.md new file mode 100644 index 00000000..387c99dc --- /dev/null +++ b/src/tests/fixtures/top_level_fields/queryFieldWithFirstArgParentType.invalid.ts.expected.md @@ -0,0 +1,22 @@ +## input + +```ts title="top_level_fields/queryFieldWithFirstArgParentType.invalid.ts" +/** @gqlType */ +type Query = unknown; + +/** @gqlQueryField */ +export function greeting(_: Query): string { + return "Hello world"; +} +``` + +## Output + +### Error Report + +```text +src/tests/fixtures/top_level_fields/queryFieldWithFirstArgParentType.invalid.ts:5:29 - error: The type of Query.greeting(_:) must be Input Type but got: Query!. + +5 export function greeting(_: Query): string { + ~~~~~ +``` \ No newline at end of file diff --git a/src/tests/fixtures/top_level_fields/rootFields.ts.expected b/src/tests/fixtures/top_level_fields/rootFields.ts.expected deleted file mode 100644 index 359316e5..00000000 --- a/src/tests/fixtures/top_level_fields/rootFields.ts.expected +++ /dev/null @@ -1,98 +0,0 @@ ------------------ -INPUT ------------------ -import { Int } from "../../../Types"; -/** @gqlQueryField */ -export function greeting(): string { - return "Hello world"; -} - -/** @gqlMutationField */ -export function deleteSomething(): string { - return "Hello world"; -} - -/** @gqlSubscriptionField */ -export async function* range(from: Int): AsyncIterable { - for (let i = from; i >= 0; i--) { - await new Promise((resolve) => setTimeout(resolve, 1000)); - yield i; - } -} - ------------------ -OUTPUT ------------------ --- SDL -- -type Mutation { - deleteSomething: String -} - -type Query { - greeting: String -} - -type Subscription { - range(from: Int!): Int -} --- TypeScript -- -import { GraphQLSchema, GraphQLObjectType, GraphQLString, GraphQLInt, GraphQLNonNull } from "graphql"; -import { greeting as queryGreetingResolver, deleteSomething as mutationDeleteSomethingResolver, range as subscriptionRangeResolver } from "./rootFields"; -export function getSchema(): GraphQLSchema { - const QueryType: GraphQLObjectType = new GraphQLObjectType({ - name: "Query", - fields() { - return { - greeting: { - name: "greeting", - type: GraphQLString, - resolve() { - return queryGreetingResolver(); - } - } - }; - } - }); - const MutationType: GraphQLObjectType = new GraphQLObjectType({ - name: "Mutation", - fields() { - return { - deleteSomething: { - name: "deleteSomething", - type: GraphQLString, - resolve() { - return mutationDeleteSomethingResolver(); - } - } - }; - } - }); - const SubscriptionType: GraphQLObjectType = new GraphQLObjectType({ - name: "Subscription", - fields() { - return { - range: { - name: "range", - type: GraphQLInt, - args: { - from: { - type: new GraphQLNonNull(GraphQLInt) - } - }, - subscribe(_source, args) { - return subscriptionRangeResolver(args.from); - }, - resolve(payload) { - return payload; - } - } - }; - } - }); - return new GraphQLSchema({ - query: QueryType, - mutation: MutationType, - subscription: SubscriptionType, - types: [MutationType, QueryType, SubscriptionType] - }); -} diff --git a/src/tests/fixtures/top_level_fields/rootFields.ts.expected.md b/src/tests/fixtures/top_level_fields/rootFields.ts.expected.md new file mode 100644 index 00000000..d241be5a --- /dev/null +++ b/src/tests/fixtures/top_level_fields/rootFields.ts.expected.md @@ -0,0 +1,105 @@ +## input + +```ts title="top_level_fields/rootFields.ts" +import { Int } from "../../../Types"; +/** @gqlQueryField */ +export function greeting(): string { + return "Hello world"; +} + +/** @gqlMutationField */ +export function deleteSomething(): string { + return "Hello world"; +} + +/** @gqlSubscriptionField */ +export async function* range(from: Int): AsyncIterable { + for (let i = from; i >= 0; i--) { + await new Promise((resolve) => setTimeout(resolve, 1000)); + yield i; + } +} +``` + +## Output + +### SDL + +```graphql +type Mutation { + deleteSomething: String +} + +type Query { + greeting: String +} + +type Subscription { + range(from: Int!): Int +} +``` + +### TypeScript + +```ts +import { GraphQLSchema, GraphQLObjectType, GraphQLString, GraphQLInt, GraphQLNonNull } from "graphql"; +import { greeting as queryGreetingResolver, deleteSomething as mutationDeleteSomethingResolver, range as subscriptionRangeResolver } from "./rootFields"; +export function getSchema(): GraphQLSchema { + const QueryType: GraphQLObjectType = new GraphQLObjectType({ + name: "Query", + fields() { + return { + greeting: { + name: "greeting", + type: GraphQLString, + resolve() { + return queryGreetingResolver(); + } + } + }; + } + }); + const MutationType: GraphQLObjectType = new GraphQLObjectType({ + name: "Mutation", + fields() { + return { + deleteSomething: { + name: "deleteSomething", + type: GraphQLString, + resolve() { + return mutationDeleteSomethingResolver(); + } + } + }; + } + }); + const SubscriptionType: GraphQLObjectType = new GraphQLObjectType({ + name: "Subscription", + fields() { + return { + range: { + name: "range", + type: GraphQLInt, + args: { + from: { + type: new GraphQLNonNull(GraphQLInt) + } + }, + subscribe(_source, args) { + return subscriptionRangeResolver(args.from); + }, + resolve(payload) { + return payload; + } + } + }; + } + }); + return new GraphQLSchema({ + query: QueryType, + mutation: MutationType, + subscription: SubscriptionType, + types: [MutationType, QueryType, SubscriptionType] + }); +} +``` \ No newline at end of file diff --git a/src/tests/fixtures/top_level_fields/rootSubscriptionFieldNotAsyncIterable.invalid.ts.expected b/src/tests/fixtures/top_level_fields/rootSubscriptionFieldNotAsyncIterable.invalid.ts.expected deleted file mode 100644 index 9cbadf63..00000000 --- a/src/tests/fixtures/top_level_fields/rootSubscriptionFieldNotAsyncIterable.invalid.ts.expected +++ /dev/null @@ -1,15 +0,0 @@ ------------------ -INPUT ------------------ -/** @gqlSubscriptionField */ -export function foo(): string { - return "Hello"; -} - ------------------ -OUTPUT ------------------ -src/tests/fixtures/top_level_fields/rootSubscriptionFieldNotAsyncIterable.invalid.ts:2:24 - error: Expected fields on `Subscription` to return an `AsyncIterable`. Fields on `Subscription` model a subscription, which is a stream of events. Grats expects fields on `Subscription` to return an `AsyncIterable` which can be used to model this stream. - -2 export function foo(): string { - ~~~~~~ diff --git a/src/tests/fixtures/top_level_fields/rootSubscriptionFieldNotAsyncIterable.invalid.ts.expected.md b/src/tests/fixtures/top_level_fields/rootSubscriptionFieldNotAsyncIterable.invalid.ts.expected.md new file mode 100644 index 00000000..54714ea0 --- /dev/null +++ b/src/tests/fixtures/top_level_fields/rootSubscriptionFieldNotAsyncIterable.invalid.ts.expected.md @@ -0,0 +1,19 @@ +## input + +```ts title="top_level_fields/rootSubscriptionFieldNotAsyncIterable.invalid.ts" +/** @gqlSubscriptionField */ +export function foo(): string { + return "Hello"; +} +``` + +## Output + +### Error Report + +```text +src/tests/fixtures/top_level_fields/rootSubscriptionFieldNotAsyncIterable.invalid.ts:2:24 - error: Expected fields on `Subscription` to return an `AsyncIterable`. Fields on `Subscription` model a subscription, which is a stream of events. Grats expects fields on `Subscription` to return an `AsyncIterable` which can be used to model this stream. + +2 export function foo(): string { + ~~~~~~ +``` \ No newline at end of file diff --git a/src/tests/fixtures/type_definitions/ClassImplementsNonGqlInterface.ts.expected b/src/tests/fixtures/type_definitions/ClassImplementsNonGqlInterface.ts.expected deleted file mode 100644 index d1726422..00000000 --- a/src/tests/fixtures/type_definitions/ClassImplementsNonGqlInterface.ts.expected +++ /dev/null @@ -1,43 +0,0 @@ ------------------ -INPUT ------------------ -/** - * The root of all evil. - * @gqlType - */ -export default class User implements IPerson { - /** @gqlField */ - hello: string; -} - -interface IPerson { - hello: string; -} - ------------------ -OUTPUT ------------------ --- SDL -- -"""The root of all evil.""" -type User { - hello: String -} --- TypeScript -- -import { GraphQLSchema, GraphQLObjectType, GraphQLString } from "graphql"; -export function getSchema(): GraphQLSchema { - const UserType: GraphQLObjectType = new GraphQLObjectType({ - name: "User", - description: "The root of all evil.", - fields() { - return { - hello: { - name: "hello", - type: GraphQLString - } - }; - } - }); - return new GraphQLSchema({ - types: [UserType] - }); -} diff --git a/src/tests/fixtures/type_definitions/ClassImplementsNonGqlInterface.ts.expected.md b/src/tests/fixtures/type_definitions/ClassImplementsNonGqlInterface.ts.expected.md new file mode 100644 index 00000000..2ccc4d04 --- /dev/null +++ b/src/tests/fixtures/type_definitions/ClassImplementsNonGqlInterface.ts.expected.md @@ -0,0 +1,50 @@ +## input + +```ts title="type_definitions/ClassImplementsNonGqlInterface.ts" +/** + * The root of all evil. + * @gqlType + */ +export default class User implements IPerson { + /** @gqlField */ + hello: string; +} + +interface IPerson { + hello: string; +} +``` + +## Output + +### SDL + +```graphql +"""The root of all evil.""" +type User { + hello: String +} +``` + +### TypeScript + +```ts +import { GraphQLSchema, GraphQLObjectType, GraphQLString } from "graphql"; +export function getSchema(): GraphQLSchema { + const UserType: GraphQLObjectType = new GraphQLObjectType({ + name: "User", + description: "The root of all evil.", + fields() { + return { + hello: { + name: "hello", + type: GraphQLString + } + }; + } + }); + return new GraphQLSchema({ + types: [UserType] + }); +} +``` \ No newline at end of file diff --git a/src/tests/fixtures/type_definitions/ClassMissingFields.invalid.ts.expected b/src/tests/fixtures/type_definitions/ClassMissingFields.invalid.ts.expected deleted file mode 100644 index 51870c5e..00000000 --- a/src/tests/fixtures/type_definitions/ClassMissingFields.invalid.ts.expected +++ /dev/null @@ -1,15 +0,0 @@ ------------------ -INPUT ------------------ -/** @gqlType */ -export default class SomeType {} - ------------------ -OUTPUT ------------------ -src/tests/fixtures/type_definitions/ClassMissingFields.invalid.ts:2:22 - error: Type `SomeType` must define one or more fields. - -Define a field by adding `/** @gqlField */` above a field, property, attribute or method of this type, or above a function that has `SomeType` as its first argument. - -2 export default class SomeType {} - ~~~~~~~~ diff --git a/src/tests/fixtures/type_definitions/ClassMissingFields.invalid.ts.expected.md b/src/tests/fixtures/type_definitions/ClassMissingFields.invalid.ts.expected.md new file mode 100644 index 00000000..48426ba6 --- /dev/null +++ b/src/tests/fixtures/type_definitions/ClassMissingFields.invalid.ts.expected.md @@ -0,0 +1,19 @@ +## input + +```ts title="type_definitions/ClassMissingFields.invalid.ts" +/** @gqlType */ +export default class SomeType {} +``` + +## Output + +### Error Report + +```text +src/tests/fixtures/type_definitions/ClassMissingFields.invalid.ts:2:22 - error: Type `SomeType` must define one or more fields. + +Define a field by adding `/** @gqlField */` above a field, property, attribute or method of this type, or above a function that has `SomeType` as its first argument. + +2 export default class SomeType {} + ~~~~~~~~ +``` \ No newline at end of file diff --git a/src/tests/fixtures/type_definitions/ClassWithDescription.ts.expected b/src/tests/fixtures/type_definitions/ClassWithDescription.ts.expected deleted file mode 100644 index 16b161f1..00000000 --- a/src/tests/fixtures/type_definitions/ClassWithDescription.ts.expected +++ /dev/null @@ -1,40 +0,0 @@ ------------------ -INPUT ------------------ -/** - * The root of all evil. - * - * @gqlType - */ -export default class SomeType { - /** @gqlField */ - hello: string; -} - ------------------ -OUTPUT ------------------ --- SDL -- -"""The root of all evil.""" -type SomeType { - hello: String -} --- TypeScript -- -import { GraphQLSchema, GraphQLObjectType, GraphQLString } from "graphql"; -export function getSchema(): GraphQLSchema { - const SomeTypeType: GraphQLObjectType = new GraphQLObjectType({ - name: "SomeType", - description: "The root of all evil.", - fields() { - return { - hello: { - name: "hello", - type: GraphQLString - } - }; - } - }); - return new GraphQLSchema({ - types: [SomeTypeType] - }); -} diff --git a/src/tests/fixtures/type_definitions/ClassWithDescription.ts.expected.md b/src/tests/fixtures/type_definitions/ClassWithDescription.ts.expected.md new file mode 100644 index 00000000..2c82ada6 --- /dev/null +++ b/src/tests/fixtures/type_definitions/ClassWithDescription.ts.expected.md @@ -0,0 +1,47 @@ +## input + +```ts title="type_definitions/ClassWithDescription.ts" +/** + * The root of all evil. + * + * @gqlType + */ +export default class SomeType { + /** @gqlField */ + hello: string; +} +``` + +## Output + +### SDL + +```graphql +"""The root of all evil.""" +type SomeType { + hello: String +} +``` + +### TypeScript + +```ts +import { GraphQLSchema, GraphQLObjectType, GraphQLString } from "graphql"; +export function getSchema(): GraphQLSchema { + const SomeTypeType: GraphQLObjectType = new GraphQLObjectType({ + name: "SomeType", + description: "The root of all evil.", + fields() { + return { + hello: { + name: "hello", + type: GraphQLString + } + }; + } + }); + return new GraphQLSchema({ + types: [SomeTypeType] + }); +} +``` \ No newline at end of file diff --git a/src/tests/fixtures/type_definitions/ClassWithDescriptionAndCustomName.ts.expected b/src/tests/fixtures/type_definitions/ClassWithDescriptionAndCustomName.ts.expected deleted file mode 100644 index ee9aed25..00000000 --- a/src/tests/fixtures/type_definitions/ClassWithDescriptionAndCustomName.ts.expected +++ /dev/null @@ -1,40 +0,0 @@ ------------------ -INPUT ------------------ -/** - * The root of all evil. - * - * @gqlType SomeType - */ -export default class NotQuery { - /** @gqlField */ - hello: string; -} - ------------------ -OUTPUT ------------------ --- SDL -- -"""The root of all evil.""" -type SomeType { - hello: String -} --- TypeScript -- -import { GraphQLSchema, GraphQLObjectType, GraphQLString } from "graphql"; -export function getSchema(): GraphQLSchema { - const SomeTypeType: GraphQLObjectType = new GraphQLObjectType({ - name: "SomeType", - description: "The root of all evil.", - fields() { - return { - hello: { - name: "hello", - type: GraphQLString - } - }; - } - }); - return new GraphQLSchema({ - types: [SomeTypeType] - }); -} diff --git a/src/tests/fixtures/type_definitions/ClassWithDescriptionAndCustomName.ts.expected.md b/src/tests/fixtures/type_definitions/ClassWithDescriptionAndCustomName.ts.expected.md new file mode 100644 index 00000000..79f97cbb --- /dev/null +++ b/src/tests/fixtures/type_definitions/ClassWithDescriptionAndCustomName.ts.expected.md @@ -0,0 +1,47 @@ +## input + +```ts title="type_definitions/ClassWithDescriptionAndCustomName.ts" +/** + * The root of all evil. + * + * @gqlType SomeType + */ +export default class NotQuery { + /** @gqlField */ + hello: string; +} +``` + +## Output + +### SDL + +```graphql +"""The root of all evil.""" +type SomeType { + hello: String +} +``` + +### TypeScript + +```ts +import { GraphQLSchema, GraphQLObjectType, GraphQLString } from "graphql"; +export function getSchema(): GraphQLSchema { + const SomeTypeType: GraphQLObjectType = new GraphQLObjectType({ + name: "SomeType", + description: "The root of all evil.", + fields() { + return { + hello: { + name: "hello", + type: GraphQLString + } + }; + } + }); + return new GraphQLSchema({ + types: [SomeTypeType] + }); +} +``` \ No newline at end of file diff --git a/src/tests/fixtures/type_definitions/ClassWithoutAName.invalid.ts.expected b/src/tests/fixtures/type_definitions/ClassWithoutAName.invalid.ts.expected deleted file mode 100644 index 4e72d502..00000000 --- a/src/tests/fixtures/type_definitions/ClassWithoutAName.invalid.ts.expected +++ /dev/null @@ -1,27 +0,0 @@ ------------------ -INPUT ------------------ -/** - * @gqlType - */ -export default class { - /** @gqlField */ - hello(): string { - return "Hello world!"; - } -} - ------------------ -OUTPUT ------------------ -src/tests/fixtures/type_definitions/ClassWithoutAName.invalid.ts:4:1 - error: Unexpected `@gqlType` annotation on unnamed class declaration. Grats uses the name of the class to derive the name of the GraphQL type. Consider naming the class. - - 4 export default class { - ~~~~~~~~~~~~~~~~~~~~~~ - 5 /** @gqlField */ - ~~~~~~~~~~~~~~~~~~ -... - 8 } - ~~~ - 9 } - ~ diff --git a/src/tests/fixtures/type_definitions/ClassWithoutAName.invalid.ts.expected.md b/src/tests/fixtures/type_definitions/ClassWithoutAName.invalid.ts.expected.md new file mode 100644 index 00000000..7889b1af --- /dev/null +++ b/src/tests/fixtures/type_definitions/ClassWithoutAName.invalid.ts.expected.md @@ -0,0 +1,31 @@ +## input + +```ts title="type_definitions/ClassWithoutAName.invalid.ts" +/** + * @gqlType + */ +export default class { + /** @gqlField */ + hello(): string { + return "Hello world!"; + } +} +``` + +## Output + +### Error Report + +```text +src/tests/fixtures/type_definitions/ClassWithoutAName.invalid.ts:4:1 - error: Unexpected `@gqlType` annotation on unnamed class declaration. Grats uses the name of the class to derive the name of the GraphQL type. Consider naming the class. + + 4 export default class { + ~~~~~~~~~~~~~~~~~~~~~~ + 5 /** @gqlField */ + ~~~~~~~~~~~~~~~~~~ +... + 8 } + ~~~ + 9 } + ~ +``` \ No newline at end of file diff --git a/src/tests/fixtures/type_definitions/QueryAsClass.invalid.ts.expected b/src/tests/fixtures/type_definitions/QueryAsClass.invalid.ts.expected deleted file mode 100644 index b6982e0c..00000000 --- a/src/tests/fixtures/type_definitions/QueryAsClass.invalid.ts.expected +++ /dev/null @@ -1,16 +0,0 @@ ------------------ -INPUT ------------------ -/** @gqlType */ -export default class Query { - /** @gqlField */ - hello: string; -} - ------------------ -OUTPUT ------------------ -src/tests/fixtures/type_definitions/QueryAsClass.invalid.ts:2:22 - error: Operation types `Query`, `Mutation`, and `Subscription` must be defined as type aliases of `unknown`. E.g. `type Query = unknown`. This is because GraphQL servers do not have an agreed upon way to produce root values, and Grats errs on the side of safety. If you are trying to implement dependency injection, consider using the `context` argument passed to each resolver instead. If you have a strong use case for a concrete root value, please file an issue. - -2 export default class Query { - ~~~~~ diff --git a/src/tests/fixtures/type_definitions/QueryAsClass.invalid.ts.expected.md b/src/tests/fixtures/type_definitions/QueryAsClass.invalid.ts.expected.md new file mode 100644 index 00000000..81f14313 --- /dev/null +++ b/src/tests/fixtures/type_definitions/QueryAsClass.invalid.ts.expected.md @@ -0,0 +1,20 @@ +## input + +```ts title="type_definitions/QueryAsClass.invalid.ts" +/** @gqlType */ +export default class Query { + /** @gqlField */ + hello: string; +} +``` + +## Output + +### Error Report + +```text +src/tests/fixtures/type_definitions/QueryAsClass.invalid.ts:2:22 - error: Operation types `Query`, `Mutation`, and `Subscription` must be defined as type aliases of `unknown`. E.g. `type Query = unknown`. This is because GraphQL servers do not have an agreed upon way to produce root values, and Grats errs on the side of safety. If you are trying to implement dependency injection, consider using the `context` argument passed to each resolver instead. If you have a strong use case for a concrete root value, please file an issue. + +2 export default class Query { + ~~~~~ +``` \ No newline at end of file diff --git a/src/tests/fixtures/type_definitions/RenamedType.ts.expected b/src/tests/fixtures/type_definitions/RenamedType.ts.expected deleted file mode 100644 index 9f191fe9..00000000 --- a/src/tests/fixtures/type_definitions/RenamedType.ts.expected +++ /dev/null @@ -1,38 +0,0 @@ ------------------ -INPUT ------------------ -/** - * @gqlType SomeType - */ -class MyClass { - /** @gqlField */ - hello(): string { - return "Hello world!"; - } -} - ------------------ -OUTPUT ------------------ --- SDL -- -type SomeType { - hello: String -} --- TypeScript -- -import { GraphQLSchema, GraphQLObjectType, GraphQLString } from "graphql"; -export function getSchema(): GraphQLSchema { - const SomeTypeType: GraphQLObjectType = new GraphQLObjectType({ - name: "SomeType", - fields() { - return { - hello: { - name: "hello", - type: GraphQLString - } - }; - } - }); - return new GraphQLSchema({ - types: [SomeTypeType] - }); -} diff --git a/src/tests/fixtures/type_definitions/RenamedType.ts.expected.md b/src/tests/fixtures/type_definitions/RenamedType.ts.expected.md new file mode 100644 index 00000000..40676a9f --- /dev/null +++ b/src/tests/fixtures/type_definitions/RenamedType.ts.expected.md @@ -0,0 +1,45 @@ +## input + +```ts title="type_definitions/RenamedType.ts" +/** + * @gqlType SomeType + */ +class MyClass { + /** @gqlField */ + hello(): string { + return "Hello world!"; + } +} +``` + +## Output + +### SDL + +```graphql +type SomeType { + hello: String +} +``` + +### TypeScript + +```ts +import { GraphQLSchema, GraphQLObjectType, GraphQLString } from "graphql"; +export function getSchema(): GraphQLSchema { + const SomeTypeType: GraphQLObjectType = new GraphQLObjectType({ + name: "SomeType", + fields() { + return { + hello: { + name: "hello", + type: GraphQLString + } + }; + } + }); + return new GraphQLSchema({ + types: [SomeTypeType] + }); +} +``` \ No newline at end of file diff --git a/src/tests/fixtures/type_definitions/RenamedTypeHasDash.invalid.ts.expected b/src/tests/fixtures/type_definitions/RenamedTypeHasDash.invalid.ts.expected deleted file mode 100644 index c40f2dc1..00000000 --- a/src/tests/fixtures/type_definitions/RenamedTypeHasDash.invalid.ts.expected +++ /dev/null @@ -1,22 +0,0 @@ ------------------ -INPUT ------------------ -/** - * @gqlType Some-Type - */ -class MyClass { - /** @gqlField */ - hello(): string { - return "Hello world!"; - } -} - ------------------ -OUTPUT ------------------ -src/tests/fixtures/type_definitions/RenamedTypeHasDash.invalid.ts:2:4 - error: Names must only contain [_a-zA-Z0-9] but "Some-Type" does not. - -2 * @gqlType Some-Type - ~~~~~~~~~~~~~~~~~~ -3 */ - ~ diff --git a/src/tests/fixtures/type_definitions/RenamedTypeHasDash.invalid.ts.expected.md b/src/tests/fixtures/type_definitions/RenamedTypeHasDash.invalid.ts.expected.md new file mode 100644 index 00000000..4ab89862 --- /dev/null +++ b/src/tests/fixtures/type_definitions/RenamedTypeHasDash.invalid.ts.expected.md @@ -0,0 +1,26 @@ +## input + +```ts title="type_definitions/RenamedTypeHasDash.invalid.ts" +/** + * @gqlType Some-Type + */ +class MyClass { + /** @gqlField */ + hello(): string { + return "Hello world!"; + } +} +``` + +## Output + +### Error Report + +```text +src/tests/fixtures/type_definitions/RenamedTypeHasDash.invalid.ts:2:4 - error: Names must only contain [_a-zA-Z0-9] but "Some-Type" does not. + +2 * @gqlType Some-Type + ~~~~~~~~~~~~~~~~~~ +3 */ + ~ +``` \ No newline at end of file diff --git a/src/tests/fixtures/type_definitions/RenamedTypeNewLine.invalid.ts.expected b/src/tests/fixtures/type_definitions/RenamedTypeNewLine.invalid.ts.expected deleted file mode 100644 index 5794df8f..00000000 --- a/src/tests/fixtures/type_definitions/RenamedTypeNewLine.invalid.ts.expected +++ /dev/null @@ -1,28 +0,0 @@ ------------------ -INPUT ------------------ -/** - * @gqlType - * - * SomeType - */ -class MyClass { - /** @gqlField */ - hello(): string { - return "Hello world!"; - } -} - ------------------ -OUTPUT ------------------ -src/tests/fixtures/type_definitions/RenamedTypeNewLine.invalid.ts:2:4 - error: Expected the GraphQL name `SomeType` to be on the same line as it's `@gqlType` tag. - -2 * @gqlType - ~~~~~~~~ -3 * - ~~ -4 * SomeType - ~~~~~~~~~~~ -5 */ - ~ diff --git a/src/tests/fixtures/type_definitions/RenamedTypeNewLine.invalid.ts.expected.md b/src/tests/fixtures/type_definitions/RenamedTypeNewLine.invalid.ts.expected.md new file mode 100644 index 00000000..ea1bdb06 --- /dev/null +++ b/src/tests/fixtures/type_definitions/RenamedTypeNewLine.invalid.ts.expected.md @@ -0,0 +1,32 @@ +## input + +```ts title="type_definitions/RenamedTypeNewLine.invalid.ts" +/** + * @gqlType + * + * SomeType + */ +class MyClass { + /** @gqlField */ + hello(): string { + return "Hello world!"; + } +} +``` + +## Output + +### Error Report + +```text +src/tests/fixtures/type_definitions/RenamedTypeNewLine.invalid.ts:2:4 - error: Expected the GraphQL name `SomeType` to be on the same line as it's `@gqlType` tag. + +2 * @gqlType + ~~~~~~~~ +3 * + ~~ +4 * SomeType + ~~~~~~~~~~~ +5 */ + ~ +``` \ No newline at end of file diff --git a/src/tests/fixtures/type_definitions/RenamedTypeStartsWithNumber.invalid.ts.expected b/src/tests/fixtures/type_definitions/RenamedTypeStartsWithNumber.invalid.ts.expected deleted file mode 100644 index 4912b428..00000000 --- a/src/tests/fixtures/type_definitions/RenamedTypeStartsWithNumber.invalid.ts.expected +++ /dev/null @@ -1,22 +0,0 @@ ------------------ -INPUT ------------------ -/** - * @gqlType 1SomeType - */ -class MyClass { - /** @gqlField */ - hello(): string { - return "Hello world!"; - } -} - ------------------ -OUTPUT ------------------ -src/tests/fixtures/type_definitions/RenamedTypeStartsWithNumber.invalid.ts:2:4 - error: Names must start with [_a-zA-Z] but "1SomeType" does not. - -2 * @gqlType 1SomeType - ~~~~~~~~~~~~~~~~~~ -3 */ - ~ diff --git a/src/tests/fixtures/type_definitions/RenamedTypeStartsWithNumber.invalid.ts.expected.md b/src/tests/fixtures/type_definitions/RenamedTypeStartsWithNumber.invalid.ts.expected.md new file mode 100644 index 00000000..af906419 --- /dev/null +++ b/src/tests/fixtures/type_definitions/RenamedTypeStartsWithNumber.invalid.ts.expected.md @@ -0,0 +1,26 @@ +## input + +```ts title="type_definitions/RenamedTypeStartsWithNumber.invalid.ts" +/** + * @gqlType 1SomeType + */ +class MyClass { + /** @gqlField */ + hello(): string { + return "Hello world!"; + } +} +``` + +## Output + +### Error Report + +```text +src/tests/fixtures/type_definitions/RenamedTypeStartsWithNumber.invalid.ts:2:4 - error: Names must start with [_a-zA-Z] but "1SomeType" does not. + +2 * @gqlType 1SomeType + ~~~~~~~~~~~~~~~~~~ +3 */ + ~ +``` \ No newline at end of file diff --git a/src/tests/fixtures/type_definitions/RenamedTypeWithoutClassName.invalid.ts.expected b/src/tests/fixtures/type_definitions/RenamedTypeWithoutClassName.invalid.ts.expected deleted file mode 100644 index e1fd9a3e..00000000 --- a/src/tests/fixtures/type_definitions/RenamedTypeWithoutClassName.invalid.ts.expected +++ /dev/null @@ -1,27 +0,0 @@ ------------------ -INPUT ------------------ -/** - * @gqlType SomeType - */ -export default class { - /** @gqlField */ - hello(): string { - return "Hello world!"; - } -} - ------------------ -OUTPUT ------------------ -src/tests/fixtures/type_definitions/RenamedTypeWithoutClassName.invalid.ts:4:1 - error: Unexpected `@gqlType` annotation on unnamed class declaration. Grats uses the name of the class to derive the name of the GraphQL type. Consider naming the class. - - 4 export default class { - ~~~~~~~~~~~~~~~~~~~~~~ - 5 /** @gqlField */ - ~~~~~~~~~~~~~~~~~~ -... - 8 } - ~~~ - 9 } - ~ diff --git a/src/tests/fixtures/type_definitions/RenamedTypeWithoutClassName.invalid.ts.expected.md b/src/tests/fixtures/type_definitions/RenamedTypeWithoutClassName.invalid.ts.expected.md new file mode 100644 index 00000000..64651b6a --- /dev/null +++ b/src/tests/fixtures/type_definitions/RenamedTypeWithoutClassName.invalid.ts.expected.md @@ -0,0 +1,31 @@ +## input + +```ts title="type_definitions/RenamedTypeWithoutClassName.invalid.ts" +/** + * @gqlType SomeType + */ +export default class { + /** @gqlField */ + hello(): string { + return "Hello world!"; + } +} +``` + +## Output + +### Error Report + +```text +src/tests/fixtures/type_definitions/RenamedTypeWithoutClassName.invalid.ts:4:1 - error: Unexpected `@gqlType` annotation on unnamed class declaration. Grats uses the name of the class to derive the name of the GraphQL type. Consider naming the class. + + 4 export default class { + ~~~~~~~~~~~~~~~~~~~~~~ + 5 /** @gqlField */ + ~~~~~~~~~~~~~~~~~~ +... + 8 } + ~~~ + 9 } + ~ +``` \ No newline at end of file diff --git a/src/tests/fixtures/type_definitions/TagAttachedToWrongNode.invalid.ts.expected b/src/tests/fixtures/type_definitions/TagAttachedToWrongNode.invalid.ts.expected deleted file mode 100644 index 74e2ecec..00000000 --- a/src/tests/fixtures/type_definitions/TagAttachedToWrongNode.invalid.ts.expected +++ /dev/null @@ -1,13 +0,0 @@ ------------------ -INPUT ------------------ -/** @gqlType */ -function MyFunc() {} - ------------------ -OUTPUT ------------------ -src/tests/fixtures/type_definitions/TagAttachedToWrongNode.invalid.ts:1:5 - error: `@gqlType` can only be used on class, interface or type declarations. e.g. `class MyType {}` - -1 /** @gqlType */ - ~~~~~~~~~ diff --git a/src/tests/fixtures/type_definitions/TagAttachedToWrongNode.invalid.ts.expected.md b/src/tests/fixtures/type_definitions/TagAttachedToWrongNode.invalid.ts.expected.md new file mode 100644 index 00000000..3f608704 --- /dev/null +++ b/src/tests/fixtures/type_definitions/TagAttachedToWrongNode.invalid.ts.expected.md @@ -0,0 +1,17 @@ +## input + +```ts title="type_definitions/TagAttachedToWrongNode.invalid.ts" +/** @gqlType */ +function MyFunc() {} +``` + +## Output + +### Error Report + +```text +src/tests/fixtures/type_definitions/TagAttachedToWrongNode.invalid.ts:1:5 - error: `@gqlType` can only be used on class, interface or type declarations. e.g. `class MyType {}` + +1 /** @gqlType */ + ~~~~~~~~~ +``` \ No newline at end of file diff --git a/src/tests/fixtures/type_definitions/TypeFromClassDefinitionImplementsInterface.ts.expected b/src/tests/fixtures/type_definitions/TypeFromClassDefinitionImplementsInterface.ts.expected deleted file mode 100644 index 70e7c4ae..00000000 --- a/src/tests/fixtures/type_definitions/TypeFromClassDefinitionImplementsInterface.ts.expected +++ /dev/null @@ -1,59 +0,0 @@ ------------------ -INPUT ------------------ -/** @gqlInterface */ -interface Person { - /** @gqlField */ - hello: string; -} - -/** @gqlType */ -export default class User implements Person { - readonly __typename = "User" as const; - /** @gqlField */ - hello: string; -} - ------------------ -OUTPUT ------------------ --- SDL -- -interface Person { - hello: String -} - -type User implements Person { - hello: String -} --- TypeScript -- -import { GraphQLSchema, GraphQLInterfaceType, GraphQLString, GraphQLObjectType } from "graphql"; -export function getSchema(): GraphQLSchema { - const PersonType: GraphQLInterfaceType = new GraphQLInterfaceType({ - name: "Person", - fields() { - return { - hello: { - name: "hello", - type: GraphQLString - } - }; - } - }); - const UserType: GraphQLObjectType = new GraphQLObjectType({ - name: "User", - fields() { - return { - hello: { - name: "hello", - type: GraphQLString - } - }; - }, - interfaces() { - return [PersonType]; - } - }); - return new GraphQLSchema({ - types: [PersonType, UserType] - }); -} diff --git a/src/tests/fixtures/type_definitions/TypeFromClassDefinitionImplementsInterface.ts.expected.md b/src/tests/fixtures/type_definitions/TypeFromClassDefinitionImplementsInterface.ts.expected.md new file mode 100644 index 00000000..2553b7cd --- /dev/null +++ b/src/tests/fixtures/type_definitions/TypeFromClassDefinitionImplementsInterface.ts.expected.md @@ -0,0 +1,66 @@ +## input + +```ts title="type_definitions/TypeFromClassDefinitionImplementsInterface.ts" +/** @gqlInterface */ +interface Person { + /** @gqlField */ + hello: string; +} + +/** @gqlType */ +export default class User implements Person { + readonly __typename = "User" as const; + /** @gqlField */ + hello: string; +} +``` + +## Output + +### SDL + +```graphql +interface Person { + hello: String +} + +type User implements Person { + hello: String +} +``` + +### TypeScript + +```ts +import { GraphQLSchema, GraphQLInterfaceType, GraphQLString, GraphQLObjectType } from "graphql"; +export function getSchema(): GraphQLSchema { + const PersonType: GraphQLInterfaceType = new GraphQLInterfaceType({ + name: "Person", + fields() { + return { + hello: { + name: "hello", + type: GraphQLString + } + }; + } + }); + const UserType: GraphQLObjectType = new GraphQLObjectType({ + name: "User", + fields() { + return { + hello: { + name: "hello", + type: GraphQLString + } + }; + }, + interfaces() { + return [PersonType]; + } + }); + return new GraphQLSchema({ + types: [PersonType, UserType] + }); +} +``` \ No newline at end of file diff --git a/src/tests/fixtures/type_definitions/TypeFromClassDefinitionImplementsInterfaceWithDeprecatedTag.invalid.ts.expected b/src/tests/fixtures/type_definitions/TypeFromClassDefinitionImplementsInterfaceWithDeprecatedTag.invalid.ts.expected deleted file mode 100644 index 356e3def..00000000 --- a/src/tests/fixtures/type_definitions/TypeFromClassDefinitionImplementsInterfaceWithDeprecatedTag.invalid.ts.expected +++ /dev/null @@ -1,32 +0,0 @@ ------------------ -INPUT ------------------ -/** @gqlInterface */ -interface Person { - /** @gqlField */ - hello: string; -} - -/** - * @gqlType - * @gqlImplements Person - */ -export default class User { - readonly __typename = "User" as const; - /** @gqlField */ - hello: string; -} - ------------------ -OUTPUT ------------------ -src/tests/fixtures/type_definitions/TypeFromClassDefinitionImplementsInterfaceWithDeprecatedTag.invalid.ts:9:4 - error: `@gqlImplements` has been deprecated. Instead use `class MyType implements MyInterface`. - - 9 * @gqlImplements Person - ~~~~~~~~~~~~~~~~~~~~~ -10 */ - ~ -src/tests/fixtures/type_definitions/TypeFromClassDefinitionImplementsInterfaceWithDeprecatedTag.invalid.ts:9:5 - error: `@gqlImplements` has been deprecated. Instead use `class MyType implements MyInterface`. - -9 * @gqlImplements Person - ~~~~~~~~~~~~~ diff --git a/src/tests/fixtures/type_definitions/TypeFromClassDefinitionImplementsInterfaceWithDeprecatedTag.invalid.ts.expected.md b/src/tests/fixtures/type_definitions/TypeFromClassDefinitionImplementsInterfaceWithDeprecatedTag.invalid.ts.expected.md new file mode 100644 index 00000000..c2018974 --- /dev/null +++ b/src/tests/fixtures/type_definitions/TypeFromClassDefinitionImplementsInterfaceWithDeprecatedTag.invalid.ts.expected.md @@ -0,0 +1,36 @@ +## input + +```ts title="type_definitions/TypeFromClassDefinitionImplementsInterfaceWithDeprecatedTag.invalid.ts" +/** @gqlInterface */ +interface Person { + /** @gqlField */ + hello: string; +} + +/** + * @gqlType + * @gqlImplements Person + */ +export default class User { + readonly __typename = "User" as const; + /** @gqlField */ + hello: string; +} +``` + +## Output + +### Error Report + +```text +src/tests/fixtures/type_definitions/TypeFromClassDefinitionImplementsInterfaceWithDeprecatedTag.invalid.ts:9:4 - error: `@gqlImplements` has been deprecated. Instead use `class MyType implements MyInterface`. + + 9 * @gqlImplements Person + ~~~~~~~~~~~~~~~~~~~~~ +10 */ + ~ +src/tests/fixtures/type_definitions/TypeFromClassDefinitionImplementsInterfaceWithDeprecatedTag.invalid.ts:9:5 - error: `@gqlImplements` has been deprecated. Instead use `class MyType implements MyInterface`. + +9 * @gqlImplements Person + ~~~~~~~~~~~~~ +``` \ No newline at end of file diff --git a/src/tests/fixtures/type_definitions/TypeFromClassDefinitionImplementsMultipleInterfaces.ts.expected b/src/tests/fixtures/type_definitions/TypeFromClassDefinitionImplementsMultipleInterfaces.ts.expected deleted file mode 100644 index ea4a8914..00000000 --- a/src/tests/fixtures/type_definitions/TypeFromClassDefinitionImplementsMultipleInterfaces.ts.expected +++ /dev/null @@ -1,88 +0,0 @@ ------------------ -INPUT ------------------ -/** @gqlInterface Node */ -interface GqlNode { - /** @gqlField */ - id: string; -} - -/** @gqlInterface */ -interface Person { - /** @gqlField */ - hello: string; -} - -/** @gqlType */ -export default class User implements Person, GqlNode { - readonly __typename = "User" as const; - /** @gqlField */ - hello: string; - - /** @gqlField */ - id: string; -} - ------------------ -OUTPUT ------------------ --- SDL -- -interface Node { - id: String -} - -interface Person { - hello: String -} - -type User implements Node & Person { - hello: String - id: String -} --- TypeScript -- -import { GraphQLSchema, GraphQLInterfaceType, GraphQLString, GraphQLObjectType } from "graphql"; -export function getSchema(): GraphQLSchema { - const NodeType: GraphQLInterfaceType = new GraphQLInterfaceType({ - name: "Node", - fields() { - return { - id: { - name: "id", - type: GraphQLString - } - }; - } - }); - const PersonType: GraphQLInterfaceType = new GraphQLInterfaceType({ - name: "Person", - fields() { - return { - hello: { - name: "hello", - type: GraphQLString - } - }; - } - }); - const UserType: GraphQLObjectType = new GraphQLObjectType({ - name: "User", - fields() { - return { - hello: { - name: "hello", - type: GraphQLString - }, - id: { - name: "id", - type: GraphQLString - } - }; - }, - interfaces() { - return [NodeType, PersonType]; - } - }); - return new GraphQLSchema({ - types: [NodeType, PersonType, UserType] - }); -} diff --git a/src/tests/fixtures/type_definitions/TypeFromClassDefinitionImplementsMultipleInterfaces.ts.expected.md b/src/tests/fixtures/type_definitions/TypeFromClassDefinitionImplementsMultipleInterfaces.ts.expected.md new file mode 100644 index 00000000..0f5bd7ef --- /dev/null +++ b/src/tests/fixtures/type_definitions/TypeFromClassDefinitionImplementsMultipleInterfaces.ts.expected.md @@ -0,0 +1,95 @@ +## input + +```ts title="type_definitions/TypeFromClassDefinitionImplementsMultipleInterfaces.ts" +/** @gqlInterface Node */ +interface GqlNode { + /** @gqlField */ + id: string; +} + +/** @gqlInterface */ +interface Person { + /** @gqlField */ + hello: string; +} + +/** @gqlType */ +export default class User implements Person, GqlNode { + readonly __typename = "User" as const; + /** @gqlField */ + hello: string; + + /** @gqlField */ + id: string; +} +``` + +## Output + +### SDL + +```graphql +interface Node { + id: String +} + +interface Person { + hello: String +} + +type User implements Node & Person { + hello: String + id: String +} +``` + +### TypeScript + +```ts +import { GraphQLSchema, GraphQLInterfaceType, GraphQLString, GraphQLObjectType } from "graphql"; +export function getSchema(): GraphQLSchema { + const NodeType: GraphQLInterfaceType = new GraphQLInterfaceType({ + name: "Node", + fields() { + return { + id: { + name: "id", + type: GraphQLString + } + }; + } + }); + const PersonType: GraphQLInterfaceType = new GraphQLInterfaceType({ + name: "Person", + fields() { + return { + hello: { + name: "hello", + type: GraphQLString + } + }; + } + }); + const UserType: GraphQLObjectType = new GraphQLObjectType({ + name: "User", + fields() { + return { + hello: { + name: "hello", + type: GraphQLString + }, + id: { + name: "id", + type: GraphQLString + } + }; + }, + interfaces() { + return [NodeType, PersonType]; + } + }); + return new GraphQLSchema({ + types: [NodeType, PersonType, UserType] + }); +} +``` \ No newline at end of file diff --git a/src/tests/fixtures/type_definitions_from_alias/AliasIsArrayNotLiteral.invalid.ts.expected b/src/tests/fixtures/type_definitions_from_alias/AliasIsArrayNotLiteral.invalid.ts.expected deleted file mode 100644 index 6e1e5da0..00000000 --- a/src/tests/fixtures/type_definitions_from_alias/AliasIsArrayNotLiteral.invalid.ts.expected +++ /dev/null @@ -1,19 +0,0 @@ ------------------ -INPUT ------------------ -/** @gqlType */ -export type SomeType = { - hello: string; -}[]; - ------------------ -OUTPUT ------------------ -src/tests/fixtures/type_definitions_from_alias/AliasIsArrayNotLiteral.invalid.ts:2:24 - error: Expected `@gqlType` type to be an object type literal (`{ }`) or `unknown`. For example: `type Foo = { bar: string }` or `type Query = unknown`. - -2 export type SomeType = { - ~ -3 hello: string; - ~~~~~~~~~~~~~~~~ -4 }[]; - ~~~ diff --git a/src/tests/fixtures/type_definitions_from_alias/AliasIsArrayNotLiteral.invalid.ts.expected.md b/src/tests/fixtures/type_definitions_from_alias/AliasIsArrayNotLiteral.invalid.ts.expected.md new file mode 100644 index 00000000..b3f5da9f --- /dev/null +++ b/src/tests/fixtures/type_definitions_from_alias/AliasIsArrayNotLiteral.invalid.ts.expected.md @@ -0,0 +1,23 @@ +## input + +```ts title="type_definitions_from_alias/AliasIsArrayNotLiteral.invalid.ts" +/** @gqlType */ +export type SomeType = { + hello: string; +}[]; +``` + +## Output + +### Error Report + +```text +src/tests/fixtures/type_definitions_from_alias/AliasIsArrayNotLiteral.invalid.ts:2:24 - error: Expected `@gqlType` type to be an object type literal (`{ }`) or `unknown`. For example: `type Foo = { bar: string }` or `type Query = unknown`. + +2 export type SomeType = { + ~ +3 hello: string; + ~~~~~~~~~~~~~~~~ +4 }[]; + ~~~ +``` \ No newline at end of file diff --git a/src/tests/fixtures/type_definitions_from_alias/AliasIsNumberNotLiteral.invalid.ts.expected b/src/tests/fixtures/type_definitions_from_alias/AliasIsNumberNotLiteral.invalid.ts.expected deleted file mode 100644 index d1418ba3..00000000 --- a/src/tests/fixtures/type_definitions_from_alias/AliasIsNumberNotLiteral.invalid.ts.expected +++ /dev/null @@ -1,13 +0,0 @@ ------------------ -INPUT ------------------ -/** @gqlType */ -export type SomeType = 10; - ------------------ -OUTPUT ------------------ -src/tests/fixtures/type_definitions_from_alias/AliasIsNumberNotLiteral.invalid.ts:2:24 - error: Expected `@gqlType` type to be an object type literal (`{ }`) or `unknown`. For example: `type Foo = { bar: string }` or `type Query = unknown`. - -2 export type SomeType = 10; - ~~ diff --git a/src/tests/fixtures/type_definitions_from_alias/AliasIsNumberNotLiteral.invalid.ts.expected.md b/src/tests/fixtures/type_definitions_from_alias/AliasIsNumberNotLiteral.invalid.ts.expected.md new file mode 100644 index 00000000..d0d51c59 --- /dev/null +++ b/src/tests/fixtures/type_definitions_from_alias/AliasIsNumberNotLiteral.invalid.ts.expected.md @@ -0,0 +1,17 @@ +## input + +```ts title="type_definitions_from_alias/AliasIsNumberNotLiteral.invalid.ts" +/** @gqlType */ +export type SomeType = 10; +``` + +## Output + +### Error Report + +```text +src/tests/fixtures/type_definitions_from_alias/AliasIsNumberNotLiteral.invalid.ts:2:24 - error: Expected `@gqlType` type to be an object type literal (`{ }`) or `unknown`. For example: `type Foo = { bar: string }` or `type Query = unknown`. + +2 export type SomeType = 10; + ~~ +``` \ No newline at end of file diff --git a/src/tests/fixtures/type_definitions_from_alias/AliasOfUnknownDefinesType.ts.expected b/src/tests/fixtures/type_definitions_from_alias/AliasOfUnknownDefinesType.ts.expected deleted file mode 100644 index 1cde3e13..00000000 --- a/src/tests/fixtures/type_definitions_from_alias/AliasOfUnknownDefinesType.ts.expected +++ /dev/null @@ -1,40 +0,0 @@ ------------------ -INPUT ------------------ -/** @gqlType */ -export type SomeType = unknown; - -/** @gqlField */ -export function greeting(_: SomeType): string { - return "Hello world"; -} - ------------------ -OUTPUT ------------------ --- SDL -- -type SomeType { - greeting: String -} --- TypeScript -- -import { GraphQLSchema, GraphQLObjectType, GraphQLString } from "graphql"; -import { greeting as someTypeGreetingResolver } from "./AliasOfUnknownDefinesType"; -export function getSchema(): GraphQLSchema { - const SomeTypeType: GraphQLObjectType = new GraphQLObjectType({ - name: "SomeType", - fields() { - return { - greeting: { - name: "greeting", - type: GraphQLString, - resolve(source) { - return someTypeGreetingResolver(source); - } - } - }; - } - }); - return new GraphQLSchema({ - types: [SomeTypeType] - }); -} diff --git a/src/tests/fixtures/type_definitions_from_alias/AliasOfUnknownDefinesType.ts.expected.md b/src/tests/fixtures/type_definitions_from_alias/AliasOfUnknownDefinesType.ts.expected.md new file mode 100644 index 00000000..e4c78b5f --- /dev/null +++ b/src/tests/fixtures/type_definitions_from_alias/AliasOfUnknownDefinesType.ts.expected.md @@ -0,0 +1,47 @@ +## input + +```ts title="type_definitions_from_alias/AliasOfUnknownDefinesType.ts" +/** @gqlType */ +export type SomeType = unknown; + +/** @gqlField */ +export function greeting(_: SomeType): string { + return "Hello world"; +} +``` + +## Output + +### SDL + +```graphql +type SomeType { + greeting: String +} +``` + +### TypeScript + +```ts +import { GraphQLSchema, GraphQLObjectType, GraphQLString } from "graphql"; +import { greeting as someTypeGreetingResolver } from "./AliasOfUnknownDefinesType"; +export function getSchema(): GraphQLSchema { + const SomeTypeType: GraphQLObjectType = new GraphQLObjectType({ + name: "SomeType", + fields() { + return { + greeting: { + name: "greeting", + type: GraphQLString, + resolve(source) { + return someTypeGreetingResolver(source); + } + } + }; + } + }); + return new GraphQLSchema({ + types: [SomeTypeType] + }); +} +``` \ No newline at end of file diff --git a/src/tests/fixtures/type_definitions_from_alias/AliasType.ts.expected b/src/tests/fixtures/type_definitions_from_alias/AliasType.ts.expected deleted file mode 100644 index 3c847830..00000000 --- a/src/tests/fixtures/type_definitions_from_alias/AliasType.ts.expected +++ /dev/null @@ -1,34 +0,0 @@ ------------------ -INPUT ------------------ -/** @gqlType */ -export type SomeType = { - /** @gqlField */ - hello: string; -}; - ------------------ -OUTPUT ------------------ --- SDL -- -type SomeType { - hello: String -} --- TypeScript -- -import { GraphQLSchema, GraphQLObjectType, GraphQLString } from "graphql"; -export function getSchema(): GraphQLSchema { - const SomeTypeType: GraphQLObjectType = new GraphQLObjectType({ - name: "SomeType", - fields() { - return { - hello: { - name: "hello", - type: GraphQLString - } - }; - } - }); - return new GraphQLSchema({ - types: [SomeTypeType] - }); -} diff --git a/src/tests/fixtures/type_definitions_from_alias/AliasType.ts.expected.md b/src/tests/fixtures/type_definitions_from_alias/AliasType.ts.expected.md new file mode 100644 index 00000000..9b63163d --- /dev/null +++ b/src/tests/fixtures/type_definitions_from_alias/AliasType.ts.expected.md @@ -0,0 +1,41 @@ +## input + +```ts title="type_definitions_from_alias/AliasType.ts" +/** @gqlType */ +export type SomeType = { + /** @gqlField */ + hello: string; +}; +``` + +## Output + +### SDL + +```graphql +type SomeType { + hello: String +} +``` + +### TypeScript + +```ts +import { GraphQLSchema, GraphQLObjectType, GraphQLString } from "graphql"; +export function getSchema(): GraphQLSchema { + const SomeTypeType: GraphQLObjectType = new GraphQLObjectType({ + name: "SomeType", + fields() { + return { + hello: { + name: "hello", + type: GraphQLString + } + }; + } + }); + return new GraphQLSchema({ + types: [SomeTypeType] + }); +} +``` \ No newline at end of file diff --git a/src/tests/fixtures/type_definitions_from_alias/AliasTypeImplementsInterface.invalid.ts.expected b/src/tests/fixtures/type_definitions_from_alias/AliasTypeImplementsInterface.invalid.ts.expected deleted file mode 100644 index 37d1f8f2..00000000 --- a/src/tests/fixtures/type_definitions_from_alias/AliasTypeImplementsInterface.invalid.ts.expected +++ /dev/null @@ -1,32 +0,0 @@ ------------------ -INPUT ------------------ -/** - * @gqlType - * @gqlImplements Person - */ -export type User = { - __typename: "User"; - /** @gqlField */ - name: string; -}; - -/** @gqlInterface */ -interface Person { - /** @gqlField */ - name: string; -} - ------------------ -OUTPUT ------------------ -src/tests/fixtures/type_definitions_from_alias/AliasTypeImplementsInterface.invalid.ts:3:4 - error: `@gqlImplements` has been deprecated. Types which implement GraphQL interfaces should be defined using TypeScript class or interface declarations. - -3 * @gqlImplements Person - ~~~~~~~~~~~~~~~~~~~~~ -4 */ - ~ -src/tests/fixtures/type_definitions_from_alias/AliasTypeImplementsInterface.invalid.ts:3:5 - error: `@gqlImplements` has been deprecated. Instead use `class MyType implements MyInterface`. - -3 * @gqlImplements Person - ~~~~~~~~~~~~~ diff --git a/src/tests/fixtures/type_definitions_from_alias/AliasTypeImplementsInterface.invalid.ts.expected.md b/src/tests/fixtures/type_definitions_from_alias/AliasTypeImplementsInterface.invalid.ts.expected.md new file mode 100644 index 00000000..a34d1315 --- /dev/null +++ b/src/tests/fixtures/type_definitions_from_alias/AliasTypeImplementsInterface.invalid.ts.expected.md @@ -0,0 +1,36 @@ +## input + +```ts title="type_definitions_from_alias/AliasTypeImplementsInterface.invalid.ts" +/** + * @gqlType + * @gqlImplements Person + */ +export type User = { + __typename: "User"; + /** @gqlField */ + name: string; +}; + +/** @gqlInterface */ +interface Person { + /** @gqlField */ + name: string; +} +``` + +## Output + +### Error Report + +```text +src/tests/fixtures/type_definitions_from_alias/AliasTypeImplementsInterface.invalid.ts:3:4 - error: `@gqlImplements` has been deprecated. Types which implement GraphQL interfaces should be defined using TypeScript class or interface declarations. + +3 * @gqlImplements Person + ~~~~~~~~~~~~~~~~~~~~~ +4 */ + ~ +src/tests/fixtures/type_definitions_from_alias/AliasTypeImplementsInterface.invalid.ts:3:5 - error: `@gqlImplements` has been deprecated. Instead use `class MyType implements MyInterface`. + +3 * @gqlImplements Person + ~~~~~~~~~~~~~ +``` \ No newline at end of file diff --git a/src/tests/fixtures/type_definitions_from_alias/AliasWithDescription.ts.expected b/src/tests/fixtures/type_definitions_from_alias/AliasWithDescription.ts.expected deleted file mode 100644 index 404a1a30..00000000 --- a/src/tests/fixtures/type_definitions_from_alias/AliasWithDescription.ts.expected +++ /dev/null @@ -1,40 +0,0 @@ ------------------ -INPUT ------------------ -/** - * The root of all evil. - * - * @gqlType - */ -export type SomeType = { - /** @gqlField */ - hello: string; -}; - ------------------ -OUTPUT ------------------ --- SDL -- -"""The root of all evil.""" -type SomeType { - hello: String -} --- TypeScript -- -import { GraphQLSchema, GraphQLObjectType, GraphQLString } from "graphql"; -export function getSchema(): GraphQLSchema { - const SomeTypeType: GraphQLObjectType = new GraphQLObjectType({ - name: "SomeType", - description: "The root of all evil.", - fields() { - return { - hello: { - name: "hello", - type: GraphQLString - } - }; - } - }); - return new GraphQLSchema({ - types: [SomeTypeType] - }); -} diff --git a/src/tests/fixtures/type_definitions_from_alias/AliasWithDescription.ts.expected.md b/src/tests/fixtures/type_definitions_from_alias/AliasWithDescription.ts.expected.md new file mode 100644 index 00000000..6165db76 --- /dev/null +++ b/src/tests/fixtures/type_definitions_from_alias/AliasWithDescription.ts.expected.md @@ -0,0 +1,47 @@ +## input + +```ts title="type_definitions_from_alias/AliasWithDescription.ts" +/** + * The root of all evil. + * + * @gqlType + */ +export type SomeType = { + /** @gqlField */ + hello: string; +}; +``` + +## Output + +### SDL + +```graphql +"""The root of all evil.""" +type SomeType { + hello: String +} +``` + +### TypeScript + +```ts +import { GraphQLSchema, GraphQLObjectType, GraphQLString } from "graphql"; +export function getSchema(): GraphQLSchema { + const SomeTypeType: GraphQLObjectType = new GraphQLObjectType({ + name: "SomeType", + description: "The root of all evil.", + fields() { + return { + hello: { + name: "hello", + type: GraphQLString + } + }; + } + }); + return new GraphQLSchema({ + types: [SomeTypeType] + }); +} +``` \ No newline at end of file diff --git a/src/tests/fixtures/type_definitions_from_alias/AliasWithDescriptionAndCustomName.ts.expected b/src/tests/fixtures/type_definitions_from_alias/AliasWithDescriptionAndCustomName.ts.expected deleted file mode 100644 index d70cec8b..00000000 --- a/src/tests/fixtures/type_definitions_from_alias/AliasWithDescriptionAndCustomName.ts.expected +++ /dev/null @@ -1,40 +0,0 @@ ------------------ -INPUT ------------------ -/** - * The root of all evil. - * - * @gqlType SomeType - */ -export type NotQuery = { - /** @gqlField */ - hello: string; -}; - ------------------ -OUTPUT ------------------ --- SDL -- -"""The root of all evil.""" -type SomeType { - hello: String -} --- TypeScript -- -import { GraphQLSchema, GraphQLObjectType, GraphQLString } from "graphql"; -export function getSchema(): GraphQLSchema { - const SomeTypeType: GraphQLObjectType = new GraphQLObjectType({ - name: "SomeType", - description: "The root of all evil.", - fields() { - return { - hello: { - name: "hello", - type: GraphQLString - } - }; - } - }); - return new GraphQLSchema({ - types: [SomeTypeType] - }); -} diff --git a/src/tests/fixtures/type_definitions_from_alias/AliasWithDescriptionAndCustomName.ts.expected.md b/src/tests/fixtures/type_definitions_from_alias/AliasWithDescriptionAndCustomName.ts.expected.md new file mode 100644 index 00000000..d7bfdbd7 --- /dev/null +++ b/src/tests/fixtures/type_definitions_from_alias/AliasWithDescriptionAndCustomName.ts.expected.md @@ -0,0 +1,47 @@ +## input + +```ts title="type_definitions_from_alias/AliasWithDescriptionAndCustomName.ts" +/** + * The root of all evil. + * + * @gqlType SomeType + */ +export type NotQuery = { + /** @gqlField */ + hello: string; +}; +``` + +## Output + +### SDL + +```graphql +"""The root of all evil.""" +type SomeType { + hello: String +} +``` + +### TypeScript + +```ts +import { GraphQLSchema, GraphQLObjectType, GraphQLString } from "graphql"; +export function getSchema(): GraphQLSchema { + const SomeTypeType: GraphQLObjectType = new GraphQLObjectType({ + name: "SomeType", + description: "The root of all evil.", + fields() { + return { + hello: { + name: "hello", + type: GraphQLString + } + }; + } + }); + return new GraphQLSchema({ + types: [SomeTypeType] + }); +} +``` \ No newline at end of file diff --git a/src/tests/fixtures/type_definitions_from_alias/QueryAsAliasOfObject.invalid.ts.expected b/src/tests/fixtures/type_definitions_from_alias/QueryAsAliasOfObject.invalid.ts.expected deleted file mode 100644 index 1d90810b..00000000 --- a/src/tests/fixtures/type_definitions_from_alias/QueryAsAliasOfObject.invalid.ts.expected +++ /dev/null @@ -1,18 +0,0 @@ ------------------ -INPUT ------------------ -/** @gqlType */ -type Query = {}; - -/** @gqlField */ -export function foo(_: Query): string { - return "foo"; -} - ------------------ -OUTPUT ------------------ -src/tests/fixtures/type_definitions_from_alias/QueryAsAliasOfObject.invalid.ts:2:14 - error: Operation types `Query`, `Mutation`, and `Subscription` must be defined as type aliases of `unknown`. E.g. `type Query = unknown`. This is because GraphQL servers do not have an agreed upon way to produce root values, and Grats errs on the side of safety. If you are trying to implement dependency injection, consider using the `context` argument passed to each resolver instead. If you have a strong use case for a concrete root value, please file an issue. - -2 type Query = {}; - ~~ diff --git a/src/tests/fixtures/type_definitions_from_alias/QueryAsAliasOfObject.invalid.ts.expected.md b/src/tests/fixtures/type_definitions_from_alias/QueryAsAliasOfObject.invalid.ts.expected.md new file mode 100644 index 00000000..f337c86c --- /dev/null +++ b/src/tests/fixtures/type_definitions_from_alias/QueryAsAliasOfObject.invalid.ts.expected.md @@ -0,0 +1,22 @@ +## input + +```ts title="type_definitions_from_alias/QueryAsAliasOfObject.invalid.ts" +/** @gqlType */ +type Query = {}; + +/** @gqlField */ +export function foo(_: Query): string { + return "foo"; +} +``` + +## Output + +### Error Report + +```text +src/tests/fixtures/type_definitions_from_alias/QueryAsAliasOfObject.invalid.ts:2:14 - error: Operation types `Query`, `Mutation`, and `Subscription` must be defined as type aliases of `unknown`. E.g. `type Query = unknown`. This is because GraphQL servers do not have an agreed upon way to produce root values, and Grats errs on the side of safety. If you are trying to implement dependency injection, consider using the `context` argument passed to each resolver instead. If you have a strong use case for a concrete root value, please file an issue. + +2 type Query = {}; + ~~ +``` \ No newline at end of file diff --git a/src/tests/fixtures/type_definitions_from_alias/QueryAsAliasOfUndefined.invalid.ts.expected b/src/tests/fixtures/type_definitions_from_alias/QueryAsAliasOfUndefined.invalid.ts.expected deleted file mode 100644 index 8df670a2..00000000 --- a/src/tests/fixtures/type_definitions_from_alias/QueryAsAliasOfUndefined.invalid.ts.expected +++ /dev/null @@ -1,18 +0,0 @@ ------------------ -INPUT ------------------ -/** @gqlType */ -type Query = undefined; - -/** @gqlField */ -export function foo(_: Query): string { - return "foo"; -} - ------------------ -OUTPUT ------------------ -src/tests/fixtures/type_definitions_from_alias/QueryAsAliasOfUndefined.invalid.ts:2:14 - error: Expected `@gqlType` type to be an object type literal (`{ }`) or `unknown`. For example: `type Foo = { bar: string }` or `type Query = unknown`. - -2 type Query = undefined; - ~~~~~~~~~ diff --git a/src/tests/fixtures/type_definitions_from_alias/QueryAsAliasOfUndefined.invalid.ts.expected.md b/src/tests/fixtures/type_definitions_from_alias/QueryAsAliasOfUndefined.invalid.ts.expected.md new file mode 100644 index 00000000..96b22ae3 --- /dev/null +++ b/src/tests/fixtures/type_definitions_from_alias/QueryAsAliasOfUndefined.invalid.ts.expected.md @@ -0,0 +1,22 @@ +## input + +```ts title="type_definitions_from_alias/QueryAsAliasOfUndefined.invalid.ts" +/** @gqlType */ +type Query = undefined; + +/** @gqlField */ +export function foo(_: Query): string { + return "foo"; +} +``` + +## Output + +### Error Report + +```text +src/tests/fixtures/type_definitions_from_alias/QueryAsAliasOfUndefined.invalid.ts:2:14 - error: Expected `@gqlType` type to be an object type literal (`{ }`) or `unknown`. For example: `type Foo = { bar: string }` or `type Query = unknown`. + +2 type Query = undefined; + ~~~~~~~~~ +``` \ No newline at end of file diff --git a/src/tests/fixtures/type_definitions_from_alias/QueryAsAliasOfUnknown.ts.expected b/src/tests/fixtures/type_definitions_from_alias/QueryAsAliasOfUnknown.ts.expected deleted file mode 100644 index 9f998446..00000000 --- a/src/tests/fixtures/type_definitions_from_alias/QueryAsAliasOfUnknown.ts.expected +++ /dev/null @@ -1,41 +0,0 @@ ------------------ -INPUT ------------------ -/** @gqlType */ -type Query = unknown; - -/** @gqlField */ -export function foo(_: Query): string { - return "foo"; -} - ------------------ -OUTPUT ------------------ --- SDL -- -type Query { - foo: String -} --- TypeScript -- -import { GraphQLSchema, GraphQLObjectType, GraphQLString } from "graphql"; -import { foo as queryFooResolver } from "./QueryAsAliasOfUnknown"; -export function getSchema(): GraphQLSchema { - const QueryType: GraphQLObjectType = new GraphQLObjectType({ - name: "Query", - fields() { - return { - foo: { - name: "foo", - type: GraphQLString, - resolve(source) { - return queryFooResolver(source); - } - } - }; - } - }); - return new GraphQLSchema({ - query: QueryType, - types: [QueryType] - }); -} diff --git a/src/tests/fixtures/type_definitions_from_alias/QueryAsAliasOfUnknown.ts.expected.md b/src/tests/fixtures/type_definitions_from_alias/QueryAsAliasOfUnknown.ts.expected.md new file mode 100644 index 00000000..0676c014 --- /dev/null +++ b/src/tests/fixtures/type_definitions_from_alias/QueryAsAliasOfUnknown.ts.expected.md @@ -0,0 +1,48 @@ +## input + +```ts title="type_definitions_from_alias/QueryAsAliasOfUnknown.ts" +/** @gqlType */ +type Query = unknown; + +/** @gqlField */ +export function foo(_: Query): string { + return "foo"; +} +``` + +## Output + +### SDL + +```graphql +type Query { + foo: String +} +``` + +### TypeScript + +```ts +import { GraphQLSchema, GraphQLObjectType, GraphQLString } from "graphql"; +import { foo as queryFooResolver } from "./QueryAsAliasOfUnknown"; +export function getSchema(): GraphQLSchema { + const QueryType: GraphQLObjectType = new GraphQLObjectType({ + name: "Query", + fields() { + return { + foo: { + name: "foo", + type: GraphQLString, + resolve(source) { + return queryFooResolver(source); + } + } + }; + } + }); + return new GraphQLSchema({ + query: QueryType, + types: [QueryType] + }); +} +``` \ No newline at end of file diff --git a/src/tests/fixtures/type_definitions_from_alias/RenamedType.ts.expected b/src/tests/fixtures/type_definitions_from_alias/RenamedType.ts.expected deleted file mode 100644 index 882bb72f..00000000 --- a/src/tests/fixtures/type_definitions_from_alias/RenamedType.ts.expected +++ /dev/null @@ -1,36 +0,0 @@ ------------------ -INPUT ------------------ -/** - * @gqlType SomeType - */ -type MyAlias = { - /** @gqlField */ - hello: string; -}; - ------------------ -OUTPUT ------------------ --- SDL -- -type SomeType { - hello: String -} --- TypeScript -- -import { GraphQLSchema, GraphQLObjectType, GraphQLString } from "graphql"; -export function getSchema(): GraphQLSchema { - const SomeTypeType: GraphQLObjectType = new GraphQLObjectType({ - name: "SomeType", - fields() { - return { - hello: { - name: "hello", - type: GraphQLString - } - }; - } - }); - return new GraphQLSchema({ - types: [SomeTypeType] - }); -} diff --git a/src/tests/fixtures/type_definitions_from_alias/RenamedType.ts.expected.md b/src/tests/fixtures/type_definitions_from_alias/RenamedType.ts.expected.md new file mode 100644 index 00000000..7f1f6f09 --- /dev/null +++ b/src/tests/fixtures/type_definitions_from_alias/RenamedType.ts.expected.md @@ -0,0 +1,43 @@ +## input + +```ts title="type_definitions_from_alias/RenamedType.ts" +/** + * @gqlType SomeType + */ +type MyAlias = { + /** @gqlField */ + hello: string; +}; +``` + +## Output + +### SDL + +```graphql +type SomeType { + hello: String +} +``` + +### TypeScript + +```ts +import { GraphQLSchema, GraphQLObjectType, GraphQLString } from "graphql"; +export function getSchema(): GraphQLSchema { + const SomeTypeType: GraphQLObjectType = new GraphQLObjectType({ + name: "SomeType", + fields() { + return { + hello: { + name: "hello", + type: GraphQLString + } + }; + } + }); + return new GraphQLSchema({ + types: [SomeTypeType] + }); +} +``` \ No newline at end of file diff --git a/src/tests/fixtures/type_definitions_from_interface/InterfaceType.ts.expected b/src/tests/fixtures/type_definitions_from_interface/InterfaceType.ts.expected deleted file mode 100644 index 2124343f..00000000 --- a/src/tests/fixtures/type_definitions_from_interface/InterfaceType.ts.expected +++ /dev/null @@ -1,34 +0,0 @@ ------------------ -INPUT ------------------ -/** @gqlType */ -export default interface SomeType { - /** @gqlField */ - hello: string; -} - ------------------ -OUTPUT ------------------ --- SDL -- -type SomeType { - hello: String -} --- TypeScript -- -import { GraphQLSchema, GraphQLObjectType, GraphQLString } from "graphql"; -export function getSchema(): GraphQLSchema { - const SomeTypeType: GraphQLObjectType = new GraphQLObjectType({ - name: "SomeType", - fields() { - return { - hello: { - name: "hello", - type: GraphQLString - } - }; - } - }); - return new GraphQLSchema({ - types: [SomeTypeType] - }); -} diff --git a/src/tests/fixtures/type_definitions_from_interface/InterfaceType.ts.expected.md b/src/tests/fixtures/type_definitions_from_interface/InterfaceType.ts.expected.md new file mode 100644 index 00000000..e494aeb2 --- /dev/null +++ b/src/tests/fixtures/type_definitions_from_interface/InterfaceType.ts.expected.md @@ -0,0 +1,41 @@ +## input + +```ts title="type_definitions_from_interface/InterfaceType.ts" +/** @gqlType */ +export default interface SomeType { + /** @gqlField */ + hello: string; +} +``` + +## Output + +### SDL + +```graphql +type SomeType { + hello: String +} +``` + +### TypeScript + +```ts +import { GraphQLSchema, GraphQLObjectType, GraphQLString } from "graphql"; +export function getSchema(): GraphQLSchema { + const SomeTypeType: GraphQLObjectType = new GraphQLObjectType({ + name: "SomeType", + fields() { + return { + hello: { + name: "hello", + type: GraphQLString + } + }; + } + }); + return new GraphQLSchema({ + types: [SomeTypeType] + }); +} +``` \ No newline at end of file diff --git a/src/tests/fixtures/type_definitions_from_interface/InterfaceTypeExtendsGqlInterface.ts.expected b/src/tests/fixtures/type_definitions_from_interface/InterfaceTypeExtendsGqlInterface.ts.expected deleted file mode 100644 index 553173e5..00000000 --- a/src/tests/fixtures/type_definitions_from_interface/InterfaceTypeExtendsGqlInterface.ts.expected +++ /dev/null @@ -1,60 +0,0 @@ ------------------ -INPUT ------------------ -/** @gqlInterface */ -interface Person { - /** @gqlField */ - name: string; -} - -/** @gqlType */ -export interface User extends Person { - __typename: "User"; - - /** @gqlField */ - name: string; -} - ------------------ -OUTPUT ------------------ --- SDL -- -interface Person { - name: String -} - -type User implements Person { - name: String -} --- TypeScript -- -import { GraphQLSchema, GraphQLInterfaceType, GraphQLString, GraphQLObjectType } from "graphql"; -export function getSchema(): GraphQLSchema { - const PersonType: GraphQLInterfaceType = new GraphQLInterfaceType({ - name: "Person", - fields() { - return { - name: { - name: "name", - type: GraphQLString - } - }; - } - }); - const UserType: GraphQLObjectType = new GraphQLObjectType({ - name: "User", - fields() { - return { - name: { - name: "name", - type: GraphQLString - } - }; - }, - interfaces() { - return [PersonType]; - } - }); - return new GraphQLSchema({ - types: [PersonType, UserType] - }); -} diff --git a/src/tests/fixtures/type_definitions_from_interface/InterfaceTypeExtendsGqlInterface.ts.expected.md b/src/tests/fixtures/type_definitions_from_interface/InterfaceTypeExtendsGqlInterface.ts.expected.md new file mode 100644 index 00000000..6a3fcea5 --- /dev/null +++ b/src/tests/fixtures/type_definitions_from_interface/InterfaceTypeExtendsGqlInterface.ts.expected.md @@ -0,0 +1,67 @@ +## input + +```ts title="type_definitions_from_interface/InterfaceTypeExtendsGqlInterface.ts" +/** @gqlInterface */ +interface Person { + /** @gqlField */ + name: string; +} + +/** @gqlType */ +export interface User extends Person { + __typename: "User"; + + /** @gqlField */ + name: string; +} +``` + +## Output + +### SDL + +```graphql +interface Person { + name: String +} + +type User implements Person { + name: String +} +``` + +### TypeScript + +```ts +import { GraphQLSchema, GraphQLInterfaceType, GraphQLString, GraphQLObjectType } from "graphql"; +export function getSchema(): GraphQLSchema { + const PersonType: GraphQLInterfaceType = new GraphQLInterfaceType({ + name: "Person", + fields() { + return { + name: { + name: "name", + type: GraphQLString + } + }; + } + }); + const UserType: GraphQLObjectType = new GraphQLObjectType({ + name: "User", + fields() { + return { + name: { + name: "name", + type: GraphQLString + } + }; + }, + interfaces() { + return [PersonType]; + } + }); + return new GraphQLSchema({ + types: [PersonType, UserType] + }); +} +``` \ No newline at end of file diff --git a/src/tests/fixtures/type_definitions_from_interface/InterfaceTypeExtendsGqlInterfaceWithDeprecatedTag.invalid.ts.expected b/src/tests/fixtures/type_definitions_from_interface/InterfaceTypeExtendsGqlInterfaceWithDeprecatedTag.invalid.ts.expected deleted file mode 100644 index 983dd0da..00000000 --- a/src/tests/fixtures/type_definitions_from_interface/InterfaceTypeExtendsGqlInterfaceWithDeprecatedTag.invalid.ts.expected +++ /dev/null @@ -1,33 +0,0 @@ ------------------ -INPUT ------------------ -/** @gqlInterface */ -interface Person { - /** @gqlField */ - name: string; -} - -/** - * @gqlType - * @gqlImplements Person - */ -export interface User { - __typename: "User"; - - /** @gqlField */ - name: string; -} - ------------------ -OUTPUT ------------------ -src/tests/fixtures/type_definitions_from_interface/InterfaceTypeExtendsGqlInterfaceWithDeprecatedTag.invalid.ts:9:4 - error: `@gqlImplements` has been deprecated. Instead use `interface MyType extends MyInterface`. - - 9 * @gqlImplements Person - ~~~~~~~~~~~~~~~~~~~~~ -10 */ - ~ -src/tests/fixtures/type_definitions_from_interface/InterfaceTypeExtendsGqlInterfaceWithDeprecatedTag.invalid.ts:9:5 - error: `@gqlImplements` has been deprecated. Instead use `class MyType implements MyInterface`. - -9 * @gqlImplements Person - ~~~~~~~~~~~~~ diff --git a/src/tests/fixtures/type_definitions_from_interface/InterfaceTypeExtendsGqlInterfaceWithDeprecatedTag.invalid.ts.expected.md b/src/tests/fixtures/type_definitions_from_interface/InterfaceTypeExtendsGqlInterfaceWithDeprecatedTag.invalid.ts.expected.md new file mode 100644 index 00000000..df0eb732 --- /dev/null +++ b/src/tests/fixtures/type_definitions_from_interface/InterfaceTypeExtendsGqlInterfaceWithDeprecatedTag.invalid.ts.expected.md @@ -0,0 +1,37 @@ +## input + +```ts title="type_definitions_from_interface/InterfaceTypeExtendsGqlInterfaceWithDeprecatedTag.invalid.ts" +/** @gqlInterface */ +interface Person { + /** @gqlField */ + name: string; +} + +/** + * @gqlType + * @gqlImplements Person + */ +export interface User { + __typename: "User"; + + /** @gqlField */ + name: string; +} +``` + +## Output + +### Error Report + +```text +src/tests/fixtures/type_definitions_from_interface/InterfaceTypeExtendsGqlInterfaceWithDeprecatedTag.invalid.ts:9:4 - error: `@gqlImplements` has been deprecated. Instead use `interface MyType extends MyInterface`. + + 9 * @gqlImplements Person + ~~~~~~~~~~~~~~~~~~~~~ +10 */ + ~ +src/tests/fixtures/type_definitions_from_interface/InterfaceTypeExtendsGqlInterfaceWithDeprecatedTag.invalid.ts:9:5 - error: `@gqlImplements` has been deprecated. Instead use `class MyType implements MyInterface`. + +9 * @gqlImplements Person + ~~~~~~~~~~~~~ +``` \ No newline at end of file diff --git a/src/tests/fixtures/type_definitions_from_interface/InterfaceTypeImplementsInterface.ts.expected b/src/tests/fixtures/type_definitions_from_interface/InterfaceTypeImplementsInterface.ts.expected deleted file mode 100644 index 14eb4cb8..00000000 --- a/src/tests/fixtures/type_definitions_from_interface/InterfaceTypeImplementsInterface.ts.expected +++ /dev/null @@ -1,67 +0,0 @@ ------------------ -INPUT ------------------ -/** @gqlType */ -export default interface User extends HasName { - __typename: "User"; - /** @gqlField */ - hello: string; - - /** @gqlField */ - name: string; -} - -/** @gqlInterface */ -interface HasName { - /** @gqlField */ - name: string; -} - ------------------ -OUTPUT ------------------ --- SDL -- -interface HasName { - name: String -} - -type User implements HasName { - hello: String - name: String -} --- TypeScript -- -import { GraphQLSchema, GraphQLInterfaceType, GraphQLString, GraphQLObjectType } from "graphql"; -export function getSchema(): GraphQLSchema { - const HasNameType: GraphQLInterfaceType = new GraphQLInterfaceType({ - name: "HasName", - fields() { - return { - name: { - name: "name", - type: GraphQLString - } - }; - } - }); - const UserType: GraphQLObjectType = new GraphQLObjectType({ - name: "User", - fields() { - return { - hello: { - name: "hello", - type: GraphQLString - }, - name: { - name: "name", - type: GraphQLString - } - }; - }, - interfaces() { - return [HasNameType]; - } - }); - return new GraphQLSchema({ - types: [HasNameType, UserType] - }); -} diff --git a/src/tests/fixtures/type_definitions_from_interface/InterfaceTypeImplementsInterface.ts.expected.md b/src/tests/fixtures/type_definitions_from_interface/InterfaceTypeImplementsInterface.ts.expected.md new file mode 100644 index 00000000..c93c05b0 --- /dev/null +++ b/src/tests/fixtures/type_definitions_from_interface/InterfaceTypeImplementsInterface.ts.expected.md @@ -0,0 +1,74 @@ +## input + +```ts title="type_definitions_from_interface/InterfaceTypeImplementsInterface.ts" +/** @gqlType */ +export default interface User extends HasName { + __typename: "User"; + /** @gqlField */ + hello: string; + + /** @gqlField */ + name: string; +} + +/** @gqlInterface */ +interface HasName { + /** @gqlField */ + name: string; +} +``` + +## Output + +### SDL + +```graphql +interface HasName { + name: String +} + +type User implements HasName { + hello: String + name: String +} +``` + +### TypeScript + +```ts +import { GraphQLSchema, GraphQLInterfaceType, GraphQLString, GraphQLObjectType } from "graphql"; +export function getSchema(): GraphQLSchema { + const HasNameType: GraphQLInterfaceType = new GraphQLInterfaceType({ + name: "HasName", + fields() { + return { + name: { + name: "name", + type: GraphQLString + } + }; + } + }); + const UserType: GraphQLObjectType = new GraphQLObjectType({ + name: "User", + fields() { + return { + hello: { + name: "hello", + type: GraphQLString + }, + name: { + name: "name", + type: GraphQLString + } + }; + }, + interfaces() { + return [HasNameType]; + } + }); + return new GraphQLSchema({ + types: [HasNameType, UserType] + }); +} +``` \ No newline at end of file diff --git a/src/tests/fixtures/type_definitions_from_interface/InterfaceWithDescription.ts.expected b/src/tests/fixtures/type_definitions_from_interface/InterfaceWithDescription.ts.expected deleted file mode 100644 index 44fe757b..00000000 --- a/src/tests/fixtures/type_definitions_from_interface/InterfaceWithDescription.ts.expected +++ /dev/null @@ -1,40 +0,0 @@ ------------------ -INPUT ------------------ -/** - * The root of all evil. - * - * @gqlType - */ -export default interface SomeType { - /** @gqlField */ - hello: string; -} - ------------------ -OUTPUT ------------------ --- SDL -- -"""The root of all evil.""" -type SomeType { - hello: String -} --- TypeScript -- -import { GraphQLSchema, GraphQLObjectType, GraphQLString } from "graphql"; -export function getSchema(): GraphQLSchema { - const SomeTypeType: GraphQLObjectType = new GraphQLObjectType({ - name: "SomeType", - description: "The root of all evil.", - fields() { - return { - hello: { - name: "hello", - type: GraphQLString - } - }; - } - }); - return new GraphQLSchema({ - types: [SomeTypeType] - }); -} diff --git a/src/tests/fixtures/type_definitions_from_interface/InterfaceWithDescription.ts.expected.md b/src/tests/fixtures/type_definitions_from_interface/InterfaceWithDescription.ts.expected.md new file mode 100644 index 00000000..d5abc7f8 --- /dev/null +++ b/src/tests/fixtures/type_definitions_from_interface/InterfaceWithDescription.ts.expected.md @@ -0,0 +1,47 @@ +## input + +```ts title="type_definitions_from_interface/InterfaceWithDescription.ts" +/** + * The root of all evil. + * + * @gqlType + */ +export default interface SomeType { + /** @gqlField */ + hello: string; +} +``` + +## Output + +### SDL + +```graphql +"""The root of all evil.""" +type SomeType { + hello: String +} +``` + +### TypeScript + +```ts +import { GraphQLSchema, GraphQLObjectType, GraphQLString } from "graphql"; +export function getSchema(): GraphQLSchema { + const SomeTypeType: GraphQLObjectType = new GraphQLObjectType({ + name: "SomeType", + description: "The root of all evil.", + fields() { + return { + hello: { + name: "hello", + type: GraphQLString + } + }; + } + }); + return new GraphQLSchema({ + types: [SomeTypeType] + }); +} +``` \ No newline at end of file diff --git a/src/tests/fixtures/type_definitions_from_interface/InterfaceWithDescriptionAndCustomName.ts.expected b/src/tests/fixtures/type_definitions_from_interface/InterfaceWithDescriptionAndCustomName.ts.expected deleted file mode 100644 index f139fc43..00000000 --- a/src/tests/fixtures/type_definitions_from_interface/InterfaceWithDescriptionAndCustomName.ts.expected +++ /dev/null @@ -1,40 +0,0 @@ ------------------ -INPUT ------------------ -/** - * The root of all evil. - * - * @gqlType SomeType - */ -export default interface NotQuery { - /** @gqlField */ - hello: string; -} - ------------------ -OUTPUT ------------------ --- SDL -- -"""The root of all evil.""" -type SomeType { - hello: String -} --- TypeScript -- -import { GraphQLSchema, GraphQLObjectType, GraphQLString } from "graphql"; -export function getSchema(): GraphQLSchema { - const SomeTypeType: GraphQLObjectType = new GraphQLObjectType({ - name: "SomeType", - description: "The root of all evil.", - fields() { - return { - hello: { - name: "hello", - type: GraphQLString - } - }; - } - }); - return new GraphQLSchema({ - types: [SomeTypeType] - }); -} diff --git a/src/tests/fixtures/type_definitions_from_interface/InterfaceWithDescriptionAndCustomName.ts.expected.md b/src/tests/fixtures/type_definitions_from_interface/InterfaceWithDescriptionAndCustomName.ts.expected.md new file mode 100644 index 00000000..aac3a6a6 --- /dev/null +++ b/src/tests/fixtures/type_definitions_from_interface/InterfaceWithDescriptionAndCustomName.ts.expected.md @@ -0,0 +1,47 @@ +## input + +```ts title="type_definitions_from_interface/InterfaceWithDescriptionAndCustomName.ts" +/** + * The root of all evil. + * + * @gqlType SomeType + */ +export default interface NotQuery { + /** @gqlField */ + hello: string; +} +``` + +## Output + +### SDL + +```graphql +"""The root of all evil.""" +type SomeType { + hello: String +} +``` + +### TypeScript + +```ts +import { GraphQLSchema, GraphQLObjectType, GraphQLString } from "graphql"; +export function getSchema(): GraphQLSchema { + const SomeTypeType: GraphQLObjectType = new GraphQLObjectType({ + name: "SomeType", + description: "The root of all evil.", + fields() { + return { + hello: { + name: "hello", + type: GraphQLString + } + }; + } + }); + return new GraphQLSchema({ + types: [SomeTypeType] + }); +} +``` \ No newline at end of file diff --git a/src/tests/fixtures/type_definitions_from_interface/QueryFromInterface.invalid.ts.expected b/src/tests/fixtures/type_definitions_from_interface/QueryFromInterface.invalid.ts.expected deleted file mode 100644 index 6b55fb83..00000000 --- a/src/tests/fixtures/type_definitions_from_interface/QueryFromInterface.invalid.ts.expected +++ /dev/null @@ -1,16 +0,0 @@ ------------------ -INPUT ------------------ -/** @gqlType */ -export default interface Query { - /** @gqlField */ - hello: string; -} - ------------------ -OUTPUT ------------------ -src/tests/fixtures/type_definitions_from_interface/QueryFromInterface.invalid.ts:2:26 - error: Operation types `Query`, `Mutation`, and `Subscription` must be defined as type aliases of `unknown`. E.g. `type Query = unknown`. This is because GraphQL servers do not have an agreed upon way to produce root values, and Grats errs on the side of safety. If you are trying to implement dependency injection, consider using the `context` argument passed to each resolver instead. If you have a strong use case for a concrete root value, please file an issue. - -2 export default interface Query { - ~~~~~ diff --git a/src/tests/fixtures/type_definitions_from_interface/QueryFromInterface.invalid.ts.expected.md b/src/tests/fixtures/type_definitions_from_interface/QueryFromInterface.invalid.ts.expected.md new file mode 100644 index 00000000..264b1a46 --- /dev/null +++ b/src/tests/fixtures/type_definitions_from_interface/QueryFromInterface.invalid.ts.expected.md @@ -0,0 +1,20 @@ +## input + +```ts title="type_definitions_from_interface/QueryFromInterface.invalid.ts" +/** @gqlType */ +export default interface Query { + /** @gqlField */ + hello: string; +} +``` + +## Output + +### Error Report + +```text +src/tests/fixtures/type_definitions_from_interface/QueryFromInterface.invalid.ts:2:26 - error: Operation types `Query`, `Mutation`, and `Subscription` must be defined as type aliases of `unknown`. E.g. `type Query = unknown`. This is because GraphQL servers do not have an agreed upon way to produce root values, and Grats errs on the side of safety. If you are trying to implement dependency injection, consider using the `context` argument passed to each resolver instead. If you have a strong use case for a concrete root value, please file an issue. + +2 export default interface Query { + ~~~~~ +``` \ No newline at end of file diff --git a/src/tests/fixtures/type_definitions_from_interface/RenamedType.ts.expected b/src/tests/fixtures/type_definitions_from_interface/RenamedType.ts.expected deleted file mode 100644 index a2aae648..00000000 --- a/src/tests/fixtures/type_definitions_from_interface/RenamedType.ts.expected +++ /dev/null @@ -1,36 +0,0 @@ ------------------ -INPUT ------------------ -/** - * @gqlType SomeType - */ -interface MyInterface { - /** @gqlField */ - hello: string; -} - ------------------ -OUTPUT ------------------ --- SDL -- -type SomeType { - hello: String -} --- TypeScript -- -import { GraphQLSchema, GraphQLObjectType, GraphQLString } from "graphql"; -export function getSchema(): GraphQLSchema { - const SomeTypeType: GraphQLObjectType = new GraphQLObjectType({ - name: "SomeType", - fields() { - return { - hello: { - name: "hello", - type: GraphQLString - } - }; - } - }); - return new GraphQLSchema({ - types: [SomeTypeType] - }); -} diff --git a/src/tests/fixtures/type_definitions_from_interface/RenamedType.ts.expected.md b/src/tests/fixtures/type_definitions_from_interface/RenamedType.ts.expected.md new file mode 100644 index 00000000..e9d99c19 --- /dev/null +++ b/src/tests/fixtures/type_definitions_from_interface/RenamedType.ts.expected.md @@ -0,0 +1,43 @@ +## input + +```ts title="type_definitions_from_interface/RenamedType.ts" +/** + * @gqlType SomeType + */ +interface MyInterface { + /** @gqlField */ + hello: string; +} +``` + +## Output + +### SDL + +```graphql +type SomeType { + hello: String +} +``` + +### TypeScript + +```ts +import { GraphQLSchema, GraphQLObjectType, GraphQLString } from "graphql"; +export function getSchema(): GraphQLSchema { + const SomeTypeType: GraphQLObjectType = new GraphQLObjectType({ + name: "SomeType", + fields() { + return { + hello: { + name: "hello", + type: GraphQLString + } + }; + } + }); + return new GraphQLSchema({ + types: [SomeTypeType] + }); +} +``` \ No newline at end of file diff --git a/src/tests/fixtures/type_definitions_from_interface/TagAttachedToWrongNode.invalid.ts.expected b/src/tests/fixtures/type_definitions_from_interface/TagAttachedToWrongNode.invalid.ts.expected deleted file mode 100644 index 5f35e21b..00000000 --- a/src/tests/fixtures/type_definitions_from_interface/TagAttachedToWrongNode.invalid.ts.expected +++ /dev/null @@ -1,13 +0,0 @@ ------------------ -INPUT ------------------ -/** @gqlType */ -function MyFunc() {} - ------------------ -OUTPUT ------------------ -src/tests/fixtures/type_definitions_from_interface/TagAttachedToWrongNode.invalid.ts:1:5 - error: `@gqlType` can only be used on class, interface or type declarations. e.g. `class MyType {}` - -1 /** @gqlType */ - ~~~~~~~~~ diff --git a/src/tests/fixtures/type_definitions_from_interface/TagAttachedToWrongNode.invalid.ts.expected.md b/src/tests/fixtures/type_definitions_from_interface/TagAttachedToWrongNode.invalid.ts.expected.md new file mode 100644 index 00000000..a01c1bd8 --- /dev/null +++ b/src/tests/fixtures/type_definitions_from_interface/TagAttachedToWrongNode.invalid.ts.expected.md @@ -0,0 +1,17 @@ +## input + +```ts title="type_definitions_from_interface/TagAttachedToWrongNode.invalid.ts" +/** @gqlType */ +function MyFunc() {} +``` + +## Output + +### Error Report + +```text +src/tests/fixtures/type_definitions_from_interface/TagAttachedToWrongNode.invalid.ts:1:5 - error: `@gqlType` can only be used on class, interface or type declarations. e.g. `class MyType {}` + +1 /** @gqlType */ + ~~~~~~~~~ +``` \ No newline at end of file diff --git a/src/tests/fixtures/typename/ImplementorMissingTypename.invalid.ts.expected b/src/tests/fixtures/typename/ImplementorMissingTypename.invalid.ts.expected deleted file mode 100644 index 6a23a5f8..00000000 --- a/src/tests/fixtures/typename/ImplementorMissingTypename.invalid.ts.expected +++ /dev/null @@ -1,27 +0,0 @@ ------------------ -INPUT ------------------ -/** @gqlType */ -class User implements IPerson { - /** @gqlField */ - name: string = "Alice"; -} - -/** @gqlInterface */ -export interface IPerson { - /** @gqlField */ - name: string; -} - ------------------ -OUTPUT ------------------ -src/tests/fixtures/typename/ImplementorMissingTypename.invalid.ts:2:7 - error: Cannot resolve typename. The type `User` implements `IPerson`, so it must either have a `__typename` property or be an exported class. - -2 class User implements IPerson { - ~~~~ - - src/tests/fixtures/typename/ImplementorMissingTypename.invalid.ts:8:18 - 8 export interface IPerson { - ~~~~~~~ - IPerson is defined here: diff --git a/src/tests/fixtures/typename/ImplementorMissingTypename.invalid.ts.expected.md b/src/tests/fixtures/typename/ImplementorMissingTypename.invalid.ts.expected.md new file mode 100644 index 00000000..3aa92133 --- /dev/null +++ b/src/tests/fixtures/typename/ImplementorMissingTypename.invalid.ts.expected.md @@ -0,0 +1,31 @@ +## input + +```ts title="typename/ImplementorMissingTypename.invalid.ts" +/** @gqlType */ +class User implements IPerson { + /** @gqlField */ + name: string = "Alice"; +} + +/** @gqlInterface */ +export interface IPerson { + /** @gqlField */ + name: string; +} +``` + +## Output + +### Error Report + +```text +src/tests/fixtures/typename/ImplementorMissingTypename.invalid.ts:2:7 - error: Cannot resolve typename. The type `User` implements `IPerson`, so it must either have a `__typename` property or be an exported class. + +2 class User implements IPerson { + ~~~~ + + src/tests/fixtures/typename/ImplementorMissingTypename.invalid.ts:8:18 + 8 export interface IPerson { + ~~~~~~~ + IPerson is defined here: +``` \ No newline at end of file diff --git a/src/tests/fixtures/typename/MethodTypename.invalid.ts.expected b/src/tests/fixtures/typename/MethodTypename.invalid.ts.expected deleted file mode 100644 index 28a7c3a9..00000000 --- a/src/tests/fixtures/typename/MethodTypename.invalid.ts.expected +++ /dev/null @@ -1,19 +0,0 @@ ------------------ -INPUT ------------------ -/** @gqlType */ -class User { - __typename() { - return "User"; - } - /** @gqlField */ - name: string = "Alice"; -} - ------------------ -OUTPUT ------------------ -src/tests/fixtures/typename/MethodTypename.invalid.ts:3:3 - error: Expected `__typename` to be a property declaration. For example: `__typename: "MyType"`. - -3 __typename() { - ~~~~~~~~~~ diff --git a/src/tests/fixtures/typename/MethodTypename.invalid.ts.expected.md b/src/tests/fixtures/typename/MethodTypename.invalid.ts.expected.md new file mode 100644 index 00000000..725c5406 --- /dev/null +++ b/src/tests/fixtures/typename/MethodTypename.invalid.ts.expected.md @@ -0,0 +1,23 @@ +## input + +```ts title="typename/MethodTypename.invalid.ts" +/** @gqlType */ +class User { + __typename() { + return "User"; + } + /** @gqlField */ + name: string = "Alice"; +} +``` + +## Output + +### Error Report + +```text +src/tests/fixtures/typename/MethodTypename.invalid.ts:3:3 - error: Expected `__typename` to be a property declaration. For example: `__typename: "MyType"`. + +3 __typename() { + ~~~~~~~~~~ +``` \ No newline at end of file diff --git a/src/tests/fixtures/typename/PropertySignatureTypename.ts.expected b/src/tests/fixtures/typename/PropertySignatureTypename.ts.expected deleted file mode 100644 index 09932219..00000000 --- a/src/tests/fixtures/typename/PropertySignatureTypename.ts.expected +++ /dev/null @@ -1,59 +0,0 @@ ------------------ -INPUT ------------------ -/** @gqlType */ -export class User implements IPerson { - __typename: "User"; - /** @gqlField */ - name: string; -} - -/** @gqlInterface */ -export interface IPerson { - /** @gqlField */ - name: string; -} - ------------------ -OUTPUT ------------------ --- SDL -- -interface IPerson { - name: String -} - -type User implements IPerson { - name: String -} --- TypeScript -- -import { GraphQLSchema, GraphQLInterfaceType, GraphQLString, GraphQLObjectType } from "graphql"; -export function getSchema(): GraphQLSchema { - const IPersonType: GraphQLInterfaceType = new GraphQLInterfaceType({ - name: "IPerson", - fields() { - return { - name: { - name: "name", - type: GraphQLString - } - }; - } - }); - const UserType: GraphQLObjectType = new GraphQLObjectType({ - name: "User", - fields() { - return { - name: { - name: "name", - type: GraphQLString - } - }; - }, - interfaces() { - return [IPersonType]; - } - }); - return new GraphQLSchema({ - types: [IPersonType, UserType] - }); -} diff --git a/src/tests/fixtures/typename/PropertySignatureTypename.ts.expected.md b/src/tests/fixtures/typename/PropertySignatureTypename.ts.expected.md new file mode 100644 index 00000000..4ef5b50c --- /dev/null +++ b/src/tests/fixtures/typename/PropertySignatureTypename.ts.expected.md @@ -0,0 +1,66 @@ +## input + +```ts title="typename/PropertySignatureTypename.ts" +/** @gqlType */ +export class User implements IPerson { + __typename: "User"; + /** @gqlField */ + name: string; +} + +/** @gqlInterface */ +export interface IPerson { + /** @gqlField */ + name: string; +} +``` + +## Output + +### SDL + +```graphql +interface IPerson { + name: String +} + +type User implements IPerson { + name: String +} +``` + +### TypeScript + +```ts +import { GraphQLSchema, GraphQLInterfaceType, GraphQLString, GraphQLObjectType } from "graphql"; +export function getSchema(): GraphQLSchema { + const IPersonType: GraphQLInterfaceType = new GraphQLInterfaceType({ + name: "IPerson", + fields() { + return { + name: { + name: "name", + type: GraphQLString + } + }; + } + }); + const UserType: GraphQLObjectType = new GraphQLObjectType({ + name: "User", + fields() { + return { + name: { + name: "name", + type: GraphQLString + } + }; + }, + interfaces() { + return [IPersonType]; + } + }); + return new GraphQLSchema({ + types: [IPersonType, UserType] + }); +} +``` \ No newline at end of file diff --git a/src/tests/fixtures/typename/PropertySignatureTypenameIncorrectName.invalid.ts.expected b/src/tests/fixtures/typename/PropertySignatureTypenameIncorrectName.invalid.ts.expected deleted file mode 100644 index 9b0ad71e..00000000 --- a/src/tests/fixtures/typename/PropertySignatureTypenameIncorrectName.invalid.ts.expected +++ /dev/null @@ -1,52 +0,0 @@ ------------------ -INPUT ------------------ -/** @gqlType */ -export class User implements IPerson { - __typename: "Group"; - /** @gqlField */ - name: string; -} - -/** @gqlInterface */ -export interface IPerson { - /** @gqlField */ - name: string; -} - ------------------ -OUTPUT ------------------ --- Error Report -- -src/tests/fixtures/typename/PropertySignatureTypenameIncorrectName.invalid.ts:3:15 - error: Expected `__typename` property to be `"User"`. This is needed to ensure Grats can determine the type of this object during GraphQL execution. - -3 __typename: "Group"; - ~~~~~~~ - - --- Code Action: "Create Grats-compatible `__typename` type" (fix-typename-type) -- -- Original -+ Fixed - -@@ -2,3 +2,3 @@ - export class User implements IPerson { -- __typename: "Group"; -+ __typename: "User"; - /** @gqlField */ - --- Applied Fixes -- - * Applied fix "Create Grats-compatible `__typename` type" in grats/src/tests/fixtures/typename/PropertySignatureTypenameIncorrectName.invalid.ts - --- Fixed Text -- -/** @gqlType */ -export class User implements IPerson { - __typename: "User"; - /** @gqlField */ - name: string; -} - -/** @gqlInterface */ -export interface IPerson { - /** @gqlField */ - name: string; -} diff --git a/src/tests/fixtures/typename/PropertySignatureTypenameIncorrectName.invalid.ts.expected.md b/src/tests/fixtures/typename/PropertySignatureTypenameIncorrectName.invalid.ts.expected.md new file mode 100644 index 00000000..87786961 --- /dev/null +++ b/src/tests/fixtures/typename/PropertySignatureTypenameIncorrectName.invalid.ts.expected.md @@ -0,0 +1,63 @@ +## input + +```ts title="typename/PropertySignatureTypenameIncorrectName.invalid.ts" +/** @gqlType */ +export class User implements IPerson { + __typename: "Group"; + /** @gqlField */ + name: string; +} + +/** @gqlInterface */ +export interface IPerson { + /** @gqlField */ + name: string; +} +``` + +## Output + +### Error Report + +```text +src/tests/fixtures/typename/PropertySignatureTypenameIncorrectName.invalid.ts:3:15 - error: Expected `__typename` property to be `"User"`. This is needed to ensure Grats can determine the type of this object during GraphQL execution. + +3 __typename: "Group"; + ~~~~~~~ +``` + +#### Code Action: "Create Grats-compatible `__typename` type" (fix-typename-type) + +```diff +- Original ++ Fixed + +@@ -2,3 +2,3 @@ + export class User implements IPerson { +- __typename: "Group"; ++ __typename: "User"; + /** @gqlField */ +``` + +#### Applied Fixes + +```text + * Applied fix "Create Grats-compatible `__typename` type" in grats/src/tests/fixtures/typename/PropertySignatureTypenameIncorrectName.invalid.ts +``` + +#### Fixed Text + +```typescript +/** @gqlType */ +export class User implements IPerson { + __typename: "User"; + /** @gqlField */ + name: string; +} + +/** @gqlInterface */ +export interface IPerson { + /** @gqlField */ + name: string; +} +``` \ No newline at end of file diff --git a/src/tests/fixtures/typename/PropertySignatureTypenameMissingType.invalid.ts.expected b/src/tests/fixtures/typename/PropertySignatureTypenameMissingType.invalid.ts.expected deleted file mode 100644 index 224b4016..00000000 --- a/src/tests/fixtures/typename/PropertySignatureTypenameMissingType.invalid.ts.expected +++ /dev/null @@ -1,52 +0,0 @@ ------------------ -INPUT ------------------ -/** @gqlType */ -export class User implements IPerson { - __typename; - /** @gqlField */ - name: string; -} - -/** @gqlInterface */ -export interface IPerson { - /** @gqlField */ - name: string; -} - ------------------ -OUTPUT ------------------ --- Error Report -- -src/tests/fixtures/typename/PropertySignatureTypenameMissingType.invalid.ts:3:3 - error: Expected `__typename` property to have an initializer or a string literal type. This is needed to ensure Grats can determine the type of this object during GraphQL execution. - -3 __typename; - ~~~~~~~~~~ - - --- Code Action: "Create Grats-compatible `__typename` property" (fix-typename-property) -- -- Original -+ Fixed - -@@ -2,3 +2,3 @@ - export class User implements IPerson { -- __typename; -+ __typename = "User" as const; - /** @gqlField */ - --- Applied Fixes -- - * Applied fix "Create Grats-compatible `__typename` property" in grats/src/tests/fixtures/typename/PropertySignatureTypenameMissingType.invalid.ts - --- Fixed Text -- -/** @gqlType */ -export class User implements IPerson { - __typename = "User" as const; - /** @gqlField */ - name: string; -} - -/** @gqlInterface */ -export interface IPerson { - /** @gqlField */ - name: string; -} diff --git a/src/tests/fixtures/typename/PropertySignatureTypenameMissingType.invalid.ts.expected.md b/src/tests/fixtures/typename/PropertySignatureTypenameMissingType.invalid.ts.expected.md new file mode 100644 index 00000000..6b2a443f --- /dev/null +++ b/src/tests/fixtures/typename/PropertySignatureTypenameMissingType.invalid.ts.expected.md @@ -0,0 +1,63 @@ +## input + +```ts title="typename/PropertySignatureTypenameMissingType.invalid.ts" +/** @gqlType */ +export class User implements IPerson { + __typename; + /** @gqlField */ + name: string; +} + +/** @gqlInterface */ +export interface IPerson { + /** @gqlField */ + name: string; +} +``` + +## Output + +### Error Report + +```text +src/tests/fixtures/typename/PropertySignatureTypenameMissingType.invalid.ts:3:3 - error: Expected `__typename` property to have an initializer or a string literal type. This is needed to ensure Grats can determine the type of this object during GraphQL execution. + +3 __typename; + ~~~~~~~~~~ +``` + +#### Code Action: "Create Grats-compatible `__typename` property" (fix-typename-property) + +```diff +- Original ++ Fixed + +@@ -2,3 +2,3 @@ + export class User implements IPerson { +- __typename; ++ __typename = "User" as const; + /** @gqlField */ +``` + +#### Applied Fixes + +```text + * Applied fix "Create Grats-compatible `__typename` property" in grats/src/tests/fixtures/typename/PropertySignatureTypenameMissingType.invalid.ts +``` + +#### Fixed Text + +```typescript +/** @gqlType */ +export class User implements IPerson { + __typename = "User" as const; + /** @gqlField */ + name: string; +} + +/** @gqlInterface */ +export interface IPerson { + /** @gqlField */ + name: string; +} +``` \ No newline at end of file diff --git a/src/tests/fixtures/typename/PropertySignatureTypenameNonLiteralType.invalid.ts.expected b/src/tests/fixtures/typename/PropertySignatureTypenameNonLiteralType.invalid.ts.expected deleted file mode 100644 index 176e1704..00000000 --- a/src/tests/fixtures/typename/PropertySignatureTypenameNonLiteralType.invalid.ts.expected +++ /dev/null @@ -1,52 +0,0 @@ ------------------ -INPUT ------------------ -/** @gqlType */ -export class User implements IPerson { - __typename: string; - /** @gqlField */ - name: string; -} - -/** @gqlInterface */ -export interface IPerson { - /** @gqlField */ - name: string; -} - ------------------ -OUTPUT ------------------ --- Error Report -- -src/tests/fixtures/typename/PropertySignatureTypenameNonLiteralType.invalid.ts:3:15 - error: Expected `__typename` property signature to specify the typename as a string literal string type. For example `__typename: "User";`. This is needed to ensure Grats can determine the type of this object during GraphQL execution. - -3 __typename: string; - ~~~~~~ - - --- Code Action: "Create Grats-compatible `__typename` type" (fix-typename-type) -- -- Original -+ Fixed - -@@ -2,3 +2,3 @@ - export class User implements IPerson { -- __typename: string; -+ __typename: "User"; - /** @gqlField */ - --- Applied Fixes -- - * Applied fix "Create Grats-compatible `__typename` type" in grats/src/tests/fixtures/typename/PropertySignatureTypenameNonLiteralType.invalid.ts - --- Fixed Text -- -/** @gqlType */ -export class User implements IPerson { - __typename: "User"; - /** @gqlField */ - name: string; -} - -/** @gqlInterface */ -export interface IPerson { - /** @gqlField */ - name: string; -} diff --git a/src/tests/fixtures/typename/PropertySignatureTypenameNonLiteralType.invalid.ts.expected.md b/src/tests/fixtures/typename/PropertySignatureTypenameNonLiteralType.invalid.ts.expected.md new file mode 100644 index 00000000..7e8d3edc --- /dev/null +++ b/src/tests/fixtures/typename/PropertySignatureTypenameNonLiteralType.invalid.ts.expected.md @@ -0,0 +1,63 @@ +## input + +```ts title="typename/PropertySignatureTypenameNonLiteralType.invalid.ts" +/** @gqlType */ +export class User implements IPerson { + __typename: string; + /** @gqlField */ + name: string; +} + +/** @gqlInterface */ +export interface IPerson { + /** @gqlField */ + name: string; +} +``` + +## Output + +### Error Report + +```text +src/tests/fixtures/typename/PropertySignatureTypenameNonLiteralType.invalid.ts:3:15 - error: Expected `__typename` property signature to specify the typename as a string literal string type. For example `__typename: "User";`. This is needed to ensure Grats can determine the type of this object during GraphQL execution. + +3 __typename: string; + ~~~~~~ +``` + +#### Code Action: "Create Grats-compatible `__typename` type" (fix-typename-type) + +```diff +- Original ++ Fixed + +@@ -2,3 +2,3 @@ + export class User implements IPerson { +- __typename: string; ++ __typename: "User"; + /** @gqlField */ +``` + +#### Applied Fixes + +```text + * Applied fix "Create Grats-compatible `__typename` type" in grats/src/tests/fixtures/typename/PropertySignatureTypenameNonLiteralType.invalid.ts +``` + +#### Fixed Text + +```typescript +/** @gqlType */ +export class User implements IPerson { + __typename: "User"; + /** @gqlField */ + name: string; +} + +/** @gqlInterface */ +export interface IPerson { + /** @gqlField */ + name: string; +} +``` \ No newline at end of file diff --git a/src/tests/fixtures/typename/PropertyTypename.ts.expected b/src/tests/fixtures/typename/PropertyTypename.ts.expected deleted file mode 100644 index 3ebd0ce8..00000000 --- a/src/tests/fixtures/typename/PropertyTypename.ts.expected +++ /dev/null @@ -1,35 +0,0 @@ ------------------ -INPUT ------------------ -/** @gqlType */ -export class User { - __typename = "User" as const; - /** @gqlField */ - name: string = "Alice"; -} - ------------------ -OUTPUT ------------------ --- SDL -- -type User { - name: String -} --- TypeScript -- -import { GraphQLSchema, GraphQLObjectType, GraphQLString } from "graphql"; -export function getSchema(): GraphQLSchema { - const UserType: GraphQLObjectType = new GraphQLObjectType({ - name: "User", - fields() { - return { - name: { - name: "name", - type: GraphQLString - } - }; - } - }); - return new GraphQLSchema({ - types: [UserType] - }); -} diff --git a/src/tests/fixtures/typename/PropertyTypename.ts.expected.md b/src/tests/fixtures/typename/PropertyTypename.ts.expected.md new file mode 100644 index 00000000..c33e3287 --- /dev/null +++ b/src/tests/fixtures/typename/PropertyTypename.ts.expected.md @@ -0,0 +1,42 @@ +## input + +```ts title="typename/PropertyTypename.ts" +/** @gqlType */ +export class User { + __typename = "User" as const; + /** @gqlField */ + name: string = "Alice"; +} +``` + +## Output + +### SDL + +```graphql +type User { + name: String +} +``` + +### TypeScript + +```ts +import { GraphQLSchema, GraphQLObjectType, GraphQLString } from "graphql"; +export function getSchema(): GraphQLSchema { + const UserType: GraphQLObjectType = new GraphQLObjectType({ + name: "User", + fields() { + return { + name: { + name: "name", + type: GraphQLString + } + }; + } + }); + return new GraphQLSchema({ + types: [UserType] + }); +} +``` \ No newline at end of file diff --git a/src/tests/fixtures/typename/PropertyTypenameDoesNotMatchClassName.invalid.ts.expected b/src/tests/fixtures/typename/PropertyTypenameDoesNotMatchClassName.invalid.ts.expected deleted file mode 100644 index 34ed324f..00000000 --- a/src/tests/fixtures/typename/PropertyTypenameDoesNotMatchClassName.invalid.ts.expected +++ /dev/null @@ -1,40 +0,0 @@ ------------------ -INPUT ------------------ -/** @gqlType */ -export class User { - __typename = "Group" as const; - /** @gqlField */ - name: string = "Alice"; -} - ------------------ -OUTPUT ------------------ --- Error Report -- -src/tests/fixtures/typename/PropertyTypenameDoesNotMatchClassName.invalid.ts:3:16 - error: Expected `__typename` property initializer to be `"User"`, found `"Group"`. This is needed to ensure Grats can determine the type of this object during GraphQL execution. - -3 __typename = "Group" as const; - ~~~~~~~ - - --- Code Action: "Create Grats-compatible `__typename` property" (fix-typename-property) -- -- Original -+ Fixed - -@@ -2,3 +2,3 @@ - export class User { -- __typename = "Group" as const; -+ __typename = "User" as const; - /** @gqlField */ - --- Applied Fixes -- - * Applied fix "Create Grats-compatible `__typename` property" in grats/src/tests/fixtures/typename/PropertyTypenameDoesNotMatchClassName.invalid.ts - --- Fixed Text -- -/** @gqlType */ -export class User { - __typename = "User" as const; - /** @gqlField */ - name: string = "Alice"; -} diff --git a/src/tests/fixtures/typename/PropertyTypenameDoesNotMatchClassName.invalid.ts.expected.md b/src/tests/fixtures/typename/PropertyTypenameDoesNotMatchClassName.invalid.ts.expected.md new file mode 100644 index 00000000..a3562cd2 --- /dev/null +++ b/src/tests/fixtures/typename/PropertyTypenameDoesNotMatchClassName.invalid.ts.expected.md @@ -0,0 +1,51 @@ +## input + +```ts title="typename/PropertyTypenameDoesNotMatchClassName.invalid.ts" +/** @gqlType */ +export class User { + __typename = "Group" as const; + /** @gqlField */ + name: string = "Alice"; +} +``` + +## Output + +### Error Report + +```text +src/tests/fixtures/typename/PropertyTypenameDoesNotMatchClassName.invalid.ts:3:16 - error: Expected `__typename` property initializer to be `"User"`, found `"Group"`. This is needed to ensure Grats can determine the type of this object during GraphQL execution. + +3 __typename = "Group" as const; + ~~~~~~~ +``` + +#### Code Action: "Create Grats-compatible `__typename` property" (fix-typename-property) + +```diff +- Original ++ Fixed + +@@ -2,3 +2,3 @@ + export class User { +- __typename = "Group" as const; ++ __typename = "User" as const; + /** @gqlField */ +``` + +#### Applied Fixes + +```text + * Applied fix "Create Grats-compatible `__typename` property" in grats/src/tests/fixtures/typename/PropertyTypenameDoesNotMatchClassName.invalid.ts +``` + +#### Fixed Text + +```typescript +/** @gqlType */ +export class User { + __typename = "User" as const; + /** @gqlField */ + name: string = "Alice"; +} +``` \ No newline at end of file diff --git a/src/tests/fixtures/typename/PropertyTypenameDoesNotMatchDeclaredName.invalid.ts.expected b/src/tests/fixtures/typename/PropertyTypenameDoesNotMatchDeclaredName.invalid.ts.expected deleted file mode 100644 index 3a890063..00000000 --- a/src/tests/fixtures/typename/PropertyTypenameDoesNotMatchDeclaredName.invalid.ts.expected +++ /dev/null @@ -1,40 +0,0 @@ ------------------ -INPUT ------------------ -/** @gqlType User */ -export class UserModel { - __typename = "UserModel" as const; - /** @gqlField */ - name: string = "Alice"; -} - ------------------ -OUTPUT ------------------ --- Error Report -- -src/tests/fixtures/typename/PropertyTypenameDoesNotMatchDeclaredName.invalid.ts:3:16 - error: Expected `__typename` property initializer to be `"User"`, found `"UserModel"`. This is needed to ensure Grats can determine the type of this object during GraphQL execution. - -3 __typename = "UserModel" as const; - ~~~~~~~~~~~ - - --- Code Action: "Create Grats-compatible `__typename` property" (fix-typename-property) -- -- Original -+ Fixed - -@@ -2,3 +2,3 @@ - export class UserModel { -- __typename = "UserModel" as const; -+ __typename = "User" as const; - /** @gqlField */ - --- Applied Fixes -- - * Applied fix "Create Grats-compatible `__typename` property" in grats/src/tests/fixtures/typename/PropertyTypenameDoesNotMatchDeclaredName.invalid.ts - --- Fixed Text -- -/** @gqlType User */ -export class UserModel { - __typename = "User" as const; - /** @gqlField */ - name: string = "Alice"; -} diff --git a/src/tests/fixtures/typename/PropertyTypenameDoesNotMatchDeclaredName.invalid.ts.expected.md b/src/tests/fixtures/typename/PropertyTypenameDoesNotMatchDeclaredName.invalid.ts.expected.md new file mode 100644 index 00000000..86e962df --- /dev/null +++ b/src/tests/fixtures/typename/PropertyTypenameDoesNotMatchDeclaredName.invalid.ts.expected.md @@ -0,0 +1,51 @@ +## input + +```ts title="typename/PropertyTypenameDoesNotMatchDeclaredName.invalid.ts" +/** @gqlType User */ +export class UserModel { + __typename = "UserModel" as const; + /** @gqlField */ + name: string = "Alice"; +} +``` + +## Output + +### Error Report + +```text +src/tests/fixtures/typename/PropertyTypenameDoesNotMatchDeclaredName.invalid.ts:3:16 - error: Expected `__typename` property initializer to be `"User"`, found `"UserModel"`. This is needed to ensure Grats can determine the type of this object during GraphQL execution. + +3 __typename = "UserModel" as const; + ~~~~~~~~~~~ +``` + +#### Code Action: "Create Grats-compatible `__typename` property" (fix-typename-property) + +```diff +- Original ++ Fixed + +@@ -2,3 +2,3 @@ + export class UserModel { +- __typename = "UserModel" as const; ++ __typename = "User" as const; + /** @gqlField */ +``` + +#### Applied Fixes + +```text + * Applied fix "Create Grats-compatible `__typename` property" in grats/src/tests/fixtures/typename/PropertyTypenameDoesNotMatchDeclaredName.invalid.ts +``` + +#### Fixed Text + +```typescript +/** @gqlType User */ +export class UserModel { + __typename = "User" as const; + /** @gqlField */ + name: string = "Alice"; +} +``` \ No newline at end of file diff --git a/src/tests/fixtures/typename/PropertyTypenameMustNeedToBeDeclaredAsConst.invalid.ts.expected b/src/tests/fixtures/typename/PropertyTypenameMustNeedToBeDeclaredAsConst.invalid.ts.expected deleted file mode 100644 index 0dd41c14..00000000 --- a/src/tests/fixtures/typename/PropertyTypenameMustNeedToBeDeclaredAsConst.invalid.ts.expected +++ /dev/null @@ -1,40 +0,0 @@ ------------------ -INPUT ------------------ -/** @gqlType */ -export class User { - __typename = "User"; - /** @gqlField */ - name: string = "Alice"; -} - ------------------ -OUTPUT ------------------ --- Error Report -- -src/tests/fixtures/typename/PropertyTypenameMustNeedToBeDeclaredAsConst.invalid.ts:3:16 - error: Expected `__typename` property initializer to be an expression with a const assertion. For example: `__typename = "User" as const` or `__typename: "User";`. This is needed to ensure Grats can determine the type of this object during GraphQL execution. - -3 __typename = "User"; - ~~~~~~ - - --- Code Action: "Create Grats-compatible `__typename` property" (fix-typename-property) -- -- Original -+ Fixed - -@@ -2,3 +2,3 @@ - export class User { -- __typename = "User"; -+ __typename = "User" as const; - /** @gqlField */ - --- Applied Fixes -- - * Applied fix "Create Grats-compatible `__typename` property" in grats/src/tests/fixtures/typename/PropertyTypenameMustNeedToBeDeclaredAsConst.invalid.ts - --- Fixed Text -- -/** @gqlType */ -export class User { - __typename = "User" as const; - /** @gqlField */ - name: string = "Alice"; -} diff --git a/src/tests/fixtures/typename/PropertyTypenameMustNeedToBeDeclaredAsConst.invalid.ts.expected.md b/src/tests/fixtures/typename/PropertyTypenameMustNeedToBeDeclaredAsConst.invalid.ts.expected.md new file mode 100644 index 00000000..ed6acb7a --- /dev/null +++ b/src/tests/fixtures/typename/PropertyTypenameMustNeedToBeDeclaredAsConst.invalid.ts.expected.md @@ -0,0 +1,51 @@ +## input + +```ts title="typename/PropertyTypenameMustNeedToBeDeclaredAsConst.invalid.ts" +/** @gqlType */ +export class User { + __typename = "User"; + /** @gqlField */ + name: string = "Alice"; +} +``` + +## Output + +### Error Report + +```text +src/tests/fixtures/typename/PropertyTypenameMustNeedToBeDeclaredAsConst.invalid.ts:3:16 - error: Expected `__typename` property initializer to be an expression with a const assertion. For example: `__typename = "User" as const` or `__typename: "User";`. This is needed to ensure Grats can determine the type of this object during GraphQL execution. + +3 __typename = "User"; + ~~~~~~ +``` + +#### Code Action: "Create Grats-compatible `__typename` property" (fix-typename-property) + +```diff +- Original ++ Fixed + +@@ -2,3 +2,3 @@ + export class User { +- __typename = "User"; ++ __typename = "User" as const; + /** @gqlField */ +``` + +#### Applied Fixes + +```text + * Applied fix "Create Grats-compatible `__typename` property" in grats/src/tests/fixtures/typename/PropertyTypenameMustNeedToBeDeclaredAsConst.invalid.ts +``` + +#### Fixed Text + +```typescript +/** @gqlType */ +export class User { + __typename = "User" as const; + /** @gqlField */ + name: string = "Alice"; +} +``` \ No newline at end of file diff --git a/src/tests/fixtures/typename/PropertyTypenameMustNeedToBeDeclaredAsExactlyConst.invalid.ts.expected b/src/tests/fixtures/typename/PropertyTypenameMustNeedToBeDeclaredAsExactlyConst.invalid.ts.expected deleted file mode 100644 index c835c749..00000000 --- a/src/tests/fixtures/typename/PropertyTypenameMustNeedToBeDeclaredAsExactlyConst.invalid.ts.expected +++ /dev/null @@ -1,44 +0,0 @@ ------------------ -INPUT ------------------ -/** @gqlType */ -export class User { - __typename = "User" as Foo; - /** @gqlField */ - name: string = "Alice"; -} - -type Foo = string; - ------------------ -OUTPUT ------------------ --- Error Report -- -src/tests/fixtures/typename/PropertyTypenameMustNeedToBeDeclaredAsExactlyConst.invalid.ts:3:26 - error: Expected `__typename` property type name to be "const". For example: `__typename = "User" as const` or `__typename: "User";`. This is needed to ensure Grats can determine the type of this object during GraphQL execution. - -3 __typename = "User" as Foo; - ~~~ - - --- Code Action: "Create Grats-compatible `__typename` property" (fix-typename-property) -- -- Original -+ Fixed - -@@ -2,3 +2,3 @@ - export class User { -- __typename = "User" as Foo; -+ __typename = "User" as const; - /** @gqlField */ - --- Applied Fixes -- - * Applied fix "Create Grats-compatible `__typename` property" in grats/src/tests/fixtures/typename/PropertyTypenameMustNeedToBeDeclaredAsExactlyConst.invalid.ts - --- Fixed Text -- -/** @gqlType */ -export class User { - __typename = "User" as const; - /** @gqlField */ - name: string = "Alice"; -} - -type Foo = string; diff --git a/src/tests/fixtures/typename/PropertyTypenameMustNeedToBeDeclaredAsExactlyConst.invalid.ts.expected.md b/src/tests/fixtures/typename/PropertyTypenameMustNeedToBeDeclaredAsExactlyConst.invalid.ts.expected.md new file mode 100644 index 00000000..37d83376 --- /dev/null +++ b/src/tests/fixtures/typename/PropertyTypenameMustNeedToBeDeclaredAsExactlyConst.invalid.ts.expected.md @@ -0,0 +1,55 @@ +## input + +```ts title="typename/PropertyTypenameMustNeedToBeDeclaredAsExactlyConst.invalid.ts" +/** @gqlType */ +export class User { + __typename = "User" as Foo; + /** @gqlField */ + name: string = "Alice"; +} + +type Foo = string; +``` + +## Output + +### Error Report + +```text +src/tests/fixtures/typename/PropertyTypenameMustNeedToBeDeclaredAsExactlyConst.invalid.ts:3:26 - error: Expected `__typename` property type name to be "const". For example: `__typename = "User" as const` or `__typename: "User";`. This is needed to ensure Grats can determine the type of this object during GraphQL execution. + +3 __typename = "User" as Foo; + ~~~ +``` + +#### Code Action: "Create Grats-compatible `__typename` property" (fix-typename-property) + +```diff +- Original ++ Fixed + +@@ -2,3 +2,3 @@ + export class User { +- __typename = "User" as Foo; ++ __typename = "User" as const; + /** @gqlField */ +``` + +#### Applied Fixes + +```text + * Applied fix "Create Grats-compatible `__typename` property" in grats/src/tests/fixtures/typename/PropertyTypenameMustNeedToBeDeclaredAsExactlyConst.invalid.ts +``` + +#### Fixed Text + +```typescript +/** @gqlType */ +export class User { + __typename = "User" as const; + /** @gqlField */ + name: string = "Alice"; +} + +type Foo = string; +``` \ No newline at end of file diff --git a/src/tests/fixtures/typename/PropertyTypenameNoInitializer.invalid.ts.expected b/src/tests/fixtures/typename/PropertyTypenameNoInitializer.invalid.ts.expected deleted file mode 100644 index 32f76fa0..00000000 --- a/src/tests/fixtures/typename/PropertyTypenameNoInitializer.invalid.ts.expected +++ /dev/null @@ -1,40 +0,0 @@ ------------------ -INPUT ------------------ -/** @gqlType */ -export class User { - __typename: string; - /** @gqlField */ - name: string = "Alice"; -} - ------------------ -OUTPUT ------------------ --- Error Report -- -src/tests/fixtures/typename/PropertyTypenameNoInitializer.invalid.ts:3:15 - error: Expected `__typename` property signature to specify the typename as a string literal string type. For example `__typename: "User";`. This is needed to ensure Grats can determine the type of this object during GraphQL execution. - -3 __typename: string; - ~~~~~~ - - --- Code Action: "Create Grats-compatible `__typename` type" (fix-typename-type) -- -- Original -+ Fixed - -@@ -2,3 +2,3 @@ - export class User { -- __typename: string; -+ __typename: "User"; - /** @gqlField */ - --- Applied Fixes -- - * Applied fix "Create Grats-compatible `__typename` type" in grats/src/tests/fixtures/typename/PropertyTypenameNoInitializer.invalid.ts - --- Fixed Text -- -/** @gqlType */ -export class User { - __typename: "User"; - /** @gqlField */ - name: string = "Alice"; -} diff --git a/src/tests/fixtures/typename/PropertyTypenameNoInitializer.invalid.ts.expected.md b/src/tests/fixtures/typename/PropertyTypenameNoInitializer.invalid.ts.expected.md new file mode 100644 index 00000000..f4fb38d9 --- /dev/null +++ b/src/tests/fixtures/typename/PropertyTypenameNoInitializer.invalid.ts.expected.md @@ -0,0 +1,51 @@ +## input + +```ts title="typename/PropertyTypenameNoInitializer.invalid.ts" +/** @gqlType */ +export class User { + __typename: string; + /** @gqlField */ + name: string = "Alice"; +} +``` + +## Output + +### Error Report + +```text +src/tests/fixtures/typename/PropertyTypenameNoInitializer.invalid.ts:3:15 - error: Expected `__typename` property signature to specify the typename as a string literal string type. For example `__typename: "User";`. This is needed to ensure Grats can determine the type of this object during GraphQL execution. + +3 __typename: string; + ~~~~~~ +``` + +#### Code Action: "Create Grats-compatible `__typename` type" (fix-typename-type) + +```diff +- Original ++ Fixed + +@@ -2,3 +2,3 @@ + export class User { +- __typename: string; ++ __typename: "User"; + /** @gqlField */ +``` + +#### Applied Fixes + +```text + * Applied fix "Create Grats-compatible `__typename` type" in grats/src/tests/fixtures/typename/PropertyTypenameNoInitializer.invalid.ts +``` + +#### Fixed Text + +```typescript +/** @gqlType */ +export class User { + __typename: "User"; + /** @gqlField */ + name: string = "Alice"; +} +``` \ No newline at end of file diff --git a/src/tests/fixtures/typename/PropertyTypenameNonStringInitializer.invalid.ts.expected b/src/tests/fixtures/typename/PropertyTypenameNonStringInitializer.invalid.ts.expected deleted file mode 100644 index acf0f3d8..00000000 --- a/src/tests/fixtures/typename/PropertyTypenameNonStringInitializer.invalid.ts.expected +++ /dev/null @@ -1,40 +0,0 @@ ------------------ -INPUT ------------------ -/** @gqlType */ -export class User { - __typename = 1 as const; - /** @gqlField */ - name: string = "Alice"; -} - ------------------ -OUTPUT ------------------ --- Error Report -- -src/tests/fixtures/typename/PropertyTypenameNonStringInitializer.invalid.ts:3:16 - error: Expected `__typename` property initializer to be a string literal. For example: `__typename = "User" as const` or `__typename: "User";`. This is needed to ensure Grats can determine the type of this object during GraphQL execution. - -3 __typename = 1 as const; - ~ - - --- Code Action: "Create Grats-compatible `__typename` property" (fix-typename-property) -- -- Original -+ Fixed - -@@ -2,3 +2,3 @@ - export class User { -- __typename = 1 as const; -+ __typename = "User" as const; - /** @gqlField */ - --- Applied Fixes -- - * Applied fix "Create Grats-compatible `__typename` property" in grats/src/tests/fixtures/typename/PropertyTypenameNonStringInitializer.invalid.ts - --- Fixed Text -- -/** @gqlType */ -export class User { - __typename = "User" as const; - /** @gqlField */ - name: string = "Alice"; -} diff --git a/src/tests/fixtures/typename/PropertyTypenameNonStringInitializer.invalid.ts.expected.md b/src/tests/fixtures/typename/PropertyTypenameNonStringInitializer.invalid.ts.expected.md new file mode 100644 index 00000000..b09457a6 --- /dev/null +++ b/src/tests/fixtures/typename/PropertyTypenameNonStringInitializer.invalid.ts.expected.md @@ -0,0 +1,51 @@ +## input + +```ts title="typename/PropertyTypenameNonStringInitializer.invalid.ts" +/** @gqlType */ +export class User { + __typename = 1 as const; + /** @gqlField */ + name: string = "Alice"; +} +``` + +## Output + +### Error Report + +```text +src/tests/fixtures/typename/PropertyTypenameNonStringInitializer.invalid.ts:3:16 - error: Expected `__typename` property initializer to be a string literal. For example: `__typename = "User" as const` or `__typename: "User";`. This is needed to ensure Grats can determine the type of this object during GraphQL execution. + +3 __typename = 1 as const; + ~ +``` + +#### Code Action: "Create Grats-compatible `__typename` property" (fix-typename-property) + +```diff +- Original ++ Fixed + +@@ -2,3 +2,3 @@ + export class User { +- __typename = 1 as const; ++ __typename = "User" as const; + /** @gqlField */ +``` + +#### Applied Fixes + +```text + * Applied fix "Create Grats-compatible `__typename` property" in grats/src/tests/fixtures/typename/PropertyTypenameNonStringInitializer.invalid.ts +``` + +#### Fixed Text + +```typescript +/** @gqlType */ +export class User { + __typename = "User" as const; + /** @gqlField */ + name: string = "Alice"; +} +``` \ No newline at end of file diff --git a/src/tests/fixtures/typename/UnionMemberMissingTypename.invalid.ts.expected b/src/tests/fixtures/typename/UnionMemberMissingTypename.invalid.ts.expected deleted file mode 100644 index f836c2c4..00000000 --- a/src/tests/fixtures/typename/UnionMemberMissingTypename.invalid.ts.expected +++ /dev/null @@ -1,39 +0,0 @@ ------------------ -INPUT ------------------ -/** @gqlType */ -class User { - /** @gqlField */ - name: string = "Alice"; -} - -/** @gqlType */ -class Group { - /** @gqlField */ - name: string = "Alice Fan Club"; -} - -/** @gqlUnion */ -export type MyUnion = User | Group; - ------------------ -OUTPUT ------------------ -src/tests/fixtures/typename/UnionMemberMissingTypename.invalid.ts:8:7 - error: Cannot resolve typename. The type `Group` is a member of `MyUnion`, so it must either have a `__typename` property or be an exported class. - -8 class Group { - ~~~~~ - - src/tests/fixtures/typename/UnionMemberMissingTypename.invalid.ts:14:13 - 14 export type MyUnion = User | Group; - ~~~~~~~ - MyUnion is defined here: -src/tests/fixtures/typename/UnionMemberMissingTypename.invalid.ts:2:7 - error: Cannot resolve typename. The type `User` is a member of `MyUnion`, so it must either have a `__typename` property or be an exported class. - -2 class User { - ~~~~ - - src/tests/fixtures/typename/UnionMemberMissingTypename.invalid.ts:14:13 - 14 export type MyUnion = User | Group; - ~~~~~~~ - MyUnion is defined here: diff --git a/src/tests/fixtures/typename/UnionMemberMissingTypename.invalid.ts.expected.md b/src/tests/fixtures/typename/UnionMemberMissingTypename.invalid.ts.expected.md new file mode 100644 index 00000000..716380dd --- /dev/null +++ b/src/tests/fixtures/typename/UnionMemberMissingTypename.invalid.ts.expected.md @@ -0,0 +1,43 @@ +## input + +```ts title="typename/UnionMemberMissingTypename.invalid.ts" +/** @gqlType */ +class User { + /** @gqlField */ + name: string = "Alice"; +} + +/** @gqlType */ +class Group { + /** @gqlField */ + name: string = "Alice Fan Club"; +} + +/** @gqlUnion */ +export type MyUnion = User | Group; +``` + +## Output + +### Error Report + +```text +src/tests/fixtures/typename/UnionMemberMissingTypename.invalid.ts:8:7 - error: Cannot resolve typename. The type `Group` is a member of `MyUnion`, so it must either have a `__typename` property or be an exported class. + +8 class Group { + ~~~~~ + + src/tests/fixtures/typename/UnionMemberMissingTypename.invalid.ts:14:13 + 14 export type MyUnion = User | Group; + ~~~~~~~ + MyUnion is defined here: +src/tests/fixtures/typename/UnionMemberMissingTypename.invalid.ts:2:7 - error: Cannot resolve typename. The type `User` is a member of `MyUnion`, so it must either have a `__typename` property or be an exported class. + +2 class User { + ~~~~ + + src/tests/fixtures/typename/UnionMemberMissingTypename.invalid.ts:14:13 + 14 export type MyUnion = User | Group; + ~~~~~~~ + MyUnion is defined here: +``` \ No newline at end of file diff --git a/src/tests/fixtures/unions/DefineUnionOfOneType.ts.expected b/src/tests/fixtures/unions/DefineUnionOfOneType.ts.expected deleted file mode 100644 index 7eebc76f..00000000 --- a/src/tests/fixtures/unions/DefineUnionOfOneType.ts.expected +++ /dev/null @@ -1,46 +0,0 @@ ------------------ -INPUT ------------------ -/** @gqlType */ -class User { - __typename = "User" as const; - /** @gqlField */ - name: string; -} - -/** @gqlUnion */ -type Actor = User; - ------------------ -OUTPUT ------------------ --- SDL -- -union Actor = User - -type User { - name: String -} --- TypeScript -- -import { GraphQLSchema, GraphQLUnionType, GraphQLObjectType, GraphQLString } from "graphql"; -export function getSchema(): GraphQLSchema { - const UserType: GraphQLObjectType = new GraphQLObjectType({ - name: "User", - fields() { - return { - name: { - name: "name", - type: GraphQLString - } - }; - } - }); - const ActorType: GraphQLUnionType = new GraphQLUnionType({ - name: "Actor", - types() { - return [UserType]; - } - }); - return new GraphQLSchema({ - types: [ActorType, UserType] - }); -} diff --git a/src/tests/fixtures/unions/DefineUnionOfOneType.ts.expected.md b/src/tests/fixtures/unions/DefineUnionOfOneType.ts.expected.md new file mode 100644 index 00000000..aa68d6ea --- /dev/null +++ b/src/tests/fixtures/unions/DefineUnionOfOneType.ts.expected.md @@ -0,0 +1,53 @@ +## input + +```ts title="unions/DefineUnionOfOneType.ts" +/** @gqlType */ +class User { + __typename = "User" as const; + /** @gqlField */ + name: string; +} + +/** @gqlUnion */ +type Actor = User; +``` + +## Output + +### SDL + +```graphql +union Actor = User + +type User { + name: String +} +``` + +### TypeScript + +```ts +import { GraphQLSchema, GraphQLUnionType, GraphQLObjectType, GraphQLString } from "graphql"; +export function getSchema(): GraphQLSchema { + const UserType: GraphQLObjectType = new GraphQLObjectType({ + name: "User", + fields() { + return { + name: { + name: "name", + type: GraphQLString + } + }; + } + }); + const ActorType: GraphQLUnionType = new GraphQLUnionType({ + name: "Actor", + types() { + return [UserType]; + } + }); + return new GraphQLSchema({ + types: [ActorType, UserType] + }); +} +``` \ No newline at end of file diff --git a/src/tests/fixtures/unions/DefineUnionType.ts.expected b/src/tests/fixtures/unions/DefineUnionType.ts.expected deleted file mode 100644 index 47b5ed1f..00000000 --- a/src/tests/fixtures/unions/DefineUnionType.ts.expected +++ /dev/null @@ -1,89 +0,0 @@ ------------------ -INPUT ------------------ -/** @gqlType */ -export default class SomeType { - /** @gqlField */ - me: Actor; -} - -/** @gqlType */ -class User { - __typename = "User" as const; - /** @gqlField */ - name: string; -} - -/** @gqlType */ -class Entity { - __typename = "Entity" as const; - /** @gqlField */ - description: string; -} - -/** @gqlUnion */ -type Actor = User | Entity; - ------------------ -OUTPUT ------------------ --- SDL -- -union Actor = Entity | User - -type Entity { - description: String -} - -type SomeType { - me: Actor -} - -type User { - name: String -} --- TypeScript -- -import { GraphQLSchema, GraphQLUnionType, GraphQLObjectType, GraphQLString } from "graphql"; -export function getSchema(): GraphQLSchema { - const EntityType: GraphQLObjectType = new GraphQLObjectType({ - name: "Entity", - fields() { - return { - description: { - name: "description", - type: GraphQLString - } - }; - } - }); - const UserType: GraphQLObjectType = new GraphQLObjectType({ - name: "User", - fields() { - return { - name: { - name: "name", - type: GraphQLString - } - }; - } - }); - const ActorType: GraphQLUnionType = new GraphQLUnionType({ - name: "Actor", - types() { - return [EntityType, UserType]; - } - }); - const SomeTypeType: GraphQLObjectType = new GraphQLObjectType({ - name: "SomeType", - fields() { - return { - me: { - name: "me", - type: ActorType - } - }; - } - }); - return new GraphQLSchema({ - types: [ActorType, EntityType, SomeTypeType, UserType] - }); -} diff --git a/src/tests/fixtures/unions/DefineUnionType.ts.expected.md b/src/tests/fixtures/unions/DefineUnionType.ts.expected.md new file mode 100644 index 00000000..25cb47b9 --- /dev/null +++ b/src/tests/fixtures/unions/DefineUnionType.ts.expected.md @@ -0,0 +1,96 @@ +## input + +```ts title="unions/DefineUnionType.ts" +/** @gqlType */ +export default class SomeType { + /** @gqlField */ + me: Actor; +} + +/** @gqlType */ +class User { + __typename = "User" as const; + /** @gqlField */ + name: string; +} + +/** @gqlType */ +class Entity { + __typename = "Entity" as const; + /** @gqlField */ + description: string; +} + +/** @gqlUnion */ +type Actor = User | Entity; +``` + +## Output + +### SDL + +```graphql +union Actor = Entity | User + +type Entity { + description: String +} + +type SomeType { + me: Actor +} + +type User { + name: String +} +``` + +### TypeScript + +```ts +import { GraphQLSchema, GraphQLUnionType, GraphQLObjectType, GraphQLString } from "graphql"; +export function getSchema(): GraphQLSchema { + const EntityType: GraphQLObjectType = new GraphQLObjectType({ + name: "Entity", + fields() { + return { + description: { + name: "description", + type: GraphQLString + } + }; + } + }); + const UserType: GraphQLObjectType = new GraphQLObjectType({ + name: "User", + fields() { + return { + name: { + name: "name", + type: GraphQLString + } + }; + } + }); + const ActorType: GraphQLUnionType = new GraphQLUnionType({ + name: "Actor", + types() { + return [EntityType, UserType]; + } + }); + const SomeTypeType: GraphQLObjectType = new GraphQLObjectType({ + name: "SomeType", + fields() { + return { + me: { + name: "me", + type: ActorType + } + }; + } + }); + return new GraphQLSchema({ + types: [ActorType, EntityType, SomeTypeType, UserType] + }); +} +``` \ No newline at end of file diff --git a/src/tests/fixtures/unions/DefineUnionTypeContainingInterface.invalid.ts.expected b/src/tests/fixtures/unions/DefineUnionTypeContainingInterface.invalid.ts.expected deleted file mode 100644 index 6da1d821..00000000 --- a/src/tests/fixtures/unions/DefineUnionTypeContainingInterface.invalid.ts.expected +++ /dev/null @@ -1,31 +0,0 @@ ------------------ -INPUT ------------------ -/** @gqlType */ -export default class SomeType { - /** @gqlField */ - me: Actor; -} - -/** @gqlType */ -class User { - /** @gqlField */ - name: string; -} - -/** @gqlInterface */ -interface Entity { - /** @gqlField */ - description: string; -} - -/** @gqlUnion */ -type Actor = User | Entity; - ------------------ -OUTPUT ------------------ -src/tests/fixtures/unions/DefineUnionTypeContainingInterface.invalid.ts:20:21 - error: Union type Actor can only include Object types, it cannot include Entity. - -20 type Actor = User | Entity; - ~~~~~~ diff --git a/src/tests/fixtures/unions/DefineUnionTypeContainingInterface.invalid.ts.expected.md b/src/tests/fixtures/unions/DefineUnionTypeContainingInterface.invalid.ts.expected.md new file mode 100644 index 00000000..231de50e --- /dev/null +++ b/src/tests/fixtures/unions/DefineUnionTypeContainingInterface.invalid.ts.expected.md @@ -0,0 +1,35 @@ +## input + +```ts title="unions/DefineUnionTypeContainingInterface.invalid.ts" +/** @gqlType */ +export default class SomeType { + /** @gqlField */ + me: Actor; +} + +/** @gqlType */ +class User { + /** @gqlField */ + name: string; +} + +/** @gqlInterface */ +interface Entity { + /** @gqlField */ + description: string; +} + +/** @gqlUnion */ +type Actor = User | Entity; +``` + +## Output + +### Error Report + +```text +src/tests/fixtures/unions/DefineUnionTypeContainingInterface.invalid.ts:20:21 - error: Union type Actor can only include Object types, it cannot include Entity. + +20 type Actor = User | Entity; + ~~~~~~ +``` \ No newline at end of file diff --git a/src/tests/fixtures/unions/DefineUnionTypeReferencingInputType.invalid.ts.expected b/src/tests/fixtures/unions/DefineUnionTypeReferencingInputType.invalid.ts.expected deleted file mode 100644 index fde8e9a1..00000000 --- a/src/tests/fixtures/unions/DefineUnionTypeReferencingInputType.invalid.ts.expected +++ /dev/null @@ -1,30 +0,0 @@ ------------------ -INPUT ------------------ -/** @gqlType */ -export default class SomeType { - /** @gqlField */ - me: Actor; -} - -/** @gqlType */ -class User { - /** @gqlField */ - name: string; -} - -/** @gqlInput */ -type Entity = { - description: string; -}; - -/** @gqlUnion */ -type Actor = User | Entity; - ------------------ -OUTPUT ------------------ -src/tests/fixtures/unions/DefineUnionTypeReferencingInputType.invalid.ts:19:21 - error: Union type Actor can only include Object types, it cannot include Entity. - -19 type Actor = User | Entity; - ~~~~~~ diff --git a/src/tests/fixtures/unions/DefineUnionTypeReferencingInputType.invalid.ts.expected.md b/src/tests/fixtures/unions/DefineUnionTypeReferencingInputType.invalid.ts.expected.md new file mode 100644 index 00000000..adfee77b --- /dev/null +++ b/src/tests/fixtures/unions/DefineUnionTypeReferencingInputType.invalid.ts.expected.md @@ -0,0 +1,34 @@ +## input + +```ts title="unions/DefineUnionTypeReferencingInputType.invalid.ts" +/** @gqlType */ +export default class SomeType { + /** @gqlField */ + me: Actor; +} + +/** @gqlType */ +class User { + /** @gqlField */ + name: string; +} + +/** @gqlInput */ +type Entity = { + description: string; +}; + +/** @gqlUnion */ +type Actor = User | Entity; +``` + +## Output + +### Error Report + +```text +src/tests/fixtures/unions/DefineUnionTypeReferencingInputType.invalid.ts:19:21 - error: Union type Actor can only include Object types, it cannot include Entity. + +19 type Actor = User | Entity; + ~~~~~~ +``` \ No newline at end of file diff --git a/src/tests/fixtures/unions/DefineUnionTypeReferencingLiteral.invalid.ts.expected b/src/tests/fixtures/unions/DefineUnionTypeReferencingLiteral.invalid.ts.expected deleted file mode 100644 index db17d41d..00000000 --- a/src/tests/fixtures/unions/DefineUnionTypeReferencingLiteral.invalid.ts.expected +++ /dev/null @@ -1,27 +0,0 @@ ------------------ -INPUT ------------------ -/** @gqlType */ -export default class SomeType { - /** @gqlField */ - me: Actor; -} - -/** @gqlType */ -class User { - /** @gqlField */ - name: string; -} - -/** @gqlUnion */ -type Actor = User | "LOL"; - ------------------ -OUTPUT ------------------ -src/tests/fixtures/unions/DefineUnionTypeReferencingLiteral.invalid.ts:14:21 - error: Expected `@gqlUnion` union members to be type references. Grats expects union members to be references to something annotated with `@gqlType`. - -If you think Grats should be able to infer this union member, please report an issue at https://github.com/captbaritone/grats/issues. - -14 type Actor = User | "LOL"; - ~~~~~ diff --git a/src/tests/fixtures/unions/DefineUnionTypeReferencingLiteral.invalid.ts.expected.md b/src/tests/fixtures/unions/DefineUnionTypeReferencingLiteral.invalid.ts.expected.md new file mode 100644 index 00000000..7200870a --- /dev/null +++ b/src/tests/fixtures/unions/DefineUnionTypeReferencingLiteral.invalid.ts.expected.md @@ -0,0 +1,31 @@ +## input + +```ts title="unions/DefineUnionTypeReferencingLiteral.invalid.ts" +/** @gqlType */ +export default class SomeType { + /** @gqlField */ + me: Actor; +} + +/** @gqlType */ +class User { + /** @gqlField */ + name: string; +} + +/** @gqlUnion */ +type Actor = User | "LOL"; +``` + +## Output + +### Error Report + +```text +src/tests/fixtures/unions/DefineUnionTypeReferencingLiteral.invalid.ts:14:21 - error: Expected `@gqlUnion` union members to be type references. Grats expects union members to be references to something annotated with `@gqlType`. + +If you think Grats should be able to infer this union member, please report an issue at https://github.com/captbaritone/grats/issues. + +14 type Actor = User | "LOL"; + ~~~~~ +``` \ No newline at end of file diff --git a/src/tests/fixtures/unions/DefineUnionTypeWithInterfaces.ts.expected b/src/tests/fixtures/unions/DefineUnionTypeWithInterfaces.ts.expected deleted file mode 100644 index 7fecbbb1..00000000 --- a/src/tests/fixtures/unions/DefineUnionTypeWithInterfaces.ts.expected +++ /dev/null @@ -1,89 +0,0 @@ ------------------ -INPUT ------------------ -/** @gqlType */ -export default class SomeType { - /** @gqlField */ - me: Actor; -} - -/** @gqlType */ -interface User { - __typename: "User"; - /** @gqlField */ - name: string; -} - -/** @gqlType */ -interface Entity { - __typename: "Entity"; - /** @gqlField */ - description: string; -} - -/** @gqlUnion */ -type Actor = User | Entity; - ------------------ -OUTPUT ------------------ --- SDL -- -union Actor = Entity | User - -type Entity { - description: String -} - -type SomeType { - me: Actor -} - -type User { - name: String -} --- TypeScript -- -import { GraphQLSchema, GraphQLUnionType, GraphQLObjectType, GraphQLString } from "graphql"; -export function getSchema(): GraphQLSchema { - const EntityType: GraphQLObjectType = new GraphQLObjectType({ - name: "Entity", - fields() { - return { - description: { - name: "description", - type: GraphQLString - } - }; - } - }); - const UserType: GraphQLObjectType = new GraphQLObjectType({ - name: "User", - fields() { - return { - name: { - name: "name", - type: GraphQLString - } - }; - } - }); - const ActorType: GraphQLUnionType = new GraphQLUnionType({ - name: "Actor", - types() { - return [EntityType, UserType]; - } - }); - const SomeTypeType: GraphQLObjectType = new GraphQLObjectType({ - name: "SomeType", - fields() { - return { - me: { - name: "me", - type: ActorType - } - }; - } - }); - return new GraphQLSchema({ - types: [ActorType, EntityType, SomeTypeType, UserType] - }); -} diff --git a/src/tests/fixtures/unions/DefineUnionTypeWithInterfaces.ts.expected.md b/src/tests/fixtures/unions/DefineUnionTypeWithInterfaces.ts.expected.md new file mode 100644 index 00000000..e41edef8 --- /dev/null +++ b/src/tests/fixtures/unions/DefineUnionTypeWithInterfaces.ts.expected.md @@ -0,0 +1,96 @@ +## input + +```ts title="unions/DefineUnionTypeWithInterfaces.ts" +/** @gqlType */ +export default class SomeType { + /** @gqlField */ + me: Actor; +} + +/** @gqlType */ +interface User { + __typename: "User"; + /** @gqlField */ + name: string; +} + +/** @gqlType */ +interface Entity { + __typename: "Entity"; + /** @gqlField */ + description: string; +} + +/** @gqlUnion */ +type Actor = User | Entity; +``` + +## Output + +### SDL + +```graphql +union Actor = Entity | User + +type Entity { + description: String +} + +type SomeType { + me: Actor +} + +type User { + name: String +} +``` + +### TypeScript + +```ts +import { GraphQLSchema, GraphQLUnionType, GraphQLObjectType, GraphQLString } from "graphql"; +export function getSchema(): GraphQLSchema { + const EntityType: GraphQLObjectType = new GraphQLObjectType({ + name: "Entity", + fields() { + return { + description: { + name: "description", + type: GraphQLString + } + }; + } + }); + const UserType: GraphQLObjectType = new GraphQLObjectType({ + name: "User", + fields() { + return { + name: { + name: "name", + type: GraphQLString + } + }; + } + }); + const ActorType: GraphQLUnionType = new GraphQLUnionType({ + name: "Actor", + types() { + return [EntityType, UserType]; + } + }); + const SomeTypeType: GraphQLObjectType = new GraphQLObjectType({ + name: "SomeType", + fields() { + return { + me: { + name: "me", + type: ActorType + } + }; + } + }); + return new GraphQLSchema({ + types: [ActorType, EntityType, SomeTypeType, UserType] + }); +} +``` \ No newline at end of file diff --git a/src/tests/fixtures/unions/DefineUnionTypeWithTypeLiterals.ts.expected b/src/tests/fixtures/unions/DefineUnionTypeWithTypeLiterals.ts.expected deleted file mode 100644 index 4c1f4dfb..00000000 --- a/src/tests/fixtures/unions/DefineUnionTypeWithTypeLiterals.ts.expected +++ /dev/null @@ -1,89 +0,0 @@ ------------------ -INPUT ------------------ -/** @gqlType */ -export default class SomeType { - /** @gqlField */ - me: Actor; -} - -/** @gqlType */ -type User = { - __typename: "User"; - /** @gqlField */ - name: string; -}; - -/** @gqlType */ -type Entity = { - __typename: "Entity"; - /** @gqlField */ - description: string; -}; - -/** @gqlUnion */ -type Actor = User | Entity; - ------------------ -OUTPUT ------------------ --- SDL -- -union Actor = Entity | User - -type Entity { - description: String -} - -type SomeType { - me: Actor -} - -type User { - name: String -} --- TypeScript -- -import { GraphQLSchema, GraphQLUnionType, GraphQLObjectType, GraphQLString } from "graphql"; -export function getSchema(): GraphQLSchema { - const EntityType: GraphQLObjectType = new GraphQLObjectType({ - name: "Entity", - fields() { - return { - description: { - name: "description", - type: GraphQLString - } - }; - } - }); - const UserType: GraphQLObjectType = new GraphQLObjectType({ - name: "User", - fields() { - return { - name: { - name: "name", - type: GraphQLString - } - }; - } - }); - const ActorType: GraphQLUnionType = new GraphQLUnionType({ - name: "Actor", - types() { - return [EntityType, UserType]; - } - }); - const SomeTypeType: GraphQLObjectType = new GraphQLObjectType({ - name: "SomeType", - fields() { - return { - me: { - name: "me", - type: ActorType - } - }; - } - }); - return new GraphQLSchema({ - types: [ActorType, EntityType, SomeTypeType, UserType] - }); -} diff --git a/src/tests/fixtures/unions/DefineUnionTypeWithTypeLiterals.ts.expected.md b/src/tests/fixtures/unions/DefineUnionTypeWithTypeLiterals.ts.expected.md new file mode 100644 index 00000000..a82b7ba1 --- /dev/null +++ b/src/tests/fixtures/unions/DefineUnionTypeWithTypeLiterals.ts.expected.md @@ -0,0 +1,96 @@ +## input + +```ts title="unions/DefineUnionTypeWithTypeLiterals.ts" +/** @gqlType */ +export default class SomeType { + /** @gqlField */ + me: Actor; +} + +/** @gqlType */ +type User = { + __typename: "User"; + /** @gqlField */ + name: string; +}; + +/** @gqlType */ +type Entity = { + __typename: "Entity"; + /** @gqlField */ + description: string; +}; + +/** @gqlUnion */ +type Actor = User | Entity; +``` + +## Output + +### SDL + +```graphql +union Actor = Entity | User + +type Entity { + description: String +} + +type SomeType { + me: Actor +} + +type User { + name: String +} +``` + +### TypeScript + +```ts +import { GraphQLSchema, GraphQLUnionType, GraphQLObjectType, GraphQLString } from "graphql"; +export function getSchema(): GraphQLSchema { + const EntityType: GraphQLObjectType = new GraphQLObjectType({ + name: "Entity", + fields() { + return { + description: { + name: "description", + type: GraphQLString + } + }; + } + }); + const UserType: GraphQLObjectType = new GraphQLObjectType({ + name: "User", + fields() { + return { + name: { + name: "name", + type: GraphQLString + } + }; + } + }); + const ActorType: GraphQLUnionType = new GraphQLUnionType({ + name: "Actor", + types() { + return [EntityType, UserType]; + } + }); + const SomeTypeType: GraphQLObjectType = new GraphQLObjectType({ + name: "SomeType", + fields() { + return { + me: { + name: "me", + type: ActorType + } + }; + } + }); + return new GraphQLSchema({ + types: [ActorType, EntityType, SomeTypeType, UserType] + }); +} +``` \ No newline at end of file diff --git a/src/tests/fixtures/unions/UnionAsMemberOfItself.invalid.ts.expected b/src/tests/fixtures/unions/UnionAsMemberOfItself.invalid.ts.expected deleted file mode 100644 index 2370d7dd..00000000 --- a/src/tests/fixtures/unions/UnionAsMemberOfItself.invalid.ts.expected +++ /dev/null @@ -1,87 +0,0 @@ ------------------ -INPUT ------------------ -/** @gqlType */ -export default class SomeType { - /** @gqlField */ - me: Actor; -} - -/** @gqlType */ -class User { - __typename = "User"; - /** @gqlField */ - name: string; -} - -/** @gqlType */ -class Entity { - __typename = "Entity"; - /** @gqlField */ - description: string; -} - -/** @gqlUnion */ -type Actor = User | Entity | Actor; - ------------------ -OUTPUT ------------------ --- Error Report -- -src/tests/fixtures/unions/UnionAsMemberOfItself.invalid.ts:9:16 - error: Expected `__typename` property initializer to be an expression with a const assertion. For example: `__typename = "User" as const` or `__typename: "User";`. This is needed to ensure Grats can determine the type of this object during GraphQL execution. - -9 __typename = "User"; - ~~~~~~ - -src/tests/fixtures/unions/UnionAsMemberOfItself.invalid.ts:16:16 - error: Expected `__typename` property initializer to be an expression with a const assertion. For example: `__typename = "Entity" as const` or `__typename: "Entity";`. This is needed to ensure Grats can determine the type of this object during GraphQL execution. - -16 __typename = "Entity"; - ~~~~~~~~ - - --- Code Action: "Create Grats-compatible `__typename` property" (fix-typename-property) -- -- Original -+ Fixed - -@@ -8,3 +8,3 @@ - class User { -- __typename = "User"; -+ __typename = "User" as const; - /** @gqlField */ --- Code Action: "Create Grats-compatible `__typename` property" (fix-typename-property) -- -- Original -+ Fixed - -@@ -15,3 +15,3 @@ - class Entity { -- __typename = "Entity"; -+ __typename = "Entity" as const; - /** @gqlField */ - --- Applied Fixes -- - * Applied fix "Create Grats-compatible `__typename` property" in grats/src/tests/fixtures/unions/UnionAsMemberOfItself.invalid.ts - * Applied fix "Create Grats-compatible `__typename` property" in grats/src/tests/fixtures/unions/UnionAsMemberOfItself.invalid.ts - --- Fixed Text -- -/** @gqlType */ -export default class SomeType { - /** @gqlField */ - me: Actor; -} - -/** @gqlType */ -class User { - __typename = "User" as const; - /** @gqlField */ - name: string; -} - -/** @gqlType */ -class Entity { - __typename = "Entity" as const; - /** @gqlField */ - description: string; -} - -/** @gqlUnion */ -type Actor = User | Entity | Actor; diff --git a/src/tests/fixtures/unions/UnionAsMemberOfItself.invalid.ts.expected.md b/src/tests/fixtures/unions/UnionAsMemberOfItself.invalid.ts.expected.md new file mode 100644 index 00000000..6179b0c0 --- /dev/null +++ b/src/tests/fixtures/unions/UnionAsMemberOfItself.invalid.ts.expected.md @@ -0,0 +1,102 @@ +## input + +```ts title="unions/UnionAsMemberOfItself.invalid.ts" +/** @gqlType */ +export default class SomeType { + /** @gqlField */ + me: Actor; +} + +/** @gqlType */ +class User { + __typename = "User"; + /** @gqlField */ + name: string; +} + +/** @gqlType */ +class Entity { + __typename = "Entity"; + /** @gqlField */ + description: string; +} + +/** @gqlUnion */ +type Actor = User | Entity | Actor; +``` + +## Output + +### Error Report + +```text +src/tests/fixtures/unions/UnionAsMemberOfItself.invalid.ts:9:16 - error: Expected `__typename` property initializer to be an expression with a const assertion. For example: `__typename = "User" as const` or `__typename: "User";`. This is needed to ensure Grats can determine the type of this object during GraphQL execution. + +9 __typename = "User"; + ~~~~~~ + +src/tests/fixtures/unions/UnionAsMemberOfItself.invalid.ts:16:16 - error: Expected `__typename` property initializer to be an expression with a const assertion. For example: `__typename = "Entity" as const` or `__typename: "Entity";`. This is needed to ensure Grats can determine the type of this object during GraphQL execution. + +16 __typename = "Entity"; + ~~~~~~~~ +``` + +#### Code Action: "Create Grats-compatible `__typename` property" (fix-typename-property) + +```diff +- Original ++ Fixed + +@@ -8,3 +8,3 @@ + class User { +- __typename = "User"; ++ __typename = "User" as const; + /** @gqlField */ +``` + +#### Code Action: "Create Grats-compatible `__typename` property" (fix-typename-property) + +```diff +- Original ++ Fixed + +@@ -15,3 +15,3 @@ + class Entity { +- __typename = "Entity"; ++ __typename = "Entity" as const; + /** @gqlField */ +``` + +#### Applied Fixes + +```text + * Applied fix "Create Grats-compatible `__typename` property" in grats/src/tests/fixtures/unions/UnionAsMemberOfItself.invalid.ts + * Applied fix "Create Grats-compatible `__typename` property" in grats/src/tests/fixtures/unions/UnionAsMemberOfItself.invalid.ts +``` + +#### Fixed Text + +```typescript +/** @gqlType */ +export default class SomeType { + /** @gqlField */ + me: Actor; +} + +/** @gqlType */ +class User { + __typename = "User" as const; + /** @gqlField */ + name: string; +} + +/** @gqlType */ +class Entity { + __typename = "Entity" as const; + /** @gqlField */ + description: string; +} + +/** @gqlUnion */ +type Actor = User | Entity | Actor; +``` \ No newline at end of file diff --git a/src/tests/fixtures/unions/UnionAsMemberOfOtherUnion.invalid.ts.expected b/src/tests/fixtures/unions/UnionAsMemberOfOtherUnion.invalid.ts.expected deleted file mode 100644 index 8ef73450..00000000 --- a/src/tests/fixtures/unions/UnionAsMemberOfOtherUnion.invalid.ts.expected +++ /dev/null @@ -1,43 +0,0 @@ ------------------ -INPUT ------------------ -/** @gqlType */ -export default class SomeType { - /** @gqlField */ - me: Actor; -} - -/** @gqlType */ -class User { - __typename = "User" as const; - /** @gqlField */ - name: string; -} - -/** @gqlType */ -class Entity { - __typename = "Entity" as const; - /** @gqlField */ - description: string; -} - -/** @gqlType */ -class Admin { - __typename = "Admin" as const; - /** @gqlField */ - description: string; -} - -/** @gqlUnion */ -type Foo = User | Entity; - -/** @gqlUnion */ -type Actor = Admin | Foo; - ------------------ -OUTPUT ------------------ -src/tests/fixtures/unions/UnionAsMemberOfOtherUnion.invalid.ts:32:22 - error: Union type Actor can only include Object types, it cannot include Foo. - -32 type Actor = Admin | Foo; - ~~~ diff --git a/src/tests/fixtures/unions/UnionAsMemberOfOtherUnion.invalid.ts.expected.md b/src/tests/fixtures/unions/UnionAsMemberOfOtherUnion.invalid.ts.expected.md new file mode 100644 index 00000000..64fb7cc9 --- /dev/null +++ b/src/tests/fixtures/unions/UnionAsMemberOfOtherUnion.invalid.ts.expected.md @@ -0,0 +1,47 @@ +## input + +```ts title="unions/UnionAsMemberOfOtherUnion.invalid.ts" +/** @gqlType */ +export default class SomeType { + /** @gqlField */ + me: Actor; +} + +/** @gqlType */ +class User { + __typename = "User" as const; + /** @gqlField */ + name: string; +} + +/** @gqlType */ +class Entity { + __typename = "Entity" as const; + /** @gqlField */ + description: string; +} + +/** @gqlType */ +class Admin { + __typename = "Admin" as const; + /** @gqlField */ + description: string; +} + +/** @gqlUnion */ +type Foo = User | Entity; + +/** @gqlUnion */ +type Actor = Admin | Foo; +``` + +## Output + +### Error Report + +```text +src/tests/fixtures/unions/UnionAsMemberOfOtherUnion.invalid.ts:32:22 - error: Union type Actor can only include Object types, it cannot include Foo. + +32 type Actor = Admin | Foo; + ~~~ +``` \ No newline at end of file diff --git a/src/tests/fixtures/unions/UnionWithDescription.ts.expected b/src/tests/fixtures/unions/UnionWithDescription.ts.expected deleted file mode 100644 index 863344b7..00000000 --- a/src/tests/fixtures/unions/UnionWithDescription.ts.expected +++ /dev/null @@ -1,94 +0,0 @@ ------------------ -INPUT ------------------ -/** @gqlType */ -export default class SomeType { - /** @gqlField */ - me: Actor; -} - -/** @gqlType */ -class User { - __typename = "User" as const; - /** @gqlField */ - name: string; -} - -/** @gqlType */ -class Entity { - __typename = "Entity" as const; - /** @gqlField */ - description: string; -} - -/** - * One type to rule them all, and in a union bind them. - * @gqlUnion - */ -type Actor = User | Entity; - ------------------ -OUTPUT ------------------ --- SDL -- -"""One type to rule them all, and in a union bind them.""" -union Actor = Entity | User - -type Entity { - description: String -} - -type SomeType { - me: Actor -} - -type User { - name: String -} --- TypeScript -- -import { GraphQLSchema, GraphQLUnionType, GraphQLObjectType, GraphQLString } from "graphql"; -export function getSchema(): GraphQLSchema { - const EntityType: GraphQLObjectType = new GraphQLObjectType({ - name: "Entity", - fields() { - return { - description: { - name: "description", - type: GraphQLString - } - }; - } - }); - const UserType: GraphQLObjectType = new GraphQLObjectType({ - name: "User", - fields() { - return { - name: { - name: "name", - type: GraphQLString - } - }; - } - }); - const ActorType: GraphQLUnionType = new GraphQLUnionType({ - name: "Actor", - description: "One type to rule them all, and in a union bind them.", - types() { - return [EntityType, UserType]; - } - }); - const SomeTypeType: GraphQLObjectType = new GraphQLObjectType({ - name: "SomeType", - fields() { - return { - me: { - name: "me", - type: ActorType - } - }; - } - }); - return new GraphQLSchema({ - types: [ActorType, EntityType, SomeTypeType, UserType] - }); -} diff --git a/src/tests/fixtures/unions/UnionWithDescription.ts.expected.md b/src/tests/fixtures/unions/UnionWithDescription.ts.expected.md new file mode 100644 index 00000000..46919bb5 --- /dev/null +++ b/src/tests/fixtures/unions/UnionWithDescription.ts.expected.md @@ -0,0 +1,101 @@ +## input + +```ts title="unions/UnionWithDescription.ts" +/** @gqlType */ +export default class SomeType { + /** @gqlField */ + me: Actor; +} + +/** @gqlType */ +class User { + __typename = "User" as const; + /** @gqlField */ + name: string; +} + +/** @gqlType */ +class Entity { + __typename = "Entity" as const; + /** @gqlField */ + description: string; +} + +/** + * One type to rule them all, and in a union bind them. + * @gqlUnion + */ +type Actor = User | Entity; +``` + +## Output + +### SDL + +```graphql +"""One type to rule them all, and in a union bind them.""" +union Actor = Entity | User + +type Entity { + description: String +} + +type SomeType { + me: Actor +} + +type User { + name: String +} +``` + +### TypeScript + +```ts +import { GraphQLSchema, GraphQLUnionType, GraphQLObjectType, GraphQLString } from "graphql"; +export function getSchema(): GraphQLSchema { + const EntityType: GraphQLObjectType = new GraphQLObjectType({ + name: "Entity", + fields() { + return { + description: { + name: "description", + type: GraphQLString + } + }; + } + }); + const UserType: GraphQLObjectType = new GraphQLObjectType({ + name: "User", + fields() { + return { + name: { + name: "name", + type: GraphQLString + } + }; + } + }); + const ActorType: GraphQLUnionType = new GraphQLUnionType({ + name: "Actor", + description: "One type to rule them all, and in a union bind them.", + types() { + return [EntityType, UserType]; + } + }); + const SomeTypeType: GraphQLObjectType = new GraphQLObjectType({ + name: "SomeType", + fields() { + return { + me: { + name: "me", + type: ActorType + } + }; + } + }); + return new GraphQLSchema({ + types: [ActorType, EntityType, SomeTypeType, UserType] + }); +} +``` \ No newline at end of file diff --git a/src/tests/fixtures/user_error/DuplicateOneOfTag.invalid.ts.expected b/src/tests/fixtures/user_error/DuplicateOneOfTag.invalid.ts.expected deleted file mode 100644 index a3becbef..00000000 --- a/src/tests/fixtures/user_error/DuplicateOneOfTag.invalid.ts.expected +++ /dev/null @@ -1,52 +0,0 @@ ------------------ -INPUT ------------------ -/** - * @gqlInput - * @oneOf - * @oneOf - */ -type Foo = { - a: string; -}; - ------------------ -OUTPUT ------------------ --- Error Report -- -src/tests/fixtures/user_error/DuplicateOneOfTag.invalid.ts:3:4 - error: Unexpected duplicate `@oneOf` tag. Grats does not accept multiple instances of the same tag. - -3 * @oneOf - ~~~~~~ -4 * @oneOf - ~~~ - - src/tests/fixtures/user_error/DuplicateOneOfTag.invalid.ts:4:4 - 4 * @oneOf - ~~~~~~ - 5 */ - ~ - Additional tag - --- Code Action: "Remove duplicate @oneOf tag" (remove-duplicate-tag) -- -- Original -+ Fixed - -@@ -3,4 +3,3 @@ - * @oneOf -- * @oneOf -- */ -+ * */ - type Foo = { - --- Applied Fixes -- - * Applied fix "Remove duplicate @oneOf tag" in grats/src/tests/fixtures/user_error/DuplicateOneOfTag.invalid.ts - --- Fixed Text -- -/** - * @gqlInput - * @oneOf - * */ -type Foo = { - a: string; -}; diff --git a/src/tests/fixtures/user_error/DuplicateOneOfTag.invalid.ts.expected.md b/src/tests/fixtures/user_error/DuplicateOneOfTag.invalid.ts.expected.md new file mode 100644 index 00000000..931fc258 --- /dev/null +++ b/src/tests/fixtures/user_error/DuplicateOneOfTag.invalid.ts.expected.md @@ -0,0 +1,64 @@ +## input + +```ts title="user_error/DuplicateOneOfTag.invalid.ts" +/** + * @gqlInput + * @oneOf + * @oneOf + */ +type Foo = { + a: string; +}; +``` + +## Output + +### Error Report + +```text +src/tests/fixtures/user_error/DuplicateOneOfTag.invalid.ts:3:4 - error: Unexpected duplicate `@oneOf` tag. Grats does not accept multiple instances of the same tag. + +3 * @oneOf + ~~~~~~ +4 * @oneOf + ~~~ + + src/tests/fixtures/user_error/DuplicateOneOfTag.invalid.ts:4:4 + 4 * @oneOf + ~~~~~~ + 5 */ + ~ + Additional tag +``` + +#### Code Action: "Remove duplicate @oneOf tag" (remove-duplicate-tag) + +```diff +- Original ++ Fixed + +@@ -3,4 +3,3 @@ + * @oneOf +- * @oneOf +- */ ++ * */ + type Foo = { +``` + +#### Applied Fixes + +```text + * Applied fix "Remove duplicate @oneOf tag" in grats/src/tests/fixtures/user_error/DuplicateOneOfTag.invalid.ts +``` + +#### Fixed Text + +```typescript +/** + * @gqlInput + * @oneOf + * */ +type Foo = { + a: string; +}; +``` \ No newline at end of file diff --git a/src/tests/fixtures/user_error/GqlTagDoesNotExist.invalid.ts.expected b/src/tests/fixtures/user_error/GqlTagDoesNotExist.invalid.ts.expected deleted file mode 100644 index de7a8f7b..00000000 --- a/src/tests/fixtures/user_error/GqlTagDoesNotExist.invalid.ts.expected +++ /dev/null @@ -1,28 +0,0 @@ ------------------ -INPUT ------------------ -/** @gqlFiled */ - ------------------ -OUTPUT ------------------ --- Error Report -- -src/tests/fixtures/user_error/GqlTagDoesNotExist.invalid.ts:1:6 - error: `@gqlFiled` is not a valid Grats tag. Valid tags are: `@gqlType`, `@gqlField`, `@gqlScalar`, `@gqlInterface`, `@gqlEnum`, `@gqlUnion`, `@gqlInput`, `@gqlDirective`, `@gqlAnnotate`, `@gqlQueryField`, `@gqlMutationField`, `@gqlSubscriptionField`. - -1 /** @gqlFiled */ - ~~~~~~~~ - - --- Code Action: "Change to @gqlField" (change-to-gqlField) -- -- Original -+ Fixed - -- /** @gqlFiled */ -+ /** @gqlField */ - - --- Applied Fixes -- - * Applied fix "Change to @gqlField" in grats/src/tests/fixtures/user_error/GqlTagDoesNotExist.invalid.ts - --- Fixed Text -- -/** @gqlField */ diff --git a/src/tests/fixtures/user_error/GqlTagDoesNotExist.invalid.ts.expected.md b/src/tests/fixtures/user_error/GqlTagDoesNotExist.invalid.ts.expected.md new file mode 100644 index 00000000..e10037f8 --- /dev/null +++ b/src/tests/fixtures/user_error/GqlTagDoesNotExist.invalid.ts.expected.md @@ -0,0 +1,38 @@ +## input + +```ts title="user_error/GqlTagDoesNotExist.invalid.ts" +/** @gqlFiled */ +``` + +## Output + +### Error Report + +```text +src/tests/fixtures/user_error/GqlTagDoesNotExist.invalid.ts:1:6 - error: `@gqlFiled` is not a valid Grats tag. Valid tags are: `@gqlType`, `@gqlField`, `@gqlScalar`, `@gqlInterface`, `@gqlEnum`, `@gqlUnion`, `@gqlInput`, `@gqlDirective`, `@gqlAnnotate`, `@gqlQueryField`, `@gqlMutationField`, `@gqlSubscriptionField`. + +1 /** @gqlFiled */ + ~~~~~~~~ +``` + +#### Code Action: "Change to @gqlField" (change-to-gqlField) + +```diff +- Original ++ Fixed + +- /** @gqlFiled */ ++ /** @gqlField */ +``` + +#### Applied Fixes + +```text + * Applied fix "Change to @gqlField" in grats/src/tests/fixtures/user_error/GqlTagDoesNotExist.invalid.ts +``` + +#### Fixed Text + +```typescript +/** @gqlField */ +``` \ No newline at end of file diff --git a/src/tests/fixtures/user_error/InvalidSyntax.invalid.ts.expected b/src/tests/fixtures/user_error/InvalidSyntax.invalid.ts.expected deleted file mode 100644 index 30ad6445..00000000 --- a/src/tests/fixtures/user_error/InvalidSyntax.invalid.ts.expected +++ /dev/null @@ -1,14 +0,0 @@ ------------------ -INPUT ------------------ -/** @gqlType */ -class #Foo { - -} ------------------ -OUTPUT ------------------ -src/tests/fixtures/user_error/InvalidSyntax.invalid.ts:2:7 - error TS1005: '{' expected. - -2 class #Foo { - ~~~~ diff --git a/src/tests/fixtures/user_error/InvalidSyntax.invalid.ts.expected.md b/src/tests/fixtures/user_error/InvalidSyntax.invalid.ts.expected.md new file mode 100644 index 00000000..769ca0e9 --- /dev/null +++ b/src/tests/fixtures/user_error/InvalidSyntax.invalid.ts.expected.md @@ -0,0 +1,19 @@ +## input + +```ts title="user_error/InvalidSyntax.invalid.ts" +/** @gqlType */ +class #Foo { + +} +``` + +## Output + +### Error Report + +```text +src/tests/fixtures/user_error/InvalidSyntax.invalid.ts:2:7 - error TS1005: '{' expected. + +2 class #Foo { + ~~~~ +``` \ No newline at end of file diff --git a/src/tests/fixtures/user_error/KillsParentOnExceptionOnNonField.invalid.ts.expected b/src/tests/fixtures/user_error/KillsParentOnExceptionOnNonField.invalid.ts.expected deleted file mode 100644 index 04db36cd..00000000 --- a/src/tests/fixtures/user_error/KillsParentOnExceptionOnNonField.invalid.ts.expected +++ /dev/null @@ -1,20 +0,0 @@ ------------------ -INPUT ------------------ -/** @killsParentOnException */ -const foo = "bar"; - -/** @gqlType */ -type Foo = { - /** @gqlField */ - bar: string; -}; - ------------------ -OUTPUT ------------------ -src/tests/fixtures/user_error/KillsParentOnExceptionOnNonField.invalid.ts:1:6 - error: Unexpected `@killsParentOnException`. `@killsParentOnException` can only be used in field annotation docblocks. Perhaps you are missing a `@gqlField` tag? - -1 /** @killsParentOnException */ - ~~~~~~~~~~~~~~~~~~~~~~ - diff --git a/src/tests/fixtures/user_error/KillsParentOnExceptionOnNonField.invalid.ts.expected.md b/src/tests/fixtures/user_error/KillsParentOnExceptionOnNonField.invalid.ts.expected.md new file mode 100644 index 00000000..3f64487c --- /dev/null +++ b/src/tests/fixtures/user_error/KillsParentOnExceptionOnNonField.invalid.ts.expected.md @@ -0,0 +1,23 @@ +## input + +```ts title="user_error/KillsParentOnExceptionOnNonField.invalid.ts" +/** @killsParentOnException */ +const foo = "bar"; + +/** @gqlType */ +type Foo = { + /** @gqlField */ + bar: string; +}; +``` + +## Output + +### Error Report + +```text +src/tests/fixtures/user_error/KillsParentOnExceptionOnNonField.invalid.ts:1:6 - error: Unexpected `@killsParentOnException`. `@killsParentOnException` can only be used in field annotation docblocks. Perhaps you are missing a `@gqlField` tag? + +1 /** @killsParentOnException */ + ~~~~~~~~~~~~~~~~~~~~~~ +``` \ No newline at end of file diff --git a/src/tests/fixtures/user_error/TypeErrorWithTypeCheckingEnabled.ts.expected b/src/tests/fixtures/user_error/TypeErrorWithTypeCheckingEnabled.ts.expected deleted file mode 100644 index f4edcfd8..00000000 --- a/src/tests/fixtures/user_error/TypeErrorWithTypeCheckingEnabled.ts.expected +++ /dev/null @@ -1,19 +0,0 @@ ------------------ -INPUT ------------------ -// { "reportTypeScriptTypeErrors": true, "tsVersion": "5.0.2" } -/** @gqlType */ -class Foo { - /** @gqlField */ - someField(): string { - return 10; - } -} - ------------------ -OUTPUT ------------------ -src/tests/fixtures/user_error/TypeErrorWithTypeCheckingEnabled.ts:6:5 - error TS2322: Type 'number' is not assignable to type 'string'. - -6 return 10; - ~~~~~~~~~~ diff --git a/src/tests/fixtures/user_error/TypeErrorWithTypeCheckingEnabled.ts.expected.md b/src/tests/fixtures/user_error/TypeErrorWithTypeCheckingEnabled.ts.expected.md new file mode 100644 index 00000000..e69de29b diff --git a/src/tests/fixtures/user_error/WrongCaseGqlTag.invalid.ts.expected b/src/tests/fixtures/user_error/WrongCaseGqlTag.invalid.ts.expected deleted file mode 100644 index d323015f..00000000 --- a/src/tests/fixtures/user_error/WrongCaseGqlTag.invalid.ts.expected +++ /dev/null @@ -1,31 +0,0 @@ ------------------ -INPUT ------------------ -/** @GQLField */ -function field() {} - ------------------ -OUTPUT ------------------ --- Error Report -- -src/tests/fixtures/user_error/WrongCaseGqlTag.invalid.ts:1:6 - error: Incorrect casing for Grats tag `@GQLField`. Use `@gqlField` instead. - -1 /** @GQLField */ - ~~~~~~~~ - - --- Code Action: "Change to @gqlField" (fix-grats-tag-casing) -- -- Original -+ Fixed - -@@ -1,2 +1,2 @@ -- /** @GQLField */ -+ /** @gqlField */ - function field() {} - --- Applied Fixes -- - * Applied fix "Change to @gqlField" in grats/src/tests/fixtures/user_error/WrongCaseGqlTag.invalid.ts - --- Fixed Text -- -/** @gqlField */ -function field() {} diff --git a/src/tests/fixtures/user_error/WrongCaseGqlTag.invalid.ts.expected.md b/src/tests/fixtures/user_error/WrongCaseGqlTag.invalid.ts.expected.md new file mode 100644 index 00000000..d21a2a54 --- /dev/null +++ b/src/tests/fixtures/user_error/WrongCaseGqlTag.invalid.ts.expected.md @@ -0,0 +1,42 @@ +## input + +```ts title="user_error/WrongCaseGqlTag.invalid.ts" +/** @GQLField */ +function field() {} +``` + +## Output + +### Error Report + +```text +src/tests/fixtures/user_error/WrongCaseGqlTag.invalid.ts:1:6 - error: Incorrect casing for Grats tag `@GQLField`. Use `@gqlField` instead. + +1 /** @GQLField */ + ~~~~~~~~ +``` + +#### Code Action: "Change to @gqlField" (fix-grats-tag-casing) + +```diff +- Original ++ Fixed + +@@ -1,2 +1,2 @@ +- /** @GQLField */ ++ /** @gqlField */ + function field() {} +``` + +#### Applied Fixes + +```text + * Applied fix "Change to @gqlField" in grats/src/tests/fixtures/user_error/WrongCaseGqlTag.invalid.ts +``` + +#### Fixed Text + +```typescript +/** @gqlField */ +function field() {} +``` \ No newline at end of file diff --git a/src/tests/integrationFixtures/aliasedMethod/index.ts.expected b/src/tests/integrationFixtures/aliasedMethod/index.ts.expected deleted file mode 100644 index 71fa9dec..00000000 --- a/src/tests/integrationFixtures/aliasedMethod/index.ts.expected +++ /dev/null @@ -1,40 +0,0 @@ ------------------ -INPUT ------------------ -/** @gqlContext */ -type GraphqlContext = {}; - -/** @gqlQueryField */ -export function someType(): SomeType { - return new SomeType(); -} - -/** @gqlType */ -class SomeType { - /** @gqlField someName */ - async someOtherName( - args: { greeting: string }, - ctx: GraphqlContext, - ): Promise { - return `${args.greeting} World!`; - } -} - -export const query = /* GraphQL */ ` - query { - someType { - someName(greeting: "Hello") - } - } -`; - ------------------ -OUTPUT ------------------ -{ - "data": { - "someType": { - "someName": "Hello World!" - } - } -} \ No newline at end of file diff --git a/src/tests/integrationFixtures/aliasedMethod/index.ts.expected.md b/src/tests/integrationFixtures/aliasedMethod/index.ts.expected.md new file mode 100644 index 00000000..4f2eba6f --- /dev/null +++ b/src/tests/integrationFixtures/aliasedMethod/index.ts.expected.md @@ -0,0 +1,44 @@ +## input + +```ts title="aliasedMethod/index.ts" +/** @gqlContext */ +type GraphqlContext = {}; + +/** @gqlQueryField */ +export function someType(): SomeType { + return new SomeType(); +} + +/** @gqlType */ +class SomeType { + /** @gqlField someName */ + async someOtherName( + args: { greeting: string }, + ctx: GraphqlContext, + ): Promise { + return `${args.greeting} World!`; + } +} + +export const query = /* GraphQL */ ` + query { + someType { + someName(greeting: "Hello") + } + } +`; +``` + +## Output + +### Query Result + +```json +{ + "data": { + "someType": { + "someName": "Hello World!" + } + } +} +``` \ No newline at end of file diff --git a/src/tests/integrationFixtures/complexDefaultInput/index.ts.expected b/src/tests/integrationFixtures/complexDefaultInput/index.ts.expected deleted file mode 100644 index e8268411..00000000 --- a/src/tests/integrationFixtures/complexDefaultInput/index.ts.expected +++ /dev/null @@ -1,35 +0,0 @@ ------------------ -INPUT ------------------ -/** - * @gqlInput - */ -type SomeObj = { - a: string; -}; - -/** - * @gqlQueryField - */ -export function hello({ - someObj = { a: "Sup" }, -}: { - someObj: SomeObj; -}): string { - return someObj.a; -} - -export const query = ` - query { - hello - } - `; - ------------------ -OUTPUT ------------------ -{ - "data": { - "hello": "Sup" - } -} \ No newline at end of file diff --git a/src/tests/integrationFixtures/complexDefaultInput/index.ts.expected.md b/src/tests/integrationFixtures/complexDefaultInput/index.ts.expected.md new file mode 100644 index 00000000..c2b64fb5 --- /dev/null +++ b/src/tests/integrationFixtures/complexDefaultInput/index.ts.expected.md @@ -0,0 +1,39 @@ +## input + +```ts title="complexDefaultInput/index.ts" +/** + * @gqlInput + */ +type SomeObj = { + a: string; +}; + +/** + * @gqlQueryField + */ +export function hello({ + someObj = { a: "Sup" }, +}: { + someObj: SomeObj; +}): string { + return someObj.a; +} + +export const query = ` + query { + hello + } + `; +``` + +## Output + +### Query Result + +```json +{ + "data": { + "hello": "Sup" + } +} +``` \ No newline at end of file diff --git a/src/tests/integrationFixtures/complexPlurals/index.ts.expected b/src/tests/integrationFixtures/complexPlurals/index.ts.expected deleted file mode 100644 index 7623c053..00000000 --- a/src/tests/integrationFixtures/complexPlurals/index.ts.expected +++ /dev/null @@ -1,76 +0,0 @@ ------------------ -INPUT ------------------ -/** @gqlQueryField */ -export function arrayOfPromises(): Promise[] { - return [ - Promise.resolve("Hello"), - Promise.resolve("World"), - Promise.resolve("!"), - ]; -} - -/** @gqlQueryField */ -export function arrayOfArrayOfPromises(): Promise[][] { - return [ - [Promise.resolve("Hello"), Promise.resolve("World"), Promise.resolve("!")], - [ - Promise.resolve("Hello"), - Promise.resolve("World"), - Promise.resolve("again"), - Promise.resolve("!"), - ], - ]; -} - -/** @gqlQueryField */ -export async function* asyncIterableOfArrayOfPromises(): AsyncIterable< - Promise[] -> { - yield [ - Promise.resolve("Hello"), - Promise.resolve("World"), - Promise.resolve("!"), - ]; - yield [ - Promise.resolve("Hello"), - Promise.resolve("World"), - Promise.resolve("again"), - Promise.resolve("!"), - ]; -} - -export const query = ` - query { - arrayOfPromises - arrayOfArrayOfPromises - # TODO: Should this work? - # asyncIterableOfArrayOfPromises - } - `; - ------------------ -OUTPUT ------------------ -{ - "data": { - "arrayOfPromises": [ - "Hello", - "World", - "!" - ], - "arrayOfArrayOfPromises": [ - [ - "Hello", - "World", - "!" - ], - [ - "Hello", - "World", - "again", - "!" - ] - ] - } -} \ No newline at end of file diff --git a/src/tests/integrationFixtures/complexPlurals/index.ts.expected.md b/src/tests/integrationFixtures/complexPlurals/index.ts.expected.md new file mode 100644 index 00000000..78f9425f --- /dev/null +++ b/src/tests/integrationFixtures/complexPlurals/index.ts.expected.md @@ -0,0 +1,80 @@ +## input + +```ts title="complexPlurals/index.ts" +/** @gqlQueryField */ +export function arrayOfPromises(): Promise[] { + return [ + Promise.resolve("Hello"), + Promise.resolve("World"), + Promise.resolve("!"), + ]; +} + +/** @gqlQueryField */ +export function arrayOfArrayOfPromises(): Promise[][] { + return [ + [Promise.resolve("Hello"), Promise.resolve("World"), Promise.resolve("!")], + [ + Promise.resolve("Hello"), + Promise.resolve("World"), + Promise.resolve("again"), + Promise.resolve("!"), + ], + ]; +} + +/** @gqlQueryField */ +export async function* asyncIterableOfArrayOfPromises(): AsyncIterable< + Promise[] +> { + yield [ + Promise.resolve("Hello"), + Promise.resolve("World"), + Promise.resolve("!"), + ]; + yield [ + Promise.resolve("Hello"), + Promise.resolve("World"), + Promise.resolve("again"), + Promise.resolve("!"), + ]; +} + +export const query = ` + query { + arrayOfPromises + arrayOfArrayOfPromises + # TODO: Should this work? + # asyncIterableOfArrayOfPromises + } + `; +``` + +## Output + +### Query Result + +```json +{ + "data": { + "arrayOfPromises": [ + "Hello", + "World", + "!" + ], + "arrayOfArrayOfPromises": [ + [ + "Hello", + "World", + "!" + ], + [ + "Hello", + "World", + "again", + "!" + ] + ] + } +} +``` \ No newline at end of file diff --git a/src/tests/integrationFixtures/connectionExample/index.ts.expected b/src/tests/integrationFixtures/connectionExample/index.ts.expected deleted file mode 100644 index 4dd67370..00000000 --- a/src/tests/integrationFixtures/connectionExample/index.ts.expected +++ /dev/null @@ -1,218 +0,0 @@ ------------------ -INPUT ------------------ -import { Int } from "../../../Types"; - -/** @gqlQueryField */ -export function firstHundredIntegers(args: { - first?: Int | null; - after?: string | null; -}): FirstHundredIntegersConnection { - return new FirstHundredIntegersConnection(args.first, args.after); -} - -type Connection = { - pageInfo: PageInfo; - edges: Edge[]; -}; - -type PageInfo = { - hasNext: boolean; - hasPrevious: boolean; - startCursor: string; - endCursor: string; -}; - -type Edge = { - cursor: string; - node: T; -}; - -/** @gqlType */ -class FirstHundredIntegersConnection { - _max: number = 100; - - /** @gqlField */ - pageInfo: FirstHundredIntegersPageInfo; - - /** @gqlField */ - edges: FirstHundredIntegersEdge[]; - - constructor( - public first?: number | null, - public after?: string | null, - ) { - const start = parseInt(after || "0", 10); - const end = first ? start + first : this._max; - - this.edges = []; - for (let i = start; i < end; i++) { - this.edges.push(new FirstHundredIntegersEdge(i)); - } - - // TODO: What about empty connections - this.pageInfo = new FirstHundredIntegersPageInfo({ - hasNext: end < this._max, - hasPrevious: start > 0, - startCursor: this.edges[0].cursor, - endCursor: this.edges[this.edges.length - 1].cursor, - }); - } -} - -/** @gqlType */ -class FirstHundredIntegersPageInfo { - constructor({ - hasNext, - hasPrevious, - startCursor, - endCursor, - }: { - hasNext: boolean; - hasPrevious: boolean; - startCursor: string; - endCursor: string; - }) { - this.hasNextPage = hasNext; - this.hasPreviousPage = hasPrevious; - this.startCursor = startCursor; - this.endCursor = endCursor; - } - /** - * @gqlField - * @killsParentOnException - */ - hasNextPage: boolean; - /** - * @gqlField - * @killsParentOnException - */ - hasPreviousPage: boolean; - - /** @gqlField */ - startCursor: string; - - /** @gqlField */ - endCursor: string; -} - -/** @gqlType */ -class FirstHundredIntegersEdge { - constructor(node: number) { - this.node = node; - this.cursor = node.toString(); - } - - /** @gqlField */ - node: Int; - - /** @gqlField */ - cursor: string; -} - -function gql(strings: TemplateStringsArray) { - return strings[0]; -} - -export const query = gql` - query { - firstTwo: firstHundredIntegers(first: 2) { - pageInfo { - hasNextPage - hasPreviousPage - startCursor - endCursor - } - edges { - cursor - node - } - } - secondTwo: firstHundredIntegers(first: 2, after: "2") { - pageInfo { - hasNextPage - hasPreviousPage - startCursor - endCursor - } - edges { - cursor - node - } - } - lastTwo: firstHundredIntegers(first: 2, after: "98") { - pageInfo { - hasNextPage - hasPreviousPage - startCursor - endCursor - } - edges { - cursor - node - } - } - } -`; - ------------------ -OUTPUT ------------------ -{ - "data": { - "firstTwo": { - "pageInfo": { - "hasNextPage": true, - "hasPreviousPage": false, - "startCursor": "0", - "endCursor": "1" - }, - "edges": [ - { - "cursor": "0", - "node": 0 - }, - { - "cursor": "1", - "node": 1 - } - ] - }, - "secondTwo": { - "pageInfo": { - "hasNextPage": true, - "hasPreviousPage": true, - "startCursor": "2", - "endCursor": "3" - }, - "edges": [ - { - "cursor": "2", - "node": 2 - }, - { - "cursor": "3", - "node": 3 - } - ] - }, - "lastTwo": { - "pageInfo": { - "hasNextPage": false, - "hasPreviousPage": true, - "startCursor": "98", - "endCursor": "99" - }, - "edges": [ - { - "cursor": "98", - "node": 98 - }, - { - "cursor": "99", - "node": 99 - } - ] - } - } -} \ No newline at end of file diff --git a/src/tests/integrationFixtures/connectionExample/index.ts.expected.md b/src/tests/integrationFixtures/connectionExample/index.ts.expected.md new file mode 100644 index 00000000..f627bd72 --- /dev/null +++ b/src/tests/integrationFixtures/connectionExample/index.ts.expected.md @@ -0,0 +1,222 @@ +## input + +```ts title="connectionExample/index.ts" +import { Int } from "../../../Types"; + +/** @gqlQueryField */ +export function firstHundredIntegers(args: { + first?: Int | null; + after?: string | null; +}): FirstHundredIntegersConnection { + return new FirstHundredIntegersConnection(args.first, args.after); +} + +type Connection = { + pageInfo: PageInfo; + edges: Edge[]; +}; + +type PageInfo = { + hasNext: boolean; + hasPrevious: boolean; + startCursor: string; + endCursor: string; +}; + +type Edge = { + cursor: string; + node: T; +}; + +/** @gqlType */ +class FirstHundredIntegersConnection { + _max: number = 100; + + /** @gqlField */ + pageInfo: FirstHundredIntegersPageInfo; + + /** @gqlField */ + edges: FirstHundredIntegersEdge[]; + + constructor( + public first?: number | null, + public after?: string | null, + ) { + const start = parseInt(after || "0", 10); + const end = first ? start + first : this._max; + + this.edges = []; + for (let i = start; i < end; i++) { + this.edges.push(new FirstHundredIntegersEdge(i)); + } + + // TODO: What about empty connections + this.pageInfo = new FirstHundredIntegersPageInfo({ + hasNext: end < this._max, + hasPrevious: start > 0, + startCursor: this.edges[0].cursor, + endCursor: this.edges[this.edges.length - 1].cursor, + }); + } +} + +/** @gqlType */ +class FirstHundredIntegersPageInfo { + constructor({ + hasNext, + hasPrevious, + startCursor, + endCursor, + }: { + hasNext: boolean; + hasPrevious: boolean; + startCursor: string; + endCursor: string; + }) { + this.hasNextPage = hasNext; + this.hasPreviousPage = hasPrevious; + this.startCursor = startCursor; + this.endCursor = endCursor; + } + /** + * @gqlField + * @killsParentOnException + */ + hasNextPage: boolean; + /** + * @gqlField + * @killsParentOnException + */ + hasPreviousPage: boolean; + + /** @gqlField */ + startCursor: string; + + /** @gqlField */ + endCursor: string; +} + +/** @gqlType */ +class FirstHundredIntegersEdge { + constructor(node: number) { + this.node = node; + this.cursor = node.toString(); + } + + /** @gqlField */ + node: Int; + + /** @gqlField */ + cursor: string; +} + +function gql(strings: TemplateStringsArray) { + return strings[0]; +} + +export const query = gql` + query { + firstTwo: firstHundredIntegers(first: 2) { + pageInfo { + hasNextPage + hasPreviousPage + startCursor + endCursor + } + edges { + cursor + node + } + } + secondTwo: firstHundredIntegers(first: 2, after: "2") { + pageInfo { + hasNextPage + hasPreviousPage + startCursor + endCursor + } + edges { + cursor + node + } + } + lastTwo: firstHundredIntegers(first: 2, after: "98") { + pageInfo { + hasNextPage + hasPreviousPage + startCursor + endCursor + } + edges { + cursor + node + } + } + } +`; +``` + +## Output + +### Query Result + +```json +{ + "data": { + "firstTwo": { + "pageInfo": { + "hasNextPage": true, + "hasPreviousPage": false, + "startCursor": "0", + "endCursor": "1" + }, + "edges": [ + { + "cursor": "0", + "node": 0 + }, + { + "cursor": "1", + "node": 1 + } + ] + }, + "secondTwo": { + "pageInfo": { + "hasNextPage": true, + "hasPreviousPage": true, + "startCursor": "2", + "endCursor": "3" + }, + "edges": [ + { + "cursor": "2", + "node": 2 + }, + { + "cursor": "3", + "node": 3 + } + ] + }, + "lastTwo": { + "pageInfo": { + "hasNextPage": false, + "hasPreviousPage": true, + "startCursor": "98", + "endCursor": "99" + }, + "edges": [ + { + "cursor": "98", + "node": 98 + }, + { + "cursor": "99", + "node": 99 + } + ] + } + } +} +``` \ No newline at end of file diff --git a/src/tests/integrationFixtures/customScalarSerialization/index.ts.expected b/src/tests/integrationFixtures/customScalarSerialization/index.ts.expected deleted file mode 100644 index 05208552..00000000 --- a/src/tests/integrationFixtures/customScalarSerialization/index.ts.expected +++ /dev/null @@ -1,70 +0,0 @@ ------------------ -INPUT ------------------ -import type { SchemaConfig } from "./schema"; - -/** @gqlScalar */ -export type CustomScalar = number; - -/** @gqlQueryField */ -export function hello(custom: CustomScalar): CustomScalar { - if (typeof custom !== "number") { - throw new Error( - `Expected custom to be a number, but it was ${typeof custom}`, - ); - } - return Number(custom); -} - -export const schemaConfig: SchemaConfig = { - scalars: { - CustomScalar: { - serialize(outputValue) { - if (typeof outputValue !== "number") { - throw new Error( - `Expected outputValue to be a number, but it was ${typeof outputValue}`, - ); - } - // value comes from the server, so it's already in the internal format - return outputValue.toString(); - }, - parseValue(value) { - // value comes from the client, so we need to convert it to the internal format - return Number(value); - }, - parseLiteral(ast) { - if (ast.kind === "StringValue") { - return Number(ast.value); - } - throw new Error( - "Query error: Can only parse strings to numbers but got a: " + - ast.kind, - ); - }, - }, - }, -}; - -export const query = /* GraphQL */ ` - query ($someVar: CustomScalar!, $someOtherVar: CustomScalar!) { - hello(custom: $someVar) - helloAsWell: hello(custom: $someOtherVar) - alsoHello: hello(custom: "5") - } -`; - -export const variables = { - someVar: 123, - someOtherVar: "456", -}; - ------------------ -OUTPUT ------------------ -{ - "data": { - "hello": "123", - "helloAsWell": "456", - "alsoHello": "5" - } -} \ No newline at end of file diff --git a/src/tests/integrationFixtures/customScalarSerialization/index.ts.expected.md b/src/tests/integrationFixtures/customScalarSerialization/index.ts.expected.md new file mode 100644 index 00000000..42eb571e --- /dev/null +++ b/src/tests/integrationFixtures/customScalarSerialization/index.ts.expected.md @@ -0,0 +1,74 @@ +## input + +```ts title="customScalarSerialization/index.ts" +import type { SchemaConfig } from "./schema"; + +/** @gqlScalar */ +export type CustomScalar = number; + +/** @gqlQueryField */ +export function hello(custom: CustomScalar): CustomScalar { + if (typeof custom !== "number") { + throw new Error( + `Expected custom to be a number, but it was ${typeof custom}`, + ); + } + return Number(custom); +} + +export const schemaConfig: SchemaConfig = { + scalars: { + CustomScalar: { + serialize(outputValue) { + if (typeof outputValue !== "number") { + throw new Error( + `Expected outputValue to be a number, but it was ${typeof outputValue}`, + ); + } + // value comes from the server, so it's already in the internal format + return outputValue.toString(); + }, + parseValue(value) { + // value comes from the client, so we need to convert it to the internal format + return Number(value); + }, + parseLiteral(ast) { + if (ast.kind === "StringValue") { + return Number(ast.value); + } + throw new Error( + "Query error: Can only parse strings to numbers but got a: " + + ast.kind, + ); + }, + }, + }, +}; + +export const query = /* GraphQL */ ` + query ($someVar: CustomScalar!, $someOtherVar: CustomScalar!) { + hello(custom: $someVar) + helloAsWell: hello(custom: $someOtherVar) + alsoHello: hello(custom: "5") + } +`; + +export const variables = { + someVar: 123, + someOtherVar: "456", +}; +``` + +## Output + +### Query Result + +```json +{ + "data": { + "hello": "123", + "helloAsWell": "456", + "alsoHello": "5" + } +} +``` \ No newline at end of file diff --git a/src/tests/integrationFixtures/deprecated/index.ts.expected b/src/tests/integrationFixtures/deprecated/index.ts.expected deleted file mode 100644 index a58d2b4e..00000000 --- a/src/tests/integrationFixtures/deprecated/index.ts.expected +++ /dev/null @@ -1,33 +0,0 @@ ------------------ -INPUT ------------------ -/** - * @gqlQueryField - * @deprecated For reasons - */ -export function hello(): string { - return "Hello World"; -} - -/** - * @gqlQueryField - * @deprecated - */ -export function goodBye(): string { - return "Farewell World"; -} - -export const query = ` - query { - hello - } - `; - ------------------ -OUTPUT ------------------ -{ - "data": { - "hello": "Hello World" - } -} \ No newline at end of file diff --git a/src/tests/integrationFixtures/deprecated/index.ts.expected.md b/src/tests/integrationFixtures/deprecated/index.ts.expected.md new file mode 100644 index 00000000..a53d4b4f --- /dev/null +++ b/src/tests/integrationFixtures/deprecated/index.ts.expected.md @@ -0,0 +1,37 @@ +## input + +```ts title="deprecated/index.ts" +/** + * @gqlQueryField + * @deprecated For reasons + */ +export function hello(): string { + return "Hello World"; +} + +/** + * @gqlQueryField + * @deprecated + */ +export function goodBye(): string { + return "Farewell World"; +} + +export const query = ` + query { + hello + } + `; +``` + +## Output + +### Query Result + +```json +{ + "data": { + "hello": "Hello World" + } +} +``` \ No newline at end of file diff --git a/src/tests/integrationFixtures/derivedContext/index.ts.expected b/src/tests/integrationFixtures/derivedContext/index.ts.expected deleted file mode 100644 index d12f3887..00000000 --- a/src/tests/integrationFixtures/derivedContext/index.ts.expected +++ /dev/null @@ -1,32 +0,0 @@ ------------------ -INPUT ------------------ -/** @gqlContext */ -type Ctx = {}; - -type SomeCtx = { name: string }; - -/** @gqlContext */ -export function derived(): SomeCtx { - return { name: "Roger" }; -} - -/** @gqlQueryField */ -export function hello(someCtx: SomeCtx): string { - return `Hello ${someCtx.name}`; -} - -export const query = ` - query { - hello - } - `; - ------------------ -OUTPUT ------------------ -{ - "data": { - "hello": "Hello Roger" - } -} \ No newline at end of file diff --git a/src/tests/integrationFixtures/derivedContext/index.ts.expected.md b/src/tests/integrationFixtures/derivedContext/index.ts.expected.md new file mode 100644 index 00000000..faa1731b --- /dev/null +++ b/src/tests/integrationFixtures/derivedContext/index.ts.expected.md @@ -0,0 +1,36 @@ +## input + +```ts title="derivedContext/index.ts" +/** @gqlContext */ +type Ctx = {}; + +type SomeCtx = { name: string }; + +/** @gqlContext */ +export function derived(): SomeCtx { + return { name: "Roger" }; +} + +/** @gqlQueryField */ +export function hello(someCtx: SomeCtx): string { + return `Hello ${someCtx.name}`; +} + +export const query = ` + query { + hello + } + `; +``` + +## Output + +### Query Result + +```json +{ + "data": { + "hello": "Hello Roger" + } +} +``` \ No newline at end of file diff --git a/src/tests/integrationFixtures/enumDefault/index.ts.expected b/src/tests/integrationFixtures/enumDefault/index.ts.expected deleted file mode 100644 index 50295e7e..00000000 --- a/src/tests/integrationFixtures/enumDefault/index.ts.expected +++ /dev/null @@ -1,27 +0,0 @@ ------------------ -INPUT ------------------ -// https://github.com/captbaritone/grats/issues/172#issuecomment-2685496600 - -/** @gqlEnum */ -type GreetingOptions = "Hello" | "Greetings" | "Sup"; - -/** @gqlQueryField */ -export function hello(greeting: GreetingOptions | null = "Greetings"): string { - return `${greeting} World`; -} - -export const query = /* GraphQL */ ` - query { - hello - } -`; - ------------------ -OUTPUT ------------------ -{ - "data": { - "hello": "Greetings World" - } -} \ No newline at end of file diff --git a/src/tests/integrationFixtures/enumDefault/index.ts.expected.md b/src/tests/integrationFixtures/enumDefault/index.ts.expected.md new file mode 100644 index 00000000..bbb818bc --- /dev/null +++ b/src/tests/integrationFixtures/enumDefault/index.ts.expected.md @@ -0,0 +1,31 @@ +## input + +```ts title="enumDefault/index.ts" +// https://github.com/captbaritone/grats/issues/172#issuecomment-2685496600 + +/** @gqlEnum */ +type GreetingOptions = "Hello" | "Greetings" | "Sup"; + +/** @gqlQueryField */ +export function hello(greeting: GreetingOptions | null = "Greetings"): string { + return `${greeting} World`; +} + +export const query = /* GraphQL */ ` + query { + hello + } +`; +``` + +## Output + +### Query Result + +```json +{ + "data": { + "hello": "Greetings World" + } +} +``` \ No newline at end of file diff --git a/src/tests/integrationFixtures/enumExport/index.ts.expected b/src/tests/integrationFixtures/enumExport/index.ts.expected deleted file mode 100644 index 825e0144..00000000 --- a/src/tests/integrationFixtures/enumExport/index.ts.expected +++ /dev/null @@ -1,61 +0,0 @@ ------------------ -INPUT ------------------ -// {"tsClientEnums": "enums.ts"} - -/** @gqlEnum */ -export enum Color { - RED = "red", - GREEN = "green", - BLUE = "blue", -} - -/** @gqlEnum */ -export enum Priority { - LOW = "low", - MEDIUM = "medium", - HIGH = "high", -} - -/** @gqlQueryField */ -export function favoriteColor(): Color { - return Color.RED; -} - -/** @gqlQueryField */ -export function currentPriority(): Priority { - return Priority.MEDIUM; -} - -/** @gqlQueryField */ -export function colorName(color: Color): string { - switch (color) { - case Color.RED: - return "Red"; - case Color.GREEN: - return "Green"; - case Color.BLUE: - return "Blue"; - default: - return "Unknown"; - } -} - -export const query = /* GraphQL */ ` - query { - favoriteColor - currentPriority - colorName(color: red) - } -`; - ------------------ -OUTPUT ------------------ -{ - "data": { - "favoriteColor": "red", - "currentPriority": "medium", - "colorName": "Red" - } -} \ No newline at end of file diff --git a/src/tests/integrationFixtures/enumExport/index.ts.expected.md b/src/tests/integrationFixtures/enumExport/index.ts.expected.md new file mode 100644 index 00000000..1a35798f --- /dev/null +++ b/src/tests/integrationFixtures/enumExport/index.ts.expected.md @@ -0,0 +1,65 @@ +## input + +```ts title="enumExport/index.ts" +// {"tsClientEnums": "enums.ts"} + +/** @gqlEnum */ +export enum Color { + RED = "red", + GREEN = "green", + BLUE = "blue", +} + +/** @gqlEnum */ +export enum Priority { + LOW = "low", + MEDIUM = "medium", + HIGH = "high", +} + +/** @gqlQueryField */ +export function favoriteColor(): Color { + return Color.RED; +} + +/** @gqlQueryField */ +export function currentPriority(): Priority { + return Priority.MEDIUM; +} + +/** @gqlQueryField */ +export function colorName(color: Color): string { + switch (color) { + case Color.RED: + return "Red"; + case Color.GREEN: + return "Green"; + case Color.BLUE: + return "Blue"; + default: + return "Unknown"; + } +} + +export const query = /* GraphQL */ ` + query { + favoriteColor + currentPriority + colorName(color: red) + } +`; +``` + +## Output + +### Query Result + +```json +{ + "data": { + "favoriteColor": "red", + "currentPriority": "medium", + "colorName": "Red" + } +} +``` \ No newline at end of file diff --git a/src/tests/integrationFixtures/explicitNullPassedToArgWithDefault/index.ts.expected b/src/tests/integrationFixtures/explicitNullPassedToArgWithDefault/index.ts.expected deleted file mode 100644 index d602372f..00000000 --- a/src/tests/integrationFixtures/explicitNullPassedToArgWithDefault/index.ts.expected +++ /dev/null @@ -1,38 +0,0 @@ ------------------ -INPUT ------------------ -/** - * Validating what graphql-js does when an explicit null is passed to an argument - * with a default value. - * - * Spoiler alert: it passes the explicit null. - */ - -/** - * @gqlQueryField - */ -export function hello({ - someArg = "Hello", -}: { - someArg?: string | null; -}): string { - if (someArg === null) { - return "got null"; - } - return `${someArg} World`; -} - -export const query = ` - query { - hello(someArg: null) - } - `; - ------------------ -OUTPUT ------------------ -{ - "data": { - "hello": "got null" - } -} \ No newline at end of file diff --git a/src/tests/integrationFixtures/explicitNullPassedToArgWithDefault/index.ts.expected.md b/src/tests/integrationFixtures/explicitNullPassedToArgWithDefault/index.ts.expected.md new file mode 100644 index 00000000..732962a1 --- /dev/null +++ b/src/tests/integrationFixtures/explicitNullPassedToArgWithDefault/index.ts.expected.md @@ -0,0 +1,42 @@ +## input + +```ts title="explicitNullPassedToArgWithDefault/index.ts" +/** + * Validating what graphql-js does when an explicit null is passed to an argument + * with a default value. + * + * Spoiler alert: it passes the explicit null. + */ + +/** + * @gqlQueryField + */ +export function hello({ + someArg = "Hello", +}: { + someArg?: string | null; +}): string { + if (someArg === null) { + return "got null"; + } + return `${someArg} World`; +} + +export const query = ` + query { + hello(someArg: null) + } + `; +``` + +## Output + +### Query Result + +```json +{ + "data": { + "hello": "got null" + } +} +``` \ No newline at end of file diff --git a/src/tests/integrationFixtures/functionField/index.ts.expected b/src/tests/integrationFixtures/functionField/index.ts.expected deleted file mode 100644 index 1d73186b..00000000 --- a/src/tests/integrationFixtures/functionField/index.ts.expected +++ /dev/null @@ -1,22 +0,0 @@ ------------------ -INPUT ------------------ -/** @gqlQueryField */ -export function hello(): string { - return "Hello World"; -} - -export const query = ` - query { - hello - } - `; - ------------------ -OUTPUT ------------------ -{ - "data": { - "hello": "Hello World" - } -} \ No newline at end of file diff --git a/src/tests/integrationFixtures/functionField/index.ts.expected.md b/src/tests/integrationFixtures/functionField/index.ts.expected.md new file mode 100644 index 00000000..9f44fac5 --- /dev/null +++ b/src/tests/integrationFixtures/functionField/index.ts.expected.md @@ -0,0 +1,26 @@ +## input + +```ts title="functionField/index.ts" +/** @gqlQueryField */ +export function hello(): string { + return "Hello World"; +} + +export const query = ` + query { + hello + } + `; +``` + +## Output + +### Query Result + +```json +{ + "data": { + "hello": "Hello World" + } +} +``` \ No newline at end of file diff --git a/src/tests/integrationFixtures/functionFieldRenamed/index.ts.expected b/src/tests/integrationFixtures/functionFieldRenamed/index.ts.expected deleted file mode 100644 index 12bad7fc..00000000 --- a/src/tests/integrationFixtures/functionFieldRenamed/index.ts.expected +++ /dev/null @@ -1,22 +0,0 @@ ------------------ -INPUT ------------------ -/** @gqlQueryField hello */ -export function notHello(): string { - return "Hello World"; -} - -export const query = ` - query { - hello - } - `; - ------------------ -OUTPUT ------------------ -{ - "data": { - "hello": "Hello World" - } -} \ No newline at end of file diff --git a/src/tests/integrationFixtures/functionFieldRenamed/index.ts.expected.md b/src/tests/integrationFixtures/functionFieldRenamed/index.ts.expected.md new file mode 100644 index 00000000..26f438bb --- /dev/null +++ b/src/tests/integrationFixtures/functionFieldRenamed/index.ts.expected.md @@ -0,0 +1,26 @@ +## input + +```ts title="functionFieldRenamed/index.ts" +/** @gqlQueryField hello */ +export function notHello(): string { + return "Hello World"; +} + +export const query = ` + query { + hello + } + `; +``` + +## Output + +### Query Result + +```json +{ + "data": { + "hello": "Hello World" + } +} +``` \ No newline at end of file diff --git a/src/tests/integrationFixtures/getAcessor/index.ts.expected b/src/tests/integrationFixtures/getAcessor/index.ts.expected deleted file mode 100644 index 12c242e2..00000000 --- a/src/tests/integrationFixtures/getAcessor/index.ts.expected +++ /dev/null @@ -1,33 +0,0 @@ ------------------ -INPUT ------------------ -/** @gqlQueryField */ -export function me(): User { - return new User(); -} - -/** @gqlType */ -class User { - /** @gqlField */ - get hello(): string { - return "Hello world!"; - } -} - -export const query = ` - query { - me { - hello - } - }`; - ------------------ -OUTPUT ------------------ -{ - "data": { - "me": { - "hello": "Hello world!" - } - } -} \ No newline at end of file diff --git a/src/tests/integrationFixtures/getAcessor/index.ts.expected.md b/src/tests/integrationFixtures/getAcessor/index.ts.expected.md new file mode 100644 index 00000000..8e2d63da --- /dev/null +++ b/src/tests/integrationFixtures/getAcessor/index.ts.expected.md @@ -0,0 +1,37 @@ +## input + +```ts title="getAcessor/index.ts" +/** @gqlQueryField */ +export function me(): User { + return new User(); +} + +/** @gqlType */ +class User { + /** @gqlField */ + get hello(): string { + return "Hello world!"; + } +} + +export const query = ` + query { + me { + hello + } + }`; +``` + +## Output + +### Query Result + +```json +{ + "data": { + "me": { + "hello": "Hello world!" + } + } +} +``` \ No newline at end of file diff --git a/src/tests/integrationFixtures/inputTypeOneOf/index.ts.expected b/src/tests/integrationFixtures/inputTypeOneOf/index.ts.expected deleted file mode 100644 index 95b513d9..00000000 --- a/src/tests/integrationFixtures/inputTypeOneOf/index.ts.expected +++ /dev/null @@ -1,47 +0,0 @@ ------------------ -INPUT ------------------ -import { ID } from "../../.."; - -/** @gqlInput */ -type UserPayload = { - id: ID; - name: string; -}; - -/** - * @gqlInput - */ -type Greeting = { name: string } | { userId: ID } | { user: UserPayload }; - -/** @gqlQueryField */ -export function greet(args: { greeting: Greeting }): string { - const greeting = args.greeting; - switch (true) { - case "name" in greeting: - return `Hello, ${greeting.name}!`; - case "userId" in greeting: - return `Hello, user with ID ${greeting.userId}!`; - case "user" in greeting: - return `Hello, ${greeting.user.name} with ID ${greeting.user.id}!`; - default: - // Assert exhaustive - const _exhaustiveCheck: never = greeting; - throw new Error(`Unexpected greeting: ${JSON.stringify(args.greeting)}`); - } -} - -export const query = ` - query { - greet(greeting: { name: "Alice" }) - } - `; - ------------------ -OUTPUT ------------------ -{ - "data": { - "greet": "Hello, Alice!" - } -} \ No newline at end of file diff --git a/src/tests/integrationFixtures/inputTypeOneOf/index.ts.expected.md b/src/tests/integrationFixtures/inputTypeOneOf/index.ts.expected.md new file mode 100644 index 00000000..8d9c7bcf --- /dev/null +++ b/src/tests/integrationFixtures/inputTypeOneOf/index.ts.expected.md @@ -0,0 +1,51 @@ +## input + +```ts title="inputTypeOneOf/index.ts" +import { ID } from "../../.."; + +/** @gqlInput */ +type UserPayload = { + id: ID; + name: string; +}; + +/** + * @gqlInput + */ +type Greeting = { name: string } | { userId: ID } | { user: UserPayload }; + +/** @gqlQueryField */ +export function greet(args: { greeting: Greeting }): string { + const greeting = args.greeting; + switch (true) { + case "name" in greeting: + return `Hello, ${greeting.name}!`; + case "userId" in greeting: + return `Hello, user with ID ${greeting.userId}!`; + case "user" in greeting: + return `Hello, ${greeting.user.name} with ID ${greeting.user.id}!`; + default: + // Assert exhaustive + const _exhaustiveCheck: never = greeting; + throw new Error(`Unexpected greeting: ${JSON.stringify(args.greeting)}`); + } +} + +export const query = ` + query { + greet(greeting: { name: "Alice" }) + } + `; +``` + +## Output + +### Query Result + +```json +{ + "data": { + "greet": "Hello, Alice!" + } +} +``` \ No newline at end of file diff --git a/src/tests/integrationFixtures/killsParentOnException/index.ts.expected b/src/tests/integrationFixtures/killsParentOnException/index.ts.expected deleted file mode 100644 index fe2d1029..00000000 --- a/src/tests/integrationFixtures/killsParentOnException/index.ts.expected +++ /dev/null @@ -1,50 +0,0 @@ ------------------ -INPUT ------------------ -/** @gqlQueryField */ -export function me(): User { - return new User(); -} - -/** @gqlType */ -class User { - /** - * @gqlField - * @killsParentOnException - */ - alwaysThrowsKillsParentOnException(): string { - throw new Error("This error should kill User"); - } -} - -export const query = ` - query { - me { - alwaysThrowsKillsParentOnException - } - } -`; - ------------------ -OUTPUT ------------------ -{ - "errors": [ - { - "message": "This error should kill User", - "locations": [ - { - "line": 4, - "column": 7 - } - ], - "path": [ - "me", - "alwaysThrowsKillsParentOnException" - ] - } - ], - "data": { - "me": null - } -} \ No newline at end of file diff --git a/src/tests/integrationFixtures/killsParentOnException/index.ts.expected.md b/src/tests/integrationFixtures/killsParentOnException/index.ts.expected.md new file mode 100644 index 00000000..0deb7555 --- /dev/null +++ b/src/tests/integrationFixtures/killsParentOnException/index.ts.expected.md @@ -0,0 +1,54 @@ +## input + +```ts title="killsParentOnException/index.ts" +/** @gqlQueryField */ +export function me(): User { + return new User(); +} + +/** @gqlType */ +class User { + /** + * @gqlField + * @killsParentOnException + */ + alwaysThrowsKillsParentOnException(): string { + throw new Error("This error should kill User"); + } +} + +export const query = ` + query { + me { + alwaysThrowsKillsParentOnException + } + } +`; +``` + +## Output + +### Query Result + +```json +{ + "errors": [ + { + "message": "This error should kill User", + "locations": [ + { + "line": 4, + "column": 7 + } + ], + "path": [ + "me", + "alwaysThrowsKillsParentOnException" + ] + } + ], + "data": { + "me": null + } +} +``` \ No newline at end of file diff --git a/src/tests/integrationFixtures/killsParentOnExceptionOnQuery/index.ts.expected b/src/tests/integrationFixtures/killsParentOnExceptionOnQuery/index.ts.expected deleted file mode 100644 index 1654d3a7..00000000 --- a/src/tests/integrationFixtures/killsParentOnExceptionOnQuery/index.ts.expected +++ /dev/null @@ -1,43 +0,0 @@ ------------------ -INPUT ------------------ -/** - * @gqlQueryField - * @killsParentOnException - */ -export function alwaysThrowsKillsParentOnException(): string { - throw new Error("This error should kill Query"); -} - -/** @gqlQueryField */ -export function hello(): string { - return "Hello World"; -} - -export const query = ` - query { - alwaysThrowsKillsParentOnException - hello - } -`; - ------------------ -OUTPUT ------------------ -{ - "errors": [ - { - "message": "This error should kill Query", - "locations": [ - { - "line": 3, - "column": 5 - } - ], - "path": [ - "alwaysThrowsKillsParentOnException" - ] - } - ], - "data": null -} \ No newline at end of file diff --git a/src/tests/integrationFixtures/killsParentOnExceptionOnQuery/index.ts.expected.md b/src/tests/integrationFixtures/killsParentOnExceptionOnQuery/index.ts.expected.md new file mode 100644 index 00000000..d10470cc --- /dev/null +++ b/src/tests/integrationFixtures/killsParentOnExceptionOnQuery/index.ts.expected.md @@ -0,0 +1,47 @@ +## input + +```ts title="killsParentOnExceptionOnQuery/index.ts" +/** + * @gqlQueryField + * @killsParentOnException + */ +export function alwaysThrowsKillsParentOnException(): string { + throw new Error("This error should kill Query"); +} + +/** @gqlQueryField */ +export function hello(): string { + return "Hello World"; +} + +export const query = ` + query { + alwaysThrowsKillsParentOnException + hello + } +`; +``` + +## Output + +### Query Result + +```json +{ + "errors": [ + { + "message": "This error should kill Query", + "locations": [ + { + "line": 3, + "column": 5 + } + ], + "path": [ + "alwaysThrowsKillsParentOnException" + ] + } + ], + "data": null +} +``` \ No newline at end of file diff --git a/src/tests/integrationFixtures/killsParentOnExceptionReturnsNull/index.ts.expected b/src/tests/integrationFixtures/killsParentOnExceptionReturnsNull/index.ts.expected deleted file mode 100644 index e0ae9a8c..00000000 --- a/src/tests/integrationFixtures/killsParentOnExceptionReturnsNull/index.ts.expected +++ /dev/null @@ -1,51 +0,0 @@ ------------------ -INPUT ------------------ -/** @gqlQueryField */ -export function me(): User { - return new User(); -} - -/** @gqlType */ -class User { - /** - * @gqlField - * @killsParentOnException - */ - alwaysThrowsKillsParentOnException(): string { - // @ts-ignore - return null; - } -} - -export const query = ` - query { - me { - alwaysThrowsKillsParentOnException - } - } -`; - ------------------ -OUTPUT ------------------ -{ - "errors": [ - { - "message": "Cannot return null for non-nullable field User.alwaysThrowsKillsParentOnException.", - "locations": [ - { - "line": 4, - "column": 7 - } - ], - "path": [ - "me", - "alwaysThrowsKillsParentOnException" - ] - } - ], - "data": { - "me": null - } -} \ No newline at end of file diff --git a/src/tests/integrationFixtures/killsParentOnExceptionReturnsNull/index.ts.expected.md b/src/tests/integrationFixtures/killsParentOnExceptionReturnsNull/index.ts.expected.md new file mode 100644 index 00000000..56ee35f8 --- /dev/null +++ b/src/tests/integrationFixtures/killsParentOnExceptionReturnsNull/index.ts.expected.md @@ -0,0 +1,55 @@ +## input + +```ts title="killsParentOnExceptionReturnsNull/index.ts" +/** @gqlQueryField */ +export function me(): User { + return new User(); +} + +/** @gqlType */ +class User { + /** + * @gqlField + * @killsParentOnException + */ + alwaysThrowsKillsParentOnException(): string { + // @ts-ignore + return null; + } +} + +export const query = ` + query { + me { + alwaysThrowsKillsParentOnException + } + } +`; +``` + +## Output + +### Query Result + +```json +{ + "errors": [ + { + "message": "Cannot return null for non-nullable field User.alwaysThrowsKillsParentOnException.", + "locations": [ + { + "line": 4, + "column": 7 + } + ], + "path": [ + "me", + "alwaysThrowsKillsParentOnException" + ] + } + ], + "data": { + "me": null + } +} +``` \ No newline at end of file diff --git a/src/tests/integrationFixtures/nonNullArgWithDefault/index.ts.expected b/src/tests/integrationFixtures/nonNullArgWithDefault/index.ts.expected deleted file mode 100644 index be117a2f..00000000 --- a/src/tests/integrationFixtures/nonNullArgWithDefault/index.ts.expected +++ /dev/null @@ -1,22 +0,0 @@ ------------------ -INPUT ------------------ -/** @gqlQueryField */ -export function hello({ greeting = "Hello" }: { greeting: string }): string { - return `${greeting}, world!`; -} - -export const query = ` - query { - hello - } - `; - ------------------ -OUTPUT ------------------ -{ - "data": { - "hello": "Hello, world!" - } -} \ No newline at end of file diff --git a/src/tests/integrationFixtures/nonNullArgWithDefault/index.ts.expected.md b/src/tests/integrationFixtures/nonNullArgWithDefault/index.ts.expected.md new file mode 100644 index 00000000..c7b78d95 --- /dev/null +++ b/src/tests/integrationFixtures/nonNullArgWithDefault/index.ts.expected.md @@ -0,0 +1,26 @@ +## input + +```ts title="nonNullArgWithDefault/index.ts" +/** @gqlQueryField */ +export function hello({ greeting = "Hello" }: { greeting: string }): string { + return `${greeting}, world!`; +} + +export const query = ` + query { + hello + } + `; +``` + +## Output + +### Query Result + +```json +{ + "data": { + "hello": "Hello, world!" + } +} +``` \ No newline at end of file diff --git a/src/tests/integrationFixtures/nonNullEnumDefault/index.ts.expected b/src/tests/integrationFixtures/nonNullEnumDefault/index.ts.expected deleted file mode 100644 index 137d10d5..00000000 --- a/src/tests/integrationFixtures/nonNullEnumDefault/index.ts.expected +++ /dev/null @@ -1,27 +0,0 @@ ------------------ -INPUT ------------------ -// https://github.com/captbaritone/grats/issues/174 - -/** @gqlEnum */ -type GreetingOptions = "Hello" | "Greetings" | "Sup"; - -/** @gqlQueryField */ -export function hello(greeting: GreetingOptions = "Greetings"): string { - return `${greeting} World`; -} - -export const query = /* GraphQL */ ` - query { - hello - } -`; - ------------------ -OUTPUT ------------------ -{ - "data": { - "hello": "Greetings World" - } -} \ No newline at end of file diff --git a/src/tests/integrationFixtures/nonNullEnumDefault/index.ts.expected.md b/src/tests/integrationFixtures/nonNullEnumDefault/index.ts.expected.md new file mode 100644 index 00000000..1d9a45b7 --- /dev/null +++ b/src/tests/integrationFixtures/nonNullEnumDefault/index.ts.expected.md @@ -0,0 +1,31 @@ +## input + +```ts title="nonNullEnumDefault/index.ts" +// https://github.com/captbaritone/grats/issues/174 + +/** @gqlEnum */ +type GreetingOptions = "Hello" | "Greetings" | "Sup"; + +/** @gqlQueryField */ +export function hello(greeting: GreetingOptions = "Greetings"): string { + return `${greeting} World`; +} + +export const query = /* GraphQL */ ` + query { + hello + } +`; +``` + +## Output + +### Query Result + +```json +{ + "data": { + "hello": "Greetings World" + } +} +``` \ No newline at end of file diff --git a/src/tests/integrationFixtures/nonNullableListIncludesNull/index.ts.expected b/src/tests/integrationFixtures/nonNullableListIncludesNull/index.ts.expected deleted file mode 100644 index 66bea10a..00000000 --- a/src/tests/integrationFixtures/nonNullableListIncludesNull/index.ts.expected +++ /dev/null @@ -1,60 +0,0 @@ ------------------ -INPUT ------------------ -/** @gqlQueryField */ -export function someList(): string[] { - // @ts-ignore - return ["a", null, "b"]; -} - -/** @gqlQueryField */ -export function someListOfLists(): string[][] { - // @ts-ignore - return [["a"], ["b", null, "c"]]; -} - -export const query = ` - query { - someList - someListOfLists - } -`; - ------------------ -OUTPUT ------------------ -{ - "errors": [ - { - "message": "Cannot return null for non-nullable field Query.someList.", - "locations": [ - { - "line": 3, - "column": 5 - } - ], - "path": [ - "someList", - 1 - ] - }, - { - "message": "Cannot return null for non-nullable field Query.someListOfLists.", - "locations": [ - { - "line": 4, - "column": 5 - } - ], - "path": [ - "someListOfLists", - 1, - 1 - ] - } - ], - "data": { - "someList": null, - "someListOfLists": null - } -} \ No newline at end of file diff --git a/src/tests/integrationFixtures/nonNullableListIncludesNull/index.ts.expected.md b/src/tests/integrationFixtures/nonNullableListIncludesNull/index.ts.expected.md new file mode 100644 index 00000000..1ac88521 --- /dev/null +++ b/src/tests/integrationFixtures/nonNullableListIncludesNull/index.ts.expected.md @@ -0,0 +1,64 @@ +## input + +```ts title="nonNullableListIncludesNull/index.ts" +/** @gqlQueryField */ +export function someList(): string[] { + // @ts-ignore + return ["a", null, "b"]; +} + +/** @gqlQueryField */ +export function someListOfLists(): string[][] { + // @ts-ignore + return [["a"], ["b", null, "c"]]; +} + +export const query = ` + query { + someList + someListOfLists + } +`; +``` + +## Output + +### Query Result + +```json +{ + "errors": [ + { + "message": "Cannot return null for non-nullable field Query.someList.", + "locations": [ + { + "line": 3, + "column": 5 + } + ], + "path": [ + "someList", + 1 + ] + }, + { + "message": "Cannot return null for non-nullable field Query.someListOfLists.", + "locations": [ + { + "line": 4, + "column": 5 + } + ], + "path": [ + "someListOfLists", + 1, + 1 + ] + } + ], + "data": { + "someList": null, + "someListOfLists": null + } +} +``` \ No newline at end of file diff --git a/src/tests/integrationFixtures/numericID/index.ts.expected b/src/tests/integrationFixtures/numericID/index.ts.expected deleted file mode 100644 index eed9fbba..00000000 --- a/src/tests/integrationFixtures/numericID/index.ts.expected +++ /dev/null @@ -1,38 +0,0 @@ ------------------ -INPUT ------------------ -import { ID } from "../../../Types"; - -/** - * Validating that graphql-js will coerce a numeric ID to a string. - * https://github.com/captbaritone/grats/issues/53 - */ - -/** @gqlQueryField */ -export function hello(args: { someID: ID }): string { - if (typeof args.someID !== "string") { - throw new Error( - `Expected someID to be a string, but it was ${typeof args.someID}`, - ); - } - return args.someID; -} - -export const query = /* GraphQL */ ` - query SomeQuery($someID: ID!) { - hello(someID: $someID) - } -`; - -export const variables = { - someID: 123, -}; - ------------------ -OUTPUT ------------------ -{ - "data": { - "hello": "123" - } -} \ No newline at end of file diff --git a/src/tests/integrationFixtures/numericID/index.ts.expected.md b/src/tests/integrationFixtures/numericID/index.ts.expected.md new file mode 100644 index 00000000..cee2f73b --- /dev/null +++ b/src/tests/integrationFixtures/numericID/index.ts.expected.md @@ -0,0 +1,42 @@ +## input + +```ts title="numericID/index.ts" +import { ID } from "../../../Types"; + +/** + * Validating that graphql-js will coerce a numeric ID to a string. + * https://github.com/captbaritone/grats/issues/53 + */ + +/** @gqlQueryField */ +export function hello(args: { someID: ID }): string { + if (typeof args.someID !== "string") { + throw new Error( + `Expected someID to be a string, but it was ${typeof args.someID}`, + ); + } + return args.someID; +} + +export const query = /* GraphQL */ ` + query SomeQuery($someID: ID!) { + hello(someID: $someID) + } +`; + +export const variables = { + someID: 123, +}; +``` + +## Output + +### Query Result + +```json +{ + "data": { + "hello": "123" + } +} +``` \ No newline at end of file diff --git a/src/tests/integrationFixtures/parameterPropertyRenamed/index.ts.expected b/src/tests/integrationFixtures/parameterPropertyRenamed/index.ts.expected deleted file mode 100644 index 8ae15ad7..00000000 --- a/src/tests/integrationFixtures/parameterPropertyRenamed/index.ts.expected +++ /dev/null @@ -1,34 +0,0 @@ ------------------ -INPUT ------------------ -/** @gqlQueryField */ -export function me(): User { - return new User(); -} - -/** @gqlType */ -class User { - constructor( - /** @gqlField hello */ - public NOT_THIS: string = "world", - ) {} -} - -export const query = ` - query { - me { - hello - } - } -`; - ------------------ -OUTPUT ------------------ -{ - "data": { - "me": { - "hello": "world" - } - } -} \ No newline at end of file diff --git a/src/tests/integrationFixtures/parameterPropertyRenamed/index.ts.expected.md b/src/tests/integrationFixtures/parameterPropertyRenamed/index.ts.expected.md new file mode 100644 index 00000000..780acf5b --- /dev/null +++ b/src/tests/integrationFixtures/parameterPropertyRenamed/index.ts.expected.md @@ -0,0 +1,38 @@ +## input + +```ts title="parameterPropertyRenamed/index.ts" +/** @gqlQueryField */ +export function me(): User { + return new User(); +} + +/** @gqlType */ +class User { + constructor( + /** @gqlField hello */ + public NOT_THIS: string = "world", + ) {} +} + +export const query = ` + query { + me { + hello + } + } +`; +``` + +## Output + +### Query Result + +```json +{ + "data": { + "me": { + "hello": "world" + } + } +} +``` \ No newline at end of file diff --git a/src/tests/integrationFixtures/positionalNonNullArgWithDefault/index.ts.expected b/src/tests/integrationFixtures/positionalNonNullArgWithDefault/index.ts.expected deleted file mode 100644 index 07436fe1..00000000 --- a/src/tests/integrationFixtures/positionalNonNullArgWithDefault/index.ts.expected +++ /dev/null @@ -1,22 +0,0 @@ ------------------ -INPUT ------------------ -/** @gqlQueryField */ -export function hello(greeting: string = "Hello"): string { - return `${greeting}, world!`; -} - -export const query = ` - query { - hello - } - `; - ------------------ -OUTPUT ------------------ -{ - "data": { - "hello": "Hello, world!" - } -} \ No newline at end of file diff --git a/src/tests/integrationFixtures/positionalNonNullArgWithDefault/index.ts.expected.md b/src/tests/integrationFixtures/positionalNonNullArgWithDefault/index.ts.expected.md new file mode 100644 index 00000000..811c965d --- /dev/null +++ b/src/tests/integrationFixtures/positionalNonNullArgWithDefault/index.ts.expected.md @@ -0,0 +1,26 @@ +## input + +```ts title="positionalNonNullArgWithDefault/index.ts" +/** @gqlQueryField */ +export function hello(greeting: string = "Hello"): string { + return `${greeting}, world!`; +} + +export const query = ` + query { + hello + } + `; +``` + +## Output + +### Query Result + +```json +{ + "data": { + "hello": "Hello, world!" + } +} +``` \ No newline at end of file diff --git a/src/tests/integrationFixtures/promiseOfPromise/index.ts.expected b/src/tests/integrationFixtures/promiseOfPromise/index.ts.expected deleted file mode 100644 index 16c3c427..00000000 --- a/src/tests/integrationFixtures/promiseOfPromise/index.ts.expected +++ /dev/null @@ -1,34 +0,0 @@ ------------------ -INPUT ------------------ -/** @gqlQueryField */ -export function promiseOfPromise(): Promise> { - return promiseOf(promiseOf("Hello world!")); -} - -/** @gqlQueryField */ -export function promiseOfPromisePromise(): Promise>> { - return promiseOf(promiseOf(promiseOf("Hello world!"))); -} - -function promiseOf(value: T): Promise { - return new Promise((resolve) => { - resolve(value); - }); -} - -export const query = ` - query { - promiseOfPromise - promiseOfPromisePromise - }`; - ------------------ -OUTPUT ------------------ -{ - "data": { - "promiseOfPromise": "Hello world!", - "promiseOfPromisePromise": "Hello world!" - } -} \ No newline at end of file diff --git a/src/tests/integrationFixtures/promiseOfPromise/index.ts.expected.md b/src/tests/integrationFixtures/promiseOfPromise/index.ts.expected.md new file mode 100644 index 00000000..84aea373 --- /dev/null +++ b/src/tests/integrationFixtures/promiseOfPromise/index.ts.expected.md @@ -0,0 +1,38 @@ +## input + +```ts title="promiseOfPromise/index.ts" +/** @gqlQueryField */ +export function promiseOfPromise(): Promise> { + return promiseOf(promiseOf("Hello world!")); +} + +/** @gqlQueryField */ +export function promiseOfPromisePromise(): Promise>> { + return promiseOf(promiseOf(promiseOf("Hello world!"))); +} + +function promiseOf(value: T): Promise { + return new Promise((resolve) => { + resolve(value); + }); +} + +export const query = ` + query { + promiseOfPromise + promiseOfPromisePromise + }`; +``` + +## Output + +### Query Result + +```json +{ + "data": { + "promiseOfPromise": "Hello world!", + "promiseOfPromisePromise": "Hello world!" + } +} +``` \ No newline at end of file diff --git a/src/tests/integrationFixtures/resolveTypeViaClass/index.ts.expected b/src/tests/integrationFixtures/resolveTypeViaClass/index.ts.expected deleted file mode 100644 index 28c80e50..00000000 --- a/src/tests/integrationFixtures/resolveTypeViaClass/index.ts.expected +++ /dev/null @@ -1,109 +0,0 @@ ------------------ -INPUT ------------------ -import { ID } from "../../../Types"; - -/** @gqlInterface */ -interface GqlNode { - /** @gqlField */ - id: ID; -} - -/** @gqlType */ -export default class DefaultNode implements GqlNode { - constructor( - /** @gqlField */ - public id: ID, - ) {} -} - -/** @gqlType */ -export class User implements GqlNode { - constructor( - /** @gqlField */ - public id: ID, - ) {} -} - -/** @gqlType RenamedNode */ -export class ThisNameGetsIgnored implements GqlNode { - constructor( - /** @gqlField */ - public id: ID, - ) {} -} - -/** @gqlType */ -export class Guest implements GqlNode { - constructor( - /** @gqlField */ - public id: ID, - ) {} -} - -class AlsoUser extends User { - constructor(id: ID) { - super(id); - } -} - -/** @gqlQueryField */ -export function node(args: { id: ID }): GqlNode { - const { id } = args; - if (id.startsWith("User:")) { - return new User(id); - } else if (id.startsWith("Guest:")) { - return new Guest(id); - } else if (id.startsWith("DefaultNode:")) { - return new DefaultNode(id); - } else if (id.startsWith("RenamedNode:")) { - return new ThisNameGetsIgnored(id); - } else if (id.startsWith("AlsoUser:")) { - return new AlsoUser(id); - } else { - return new Guest(id); - } -} - -export const query = /* GraphQL */ ` - query { - user: node(id: "User:1") { - __typename - } - alsoUser: node(id: "AlsoUser:1") { - __typename - } - guest: node(id: "Guest:1") { - __typename - } - defaultNode: node(id: "DefaultNode:1") { - __typename - } - renamedNode: node(id: "RenamedNode:1") { - __typename - } - } -`; - ------------------ -OUTPUT ------------------ -{ - "data": { - "user": { - "__typename": "User" - }, - "alsoUser": { - "__typename": "User" - }, - "guest": { - "__typename": "Guest" - }, - "defaultNode": { - "__typename": "DefaultNode" - }, - "renamedNode": { - "__typename": "RenamedNode" - } - } -} \ No newline at end of file diff --git a/src/tests/integrationFixtures/resolveTypeViaClass/index.ts.expected.md b/src/tests/integrationFixtures/resolveTypeViaClass/index.ts.expected.md new file mode 100644 index 00000000..3178feef --- /dev/null +++ b/src/tests/integrationFixtures/resolveTypeViaClass/index.ts.expected.md @@ -0,0 +1,113 @@ +## input + +```ts title="resolveTypeViaClass/index.ts" +import { ID } from "../../../Types"; + +/** @gqlInterface */ +interface GqlNode { + /** @gqlField */ + id: ID; +} + +/** @gqlType */ +export default class DefaultNode implements GqlNode { + constructor( + /** @gqlField */ + public id: ID, + ) {} +} + +/** @gqlType */ +export class User implements GqlNode { + constructor( + /** @gqlField */ + public id: ID, + ) {} +} + +/** @gqlType RenamedNode */ +export class ThisNameGetsIgnored implements GqlNode { + constructor( + /** @gqlField */ + public id: ID, + ) {} +} + +/** @gqlType */ +export class Guest implements GqlNode { + constructor( + /** @gqlField */ + public id: ID, + ) {} +} + +class AlsoUser extends User { + constructor(id: ID) { + super(id); + } +} + +/** @gqlQueryField */ +export function node(args: { id: ID }): GqlNode { + const { id } = args; + if (id.startsWith("User:")) { + return new User(id); + } else if (id.startsWith("Guest:")) { + return new Guest(id); + } else if (id.startsWith("DefaultNode:")) { + return new DefaultNode(id); + } else if (id.startsWith("RenamedNode:")) { + return new ThisNameGetsIgnored(id); + } else if (id.startsWith("AlsoUser:")) { + return new AlsoUser(id); + } else { + return new Guest(id); + } +} + +export const query = /* GraphQL */ ` + query { + user: node(id: "User:1") { + __typename + } + alsoUser: node(id: "AlsoUser:1") { + __typename + } + guest: node(id: "Guest:1") { + __typename + } + defaultNode: node(id: "DefaultNode:1") { + __typename + } + renamedNode: node(id: "RenamedNode:1") { + __typename + } + } +`; +``` + +## Output + +### Query Result + +```json +{ + "data": { + "user": { + "__typename": "User" + }, + "alsoUser": { + "__typename": "User" + }, + "guest": { + "__typename": "Guest" + }, + "defaultNode": { + "__typename": "DefaultNode" + }, + "renamedNode": { + "__typename": "RenamedNode" + } + } +} +``` \ No newline at end of file diff --git a/src/tests/integrationFixtures/resolverErrorElidedToNull/index.ts.expected b/src/tests/integrationFixtures/resolverErrorElidedToNull/index.ts.expected deleted file mode 100644 index b2705c65..00000000 --- a/src/tests/integrationFixtures/resolverErrorElidedToNull/index.ts.expected +++ /dev/null @@ -1,36 +0,0 @@ ------------------ -INPUT ------------------ -/** @gqlQueryField */ -export function alwaysThrows(): string { - throw new Error("This should null out the field"); -} - -export const query = ` - query { - alwaysThrows - } -`; - ------------------ -OUTPUT ------------------ -{ - "errors": [ - { - "message": "This should null out the field", - "locations": [ - { - "line": 3, - "column": 5 - } - ], - "path": [ - "alwaysThrows" - ] - } - ], - "data": { - "alwaysThrows": null - } -} \ No newline at end of file diff --git a/src/tests/integrationFixtures/resolverErrorElidedToNull/index.ts.expected.md b/src/tests/integrationFixtures/resolverErrorElidedToNull/index.ts.expected.md new file mode 100644 index 00000000..7c03289d --- /dev/null +++ b/src/tests/integrationFixtures/resolverErrorElidedToNull/index.ts.expected.md @@ -0,0 +1,40 @@ +## input + +```ts title="resolverErrorElidedToNull/index.ts" +/** @gqlQueryField */ +export function alwaysThrows(): string { + throw new Error("This should null out the field"); +} + +export const query = ` + query { + alwaysThrows + } +`; +``` + +## Output + +### Query Result + +```json +{ + "errors": [ + { + "message": "This should null out the field", + "locations": [ + { + "line": 3, + "column": 5 + } + ], + "path": [ + "alwaysThrows" + ] + } + ], + "data": { + "alwaysThrows": null + } +} +``` \ No newline at end of file diff --git a/src/tests/integrationFixtures/skipInclude/index.ts.expected b/src/tests/integrationFixtures/skipInclude/index.ts.expected deleted file mode 100644 index 1b0a0b85..00000000 --- a/src/tests/integrationFixtures/skipInclude/index.ts.expected +++ /dev/null @@ -1,27 +0,0 @@ ------------------ -INPUT ------------------ -/** @gqlQueryField */ -export function greeting(): string { - return "Hello World!"; -} - -/** @gqlDirective on FIELD */ -export function CustomDirective() { - // -} - -export const query = /* GraphQL */ ` - query { - greeting @include(if: true) - } -`; - ------------------ -OUTPUT ------------------ -{ - "data": { - "greeting": "Hello World!" - } -} \ No newline at end of file diff --git a/src/tests/integrationFixtures/skipInclude/index.ts.expected.md b/src/tests/integrationFixtures/skipInclude/index.ts.expected.md new file mode 100644 index 00000000..187b3ac1 --- /dev/null +++ b/src/tests/integrationFixtures/skipInclude/index.ts.expected.md @@ -0,0 +1,31 @@ +## input + +```ts title="skipInclude/index.ts" +/** @gqlQueryField */ +export function greeting(): string { + return "Hello World!"; +} + +/** @gqlDirective on FIELD */ +export function CustomDirective() { + // +} + +export const query = /* GraphQL */ ` + query { + greeting @include(if: true) + } +`; +``` + +## Output + +### Query Result + +```json +{ + "data": { + "greeting": "Hello World!" + } +} +``` \ No newline at end of file diff --git a/src/tests/integrationFixtures/strictSemanticNullability/index.ts.expected b/src/tests/integrationFixtures/strictSemanticNullability/index.ts.expected deleted file mode 100644 index b08959e9..00000000 --- a/src/tests/integrationFixtures/strictSemanticNullability/index.ts.expected +++ /dev/null @@ -1,126 +0,0 @@ ------------------ -INPUT ------------------ -// { "strictSemanticNullability": true } - -/** @gqlQueryField */ -export function actuallyReturnsNull(): string { - const empty: string[] = []; - return empty[0]; // Oops! -} - -/** @gqlQueryField */ -export async function actuallyReturnsAsyncNull(): Promise { - const empty: string[] = []; - return empty[0]; // Oops! -} - -/** @gqlQueryField */ -export function me(): User { - const empty: string[] = []; - return new User(empty[0]); -} - -/** @gqlInterface */ -interface IPerson { - /** @gqlField */ - name: string; -} - -/** @gqlType */ -class User implements IPerson { - __typename = "User" as const; - constructor(name: string) { - this.name = name; - this.alsoName = name; - } - /** @gqlField */ - name: string; - - /** @gqlField notName */ - alsoName: string; -} - -/** @gqlSubscriptionField */ -export async function* names(): AsyncIterable { - const empty: string[] = []; - yield empty[0]; // Oops! -} - -// All of these should result in an error -export const query = ` - query { - actuallyReturnsNull - actuallyReturnsAsyncNull - me { - name - notName - } - } -`; - ------------------ -OUTPUT ------------------ -{ - "errors": [ - { - "message": "Cannot return null for semantically non-nullable field.", - "locations": [ - { - "line": 3, - "column": 5 - } - ], - "path": [ - "actuallyReturnsNull" - ] - }, - { - "message": "Cannot return null for semantically non-nullable field.", - "locations": [ - { - "line": 4, - "column": 5 - } - ], - "path": [ - "actuallyReturnsAsyncNull" - ] - }, - { - "message": "Cannot return null for semantically non-nullable field.", - "locations": [ - { - "line": 6, - "column": 7 - } - ], - "path": [ - "me", - "name" - ] - }, - { - "message": "Cannot return null for semantically non-nullable field.", - "locations": [ - { - "line": 7, - "column": 7 - } - ], - "path": [ - "me", - "notName" - ] - } - ], - "data": { - "actuallyReturnsNull": null, - "actuallyReturnsAsyncNull": null, - "me": { - "name": null, - "notName": null - } - } -} \ No newline at end of file diff --git a/src/tests/integrationFixtures/strictSemanticNullability/index.ts.expected.md b/src/tests/integrationFixtures/strictSemanticNullability/index.ts.expected.md new file mode 100644 index 00000000..d631c149 --- /dev/null +++ b/src/tests/integrationFixtures/strictSemanticNullability/index.ts.expected.md @@ -0,0 +1,130 @@ +## input + +```ts title="strictSemanticNullability/index.ts" +// { "strictSemanticNullability": true } + +/** @gqlQueryField */ +export function actuallyReturnsNull(): string { + const empty: string[] = []; + return empty[0]; // Oops! +} + +/** @gqlQueryField */ +export async function actuallyReturnsAsyncNull(): Promise { + const empty: string[] = []; + return empty[0]; // Oops! +} + +/** @gqlQueryField */ +export function me(): User { + const empty: string[] = []; + return new User(empty[0]); +} + +/** @gqlInterface */ +interface IPerson { + /** @gqlField */ + name: string; +} + +/** @gqlType */ +class User implements IPerson { + __typename = "User" as const; + constructor(name: string) { + this.name = name; + this.alsoName = name; + } + /** @gqlField */ + name: string; + + /** @gqlField notName */ + alsoName: string; +} + +/** @gqlSubscriptionField */ +export async function* names(): AsyncIterable { + const empty: string[] = []; + yield empty[0]; // Oops! +} + +// All of these should result in an error +export const query = ` + query { + actuallyReturnsNull + actuallyReturnsAsyncNull + me { + name + notName + } + } +`; +``` + +## Output + +### Query Result + +```json +{ + "errors": [ + { + "message": "Cannot return null for semantically non-nullable field.", + "locations": [ + { + "line": 3, + "column": 5 + } + ], + "path": [ + "actuallyReturnsNull" + ] + }, + { + "message": "Cannot return null for semantically non-nullable field.", + "locations": [ + { + "line": 4, + "column": 5 + } + ], + "path": [ + "actuallyReturnsAsyncNull" + ] + }, + { + "message": "Cannot return null for semantically non-nullable field.", + "locations": [ + { + "line": 6, + "column": 7 + } + ], + "path": [ + "me", + "name" + ] + }, + { + "message": "Cannot return null for semantically non-nullable field.", + "locations": [ + { + "line": 7, + "column": 7 + } + ], + "path": [ + "me", + "notName" + ] + } + ], + "data": { + "actuallyReturnsNull": null, + "actuallyReturnsAsyncNull": null, + "me": { + "name": null, + "notName": null + } + } +} +``` \ No newline at end of file diff --git a/src/tests/test.ts b/src/tests/test.ts index 8b42c4a1..367f2a8c 100644 --- a/src/tests/test.ts +++ b/src/tests/test.ts @@ -1,5 +1,5 @@ import * as path from "path"; -import TestRunner from "./TestRunner"; +import TestRunner, { Transformer, TransformerResult } from "./TestRunner"; import { buildSchemaAndDocResult, buildSchemaAndDocResultWithHost, @@ -32,6 +32,7 @@ import { extend } from "../utils/helpers"; import { Result, ok, err } from "../utils/Result"; import { applyFixes } from "../fixFixable"; import { writeTypeScriptTypeToDisk } from "../../scripts/buildConfigTypes"; +import { Markdown } from "./Markdown"; writeTypeScriptTypeToDisk(); @@ -80,12 +81,22 @@ const fixturesDir = path.join(__dirname, "fixtures"); const configFixturesDir = path.join(__dirname, "configParserFixtures"); const integrationFixturesDir = path.join(__dirname, "integrationFixtures"); -const testDirs = [ +type TestDir = { + fixturesDir: string; + testFilePattern: RegExp; + ignoreFilePattern: RegExp | null; + transformer: Transformer; +}; + +const testDirs: TestDir[] = [ { fixturesDir: configFixturesDir, testFilePattern: /\.json$/, ignoreFilePattern: null, - transformer: (code: string, _fileName: string): Result => { + transformer: ( + code: string, + _fileName: string, + ): Result => { const config = JSON.parse(code); let parsed: ParsedCommandLineGrats; const warnings: string[] = []; @@ -104,9 +115,10 @@ const testDirs = [ }); if (parsedResult.kind === "ERROR") { return err( - ReportableDiagnostics.fromDiagnostics( - parsedResult.err, - ).formatDiagnosticsWithContext(), + formatDiagnosticsWithContext( + code, + ReportableDiagnostics.fromDiagnostics(parsedResult.err), + ), ); } parsed = parsedResult.value; @@ -115,25 +127,22 @@ const testDirs = [ } console.warn = consoleWarn; - let result = `-- Parsed Config --\n${JSON.stringify( - parsed.raw.grats, - null, - 2, - )}`; + const markdown = new Markdown(); + + markdown.addHeader(3, "Parsed Config"); + markdown.addCodeBlock(JSON.stringify(parsed.raw.grats, null, 2), "json"); if (warnings.length > 0) { - result += `\n-- Warnings --\n${warnings.join("\n")}`; + markdown.addHeader(3, "Warnings"); + markdown.addCodeBlock(warnings.join("\n"), "text"); } - return ok(result); + return ok(markdown); }, }, { fixturesDir, testFilePattern: /\.ts$/, ignoreFilePattern: null, - transformer: ( - code: string, - fileName: string, - ): Result | false => { + transformer: (code: string, fileName: string): TransformerResult => { const firstLine = code.split("\n")[0]; let config: Partial = { nullableByDefault: true, @@ -220,13 +229,19 @@ const testDirs = [ if (locationMatch != null) { const locResult = locate(schema, locationMatch[1].trim()); if (locResult.kind === "ERROR") { - return err(locResult.err); + const markdown = new Markdown(); + markdown.addHeader(3, "Error Locating Type"); + markdown.addCodeBlock(locResult.err, "text"); + return err(markdown); } return err( - new ReportableDiagnostics(compilerHost, [ - gqlErr({ loc: locResult.value }, "Located here"), - ]).formatDiagnosticsWithContext(), + formatDiagnosticsWithContext( + code, + new ReportableDiagnostics(compilerHost, [ + gqlErr({ loc: locResult.value }, "Located here"), + ]), + ), ); } else { const docSansDirectives = { @@ -245,7 +260,13 @@ const testDirs = [ print(docSansDirectives), ); - return ok(`-- SDL --\n${sdl}\n-- TypeScript --\n${executableSchema}`); + const markdown = new Markdown(); + markdown.addHeader(3, "SDL"); + markdown.addCodeBlock(sdl, "graphql"); + markdown.addHeader(3, "TypeScript"); + markdown.addCodeBlock(executableSchema, "ts"); + + return ok(markdown); } }, }, @@ -256,7 +277,7 @@ const testDirs = [ transformer: async ( code: string, fileName: string, - ): Promise | false> => { + ): Promise | false> => { const firstLine = code.split("\n")[0]; let config: Partial = { nullableByDefault: true, @@ -284,6 +305,8 @@ const testDirs = [ fileNames: files, }); if (parsedOptionsResult.kind === "ERROR") { + // We don't expect integration tests to error during config parsing + // so we throw here instead of returning a Markdown result. throw new Error( ReportableDiagnostics.fromDiagnostics( parsedOptionsResult.err, @@ -293,6 +316,8 @@ const testDirs = [ const parsedOptions = parsedOptionsResult.value; const schemaResult = buildSchemaAndDocResult(parsedOptions); if (schemaResult.kind === "ERROR") { + // We don't expect integration tests to error GraphQL schema building + // so we throw here instead of returning a Markdown result. throw new Error( ReportableDiagnostics.fromDiagnostics( schemaResult.err, @@ -351,7 +376,11 @@ const testDirs = [ variableValues: server.variables, }); - return ok(JSON.stringify(data, null, 2)); + const markdown = new Markdown(); + markdown.addHeader(3, "Query Result"); + markdown.addCodeBlock(JSON.stringify(data, null, 2), "json"); + + return ok(markdown); }, }, ]; @@ -385,7 +414,7 @@ function printSDLFromSchemaWithoutDirectives(schema: GraphQLSchema): string { function formatDiagnosticsWithContext( code: string, diagnostics: ReportableDiagnostics, -): string { +): Markdown { const formatted = diagnostics.formatDiagnosticsWithContext(); const actions: { @@ -435,8 +464,12 @@ function formatDiagnosticsWithContext( }); } + const markdown = new Markdown(); + markdown.addHeader(3, "Error Report"); + markdown.addCodeBlock(formatted, "text"); + if (actions.length === 0) { - return formatted; + return markdown; } const fixable = diagnostics._diagnostics.filter((d) => d.fix != null); @@ -445,7 +478,13 @@ function formatDiagnosticsWithContext( logEvents.push(event); } - let fixedText = ""; + for (const action of actions) { + markdown.addHeader( + 4, + `Code Action: "${action.description}" (${action.fixName})`, + ); + markdown.addCodeBlock(action.diff, "diff"); + } if (fixable.length > 0) { const fileName = fixable[0].file?.fileName; @@ -459,16 +498,13 @@ function formatDiagnosticsWithContext( writeFileSync(fileName, current, "utf8"); - fixedText = `\n\n-- Applied Fixes --\n${logEvents.join("\n")}\n\n-- Fixed Text --\n${newText}`; + markdown.addHeader(4, "Applied Fixes"); + markdown.addCodeBlock(logEvents.join("\n"), "text"); + markdown.addHeader(4, "Fixed Text"); + markdown.addCodeBlock(newText, "typescript"); } - const actionText = actions - .map((action) => { - return `-- Code Action: "${action.description}" (${action.fixName}) --\n${action.diff}`; - }) - .join("\n"); - - return `-- Error Report --\n${formatted}\n${actionText}${fixedText}`; + return markdown; } program.parse();