import validator from '../src/doctor/configValidator' const baseConfig = { projectName: 'test', sourceRoot: 'src', outputRoot: 'dist' } function getConfig (config) { return { projectConfig: { ...baseConfig, ...config }, configPath: '' } } describe('config validator of doctor', () => { it('should config include\'s all the required values', async () => { let { lines } = await validator({ projectConfig: {}, configPath: '' }) expect(lines.length).toEqual(3) let msgs = lines.map(line => line.desc) expect(msgs.includes('projectName 必须填写')).toBeTruthy() expect(msgs.includes('sourceRoot 必须填写')).toBeTruthy() expect(msgs.includes('outputRoot 必须填写')).toBeTruthy() const res = await validator({ projectConfig: { projectName: '', sourceRoot: '', outputRoot: '' }, configPath: '' }) lines = res.lines expect(lines.length).toEqual(3) msgs = lines.map(line => line.desc) expect(msgs.includes('projectName "projectName" is not allowed to be empty')).toBeTruthy() expect(msgs.includes('sourceRoot "sourceRoot" is not allowed to be empty')).toBeTruthy() expect(msgs.includes('outputRoot "outputRoot" is not allowed to be empty')).toBeTruthy() }) it('date', async () => { let { lines } = await validator(getConfig({ date: '2020-5-26' })) expect(lines.length).toEqual(0) const res = await validator(getConfig({ date: 'abc' })) lines = res.lines expect(lines.length).toEqual(1) expect(lines[0].desc).toEqual('date 应该为一个日期') }) it('framework', async () => { let res = await validator(getConfig({ framework: 'react' })) expect(res.lines.length).toEqual(0) res = await validator(getConfig({ framework: 'vue' })) expect(res.lines.length).toEqual(0) res = await validator(getConfig({ framework: 'nerv' })) expect(res.lines.length).toEqual(0) res = await validator(getConfig({ framework: 'vue3' })) expect(res.lines.length).toEqual(0) res = await validator(getConfig({ framework: 'other' })) expect(res.lines.length).toEqual(1) expect(res.lines[0].desc).toEqual('framework "framework" must be one of [nerv, react, vue, vue3]') }) it('designWidth', async () => { let res = await validator(getConfig({ designWidth: '750' })) expect(res.lines.length).toEqual(0) res = await validator(getConfig({ designWidth: 'a' })) expect(res.lines.length).toEqual(1) res = await validator(getConfig({ designWidth: 700.5 })) expect(res.lines.length).toEqual(1) res = await validator(getConfig({ designWidth: -640 })) expect(res.lines.length).toEqual(1) }) it('deviceRatio', async () => { let res = await validator(getConfig({ deviceRatio: { 640: 2.34 / 2, 750: 1, 828: 1.81 / 2 } })) expect(res.lines.length).toEqual(0) res = await validator(getConfig({ deviceRatio: { 640: 2.34 / 2, 750: 'a', 828: 1.81 / 2 } })) expect(res.lines.length).toEqual(1) }) it('plugins', async () => { let res = await validator(getConfig({ plugins: [ '@tarojs/plugin-mock', ['@tarojs/plugin-mock', { mocks: { '/api/user/1': { name: 'judy', desc: 'Mental guy' } } }], ['@tarojs/plugin-mock'], '/absulute/path/plugin/filename' ] })) expect(res.lines.length).toEqual(0) res = await validator(getConfig({ plugins: [ 1, {}, ['x', 1], [{}, 'x'], ['x', {}, 1], [''] ] })) expect(res.lines.length).toEqual(6) }) it('presets', async () => { let res = await validator(getConfig({ presets: [ '@tarojs/plugin-mock', ['@tarojs/plugin-mock', { mocks: { '/api/user/1': { name: 'judy', desc: 'Mental guy' } } }], ['@tarojs/plugin-mock'], '/absulute/path/plugin/filename' ] })) expect(res.lines.length).toEqual(0) res = await validator(getConfig({ presets: [ 1, {}, ['x', 1], [{}, 'x'], ['x', {}, 1], [''] ] })) expect(res.lines.length).toEqual(6) }) it('terser', async () => { let res = await validator(getConfig({ terser: { enable: true, config: { } } })) expect(res.lines.length).toEqual(0) res = await validator(getConfig({ terser: { enables: true, enable: 1, config: [] } })) expect(res.lines.length).toEqual(3) }) it('csso', async () => { let res = await validator(getConfig({ csso: { enable: true, config: { } } })) expect(res.lines.length).toEqual(0) res = await validator(getConfig({ csso: { enables: true, enable: 1, config: [] } })) expect(res.lines.length).toEqual(3) }) it('uglify', async () => { let res = await validator(getConfig({ uglify: { enable: true, config: { } } })) expect(res.lines.length).toEqual(0) res = await validator(getConfig({ uglify: { enables: true, enable: 1, config: [] } })) expect(res.lines.length).toEqual(3) }) it('sass', async () => { let res = await validator(getConfig({ sass: { resource: '/src/styles/variable.scss' } })) expect(res.lines.length).toEqual(0) res = await validator(getConfig({ sass: { resource: [ './src/styles/variable.scss', './src/styles/mixins.scss' ], projectDirectory: '/root', data: '$nav-height: 48px;' } })) expect(res.lines.length).toEqual(0) res = await validator(getConfig({ sass: { resource: {}, projectDirectory: 1, data: 1 } })) expect(res.lines.length).toEqual(3) }) it('env', async () => { const res = await validator(getConfig({ env: { NODE_ENV: '"development"' } })) expect(res.lines.length).toEqual(0) }) it('defineConstants', async () => { const res = await validator(getConfig({ defineConstants: { A: '"a"' } })) expect(res.lines.length).toEqual(0) }) it('alias', async () => { let res = await validator(getConfig({ alias: { '@/components': 'src/components' } })) expect(res.lines.length).toEqual(0) res = await validator(getConfig({ alias: { '@/components': ['src/components'], '@/utils': 1, '@/project': {} } })) expect(res.lines.length).toEqual(3) }) it('copy', async () => { let res = await validator(getConfig({ copy: { patterns: [ { from: 'src/asset/tt/', to: 'dist/asset/tt/', ignore: '*.js' }, { from: 'src/asset/tt/sd.jpg', to: 'dist/asset/tt/sd.jpg' } ] } })) expect(res.lines.length).toEqual(0) res = await validator(getConfig({ copy: { options: { ignore: ['*.js', '*.css'] } } })) expect(res.lines.length).toEqual(0) res = await validator(getConfig({ copy: { patterns: [ { ignore: '*.js' }, { from: 'src/asset/tt/sd.jpg' }, { to: 'dist/asset/tt/sd.jpg' } ], options: { ignore: [1, true, {}] } } })) expect(res.lines.length).toEqual(7) }) it('mini.compile', async () => { let res = await validator(getConfig({ mini: { compile: { exclude: [ 'src/pages/index/vod-wx-sdk-v2.js', modulePath => modulePath.indexOf('vod-wx-sdk-v2') >= 0 ], include: [ 'src/pages/index/vod-wx-sdk-v2.js', modulePath => modulePath.indexOf('vod-wx-sdk-v2') >= 0 ] } } })) expect(res.lines.length).toEqual(0) res = await validator(getConfig({ mini: { compile: { exclude: [null, []], include: [1, {}] } } })) expect(res.lines.length).toEqual(4) }) it('mini.webpackChain', async () => { let res = await validator(getConfig({ mini: { webpackChain (chain, webpack) { console.log(chain, webpack) } } })) expect(res.lines.length).toEqual(0) res = await validator(getConfig({ mini: { webpackChain: 'some' } })) expect(res.lines.length).toEqual(1) }) it('mini.commonChunks', async () => { let res = await validator(getConfig({ mini: { commonChunks: ['runtime', 'vendors', 'taro', 'common'] } })) expect(res.lines.length).toEqual(0) res = await validator(getConfig({ mini: { commonChunks (commonChunks) { commonChunks.push('yourCustomCommonChunkName') return commonChunks } } })) expect(res.lines.length).toEqual(0) res = await validator(getConfig({ mini: { commonChunks: 1 } })) expect(res.lines.length).toEqual(1) }) it('mini.addChunkPages', async () => { let res = await validator(getConfig({ mini: { addChunkPages (pages, pagesNames) { console.log(pages, pagesNames) } } })) expect(res.lines.length).toEqual(0) res = await validator(getConfig({ mini: { addChunkPages: 1 } })) expect(res.lines.length).toEqual(1) }) it('mini.postcss', async () => { let res = await validator(getConfig({ mini: { postcss: { autoprefixer: { enable: true, config: {} } } } })) expect(res.lines.length).toEqual(0) res = await validator(getConfig({ mini: { postcss: { autoprefixer: { enable: 1, config: 'a' }, pxtransform: true } } })) expect(res.lines.length).toEqual(3) }) it('mini.output', async () => { let res = await validator(getConfig({ mini: { output: {} } })) expect(res.lines.length).toEqual(0) res = await validator(getConfig({ mini: { output: 1 } })) expect(res.lines.length).toEqual(1) }) it('mini\'s third party options', async () => { const res = await validator(getConfig({ mini: { cssLoaderOption: {}, styleLoaderOption: {}, sassLoaderOption: {}, lessLoaderOption: {}, stylusLoaderOption: {}, mediaUrlLoaderOption: {}, fontUrlLoaderOption: {}, imageUrlLoaderOption: {}, miniCssExtractPluginOption: {} } })) expect(res.lines.length).toEqual(0) }) it('h5.devServer', async () => { let res = await validator(getConfig({ h5: { devServer: { port: 10086 } } })) expect(res.lines.length).toEqual(0) res = await validator(getConfig({ h5: { devServer: 1 } })) expect(res.lines.length).toEqual(1) }) it('h5.output', async () => { let res = await validator(getConfig({ h5: { output: { filename: 'js/[name].[hash:8].js', chunkFilename: 'js/[name].[chunkhash:8].js' } } })) expect(res.lines.length).toEqual(0) res = await validator(getConfig({ h5: { output: 1 } })) expect(res.lines.length).toEqual(1) }) it('h5.publicPath', async () => { let res = await validator(getConfig({ h5: { publicPath: '/' } })) expect(res.lines.length).toEqual(0) res = await validator(getConfig({ h5: { publicPath: 1 } })) expect(res.lines.length).toEqual(1) }) it('h5.staticDirectory', async () => { let res = await validator(getConfig({ h5: { staticDirectory: '/' } })) expect(res.lines.length).toEqual(0) res = await validator(getConfig({ h5: { staticDirectory: 1 } })) expect(res.lines.length).toEqual(1) }) it('h5.chunkDirectory', async () => { let res = await validator(getConfig({ h5: { chunkDirectory: '/' } })) expect(res.lines.length).toEqual(0) res = await validator(getConfig({ h5: { chunkDirectory: 1 } })) expect(res.lines.length).toEqual(1) }) it('h5.webpackChain', async () => { let res = await validator(getConfig({ h5: { webpackChain (chain, webpack) { console.log(chain, webpack) } } })) expect(res.lines.length).toEqual(0) res = await validator(getConfig({ h5: { webpackChain: 'some' } })) expect(res.lines.length).toEqual(1) }) it('h5.webpack[DEPRECATED]', async () => { const res = await validator(getConfig({ h5: { webpack: 1 } })) expect(res.lines.length).toEqual(1) expect(res.lines[0].desc).toEqual('h5.webpack "h5.webpack" is not allowed') }) it('h5.router', async () => { let res = await validator(getConfig({ h5: { router: { mode: 'hash' } } })) expect(res.lines.length).toEqual(0) res = await validator(getConfig({ h5: { router: 1 } })) expect(res.lines.length).toEqual(1) }) it('h5.entry', async () => { let res = await validator(getConfig({ h5: { entry: './path/to/my/entry/file.js' } })) expect(res.lines.length).toEqual(0) res = await validator(getConfig({ h5: { entry: ['./path/to/my/entry/file.js', './path/other/file.js'] } })) expect(res.lines.length).toEqual(0) res = await validator(getConfig({ h5: { entry: { main: './path/to/my/entry/file.js' } } })) expect(res.lines.length).toEqual(0) res = await validator(getConfig({ h5: { entry: { main: ['./path/to/my/entry/file.js', './path/other/file.js'] } } })) expect(res.lines.length).toEqual(0) res = await validator(getConfig({ h5: { entry: () => './demo' } })) expect(res.lines.length).toEqual(0) }) it('h5.enableSourceMap', async () => { let res = await validator(getConfig({ h5: { enableSourceMap: true } })) expect(res.lines.length).toEqual(0) res = await validator(getConfig({ h5: { enableSourceMap: 1 } })) expect(res.lines.length).toEqual(1) }) it('h5.enableExtract', async () => { let res = await validator(getConfig({ h5: { enableExtract: true } })) expect(res.lines.length).toEqual(0) res = await validator(getConfig({ h5: { enableExtract: 1 } })) expect(res.lines.length).toEqual(1) }) it('h5.esnextModules', async () => { let res = await validator(getConfig({ h5: { esnextModules: ['taro-ui'] } })) expect(res.lines.length).toEqual(0) res = await validator(getConfig({ h5: { esnextModules: [1, true, {}] } })) expect(res.lines.length).toEqual(3) res = await validator(getConfig({ h5: 1 })) expect(res.lines.length).toEqual(1) }) it('h5.postcss', async () => { let res = await validator(getConfig({ h5: { postcss: { autoprefixer: { enable: true, config: {} } } } })) expect(res.lines.length).toEqual(0) res = await validator(getConfig({ h5: { postcss: { autoprefixer: { enable: 1, config: 'a' }, pxtransform: true } } })) expect(res.lines.length).toEqual(3) }) it('h5\'s third party options', async () => { const res = await validator(getConfig({ h5: { cssLoaderOption: {}, styleLoaderOption: {}, sassLoaderOption: {}, lessLoaderOption: {}, stylusLoaderOption: {}, mediaUrlLoaderOption: {}, fontUrlLoaderOption: {}, imageUrlLoaderOption: {}, miniCssExtractPluginOption: {} } })) expect(res.lines.length).toEqual(0) }) it('unknow', async () => { const res = await validator(getConfig({ unknow: {} })) expect(res.lines.length).toEqual(0) }) it('mini.unknow', async () => { const res = await validator(getConfig({ mini: { unknow: {} } })) expect(res.lines.length).toEqual(0) }) it('h5.unknow', async () => { const res = await validator(getConfig({ h5: { unknow: {} } })) expect(res.lines.length).toEqual(0) }) })