Skip to content

Commit

Permalink
test: refactor tests to use async methods and configurable packager (…
Browse files Browse the repository at this point in the history
…default: yarn) (#578)

* fix: change packager in tests

* build: add helper script for cleaning tests cache

* test: build tests locally in band

yalc publish is resulting in race condition we need torefactor that

* test: change packager for run provider

* test: migrate jest config deprecated type

* test: refactor tests to use async methods and configurable packager

* test: remove runInBand option for ci

* test: increase timouts for tests

* test: increase timeout for kitchen-sink test

* test: reintroduce runInBand

* test: add timeouts to run executions with debug printouts in case of failure

* style: fix formatting

* test: refactor async run monitoring only to dedicated methods

* style: fix formatting

* test: fix package run command

* test: add monitoring for all dependency installation commands

* test: refactor async run monitoring and add retry option

* test: remove debug printout

* test: revert back timeout logic
  • Loading branch information
rostislav-simonik committed May 28, 2023
1 parent 89d5e47 commit 754a70e
Show file tree
Hide file tree
Showing 22 changed files with 472 additions and 186 deletions.
3 changes: 2 additions & 1 deletion .eslintignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
.github
node_modules
dist-*
tests
tests/e2e/fixtures
tests/__cache__
docs
jest.config.*
6 changes: 5 additions & 1 deletion .eslintrc
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,10 @@
// TypeScript makes these safe & effective
"no-case-declarations": "off",
// Same approach used by TypeScript noUnusedLocals
"@typescript-eslint/no-unused-vars": ["warn", { "varsIgnorePattern": "^_", "argsIgnorePattern": "^_" }]
"@typescript-eslint/no-unused-vars": ["warn", { "varsIgnorePattern": "^_", "argsIgnorePattern": "^_" }],
"no-return-await": "off",
"@typescript-eslint/return-await": ["error", "always"],
"@typescript-eslint/no-floating-promises": ["error", { "ignoreVoid": true }],
"@typescript-eslint/require-await": "error"
}
}
4 changes: 2 additions & 2 deletions .github/workflows/validate.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ jobs:
run: yarn --frozen-lockfile

- name: Run prettier
run: yarn -s format:check
run: yarn -s format

- name: Run es-lint
run: yarn -s lint:check
run: yarn -s lint
5 changes: 3 additions & 2 deletions jest.config.e2e.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import type { InitialOptionsTsJest } from 'ts-jest/dist/types'
import type { JestConfigWithTsJest } from 'ts-jest/dist/types'

