mirror of
https://github.com/vuejs/vue-cli.git
synced 2026-04-23 04:58:56 -05:00
refactor for testing
This commit is contained in:
@@ -5,3 +5,4 @@ design
|
||||
packages/test
|
||||
dist
|
||||
yarn.lock
|
||||
.vuerc
|
||||
|
||||
@@ -16,7 +16,7 @@ cd packages/@vue/cli
|
||||
yarn link
|
||||
|
||||
# create test projects in /packages/test
|
||||
export VUE_CLI_DEBUG=true # necessary for local tests to work
|
||||
export VUE_CLI_TEST=true # necessary for manual tests to work
|
||||
cd -
|
||||
cd packages/test
|
||||
vue create test-app
|
||||
@@ -87,6 +87,10 @@ module.exports = (api, options) => {
|
||||
}
|
||||
```
|
||||
|
||||
#### Important Development Note
|
||||
|
||||
A plugin with a generator that injects additional dependencies other than packages in this repo (e.g. `chai` is conditionally injected by `@vue/cli-plugin-unit-mocha-webpack/generator/index.js`) should have those dependencies listed in its "devDependencies" field. This ensures that the package always exist in this repo's root `node_modules` so that we don't have to reinstall them on every test.
|
||||
|
||||
[1]: https://github.com/vuejs/vue-cli/tree/next/packages/@vue/cli/lib/Creator.js
|
||||
[3]: https://github.com/vuejs/vue-cli/tree/next/packages/@vue/cli/lib/GeneratorAPI.js
|
||||
[4]: https://github.com/vuejs/vue-cli/tree/next/packages/@vue/cli-service/lib/Service.js
|
||||
|
||||
+19
-5
@@ -10,16 +10,29 @@
|
||||
"precommit": "lint-staged"
|
||||
},
|
||||
"jest": {
|
||||
"testMatch": ["<rootDir>/test/**/*.js"],
|
||||
"testMatch": [
|
||||
"<rootDir>/test/**/*.js"
|
||||
],
|
||||
"testEnvironment": "node",
|
||||
"setupFiles": [
|
||||
"<rootDir>/test/__setup__.js"
|
||||
],
|
||||
"testPathIgnorePatterns": [
|
||||
"/node_modules/",
|
||||
"/packages/"
|
||||
"/packages/",
|
||||
"/__mocks__/",
|
||||
"__setup__.js"
|
||||
]
|
||||
},
|
||||
"lint-staged": {
|
||||
"*.js": ["eslint --fix", "git add"],
|
||||
"packages/**/bin/*": ["eslint --fix", "git add"]
|
||||
"*.js": [
|
||||
"eslint --fix",
|
||||
"git add"
|
||||
],
|
||||
"packages/**/bin/*": [
|
||||
"eslint --fix",
|
||||
"git add"
|
||||
]
|
||||
},
|
||||
"devDependencies": {
|
||||
"debug": "^3.1.0",
|
||||
@@ -29,6 +42,7 @@
|
||||
"husky": "^0.14.3",
|
||||
"jest": "^22.0.4",
|
||||
"lerna": "^2.5.1",
|
||||
"lint-staged": "^6.0.0"
|
||||
"lint-staged": "^6.0.0",
|
||||
"memfs": "^2.6.0"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,5 +25,8 @@
|
||||
"babel-eslint": "^8.1.2",
|
||||
"eslint": "^4.14.0",
|
||||
"eslint-loader": "^1.9.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"eslint-plugin-vue": "^4.0.0"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,5 +26,8 @@
|
||||
"jest": "^22.0.4",
|
||||
"jest-serializer-vue": "^0.3.0",
|
||||
"vue-jest": "^1.4.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"vue-test-utils": "^1.0.0-beta.9"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,6 +27,10 @@
|
||||
"mocha-webpack": "^1.0.1",
|
||||
"webpack-node-externals": "^1.6.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"chai": "^4.1.2",
|
||||
"vue-test-utils": "^1.0.0-beta.9"
|
||||
},
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
}
|
||||
|
||||
@@ -4,14 +4,6 @@ const { execSync } = require('child_process')
|
||||
const padStart = require('string.prototype.padstart')
|
||||
const { logWithSpinner, stopSpinner } = require('./spinner')
|
||||
|
||||
const wrapForTest = fn => {
|
||||
return (...args) => {
|
||||
if (!process.env.VUE_CLI_TEST) {
|
||||
return fn.apply(null, args)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const format = (label, msg) => {
|
||||
return msg.split('\n').map((line, i) => {
|
||||
return i === 0
|
||||
@@ -56,12 +48,10 @@ exports.clearConsole = title => {
|
||||
}
|
||||
}
|
||||
|
||||
// wrap all log utils for tests
|
||||
Object.keys(exports).forEach(key => {
|
||||
exports[key] = wrapForTest(exports[key])
|
||||
})
|
||||
|
||||
exports.hasYarn = (() => {
|
||||
if (process.env.VUE_CLI_TEST) {
|
||||
return true
|
||||
}
|
||||
try {
|
||||
execSync('yarnpkg --version', { stdio: 'ignore' })
|
||||
return true
|
||||
@@ -71,6 +61,9 @@ exports.hasYarn = (() => {
|
||||
})()
|
||||
|
||||
exports.hasGit = () => {
|
||||
if (process.env.VUE_CLI_TEST) {
|
||||
return true
|
||||
}
|
||||
try {
|
||||
execSync('git --version', { stdio: 'ignore' })
|
||||
return true
|
||||
|
||||
@@ -9,7 +9,7 @@ const clearConsole = require('./util/clearConsole')
|
||||
const PromptModuleAPI = require('./PromptModuleAPI')
|
||||
const writeFileTree = require('./util/writeFileTree')
|
||||
const formatFeatures = require('./util/formatfeatures')
|
||||
const updatePackageForDev = require('./util/updatePackageForDev')
|
||||
const setupDevProject = require('./util/setupDevProject')
|
||||
const exec = require('util').promisify(require('child_process').exec)
|
||||
|
||||
const {
|
||||
@@ -52,7 +52,70 @@ module.exports = class Creator {
|
||||
async create () {
|
||||
const name = this.name
|
||||
const targetDir = process.env.VUE_CLI_CONTEXT = this.context
|
||||
const options = await this.promptAndResolveOptions()
|
||||
|
||||
// write base package.json to disk
|
||||
clearConsole()
|
||||
logWithSpinner('✨', `Creating project in ${chalk.yellow(targetDir)}.`)
|
||||
writeFileTree(targetDir, {
|
||||
'package.json': JSON.stringify({
|
||||
name,
|
||||
version: '0.1.0',
|
||||
private: true
|
||||
}, null, 2)
|
||||
})
|
||||
|
||||
// intilaize git repository
|
||||
if (hasGit) {
|
||||
logWithSpinner('🗃', `Initializing git repository...`)
|
||||
await exec('git init', { cwd: targetDir })
|
||||
}
|
||||
|
||||
// install plugins
|
||||
logWithSpinner('⚙', `Installing CLI plugins. This might take a while...`)
|
||||
const deps = Object.keys(options.plugins)
|
||||
if (process.env.VUE_CLI_TEST) {
|
||||
// in development, avoid installation process
|
||||
setupDevProject(targetDir, deps)
|
||||
} else {
|
||||
await installDeps(targetDir, options, deps)
|
||||
}
|
||||
|
||||
// run generator
|
||||
logWithSpinner('🚀', `Invoking generators...`)
|
||||
const generator = new Generator(targetDir, options, this)
|
||||
await generator.generate()
|
||||
|
||||
// install additional deps (injected by generators)
|
||||
logWithSpinner('📦', `Installing additional dependencies...`)
|
||||
if (!process.env.VUE_CLI_TEST) {
|
||||
await installDeps(targetDir, options)
|
||||
}
|
||||
|
||||
// run complete cbs if any
|
||||
for (const cb of this.createCompleteCbs) {
|
||||
await cb()
|
||||
}
|
||||
|
||||
// commit initial state
|
||||
if (hasGit) {
|
||||
await exec('git add -A', { cwd: targetDir, stdio: 'ignore' })
|
||||
await exec('git commit -m init', { cwd: targetDir, stdio: 'ignore' })
|
||||
}
|
||||
|
||||
// log instructions
|
||||
stopSpinner()
|
||||
log()
|
||||
log(`🎉 Successfully created project ${chalk.yellow(name)}.`)
|
||||
log(
|
||||
`👉 Get started with the following commands:\n\n` +
|
||||
chalk.cyan(` ${chalk.gray('$')} cd ${name}\n`) +
|
||||
chalk.cyan(` ${chalk.gray('$')} ${options.packageManager === 'yarn' ? 'yarn serve' : 'npm run serve'}`)
|
||||
)
|
||||
log()
|
||||
}
|
||||
|
||||
async promptAndResolveOptions () {
|
||||
// prompt
|
||||
clearConsole()
|
||||
const answers = await inquirer.prompt(this.resolveFinalPrompts())
|
||||
@@ -81,69 +144,11 @@ module.exports = class Creator {
|
||||
|
||||
// inject core service
|
||||
options.plugins['@vue/cli-service'] = {
|
||||
projectName: name
|
||||
projectName: this.name
|
||||
}
|
||||
|
||||
debug('vue:cli-ptions')(options)
|
||||
|
||||
// write base package.json to disk
|
||||
clearConsole()
|
||||
logWithSpinner('✨', `Creating project in ${chalk.yellow(targetDir)}.`)
|
||||
writeFileTree(targetDir, {
|
||||
'package.json': JSON.stringify({
|
||||
name,
|
||||
version: '0.1.0',
|
||||
private: true
|
||||
}, null, 2)
|
||||
})
|
||||
|
||||
// intilaize git repository
|
||||
if (hasGit) {
|
||||
logWithSpinner('🗃', `Initializing git repository...`)
|
||||
await exec('git init', { cwd: targetDir })
|
||||
}
|
||||
|
||||
// install plugins
|
||||
logWithSpinner('⚙', `Installing CLI plugins. This might take a while...`)
|
||||
const deps = Object.keys(options.plugins)
|
||||
if (process.env.VUE_CLI_DEBUG) {
|
||||
// in development, use linked packages
|
||||
updatePackageForDev(targetDir, deps)
|
||||
await installDeps(targetDir, options)
|
||||
} else {
|
||||
await installDeps(targetDir, options, deps)
|
||||
}
|
||||
|
||||
// run generator
|
||||
logWithSpinner('🚀', `Invoking generators...`)
|
||||
const generator = new Generator(targetDir, options, this)
|
||||
await generator.generate()
|
||||
|
||||
// install additional deps (injected by generators)
|
||||
logWithSpinner('📦', `Installing additional dependencies...`)
|
||||
await installDeps(targetDir, options)
|
||||
|
||||
// run complete cbs if any
|
||||
for (const cb of this.createCompleteCbs) {
|
||||
await cb()
|
||||
}
|
||||
|
||||
// commit initial state
|
||||
if (hasGit) {
|
||||
await exec('git add -A', { cwd: targetDir })
|
||||
await exec('git commit -m init', { cwd: targetDir })
|
||||
}
|
||||
|
||||
// log instructions
|
||||
stopSpinner()
|
||||
log()
|
||||
log(`🎉 Successfully created project ${chalk.yellow(name)}.`)
|
||||
log(
|
||||
`👉 Get started with the following commands:\n\n` +
|
||||
chalk.cyan(` ${chalk.gray('$')} cd ${name}\n`) +
|
||||
chalk.cyan(` ${chalk.gray('$')} ${options.packageManager === 'yarn' ? 'yarn dev' : 'npm run dev'}`)
|
||||
)
|
||||
log()
|
||||
return options
|
||||
}
|
||||
|
||||
resolveIntroPrompts () {
|
||||
|
||||
@@ -3,7 +3,10 @@ const os = require('os')
|
||||
const path = require('path')
|
||||
const { error, hasYarn } = require('@vue/cli-shared-utils')
|
||||
|
||||
const rcPath = exports.rcPath = path.join(os.homedir(), '.vuerc')
|
||||
const rcPath = exports.rcPath = (
|
||||
process.env.VUE_CLI_CONFIG_PATH ||
|
||||
path.join(os.homedir(), '.vuerc')
|
||||
)
|
||||
|
||||
exports.defaults = {
|
||||
useTaobaoRegistry: null,
|
||||
@@ -45,7 +48,7 @@ exports.saveOptions = options => {
|
||||
} catch (e) {
|
||||
error(
|
||||
`Error saving preferences: ` +
|
||||
`make sure you have write access to ~/.vuerc.\n` +
|
||||
`make sure you have write access to ${rcPath}.\n` +
|
||||
`(${e.message})`
|
||||
)
|
||||
}
|
||||
|
||||
+8
-1
@@ -2,8 +2,9 @@
|
||||
|
||||
const fs = require('fs')
|
||||
const path = require('path')
|
||||
const mkdirp = require('mkdirp')
|
||||
|
||||
module.exports = function updatePackageForDev (targetDir, deps) {
|
||||
module.exports = function setupDevProject (targetDir, deps) {
|
||||
const pkg = require(path.resolve(targetDir, 'package.json'))
|
||||
pkg.devDependencies = {}
|
||||
deps.forEach(dep => {
|
||||
@@ -18,4 +19,10 @@ module.exports = function updatePackageForDev (targetDir, deps) {
|
||||
path.resolve(targetDir, 'package.json'),
|
||||
JSON.stringify(pkg, null, 2)
|
||||
)
|
||||
const binPath = path.join(targetDir, 'node_modules', '.bin')
|
||||
mkdirp.sync(binPath)
|
||||
fs.symlinkSync(
|
||||
require.resolve('@vue/cli-service/bin/vue-cli-service'),
|
||||
path.join(binPath, 'vue-cli-service')
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
process.env.VUE_CLI_TEST = true
|
||||
process.env.VUE_CLI_CONFIG_PATH = require('path').join(__dirname, '.vuerc')
|
||||
@@ -0,0 +1,6 @@
|
||||
const { fs } = require('memfs')
|
||||
|
||||
// overwrite config path when fs is mocked
|
||||
process.env.VUE_CLI_CONFIG_PATH = '/.vuerc'
|
||||
|
||||
module.exports = fs
|
||||
@@ -1,3 +1,9 @@
|
||||
it('should pass', () => {
|
||||
jest.mock('fs')
|
||||
|
||||
const { saveOptions } = require('@vue/cli/lib/options')
|
||||
|
||||
it('should pass', () => {
|
||||
saveOptions({
|
||||
useTaobaoRegistry: true
|
||||
})
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user