From daba4cf0ee740a054dd917f1ab575383e280d7e3 Mon Sep 17 00:00:00 2001 From: ehmicky Date: Fri, 13 Nov 2020 20:27:18 +0100 Subject: [PATCH 1/2] Use test fixtures --- package-lock.json | 6 ------ package.json | 4 ++-- .../invalid_next_config/next.config.js | 3 +++ test/index.js | 18 +++++++++++------- 4 files changed, 16 insertions(+), 15 deletions(-) create mode 100644 test/fixtures/invalid_next_config/next.config.js diff --git a/package-lock.json b/package-lock.json index fafbf5a80c..84a78991ca 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9591,12 +9591,6 @@ "minimist": "^1.2.5" } }, - "mock-fs": { - "version": "4.13.0", - "resolved": "https://registry.npmjs.org/mock-fs/-/mock-fs-4.13.0.tgz", - "integrity": "sha512-DD0vOdofJdoaRNtnWcrXe6RQbpHkPPmtqGq14uRX0F8ZKJ5nv89CVTYl/BZdppDxBDaV0hl75htg3abpEWlPZA==", - "dev": true - }, "move-concurrently": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/move-concurrently/-/move-concurrently-1.0.1.tgz", diff --git a/package.json b/package.json index 4ff7cef1f7..a887abf8fa 100644 --- a/package.json +++ b/package.json @@ -35,7 +35,6 @@ "@netlify/eslint-config-node": "^0.3.0", "husky": "^4.3.0", "jest": "^26.6.1", - "mock-fs": "^4.13.0", "prettier": "^2.1.2", "react": "^17.0.1", "react-dom": "^17.0.1" @@ -47,7 +46,8 @@ }, "jest": { "testMatch": [ - "**/test/**/*.js" + "**/test/**/*.js", + "!**/test/fixtures/**" ], "verbose": true } diff --git a/test/fixtures/invalid_next_config/next.config.js b/test/fixtures/invalid_next_config/next.config.js new file mode 100644 index 0000000000..f72b6cf52f --- /dev/null +++ b/test/fixtures/invalid_next_config/next.config.js @@ -0,0 +1,3 @@ +module.exports = { + target: 'server', +} diff --git a/test/index.js b/test/index.js index 944633fdd9..dc8fed7150 100644 --- a/test/index.js +++ b/test/index.js @@ -1,9 +1,9 @@ const path = require('path') +const process = require('process') const nextOnNetlify = require('next-on-netlify') const makef = require('makef') const makeDir = require('make-dir') const cpx = require('cpx') -const mockFs = require('mock-fs') const plugin = require('../index') const utils = { @@ -33,6 +33,14 @@ console.log('Initializing tests') const DUMMY_PACKAGE_JSON = { name: 'dummy', version: '1.0.0' } +const FIXTURES_DIR = `${__dirname}/fixtures` + +const useFixture = function (fixtureName) { + const originalCwd = process.cwd() + process.chdir(`${FIXTURES_DIR}/${fixtureName}`) + return process.chdir.bind(process, originalCwd) +} + describe('preBuild()', () => { test('fail build if the app has static html export in npm script', async () => { await plugin.onPreBuild({ @@ -98,11 +106,7 @@ describe('preBuild()', () => { }) test(`fail build if the app's next config has an invalid target`, async () => { - mockFs({ - 'next.config.js': { - target: 'nonsense', - }, - }) + const restoreCwd = useFixture('invalid_next_config') await plugin.onPreBuild({ netlifyConfig: {}, @@ -111,7 +115,7 @@ describe('preBuild()', () => { constants: { FUNCTIONS_SRC: 'out_functions' }, }) - mockFs.restore() + restoreCwd() const acceptableTargets = ['serverless', 'experimental-serverless-trace'] expect(utils.build.failBuild.mock.calls[0][0]).toEqual( From b31cf242c5354705e65b2496ca148354622cbf18 Mon Sep 17 00:00:00 2001 From: ehmicky Date: Fri, 13 Nov 2020 21:24:25 +0100 Subject: [PATCH 2/2] Fix mocking --- __mocks__/cpx.js | 3 - __mocks__/make-dir.js | 1 - __mocks__/makef.js | 3 - __mocks__/next-on-netlify.js | 1 - index.js | 9 ++- package-lock.json | 26 ++++--- package.json | 4 +- .../out_publish/subdir/dummy.txt | 0 .../publish/subdir/dummy.txt | 0 .../publish_copy_files/subdir/dummy.txt | 0 test/index.js | 69 +++++++++++-------- 11 files changed, 69 insertions(+), 47 deletions(-) delete mode 100644 __mocks__/cpx.js delete mode 100644 __mocks__/make-dir.js delete mode 100644 __mocks__/makef.js delete mode 100644 __mocks__/next-on-netlify.js create mode 100644 test/fixtures/publish_copy_files/out_publish/subdir/dummy.txt create mode 100644 test/fixtures/publish_copy_files/publish/subdir/dummy.txt create mode 100644 test/fixtures/publish_copy_files/subdir/dummy.txt diff --git a/__mocks__/cpx.js b/__mocks__/cpx.js deleted file mode 100644 index 386ba31819..0000000000 --- a/__mocks__/cpx.js +++ /dev/null @@ -1,3 +0,0 @@ -module.exports = { - copySync: jest.fn() -}; diff --git a/__mocks__/make-dir.js b/__mocks__/make-dir.js deleted file mode 100644 index 6ee585673e..0000000000 --- a/__mocks__/make-dir.js +++ /dev/null @@ -1 +0,0 @@ -module.exports = jest.fn(); diff --git a/__mocks__/makef.js b/__mocks__/makef.js deleted file mode 100644 index f7048bba0a..0000000000 --- a/__mocks__/makef.js +++ /dev/null @@ -1,3 +0,0 @@ -module.exports = { - createFile: jest.fn() -}; diff --git a/__mocks__/next-on-netlify.js b/__mocks__/next-on-netlify.js deleted file mode 100644 index 6ee585673e..0000000000 --- a/__mocks__/next-on-netlify.js +++ /dev/null @@ -1 +0,0 @@ -module.exports = jest.fn(); diff --git a/index.js b/index.js index 5f093ab507..e81d3628e4 100644 --- a/index.js +++ b/index.js @@ -1,13 +1,18 @@ +const fs = require('fs') const path = require('path') +const util = require('util') + const nextOnNetlify = require('next-on-netlify') const { PHASE_PRODUCTION_BUILD } = require('next/constants') const { default: loadConfig } = require('next/dist/next-server/server/config') -const makef = require('makef') const makeDir = require('make-dir') const pathExists = require('path-exists') const cpx = require('cpx') + const isStaticExportProject = require('./helpers/isStaticExportProject') +const pWriteFile = util.promisify(fs.writeFile) + // * Helpful Plugin Context * // - Between the prebuild and build steps, the project's build command is run // - Between the build and postbuild steps, any functions are bundled @@ -64,7 +69,7 @@ module.exports = { target: 'serverless' } ` - makef.createFile({ 'next.config.js': nextConfig }) + await pWriteFile('next.config.js', nextConfig) console.log(`** Adding next.config.js with target set to 'serverless' **`) } }, diff --git a/package-lock.json b/package-lock.json index 84a78991ca..7f230d21fb 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9365,14 +9365,6 @@ "tmpl": "1.0.x" } }, - "makef": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/makef/-/makef-1.0.0.tgz", - "integrity": "sha512-i5y70loMn59Y7cA3L1tHCJygbONlZaA6GixFrjWNJ2x2BkSFZvgO/9LeWwAMyus7/Y++TIadv8jJsTtpLK0pug==", - "requires": { - "fs-extra": "8.x.x || 9.x.x" - } - }, "map-cache": { "version": "0.2.2", "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz", @@ -13541,6 +13533,24 @@ "setimmediate": "^1.0.4" } }, + "tmp": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.1.tgz", + "integrity": "sha512-76SUhtfqR2Ijn+xllcI5P1oyannHNHByD80W1q447gU3mp9G9PSpGdWmjUOHRDPiHYacIk66W7ubDTuPF3BEtQ==", + "dev": true, + "requires": { + "rimraf": "^3.0.0" + } + }, + "tmp-promise": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/tmp-promise/-/tmp-promise-3.0.2.tgz", + "integrity": "sha512-OyCLAKU1HzBjL6Ev3gxUeraJNlbNingmi8IrHHEsYH8LTmEuhvYfqvhn2F/je+mjf4N58UmZ96OMEy1JanSCpA==", + "dev": true, + "requires": { + "tmp": "^0.2.0" + } + }, "tmpl": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.4.tgz", diff --git a/package.json b/package.json index a887abf8fa..269998345c 100644 --- a/package.json +++ b/package.json @@ -26,7 +26,6 @@ "dependencies": { "cpx": "^1.5.0", "make-dir": "^3.1.0", - "makef": "^1.0.0", "next": "^9.5.3", "next-on-netlify": "^2.6.0", "path-exists": "^4.0.0" @@ -37,7 +36,8 @@ "jest": "^26.6.1", "prettier": "^2.1.2", "react": "^17.0.1", - "react-dom": "^17.0.1" + "react-dom": "^17.0.1", + "tmp-promise": "^3.0.2" }, "husky": { "hooks": { diff --git a/test/fixtures/publish_copy_files/out_publish/subdir/dummy.txt b/test/fixtures/publish_copy_files/out_publish/subdir/dummy.txt new file mode 100644 index 0000000000..e69de29bb2 diff --git a/test/fixtures/publish_copy_files/publish/subdir/dummy.txt b/test/fixtures/publish_copy_files/publish/subdir/dummy.txt new file mode 100644 index 0000000000..e69de29bb2 diff --git a/test/fixtures/publish_copy_files/subdir/dummy.txt b/test/fixtures/publish_copy_files/subdir/dummy.txt new file mode 100644 index 0000000000..e69de29bb2 diff --git a/test/index.js b/test/index.js index dc8fed7150..c336c8f9ce 100644 --- a/test/index.js +++ b/test/index.js @@ -1,10 +1,13 @@ const path = require('path') const process = require('process') + const nextOnNetlify = require('next-on-netlify') -const makef = require('makef') -const makeDir = require('make-dir') -const cpx = require('cpx') -const plugin = require('../index') +const pathExists = require('path-exists') +const { dir: getTmpDir } = require('tmp-promise') + +const plugin = require('..') + +const FIXTURES_DIR = `${__dirname}/fixtures` const utils = { run: { @@ -15,32 +18,44 @@ const utils = { }, } -afterEach(() => { +// Temporary switch cwd +const changeCwd = function (cwd) { + const originalCwd = process.cwd() + process.chdir(cwd) + return process.chdir.bind(process, originalCwd) +} + +// Switch cwd to a fixture directory +const useFixture = function (fixtureName) { + const fixtureDir = `${FIXTURES_DIR}/${fixtureName}` + const restoreCwd = changeCwd(fixtureDir) + return { restoreCwd, fixtureDir } +} + +// In each test, we change cwd to a temporary directory. +// This allows us not to have to mock filesystem operations. +beforeEach(async () => { + const { path, cleanup } = await getTmpDir({ unsafeCleanup: true }) + const restoreCwd = changeCwd(path) + Object.assign(this, { cleanup, restoreCwd }) +}) + +afterEach(async () => { utils.build.failBuild.mockReset() utils.run.command.mockReset() jest.clearAllMocks() jest.resetAllMocks() + + // Cleans up the temporary directory from `getTmpDir()` and do not make it + // the current directory anymore + this.restoreCwd() + await this.cleanup() }) jest.mock('next-on-netlify') -jest.mock('makef') -jest.mock('make-dir') -jest.mock('cpx') - -// See: https://github.com/tschaub/mock-fs/issues/234#issuecomment-377862172 -// for why this log is required -console.log('Initializing tests') const DUMMY_PACKAGE_JSON = { name: 'dummy', version: '1.0.0' } -const FIXTURES_DIR = `${__dirname}/fixtures` - -const useFixture = function (fixtureName) { - const originalCwd = process.cwd() - process.chdir(`${FIXTURES_DIR}/${fixtureName}`) - return process.chdir.bind(process, originalCwd) -} - describe('preBuild()', () => { test('fail build if the app has static html export in npm script', async () => { await plugin.onPreBuild({ @@ -102,19 +117,17 @@ describe('preBuild()', () => { constants: { FUNCTIONS_SRC: 'out_functions' }, }) - expect(makef.createFile.mock.calls.length).toEqual(1) + expect(await pathExists('next.config.js')).toBeTruthy() }) test(`fail build if the app's next config has an invalid target`, async () => { - const restoreCwd = useFixture('invalid_next_config') - + const { restoreCwd } = useFixture('invalid_next_config') await plugin.onPreBuild({ netlifyConfig: {}, packageJson: DUMMY_PACKAGE_JSON, utils, constants: { FUNCTIONS_SRC: 'out_functions' }, }) - restoreCwd() const acceptableTargets = ['serverless', 'experimental-serverless-trace'] @@ -143,17 +156,19 @@ describe('onBuild()', () => { }, }) - expect(makeDir.mock.calls[0][0]).toEqual(PUBLISH_DIR) + expect(await pathExists(PUBLISH_DIR)).toBeTruthy() }) test('calls copySync with correct args', async () => { - const PUBLISH_DIR = 'some/path' + const { restoreCwd, fixtureDir } = useFixture('publish_copy_files') + const PUBLISH_DIR = `${fixtureDir}/publish` await plugin.onBuild({ constants: { PUBLISH_DIR, }, }) + restoreCwd() - expect(cpx.copySync.mock.calls[0][0]).toEqual('out_publish/**/*', PUBLISH_DIR) + expect(await pathExists(`${PUBLISH_DIR}/subdir/dummy.txt`)).toBeTruthy() }) })