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

Move unit tests to one folder and migrate them to TypeScript #28427

Merged
merged 7 commits into from Aug 24, 2021
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/build_test_deploy.yml
Expand Up @@ -104,7 +104,7 @@ jobs:
path: ./*
key: ${{ github.sha }}

- run: node run-tests.js --timings --type unit -g 1/1
- run: node run-tests.js --type unit
if: ${{needs.build.outputs.docsChange != 'docs only change'}}

testIntegration:
Expand Down
2 changes: 1 addition & 1 deletion azure-pipelines.yml
Expand Up @@ -111,7 +111,7 @@ stages:
path: $(System.DefaultWorkingDirectory)
displayName: Cache Build
- script: |
node run-tests.js -g 1/1 --timings --azure --type unit
node run-tests.js --type unit
displayName: 'Run tests'
# TODO: investigate re-enabling when stability matches running in
# tests in ubuntu environment
Expand Down
Empty file removed data.sqlite
Empty file.
2 changes: 1 addition & 1 deletion jest.config.js
@@ -1,5 +1,5 @@
module.exports = {
testMatch: ['**/*.test.js'],
testMatch: ['**/*.test.js', '**/*.test.ts', '**/*.test.tsx'],
verbose: true,
rootDir: 'test',
modulePaths: ['<rootDir>/lib'],
Expand Down
14 changes: 5 additions & 9 deletions package.json
Expand Up @@ -10,22 +10,18 @@
"lerna": "lerna",
"dev": "lerna run dev --stream --parallel",
"dev2": "while true; do yarn --check-files && yarn dev; done",
"testonly": "jest --runInBand",
"test-types": "yarn tsc",
"test-unit": "yarn jest test/unit/",
"testonly": "yarn jest --runInBand",
"testheadless": "cross-env HEADLESS=true yarn testonly",
"testsafari": "cross-env BROWSER_NAME=safari yarn testonly",
"testfirefox": "cross-env BROWSER_NAME=firefox yarn testonly",
"testie": "cross-env BROWSER_NAME=\"internet explorer\" yarn testonly",
"testall": "yarn run testonly -- --ci --forceExit && lerna run --scope @next/codemod test",
"testall": "yarn test -- --ci --forceExit && lerna run --scope @next/codemod test",
"genstats": "cross-env LOCAL_STATS=true node .github/actions/next-stats-action/src/index.js",
"pretest": "yarn run lint",
"git-reset": "git reset --hard HEAD",
"git-clean": "git clean -d -x -e node_modules -e packages -f",
"test-take2": "yarn git-reset && yarn git-clean && yarn testall",
"test": "yarn run testall || yarn run test-take2",
"lint-typescript": "lerna run typescript",
"lint-eslint": "eslint . --ext js,jsx,ts,tsx --max-warnings=0",
"lint-no-typescript": "run-p prettier-check lint-eslint",
"lint": "run-p lint-typescript prettier-check lint-eslint lint-language",
"lint": "run-p test-types lint-typescript prettier-check lint-eslint lint-language",
"lint-fix": "yarn prettier-fix && eslint . --ext js,jsx,ts,tsx --fix --max-warnings=0",
"lint-language": "alex .",
"prettier-check": "prettier --check .",
Expand Down
75 changes: 40 additions & 35 deletions run-tests.js
Expand Up @@ -12,16 +12,12 @@ const glob = promisify(_glob)
const exec = promisify(execOrig)

const timings = []
const NUM_RETRIES = 2
const DEFAULT_NUM_RETRIES = 2
const DEFAULT_CONCURRENCY = 2
const RESULTS_EXT = `.results.json`
const isTestJob = !!process.env.NEXT_TEST_JOB
const TIMINGS_API = `https://next-timings.jjsweb.site/api/timings`

const UNIT_TEST_EXT = '.unit.test.js'
const DEV_TEST_EXT = '.dev.test.js'
const PROD_TEST_EXT = '.prod.test.js'

