[lint] Disable linting using project config for tests (#66145)

During integration testing, previously, calls to `next build` could rely
on the project (the Next.js project) level ESLint configuration. In
order to correct this, a new `lint` option was added to `nextBuild` that
can be passed to enabled linting. If this is `false` or `undefined`, a
`--no-lint` argument will be passed to `next build` to prevent it from
running.
This commit is contained in:
Wyatt Johnson 2024-05-28 08:53:26 -06:00 committed by GitHub
parent b5d911c92c
commit 9d1ae19af3
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
7 changed files with 52 additions and 64 deletions

View file

@ -5,17 +5,18 @@ import { join } from 'path'
import { nextBuild } from 'next-test-utils'
const appDir = join(__dirname, '../')
const customFile = join(appDir, '.next/extra-file.txt')
const cacheDir = join(appDir, '.next/cache')
// const swcCacheDir = join(appDir, '.next/cache/swc')
const nextDir = join(appDir, '.next')
const customFile = join(nextDir, '/extra-file.txt')
const cacheDir = join(nextDir, '/cache')
// const swcCacheDir = join(nextDir, '/cache/swc')
const nextConfig = join(appDir, 'next.config.js')
let nextConfigContent
async function checkFileWrite(existsAfterBuild) {
await nextBuild(appDir)
await nextBuild(appDir, [], { lint: true })
fs.writeFileSync(customFile, 'this is a testing file')
await nextBuild(appDir)
await nextBuild(appDir, [], { lint: true })
expect(fs.existsSync(customFile)).toBe(existsAfterBuild)
// `.next/cache` should be preserved in all cases
expect(fs.existsSync(cacheDir)).toBe(true)
@ -32,6 +33,10 @@ describe('Cleaning distDir', () => {
;(process.env.TURBOPACK_DEV ? describe.skip : describe)(
'production mode',
() => {
beforeAll(() => {
fs.removeSync(nextDir)
})
runTests()
describe('disabled write', () => {

View file

@ -25,7 +25,7 @@ describe('distDir', () => {
beforeAll(async () => {
await fs.remove(join(appDir, '.next'))
await fs.remove(join(appDir, 'dist'))
await nextBuild(appDir)
await nextBuild(appDir, [], { lint: true })
appPort = await findPort()
app = await nextStart(appDir, appPort)
})
@ -79,7 +79,10 @@ describe('distDir', () => {
it('should throw error with invalid distDir', async () => {
const origNextConfig = await fs.readFile(nextConfig, 'utf8')
await fs.writeFile(nextConfig, `module.exports = { distDir: '' }`)
const { stderr } = await nextBuild(appDir, [], { stderr: true })
const { stderr } = await nextBuild(appDir, [], {
stderr: true,
lint: true,
})
await fs.writeFile(nextConfig, origNextConfig)
expect(stderr).toContain(
@ -93,7 +96,10 @@ describe('distDir', () => {
nextConfig,
`module.exports = { distDir: undefined, eslint: { ignoreDuringBuilds: true } }`
)
const { stderr } = await nextBuild(appDir, [], { stderr: true })
const { stderr } = await nextBuild(appDir, [], {
stderr: true,
lint: true,
})
await fs.writeFile(nextConfig, origNextConfig)
expect(stderr.length).toBe(0)

View file

@ -1,43 +1,11 @@
import fs from 'fs-extra'
import os from 'os'
import { join } from 'path'
import findUp from 'next/dist/compiled/find-up'
import { File, nextBuild, nextLint } from 'next-test-utils'
import { nextLint } from 'next-test-utils'
const dirFirstTimeSetup = join(__dirname, '../first-time-setup')
const dirCustomConfig = join(__dirname, '../custom-config')
const dirWebVitalsConfig = join(__dirname, '../config-core-web-vitals')
const dirPluginRecommendedConfig = join(
__dirname,
'../plugin-recommended-config'
)
const dirPluginCoreWebVitalsConfig = join(
__dirname,
'../plugin-core-web-vitals-config'
)
const dirIgnoreDuringBuilds = join(__dirname, '../ignore-during-builds')
const dirBaseDirectories = join(__dirname, '../base-directories')
const dirBaseDirectoriesConfigFile = new File(
join(dirBaseDirectories, '/next.config.js')
)
const dirCustomDirectories = join(__dirname, '../custom-directories')
const dirConfigInPackageJson = join(__dirname, '../config-in-package-json')
const dirInvalidOlderEslintVersion = join(
__dirname,
'../invalid-eslint-version'
)
const dirMaxWarnings = join(__dirname, '../max-warnings')
const dirEmptyDirectory = join(__dirname, '../empty-directory')
const dirEslintIgnore = join(__dirname, '../eslint-ignore')
const dirNoEslintPlugin = join(__dirname, '../no-eslint-plugin')
const dirNoConfig = join(__dirname, '../no-config')
const dirEslintCache = join(__dirname, '../eslint-cache')
const dirEslintCacheCustomDir = join(__dirname, '../eslint-cache-custom-dir')
const dirFileLinting = join(__dirname, '../file-linting')
const mjsCjsLinting = join(__dirname, '../mjs-cjs-linting')
const dirTypescript = join(__dirname, '../with-typescript')
test('eslint caching is enabled by default', async () => {
const cacheDir = join(dirEslintCache, '.next', 'cache')

View file

@ -1,43 +1,23 @@
import fs from 'fs-extra'
import os from 'os'
import { join } from 'path'
import findUp from 'next/dist/compiled/find-up'
import { File, nextBuild, nextLint } from 'next-test-utils'
import { nextBuild } from 'next-test-utils'
const dirFirstTimeSetup = join(__dirname, '../first-time-setup')
const dirCustomConfig = join(__dirname, '../custom-config')
const dirWebVitalsConfig = join(__dirname, '../config-core-web-vitals')
const dirPluginRecommendedConfig = join(
__dirname,
'../plugin-recommended-config'
)
const dirPluginCoreWebVitalsConfig = join(
__dirname,
'../plugin-core-web-vitals-config'
)
const dirIgnoreDuringBuilds = join(__dirname, '../ignore-during-builds')
const dirBaseDirectories = join(__dirname, '../base-directories')
const dirBaseDirectoriesConfigFile = new File(
join(dirBaseDirectories, '/next.config.js')
)
const dirCustomDirectories = join(__dirname, '../custom-directories')
const dirConfigInPackageJson = join(__dirname, '../config-in-package-json')
const dirInvalidOlderEslintVersion = join(
__dirname,
'../invalid-eslint-version'
)
const dirMaxWarnings = join(__dirname, '../max-warnings')
const dirEmptyDirectory = join(__dirname, '../empty-directory')
const dirEslintIgnore = join(__dirname, '../eslint-ignore')
const dirNoEslintPlugin = join(__dirname, '../no-eslint-plugin')
const dirNoConfig = join(__dirname, '../no-config')
const dirEslintCache = join(__dirname, '../eslint-cache')
const dirEslintCacheCustomDir = join(__dirname, '../eslint-cache-custom-dir')
const dirFileLinting = join(__dirname, '../file-linting')
const mjsCjsLinting = join(__dirname, '../mjs-cjs-linting')
const dirTypescript = join(__dirname, '../with-typescript')
describe('Next Build', () => {
;(process.env.TURBOPACK_DEV ? describe.skip : describe)(
@ -50,6 +30,7 @@ describe('Next Build', () => {
const { stdout, stderr } = await nextBuild(dirFirstTimeSetup, [], {
stdout: true,
stderr: true,
lint: true,
})
const output = stdout + stderr
@ -62,6 +43,7 @@ describe('Next Build', () => {
const { stdout, stderr } = await nextBuild(dirCustomConfig, [], {
stdout: true,
stderr: true,
lint: true,
})
const output = stdout + stderr
@ -77,6 +59,7 @@ describe('Next Build', () => {
const { stdout, stderr } = await nextBuild(dirIgnoreDuringBuilds, [], {
stdout: true,
stderr: true,
lint: true,
})
const output = stdout + stderr
@ -90,6 +73,7 @@ describe('Next Build', () => {
const { stdout, stderr } = await nextBuild(dirBaseDirectories, [], {
stdout: true,
stderr: true,
lint: true,
})
const output = stdout + stderr
@ -121,6 +105,7 @@ describe('Next Build', () => {
const { stdout, stderr } = await nextBuild(dirCustomDirectories, [], {
stdout: true,
stderr: true,
lint: true,
})
const output = stdout + stderr
@ -140,6 +125,7 @@ describe('Next Build', () => {
{
stdout: true,
stderr: true,
lint: true,
}
)
@ -153,6 +139,7 @@ describe('Next Build', () => {
const { stdout, stderr } = await nextBuild(dirEmptyDirectory, [], {
stdout: true,
stderr: true,
lint: true,
})
const output = stdout + stderr
@ -168,6 +155,7 @@ describe('Next Build', () => {
const { stdout, stderr } = await nextBuild(dirEslintIgnore, [], {
stdout: true,
stderr: true,
lint: true,
})
const output = stdout + stderr
@ -183,6 +171,7 @@ describe('Next Build', () => {
const { stdout, stderr } = await nextBuild(dirNoEslintPlugin, [], {
stdout: true,
stderr: true,
lint: true,
})
const output = stdout + stderr
@ -195,7 +184,9 @@ describe('Next Build', () => {
const cacheDir = join(dirEslintCache, '.next', 'cache')
await fs.remove(cacheDir)
await nextBuild(dirEslintCache, [])
await nextBuild(dirEslintCache, [], {
lint: true,
})
const files = await fs.readdir(join(cacheDir, 'eslint/'))
const cacheExists = files.some((f) => /\.cache/.test(f))
@ -210,7 +201,9 @@ describe('Next Build', () => {
await fs.remove(oldCacheDir)
await fs.remove(newCacheDir)
await nextBuild(dirEslintCacheCustomDir, [])
await nextBuild(dirEslintCacheCustomDir, [], {
lint: true,
})
expect(fs.existsSync(oldCacheDir)).toBe(false)

View file

@ -165,6 +165,7 @@ describe('config telemetry', () => {
const { stderr } = await nextBuild(appDir, [], {
stderr: true,
env: { NEXT_TELEMETRY_DEBUG: 1 },
lint: true,
})
await fs.remove(path.join(appDir, '.eslintrc'))
@ -222,6 +223,7 @@ describe('config telemetry', () => {
const { stderr } = await nextBuild(appDir, [], {
stderr: true,
env: { NEXT_TELEMETRY_DEBUG: 1 },
lint: true,
})
await fs.remove(nextConfig)
@ -266,6 +268,7 @@ describe('config telemetry', () => {
const { stderr } = await nextBuild(appDir, [], {
stderr: true,
env: { NEXT_TELEMETRY_DEBUG: 1 },
lint: true,
})
const featureUsageEvents = findAllTelemetryEvents(
stderr,

View file

@ -68,6 +68,7 @@ export class NextStartInstance extends NextInstance {
if (this.buildCommand) {
buildArgs = this.buildCommand.split(' ')
}
if (this.startCommand) {
startArgs = this.startCommand.split(' ')
}

View file

@ -192,6 +192,12 @@ export interface NextOptions {
stdout?: true | 'log'
ignoreFail?: boolean
/**
* If true, this enables the linting step in the build process. If false or
* undefined, it adds a `--no-lint` flag to the build command.
*/
lint?: boolean
onStdout?: (data: any) => void
onStderr?: (data: any) => void
}
@ -442,6 +448,12 @@ export function nextBuild(
args: string[] = [],
opts: NextOptions = {}
) {
// If the build hasn't requested it to be linted explicitly, disable linting
// if it's not already disabled.
if (!opts.lint && !args.includes('--no-lint')) {
args.push('--no-lint')
}
return runNextCommand(['build', dir, ...args], opts)
}