From a433902d46b48c912a6c2181ae5cb1428fce9a1f Mon Sep 17 00:00:00 2001 From: yuangongji Date: Fri, 7 May 2021 21:07:15 +0800 Subject: [PATCH 01/10] feat: add emits declaration --- .../codemods/vue/add-emit-declaration.js | 74 +++++++++++++++++++ generator/codemods/vue/index.js | 12 +++ generator/index.js | 8 ++ 3 files changed, 94 insertions(+) create mode 100644 generator/codemods/vue/add-emit-declaration.js create mode 100644 generator/codemods/vue/index.js diff --git a/generator/codemods/vue/add-emit-declaration.js b/generator/codemods/vue/add-emit-declaration.js new file mode 100644 index 0000000..8959092 --- /dev/null +++ b/generator/codemods/vue/add-emit-declaration.js @@ -0,0 +1,74 @@ +/** + * @param {Object} context + * @param {import('jscodeshift').JSCodeshift} context.j + * @param {ReturnType} context.root + */ +module.exports = function addEmitDeclaration(context) { + const { j, root } = context + + // this.$emit('xxx') => emits: ['xxx'] + const this$emits = root.find(j.CallExpression, { + callee: { + type: 'MemberExpression', + object: { type: 'ThisExpression' }, + property: { + type: 'Identifier', + name: '$emit' + } + } + }) + + const emits = [] + for (let i = 0; i < this$emits.length; i++) { + const arg = this$emits.at(i).get().node.arguments[0] + if (arg.type === 'StringLiteral') { + emits.push(arg.value) + } + } + + if (emits.length === 0) { + return + } + + const defaultObject = root + .find(j.ExportDefaultDeclaration) + .at(0) + .find(j.ObjectExpression) + .at(0) + + let oldEmits = emits + let emitsProperty = defaultObject.find(j.ObjectProperty, { + key: { + type: 'Identifier', + name: 'emits' + } + }) + if (emitsProperty.length > 0) { + oldEmits = emitsProperty + .at(0) + .get() + .node.value.elements.map(el => el.value) + + let hasChange = false + for (const el of emits) { + if (!oldEmits.includes(el)) { + oldEmits.push(el) + hasChange = true + } + } + if (!hasChange) { + return + } + emitsProperty.remove() + } + + defaultObject.replaceWith(({ node }) => { + node.properties.unshift( + j.objectProperty( + j.identifier('emits'), + j.arrayExpression(oldEmits.map(el => j.stringLiteral(el))) + ) + ) + return node + }) +} diff --git a/generator/codemods/vue/index.js b/generator/codemods/vue/index.js new file mode 100644 index 0000000..b6aa4ed --- /dev/null +++ b/generator/codemods/vue/index.js @@ -0,0 +1,12 @@ +/** @type {import('jscodeshift').Transform} */ +module.exports = function(fileInfo, api) { + const j = api.jscodeshift + const root = j(fileInfo.source) + const context = { j, root } + + require('./add-emit-declaration')(context) + + return root.toSource({ lineTerminator: '\n' }) +} + +module.exports.parser = 'babylon' diff --git a/generator/index.js b/generator/index.js index d9f4604..e97a555 100644 --- a/generator/index.js +++ b/generator/index.js @@ -22,6 +22,14 @@ module.exports = (api) => { const globalAPITransform = require('./codemods/global-api') api.transformScript(api.entryFile, globalAPITransform) + const vueTransform = require('./codemods/vue') + const vueFiles = Object.keys(api.generator.files).filter(el => + el.endsWith('.vue') + ) + for (let i = 0; i < vueFiles.length; i++) { + api.transformScript(vueFiles[i], vueTransform) + } + if (api.hasPlugin('eslint')) { api.extendPackage({ devDependencies: { From 5fff976f09390644114a3d6dc2c9c9faba63c638 Mon Sep 17 00:00:00 2001 From: yuangongji Date: Mon, 10 May 2021 21:03:52 +0800 Subject: [PATCH 02/10] add deep option for watch --- generator/codemods/vue/add-watch-deep.js | 124 +++++++++++++++++++++++ generator/codemods/vue/index.js | 1 + 2 files changed, 125 insertions(+) create mode 100644 generator/codemods/vue/add-watch-deep.js diff --git a/generator/codemods/vue/add-watch-deep.js b/generator/codemods/vue/add-watch-deep.js new file mode 100644 index 0000000..edbfe4d --- /dev/null +++ b/generator/codemods/vue/add-watch-deep.js @@ -0,0 +1,124 @@ +/** + * @param {Object} context + * @param {import('jscodeshift').JSCodeshift} context.j + * @param {ReturnType} context.root + */ +module.exports = function addEmitDeclaration(context) { + const { j, root } = context + + // this.$watch(...) add deep option + const this$watches = root.find(j.CallExpression, { + callee: { + type: 'MemberExpression', + object: { type: 'ThisExpression' }, + property: { + type: 'Identifier', + name: '$watch' + } + } + }) + + for (let i = 0; i < this$watches.length; i++) { + const watchFunc = this$watches.at(i) + const deepProperty = watchFunc.find(j.ObjectProperty, { + key: { + type: 'Identifier', + name: 'deep' + } + }) + if (deepProperty.length > 0) { + continue + } + const args = watchFunc.get().node.arguments + if (args.length < 2) { + continue + } + if (args[1].type != 'ObjectExpression') { + if (args.length < 3) { + watchFunc.replaceWith(nodePath => { + nodePath.node.arguments.push(j.objectExpression([])) + return nodePath.node + }) + } + const target = watchFunc.find(j.ObjectExpression).at(0) + target.replaceWith(nodePath => { + nodePath.node.properties.push( + j.objectProperty(j.identifier('deep'), j.booleanLiteral(true)) + ) + return nodePath.node + }) + } + } + + // watch: {...} add deep option + const watchFuncs = root + .find(j.ExportDefaultDeclaration) + .at(0) + .find(j.ObjectExpression) + .at(0) + .find(j.ObjectProperty, { + key: { + type: 'Identifier', + name: 'watch' + } + }) + .at(0) + .find(j.ObjectExpression) + .at(0) + .find(j.ObjectProperty) + + for (let i = 0; i < watchFuncs.length; i++) { + const watchProperty = watchFuncs.at(i) + if (!inExportDefaultLevel(watchProperty, 2)) { + continue + } + const deepProperty = watchProperty.find(j.ObjectProperty, { + key: { + type: 'Identifier', + name: 'deep' + } + }) + if (deepProperty.length > 0) { + continue + } + + if (watchProperty.get().node.value.type === 'ObjectExpression') { + const target = watchProperty.find(j.ObjectExpression).at(0) + target.replaceWith(nodePath => { + nodePath.node.properties.push( + j.objectProperty(j.identifier('deep'), j.booleanLiteral(true)) + ) + return nodePath.node + }) + } else { + watchProperty.replaceWith(nodePath => { + nodePath.node.value = j.objectExpression([ + j.objectProperty(j.identifier('handler'), nodePath.node.value), + j.objectProperty(j.identifier('deep'), j.booleanLiteral(true)) + ]) + return nodePath.node + }) + } + } +} + +function getExportDefaultLevel(collection) { + let path = collection.get() + let level = 0 + while (path) { + if (path.node.type === 'ExportDefaultDeclaration') { + return level + } + path = path.parentPath + level++ + } + return -1 +} + +function inExportDefaultLevel(collection, level) { + const lvl = getExportDefaultLevel(collection) + if (level * 3 === lvl) { + return true + } + return false +} diff --git a/generator/codemods/vue/index.js b/generator/codemods/vue/index.js index b6aa4ed..d51f32e 100644 --- a/generator/codemods/vue/index.js +++ b/generator/codemods/vue/index.js @@ -5,6 +5,7 @@ module.exports = function(fileInfo, api) { const context = { j, root } require('./add-emit-declaration')(context) + require('./add-watch-deep')(context) return root.toSource({ lineTerminator: '\n' }) } From c237c50d6234c13f264a41fa0528281f981f6afb Mon Sep 17 00:00:00 2001 From: ygj6 Date: Tue, 11 May 2021 20:18:21 +0800 Subject: [PATCH 03/10] feet: remove event native; add transition from --- generator/codemods/vue-addition/index.js | 28 ++++++++++++++++++++++++ generator/index.js | 12 ++++++++++ 2 files changed, 40 insertions(+) create mode 100644 generator/codemods/vue-addition/index.js diff --git a/generator/codemods/vue-addition/index.js b/generator/codemods/vue-addition/index.js new file mode 100644 index 0000000..918fa38 --- /dev/null +++ b/generator/codemods/vue-addition/index.js @@ -0,0 +1,28 @@ +module.exports = function(files, filename) { + let content = files[filename] + content = removeEventNative(content) + content = addTransitionFrom(content) + files[filename] = content +} + +// template +// v-on:event.native => v-on:event +// @event.native => @event +function removeEventNative(content) { + const reg = new RegExp( + '(?<=)', + 'g' + ) + return content.replace(reg, '') +} + +// style +// .xxx-enter => .xxx-enter-from +// .xxx-leave => .xxx-leave-from +function addTransitionFrom(content) { + const reg = new RegExp( + '(?<=][\\s\\S]*?\\s\\.[A-Za-z0-9_-]+-)(enter|leave)(?=[,{\\s][\\s\\S]*?)', + 'g' + ) + return content.replace(reg, '$1-from') +} diff --git a/generator/index.js b/generator/index.js index e97a555..f6d2480 100644 --- a/generator/index.js +++ b/generator/index.js @@ -134,3 +134,15 @@ module.exports = (api) => { api.exitLog('Documentation available at https://github.com/vuejs/vue-test-utils-next') } } + +module.exports.hooks = api => { + api.postProcessFiles(files => { + const vueTransform = require('./codemods/vue-addition') + const vueFiles = Object.keys(api.generator.files).filter(el => + el.endsWith('.vue') + ) + for (let i = 0; i < vueFiles.length; i++) { + vueTransform(files, vueFiles[i]) + } + }) +} From da31b588a885762d4208541df3945ac6ecb25fa6 Mon Sep 17 00:00:00 2001 From: ygj6 Date: Wed, 12 May 2021 11:36:35 +0800 Subject: [PATCH 04/10] feat: implement tree-shaking api --- generator/codemods/global-api/index.js | 3 +++ generator/codemods/global-api/next-tick.js | 30 +++++++++++++++++++++ generator/codemods/global-api/observable.js | 30 +++++++++++++++++++++ generator/codemods/global-api/version.js | 29 ++++++++++++++++++++ 4 files changed, 92 insertions(+) create mode 100644 generator/codemods/global-api/next-tick.js create mode 100644 generator/codemods/global-api/observable.js create mode 100644 generator/codemods/global-api/version.js diff --git a/generator/codemods/global-api/index.js b/generator/codemods/global-api/index.js index 6ab3557..9d3720e 100644 --- a/generator/codemods/global-api/index.js +++ b/generator/codemods/global-api/index.js @@ -11,6 +11,9 @@ module.exports = function(fileInfo, api) { require('./remove-production-tip')(context) require('./remove-vue-use')(context) require('./remove-contextual-h')(context) + require('./next-tick')(context) + require('./observable')(context) + require('./version')(context) // remove extraneous imports const removeExtraneousImport = require('../utils/remove-extraneous-import') diff --git a/generator/codemods/global-api/next-tick.js b/generator/codemods/global-api/next-tick.js new file mode 100644 index 0000000..f713005 --- /dev/null +++ b/generator/codemods/global-api/next-tick.js @@ -0,0 +1,30 @@ +/** + * @param {Object} context + * @param {import('jscodeshift').JSCodeshift} context.j + * @param {ReturnType} context.root + */ +module.exports = function createAppMount(context) { + const { j, root } = context + + // Vue.nextTick(() => {}) + const nextTickCalls = root.find(j.CallExpression, n => { + return ( + n.callee.type === 'MemberExpression' && + n.callee.property.name === 'nextTick' && + n.callee.object.name === 'Vue' + ) + }) + + if (!nextTickCalls.length) { + return + } + + const addImport = require('../utils/add-import') + addImport(context, { imported: 'nextTick' }, 'vue') + + nextTickCalls.replaceWith(({ node }) => { + const el = node.arguments[0] + + return j.callExpression(j.identifier('nextTick'), [el]) + }) +} diff --git a/generator/codemods/global-api/observable.js b/generator/codemods/global-api/observable.js new file mode 100644 index 0000000..9a01221 --- /dev/null +++ b/generator/codemods/global-api/observable.js @@ -0,0 +1,30 @@ +/** + * @param {Object} context + * @param {import('jscodeshift').JSCodeshift} context.j + * @param {ReturnType} context.root + */ +module.exports = function createAppMount(context) { + const { j, root } = context + + // Vue.observable(state) + const observableCalls = root.find(j.CallExpression, n => { + return ( + n.callee.type === 'MemberExpression' && + n.callee.property.name === 'observable' && + n.callee.object.name === 'Vue' + ) + }) + + if (!observableCalls.length) { + return + } + + const addImport = require('../utils/add-import') + addImport(context, { imported: 'reactive' }, 'vue') + + observableCalls.replaceWith(({ node }) => { + const el = node.arguments[0] + + return j.callExpression(j.identifier('reactive'), [el]) + }) +} diff --git a/generator/codemods/global-api/version.js b/generator/codemods/global-api/version.js new file mode 100644 index 0000000..fa8e894 --- /dev/null +++ b/generator/codemods/global-api/version.js @@ -0,0 +1,29 @@ +/** + * @param {Object} context + * @param {import('jscodeshift').JSCodeshift} context.j + * @param {ReturnType} context.root + */ +module.exports = function createAppMount(context) { + const { j, root } = context + + // Vue.version + const versionCalls = root.find(j.MemberExpression, n => { + return ( + n.property.name === 'version' && + n.object.name === 'Vue' + ) + }) + + if (!versionCalls.length) { + return + } + + const addImport = require('../utils/add-import') + addImport(context, { imported: 'version' }, 'vue') + + versionCalls.replaceWith(({ node }) => { + const property = node.property.name + + return j.identifier(property) + }) +} From 448f2f75cc8df24b3db1a678010494b2501c276c Mon Sep 17 00:00:00 2001 From: ygj6 Date: Wed, 12 May 2021 11:50:33 +0800 Subject: [PATCH 05/10] feat: rename deprecated lifecycle --- generator/codemods/vue/index.js | 1 + generator/codemods/vue/rename-lifecycle.js | 28 ++++++++++++++++++++++ 2 files changed, 29 insertions(+) create mode 100644 generator/codemods/vue/rename-lifecycle.js diff --git a/generator/codemods/vue/index.js b/generator/codemods/vue/index.js index d51f32e..b0d67ee 100644 --- a/generator/codemods/vue/index.js +++ b/generator/codemods/vue/index.js @@ -6,6 +6,7 @@ module.exports = function(fileInfo, api) { require('./add-emit-declaration')(context) require('./add-watch-deep')(context) + require('./rename-lifecycle')(context) return root.toSource({ lineTerminator: '\n' }) } diff --git a/generator/codemods/vue/rename-lifecycle.js b/generator/codemods/vue/rename-lifecycle.js new file mode 100644 index 0000000..48f3673 --- /dev/null +++ b/generator/codemods/vue/rename-lifecycle.js @@ -0,0 +1,28 @@ +/** @type {import('jscodeshift').Transform} */ + +const DEPRECATED_LIFECYCLE = Object.create(null) +DEPRECATED_LIFECYCLE.destroyed = 'unmounted' +DEPRECATED_LIFECYCLE.beforeDestroy = 'beforeUnmount' + +module.exports = function renameLifecycle(context) { + const { j, root } = context + + const renameDeprecatedLifecycle = path => { + const name = path.node.key.name + + if ( + DEPRECATED_LIFECYCLE[name] && + path.parent && + path.parent.parent && + path.parent.parent.value.type === 'ExportDefaultDeclaration' + ) { + path.value.key.name = DEPRECATED_LIFECYCLE[name] + } + } + + root.find(j.ObjectProperty).forEach(renameDeprecatedLifecycle) + root.find(j.ObjectMethod).forEach(renameDeprecatedLifecycle) + root.find(j.ClassProperty).forEach(renameDeprecatedLifecycle) + + return root.toSource({ lineTerminator: '\n' }) +} From 267d9771dcde6f79fa6ca117c91cb3138506da99 Mon Sep 17 00:00:00 2001 From: ygj6 Date: Thu, 13 May 2021 08:43:52 +0800 Subject: [PATCH 06/10] split app mount expression createApp().mount() => app=createApp();app.mount() --- .../codemods/global-api/create-app-mount.js | 52 +++++++++++++------ 1 file changed, 35 insertions(+), 17 deletions(-) diff --git a/generator/codemods/global-api/create-app-mount.js b/generator/codemods/global-api/create-app-mount.js index 6cba44d..b878986 100644 --- a/generator/codemods/global-api/create-app-mount.js +++ b/generator/codemods/global-api/create-app-mount.js @@ -7,13 +7,21 @@ module.exports = function createAppMount(context) { const { j, root } = context // new Vue(...).$mount() - const mountCalls = root.find(j.CallExpression, n => { - return ( - n.callee.type === 'MemberExpression' && - n.callee.property.name === '$mount' && - n.callee.object.type === 'NewExpression' && - n.callee.object.callee.name === 'Vue' - ) + const mountCalls = root.find(j.ExpressionStatement, { + expression: { + type: 'CallExpression', + callee: { + type: 'MemberExpression', + object: { + type: 'NewExpression', + callee: { + type: 'Identifier', + name: 'Vue' + } + }, + property: { type: 'Identifier', name: '$mount' } + } + } }) if (!mountCalls.length) { @@ -23,16 +31,26 @@ module.exports = function createAppMount(context) { const addImport = require('../utils/add-import') addImport(context, { imported: 'createApp' }, 'vue') - mountCalls.replaceWith(({ node }) => { - let rootProps = node.callee.object.arguments[0] - const el = node.arguments[0] + const rootProps = mountCalls.at(0).get().node.expression.callee.object + .arguments + mountCalls.insertBefore( + j.variableDeclaration('const', [ + j.variableDeclarator( + j.identifier('app'), + j.callExpression(j.identifier('createApp'), rootProps) + ) + ]) + ) - return j.callExpression( - j.memberExpression( - j.callExpression(j.identifier('createApp'), [rootProps]), - j.identifier('mount') - ), - [el] + const args = mountCalls.at(0).get().node.expression.arguments + mountCalls.insertBefore( + j.expressionStatement( + j.callExpression( + j.memberExpression(j.identifier('app'), j.identifier('mount'), false), + args + ) ) - }) + ) + + mountCalls.remove() } From 49af33f99242fed0b96fd1adafc52e533ec1a610 Mon Sep 17 00:00:00 2001 From: ygj6 Date: Thu, 13 May 2021 08:53:07 +0800 Subject: [PATCH 07/10] feat: adapt global filters --- .../codemods/global-api/global-filter.js | 75 +++++++++++++++++++ generator/codemods/global-api/index.js | 1 + 2 files changed, 76 insertions(+) create mode 100644 generator/codemods/global-api/global-filter.js diff --git a/generator/codemods/global-api/global-filter.js b/generator/codemods/global-api/global-filter.js new file mode 100644 index 0000000..714043a --- /dev/null +++ b/generator/codemods/global-api/global-filter.js @@ -0,0 +1,75 @@ +/** + * @param {Object} context + * @param {import('jscodeshift').JSCodeshift} context.j + * @param {ReturnType} context.root + */ +module.exports = function createAppMount(context) { + const { j, root } = context + + // find const appName = createApp(...) + const appDeclare = root.find(j.VariableDeclarator, { + id: { type: 'Identifier' }, + init: { + type: 'CallExpression', + callee: { + type: 'Identifier', + name: 'createApp' + } + } + }) + if (!appDeclare.length) { + return + } + const appName = appDeclare.at(0).get().node.id.name + + // Vue.filter('filterName', function(value) {}) => + // app.config.globalProperties.$filters = { filterName(value) {} } + const filters = root.find(j.ExpressionStatement, { + expression: { + type: 'CallExpression', + callee: { + type: 'MemberExpression', + object: { type: 'Identifier', name: 'Vue' }, + property: { type: 'Identifier', name: 'filter' } + } + } + }) + if (!filters.length) { + return + } + + const methods = [] + for (let i = 0; i < filters.length; i++) { + const filter = filters.at(i) + const args = filter.get().node.expression.arguments + + methods.push( + j.objectMethod( + 'method', + j.identifier(args[0].value), + args[1].params, + args[1].body + ) + ) + } + + filters + .at(0) + .insertBefore( + j.expressionStatement( + j.assignmentExpression( + '=', + j.memberExpression( + j.identifier(appName), + j.identifier('config.globalProperties.$filters'), + false + ), + j.objectExpression(methods) + ) + ) + ) + + for (let i = 0; i < filters.length; i++) { + filters.at(i).remove() + } +} diff --git a/generator/codemods/global-api/index.js b/generator/codemods/global-api/index.js index 9d3720e..5891f9a 100644 --- a/generator/codemods/global-api/index.js +++ b/generator/codemods/global-api/index.js @@ -14,6 +14,7 @@ module.exports = function(fileInfo, api) { require('./next-tick')(context) require('./observable')(context) require('./version')(context) + require('./global-filter')(context) // remove extraneous imports const removeExtraneousImport = require('../utils/remove-extraneous-import') From 8b103121746b07ec2c5015b5a60036296b7e21b2 Mon Sep 17 00:00:00 2001 From: wangsongc Date: Mon, 24 May 2021 11:28:14 +0800 Subject: [PATCH 08/10] test: fix global-api tests --- .../codemods/global-api/__testfixtures__/basic.output.js | 3 ++- .../global-api/__testfixtures__/custom-root-prop.output.js | 6 ++++-- .../global-api/__testfixtures__/vue-router.output.js | 3 ++- .../codemods/global-api/__testfixtures__/vuex.output.js | 7 ++++--- 4 files changed, 12 insertions(+), 7 deletions(-) diff --git a/generator/codemods/global-api/__testfixtures__/basic.output.js b/generator/codemods/global-api/__testfixtures__/basic.output.js index 684d042..b0788dd 100644 --- a/generator/codemods/global-api/__testfixtures__/basic.output.js +++ b/generator/codemods/global-api/__testfixtures__/basic.output.js @@ -1,4 +1,5 @@ import { createApp } from 'vue'; import App from './App.vue'; -createApp(App).mount('#app'); +const app = createApp(App); +app.mount('#app'); diff --git a/generator/codemods/global-api/__testfixtures__/custom-root-prop.output.js b/generator/codemods/global-api/__testfixtures__/custom-root-prop.output.js index b9ade05..59e84ff 100644 --- a/generator/codemods/global-api/__testfixtures__/custom-root-prop.output.js +++ b/generator/codemods/global-api/__testfixtures__/custom-root-prop.output.js @@ -1,7 +1,9 @@ import { createApp, h } from 'vue'; import App from './App.vue'; -createApp({ +const app = createApp({ myOption: 'hello!', render: () => h(App), -}).mount('#app'); +}); + +app.mount('#app'); diff --git a/generator/codemods/global-api/__testfixtures__/vue-router.output.js b/generator/codemods/global-api/__testfixtures__/vue-router.output.js index 82ac74e..138eb97 100644 --- a/generator/codemods/global-api/__testfixtures__/vue-router.output.js +++ b/generator/codemods/global-api/__testfixtures__/vue-router.output.js @@ -2,4 +2,5 @@ import { createApp } from 'vue'; import App from './App.vue'; import router from './router'; -createApp(App).use(router).mount('#app'); +const app = createApp(App).use(router); +app.mount('#app'); diff --git a/generator/codemods/global-api/__testfixtures__/vuex.output.js b/generator/codemods/global-api/__testfixtures__/vuex.output.js index f1a5d84..958566a 100644 --- a/generator/codemods/global-api/__testfixtures__/vuex.output.js +++ b/generator/codemods/global-api/__testfixtures__/vuex.output.js @@ -3,6 +3,7 @@ import App from './App.vue'; import store from './store'; import anotherStore from './another-store'; -createApp(App).use(store).mount('#app'); - -createApp(App).use(anotherStore).mount('#app'); +const app = createApp({}).use(h => h(App)); +app.mount('#app'); +const app = createApp({}).use(h => h(App)); +app.mount('#app'); From 1b870655d034ed55fd4745b16151e7eda2057959 Mon Sep 17 00:00:00 2001 From: ygj6 Date: Mon, 24 May 2021 11:38:29 +0800 Subject: [PATCH 09/10] ci: add github action --- .github/workflows/ci.yml | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) create mode 100644 .github/workflows/ci.yml diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..b16a639 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,27 @@ +name: CI + +on: + push: + branches: [ master ] + pull_request: + branches: [ master ] + +jobs: + build: + + runs-on: ubuntu-latest + + strategy: + matrix: + node-version: [10.x, 12.x, 14.x, 15.x] + + steps: + - uses: actions/checkout@v2 + - name: Use Node.js ${{ matrix.node-version }} + uses: actions/setup-node@v2 + with: + node-version: ${{ matrix.node-version }} + - name: Run test + run: | + npm install + npm test From d97e07e9ca19be9f7991f630165c1138021552ee Mon Sep 17 00:00:00 2001 From: ygj6 Date: Tue, 25 May 2021 14:49:25 +0800 Subject: [PATCH 10/10] test: add testcase --- .../global-api/__testfixtures__/next-tick.input.js | 5 +++++ .../global-api/__testfixtures__/next-tick.output.js | 5 +++++ .../codemods/global-api/__tests__/global-api-test.js | 1 + .../__testfixtures__/add-emit-declaration.input.js | 9 +++++++++ .../__testfixtures__/add-emit-declaration.output.js | 11 +++++++++++ .../vue/__testfixtures__/rename-lifecycle.input.js | 8 ++++++++ .../vue/__testfixtures__/rename-lifecycle.output.js | 8 ++++++++ generator/codemods/vue/__tests__/vue-test.js | 6 ++++++ 8 files changed, 53 insertions(+) create mode 100644 generator/codemods/global-api/__testfixtures__/next-tick.input.js create mode 100644 generator/codemods/global-api/__testfixtures__/next-tick.output.js create mode 100644 generator/codemods/vue/__testfixtures__/add-emit-declaration.input.js create mode 100644 generator/codemods/vue/__testfixtures__/add-emit-declaration.output.js create mode 100644 generator/codemods/vue/__testfixtures__/rename-lifecycle.input.js create mode 100644 generator/codemods/vue/__testfixtures__/rename-lifecycle.output.js create mode 100644 generator/codemods/vue/__tests__/vue-test.js diff --git a/generator/codemods/global-api/__testfixtures__/next-tick.input.js b/generator/codemods/global-api/__testfixtures__/next-tick.input.js new file mode 100644 index 0000000..1d22568 --- /dev/null +++ b/generator/codemods/global-api/__testfixtures__/next-tick.input.js @@ -0,0 +1,5 @@ +import Vue from 'vue'; + +Vue.nextTick(() => { + console.log('foo'); +}) diff --git a/generator/codemods/global-api/__testfixtures__/next-tick.output.js b/generator/codemods/global-api/__testfixtures__/next-tick.output.js new file mode 100644 index 0000000..e69e67e --- /dev/null +++ b/generator/codemods/global-api/__testfixtures__/next-tick.output.js @@ -0,0 +1,5 @@ +import { nextTick } from 'vue'; + +nextTick(() => { + console.log('foo'); +}) diff --git a/generator/codemods/global-api/__tests__/global-api-test.js b/generator/codemods/global-api/__tests__/global-api-test.js index ab05aaa..f63f9c9 100644 --- a/generator/codemods/global-api/__tests__/global-api-test.js +++ b/generator/codemods/global-api/__tests__/global-api-test.js @@ -8,3 +8,4 @@ defineTest(__dirname, 'index', null, 'custom-root-prop') defineTest(__dirname, 'index', null, 'vue-router') defineTest(__dirname, 'index', null, 'vuex') defineTest(__dirname, 'index', null, 'vue-use') +defineTest(__dirname, 'index', null, 'next-tick') diff --git a/generator/codemods/vue/__testfixtures__/add-emit-declaration.input.js b/generator/codemods/vue/__testfixtures__/add-emit-declaration.input.js new file mode 100644 index 0000000..4b02f03 --- /dev/null +++ b/generator/codemods/vue/__testfixtures__/add-emit-declaration.input.js @@ -0,0 +1,9 @@ +export default { + props: ['text'], + methods: { + input: function(){ + this.$emit('increment'); + this.$emit('decrement'); + } + } +} diff --git a/generator/codemods/vue/__testfixtures__/add-emit-declaration.output.js b/generator/codemods/vue/__testfixtures__/add-emit-declaration.output.js new file mode 100644 index 0000000..0426910 --- /dev/null +++ b/generator/codemods/vue/__testfixtures__/add-emit-declaration.output.js @@ -0,0 +1,11 @@ +export default { + emits: ["increment", "decrement"], + props: ['text'], + + methods: { + input: function(){ + this.$emit('increment'); + this.$emit('decrement'); + } + } +}; diff --git a/generator/codemods/vue/__testfixtures__/rename-lifecycle.input.js b/generator/codemods/vue/__testfixtures__/rename-lifecycle.input.js new file mode 100644 index 0000000..cd67429 --- /dev/null +++ b/generator/codemods/vue/__testfixtures__/rename-lifecycle.input.js @@ -0,0 +1,8 @@ +export default { + destroyed: function () { + console.log('foo') + }, + beforeDestroy: function () { + console.log('bar') + } +} diff --git a/generator/codemods/vue/__testfixtures__/rename-lifecycle.output.js b/generator/codemods/vue/__testfixtures__/rename-lifecycle.output.js new file mode 100644 index 0000000..3f243ec --- /dev/null +++ b/generator/codemods/vue/__testfixtures__/rename-lifecycle.output.js @@ -0,0 +1,8 @@ +export default { + unmounted: function () { + console.log('foo') + }, + beforeUnmount: function () { + console.log('bar') + } +} diff --git a/generator/codemods/vue/__tests__/vue-test.js b/generator/codemods/vue/__tests__/vue-test.js new file mode 100644 index 0000000..3e3c669 --- /dev/null +++ b/generator/codemods/vue/__tests__/vue-test.js @@ -0,0 +1,6 @@ +jest.autoMockOff() + +const { defineTest } = require('jscodeshift/dist/testUtils') + +defineTest(__dirname, 'index', null, 'add-emit-declaration') +defineTest(__dirname, 'index', null, 'rename-lifecycle')