Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

tests(e2e): server with client queries #29

Merged
merged 15 commits into from
May 11, 2021
6 changes: 6 additions & 0 deletions .github/workflows/pr.yml
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,12 @@ jobs:
node-version: ${{ matrix.node-version }}
- run: yarn global add yalc
- run: yarn --frozen-lockfile
- name: Set E2E DB Schema
run: yarn -s ts-node scripts/get-e2e-db-schema --os ${{ matrix.os }} --node-version ${{ matrix.node-version }} --github-env $env:GITHUB_ENV
if: ${{ matrix.os == 'windows-latest' }}
- name: Set E2E DB Schema
run: yarn -s ts-node scripts/get-e2e-db-schema --os ${{ matrix.os }} --node-version ${{ matrix.node-version }} --github-env $GITHUB_ENV
if: ${{ matrix.os != 'windows-latest' }}
- run: yarn -s build
- run: yarn -s test:ci
- name: Upload coverage to Codecov
Expand Down
7 changes: 6 additions & 1 deletion .github/workflows/trunk.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,13 @@ jobs:
node-version: ${{ matrix.node-version }}
- run: yarn global add yalc
- run: yarn --frozen-lockfile
- name: Set E2E DB Schema
run: yarn -s ts-node scripts/get-e2e-db-schema --os ${{ matrix.os }} --node-version ${{ matrix.node-version }} --github-env $env:GITHUB_ENV
if: ${{ matrix.os == 'windows-latest' }}
- name: Set E2E DB Schema
run: yarn -s ts-node scripts/get-e2e-db-schema --os ${{ matrix.os }} --node-version ${{ matrix.node-version }} --github-env $GITHUB_ENV
if: ${{ matrix.os != 'windows-latest' }}
- run: yarn -s build

- run: yarn -s test:ci
- name: Upload coverage to Codecov
uses: codecov/codecov-action@v1
Expand Down
6 changes: 6 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,13 @@
## Tests

#### General