const NON_CONCURRENT_TESTS = [
'test/integration/basic/test/index.test.js',
'test/acceptance/ReactRefresh.dev.test.js',
Expand All @@ -30,12 +26,17 @@ const NON_CONCURRENT_TESTS = [
'test/acceptance/ReactRefreshRequire.dev.test.js',
]

const testFilters = {
unit: 'unit/',
}

// which types we have configured to run separate
const configuredTestTypes = [UNIT_TEST_EXT]
const configuredTestTypes = Object.values(testFilters)

async function main() {
let numRetries = DEFAULT_NUM_RETRIES
let concurrencyIdx = process.argv.indexOf('-c')
const concurrency =
let concurrency =
parseInt(process.argv[concurrencyIdx + 1], 10) || DEFAULT_CONCURRENCY

const outputTimings = process.argv.indexOf('--timings') !== -1
Expand All @@ -50,15 +51,17 @@ async function main() {
let filterTestsBy

switch (testType) {
case 'unit':
filterTestsBy = UNIT_TEST_EXT
break
case 'dev':
filterTestsBy = DEV_TEST_EXT
break
case 'production':
filterTestsBy = PROD_TEST_EXT
case 'unit': {
numRetries = 0
filterTestsBy = testFilters.unit
break
}
// case 'dev':
// filterTestsBy = DEV_TEST_EXT
// break
// case 'production':
// filterTestsBy = PROD_TEST_EXT
// break
case 'all':
filterTestsBy = 'none'
break
Expand All @@ -67,22 +70,22 @@ async function main() {
}

console.log('Running tests with concurrency:', concurrency)
let tests = process.argv.filter((arg) => arg.endsWith('.test.js'))
let tests = process.argv.filter((arg) => arg.match(/\.test\.(js|ts|tsx)/))
let prevTimings

if (tests.length === 0) {
tests = (
await glob('**/*.test.js', {
await glob('**/*.test.{js,ts,tsx}', {
nodir: true,
cwd: path.join(__dirname, 'test'),
})
).filter((test) => {
// only include the specified type
if (filterTestsBy) {
return filterTestsBy === 'none' ? true : test.endsWith(filterTestsBy)
// include all except the separately configured types
// only include the specified type
return filterTestsBy === 'none' ? true : test.startsWith(filterTestsBy)
} else {
return !configuredTestTypes.some((type) => test.endsWith(type))
// include all except the separately configured types
return !configuredTestTypes.some((type) => test.startsWith(type))
}
})

Expand Down Expand Up @@ -183,7 +186,7 @@ async function main() {
)
const children = new Set()

const runTest = (test = '', usePolling) =>
const runTest = (test = '', usePolling, isFinalRun) =>
new Promise((resolve, reject) => {
const start = new Date().getTime()
let outputChunks = []
Expand Down Expand Up @@ -232,7 +235,9 @@ async function main() {
child.on('exit', (code) => {
children.delete(child)
if (code) {
outputChunks.forEach((chunk) => process.stdout.write(chunk))
if (isFinalRun) {
outputChunks.forEach((chunk) => process.stdout.write(chunk))
}
reject(new Error(`failed with code: ${code}`))
}
resolve(new Date().getTime() - start)
Expand All @@ -254,21 +259,21 @@ async function main() {
for (const test of nonConcurrentTestNames) {
let passed = false

for (let i = 0; i < NUM_RETRIES + 1; i++) {
for (let i = 0; i < numRetries + 1; i++) {
try {
console.log(`Starting ${test} retry ${i}/${NUM_RETRIES}`)
const time = await runTest(test, i > 0)
console.log(`Starting ${test} retry ${i}/${numRetries}`)
const time = await runTest(test, i > 0, i === numRetries)
timings.push({
file: test,
time,
})
passed = true
console.log(
`Finished ${test} on retry ${i}/${NUM_RETRIES} in ${time / 1000}s`
`Finished ${test} on retry ${i}/${numRetries} in ${time / 1000}s`
)
break
} catch (err) {
if (i < NUM_RETRIES) {
if (i < numRetries) {
try {
const testDir = path.dirname(path.join(__dirname, test))
console.log('Cleaning test files at', testDir)
Expand All @@ -279,7 +284,7 @@ async function main() {
}
}
if (!passed) {
console.error(`${test} failed to pass within ${NUM_RETRIES} retries`)
console.error(`${test} failed to pass within ${numRetries} retries`)
children.forEach((child) => child.kill())

if (isTestJob) {
Expand All @@ -303,21 +308,21 @@ async function main() {
await sema.acquire()
let passed = false

for (let i = 0; i < NUM_RETRIES + 1; i++) {
for (let i = 0; i < numRetries + 1; i++) {
try {
console.log(`Starting ${test} retry ${i}/${NUM_RETRIES}`)
const time = await runTest(test, i > 0)
console.log(`Starting ${test} retry ${i}/${numRetries}`)
const time = await runTest(test, i > 0, i === numRetries)
timings.push({
file: test,
time,
})
passed = true
console.log(
`Finished ${test} on retry ${i}/${NUM_RETRIES} in ${time / 1000}s`
`Finished ${test} on retry ${i}/${numRetries} in ${time / 1000}s`
)
break
} catch (err) {
if (i < NUM_RETRIES) {
if (i < numRetries) {
try {
const testDir = path.dirname(path.join(__dirname, test))
console.log('Cleaning test files at', testDir)
Expand All @@ -328,7 +333,7 @@ async function main() {
}
}
if (!passed) {
console.error(`${test} failed to pass within ${NUM_RETRIES} retries`)
console.error(`${test} failed to pass within ${numRetries} retries`)
children.forEach((child) => child.kill())

if (isTestJob) {
Expand Down
14 changes: 0 additions & 14 deletions test/tsconfig.json

This file was deleted.

@@ -1,7 +1,6 @@
const rule = require('@next/eslint-plugin-next/lib/rules/google-font-display')
const RuleTester = require('eslint').RuleTester

RuleTester.setDefaultConfig({
import rule from '@next/eslint-plugin-next/lib/rules/google-font-display'
import { RuleTester } from 'eslint'
;(RuleTester as any).setDefaultConfig({
parserOptions: {
ecmaVersion: 2020,
sourceType: 'module',
Expand All @@ -11,8 +10,8 @@ RuleTester.setDefaultConfig({
},
},
})
const ruleTester = new RuleTester()

var ruleTester = new RuleTester()
ruleTester.run('google-font-display', rule, {
valid: [
`import Head from "next/head";
Expand Down
@@ -1,7 +1,6 @@
const rule = require('@next/eslint-plugin-next/lib/rules/google-font-preconnect')
const RuleTester = require('eslint').RuleTester

RuleTester.setDefaultConfig({
import rule from '@next/eslint-plugin-next/lib/rules/google-font-preconnect'
import { RuleTester } from 'eslint'
;(RuleTester as any).setDefaultConfig({
parserOptions: {
ecmaVersion: 2020,
sourceType: 'module',
Expand All @@ -11,8 +10,8 @@ RuleTester.setDefaultConfig({
},
},
})
const ruleTester = new RuleTester()

var ruleTester = new RuleTester()
ruleTester.run('google-font-preconnect', rule, {
valid: [
`export const Test = () => (
Expand Down
@@ -1,8 +1,6 @@
const rule = require('@next/eslint-plugin-next/lib/rules/inline-script-id')

const RuleTester = require('eslint').RuleTester

RuleTester.setDefaultConfig({
import rule from '@next/eslint-plugin-next/lib/rules/inline-script-id'
import { RuleTester } from 'eslint'
;(RuleTester as any).setDefaultConfig({
parserOptions: {
ecmaVersion: 2018,
sourceType: 'module',
Expand Down
@@ -1,7 +1,6 @@
const rule = require('@next/eslint-plugin-next/lib/rules/link-passhref')
const RuleTester = require('eslint').RuleTester

RuleTester.setDefaultConfig({
import rule from '@next/eslint-plugin-next/lib/rules/link-passhref'
import { RuleTester } from 'eslint'
;(RuleTester as any).setDefaultConfig({
parserOptions: {
ecmaVersion: 2018,
sourceType: 'module',
Expand All @@ -11,8 +10,8 @@ RuleTester.setDefaultConfig({
},
},
})
const ruleTester = new RuleTester()

var ruleTester = new RuleTester()
ruleTester.run('link-passhref', rule, {
valid: [
`export const Home = () => (
Expand Down
@@ -1,11 +1,6 @@
const rule = require('@next/eslint-plugin-next/lib/rules/next-script-for-ga')

const RuleTester = require('eslint').RuleTester

const ERROR_MSG =
'Use the `next/script` component for loading third party scripts. See: https://nextjs.org/docs/messages/next-script-for-ga.'

RuleTester.setDefaultConfig({
import rule from '@next/eslint-plugin-next/lib/rules/next-script-for-ga'
import { RuleTester } from 'eslint'
;(RuleTester as any).setDefaultConfig({
parserOptions: {
ecmaVersion: 2018,
sourceType: 'module',
Expand All @@ -16,7 +11,11 @@ RuleTester.setDefaultConfig({
},
})

var ruleTester = new RuleTester()
const ERROR_MSG =
'Use the `next/script` component for loading third party scripts. See: https://nextjs.org/docs/messages/next-script-for-ga.'

const ruleTester = new RuleTester()

ruleTester.run('sync-scripts', rule, {
valid: [
`import Script from 'next/script'
Expand Down
@@ -1,7 +1,6 @@
const rule = require('@next/eslint-plugin-next/lib/rules/no-css-tags')
const RuleTester = require('eslint').RuleTester

RuleTester.setDefaultConfig({
import rule from '@next/eslint-plugin-next/lib/rules/no-css-tags'
import { RuleTester } from 'eslint'
;(RuleTester as any).setDefaultConfig({
parserOptions: {
ecmaVersion: 2018,
sourceType: 'module',
Expand All @@ -11,8 +10,8 @@ RuleTester.setDefaultConfig({
},
},
})
const ruleTester = new RuleTester()

var ruleTester = new RuleTester()
ruleTester.run('no-css-tags', rule, {
valid: [
`import {Head} from 'next/document';
Expand Down
@@ -1,8 +1,6 @@
const rule = require('@next/eslint-plugin-next/lib/rules/no-document-import-in-page')

const RuleTester = require('eslint').RuleTester

RuleTester.setDefaultConfig({
import rule from '@next/eslint-plugin-next/lib/rules/no-document-import-in-page'
import { RuleTester } from 'eslint'
;(RuleTester as any).setDefaultConfig({
parserOptions: {
ecmaVersion: 2018,
sourceType: 'module',
Expand All @@ -12,8 +10,8 @@ RuleTester.setDefaultConfig({
},
},
})
const ruleTester = new RuleTester()

var ruleTester = new RuleTester()
ruleTester.run('no-document-import-in-page', rule, {
valid: [
{
Expand Down