diff --git a/.gitignore b/.gitignore index 3c508998a3f..7cee14e3353 100644 --- a/.gitignore +++ b/.gitignore @@ -2,6 +2,9 @@ .idea .vscode +# IDE files +*.code-workspace + # Vim swap files .s[a-z][a-z] .*.s[a-z][a-z] diff --git a/packages/utils/src/scaffold.ts b/packages/utils/src/scaffold.ts index e47fc539f29..97c0813815b 100644 --- a/packages/utils/src/scaffold.ts +++ b/packages/utils/src/scaffold.ts @@ -21,6 +21,7 @@ import { Node } from './types/NodePath'; */ function mapOptionsToTransform(config: Config): string[] { + if (!config.webpackOptions) return []; return Object.keys(config.webpackOptions).filter((k: string): boolean => PROP_TYPES.has(k)); } diff --git a/test/init/auto/init-auto.test.js b/test/init/auto/init-auto.test.js index f552fd895d8..bd772cb4b35 100644 --- a/test/init/auto/init-auto.test.js +++ b/test/init/auto/init-auto.test.js @@ -2,13 +2,13 @@ const fs = require('fs'); const rimraf = require('rimraf'); -const { join } = require('path'); +const { join, resolve } = require('path'); const { run } = require('../../utils/test-utils'); const firstPrompt = 'Will your application have multiple bundles?'; const genPath = join(__dirname, 'test-assets'); -jest.setTimeout(200000); +jest.setTimeout(60000); describe('init auto flag', () => { beforeAll(() => { rimraf.sync(genPath); @@ -32,11 +32,27 @@ describe('init auto flag', () => { expect(stdout).toBeTruthy(); expect(stdout).not.toContain(firstPrompt); + // Skip test in case installation fails + if (!fs.existsSync(resolve(genPath, './yarn.lock'))) { + return; + } + // Test regressively files are scaffolded - const files = ['sw.js', 'package.json', 'src/index.js']; + const files = ['./sw.js', './package.json', './src/index.js']; + // eslint-disable-next-line prettier/prettier files.forEach((file) => { - expect(fs.existsSync(join(genPath, file))).toBeTruthy(); + expect(fs.existsSync(resolve(genPath, file))).toBeTruthy(); }); + + // Check package json is correctly configured + const pkgJsonTests = () => { + const pkgJson = require(join(genPath, './package.json')); + expect(pkgJson).toBeTruthy(); + expect(pkgJson['devDependencies']).toBeTruthy(); + expect(pkgJson['devDependencies']['webpack']).toBeTruthy(); + expect(pkgJson['scripts']['build'] == 'webpack').toBeTruthy(); + }; + expect(pkgJsonTests).not.toThrow(); }); }); diff --git a/test/init/coreFlags/init-flags.test.js b/test/init/coreFlags/init-flags.test.js index 379b206a9c5..2dc1a3b471c 100644 --- a/test/init/coreFlags/init-flags.test.js +++ b/test/init/coreFlags/init-flags.test.js @@ -11,4 +11,10 @@ describe('init with core flags', () => { expect(stdout).not.toContain(firstPrompt); expect(stdout).toContain('Initialize a new webpack configuration'); }); + it('should throw error with invalid scaffolder package', () => { + const { stdout, stderr } = run(__dirname, ['init', 'webpack-rocks'], false); + expect(stdout).toBeFalsy(); + expect(stderr).toBeTruthy(); + expect(stderr).toContain("[webpack-cli] Promise rejection: TypeError: webpack-rocks isn't a valid name"); + }); }); diff --git a/test/init/generator/init-inquirer.test.js b/test/init/generator/init-inquirer.test.js index 9327cbf7cf9..e08efae10d0 100644 --- a/test/init/generator/init-inquirer.test.js +++ b/test/init/generator/init-inquirer.test.js @@ -1,15 +1,15 @@ 'use strict'; const fs = require('fs'); -const path = require('path'); +const { join, resolve } = require('path'); const rimraf = require('rimraf'); const { runPromptWithAnswers } = require('../../utils/test-utils'); const firstPrompt = 'Will your application have multiple bundles?'; const ENTER = '\x0D'; -const genPath = path.join(__dirname, 'test-assets'); +const genPath = join(__dirname, 'test-assets'); -jest.setTimeout(200000); +jest.setTimeout(100000); describe('init', () => { beforeAll(() => { @@ -22,16 +22,32 @@ describe('init', () => { }); it('should scaffold when given answers', async () => { - const { stdout } = await runPromptWithAnswers(genPath, ['init'], [`N${ENTER}`, ENTER, ENTER, ENTER, ENTER, ENTER, ENTER]); + const { stdout } = await runPromptWithAnswers(genPath, ['init'], [`N${ENTER}`, ENTER, ENTER, ENTER, ENTER, ENTER]); expect(stdout).toBeTruthy(); expect(stdout).toContain(firstPrompt); + // Skip test in case installation fails + if (!fs.existsSync(resolve(genPath, './yarn.lock'))) { + return; + } + // Test regressively files are scaffolded - const files = ['sw.js', 'package.json', 'src/index.js']; + const files = ['./sw.js', './package.json', './src/index.js']; + // eslint-disable-next-line prettier/prettier files.forEach((file) => { - expect(fs.existsSync(path.join(genPath, file))).toBeTruthy(); + expect(fs.existsSync(resolve(genPath, file))).toBeTruthy(); }); + + // Check package json is correctly configured + const pkgJsonTests = () => { + const pkgJson = require(join(genPath, './package.json')); + expect(pkgJson).toBeTruthy(); + expect(pkgJson['devDependencies']).toBeTruthy(); + expect(pkgJson['devDependencies']['webpack']).toBeTruthy(); + expect(pkgJson['scripts']['build'] == 'webpack').toBeTruthy(); + }; + expect(pkgJsonTests).not.toThrow(); }); }); diff --git a/test/init/language/css/init-language-css.test.js b/test/init/language/css/init-language-css.test.js new file mode 100644 index 00000000000..5e973e9b564 --- /dev/null +++ b/test/init/language/css/init-language-css.test.js @@ -0,0 +1,60 @@ +'use strict'; + +const fs = require('fs'); +const { join, resolve } = require('path'); +const rimraf = require('rimraf'); +const { runPromptWithAnswers } = require('../../../utils/test-utils'); +const firstPrompt = 'Will your application have multiple bundles?'; + +const ENTER = '\x0D'; +const DOWN = '\x1B\x5B\x42'; +const genPath = join(__dirname, 'test-assets'); + +jest.setTimeout(100000); + +describe('init with SCSS', () => { + beforeAll(() => { + rimraf.sync(genPath); + fs.mkdirSync(genPath); + }); + + afterAll(() => { + rimraf.sync(genPath); + }); + + it('should use SCSS', async () => { + const { stdout } = await runPromptWithAnswers( + genPath, + ['init'], + [`N${ENTER}`, ENTER, ENTER, ENTER, `${DOWN}${DOWN}${ENTER}`, `Y${ENTER}`, `apple${ENTER}`], + ); + + expect(stdout).toBeTruthy(); + expect(stdout).toContain(firstPrompt); + + // Skip test in case installation fails + if (!fs.existsSync(resolve(genPath, './yarn.lock'))) { + return; + } + + // Test regressively files are scaffolded + const files = ['./package.json', './.yo-rc.json', './src/index.js']; + + // eslint-disable-next-line prettier/prettier + files.forEach((file) => { + expect(fs.existsSync(resolve(genPath, file))).toBeTruthy(); + }); + + // Check if package.json is correctly configured + const pkgJsonTests = () => { + const pkgJson = require(join(genPath, './package.json')); + expect(pkgJson).toBeTruthy(); + expect(pkgJson['devDependencies']).toBeTruthy(); + expect(pkgJson['devDependencies']['webpack']).toBeTruthy(); + expect(pkgJson['devDependencies']['node-sass']).toBeTruthy(); + expect(pkgJson['devDependencies']['mini-css-extract-plugin']).toBeTruthy(); + expect(pkgJson['scripts']['build'] == 'webpack').toBeTruthy(); + }; + expect(pkgJsonTests).not.toThrow(); + }); +}); diff --git a/test/init/language/js/init-language-js.test.js b/test/init/language/js/init-language-js.test.js new file mode 100644 index 00000000000..7b73f94a9c7 --- /dev/null +++ b/test/init/language/js/init-language-js.test.js @@ -0,0 +1,60 @@ +'use strict'; + +const fs = require('fs'); +const { join, resolve } = require('path'); +const rimraf = require('rimraf'); +const { runPromptWithAnswers } = require('../../../utils/test-utils'); +const firstPrompt = 'Will your application have multiple bundles?'; + +const ENTER = '\x0D'; +const DOWN = '\x1B\x5B\x42'; +const genPath = join(__dirname, 'test-assets'); + +jest.setTimeout(100000); + +describe('init with Typescript', () => { + beforeAll(() => { + rimraf.sync(genPath); + fs.mkdirSync(genPath); + }); + + afterAll(() => { + rimraf.sync(genPath); + }); + + it('should use typescript', async () => { + const { stdout } = await runPromptWithAnswers( + genPath, + ['init'], + [`N${ENTER}`, ENTER, ENTER, `${DOWN}${DOWN}${ENTER}`, ENTER, ENTER], + ); + + expect(stdout).toBeTruthy(); + expect(stdout).toContain(firstPrompt); + + // Skip test in case installation fails + if (!fs.existsSync(resolve(genPath, './yarn.lock'))) { + return; + } + + // Test regressively files are scaffolded + const files = ['./package.json', './.yo-rc.json', './tsconfig.json', './src/index.ts']; + + // eslint-disable-next-line prettier/prettier + files.forEach((file) => { + expect(fs.existsSync(resolve(genPath, file))).toBeTruthy(); + }); + + // Check package json is correctly configured + const pkgJsonTests = () => { + const pkgJson = require(join(genPath, './package.json')); + expect(pkgJson).toBeTruthy(); + expect(pkgJson['devDependencies']).toBeTruthy(); + expect(pkgJson['devDependencies']['webpack']).toBeTruthy(); + expect(pkgJson['devDependencies']['typescript']).toBeTruthy(); + expect(pkgJson['devDependencies']['ts-loader']).toBeTruthy(); + expect(pkgJson['scripts']['build'] == 'webpack').toBeTruthy(); + }; + expect(pkgJsonTests).not.toThrow(); + }); +}); diff --git a/test/init/multipleEntries/init-multipleEntries.test.js b/test/init/multipleEntries/init-multipleEntries.test.js new file mode 100644 index 00000000000..c3f1078a517 --- /dev/null +++ b/test/init/multipleEntries/init-multipleEntries.test.js @@ -0,0 +1,46 @@ +'use strict'; + +const fs = require('fs'); +const path = require('path'); +const rimraf = require('rimraf'); +const { runPromptWithAnswers } = require('../../utils/test-utils'); +const firstPrompt = 'Will your application have multiple bundles?'; + +const ENTER = '\x0D'; +const genPath = path.join(__dirname, 'test-assets'); + +jest.setTimeout(100000); + +describe('init with multiple entries', () => { + beforeAll(() => { + rimraf.sync(genPath); + fs.mkdirSync(genPath); + }); + + afterAll(() => { + rimraf.sync(genPath); + }); + + it('should scaffold with multiple entries', async () => { + const { stdout } = await runPromptWithAnswers( + genPath, + ['init'], + [`Y${ENTER}`, `a, b${ENTER}`, ENTER, ENTER, ENTER, ENTER, ENTER, ENTER], + ); + + expect(stdout).toBeTruthy(); + expect(stdout).toContain(firstPrompt); + + // Skip test in case installation fails + if (!fs.existsSync(path.resolve(genPath, './yarn.lock'))) { + return; + } + + // Test regressively files are scaffolded + const files = ['./package.json', './src/a.js', './src/b.js', './.yo-rc.json']; + // eslint-disable-next-line prettier/prettier + files.forEach((file) => { + expect(fs.existsSync(path.resolve(genPath, file))).toBeTruthy(); + }); + }); +}); diff --git a/test/loader/loader.test.js b/test/loader/loader.test.js index 00d405187f7..c8a24fe2f58 100644 --- a/test/loader/loader.test.js +++ b/test/loader/loader.test.js @@ -2,7 +2,7 @@ 'use strict'; const { existsSync } = require('fs'); -const { join } = require('path'); +const { join, resolve } = require('path'); const rimraf = require('rimraf'); const { run, runPromptWithAnswers } = require('../utils/test-utils'); @@ -12,7 +12,8 @@ const loaderName = 'test-loader'; const loaderPath = join(__dirname, loaderName); // Since scaffolding is time consuming -jest.setTimeout(40000); + +jest.setTimeout(60000); describe('loader command', () => { beforeAll(() => { @@ -35,6 +36,11 @@ describe('loader command', () => { expect(stdout).toContain(firstPrompt); + // Skip test in case installation fails + if (!existsSync(resolve(loaderPath, './yarn.lock'))) { + return; + } + // check if the output directory exists with the appropriate loader name expect(existsSync(join(__dirname, loaderName))).toBeTruthy(); diff --git a/test/migrate/config/migrate-config.test.js b/test/migrate/config/migrate-config.test.js index 4c60ca6f940..615b6dd21ce 100644 --- a/test/migrate/config/migrate-config.test.js +++ b/test/migrate/config/migrate-config.test.js @@ -11,6 +11,8 @@ const outputPath = path.join(__dirname, outputDir); const outputFile = `${outputDir}/updated-webpack.config.js`; const outputFilePath = path.join(__dirname, outputFile); +jest.setTimeout(60000); + describe('migrate command', () => { beforeEach(() => { rimraf.sync(outputPath); diff --git a/test/plugin/plugin.test.js b/test/plugin/plugin.test.js index 9df31a6c6a1..b1ac55c9739 100644 --- a/test/plugin/plugin.test.js +++ b/test/plugin/plugin.test.js @@ -1,5 +1,5 @@ const { existsSync } = require('fs'); -const { join } = require('path'); +const { join, resolve } = require('path'); const rimraf = require('rimraf'); const { run, runPromptWithAnswers } = require('../utils/test-utils'); @@ -9,7 +9,7 @@ const pluginName = 'test-plugin'; const pluginPath = join(__dirname, pluginName); // Since scaffolding is time consuming -jest.setTimeout(40000); +jest.setTimeout(60000); describe('plugin command', () => { beforeAll(() => { @@ -35,6 +35,11 @@ describe('plugin command', () => { // check if the output directory exists with the appropriate plugin name expect(existsSync(join(__dirname, pluginName))).toBeTruthy(); + // Skip test in case installation fails + if (!existsSync(resolve(pluginPath, './yarn.lock'))) { + return; + } + // Test regressively files are scaffolded const files = ['package.json', 'examples', 'src', 'test', 'src/index.js', 'examples/simple/webpack.config.js'];