- We disable `kleur` colors so snapshots do not have them. It would be nice to put the DX of colors into tests but needs some work. Node 12/14 results in different codes, [thus different snapshots](https://github.com/prisma/nexus-prisma/pull/3#issuecomment-782432471). See test-mode feature request here: https://github.com/lukeed/kleur/issues/47#issue-812419257.

#### E2E

- Runs against a [Heroku Postgres database](https://data.heroku.com/datastores/6e28e827-3dec-4181-b7a1-b219c5016437). Each run of the test e2e test will reset all data in that database. We do not use `docker-compose` because [it is not available on the macOS docker images](https://github.com/actions/virtual-environments/issues/17#issuecomment-614726536) and it is not possible to run Postgres in Windows GitHub actions machines either. Our CI runs against all OS's.

## Link-Like Development

Sometimes it is useful to use a [link workflow](https://docs.npmjs.com/cli/v6/commands/npm-link). This means working on a local checkout of the Nexus Prisma source code, while trying it out in a project as local on your machine. This can be great for feeling out ideas.
Expand Down
12 changes: 12 additions & 0 deletions docker-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
version: '3.8'
services:
# postgres://prisma:prisma@localhost:5700
postgres:
image: postgres:10
container_name: nexus-prisma-test
restart: always
environment:
- POSTGRES_USER=prisma
- POSTGRES_PASSWORD=prisma
ports:
- '5700:5432'
7 changes: 5 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
"build:module-facades": "ts-node scripts/build-module-facades",
"build": "yarn clean && yarn build:module-facades && tsc",
"test": "jest",
"test:ci": "jest --coverage",
"test:ci": "jest --coverage --forceExit",
"tdd": "jest --watch",
"tdd:e2e:debug": "cross-env test_project_reuse=true jest --watch e2e",
"clean": "rm -rf dist && rm -rf node_modules/.cache",
Expand All @@ -50,13 +50,15 @@
"@types/strip-ansi": "^5.2.1",
"@typescript-eslint/eslint-plugin": "^4.22.1",
"@typescript-eslint/parser": "^4.22.1",
"arg": "^5.0.0",
"cross-env": "^7.0.3",
"dripip": "0.10.0",
"eslint": "^7.25.0",
"eslint-config-prettier": "^8.3.0",
"eslint-plugin-only-warn": "^1.0.2",
"execa": "^5.0.0",
"graphql": "^15.5.0",
"graphql-request": "^3.4.0",
"jest": "26.6.3",
"jest-watch-typeahead": "0.6.3",
"lodash": "^4.17.21",
Expand All @@ -69,7 +71,8 @@
"ts-jest": "26.5.6",
"ts-node": "^9.1.1",
"type-fest": "^1.1.0",
"typescript": "^4.2.4"
"typescript": "^4.2.4",
"zod": "^3.0.0-beta.1"
},
"prettier": "@prisma-labs/prettier-config",
"peerDependencies": {
Expand Down
49 changes: 49 additions & 0 deletions scripts/get-e2e-db-schema.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import arg from 'arg'
import fs from 'fs-jetpack'
import { z } from 'zod'

type ComboCase =
| '12.x + windows-latest'
| '12.x + macos-latest'
| '12.x + ubuntu-latest'
| '14.x + windows-latest'
| '14.x + macos-latest'
| '14.x + ubuntu-latest'

const nodeVersionParser = z.union([z.literal('12.x'), z.literal('14.x')])

const osParser = z.union([z.literal('macos-latest'), z.literal('ubuntu-latest'), z.literal('windows-latest')])

const connectionStringMapping: Record<ComboCase, string> = {
'12.x + macos-latest': 'node_12_macos_latest',
'12.x + windows-latest': 'node_12_windows_latest',
'12.x + ubuntu-latest': 'node_12_ubuntu_latest',
'14.x + macos-latest': 'node_14_macos_latest',
'14.x + windows-latest': 'node_14_windows_latest',
'14.x + ubuntu-latest': 'node_14_ubuntu_latest',
}

const args = arg({
'--os': String,
'--node-version': String,
'--github-env': String,
})

const comboCase = parseComboCase(args['--node-version'] ?? '', args['--os'] ?? '')

if (args['--github-env']) {
fs.append(args['--github-env'], `E2E_DB_SCHEMA=${connectionStringMapping[comboCase]}`)
} else {
process.stdout.write(connectionStringMapping[comboCase])
}

//
// Helpers
//

function parseComboCase(nodeVersionInput: string, osInput: string): ComboCase {
const nodeVersion = nodeVersionParser.parse(nodeVersionInput)
const os = osParser.parse(osInput)
// eslint-disable-next-line
return [nodeVersion, os].join(' + ') as any
}
18 changes: 14 additions & 4 deletions tests/__helpers__.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import execa from 'execa'
import * as fs from 'fs-jetpack'
import { FSJetpack } from 'fs-jetpack/types'
import { printSchema } from 'graphql'
import { GraphQLClient } from 'graphql-request'
import { merge } from 'lodash'
import { core } from 'nexus'
import { AllNexusTypeDefs } from 'nexus/dist/core'
Expand Down Expand Up @@ -159,11 +160,11 @@ export function setupTestProject({
{
compilerOptions: {
strict: true,
noEmit: true,
target: 'ES2018',
module: 'CommonJS',
moduleResolution: 'node',
rootDir: 'src',
outDir: 'build',
esModuleInterop: true, // for ApolloServer b/c ws dep :(
},
include: ['src'],
Expand All @@ -175,19 +176,26 @@ export function setupTestProject({
const api: TestProject = {
fs: fs_,
info: tpi,
runOrThrow(command, options) {
run(command, options) {
return execa.commandSync(command, {
reject: false,
...options,
cwd: fs_.cwd(),
})
},
run(command, options) {
runOrThrow(command, options) {
return execa.commandSync(command, {
reject: false,
...options,
cwd: fs_.cwd(),
})
},
runAsync(command, options) {
return execa.command(command, {
...options,
cwd: fs_.cwd(),
})
},
client: new GraphQLClient('http://localhost:4000'),
}

return api
Expand All @@ -197,7 +205,9 @@ export interface TestProject {
fs: FSJetpack
info: TestProjectInfo
run(command: string, options?: execa.SyncOptions): execa.ExecaSyncReturnValue
runAsync(command: string, options?: execa.SyncOptions): execa.ExecaChildProcess
runOrThrow(command: string, options?: execa.SyncOptions): execa.ExecaSyncReturnValue
client: GraphQLClient
}

export function assertBuildPresent() {
Expand Down
35 changes: 25 additions & 10 deletions tests/e2e/__snapshots__/e2e.test.ts.snap
Original file line number Diff line number Diff line change
@@ -1,5 +1,20 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`When bundled custom scalars are used the project type checks and generates expected GraphQL schema: client request 1 1`] = `
Object {
"bars": Array [
Object {
"foo": Object {
"DateTimeManually": null,
"JsonManually": null,
"someDateTimeField": "2021-05-10T20:42:46.609Z",
"someEnumA": "alpha",
},
},
],
}
`;

exports[`When bundled custom scalars are used the project type checks and generates expected GraphQL schema: graphql schema 1`] = `
"### This file was generated by Nexus Schema
### Do not make changes to this file directly
Expand All @@ -14,17 +29,11 @@ A date-time string at UTC, such as 2007-12-03T10:15:30Z, compliant with the \`da
\\"\\"\\"
scalar DateTime

enum E1 {
a
b
c
}

type Foo {
DateTimeManually: DateTime
JsonManually: Json
e1: E1
someDateTimeField: DateTime!
someEnumA: SomeEnumA
someJsonField: Json!
}

Expand All @@ -36,6 +45,12 @@ scalar Json @specifiedBy(url: \\"http://www.ecma-international.org/publications/
type Query {
bars: [Bar]
}

enum SomeEnumA {
alpha
bravo
charlie
}
"
`;

Expand Down Expand Up @@ -81,7 +96,7 @@ export interface NexusGenInputs {
}

export interface NexusGenEnums {
E1: \\"a\\" | \\"b\\" | \\"c\\"
SomeEnumA: PrismaClient.SomeEnumA
}

export interface NexusGenScalars {
Expand Down Expand Up @@ -117,8 +132,8 @@ export interface NexusGenFieldTypes {
Foo: { // field return type
DateTimeManually: NexusGenScalars['DateTime'] | null; // DateTime
JsonManually: NexusGenScalars['Json'] | null; // Json
e1: NexusGenEnums['E1'] | null; // E1
someDateTimeField: NexusGenScalars['DateTime']; // DateTime!
someEnumA: NexusGenEnums['SomeEnumA'] | null; // SomeEnumA
someJsonField: NexusGenScalars['Json']; // Json!
}
Query: { // field return type
Expand All @@ -133,8 +148,8 @@ export interface NexusGenFieldTypeNames {
Foo: { // field return type name
DateTimeManually: 'DateTime'
JsonManually: 'Json'
e1: 'E1'
someDateTimeField: 'DateTime'
someEnumA: 'SomeEnumA'
someJsonField: 'Json'
}
Query: { // field return type name
Expand Down
Loading