Skip to content

Commit

Permalink
chore: store outputs in own directory (#1078)
Browse files Browse the repository at this point in the history
  • Loading branch information
jasonkuhrt authored Sep 10, 2024
1 parent 16377bb commit 3a3a098
Show file tree
Hide file tree
Showing 60 changed files with 147 additions and 67 deletions.
File renamed without changes.
File renamed without changes.
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { dynamicValue } from './$/helpers.js'
import { dynamicValue } from '../$/helpers.js'

export const encode = (value: string) => {
return value.replace(/Headers {[^}]*}/s, dynamicValue)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
headers: Headers {
connection: 'keep-alive',
'content-length': '119',
'x-served-by': 'cache-yul1970051-YUL',
'x-served-by': 'cache-yul1970035-YUL',
'accept-ranges': 'bytes',
date: 'Sun, 08 Sep 2024 18:13:26 GMT',
'content-type': 'application/graphql-response+json; charset=utf-8',
Expand All @@ -32,13 +32,13 @@
'alt-svc': 'h3=":443"; ma=86400',
'access-control-allow-origin': '*',
'x-powered-by': 'Stellate',
age: '158583',
age: '176284',
'cache-control': 'public, s-maxage=2628000, stale-while-revalidate=2628000',
'x-cache': 'HIT',
'x-cache-hits': '36',
'x-cache-hits': '13',
'gcdn-cache': 'HIT',
'stellate-rate-limit-budget-remaining': '44',
'stellate-rate-limit-rules': '"IP limit";type="RequestCount";budget=50;limited=?0;remaining=44;refill=60',
'stellate-rate-limit-budget-remaining': '49',
'stellate-rate-limit-rules': '"IP limit";type="RequestCount";budget=50;limited=?0;remaining=49;refill=60',
'stellate-rate-limit-decision': 'pass',
'stellate-rate-limit-budget-required': '5',
'content-encoding': 'br'
Expand Down
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
headers: Headers {
accept: 'application/graphql-response+json; charset=utf-8, application/json; charset=utf-8',
'content-type': 'application/json',
'x-sent-at-time': '1725977788513'
'x-sent-at-time': '1725995489078'
},
signal: undefined,
method: 'post',
Expand Down
4 changes: 4 additions & 0 deletions examples/generated|generated_arguments__arguments.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
/**
* This example shows how to use the TypeScript interface for GraphQL arguments.
*/

import { Atlas } from './$/generated-clients/atlas/__.js'
import { showJson } from './$/helpers.js'

Expand Down
4 changes: 4 additions & 0 deletions examples/other|transport-memory.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
/**
* This example shows how you can send requests against an in-memory GraphQL schema instead of one hosted over HTTP.
*/

import { GraphQLObjectType, GraphQLSchema, GraphQLString } from 'graphql'
import { Graffle } from '../src/entrypoints/main.js'
import { showJson } from './$/helpers.js'
Expand Down
4 changes: 4 additions & 0 deletions examples/output|output_default.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
/**
* This example shows the default output behavior.
*/

import { Atlas } from './$/generated-clients/atlas/__.js'
import { show } from './$/helpers.js'

Expand Down
4 changes: 4 additions & 0 deletions examples/output|output_envelope.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
/**
* This example shows how to configure output to use the envelope.
*/

import { Atlas } from './$/generated-clients/atlas/__.js'
import { show } from './$/helpers.js'

Expand Down
4 changes: 4 additions & 0 deletions examples/raw|raw.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
/**
* This example shows how to send a request using a Document instance for the GraphQL document.
*/

import { gql, Graffle } from '../src/entrypoints/main.js'
import { publicGraphQLSchemaEndpoints, show } from './$/helpers.js'

Expand Down
4 changes: 4 additions & 0 deletions examples/raw|raw_rawString__rawString.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
/**
* This example shows how to send a request using a string for the GraphQL document.
*/

import { Graffle } from '../src/entrypoints/main.js'
import { publicGraphQLSchemaEndpoints, show } from './$/helpers.js'

Expand Down
6 changes: 6 additions & 0 deletions examples/raw|raw_rawString_rawTyped__rawString-typed.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
/**
* This example shows how to send a request using a string for the GraphQL document while also being typesafe in regards to the passed variables and return type.
* Note that the typing is a cast and would not catch if the actual GraphQL document disagreed with the types. As the comment suggests below, ideally some sort
* of automation would generate the types for you.
*/

import { Graffle, type TypedDocumentString } from '../src/entrypoints/main.js'
import { publicGraphQLSchemaEndpoints, show } from './$/helpers.js'

Expand Down
4 changes: 4 additions & 0 deletions examples/raw|raw_rawTyped__raw-typed.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
/**
* This example shows how to send a request using a Document instance for the GraphQL document while also being typesafe in regards to the passed variables and return type.
*/

import type { TypedQueryDocumentNode } from 'graphql'
import { gql, Graffle } from '../src/entrypoints/main.js'
import { publicGraphQLSchemaEndpoints, show } from './$/helpers.js'
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
/**
* This example shows how to use the `transport` configuration to control request headers. Notice how empty string headers unset previously set headers.
*/

import { Graffle } from '../src/entrypoints/main.js'
import { show } from './$/helpers.js'
import { publicGraphQLSchemaEndpoints } from './$/helpers.js'
Expand Down
1 change: 1 addition & 0 deletions examples/transport-http|transport-http_raw.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
/**
* This example shows how to use the `raw` configuration of transport configuration to easily access low-level `RequestInit` configuration.
*/

import { Graffle } from '../src/entrypoints/main.js'
import { show } from './$/helpers.js'
import { publicGraphQLSchemaEndpoints } from './$/helpers.js'
Expand Down
6 changes: 2 additions & 4 deletions scripts/generate-examples-derivatives/generate-docs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,9 @@ import * as FS from 'node:fs/promises'
import { type DefaultTheme } from 'vitepress'
import { documentQueryContinents, publicGraphQLSchemaEndpoints } from '../../examples/$/helpers.js'
import { deleteFiles } from '../lib/deleteFiles.js'
import { computeCombinations, type Example, readExamples, toTitle } from './helpers.js'

export const generateDocs = async () => {
const examples = await readExamples()
import { computeCombinations, type Example, toTitle } from './helpers.js'

export const generateDocs = async (examples: Example[]) => {
const examplesTransformed = examples
.map(transformOther)
.map(transformRewriteGraffleImports)
Expand Down
17 changes: 9 additions & 8 deletions scripts/generate-examples-derivatives/generate-outputs.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,18 @@
import * as FS from 'node:fs/promises'
import { deleteFiles } from '../lib/deleteFiles.js'
import { readExampleFiles, runExample } from './helpers.js'
import { directories, type Example, runExample } from './helpers.js'

export const generateOutputs = async () => {
export const generateOutputs = async (examples: Example[]) => {
// Handle case of renaming or deleting examples.
await deleteFiles({ pattern: `./examples/*.output.*` })
await Promise.all([
deleteFiles({ pattern: `./examples/*.output.txt` }),
deleteFiles({ pattern: `${directories.outputs}/*.output.txt` }),
])

const exampleFiles = await readExampleFiles()

await Promise.all(exampleFiles.map(async (file) => {
const filePath = `./examples/${file.name}.ts`
await Promise.all(examples.map(async (example) => {
const filePath = `./examples/${example.file.name}.ts`
const exampleResult = await runExample(filePath)
await FS.writeFile(`./examples/${file.name}.output.txt`, exampleResult)
await FS.writeFile(`${directories.outputs}/${example.file.name}.output.txt`, exampleResult)
}))

console.log(`Generated an output for each example.`)
Expand Down
40 changes: 19 additions & 21 deletions scripts/generate-examples-derivatives/generate-tests.ts
Original file line number Diff line number Diff line change
@@ -1,27 +1,23 @@
import { globby } from 'globby'
import * as FS from 'node:fs/promises'
import * as Path from 'node:path'
import { deleteFiles } from '../lib/deleteFiles.js'
import { readFiles } from '../lib/readFiles.js'
import { directories, type Example } from './helpers.js'

export const generateTests = async () => {
export const generateTests = async (examples: Example[]) => {
// Handle case of renaming or deleting examples.
await deleteFiles({ pattern: `./tests/examples/*.test.ts` })

const exampleFiles = await readFiles({
pattern: `./examples/*.ts`,
options: { ignore: [`./examples/$*`, `./examples/*.output.*`, `./examples/*.output-encoder.*`] },
})
const encoderFilePaths = await globby(`./examples/*.output-encoder.ts`)
await Promise.all([
deleteFiles({ pattern: `${directories.outputs}/*.output.test.txt` }),
deleteFiles({ pattern: `${directories.examples}/*.output.test.txt` }),
deleteFiles({ pattern: `./tests/examples/*.test.ts` }),
])

const outputDir = Path.join(process.cwd(), `./tests/examples`)

await Promise.all(exampleFiles.map(async (file) => {
const encoderFilePath = encoderFilePaths.find((encoderFilePath) =>
encoderFilePath.includes(`${file.name}.output-encoder.ts`)
)
const snapshotFileName = `../../${file.path.dir}/${file.name}.output${encoderFilePath ? `.test` : ``}.txt`
const exampleFilePath = `./examples/${file.name}.ts`
await Promise.all(examples.map(async (example) => {
const snapshotFileName = `../../${example.file.path.dir}/__outputs__/${example.file.name}.output${
example.output.encoder ? `.test` : ``
}.txt`
const exampleFilePath = `./examples/${example.file.name}.ts`
const code = `// @vitest-environment node
// WARNING:
Expand All @@ -30,21 +26,23 @@ export const generateTests = async () => {
import { runExample } from '../../scripts/generate-examples-derivatives/helpers.js'
import { expect, test } from 'vitest'${
encoderFilePath
? `\nimport { encode } from '${Path.relative(outputDir, encoderFilePath.replace(`.ts`, `.js`))}'`
example.output.encoder
? `\nimport { encode } from '${
Path.relative(outputDir, example.output.encoder.filePath.replace(`.ts`, `.js`))
}'`
: ``
}
test(\`${file.name}\`, async () => {
test(\`${example.file.name}\`, async () => {
const exampleResult = await runExample(\`${exampleFilePath}\`)
// Examples should output their data results.
const exampleResultMaybeEncoded = ${encoderFilePath ? `encode(exampleResult)` : `exampleResult`}
const exampleResultMaybeEncoded = ${example.output.encoder ? `encode(exampleResult)` : `exampleResult`}
// If ever outputs vary by Node version, you can use this to snapshot by Node version.
// const nodeMajor = process.version.match(/v(\\d+)/)?.[1] ?? \`unknown\`
await expect(exampleResultMaybeEncoded).toMatchFileSnapshot(\`${snapshotFileName}\`)
})
`
await FS.writeFile(Path.join(outputDir, `${file.name}.test.ts`), code)
await FS.writeFile(Path.join(outputDir, `${example.file.name}.test.ts`), code)
}))

console.log(`Generated a test for each example.`)
Expand Down
6 changes: 4 additions & 2 deletions scripts/generate-examples-derivatives/generate.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import { generateDocs } from './generate-docs.js'
import { generateOutputs } from './generate-outputs.js'
import { generateTests } from './generate-tests.js'
import { readExamples } from './helpers.js'

await Promise.all([generateOutputs(), generateTests()])
await generateDocs()
const examples = await readExamples()
await Promise.all([generateOutputs(examples), generateTests(examples)])
await generateDocs(examples)
21 changes: 20 additions & 1 deletion scripts/generate-examples-derivatives/helpers.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,15 @@
import { capitalize, kebabCase } from 'es-toolkit'
import { execa } from 'execa'
import { globby } from 'globby'
import stripAnsi from 'strip-ansi'
import { showPartition } from '../../examples/$/helpers.js'
import { type File, readFiles } from '../lib/readFiles.js'

export const directories = {
outputs: `./examples/__outputs__`,
examples: `./examples`,
}

export const examplesIgnorePatterns = [`./examples/$*`, `./examples/*.output.*`, `./examples/*.output-encoder.*`]

export const readExampleFiles = () =>
Expand All @@ -16,12 +22,17 @@ export const readExamples = async (): Promise<Example[]> => {
const exampleFiles = await readExampleFiles()

const outputFiles = await readFiles({
pattern: `./examples/*.output.txt`,
pattern: `./examples/__outputs__/*.output.txt`,
})

const encoderFilePaths = await globby(`${directories.outputs}/*.output.encoder.ts`)

const examples = exampleFiles.map((example) => {
const outputFile = outputFiles.find(file => file.name === `${example.name}.output.txt`)
if (!outputFile) throw new Error(`Could not find output file for ${example.name}`)
const encoderFilePath = encoderFilePaths.find((encoderFilePath) =>
encoderFilePath.includes(`${example.name}.output.encoder.ts`)
)

const { description, content } = extractDescription(example.content)

Expand All @@ -34,6 +45,11 @@ export const readExamples = async (): Promise<Example[]> => {
output: {
file: outputFile,
blocks: outputFile.content.split(showPartition + `\n`).map(block => block.trim()).filter(Boolean),
encoder: encoderFilePath
? {
filePath: encoderFilePath,
}
: undefined,
},
isUsingJsonOutput: example.content.includes(`showJson`),
description,
Expand Down Expand Up @@ -82,6 +98,9 @@ export interface Example {
output: {
file: File
blocks: string[]
encoder?: {
filePath: string
}
}
isUsingJsonOutput: boolean
tags: Tag[]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,6 @@ test(`generated|generated_arguments__arguments`, async () => {
// If ever outputs vary by Node version, you can use this to snapshot by Node version.
// const nodeMajor = process.version.match(/v(\d+)/)?.[1] ?? `unknown`
await expect(exampleResultMaybeEncoded).toMatchFileSnapshot(
`../.././examples/generated|generated_arguments__arguments.output.txt`,
`../.././examples/__outputs__/generated|generated_arguments__arguments.output.txt`,
)
})
4 changes: 3 additions & 1 deletion tests/examples/other|transport-memory.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,5 +13,7 @@ test(`other|transport-memory`, async () => {
const exampleResultMaybeEncoded = exampleResult
// If ever outputs vary by Node version, you can use this to snapshot by Node version.
// const nodeMajor = process.version.match(/v(\d+)/)?.[1] ?? `unknown`
await expect(exampleResultMaybeEncoded).toMatchFileSnapshot(`../.././examples/other|transport-memory.output.txt`)
await expect(exampleResultMaybeEncoded).toMatchFileSnapshot(
`../.././examples/__outputs__/other|transport-memory.output.txt`,
)
})
4 changes: 3 additions & 1 deletion tests/examples/output|output_default.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,5 +13,7 @@ test(`output|output_default`, async () => {
const exampleResultMaybeEncoded = exampleResult
// If ever outputs vary by Node version, you can use this to snapshot by Node version.
// const nodeMajor = process.version.match(/v(\d+)/)?.[1] ?? `unknown`
await expect(exampleResultMaybeEncoded).toMatchFileSnapshot(`../.././examples/output|output_default.output.txt`)
await expect(exampleResultMaybeEncoded).toMatchFileSnapshot(
`../.././examples/__outputs__/output|output_default.output.txt`,
)
})
6 changes: 4 additions & 2 deletions tests/examples/output|output_envelope.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
// Do not modify this file directly.

import { expect, test } from 'vitest'
import { encode } from '../../examples/output|output_envelope.output-encoder.js'
import { encode } from '../../examples/__outputs__/output|output_envelope.output.encoder.js'
import { runExample } from '../../scripts/generate-examples-derivatives/helpers.js'

test(`output|output_envelope`, async () => {
Expand All @@ -14,5 +14,7 @@ test(`output|output_envelope`, async () => {
const exampleResultMaybeEncoded = encode(exampleResult)
// If ever outputs vary by Node version, you can use this to snapshot by Node version.
// const nodeMajor = process.version.match(/v(\d+)/)?.[1] ?? `unknown`
await expect(exampleResultMaybeEncoded).toMatchFileSnapshot(`../.././examples/output|output_envelope.output.test.txt`)
await expect(exampleResultMaybeEncoded).toMatchFileSnapshot(
`../.././examples/__outputs__/output|output_envelope.output.test.txt`,
)
})
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,6 @@ test(`output|output_envelope_envelope-error__envelope-error`, async () => {
// If ever outputs vary by Node version, you can use this to snapshot by Node version.
// const nodeMajor = process.version.match(/v(\d+)/)?.[1] ?? `unknown`
await expect(exampleResultMaybeEncoded).toMatchFileSnapshot(
`../.././examples/output|output_envelope_envelope-error__envelope-error.output.txt`,
`../.././examples/__outputs__/output|output_envelope_envelope-error__envelope-error.output.txt`,
)
})
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,6 @@ test(`output|output_envelope_envelope_error-throw__envelope-error-throw`, async
// If ever outputs vary by Node version, you can use this to snapshot by Node version.
// const nodeMajor = process.version.match(/v(\d+)/)?.[1] ?? `unknown`
await expect(exampleResultMaybeEncoded).toMatchFileSnapshot(
`../.././examples/output|output_envelope_envelope_error-throw__envelope-error-throw.output.txt`,
`../.././examples/__outputs__/output|output_envelope_envelope_error-throw__envelope-error-throw.output.txt`,
)
})
2 changes: 1 addition & 1 deletion tests/examples/raw|raw.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,5 +13,5 @@ test(`raw|raw`, async () => {
const exampleResultMaybeEncoded = exampleResult
// If ever outputs vary by Node version, you can use this to snapshot by Node version.
// const nodeMajor = process.version.match(/v(\d+)/)?.[1] ?? `unknown`
await expect(exampleResultMaybeEncoded).toMatchFileSnapshot(`../.././examples/raw|raw.output.txt`)
await expect(exampleResultMaybeEncoded).toMatchFileSnapshot(`../.././examples/__outputs__/raw|raw.output.txt`)
})
2 changes: 1 addition & 1 deletion tests/examples/raw|raw_rawString__rawString.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,6 @@ test(`raw|raw_rawString__rawString`, async () => {
// If ever outputs vary by Node version, you can use this to snapshot by Node version.
// const nodeMajor = process.version.match(/v(\d+)/)?.[1] ?? `unknown`
await expect(exampleResultMaybeEncoded).toMatchFileSnapshot(
`../.././examples/raw|raw_rawString__rawString.output.txt`,
`../.././examples/__outputs__/raw|raw_rawString__rawString.output.txt`,
)
})
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,6 @@ test(`raw|raw_rawString_rawTyped__rawString-typed`, async () => {
// If ever outputs vary by Node version, you can use this to snapshot by Node version.
// const nodeMajor = process.version.match(/v(\d+)/)?.[1] ?? `unknown`
await expect(exampleResultMaybeEncoded).toMatchFileSnapshot(
`../.././examples/raw|raw_rawString_rawTyped__rawString-typed.output.txt`,
`../.././examples/__outputs__/raw|raw_rawString_rawTyped__rawString-typed.output.txt`,
)
})
4 changes: 3 additions & 1 deletion tests/examples/raw|raw_rawTyped__raw-typed.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,5 +13,7 @@ test(`raw|raw_rawTyped__raw-typed`, async () => {
const exampleResultMaybeEncoded = exampleResult
// If ever outputs vary by Node version, you can use this to snapshot by Node version.
// const nodeMajor = process.version.match(/v(\d+)/)?.[1] ?? `unknown`
await expect(exampleResultMaybeEncoded).toMatchFileSnapshot(`../.././examples/raw|raw_rawTyped__raw-typed.output.txt`)
await expect(exampleResultMaybeEncoded).toMatchFileSnapshot(
`../.././examples/__outputs__/raw|raw_rawTyped__raw-typed.output.txt`,
)
})
Loading

0 comments on commit 3a3a098

Please sign in to comment.