diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index cf7c381d8..6458a7d73 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -27,9 +27,11 @@ jobs:
- run: yarn install
- run: yarn lint
- run: yarn test
+ - run: yarn test:compat
- run: yarn build
env:
CI: true
- run: yarn test:build
+ - run: yarn test:compat:build
- run: yarn tsd
- run: yarn vue-tsc
diff --git a/jest.config.js b/jest.config.js
index 49ace6603..0fe7260da 100644
--- a/jest.config.js
+++ b/jest.config.js
@@ -1,3 +1,5 @@
+const path = require('path')
+
module.exports = {
preset: 'ts-jest',
globals: {
@@ -14,5 +16,5 @@ module.exports = {
'^.+\\js$': 'babel-jest'
},
moduleFileExtensions: ['vue', 'js', 'json', 'jsx', 'ts', 'tsx', 'node'],
- setupFiles: ['./setup.js']
+ setupFiles: [path.resolve(__dirname, './setup.js')]
}
diff --git a/package.json b/package.json
index 755127264..46186be94 100644
--- a/package.json
+++ b/package.json
@@ -23,6 +23,7 @@
"@types/node": "15.12.4",
"@types/pretty": "^2.0.0",
"@vue/babel-plugin-jsx": "^1.0.6",
+ "@vue/compat": "^3.1.2",
"@vue/compiler-dom": "^3.1.2",
"@vue/compiler-sfc": "3.1.2",
"babel-jest": "^26.6.3",
@@ -55,8 +56,10 @@
"email": "lachlan.miller.1990@outlook.com"
},
"scripts": {
- "test": "yarn jest --runInBand tests",
- "test:build": "yarn jest --runInBand tests -use-build",
+ "test": "yarn jest --runInBand tests/",
+ "test:compat": "yarn jest -c tests-compat/jest-compat.config.js --runInBand tests-compat/",
+ "test:build": "yarn jest --runInBand tests/ -use-build",
+ "test:compat:build": "yarn jest -c tests-compat/jest-compat.config.js --runInBand tests-compat/ -use-build",
"tsd": "tsc -p test-dts/tsconfig.tsd.json",
"build": "yarn rollup -c rollup.config.js",
"lint": "prettier -c --parser typescript \"(src|tests)/**/*.ts?(x)\"",
diff --git a/src/stubs.ts b/src/stubs.ts
index 34f166279..30e79f785 100644
--- a/src/stubs.ts
+++ b/src/stubs.ts
@@ -61,7 +61,12 @@ const createTransitionStub = ({
return h(name, {}, ctx.$slots)
}
- return defineComponent({ name, render, props })
+ return defineComponent({
+ name,
+ compatConfig: { MODE: 3, RENDER_FUNCTION: false },
+ render,
+ props
+ })
}
const resolveComponentStubByName = (
diff --git a/src/utils/find.ts b/src/utils/find.ts
index 486a217f3..cef6cb8d1 100644
--- a/src/utils/find.ts
+++ b/src/utils/find.ts
@@ -8,6 +8,7 @@ import { FindAllComponentsSelector } from '../types'
import { getOriginalVNodeTypeFromStub } from '../stubs'
import { isComponent } from '../utils'
import { matchName } from './matchName'
+import { convertLegacyVueExtendSelector } from './vueCompatSupport'
/**
* Detect whether a selector matches a VNode
@@ -17,8 +18,10 @@ import { matchName } from './matchName'
*/
export function matches(
node: VNode,
- selector: FindAllComponentsSelector
+ rawSelector: FindAllComponentsSelector
): boolean {
+ const selector = convertLegacyVueExtendSelector(rawSelector)
+
// do not return none Vue components
if (!node.component) return false
diff --git a/src/utils/vueCompatSupport.ts b/src/utils/vueCompatSupport.ts
new file mode 100644
index 000000000..194e46304
--- /dev/null
+++ b/src/utils/vueCompatSupport.ts
@@ -0,0 +1,21 @@
+import * as Vue from 'vue'
+import type { ComponentOptions } from 'vue'
+import { FindAllComponentsSelector } from '../types'
+
+function isCompatEnabled(key: string): boolean {
+ return (Vue as any).compatUtils?.isCompatEnabled(key) ?? false
+}
+
+export function convertLegacyVueExtendSelector(
+ selector: FindAllComponentsSelector
+): FindAllComponentsSelector {
+ if (!isCompatEnabled('GLOBAL_EXTEND') || typeof selector !== 'function') {
+ return selector
+ }
+
+ // @ts-ignore Vue.extend is part of Vue2 compat API, types are missing
+ const fakeCmp = Vue.extend({})
+
+ // @ts-ignore TypeScript does not allow access of properties on functions
+ return fakeCmp.super === selector.super ? selector.options : selector
+}
diff --git a/tests-compat/compat.spec.ts b/tests-compat/compat.spec.ts
new file mode 100644
index 000000000..11fff69ef
--- /dev/null
+++ b/tests-compat/compat.spec.ts
@@ -0,0 +1,38 @@
+import * as Vue from '@vue/compat'
+import { mount } from '../src'
+
+const { configureCompat, extend, defineComponent } = Vue as any
+
+describe('@vue/compat build', () => {
+ it.each([true, false])(
+ 'correctly renders transition when RENDER_FUNCTION compat is %p',
+ (RENDER_FUNCTION) => {
+ configureCompat({ MODE: 3, RENDER_FUNCTION })
+
+ const Component = defineComponent({
+ template: '