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

* Move unit tests to one folder

* Migrate unit tests to TypeScript

* add test types to lint

* Ensure ts(x) tests are run with util

* Add tsx extension to jest config

* bump
This commit is contained in:
JJ Kasper 2021-08-24 07:52:45 -05:00 committed by GitHub
parent 6072afc83a
commit 005b13f1ac
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
99 changed files with 202 additions and 214 deletions

View file

@ -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:

View file

@ -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

View file

View file

@ -1,5 +1,5 @@
module.exports = {
testMatch: ['**/*.test.js'],
testMatch: ['**/*.test.js', '**/*.test.ts', '**/*.test.tsx'],
verbose: true,
rootDir: 'test',
modulePaths: ['<rootDir>/lib'],

View file

@ -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 .",

View file

@ -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',
@ -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
@ -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
@ -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))
}
})
@ -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 = []
@ -232,7 +235,9 @@ async function main() {
child.on('exit', (code) => {
children.delete(child)
if (code) {
if (isFinalRun) {
outputChunks.forEach((chunk) => process.stdout.write(chunk))
}
reject(new Error(`failed with code: ${code}`))
}
resolve(new Date().getTime() - start)
@ -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)
@ -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) {
@ -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)
@ -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) {

View file

@ -1,14 +0,0 @@
{
"compilerOptions": {
"module": "esnext",
"target": "es6",
"allowJs": true,
"noEmit": true,
"baseUrl": "../",
"paths": {
"next-test-utils": ["./test/lib/next-test-utils"],
"amp-test-utils": ["./test/lib/amp-test-utils"],
"next-webdriver": ["./test/lib/next-webdriver"]
}
}
}

View file

@ -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',
@ -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";

View file

@ -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',
@ -11,8 +10,8 @@ RuleTester.setDefaultConfig({
},
},
})
const ruleTester = new RuleTester()
var ruleTester = new RuleTester()
ruleTester.run('google-font-preconnect', rule, {
valid: [
`export const Test = () => (

View file

@ -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',

View file

@ -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',
@ -11,8 +10,8 @@ RuleTester.setDefaultConfig({
},
},
})
const ruleTester = new RuleTester()
var ruleTester = new RuleTester()
ruleTester.run('link-passhref', rule, {
valid: [
`export const Home = () => (

View file

@ -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',
@ -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'

View file

@ -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',
@ -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';

View file

@ -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',
@ -12,8 +10,8 @@ RuleTester.setDefaultConfig({
},
},
})
const ruleTester = new RuleTester()
var ruleTester = new RuleTester()
ruleTester.run('no-document-import-in-page', rule, {
valid: [
{

View file

@ -1,8 +1,6 @@
const rule = require('@next/eslint-plugin-next/lib/rules/no-duplicate-head')
const RuleTester = require('eslint').RuleTester
RuleTester.setDefaultConfig({
import rule from '@next/eslint-plugin-next/lib/rules/no-duplicate-head'
import { RuleTester } from 'eslint'
;(RuleTester as any).setDefaultConfig({
parserOptions: {
ecmaVersion: 2018,
sourceType: 'module',
@ -12,8 +10,8 @@ RuleTester.setDefaultConfig({
},
},
})
const ruleTester = new RuleTester()
var ruleTester = new RuleTester()
ruleTester.run('no-duplicate-head', rule, {
valid: [
{

View file

@ -1,8 +1,6 @@
const rule = require('@next/eslint-plugin-next/lib/rules/no-head-import-in-document')
const RuleTester = require('eslint').RuleTester
RuleTester.setDefaultConfig({
import rule from '@next/eslint-plugin-next/lib/rules/no-head-import-in-document'
import { RuleTester } from 'eslint'
;(RuleTester as any).setDefaultConfig({
parserOptions: {
ecmaVersion: 2018,
sourceType: 'module',
@ -12,8 +10,8 @@ RuleTester.setDefaultConfig({
},
},
})
const ruleTester = new RuleTester()
var ruleTester = new RuleTester()
ruleTester.run('no-head-import-in-document', rule, {
valid: [
{

View file

@ -1,11 +1,11 @@
/* eslint-env jest */
const rule = require('@next/eslint-plugin-next/lib/rules/no-html-link-for-pages')
const { Linter } = require('eslint')
const assert = require('assert')
const path = require('path')
import rule from '@next/eslint-plugin-next/lib/rules/no-html-link-for-pages'
import { Linter } from 'eslint'
import assert from 'assert'
import path from 'path'
const linter = new Linter({ cwd: __dirname })
const linterConfig = {
const linterConfig: any = {
rules: {
'no-html-link-for-pages': [2, path.join(__dirname, 'custom-pages')],
},

View file

@ -1,8 +1,6 @@
const rule = require('@next/eslint-plugin-next/lib/rules/no-img-element')
const RuleTester = require('eslint').RuleTester
RuleTester.setDefaultConfig({
import rule from '@next/eslint-plugin-next/lib/rules/no-img-element'
import { RuleTester } from 'eslint'
;(RuleTester as any).setDefaultConfig({
parserOptions: {
ecmaVersion: 2018,
sourceType: 'module',
@ -12,8 +10,8 @@ RuleTester.setDefaultConfig({
},
},
})
const ruleTester = new RuleTester()
var ruleTester = new RuleTester()
ruleTester.run('no-img-element', rule, {
valid: [
`import { Image } from 'next/image';

View file

@ -1,9 +1,8 @@
const rule = require('@next/eslint-plugin-next/lib/rules/no-page-custom-font')
const RuleTester = require('eslint').RuleTester
RuleTester.setDefaultConfig({
import rule from '@next/eslint-plugin-next/lib/rules/no-page-custom-font'
import { RuleTester } from 'eslint'
;(RuleTester as any).setDefaultConfig({
parserOptions: {
ecmaVersion: 2020,
ecmaVersion: 2018,
sourceType: 'module',
ecmaFeatures: {
modules: true,
@ -11,8 +10,8 @@ RuleTester.setDefaultConfig({
},
},
})
const ruleTester = new RuleTester()
var ruleTester = new RuleTester()
ruleTester.run('no-page-custom-font', rule, {
valid: [
`import Document, { Html, Head } from "next/document";

View file

@ -1,8 +1,6 @@
const rule = require('@next/eslint-plugin-next/lib/rules/no-script-in-document')
const RuleTester = require('eslint').RuleTester
RuleTester.setDefaultConfig({
import rule from '@next/eslint-plugin-next/lib/rules/no-script-in-document'
import { RuleTester } from 'eslint'
;(RuleTester as any).setDefaultConfig({
parserOptions: {
ecmaVersion: 2018,
sourceType: 'module',
@ -12,8 +10,8 @@ RuleTester.setDefaultConfig({
},
},
})
const ruleTester = new RuleTester()
var ruleTester = new RuleTester()
ruleTester.run('no-script-import-in-document', rule, {
valid: [
{

View file

@ -1,7 +1,6 @@
const rule = require('@next/eslint-plugin-next/lib/rules/no-script-in-head.js')
const RuleTester = require('eslint').RuleTester
RuleTester.setDefaultConfig({
import rule from '@next/eslint-plugin-next/lib/rules/no-script-in-head'
import { RuleTester } from 'eslint'
;(RuleTester as any).setDefaultConfig({
parserOptions: {
ecmaVersion: 2018,
sourceType: 'module',
@ -11,8 +10,8 @@ RuleTester.setDefaultConfig({
},
},
})
const ruleTester = new RuleTester()
var ruleTester = new RuleTester()
ruleTester.run('no-script-in-head', rule, {
valid: [
`import Script from "next/script";

View file

@ -1,8 +1,6 @@
const rule = require('@next/eslint-plugin-next/lib/rules/no-sync-scripts')
const RuleTester = require('eslint').RuleTester
RuleTester.setDefaultConfig({
import rule from '@next/eslint-plugin-next/lib/rules/no-sync-scripts'
import { RuleTester } from 'eslint'
;(RuleTester as any).setDefaultConfig({
parserOptions: {
ecmaVersion: 2018,
sourceType: 'module',
@ -12,8 +10,8 @@ RuleTester.setDefaultConfig({
},
},
})
const ruleTester = new RuleTester()
var ruleTester = new RuleTester()
ruleTester.run('sync-scripts', rule, {
valid: [
`import {Head} from 'next/document';

View file

@ -1,7 +1,6 @@
const rule = require('@next/eslint-plugin-next/lib/rules/no-title-in-document-head')
const RuleTester = require('eslint').RuleTester
RuleTester.setDefaultConfig({
import rule from '@next/eslint-plugin-next/lib/rules/no-title-in-document-head'
import { RuleTester } from 'eslint'
;(RuleTester as any).setDefaultConfig({
parserOptions: {
ecmaVersion: 2018,
sourceType: 'module',
@ -11,8 +10,8 @@ RuleTester.setDefaultConfig({
},
},
})
const ruleTester = new RuleTester()
var ruleTester = new RuleTester()
ruleTester.run('no-title-in-document-head', rule, {
valid: [
`import Head from "next/head";

View file

@ -1,8 +1,6 @@
const rule = require('@next/eslint-plugin-next/lib/rules/no-typos')
const RuleTester = require('eslint').RuleTester
RuleTester.setDefaultConfig({
import rule from '@next/eslint-plugin-next/lib/rules/no-typos'
import { RuleTester } from 'eslint'
;(RuleTester as any).setDefaultConfig({
parserOptions: {
ecmaVersion: 2018,
sourceType: 'module',
@ -13,7 +11,8 @@ RuleTester.setDefaultConfig({
},
})
var ruleTester = new RuleTester()
const ruleTester = new RuleTester()
ruleTester.run('no-typos', rule, {
valid: [
`

View file

@ -1,8 +1,6 @@
const rule = require('@next/eslint-plugin-next/lib/rules/no-unwanted-polyfillio')
const RuleTester = require('eslint').RuleTester
RuleTester.setDefaultConfig({
import rule from '@next/eslint-plugin-next/lib/rules/no-unwanted-polyfillio'
import { RuleTester } from 'eslint'
;(RuleTester as any).setDefaultConfig({
parserOptions: {
ecmaVersion: 2018,
sourceType: 'module',
@ -12,8 +10,8 @@ RuleTester.setDefaultConfig({
},
},
})
const ruleTester = new RuleTester()
var ruleTester = new RuleTester()
ruleTester.run('unwanted-polyfillsio', rule, {
valid: [
`import {Head} from 'next/document';

View file

@ -4,7 +4,7 @@ import { normalizePagePath } from 'next/dist/server/normalize-page-path'
import { join } from 'path'
const resolveDataDir = join(__dirname, '..', 'isolated', '_resolvedata')
const resolveDataDir = join(__dirname, 'isolated', '_resolvedata')
const dirWithPages = join(resolveDataDir, 'readdir', 'pages')
describe('findPageFile', () => {

View file

@ -25,6 +25,6 @@ describe('getDisplayName', () => {
expect(getDisplayName(ComponentTwo)).toBe('CustomDisplayName')
expect(getDisplayName(FunctionalComponent)).toBe('FunctionalComponent')
expect(getDisplayName(() => null)).toBe('Unknown')
expect(getDisplayName('div')).toBe('div')
expect(getDisplayName('div' as any)).toBe('div')
})
})

View file

@ -1,5 +1,5 @@
/* eslint-env jest */
import { detectContentType } from '../../../../packages/next/dist/server/image-optimizer.js'
import { detectContentType } from 'next/dist/server/image-optimizer'
import { readFile } from 'fs-extra'
import { join } from 'path'
@ -7,19 +7,19 @@ const getImage = (filepath) => readFile(join(__dirname, filepath))
describe('detectContentType', () => {
it('should return jpg', async () => {
const buffer = await getImage('../app/public/test.jpg')
const buffer = await getImage('./images/test.jpg')
expect(detectContentType(buffer)).toBe('image/jpeg')
})
it('should return png', async () => {
const buffer = await getImage('../app/public/test.png')
const buffer = await getImage('./images/test.png')
expect(detectContentType(buffer)).toBe('image/png')
})
it('should return webp', async () => {
const buffer = await getImage('../app/public/animated.webp')
const buffer = await getImage('./images/animated.webp')
expect(detectContentType(buffer)).toBe('image/webp')
})
it('should return svg', async () => {
const buffer = await getImage('../app/public/test.svg')
const buffer = await getImage('./images/test.svg')
expect(detectContentType(buffer)).toBe('image/svg+xml')
})
})

View file

@ -1,5 +1,5 @@
/* eslint-env jest */
import { getMaxAge } from '../../../../packages/next/dist/server/image-optimizer.js'
import { getMaxAge } from 'next/dist/server/image-optimizer'
describe('getMaxAge', () => {
it('should return 0 when no cache-control provided', () => {

Binary file not shown.

After

Width:  |  Height:  |  Size: 36 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

View file

@ -0,0 +1,13 @@
<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 20010904//EN"
"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
<svg version="1.0" xmlns="http://www.w3.org/2000/svg"
width="400" height="400" viewBox="0 0 400 400"
preserveAspectRatio="xMidYMid meet">
<g transform="translate(0.000000,400.000000) scale(0.100000,-0.100000)"
fill="#000000" stroke="none">
<path d="M0 2000 l0 -2000 2000 0 2000 0 0 2000 0 2000 -2000 0 -2000 0 0
-2000z m2401 118 l396 -693 -398 -3 c-220 -1 -578 -1 -798 0 l-398 3 396 693
c217 380 398 692 401 692 3 0 184 -312 401 -692z"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 603 B

View file

@ -175,7 +175,7 @@ describe('isSerializableProps', () => {
})
it('can handle obj circular refs', () => {
const obj = { foo: 'bar', test: true }
const obj: any = { foo: 'bar', test: true }
obj.child = obj
expect(() => isSerializableProps('/', 'test', obj))
@ -192,7 +192,7 @@ describe('isSerializableProps', () => {
})
it('can handle arr circular refs', () => {
const arr = [{ foo: 'bar' }, true]
const arr: any = [{ foo: 'bar' }, true]
arr.push(arr)
expect(() => isSerializableProps('/', 'test', { arr }))
@ -209,7 +209,7 @@ describe('isSerializableProps', () => {
})
it('can handle deep obj circular refs', () => {
const obj = { foo: 'bar', test: true, leve1: { level2: {} } }
const obj: any = { foo: 'bar', test: true, leve1: { level2: {} } }
obj.leve1.level2.child = obj
expect(() => isSerializableProps('/', 'test', obj))
@ -220,7 +220,7 @@ describe('isSerializableProps', () => {
})
it('can handle deep obj circular refs (with arrays)', () => {
const obj = { foo: 'bar', test: true, leve1: { level2: {} } }
const obj: any = { foo: 'bar', test: true, leve1: { level2: {} } }
obj.leve1.level2.child = [{ another: [obj] }]
expect(() => isSerializableProps('/', 'test', obj))

View file

@ -1,13 +1,13 @@
/* eslint-env jest */
import { join } from 'path'
import { normalizePagePath } from 'next/dist/server/normalize-page-path'
import { SERVER_DIRECTORY, CLIENT_STATIC_FILES_PATH } from 'next/constants'
import {
requirePage,
getPagePath,
pageNotFoundError,
} from 'next/dist/server/require'
import { normalizePagePath } from 'next/dist/server/normalize-page-path'
const sep = '/'
const distDir = join(__dirname, '_resolvedata')
@ -55,42 +55,42 @@ describe('normalizePagePath', () => {
describe('getPagePath', () => {
it('Should not append /index to the / page', () => {
expect(() => getPagePath('/', distDir)).toThrow(
expect(() => getPagePath('/', distDir, false)).toThrow(
'Cannot find module for page: /'
)
})
it('Should prepend / when a page does not have it', () => {
const pagePath = getPagePath('_error', distDir)
const pagePath = getPagePath('_error', distDir, false)
expect(pagePath).toBe(join(pathToBundles, `${sep}_error.js`))
})
it('Should throw with paths containing ../', () => {
expect(() => getPagePath('/../../package.json', distDir)).toThrow()
expect(() => getPagePath('/../../package.json', distDir, false)).toThrow()
})
})
describe('requirePage', () => {
it('Should not find page /index when using /', async () => {
await expect(() => requirePage('/', distDir)).toThrow(
await expect(() => requirePage('/', distDir, false)).toThrow(
'Cannot find module for page: /'
)
})
it('Should require /index.js when using /index', async () => {
const page = await requirePage('/index', distDir)
const page = await requirePage('/index', distDir, false)
expect(page.test).toBe('hello')
})
it('Should require /world.js when using /world', async () => {
const page = await requirePage('/world', distDir)
const page = await requirePage('/world', distDir, false)
expect(page.test).toBe('world')
})
it('Should throw when using /../../test.js', async () => {
expect.assertions(1)
try {
await requirePage('/../../test', distDir)
await requirePage('/../../test', distDir, false)
} catch (err) {
// eslint-disable-next-line jest/no-try-expect
expect(err.code).toBe('ENOENT')
@ -100,7 +100,7 @@ describe('requirePage', () => {
it('Should throw when using non existent pages like /non-existent.js', async () => {
expect.assertions(1)
try {
await requirePage('/non-existent', distDir)
await requirePage('/non-existent', distDir, false)
} catch (err) {
// eslint-disable-next-line jest/no-try-expect
expect(err.code).toBe('ENOENT')
@ -110,7 +110,7 @@ describe('requirePage', () => {
it('Should bubble up errors in the child component', async () => {
expect.assertions(1)
try {
await requirePage('/non-existent-child', distDir)
await requirePage('/non-existent-child', distDir, false)
} catch (err) {
// eslint-disable-next-line jest/no-try-expect
expect(err.code).toBe('MODULE_NOT_FOUND')

View file

@ -6,7 +6,7 @@ describe('loadGetInitialProps', () => {
class TestComponent {
getInitialProps() {}
}
const rejectPromise = loadGetInitialProps(TestComponent, {})
const rejectPromise = loadGetInitialProps(TestComponent as any, {})
const error = new Error(
'"TestComponent.getInitialProps()" is defined as an instance method - visit https://nextjs.org/docs/messages/get-initial-props-as-an-instance-method for more information.'
)
@ -14,7 +14,7 @@ describe('loadGetInitialProps', () => {
})
it('should resolve to an empty object if getInitialProps is missing', async () => {
const result = await loadGetInitialProps(() => {}, {})
const result = await loadGetInitialProps((() => {}) as any, {})
expect(result).toEqual({})
})
@ -24,7 +24,7 @@ describe('loadGetInitialProps', () => {
return { foo: 1 }
}
}
const result = await loadGetInitialProps(TestComponent, {})
const result = await loadGetInitialProps(TestComponent as any, {})
expect(result).toEqual({ foo: 1 })
})
@ -34,12 +34,12 @@ describe('loadGetInitialProps', () => {
return 'invalidValue'
}
}
const ctx = {
const ctx: any = {
res: {
finished: true,
},
}
const result = await loadGetInitialProps(TestComponent, ctx)
const result = await loadGetInitialProps(TestComponent as any, ctx)
expect(result).toBe('invalidValue')
})
@ -47,7 +47,7 @@ describe('loadGetInitialProps', () => {
class TestComponent {
static async getInitialProps() {}
}
const rejectPromise = loadGetInitialProps(TestComponent, {})
const rejectPromise = loadGetInitialProps(TestComponent as any, {})
const error = new Error(
'"TestComponent.getInitialProps()" should resolve to an object. But found "undefined" instead.'
)

View file

@ -1,17 +1,11 @@
/* eslint-env jest */
function interopRequireDefault(mod) {
return mod.default || mod
}
const loader = interopRequireDefault(
require('next/dist/build/webpack/loaders/next-babel-loader')
)
const os = require('os')
const path = require('path')
import os from 'os'
import path from 'path'
import loader from 'next/dist/build/webpack/loaders/next-babel-loader'
const dir = path.resolve(os.tmpdir())
const babel = async (code, queryOpts = {}) => {
const babel = async (code: string, queryOpts = {} as any) => {
const {
isServer = false,
resourcePath = 'index.js',
@ -19,7 +13,7 @@ const babel = async (code, queryOpts = {}) => {
} = queryOpts
let isAsync = false
return new Promise((resolve, reject) => {
return new Promise<string>((resolve, reject) => {
function callback(err, content) {
if (err) {
reject(err)

View file

@ -1,10 +1,10 @@
/* eslint-env jest */
import { transform } from '@babel/core'
import { transformSync } from '@babel/core'
const trim = (s) => s.join('\n').trim().replace(/^\s+/gm, '')
const babel = (code, esm = false, presetOptions = {}, filename = 'noop.js') =>
transform(code, {
transformSync(code, {
filename,
presets: [[require('next/dist/build/babel/preset'), presetOptions]],
babelrc: false,
@ -16,7 +16,7 @@ const babel = (code, esm = false, presetOptions = {}, filename = 'noop.js') =>
supportsStaticESM: esm,
isDev: false,
},
}).code
} as any).code
describe('next/babel', () => {
describe('jsx-pragma', () => {

View file

@ -9,7 +9,7 @@ describe('Rendering next/head', () => {
React.createElement(
React.Fragment,
{},
React.createElement(Head, {}),
React.createElement(Head),
React.createElement('p', {}, 'hello world')
)
)

View file

@ -4,7 +4,7 @@ import { parseRelativeUrl } from 'next/dist/shared/lib/router/utils/parse-relati
// convenience function so tests can be aligned neatly
// and easy to eyeball
const check = (windowUrl, targetUrl, expected) => {
window.location = new URL(windowUrl)
window.location = new URL(windowUrl) as any
if (typeof expected === 'string') {
expect(() => parseRelativeUrl(targetUrl)).toThrow(expected)
} else {
@ -17,13 +17,13 @@ const check = (windowUrl, targetUrl, expected) => {
describe('parseRelativeUrl', () => {
beforeAll(() => {
global.window = {
;(global as any).window = {
location: {},
}
})
afterAll(() => {
delete global.window
delete (global as any).window
})
it('should parse relative url', () => {

View file

@ -4,9 +4,9 @@ import { recursiveReadDir } from 'next/dist/lib/recursive-readdir'
import { recursiveCopy } from 'next/dist/lib/recursive-copy'
import { join } from 'path'
const resolveDataDir = join(__dirname, '..', 'isolated', '_resolvedata')
const testResolveDataDir = join(__dirname, '..', 'isolated', 'test_resolvedata')
const testpreservefileDir = join(__dirname, '..', 'isolated', 'preservefiles')
const resolveDataDir = join(__dirname, 'isolated', '_resolvedata')
const testResolveDataDir = join(__dirname, 'isolated', 'test_resolvedata')
const testpreservefileDir = join(__dirname, 'isolated', 'preservefiles')
describe('recursiveDelete', () => {
it('should work', async () => {

View file

@ -3,7 +3,7 @@
import { recursiveReadDir } from 'next/dist/lib/recursive-readdir'
import { join } from 'path'
const resolveDataDir = join(__dirname, '..', 'isolated', '_resolvedata')
const resolveDataDir = join(__dirname, 'isolated', '_resolvedata')
const dirWithPages = join(resolveDataDir, 'readdir', 'pages')
jest.setTimeout(1000 * 60 * 5)

19
tsconfig.json Normal file
View file

@ -0,0 +1,19 @@
{
"compilerOptions": {
"strict": false,
"noEmit": true,
"allowJs": true,
"jsx": "react",
"module": "esnext",
"skipLibCheck": true,
"esModuleInterop": true,
"moduleResolution": "node",
"baseUrl": ".",
"paths": {
"next-test-utils": ["test/lib/next-test-utils"],
"amp-test-utils": ["test/lib/amp-test-utils"],
"next-webdriver": ["test/lib/next-webdriver"]
}
},
"include": ["test/**/*.test.ts", "test/**/*.test.tsx", "test/**/test/*"]
}