Skip to content

Commit

Permalink
chore: separate unit and integration tests (#1567)
Browse files Browse the repository at this point in the history
* separate unit and integration tests

* split integration and unit tests

* run tests in parallel

* fix: typo

* fix: handle invalid JSON body

* gget whole response

* chore: ignore svelte and fastify on Node <= 14

* move readiness check to integration tests

* chore: fix regex???

* chore: increase test timeout for integration tests ok

* lol you should run the code locally before for pushing

* chore: add dependency for pleasing vercelino

* chore: "fix" integration test

* chore: run as precheck

* cover more cases for the accept header

* chore: remove debug info

* renable test

* Fix tests

Co-authored-by: Arda TANRIKULU <ardatanrikulu@gmail.com>
  • Loading branch information
n1ru4l and ardatan committed Aug 12, 2022
1 parent 77dcf4b commit e7a47b5
Show file tree
Hide file tree
Showing 47 changed files with 2,618 additions and 2,114 deletions.
5 changes: 5 additions & 0 deletions .changeset/happy-dolls-shout.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'graphql-yoga': patch
---

Handle invalid JSON body gracefully
38 changes: 36 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,41 @@ jobs:
- name: Run Tests
run: yarn test

test-integration:
name: Run integration tests
runs-on: ubuntu-latest
strategy:
matrix:
node-version: [14, 16, 18]
fail-fast: false
steps:
- name: Checkout Repository
uses: actions/checkout@v3

- name: Use Node ${{ matrix.node-version }}
uses: actions/setup-node@master
with:
node-version: ${{ matrix.node-version }}
cache: 'yarn'

- name: Cache Node Modules
uses: actions/cache@v3
id: node-modules-cache-test-node
with:
path: '**/node_modules'
key: ${{runner.os}}-${{ matrix.node-version }}-node-modules-${{hashFiles('yarn.lock')}}-${{hashFiles('patches/**/*')}}
restore-keys: |
${{runner.os}}-${{ matrix.node-version }}-node-modules-${{hashFiles('yarn.lock')}}-${{hashFiles('patches/**/*')}}
- name: Install Dependencies using Yarn
run: yarn install --ignore-engines --frozen-lockfile --immutable
if: steps.node-modules-cache-test-node.outputs.cache-hit != 'true'

- name: Build Packages
run: yarn build

- name: Run Tests
run: yarn test:integration

test-esm:
name: Testing with Node ESM
runs-on: ubuntu-latest
Expand Down Expand Up @@ -74,8 +109,7 @@ jobs:
run: yarn build

- name: Run Tests
working-directory: ./examples/node-esm
run: yarn test
run: yarn workspace example-node-esm run test

typecheck:
name: Typecheck
Expand Down
2 changes: 1 addition & 1 deletion examples/cloudflare-modules/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,5 @@
"skipLibCheck": true
},
"include": ["src"],
"exclude": ["node_modules", "dist", "test"]
"exclude": ["node_modules", "dist", "__integration-tests__"]
}
File renamed without changes.
File renamed without changes.
File renamed without changes.
2 changes: 1 addition & 1 deletion examples/koa/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,5 @@
"skipLibCheck": true
},
"include": ["src"],
"exclude": ["node_modules", "dist", "test"]
"exclude": ["node_modules", "dist", "__integration-tests__"]
}
18 changes: 18 additions & 0 deletions examples/node-esm/__integration-tests__/esm.spec.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { yoga } from '../yoga.mjs'

describe('Node ESM', () => {
it('should work', async () => {
const response = await yoga.fetch('https://yoga/graphql', {
method: 'POST',
headers: {
'content-type': 'application/json',
},
body: JSON.stringify({
query: '{ greetings }',
}),
})
expect(response.status).toBe(200)
const body = JSON.parse(await response.text())
expect(body.data.greetings).toBe('Hello world!')
})
})
16 changes: 0 additions & 16 deletions examples/node-esm/__tests__/esm.spec.js

This file was deleted.