const config: InitialOptionsTsJest = {
const config: JestConfigWithTsJest = {
preset: 'ts-jest',
displayName: 'e2e',
testMatch: ['**/e2e/**/*.test.ts'],
globalSetup: './tests/e2e/__global__/setup.ts',
}

export default config
5 changes: 3 additions & 2 deletions jest.config.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import type { InitialOptionsTsJest } from 'ts-jest/dist/types'
import type { JestConfigWithTsJest } from 'ts-jest/dist/types'

const config: InitialOptionsTsJest = {
const config: JestConfigWithTsJest = {
preset: 'ts-jest',
watchPlugins: [
'jest-watch-typeahead/filename',
Expand All @@ -10,6 +10,7 @@ const config: InitialOptionsTsJest = {
collectCoverageFrom: ['src/**/*'],
coverageReporters: ['lcov', 'text', 'html'],
projects: [`<rootDir>/jest.config.e2e.ts`, `<rootDir>/jest.config.unit.ts`],
testTimeout: 2 * 60 * 1000,
}

export default config
4 changes: 2 additions & 2 deletions jest.config.unit.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import type { InitialOptionsTsJest } from 'ts-jest/dist/types'
import type { JestConfigWithTsJest } from 'ts-jest/dist/types'

const config: InitialOptionsTsJest = {
const config: JestConfigWithTsJest = {
preset: 'ts-jest',
displayName: 'unit',
testMatch: [
Expand Down
9 changes: 5 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -53,10 +53,10 @@
},
"scripts": {
"reflect:toc": "markdown-toc README.md -i --maxdepth 4 && prettier --write README.md",
"format": "prettier --write .",
"format:check": "prettier --check .",
"lint": "eslint . --ext .ts,.tsx --fix",
"lint:check": "eslint . --ext .ts,.tsx --max-warnings 0",
"format:fix": "prettier --write .",
"format": "prettier --check .",
"lint:fix": "eslint . --ext .ts,.tsx --fix",
"lint": "eslint . --ext .ts,.tsx --max-warnings 0",
"dev": "yarn -s clean && tsc --build --watch tsconfig.cjs.json tsconfig.esm.json",
"dev:ts": "yarn dev",
"dev:yalc": "nodemon --delay 1.5 --exec 'yalc push --no-scripts' --watch 'dist-*/**/*'",
Expand All @@ -68,6 +68,7 @@
"tdd": "jest --selectProjects unit --watch",
"tdd:e2e:debug": "cross-env test_project_reuse=true jest --selectProjects e2e --watch",
"clean": "rm -rf dist-cjs dist-esm node_modules/.cache",
"clean:test:cache": "rm -rf tests/__cache__",
"release:pr": "dripip pr",
"release:canary": "dripip preview",
"release:stable": "dripip stable",
Expand Down
12 changes: 12 additions & 0 deletions tests/.eslintrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{
"rules": {
"@typescript-eslint/no-unsafe-assignment": "off",
"@typescript-eslint/no-unsafe-member-access": "off",
"@typescript-eslint/no-unsafe-return": "off",
"@typescript-eslint/no-unsafe-call": "off",
"@typescript-eslint/no-unsafe-argument": "off",
"@typescript-eslint/no-non-null-assertion": "off",
"@typescript-eslint/no-explicit-any": "off",
"@typescript-eslint/no-var-requires": "off"
}
}
1 change: 1 addition & 0 deletions tests/__helpers__/packageManager.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export const getPackageManager = () => process.env.PACKAGE_MANAGER ?? 'yarn'
24 changes: 16 additions & 8 deletions tests/__helpers__/testers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import { Module } from '../../src/generator/helpers/types'
import { ModuleGenerators } from '../../src/generator/ModuleGenerators'
import { Settings } from '../../src/generator/Settings'
import { createConsoleLogCapture, createPrismaSchema, prepareGraphQLSDLForSnapshot } from './helpers'
import { getPackageManager } from './packageManager'

/**
* Define Nexus type definitions based on the Nexus Prisma configurations
Expand Down Expand Up @@ -117,14 +118,16 @@ export const testIntegration = (params: TestIntegrationParams) => {
async () => {
const result = await integrationTest(params)
if (params.expect) {
expect.assertions(0)
params.expect(result)
} else {
expect.assertions(3)
expect(result.logs).toMatchSnapshot(`logs`)
expect(result.graphqlSchemaSDL).toMatchSnapshot(`graphqlSchemaSDL`)
expect(result.graphqlOperationExecutionResult).toMatchSnapshot(`graphqlOperationExecutionResult`)
}
},
30_000
60_000
)
}

Expand All @@ -141,6 +144,7 @@ export const testGraphqlSchema = (
params: Pick<TestIntegrationParams, 'api' | 'description' | 'database'>
) => {
it(params.description, async () => {
expect.assertions(1)
const dmmf = await PrismaInternals.getDMMF({
datamodel: createPrismaSchema({
content: params.database,
Expand Down Expand Up @@ -192,21 +196,25 @@ export const integrationTest = async (params: TestIntegrationParams) => {
clientOutput: prismaClientOutputDir,
})

const cacheHit = fs.exists(prismaClientOutputDirAbsolute)
const cacheHit = await fs.existsAsync(prismaClientOutputDirAbsolute)
let dmmf: DMMF.Document

if (!cacheHit) {
fs.write(`${outputDirPath}/schema.prisma`, prismaSchemaContents)
execa.commandSync(`yarn -s prisma db push --force-reset --schema ${outputDirPath}/schema.prisma`)
fs.copy(sqliteDatabaseFileOutputAbsolute, `${sqliteDatabaseFileOutputAbsolute}.bak`)
await fs.writeAsync(`${outputDirPath}/schema.prisma`, prismaSchemaContents)
await execa.command(
`${getPackageManager()} -s prisma db push --force-reset --schema ${outputDirPath}/schema.prisma`
)
await fs.copyAsync(sqliteDatabaseFileOutputAbsolute, `${sqliteDatabaseFileOutputAbsolute}.bak`)
dmmf = await PrismaInternals.getDMMF({
datamodel: prismaSchemaContents,
})
fs.write(dmmfFileOutputAbsolute, dmmf)
await fs.writeAsync(dmmfFileOutputAbsolute, dmmf)
} else {
// restore empty database
fs.copy(`${sqliteDatabaseFileOutputAbsolute}.bak`, sqliteDatabaseFileOutputAbsolute, { overwrite: true })
dmmf = fs.read(dmmfFileOutputAbsolute, 'json')
await fs.copyAsync(`${sqliteDatabaseFileOutputAbsolute}.bak`, sqliteDatabaseFileOutputAbsolute, {
overwrite: true,
})
dmmf = await fs.readAsync(dmmfFileOutputAbsolute, 'json')
}

const prismaClientPackage = require(prismaClientOutputDirAbsolute)
Expand Down
55 changes: 28 additions & 27 deletions tests/__providers__/project.ts
Original file line number Diff line number Diff line change
@@ -1,39 +1,38 @@
import * as Execa from 'execa'
import { provider } from 'konn'
import { Providers } from 'konn/providers'
import { merge } from 'lodash'
import readPkgUp from 'read-pkg-up'
import { PackageJson, TsConfigJson } from 'type-fest'
import { assertBuildPresent } from '../__helpers__/helpers'
import type * as Run from './run'
import * as Package from '../../package.json'

type Project = {
thisPackageName: string
fixture: {
use(path: string): void
useAsync(path: string): Promise<void>
}
packageJson: {
merge(fields: PackageJson): void
create(fields: PackageJson): void
mergeAsync(fields: PackageJson): Promise<void>
createAsync(fields: PackageJson): Promise<void>
}
tsconfig: {
merge(fields: TsConfigJson): void
create(fields: TsConfigJson): void
mergeAsync(fields: TsConfigJson): Promise<void>
createAsync(fields: TsConfigJson): Promise<void>
}
}

export type Needs = Providers.Dir.Contributes & Providers.Run.Contributes
export type Needs = Providers.Dir.Contributes & Run.Contributes

export type Contributes = Project

export const project = () =>
provider<Needs, Contributes>()
.name('project')
.before((ctx) => {
.before(async (ctx) => {
assertBuildPresent()
Execa.commandSync(`yarn -s yalc publish --no-scripts`)

const thisPackageJson = readPkgUp.sync({ cwd: __dirname })?.packageJson
const thisPackageJson = (await readPkgUp({ cwd: __dirname }))?.packageJson

if (!thisPackageJson) {
throw new Error(`Failed to get own package.json`)
Expand All @@ -44,11 +43,14 @@ export const project = () =>
const api: Project = {
thisPackageName,
fixture: {
use: (path) => {
ctx.fs.copy(path, ctx.fs.cwd(), {
useAsync: async (path) => {
if (!process.env.CI) {
console.log('e2e project path:', ctx.fs.cwd())
}
await ctx.fs.copyAsync(path, ctx.fs.cwd(), {
overwrite: true,
})
api.packageJson.merge({
await api.packageJson.mergeAsync({
devDependencies: {
'@prisma/client': Package.devDependencies['@prisma/client'],
prisma: Package.devDependencies.prisma,
Expand All @@ -59,37 +61,36 @@ export const project = () =>
},
},
packageJson: {
create: (packageJson) => {
createAsync: async (packageJson) => {
const fileName = 'package.json'
ctx.fs.write(fileName, packageJson, { jsonIndent: 2 })
await ctx.fs.writeAsync(fileName, packageJson, { jsonIndent: 2 })
},
merge: (fields) => {
mergeAsync: async (fields) => {
const fileName = 'package.json'
const PackageJson = ctx.fs.read(fileName, 'json')
const PackageJson = await ctx.fs.readAsync(fileName, 'json')
const PackageJsonNew = merge(PackageJson, fields)
ctx.fs.write(fileName, PackageJsonNew, { jsonIndent: 2 })
await ctx.fs.writeAsync(fileName, PackageJsonNew, { jsonIndent: 2 })
},
},
tsconfig: {
create: (tsconfig) => {
createAsync: async (tsconfig) => {
const fileName = 'tsconfig.json'
ctx.fs.write(fileName, tsconfig, { jsonIndent: 2 })
await ctx.fs.writeAsync(fileName, tsconfig, { jsonIndent: 2 })
},
merge: (fields) => {
mergeAsync: async (fields) => {
const fileName = 'tsconfig.json'
const tsconfig = ctx.fs.read(fileName, 'json')
const tsconfig = await ctx.fs.readAsync(fileName, 'json')
const tsconfigNew = merge(tsconfig, fields)
ctx.fs.write(fileName, tsconfigNew, { jsonIndent: 2 })
await ctx.fs.writeAsync(fileName, tsconfigNew, { jsonIndent: 2 })
},
},
}

api.packageJson.create({
await api.packageJson.createAsync({
name: 'some-test-project',
version: '1.0.0',
})

api.tsconfig.create({
await api.tsconfig.createAsync({
compilerOptions: {
strict: true,
target: 'ES2018',
Expand All @@ -105,7 +106,7 @@ export const project = () =>
// d(`starting project setup`)
// Execa.commandSync(`yalc publish --no-scripts`)
// ctx.runOrThrow(`yalc add ${thisPackageName}`)
// ctx.runOrThrow(`npm install --legacy-peer-deps`)
// ctx.runOrThrow(`yarn install --legacy-peer-deps`)
// d(`done project setup`)

return api
Expand Down
Loading

0 comments on commit 754a70e

Please sign in to comment.