3 changes: 3 additions & 0 deletions examples/node-esm/jest.config.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
export default {
transform: {},
testMatch: [
'<rootDir>/**/__integration-tests__/**/?(*.)+(spec|test).m[jt]s?(x)',
],
}
2 changes: 1 addition & 1 deletion examples/service-worker/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,5 @@
"skipLibCheck": true
},
"include": ["src"],
"exclude": ["node_modules", "dist", "test"]
"exclude": ["node_modules", "dist", "__integration-tests__"]
}
4 changes: 3 additions & 1 deletion examples/subscriptions/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,10 @@
"private": true,
"version": "0.13.4",
"scripts": {
"postinstall": "graphql-codegen --config codegen.yml",
"codegen": "graphql-codegen --config codegen.yml",
"postinstall": "yarn run codegen",
"start": "ts-node src/index.ts",
"precheck": "yarn run codegen",
"check": "tsc --pretty --noEmit"
},
"dependencies": {
Expand Down
26 changes: 15 additions & 11 deletions examples/subscriptions/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import {
createYoga,
createSchema,
useExtendContext,
YogaInitialContext,
createPubSub,
Repeater,
Expand Down Expand Up @@ -57,15 +56,20 @@ const resolvers: Resolvers<Context> = {
},
Subscription: {
counter: {
async *subscribe() {
let counter = 0

// count up until the subscription is terminated
while (true) {
yield counter++
await wait(1000)
}
},
subscribe: () =>
new Repeater((push, stop) => {
let counter = 0
function increment() {
push(counter++)
console.log('push')
}
increment()
let interval = setInterval(increment, 1000)
stop.then(() => {
clearInterval(interval)
console.log('stop')
})
}),
resolve: (payload: any) => payload,
},
globalCounter: {
Expand Down Expand Up @@ -100,7 +104,7 @@ const yoga = createYoga<Context, any>({
typeDefs,
}),
logging: true,
plugins: [useExtendContext(() => ({ pubSub }))],
context: () => ({ pubSub }),
})

const server = createServer(yoga)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,9 @@ describe('SvelteKit integration', () => {
// Kill the port if it's used!
try {
execSync('fuser -k 3007/tcp');
} catch (error) {}
} catch (error) {
// console.error(error)
}

// Build svelteKit
execSync('yarn workspace example-sveltekit build');
Expand Down Expand Up @@ -86,10 +88,10 @@ describe('SvelteKit integration', () => {
let strIntro = '';
try {
// A-1/ Wait for the introspection query result getting our type "hello"
let resIntro = await page.waitForResponse((res) => res.url().endsWith('/api/graphql'), {
const resIntro = await page.waitForResponse((res) => res.url().endsWith('/api/graphql'), {
timeout: timings.waitForResponse
});
let jsonIntro = await resIntro.json();
const jsonIntro = await resIntro.json();
strIntro = JSON.stringify(jsonIntro, null, 0);
} catch (error) {
// We had an issue grabbing the introspection query result!
Expand All @@ -99,7 +101,7 @@ describe('SvelteKit integration', () => {

// B/ Check that GraphiQL is showing
expect(bodyContent).toContain(
`renderYogaGraphiQL(root,{\"endpoint\":\"/api/graphql\",\"defaultQuery\":\"query Hello {\\n\\thello\\n}\"})`
`renderYogaGraphiQL(root,{"endpoint":"/api/graphql","defaultQuery":"query Hello {\\n\\thello\\n}"})`
);
}

Expand Down
28 changes: 20 additions & 8 deletions jest.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,17 +8,28 @@ const tsconfig = require(TSCONFIG)

process.env.LC_ALL = 'en_US'

const testMatch = [
'**/?(*.)+(spec|test).[jt]s?(x)',
'!**/examples/node-esm/**',
'!**/.bob/**',
]
const testMatch = []

if (parseInt(process.versions.node.split('.')[0]) <= 14) {
testMatch.push('!**/examples/sveltekit/**')
testMatch.push('!**/examples/fastify*/**')
let testTimeout = undefined

if (process.env.INTEGRATION_TEST === 'true') {
testTimeout = 10000
testMatch.push(
'<rootDir>/**/__integration-tests__/**/?(*.)+(spec|test).[jt]s?(x)',
)
if (parseInt(process.versions.node.split('.')[0]) <= 14) {
testMatch.push('!**/examples/sveltekit/**')
testMatch.push('!**/examples/fastify*/**')
}
} else {
testMatch.push(
'<rootDir>/packages/**/?(*.)+(spec|test).[jt]s?(x)',
'!**/__integration-tests__/**',
)
}

testMatch.push('!**/dist/**', '!**/.bob/**')

module.exports = {
testEnvironment: 'node',
rootDir: ROOT_DIR,
Expand All @@ -34,5 +45,6 @@ module.exports = {
collectCoverage: false,
cacheDirectory: resolve(ROOT_DIR, `${CI ? '' : 'node_modules/'}.cache/jest`),
testMatch,
testTimeout,
resolver: 'bob-the-bundler/jest-resolver.js',
}
5 changes: 4 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
"check": "yarn workspaces run check",
"build": "yarn workspace @graphql-yoga/graphiql run build && yarn workspace @graphql-yoga/render-graphiql run build && yarn workspace graphql-yoga run generate-graphiql-html && bob build",
"test": "jest --passWithNoTests --forceExit",
"test:integration": "cross-env INTEGRATION_TEST=true jest --passWithNoTests --forceExit",
"release": "yarn build && changeset publish",
"release:canary": "(node scripts/canary-release.js && yarn build && yarn changeset publish --tag canary) || echo Skipping Canary...",
"start:docs": "yarn workspace website dev",
Expand Down Expand Up @@ -74,13 +75,15 @@
"babel-plugin-parameter-decorator": "1.0.16",
"babel-plugin-transform-typescript-metadata": "0.3.2",
"bob-the-bundler": "4.0.0",
"cross-env": "7.0.3",
"eslint": "^8.15.0",
"get-port": "5.1.1",
"graphql": "^16.5.0",
"husky": "^8.0.0",
"jest": "^28.0.0",
"lint-staged": "^13.0.3",
"patch-package": "^6.4.7",
"prettier": "^2.4.1",
"lint-staged": "^13.0.3",
"rimraf": "^3.0.2",
"supertest": "^6.1.6",
"ts-jest": "^28.0.0",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
import { ApolloClient, FetchResult, InMemoryCache } from '@apollo/client/core'
import { createYoga, createSchema } from 'graphql-yoga'
import { createServer } from 'http'
import { createServer, Server } from 'http'
import { parse } from 'graphql'
import { observableToAsyncIterable } from '@graphql-tools/utils'
import { YogaLink } from '@graphql-yoga/apollo-link'
import { File } from '@whatwg-node/fetch'
import getPort from 'get-port'

describe('Yoga Apollo Link', () => {
const port = 4000 + Math.floor(Math.random() * 1000)
const endpoint = '/graphql'
const hostname = '127.0.0.1'
const yoga = createYoga({
Expand Down Expand Up @@ -48,16 +48,22 @@ describe('Yoga Apollo Link', () => {
},
}),
})
const server = createServer(yoga)
const url = `http://${hostname}:${port}${endpoint}`
const client = new ApolloClient({
link: new YogaLink({
endpoint: url,
customFetch: yoga.fetchAPI.fetch,
}),
cache: new InMemoryCache(),
})

let server: Server
let url: string
let client: ApolloClient<any>

beforeAll(async () => {
const port = await getPort()
server = createServer(yoga)
url = `http://${hostname}:${port}${endpoint}`
client = new ApolloClient({
link: new YogaLink({
endpoint: url,
customFetch: yoga.fetchAPI.fetch,
}),
cache: new InMemoryCache(),
})
await new Promise<void>((resolve) => server.listen(port, hostname, resolve))
})
afterAll(async () => {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
import { createClient, OperationResult } from '@urql/core'
import { Client, createClient, OperationResult } from '@urql/core'
import { yogaExchange } from '@graphql-yoga/urql-exchange'
import { observableToAsyncIterable } from '@graphql-tools/utils'
import { pipe, toObservable } from 'wonka'
import { createYoga, createSchema } from 'graphql-yoga'
import { File } from '@whatwg-node/fetch'
import { createServer } from 'http'
import { createServer, Server } from 'http'
import getPort from 'get-port'

describe('graphExchange', () => {
const port = 4000 + Math.floor(Math.random() * 1000)
const endpoint = '/graphql'
const hostname = '127.0.0.1'
const yoga = createYoga({
Expand Down Expand Up @@ -48,17 +48,23 @@ describe('graphExchange', () => {
},
}),
})
const server = createServer(yoga)
const url = `http://${hostname}:${port}${endpoint}`
const client = createClient({
url,
exchanges: [
yogaExchange({
customFetch: yoga.fetchAPI.fetch,
}),
],
})

let server: Server
let url: string
let client: Client

beforeAll(async () => {
const port = await getPort()
server = createServer(yoga)
url = `http://${hostname}:${port}${endpoint}`
client = createClient({
url,
exchanges: [
yogaExchange({
customFetch: yoga.fetchAPI.fetch,
}),
],
})
await new Promise<void>((resolve) => server.listen(port, hostname, resolve))
})
afterAll(async () => {
Expand Down
Loading

0 comments on commit e7a47b5

Please sign in to comment.