/foo/$1",
+ // @import '~foo'; -> @import 'path/to/project/foo';
+ "^~bar/(.*)": "~baz/lib/$1"
+ // @import '~bar/qux'; -> @import 'path/to/project/node_modules/baz/lib/qux';
+ // Notice how the tilde (~) was needed on the bare import to baz.
+ }
+ }
+ }
+ ```
+ - To import globally included files (ie. variables, mixins, etc.), include them in the Jest configuration at `jest.globals['vue-jest'].resources.scss`:
+
+ ```json
+ {
+ "jest": {
+ "globals": {
+ "vue-jest": {
+ "resources": {
+ "scss": [
+ "./node_modules/package/_mixins.scss",
+ "./src/assets/css/globals.scss"
+ ]
+ }
+ }
+ }
+ }
+ }
+ ```
+
+## CSS options
+
+`experimentalCSSCompile`: `Boolean` Default true. Turn off CSS compilation
+
+`hideStyleWarn`: `Boolean` Default false. Hide warnings about CSS compilation
+
+`resources`:
+
+```json
+{
+ "jest": {
+ "globals": {
+ "vue-jest": {
+ "hideStyleWarn": true,
+ "experimentalCSSCompile": true
+ }
+ }
+ }
+}
+```
+
+## Style options
+
+Possbility to change style loader options (sass, scss, less etc).
+
+`styleOptions`: `Object` Default `{}`.
+
+```json
+{
+ "jest": {
+ "globals": {
+ "vue-jest": {
+ "styleOptions": {
+ "quietDeps" // e.q. sass options https://sass-lang.com/documentation/js-api#quietdeps
+ // unfortunately rest options like `data`, `file` doesnt work because @vue/compiler-component-utils internally overwrite options with their values
+ },
+ }
+ }
+ }
+}
+```
diff --git a/e2e/2.x/babel-in-package/components/Basic.vue b/e2e/2.x/babel-in-package/components/Basic.vue
new file mode 100644
index 00000000..a37429b0
--- /dev/null
+++ b/e2e/2.x/babel-in-package/components/Basic.vue
@@ -0,0 +1,47 @@
+
+
+
{{ msg }}
+
+
+
+
+
+
+
+
diff --git a/e2e/2.x/babel-in-package/components/Coffee.vue b/e2e/2.x/babel-in-package/components/Coffee.vue
new file mode 100644
index 00000000..1d3b1bed
--- /dev/null
+++ b/e2e/2.x/babel-in-package/components/Coffee.vue
@@ -0,0 +1,8 @@
+
+
+
+
+
diff --git a/e2e/2.x/babel-in-package/components/Tsx.vue b/e2e/2.x/babel-in-package/components/Tsx.vue
new file mode 100644
index 00000000..6b1040d3
--- /dev/null
+++ b/e2e/2.x/babel-in-package/components/Tsx.vue
@@ -0,0 +1,14 @@
+
diff --git a/e2e/2.x/babel-in-package/components/TypeScript.vue b/e2e/2.x/babel-in-package/components/TypeScript.vue
new file mode 100644
index 00000000..145560ab
--- /dev/null
+++ b/e2e/2.x/babel-in-package/components/TypeScript.vue
@@ -0,0 +1,21 @@
+
+
+ {{ exclamationMarks }}
+
+
+
+
+
diff --git a/e2e/2.x/babel-in-package/components/TypeScriptChild.vue b/e2e/2.x/babel-in-package/components/TypeScriptChild.vue
new file mode 100644
index 00000000..985a1f72
--- /dev/null
+++ b/e2e/2.x/babel-in-package/components/TypeScriptChild.vue
@@ -0,0 +1,13 @@
+
+ {{ exclamationMarks }}
+
+
+
diff --git a/e2e/2.x/babel-in-package/package.json b/e2e/2.x/babel-in-package/package.json
new file mode 100644
index 00000000..b9ebc577
--- /dev/null
+++ b/e2e/2.x/babel-in-package/package.json
@@ -0,0 +1,43 @@
+{
+ "name": "vue2-babel-in-package",
+ "version": "1.0.0",
+ "license": "MIT",
+ "private": true,
+ "scripts": {
+ "test": "jest --no-cache test.js"
+ },
+ "dependencies": {
+ "source-map": "0.5.6",
+ "vue": "^2.7.7",
+ "vue-template-compiler": "^2.7.7"
+ },
+ "devDependencies": {
+ "@babel/core": "^7.9.0",
+ "@babel/preset-env": "^7.9.0",
+ "@vue/babel-preset-jsx": "^1.2.4",
+ "@vue/test-utils": "^1.1.0",
+ "@vue/vue2-jest": "^29.0.0",
+ "coffeescript": "^2.3.2",
+ "jest": "29.x",
+ "jest-environment-jsdom": "29.x",
+ "typescript": "^4.6.4"
+ },
+ "jest": {
+ "testEnvironment": "jsdom",
+ "moduleFileExtensions": [
+ "js",
+ "json",
+ "vue"
+ ],
+ "transform": {
+ "^.+\\.js$": "babel-jest",
+ "^.+\\.vue$": "@vue/vue2-jest"
+ }
+ },
+ "babel": {
+ "presets": [
+ "@babel/env",
+ "@vue/babel-preset-jsx"
+ ]
+ }
+}
diff --git a/e2e/2.x/babel-in-package/test.js b/e2e/2.x/babel-in-package/test.js
new file mode 100644
index 00000000..06709f6d
--- /dev/null
+++ b/e2e/2.x/babel-in-package/test.js
@@ -0,0 +1,25 @@
+import { mount } from '@vue/test-utils'
+import TypeScript from './components/TypeScript.vue'
+import Basic from './components/Basic.vue'
+import Coffee from './components/Coffee.vue'
+import Tsx from './components/Tsx.vue'
+
+test('processes .vue files', () => {
+ const wrapper = mount(Basic)
+ wrapper.vm.toggleClass()
+})
+
+test('processes .vue file with lang set to coffee', () => {
+ const wrapper = mount(Coffee)
+ expect(wrapper.vm).toBeTruthy()
+})
+
+test('processes .vue files with lang set to ts(typescript)', () => {
+ const wrapper = mount(TypeScript)
+ expect(wrapper.vm).toBeTruthy()
+})
+
+test('processes .vue files with lang set to tsx(typescript)', () => {
+ const wrapper = mount(Tsx)
+ expect(wrapper.text()).toContain('tsx components')
+})
diff --git a/e2e/2.x/babel-in-package/tsconfig.json b/e2e/2.x/babel-in-package/tsconfig.json
new file mode 100644
index 00000000..98e192f0
--- /dev/null
+++ b/e2e/2.x/babel-in-package/tsconfig.json
@@ -0,0 +1,20 @@
+{
+ "compilerOptions": {
+ "target": "ES2017",
+ "lib": ["dom", "es6"],
+ "module": "ES2015",
+ "moduleResolution": "node",
+ "types": ["vue-typescript-import-dts", "node"],
+ "isolatedModules": false,
+ "experimentalDecorators": true,
+ "noImplicitAny": true,
+ "noImplicitThis": true,
+ "strictNullChecks": true,
+ "removeComments": true,
+ "emitDecoratorMetadata": true,
+ "suppressImplicitAnyIndexErrors": true,
+ "allowSyntheticDefaultImports": true,
+ "sourceMap": true,
+ "esModuleInterop": true
+ }
+}
diff --git a/e2e/2.x/basic/__snapshots__/test.js.snap b/e2e/2.x/basic/__snapshots__/test.js.snap
new file mode 100644
index 00000000..f8f9c647
--- /dev/null
+++ b/e2e/2.x/basic/__snapshots__/test.js.snap
@@ -0,0 +1,113 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`generates source maps for .vue files 1`] = `
+{
+ "file": "./components/Basic.vue",
+ "mappings": ";;;;;;eAuBe;AACb,MAAI,EAAE,OADO;AAEb,UAAQ,EAAE;AACR,kBAAc,EAAE,SAAS,cAAT,GAA0B;AACxC,aAAO;AACL,WAAG,EAAE,KAAK,OADL;AAEL,YAAI,EAAE,CAAC,KAAK,OAFP;AAGL,cAAM,EAAE,KAAK;AAHR,OAAP;AAKD;AAPO,GAFG;AAWb,MAAI,EAAE,SAAS,IAAT,GAAgB;AACpB,WAAO;AACL,SAAG,EAAE,4BADA;AAEL,aAAO,EAAE;AAFJ,KAAP;AAID,GAhBY;AAiBb,SAAO,EAAE;AACP,eAAW,EAAE,SAAS,WAAT,GAAuB;AAClC,WAAK,OAAL,GAAe,CAAC,KAAK,OAArB;AACD;AAHM;AAjBI",
+ "names": [],
+ "sources": [
+ "components/Basic.vue",
+ ],
+ "sourcesContent": [
+ "
+
+
{{ msg }}
+
+
+
+
+
+
+
+
+",
+ ],
+ "version": 3,
+}
+`;
+
+exports[`generates source maps using src attributes 1`] = `
+{
+ "file": "./components/SourceMapsSrc.vue",
+ "mappings": ";;;;;;eAAe;AACbA,MAAI,EAAE,OADO;AAEbC,UAAQ,EAAE;AACRC,kBAAc,EAAE,SAASA,cAAT,GAA0B;AACxC,aAAO;AACLC,WAAG,EAAE,KAAKC,OADL;AAELC,YAAI,EAAE,CAAC,KAAKD,OAFP;AAGLE,cAAM,EAAE,KAAKF;AAHR,OAAP;AAKD;AAPO,GAFG;AAWbG,MAAI,EAAE,SAASA,IAAT,GAAgB;AACpB,WAAO;AACLC,SAAG,EAAE,4BADA;AAELJ,aAAO,EAAE;AAFJ,KAAP;AAID,GAhBY;AAiBbK,SAAO,EAAE;AACPC,eAAW,EAAE,SAASA,WAAT,GAAuB;AAClC,WAAKN,OAAL,GAAe,CAAC,KAAKA,OAArB;AACD;AAHM;AAjBI,C",
+ "names": [
+ "name",
+ "computed",
+ "headingClasses",
+ "red",
+ "isCrazy",
+ "blue",
+ "shadow",
+ "data",
+ "msg",
+ "methods",
+ "toggleClass",
+ ],
+ "sources": [
+ "SourceMapsSrc.vue",
+ ],
+ "sourcesContent": [
+ "export default {
+ name: 'basic',
+ computed: {
+ headingClasses: function headingClasses() {
+ return {
+ red: this.isCrazy,
+ blue: !this.isCrazy,
+ shadow: this.isCrazy
+ }
+ }
+ },
+ data: function data() {
+ return {
+ msg: 'Welcome to Your Vue.js App',
+ isCrazy: false
+ }
+ },
+ methods: {
+ toggleClass: function toggleClass() {
+ this.isCrazy = !this.isCrazy
+ }
+ }
+}
+",
+ ],
+ "version": 3,
+}
+`;
diff --git a/e2e/2.x/basic/babel.config.js b/e2e/2.x/basic/babel.config.js
new file mode 100644
index 00000000..3ba5f43c
--- /dev/null
+++ b/e2e/2.x/basic/babel.config.js
@@ -0,0 +1,4 @@
+module.exports = {
+ presets: ['@babel/preset-env'],
+ plugins: ['transform-vue-jsx']
+}
diff --git a/e2e/2.x/basic/components/Basic.vue b/e2e/2.x/basic/components/Basic.vue
new file mode 100644
index 00000000..a37429b0
--- /dev/null
+++ b/e2e/2.x/basic/components/Basic.vue
@@ -0,0 +1,47 @@
+
+
+
{{ msg }}
+
+
+
+
+
+
+
+
diff --git a/e2e/2.x/basic/components/BasicSrc.html b/e2e/2.x/basic/components/BasicSrc.html
new file mode 100644
index 00000000..67c4dfde
--- /dev/null
+++ b/e2e/2.x/basic/components/BasicSrc.html
@@ -0,0 +1,3 @@
+
+
{{ msg }}
+
\ No newline at end of file
diff --git a/e2e/2.x/basic/components/BasicSrc.js b/e2e/2.x/basic/components/BasicSrc.js
new file mode 100644
index 00000000..3aeef17c
--- /dev/null
+++ b/e2e/2.x/basic/components/BasicSrc.js
@@ -0,0 +1,23 @@
+export default {
+ name: 'basic',
+ computed: {
+ headingClasses: function headingClasses() {
+ return {
+ red: this.isCrazy,
+ blue: !this.isCrazy,
+ shadow: this.isCrazy
+ }
+ }
+ },
+ data: function data() {
+ return {
+ msg: 'Welcome to Your Vue.js App',
+ isCrazy: false
+ }
+ },
+ methods: {
+ toggleClass: function toggleClass() {
+ this.isCrazy = !this.isCrazy
+ }
+ }
+}
diff --git a/e2e/2.x/basic/components/BasicSrc.vue b/e2e/2.x/basic/components/BasicSrc.vue
new file mode 100644
index 00000000..2fbf9f1e
--- /dev/null
+++ b/e2e/2.x/basic/components/BasicSrc.vue
@@ -0,0 +1,3 @@
+
+
+
diff --git a/e2e/2.x/basic/components/Coffee.vue b/e2e/2.x/basic/components/Coffee.vue
new file mode 100644
index 00000000..1d3b1bed
--- /dev/null
+++ b/e2e/2.x/basic/components/Coffee.vue
@@ -0,0 +1,8 @@
+
+
+
+
+
diff --git a/e2e/2.x/basic/components/CoffeeScript.vue b/e2e/2.x/basic/components/CoffeeScript.vue
new file mode 100644
index 00000000..979664d9
--- /dev/null
+++ b/e2e/2.x/basic/components/CoffeeScript.vue
@@ -0,0 +1,8 @@
+
+
+
+
+
diff --git a/e2e/2.x/basic/components/Constructor.vue b/e2e/2.x/basic/components/Constructor.vue
new file mode 100644
index 00000000..c81625e8
--- /dev/null
+++ b/e2e/2.x/basic/components/Constructor.vue
@@ -0,0 +1,9 @@
+
+
+
+
+
diff --git a/e2e/2.x/basic/components/ExtendedTsConfig.vue b/e2e/2.x/basic/components/ExtendedTsConfig.vue
new file mode 100644
index 00000000..8dc7001f
--- /dev/null
+++ b/e2e/2.x/basic/components/ExtendedTsConfig.vue
@@ -0,0 +1,34 @@
+
+
+ {{ exclamationMarks }}
+
+
+
+
+
diff --git a/e2e/2.x/basic/components/FunctionalSFC.vue b/e2e/2.x/basic/components/FunctionalSFC.vue
new file mode 100644
index 00000000..1395f320
--- /dev/null
+++ b/e2e/2.x/basic/components/FunctionalSFC.vue
@@ -0,0 +1,5 @@
+
+
+ {{ props.msg.title }}
+
+
diff --git a/e2e/2.x/basic/components/FunctionalSFCParent.vue b/e2e/2.x/basic/components/FunctionalSFCParent.vue
new file mode 100644
index 00000000..01509456
--- /dev/null
+++ b/e2e/2.x/basic/components/FunctionalSFCParent.vue
@@ -0,0 +1,14 @@
+
+
+
+
+
diff --git a/e2e/2.x/basic/components/FunctionalSFCRender.vue b/e2e/2.x/basic/components/FunctionalSFCRender.vue
new file mode 100644
index 00000000..4bf47201
--- /dev/null
+++ b/e2e/2.x/basic/components/FunctionalSFCRender.vue
@@ -0,0 +1,17 @@
+
+
+
diff --git a/e2e/2.x/basic/components/Jade.vue b/e2e/2.x/basic/components/Jade.vue
new file mode 100644
index 00000000..4195a137
--- /dev/null
+++ b/e2e/2.x/basic/components/Jade.vue
@@ -0,0 +1,9 @@
+
+ .jade
+
+
+
diff --git a/e2e/2.x/basic/components/Jsx.vue b/e2e/2.x/basic/components/Jsx.vue
new file mode 100644
index 00000000..958891b9
--- /dev/null
+++ b/e2e/2.x/basic/components/Jsx.vue
@@ -0,0 +1,7 @@
+
diff --git a/e2e/2.x/basic/components/ModuleRequiringEsModuleInterop.js b/e2e/2.x/basic/components/ModuleRequiringEsModuleInterop.js
new file mode 100644
index 00000000..fed7caa7
--- /dev/null
+++ b/e2e/2.x/basic/components/ModuleRequiringEsModuleInterop.js
@@ -0,0 +1 @@
+module.exports = () => false
diff --git a/e2e/2.x/basic/components/NamedExport.vue b/e2e/2.x/basic/components/NamedExport.vue
new file mode 100644
index 00000000..1d2c6f0f
--- /dev/null
+++ b/e2e/2.x/basic/components/NamedExport.vue
@@ -0,0 +1,7 @@
+
diff --git a/e2e/2.x/basic/components/NoScript.vue b/e2e/2.x/basic/components/NoScript.vue
new file mode 100644
index 00000000..976b9f7d
--- /dev/null
+++ b/e2e/2.x/basic/components/NoScript.vue
@@ -0,0 +1,12 @@
+
+
+
+
+
diff --git a/e2e/2.x/basic/components/Pug.vue b/e2e/2.x/basic/components/Pug.vue
new file mode 100644
index 00000000..eddf14e4
--- /dev/null
+++ b/e2e/2.x/basic/components/Pug.vue
@@ -0,0 +1,11 @@
+
+ extends /components/PugBase.pug
+ block component
+ div(class="pug-extended")
+
+
+
diff --git a/e2e/2.x/basic/components/PugBase.pug b/e2e/2.x/basic/components/PugBase.pug
new file mode 100644
index 00000000..93fdad14
--- /dev/null
+++ b/e2e/2.x/basic/components/PugBase.pug
@@ -0,0 +1,2 @@
+div(class='pug-base')
+ block component
\ No newline at end of file
diff --git a/e2e/2.x/basic/components/PugRelativeExtends.vue b/e2e/2.x/basic/components/PugRelativeExtends.vue
new file mode 100644
index 00000000..963ec0fa
--- /dev/null
+++ b/e2e/2.x/basic/components/PugRelativeExtends.vue
@@ -0,0 +1,11 @@
+
+ extends ./relative/PugRelativeBase.pug
+ block component
+ div(class="pug-extended")
+
+
+
diff --git a/e2e/2.x/basic/components/RenderFunction.vue b/e2e/2.x/basic/components/RenderFunction.vue
new file mode 100644
index 00000000..fcabb646
--- /dev/null
+++ b/e2e/2.x/basic/components/RenderFunction.vue
@@ -0,0 +1,8 @@
+
diff --git a/e2e/2.x/basic/components/ScriptAndScriptSetup.vue b/e2e/2.x/basic/components/ScriptAndScriptSetup.vue
new file mode 100644
index 00000000..e3aa2fcb
--- /dev/null
+++ b/e2e/2.x/basic/components/ScriptAndScriptSetup.vue
@@ -0,0 +1,23 @@
+
+
+
+
+ {{ msg }}
+
+
+
+
+
+
diff --git a/e2e/2.x/basic/components/ScriptSetup.vue b/e2e/2.x/basic/components/ScriptSetup.vue
new file mode 100644
index 00000000..6c413862
--- /dev/null
+++ b/e2e/2.x/basic/components/ScriptSetup.vue
@@ -0,0 +1,20 @@
+
+
+
+
+ {{ msg }}
+
+
+
+
diff --git a/e2e/2.x/basic/components/SourceMapsSrc.vue b/e2e/2.x/basic/components/SourceMapsSrc.vue
new file mode 100644
index 00000000..2fbf9f1e
--- /dev/null
+++ b/e2e/2.x/basic/components/SourceMapsSrc.vue
@@ -0,0 +1,3 @@
+
+
+
diff --git a/e2e/2.x/basic/components/TemplateString.vue b/e2e/2.x/basic/components/TemplateString.vue
new file mode 100644
index 00000000..7454d234
--- /dev/null
+++ b/e2e/2.x/basic/components/TemplateString.vue
@@ -0,0 +1,21 @@
+
+
+
+
+
diff --git a/e2e/2.x/basic/components/TypeScript.vue b/e2e/2.x/basic/components/TypeScript.vue
new file mode 100644
index 00000000..145560ab
--- /dev/null
+++ b/e2e/2.x/basic/components/TypeScript.vue
@@ -0,0 +1,21 @@
+
+
+ {{ exclamationMarks }}
+
+
+
+
+
diff --git a/e2e/2.x/basic/components/TypeScriptChild.vue b/e2e/2.x/basic/components/TypeScriptChild.vue
new file mode 100644
index 00000000..985a1f72
--- /dev/null
+++ b/e2e/2.x/basic/components/TypeScriptChild.vue
@@ -0,0 +1,13 @@
+
+ {{ exclamationMarks }}
+
+
+
diff --git a/e2e/2.x/basic/components/coffee.spec.js b/e2e/2.x/basic/components/coffee.spec.js
new file mode 100644
index 00000000..163edcb2
--- /dev/null
+++ b/e2e/2.x/basic/components/coffee.spec.js
@@ -0,0 +1,28 @@
+import { shallowMount, mount } from '@vue/test-utils'
+import Coffee from './resources/Coffee.vue'
+import CoffeeScript from './resources/CoffeeScript.vue'
+import CoffeeES6 from './resources/CoffeeES6.vue'
+import CoffeeScriptES6 from './resources/CoffeeScriptES6.vue'
+
+describe('Test CoffeeScript - coffee.spec.js', () => {
+ test('processes .vue file with lang set to coffee', () => {
+ shallowMount(Coffee)
+ })
+
+ test('processes .vue file with lang set to coffeescript', () => {
+ shallowMount(CoffeeScript)
+ })
+
+ test('processes .vue file with lang set to coffee (ES6)', () => {
+ shallowMount(CoffeeES6)
+ })
+
+ test('processes .vue file with lang set to coffeescript (ES6)', () => {
+ shallowMount(CoffeeScriptES6)
+ })
+
+ test('processes .vue file with lang set to coffeescript (ES6)', () => {
+ const wrapper = mount(CoffeeScriptES6)
+ expect(typeof wrapper).toBe('object')
+ })
+})
diff --git a/e2e/2.x/basic/components/relative/PugRelativeBase.pug b/e2e/2.x/basic/components/relative/PugRelativeBase.pug
new file mode 100644
index 00000000..2347fc06
--- /dev/null
+++ b/e2e/2.x/basic/components/relative/PugRelativeBase.pug
@@ -0,0 +1,2 @@
+div(class='pug-relative-base')
+ block component
\ No newline at end of file
diff --git a/e2e/2.x/basic/package.json b/e2e/2.x/basic/package.json
new file mode 100644
index 00000000..152b804c
--- /dev/null
+++ b/e2e/2.x/basic/package.json
@@ -0,0 +1,58 @@
+{
+ "name": "vue2-basic",
+ "version": "1.0.0",
+ "license": "MIT",
+ "private": true,
+ "scripts": {
+ "test": "jest --no-cache --coverage test.js"
+ },
+ "dependencies": {
+ "vue": "^2.7.7",
+ "vue-template-compiler": "^2.7.7"
+ },
+ "devDependencies": {
+ "@babel/core": "^7.9.0",
+ "@babel/preset-env": "^7.9.0",
+ "@vue/test-utils": "^1.1.0",
+ "@vue/vue2-jest": "^29.0.0",
+ "babel-helper-vue-jsx-merge-props": "^2.0.3",
+ "babel-plugin-syntax-jsx": "^6.18.0",
+ "babel-plugin-transform-vue-jsx": "^3.7.0",
+ "coffeescript": "^2.3.2",
+ "jade": "^1.11.0",
+ "jest": "29.x",
+ "jest-environment-jsdom": "29.x",
+ "pug": "^3.0.1",
+ "sass": "^1.23.7",
+ "typescript": "^4.6.4"
+ },
+ "jest": {
+ "testEnvironment": "jsdom",
+ "moduleFileExtensions": [
+ "js",
+ "json",
+ "vue"
+ ],
+ "transform": {
+ "^.+\\.js$": "babel-jest",
+ "^.+\\.vue$": "@vue/vue2-jest"
+ },
+ "moduleNameMapper": {
+ "^~?__styles/(.*)$": "/components/styles/$1"
+ },
+ "globals": {
+ "vue-jest": {
+ "pug": {
+ "basedir": "./"
+ },
+ "templateCompiler": {
+ "transpileOptions": {
+ "transforms": {
+ "dangerousTaggedTemplateString": true
+ }
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/e2e/2.x/basic/test.js b/e2e/2.x/basic/test.js
new file mode 100644
index 00000000..9eb6b525
--- /dev/null
+++ b/e2e/2.x/basic/test.js
@@ -0,0 +1,204 @@
+import { mount } from '@vue/test-utils'
+import TypeScript from './components/TypeScript.vue'
+import TemplateString from './components/TemplateString.vue'
+import { resolve } from 'path'
+import { readFileSync } from 'fs'
+import jestVue from '@vue/vue2-jest'
+import RenderFunction from './components/RenderFunction.vue'
+import Jade from './components/Jade.vue'
+import FunctionalSFC from './components/FunctionalSFC.vue'
+import FunctionalSFCRender from './components/FunctionalSFCRender.vue'
+import Basic from './components/Basic.vue'
+import BasicSrc from './components/BasicSrc.vue'
+import { randomExport } from './components/NamedExport.vue'
+import Coffee from './components/Coffee.vue'
+import CoffeeScript from './components/CoffeeScript.vue'
+import FunctionalSFCParent from './components/FunctionalSFCParent.vue'
+import NoScript from './components/NoScript.vue'
+import Pug from './components/Pug.vue'
+import PugRelative from './components/PugRelativeExtends.vue'
+import Jsx from './components/Jsx.vue'
+import Constructor from './components/Constructor.vue'
+import { compileStyle } from '@vue/component-compiler-utils'
+import ScriptSetup from './components/ScriptSetup'
+import ScriptAndScriptSetup from './components/ScriptAndScriptSetup'
+import ExtendedTsConfig from './components/ExtendedTsConfig.vue'
+
+jest.mock('@vue/component-compiler-utils', () => ({
+ ...jest.requireActual('@vue/component-compiler-utils'),
+ compileStyle: jest.fn(() => ({ errors: [], code: '' }))
+}))
+
+beforeEach(() => jest.clearAllMocks())
+test('processes .vue files', () => {
+ const wrapper = mount(Basic)
+ expect(wrapper.vm.msg).toEqual('Welcome to Your Vue.js App')
+ wrapper.vm.toggleClass()
+})
+
+test('processes .vue files with src attributes', () => {
+ const wrapper = mount(BasicSrc)
+ wrapper.vm.toggleClass()
+})
+
+test('handles named exports', () => {
+ expect(randomExport).toEqual(42)
+})
+
+test('generates source maps for .vue files', () => {
+ const filePath = './components/Basic.vue'
+ const fileString = readFileSync(resolve(__dirname, filePath), {
+ encoding: 'utf8'
+ })
+ const config = {
+ moduleFileExtensions: ['js', 'vue']
+ }
+
+ const { map } = jestVue.process(fileString, filePath, {
+ config
+ })
+
+ expect(JSON.parse(map)).toMatchSnapshot()
+})
+
+test('generates source maps using src attributes', () => {
+ const filePath = './components/SourceMapsSrc.vue'
+ const fileString = readFileSync(resolve(__dirname, filePath), {
+ encoding: 'utf8'
+ })
+
+ const config = { moduleFileExtensions: ['js', 'vue'] }
+
+ const { map } = jestVue.process(fileString, filePath, { config })
+
+ expect(JSON.parse(map)).toMatchSnapshot()
+})
+
+test('processes .vue file using jsx', () => {
+ const wrapper = mount(Jsx)
+ expect(wrapper.element.tagName).toBe('DIV')
+})
+
+test('processes extended functions', () => {
+ const wrapper = mount(Constructor)
+ expect(wrapper.element.tagName).toBe('DIV')
+})
+
+test('processes .vue file with lang set to coffee', () => {
+ const wrapper = mount(Coffee)
+ expect(wrapper.element.tagName).toBe('DIV')
+})
+
+test('processes .vue file with lang set to coffeescript', () => {
+ const wrapper = mount(CoffeeScript)
+ expect(wrapper.element.tagName).toBe('DIV')
+})
+
+test('processes .vue files with lang set to typescript', () => {
+ const wrapper = mount(TypeScript)
+ expect(wrapper.element.tagName).toBe('DIV')
+})
+
+test('processes .vue files with template strings in the template', () => {
+ const wrapper = mount(TemplateString)
+ expect(wrapper.attributes('data-sth')).toBe(`
+ query {
+ id
+ }
+ `)
+})
+
+test('processes functional components', () => {
+ const clickSpy = jest.fn()
+ const wrapper = mount(FunctionalSFC, {
+ context: {
+ props: { msg: { id: 1, title: 'foo' }, onClick: clickSpy }
+ }
+ })
+ expect(wrapper.text().trim()).toBe('foo')
+ wrapper.trigger('click')
+ expect(clickSpy).toHaveBeenCalledWith(1)
+})
+
+test('processes functional components using render function', () => {
+ const wrapper = mount(FunctionalSFCRender)
+ const CSS_CLASSES = ['ModuleClass']
+ expect(wrapper.classes().toString()).toBe(CSS_CLASSES.toString())
+})
+
+test('processes SFC with functional template from parent', () => {
+ const wrapper = mount(FunctionalSFCParent)
+ expect(wrapper.text().trim()).toBe('foo')
+})
+
+test('handles missing script block', () => {
+ const wrapper = mount(NoScript)
+ expect(wrapper.element.tagName).toBe('FOOTER')
+})
+
+test('processes .vue file with jade template', () => {
+ const wrapper = mount(Jade)
+ expect(wrapper.element.tagName).toBe('DIV')
+ expect(wrapper.classes()).toContain('jade')
+})
+
+test('processes pug templates', () => {
+ const wrapper = mount(Pug)
+ expect(wrapper.element.tagName).toBe('DIV')
+ expect(wrapper.classes()).toContain('pug-base')
+ expect(wrapper.find('.pug-extended').exists()).toBeTruthy()
+})
+
+test('supports relative paths when extending templates from .pug files', () => {
+ const wrapper = mount(PugRelative)
+ expect(wrapper.element.tagName).toBe('DIV')
+ expect(wrapper.find('.pug-relative-base').exists()).toBeTruthy()
+})
+
+test('processes SFC with no template', () => {
+ const wrapper = mount(RenderFunction)
+ expect(wrapper.element.tagName).toBe('SECTION')
+})
+
+test('processes SFC with
+
+
+{
+ "en": {
+ "hello": "Hello!"
+ },
+ "ja": {
+ "hello": "こんにちは!"
+ }
+}
+
diff --git a/e2e/2.x/custom-block/components/Multiple.vue b/e2e/2.x/custom-block/components/Multiple.vue
new file mode 100644
index 00000000..f204d041
--- /dev/null
+++ b/e2e/2.x/custom-block/components/Multiple.vue
@@ -0,0 +1,26 @@
+
+ multiple custom block
+
+
+
+
+
+{
+ "en": {
+ "hello": "Hello!"
+ },
+ "ja": {
+ "hello": "こんにちは!"
+ }
+}
+
+
+
+{
+ "foo": "foo"
+}
+
diff --git a/e2e/2.x/custom-block/package.json b/e2e/2.x/custom-block/package.json
new file mode 100644
index 00000000..0b0442f6
--- /dev/null
+++ b/e2e/2.x/custom-block/package.json
@@ -0,0 +1,41 @@
+{
+ "name": "vue2-custom-block",
+ "version": "1.0.0",
+ "license": "MIT",
+ "private": true,
+ "scripts": {
+ "test": "jest --no-cache --coverage test.js"
+ },
+ "dependencies": {
+ "vue": "^2.7.7",
+ "vue-template-compiler": "^2.7.7"
+ },
+ "devDependencies": {
+ "@babel/core": "^7.9.0",
+ "@babel/preset-env": "^7.9.0",
+ "@vue/vue2-jest": "^29.0.0",
+ "jest": "29.x",
+ "jest-environment-jsdom": "29.x"
+ },
+ "jest": {
+ "moduleFileExtensions": [
+ "js",
+ "json",
+ "vue"
+ ],
+ "transform": {
+ "^.+\\.js$": "babel-jest",
+ "^.+\\.vue$": "@vue/vue2-jest"
+ },
+ "moduleNameMapper": {
+ "^~?__styles/(.*)$": "/components/styles/$1"
+ },
+ "globals": {
+ "vue-jest": {
+ "transform": {
+ "custom": "./transformer.js"
+ }
+ }
+ }
+ }
+}
diff --git a/e2e/2.x/custom-block/test.js b/e2e/2.x/custom-block/test.js
new file mode 100644
index 00000000..79556a9c
--- /dev/null
+++ b/e2e/2.x/custom-block/test.js
@@ -0,0 +1,33 @@
+import Basic from './components/Basic.vue'
+import Multiple from './components/Multiple.vue'
+
+test('Basic', () => {
+ expect(Basic.__custom).toMatchObject([
+ {
+ en: {
+ hello: 'Hello!'
+ },
+ ja: {
+ hello: 'こんにちは!'
+ }
+ }
+ ])
+ expect(Basic.__custom).toMatchSnapshot()
+})
+
+test('Multiple blocks', () => {
+ expect(Multiple.__custom).toMatchObject([
+ {
+ en: {
+ hello: 'Hello!'
+ },
+ ja: {
+ hello: 'こんにちは!'
+ }
+ },
+ {
+ foo: 'foo'
+ }
+ ])
+ expect(Multiple.__custom).toMatchSnapshot()
+})
diff --git a/e2e/2.x/custom-block/transformer.js b/e2e/2.x/custom-block/transformer.js
new file mode 100644
index 00000000..b0266930
--- /dev/null
+++ b/e2e/2.x/custom-block/transformer.js
@@ -0,0 +1,21 @@
+function convert(content) {
+ return JSON.stringify(JSON.parse(content))
+ .replace(/\u2028/g, '\\u2028') // LINE SEPARATOR
+ .replace(/\u2029/g, '\\u2029') // PARAGRAPH SEPARATOR
+ .replace(/\\/g, '\\\\')
+ .replace(/'/g, "\\'")
+}
+
+module.exports = {
+ process({ blocks, vueOptionsNamespace, filename, config }) {
+ const ret = blocks.reduce((codes, block) => {
+ codes.push(
+ `${vueOptionsNamespace}.__custom = ${vueOptionsNamespace}.__custom || [];${vueOptionsNamespace}.__custom.push(${convert(
+ block.content
+ )});`
+ )
+ return codes
+ }, [])
+ return ret.join('')
+ }
+}
diff --git a/e2e/2.x/custom-transformers/babel-transformer.js b/e2e/2.x/custom-transformers/babel-transformer.js
new file mode 100644
index 00000000..193503e5
--- /dev/null
+++ b/e2e/2.x/custom-transformers/babel-transformer.js
@@ -0,0 +1,4 @@
+const { createTransformer } = require('babel-jest').default
+module.exports = createTransformer({
+ presets: ['@babel/preset-env']
+})
diff --git a/e2e/2.x/custom-transformers/components/Scss.vue b/e2e/2.x/custom-transformers/components/Scss.vue
new file mode 100644
index 00000000..474edea9
--- /dev/null
+++ b/e2e/2.x/custom-transformers/components/Scss.vue
@@ -0,0 +1,18 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/e2e/2.x/custom-transformers/package.json b/e2e/2.x/custom-transformers/package.json
new file mode 100644
index 00000000..7d5609c9
--- /dev/null
+++ b/e2e/2.x/custom-transformers/package.json
@@ -0,0 +1,49 @@
+{
+ "name": "vue2-custom-transformers",
+ "version": "1.0.0",
+ "license": "MIT",
+ "private": true,
+ "scripts": {
+ "test": "jest --no-cache --coverage test.js"
+ },
+ "dependencies": {
+ "vue": "^2.7.7",
+ "vue-template-compiler": "^2.7.7"
+ },
+ "devDependencies": {
+ "@babel/core": "^7.9.0",
+ "@babel/preset-env": "^7.9.0",
+ "@vue/test-utils": "^1.1.0",
+ "@vue/vue2-jest": "^29.0.0",
+ "babel-jest": "29.x",
+ "jest": "29.x",
+ "jest-environment-jsdom": "29.x",
+ "postcss": "^7.0.13",
+ "postcss-color-function": "^4.0.1",
+ "sass": "^1.23.7"
+ },
+ "jest": {
+ "testEnvironment": "jsdom",
+ "moduleFileExtensions": [
+ "js",
+ "json",
+ "vue"
+ ],
+ "transform": {
+ "^.+\\.js$": "./babel-transformer.js",
+ "^.+\\.vue$": "@vue/vue2-jest"
+ },
+ "moduleNameMapper": {
+ "^~?__styles/(.*)$": "/components/styles/$1"
+ },
+ "globals": {
+ "vue-jest": {
+ "transform": {
+ "^scss$": "./scss-transformer.js",
+ "^pcss|postcss$": "./pcss-transformer.js",
+ "^js$": "./babel-transformer.js"
+ }
+ }
+ }
+ }
+}
diff --git a/e2e/2.x/custom-transformers/pcss-transformer.js b/e2e/2.x/custom-transformers/pcss-transformer.js
new file mode 100644
index 00000000..3fc383f0
--- /dev/null
+++ b/e2e/2.x/custom-transformers/pcss-transformer.js
@@ -0,0 +1,7 @@
+const postcss = require('postcss')
+var colorFunction = require('postcss-color-function')
+module.exports = {
+ process: function(content, filepath, config, attrs) {
+ return postcss([colorFunction()]).process(content).css
+ }
+}
diff --git a/e2e/2.x/custom-transformers/scss-transformer.js b/e2e/2.x/custom-transformers/scss-transformer.js
new file mode 100644
index 00000000..15eb6cb0
--- /dev/null
+++ b/e2e/2.x/custom-transformers/scss-transformer.js
@@ -0,0 +1,26 @@
+const cssTree = require('css-tree')
+
+module.exports = {
+ preprocess: function preprocess(src, filepath, config, attrs) {
+ return `${src}\n .g{width: 10px}`
+ },
+ postprocess: function postprocess(src, filepath, config, attrs) {
+ const ast = cssTree.parse(src)
+ const obj = cssTree
+ .findAll(ast, node => node.type === 'ClassSelector')
+ .reduce((acc, cssNode) => {
+ acc[cssNode.name] = cssNode.name
+
+ return acc
+ }, {})
+
+ if (!attrs.themed) {
+ return JSON.stringify(obj)
+ }
+
+ return JSON.stringify({
+ light: obj,
+ dark: obj
+ })
+ }
+}
diff --git a/e2e/2.x/custom-transformers/test.js b/e2e/2.x/custom-transformers/test.js
new file mode 100644
index 00000000..8794fe21
--- /dev/null
+++ b/e2e/2.x/custom-transformers/test.js
@@ -0,0 +1,15 @@
+import { mount } from '@vue/test-utils'
+import Scss from './components/Scss.vue'
+
+test('processes SCSS using user specified post transforms', () => {
+ const wrapper = mount(Scss)
+ expect(wrapper.vm.$style.light.a).toBeUndefined()
+ expect(wrapper.vm.$style.light.f).toEqual('f')
+ expect(wrapper.vm.$style.dark.f).toEqual('f')
+ expect(wrapper.vm.$style.dark.g).toEqual('g')
+})
+
+test('processes SCSS using user specified pre transforms', () => {
+ const wrapper = mount(Scss)
+ expect(wrapper.vm.$style.g).toEqual('g')
+})
diff --git a/e2e/2.x/sass-importer/entry/babel-transformer.js b/e2e/2.x/sass-importer/entry/babel-transformer.js
new file mode 100644
index 00000000..193503e5
--- /dev/null
+++ b/e2e/2.x/sass-importer/entry/babel-transformer.js
@@ -0,0 +1,4 @@
+const { createTransformer } = require('babel-jest').default
+module.exports = createTransformer({
+ presets: ['@babel/preset-env']
+})
diff --git a/e2e/2.x/sass-importer/entry/components/Entry.vue b/e2e/2.x/sass-importer/entry/components/Entry.vue
new file mode 100644
index 00000000..63adb0ce
--- /dev/null
+++ b/e2e/2.x/sass-importer/entry/components/Entry.vue
@@ -0,0 +1,24 @@
+
+
+
Entry
+
+
+
+
+
+
+
diff --git a/e2e/2.x/sass-importer/entry/package.json b/e2e/2.x/sass-importer/entry/package.json
new file mode 100644
index 00000000..5637c767
--- /dev/null
+++ b/e2e/2.x/sass-importer/entry/package.json
@@ -0,0 +1,49 @@
+{
+ "name": "vue2-sass-importer-entry",
+ "version": "1.0.0",
+ "license": "MIT",
+ "private": true,
+ "scripts": {
+ "test": "jest --no-cache --coverage test.js"
+ },
+ "dependencies": {
+ "vue": "^2.7.7",
+ "vue-template-compiler": "^2.7.7",
+ "vue2-sass-importer-lib": "file:../lib",
+ "vue2-sass-importer-sass-lib": "file:../sass-lib-v2"
+ },
+ "devDependencies": {
+ "@babel/core": "^7.9.0",
+ "@babel/preset-env": "^7.9.0",
+ "@vue/vue2-jest": "^29.0.0",
+ "@vue/test-utils": "^1.1.0",
+ "babel-jest": "29.x",
+ "jest": "29.x",
+ "jest-environment-jsdom": "29.x",
+ "postcss": "^7.0.13",
+ "postcss-color-function": "^4.0.1",
+ "sass": "^1.23.7"
+ },
+ "jest": {
+ "testEnvironment": "jsdom",
+ "moduleFileExtensions": [
+ "js",
+ "json",
+ "vue"
+ ],
+ "transformIgnorePatterns": [
+ "/node_modules/.*(? {
+ const wrapper = mount(Entry)
+ expect(wrapper).toBeDefined()
+})
diff --git a/e2e/2.x/sass-importer/lib/index.vue b/e2e/2.x/sass-importer/lib/index.vue
new file mode 100644
index 00000000..50d3742c
--- /dev/null
+++ b/e2e/2.x/sass-importer/lib/index.vue
@@ -0,0 +1,11 @@
+
+ Lib Component
+
+
+
diff --git a/e2e/2.x/sass-importer/lib/package.json b/e2e/2.x/sass-importer/lib/package.json
new file mode 100644
index 00000000..6d9b3678
--- /dev/null
+++ b/e2e/2.x/sass-importer/lib/package.json
@@ -0,0 +1,19 @@
+{
+ "name": "vue2-sass-importer-lib",
+ "version": "1.0.0",
+ "license": "MIT",
+ "private": true,
+ "main": "index.vue",
+ "files": [
+ "index.vue"
+ ],
+ "scripts": {
+ "test": "echo 'No tests found.'"
+ },
+ "dependencies": {
+ "vue2-sass-importer-sass-lib": "file:../sass-lib-v1"
+ },
+ "peerDependencies": {
+ "vue": "^2.7.7"
+ }
+}
diff --git a/e2e/2.x/sass-importer/sass-lib-v1/index.scss b/e2e/2.x/sass-importer/sass-lib-v1/index.scss
new file mode 100644
index 00000000..05795e0f
--- /dev/null
+++ b/e2e/2.x/sass-importer/sass-lib-v1/index.scss
@@ -0,0 +1,3 @@
+@mixin my-v1-mixin {
+ color: blue;
+}
diff --git a/e2e/2.x/sass-importer/sass-lib-v1/package.json b/e2e/2.x/sass-importer/sass-lib-v1/package.json
new file mode 100644
index 00000000..cc5fc32c
--- /dev/null
+++ b/e2e/2.x/sass-importer/sass-lib-v1/package.json
@@ -0,0 +1,12 @@
+{
+ "name": "vue2-sass-importer-sass-lib",
+ "version": "1.0.0",
+ "license": "MIT",
+ "private": true,
+ "files": [
+ "index.scss"
+ ],
+ "scripts": {
+ "test": "echo 'No tests found.'"
+ }
+}
diff --git a/e2e/2.x/sass-importer/sass-lib-v2/index.scss b/e2e/2.x/sass-importer/sass-lib-v2/index.scss
new file mode 100644
index 00000000..8f5e144d
--- /dev/null
+++ b/e2e/2.x/sass-importer/sass-lib-v2/index.scss
@@ -0,0 +1,3 @@
+@mixin my-v2-mixin {
+ color: red;
+}
diff --git a/e2e/2.x/sass-importer/sass-lib-v2/package.json b/e2e/2.x/sass-importer/sass-lib-v2/package.json
new file mode 100644
index 00000000..b9b40960
--- /dev/null
+++ b/e2e/2.x/sass-importer/sass-lib-v2/package.json
@@ -0,0 +1,12 @@
+{
+ "name": "vue2-sass-importer-sass-lib",
+ "version": "2.0.0",
+ "license": "MIT",
+ "private": true,
+ "files": [
+ "index.scss"
+ ],
+ "scripts": {
+ "test": "echo 'No tests found.'"
+ }
+}
diff --git a/e2e/2.x/style/babel.config.js b/e2e/2.x/style/babel.config.js
new file mode 100644
index 00000000..7db9b6f5
--- /dev/null
+++ b/e2e/2.x/style/babel.config.js
@@ -0,0 +1,3 @@
+module.exports = {
+ presets: ['@babel/preset-env']
+}
diff --git a/e2e/2.x/style/colors.less b/e2e/2.x/style/colors.less
new file mode 100644
index 00000000..7b9ea3f9
--- /dev/null
+++ b/e2e/2.x/style/colors.less
@@ -0,0 +1 @@
+@primary-color: "red";
diff --git a/e2e/2.x/style/colors.scss b/e2e/2.x/style/colors.scss
new file mode 100644
index 00000000..d7cf8edb
--- /dev/null
+++ b/e2e/2.x/style/colors.scss
@@ -0,0 +1 @@
+$primary-color: #333;
diff --git a/e2e/2.x/style/components/External.vue b/e2e/2.x/style/components/External.vue
new file mode 100644
index 00000000..a73939a0
--- /dev/null
+++ b/e2e/2.x/style/components/External.vue
@@ -0,0 +1,17 @@
+
+
+
+
+
+
+
+
+
+
+
diff --git a/e2e/2.x/style/components/Less.vue b/e2e/2.x/style/components/Less.vue
new file mode 100644
index 00000000..3e94f459
--- /dev/null
+++ b/e2e/2.x/style/components/Less.vue
@@ -0,0 +1,18 @@
+
+
+
+
+
diff --git a/e2e/2.x/style/components/PostCss.vue b/e2e/2.x/style/components/PostCss.vue
new file mode 100644
index 00000000..1d748f32
--- /dev/null
+++ b/e2e/2.x/style/components/PostCss.vue
@@ -0,0 +1,31 @@
+
+
+
+
+
+
+
diff --git a/e2e/2.x/style/components/Sass.vue b/e2e/2.x/style/components/Sass.vue
new file mode 100644
index 00000000..a76ec392
--- /dev/null
+++ b/e2e/2.x/style/components/Sass.vue
@@ -0,0 +1,20 @@
+
+
+
+
+
+
+
+
+
diff --git a/e2e/2.x/style/components/Scss.vue b/e2e/2.x/style/components/Scss.vue
new file mode 100644
index 00000000..36e2b582
--- /dev/null
+++ b/e2e/2.x/style/components/Scss.vue
@@ -0,0 +1,30 @@
+
+
+
+
+
+
+
+
+
diff --git a/e2e/2.x/style/components/Stylus.vue b/e2e/2.x/style/components/Stylus.vue
new file mode 100644
index 00000000..7a790344
--- /dev/null
+++ b/e2e/2.x/style/components/Stylus.vue
@@ -0,0 +1,17 @@
+
+
+
+
+
+
+
diff --git a/e2e/2.x/style/components/relative/resource.styl b/e2e/2.x/style/components/relative/resource.styl
new file mode 100644
index 00000000..a1417501
--- /dev/null
+++ b/e2e/2.x/style/components/relative/resource.styl
@@ -0,0 +1 @@
+standard-space = 11px
\ No newline at end of file
diff --git a/e2e/2.x/style/components/styles/external.css b/e2e/2.x/style/components/styles/external.css
new file mode 100644
index 00000000..365af23e
--- /dev/null
+++ b/e2e/2.x/style/components/styles/external.css
@@ -0,0 +1,3 @@
+.testClass {
+ background-color: red;
+}
diff --git a/e2e/2.x/style/components/styles/less-a.less b/e2e/2.x/style/components/styles/less-a.less
new file mode 100644
index 00000000..6b45a74c
--- /dev/null
+++ b/e2e/2.x/style/components/styles/less-a.less
@@ -0,0 +1,7 @@
+@import "variables";
+.c {
+ color: @primary-color;
+}
+.d {
+ background-color: @primary-color;
+}
diff --git a/e2e/2.x/style/components/styles/sass-a.sass b/e2e/2.x/style/components/styles/sass-a.sass
new file mode 100644
index 00000000..222ddb76
--- /dev/null
+++ b/e2e/2.x/style/components/styles/sass-a.sass
@@ -0,0 +1,4 @@
+@import "./sass-b"
+
+.a
+ background-color: blue
diff --git a/e2e/2.x/style/components/styles/sass-b.sass b/e2e/2.x/style/components/styles/sass-b.sass
new file mode 100644
index 00000000..ec96d2c0
--- /dev/null
+++ b/e2e/2.x/style/components/styles/sass-b.sass
@@ -0,0 +1,2 @@
+.b
+ background-color: blue
diff --git a/e2e/2.x/style/components/styles/scss-a.scss b/e2e/2.x/style/components/styles/scss-a.scss
new file mode 100644
index 00000000..30630635
--- /dev/null
+++ b/e2e/2.x/style/components/styles/scss-a.scss
@@ -0,0 +1,5 @@
+@import "./scss-b";
+
+.a {
+ background-color: blue
+}
diff --git a/e2e/2.x/style/components/styles/scss-b.scss b/e2e/2.x/style/components/styles/scss-b.scss
new file mode 100644
index 00000000..b8341292
--- /dev/null
+++ b/e2e/2.x/style/components/styles/scss-b.scss
@@ -0,0 +1,3 @@
+.b {
+ background-color: blue;
+}
diff --git a/e2e/2.x/style/jest.config.js b/e2e/2.x/style/jest.config.js
new file mode 100644
index 00000000..ee5fa002
--- /dev/null
+++ b/e2e/2.x/style/jest.config.js
@@ -0,0 +1,23 @@
+const os = require('node:os')
+
+/** @type {import('@jest/types').Config.InitialOptions} */
+module.exports = {
+ testEnvironment: 'jsdom',
+ moduleFileExtensions: ['js', 'json', 'vue'],
+ transform: {
+ '^.+\\.js$': 'babel-jest',
+ '^.+\\.vue$': '@vue/vue2-jest'
+ },
+ moduleNameMapper: {
+ '^~tmp/(.*)': `${os.tmpdir()}/$1`,
+ '^~?__styles/(.*)$': '/components/styles/$1'
+ },
+ globals: {
+ 'vue-jest': {
+ resources: {
+ scss: ['variables.scss'],
+ less: ['variables.less']
+ }
+ }
+ }
+}
diff --git a/e2e/2.x/style/package.json b/e2e/2.x/style/package.json
new file mode 100644
index 00000000..26fa1828
--- /dev/null
+++ b/e2e/2.x/style/package.json
@@ -0,0 +1,25 @@
+{
+ "name": "vue2-style",
+ "version": "1.0.0",
+ "license": "MIT",
+ "private": true,
+ "scripts": {
+ "test": "node setup.js && jest --no-cache test.js"
+ },
+ "dependencies": {
+ "vue": "^2.7.7",
+ "vue-template-compiler": "^2.7.7"
+ },
+ "devDependencies": {
+ "@babel/core": "^7.9.0",
+ "@babel/preset-env": "^7.9.0",
+ "@vue/test-utils": "^1.1.0",
+ "@vue/vue2-jest": "^29.0.0",
+ "jest": "29.x",
+ "jest-environment-jsdom": "29.x",
+ "less": "^3.9.0",
+ "postcss": "^7.0.13",
+ "sass": "^1.23.7",
+ "stylus": "^0.54.5"
+ }
+}
diff --git a/e2e/2.x/style/setup.js b/e2e/2.x/style/setup.js
new file mode 100644
index 00000000..70852065
--- /dev/null
+++ b/e2e/2.x/style/setup.js
@@ -0,0 +1,14 @@
+const fs = require('fs')
+const os = require('node:os')
+
+const testDir = '../../../node_modules/vue-jest-test'
+
+if (!fs.existsSync(testDir)) {
+ fs.mkdirSync(testDir)
+}
+
+fs.openSync(`${os.tmpdir()}/absolute.scss`, 'w')
+fs.openSync(`${testDir}/_partial.scss`, 'w')
+fs.openSync(`${testDir}/foo.bar.scss`, 'w')
+fs.openSync(`${testDir}/baz.css`, 'w')
+fs.openSync(`${testDir}/qux.sass`, 'w')
diff --git a/e2e/2.x/style/test.js b/e2e/2.x/style/test.js
new file mode 100644
index 00000000..af0777bd
--- /dev/null
+++ b/e2e/2.x/style/test.js
@@ -0,0 +1,51 @@
+import { mount } from '@vue/test-utils'
+import Stylus from './components/Stylus.vue'
+import Scss from './components/Scss.vue'
+import Sass from './components/Sass.vue'
+import Less from './components/Less.vue'
+import PostCss from './components/PostCss.vue'
+import External from './components/External.vue'
+
+test('processes Less', () => {
+ const wrapper = mount(Less)
+ expect(wrapper.element.tagName).toBe('DIV')
+ expect(wrapper.vm.$style.a).toEqual('a')
+})
+
+test('processes PostCSS', () => {
+ const wrapper = mount(PostCss)
+ expect(wrapper.element.tagName).toBe('SECTION')
+ expect(wrapper.vm.$style.a).toEqual('a')
+ expect(wrapper.vm.$style.b).toEqual('b')
+})
+
+test('processes Sass', () => {
+ const wrapper = mount(Sass)
+ expect(wrapper.vm.$style.a).toEqual('a')
+ expect(wrapper.vm.$style.b).toEqual('b')
+ expect(wrapper.vm.$style.c).toEqual('c')
+ expect(wrapper.vm.$style.light).toBeUndefined()
+})
+
+test('processes SCSS with resources', () => {
+ const wrapper = mount(Scss)
+ expect(wrapper.vm.$style.a).toEqual('a')
+ expect(wrapper.vm.$style.b).toEqual('b')
+ expect(wrapper.vm.$style.c).toEqual('c')
+})
+
+test('process Stylus', () => {
+ const wrapper = mount(Stylus)
+ expect(wrapper.vm).toBeTruthy()
+ expect(wrapper.vm.css.a).toEqual('a')
+ expect(wrapper.vm.$style.b).toEqual('b')
+})
+
+test('process External', () => {
+ const wrapper = mount(External)
+ expect(wrapper.vm).toBeTruthy()
+ expect(wrapper.vm.$style.testClass).toEqual('testClass')
+ expect(wrapper.vm.$style2.testClass).toEqual('testClass')
+ expect(wrapper.vm.$style3.testClass).toEqual('testClass')
+ expect(wrapper.vm.css.a).toEqual('a')
+})
diff --git a/e2e/2.x/style/variables.less b/e2e/2.x/style/variables.less
new file mode 100644
index 00000000..57319a4a
--- /dev/null
+++ b/e2e/2.x/style/variables.less
@@ -0,0 +1,3 @@
+@import "./colors.less";
+
+@font-size: 16px;
diff --git a/e2e/2.x/style/variables.scss b/e2e/2.x/style/variables.scss
new file mode 100644
index 00000000..4f8d9064
--- /dev/null
+++ b/e2e/2.x/style/variables.scss
@@ -0,0 +1,3 @@
+@import './colors.scss';
+
+$font-size: 16px;
diff --git a/e2e/3.x/babel-in-package/components/Tsx.vue b/e2e/3.x/babel-in-package/components/Tsx.vue
new file mode 100644
index 00000000..7a1062c3
--- /dev/null
+++ b/e2e/3.x/babel-in-package/components/Tsx.vue
@@ -0,0 +1,7 @@
+
diff --git a/e2e/3.x/babel-in-package/package.json b/e2e/3.x/babel-in-package/package.json
index 23c24c39..5c2ffe0f 100644
--- a/e2e/3.x/babel-in-package/package.json
+++ b/e2e/3.x/babel-in-package/package.json
@@ -7,19 +7,21 @@
"test": "jest --no-cache test.js"
},
"dependencies": {
- "vue": "^3.0.3"
+ "vue": "^3.2.22"
},
"devDependencies": {
"@babel/core": "^7.9.0",
"@babel/preset-env": "^7.9.0",
- "@vue/compiler-sfc": "^3.0.3",
+ "@vue/babel-plugin-jsx": "^1.1.5",
+ "@vue/vue3-jest": "^29.0.0",
"coffeescript": "^2.3.2",
- "jest": "^26.0.0",
- "ts-jest": "^26.4.4",
- "typescript": "^4.1.2",
- "vue3-jest": "^26.0.0-alpha.10"
+ "jest": "29.x",
+ "jest-environment-jsdom": "29.x",
+ "ts-jest": "^29.0.0-next.0",
+ "typescript": "^4.6.4"
},
"jest": {
+ "testEnvironment": "jsdom",
"moduleFileExtensions": [
"js",
"json",
@@ -27,12 +29,15 @@
],
"transform": {
"^.+\\.js$": "babel-jest",
- "^.+\\.vue$": "vue3-jest"
+ "^.+\\.vue$": "@vue/vue3-jest"
}
},
"babel": {
"presets": [
"@babel/env"
+ ],
+ "plugins": [
+ "@vue/babel-plugin-jsx"
]
}
}
diff --git a/e2e/3.x/babel-in-package/test.js b/e2e/3.x/babel-in-package/test.js
index 8bc52e74..e5b7d33d 100644
--- a/e2e/3.x/babel-in-package/test.js
+++ b/e2e/3.x/babel-in-package/test.js
@@ -3,6 +3,7 @@ import { createApp, h } from 'vue'
import TypeScript from './components/TypeScript.vue'
import Basic from './components/Basic.vue'
import Coffee from './components/Coffee.vue'
+import Tsx from './components/Tsx.vue'
function mount(Component, props, slots) {
document.getElementsByTagName('html')[0].innerHTML = ''
@@ -34,3 +35,8 @@ test('processes .vue files with lang set to typescript', () => {
expect(document.querySelector('#parent').textContent).toBe('Parent')
expect(document.querySelector('#child').textContent).toBe('Child')
})
+
+test('processes .vue files with lang set to tsx(typescript)', () => {
+ mount(Tsx)
+ expect(document.querySelector('div').textContent).toContain('tsx components')
+})
diff --git a/e2e/3.x/basic/__snapshots__/test.js.snap b/e2e/3.x/basic/__snapshots__/test.js.snap
index a10f241c..7ced6a2a 100644
--- a/e2e/3.x/basic/__snapshots__/test.js.snap
+++ b/e2e/3.x/basic/__snapshots__/test.js.snap
@@ -1,12 +1,12 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`generates source maps for .vue files 1`] = `
-"\\"use strict\\";
+""use strict";
-Object.defineProperty(exports, \\"__esModule\\", {
+Object.defineProperty(exports, "__esModule", {
value: true
});
-exports[\\"default\\"] = void 0;
+exports["default"] = void 0;
var _default = {
name: 'basic',
computed: {
@@ -30,28 +30,36 @@ var _default = {
}
}
};
-exports[\\"default\\"] = _default;
-\\"use strict\\";
-Object.defineProperty(exports, \\"__esModule\\", { value: true });
-exports.render = void 0;
-var vue_1 = require(\\"vue\\");
-var _hoisted_1 = { class: \\"hello\\" };
-function render(_ctx, _cache) {
- return (vue_1.openBlock(), vue_1.createBlock(\\"div\\", _hoisted_1, [
- vue_1.createVNode(\\"h1\\", { class: _ctx.headingClasses }, vue_1.toDisplayString(_ctx.msg), 3 /* TEXT, CLASS */)
- ]));
-}
+exports["default"] = _default;
+"use strict";
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
exports.render = render;
-;exports.default = {...exports.default, render};;exports.default = {...exports.default, __cssModules: {\\"css\\":{\\"testA\\":\\"testA\\"},\\"$style\\":{\\"testB\\":\\"testB\\"}}}"
+
+var _vue = require("vue");
+
+var _hoisted_1 = {
+ "class": "hello"
+};
+
+function render(_ctx, _cache) {
+ return (0, _vue.openBlock)(), (0, _vue.createElementBlock)("div", _hoisted_1, [(0, _vue.createElementVNode)("h1", {
+ "class": (0, _vue.normalizeClass)(_ctx.headingClasses)
+ }, (0, _vue.toDisplayString)(_ctx.msg), 3
+ /* TEXT, CLASS */
+ )]);
+};exports.default = {...exports.default, render};;exports.default = {...exports.default, __cssModules: {"css":{"testA":"testA"},"$style":{"testB":"testB"}}}"
`;
exports[`generates source maps using src attributes 1`] = `
-"\\"use strict\\";
+""use strict";
-Object.defineProperty(exports, \\"__esModule\\", {
+Object.defineProperty(exports, "__esModule", {
value: true
});
-exports[\\"default\\"] = void 0;
+exports["default"] = void 0;
var _default = {
name: 'basic',
computed: {
@@ -75,17 +83,25 @@ var _default = {
}
}
};
-exports[\\"default\\"] = _default;
-\\"use strict\\";
-Object.defineProperty(exports, \\"__esModule\\", { value: true });
-exports.render = void 0;
-var vue_1 = require(\\"vue\\");
-var _hoisted_1 = { class: \\"hello\\" };
-function render(_ctx, _cache) {
- return (vue_1.openBlock(), vue_1.createBlock(\\"div\\", _hoisted_1, [
- vue_1.createVNode(\\"h1\\", { class: _ctx.headingClasses }, vue_1.toDisplayString(_ctx.msg), 3 /* TEXT, CLASS */)
- ]));
-}
+exports["default"] = _default;
+"use strict";
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
exports.render = render;
-;exports.default = {...exports.default, render};"
+
+var _vue = require("vue");
+
+var _hoisted_1 = {
+ "class": "hello"
+};
+
+function render(_ctx, _cache) {
+ return (0, _vue.openBlock)(), (0, _vue.createElementBlock)("div", _hoisted_1, [(0, _vue.createElementVNode)("h1", {
+ "class": (0, _vue.normalizeClass)(_ctx.headingClasses)
+ }, (0, _vue.toDisplayString)(_ctx.msg), 3
+ /* TEXT, CLASS */
+ )]);
+};exports.default = {...exports.default, render};"
`;
diff --git a/e2e/3.x/basic/components/CompilerDirective.vue b/e2e/3.x/basic/components/CompilerDirective.vue
new file mode 100644
index 00000000..9ae9a9a2
--- /dev/null
+++ b/e2e/3.x/basic/components/CompilerDirective.vue
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/e2e/3.x/basic/components/ExtendedTsConfig.vue b/e2e/3.x/basic/components/ExtendedTsConfig.vue
new file mode 100644
index 00000000..8dc7001f
--- /dev/null
+++ b/e2e/3.x/basic/components/ExtendedTsConfig.vue
@@ -0,0 +1,34 @@
+
+
+ {{ exclamationMarks }}
+
+
+
+
+
diff --git a/e2e/3.x/basic/components/ModuleRequiringEsModuleInterop.js b/e2e/3.x/basic/components/ModuleRequiringEsModuleInterop.js
new file mode 100644
index 00000000..fed7caa7
--- /dev/null
+++ b/e2e/3.x/basic/components/ModuleRequiringEsModuleInterop.js
@@ -0,0 +1 @@
+module.exports = () => false
diff --git a/e2e/3.x/basic/components/ScriptAndScriptSetup.vue b/e2e/3.x/basic/components/ScriptAndScriptSetup.vue
new file mode 100644
index 00000000..e3aa2fcb
--- /dev/null
+++ b/e2e/3.x/basic/components/ScriptAndScriptSetup.vue
@@ -0,0 +1,23 @@
+
+
+
+
+ {{ msg }}
+
+
+
+
+
+
diff --git a/e2e/3.x/basic/components/ScriptSetupSugarRef.vue b/e2e/3.x/basic/components/ScriptSetupSugarRef.vue
new file mode 100644
index 00000000..268a78a7
--- /dev/null
+++ b/e2e/3.x/basic/components/ScriptSetupSugarRef.vue
@@ -0,0 +1,17 @@
+
+
+
+ {{ msg }}
+
+
+
diff --git a/e2e/3.x/basic/jest.config.js b/e2e/3.x/basic/jest.config.js
new file mode 100644
index 00000000..4552a185
--- /dev/null
+++ b/e2e/3.x/basic/jest.config.js
@@ -0,0 +1,26 @@
+const vTestDirective = require('./v-test-directive')
+
+module.exports = {
+ testEnvironment: 'jsdom',
+ moduleFileExtensions: ['js', 'json', 'vue', 'ts'],
+ transform: {
+ '^.+\\.ts$': 'ts-jest',
+ '^.+\\.js$': 'babel-jest',
+ '^.+\\.vue$': '@vue/vue3-jest'
+ },
+ moduleNameMapper: {
+ '^~?__styles/(.*)$': '/components/styles/$1'
+ },
+ globals: {
+ 'vue-jest': {
+ pug: {
+ basedir: './'
+ },
+ compilerOptions: {
+ directiveTransforms: {
+ test: vTestDirective
+ }
+ }
+ }
+ }
+}
diff --git a/e2e/3.x/basic/package.json b/e2e/3.x/basic/package.json
index 95365075..802d2608 100644
--- a/e2e/3.x/basic/package.json
+++ b/e2e/3.x/basic/package.json
@@ -7,46 +7,23 @@
"test": "jest --no-cache --coverage test.js"
},
"dependencies": {
- "vue": "^3.0.3"
+ "vue": "^3.2.22"
},
"devDependencies": {
"@babel/core": "^7.9.0",
"@babel/preset-env": "^7.9.0",
- "@vue/compiler-sfc": "^3.0.3",
+ "@vue/vue3-jest": "^29.0.0",
"babel-helper-vue-jsx-merge-props": "^2.0.3",
"babel-plugin-syntax-jsx": "^6.18.0",
"babel-plugin-transform-vue-jsx": "^3.7.0",
"coffeescript": "^2.3.2",
"jade": "^1.11.0",
- "jest": "^26.0.0",
+ "jest": "29.x",
+ "jest-environment-jsdom": "29.x",
"pug": "^2.0.3",
- "ts-jest": "^26.4.4",
- "typescript": "^4.1.2",
+ "ts-jest": "^29.0.0-next.0",
+ "typescript": "^4.6.4",
"vue-class-component": "^8.0.0-beta.4",
- "vue3-jest": "^26.0.0-alpha.10",
"vue-property-decorator": "^10.0.0-rc.3"
- },
- "jest": {
- "moduleFileExtensions": [
- "js",
- "json",
- "vue",
- "ts"
- ],
- "transform": {
- "^.+\\.ts$": "ts-jest",
- "^.+\\.js$": "babel-jest",
- "^.+\\.vue$": "vue3-jest"
- },
- "moduleNameMapper": {
- "^~?__styles/(.*)$": "/components/styles/$1"
- },
- "globals": {
- "vue-jest": {
- "pug": {
- "basedir": "./"
- }
- }
- }
}
}
diff --git a/e2e/3.x/basic/test.js b/e2e/3.x/basic/test.js
index 16360102..504c44c7 100644
--- a/e2e/3.x/basic/test.js
+++ b/e2e/3.x/basic/test.js
@@ -11,7 +11,7 @@ import ClassComponent from './components/ClassComponent.vue'
import ClassComponentWithMixin from './components/ClassComponentWithMixin.vue'
import ClassComponentProperty from './components/ClassComponentProperty.vue'
import TypeScript from './components/TypeScript.vue'
-import jestVue from 'vue3-jest'
+import jestVue from '@vue/vue3-jest'
import RenderFunction from './components/RenderFunction.vue'
import FunctionalSFC from './components/FunctionalSFC.vue'
import CoffeeScript from './components/CoffeeScript.vue'
@@ -20,7 +20,11 @@ import NoScript from './components/NoScript.vue'
import PugRelative from './components/PugRelativeExtends.vue'
import { randomExport } from './components/NamedExport.vue'
import ScriptSetup from './components/ScriptSetup.vue'
+import ScriptSetupSugarRef from './components/ScriptSetupSugarRef.vue'
import FunctionalRenderFn from './components/FunctionalRenderFn.vue'
+import CompilerDirective from './components/CompilerDirective.vue'
+import ExtendedTsConfig from './components/ExtendedTsConfig.vue'
+import ScriptAndScriptSetup from './components/ScriptAndScriptSetup.vue'
// TODO: JSX for Vue 3? TSX?
import Jsx from './components/Jsx.vue'
@@ -35,7 +39,9 @@ function mount(Component, props, slots) {
return h(Component, props, slots)
}
}
- createApp(Parent).mount(el)
+ const app = createApp(Parent)
+ app.directive('test', el => el.setAttribute('data-test', 'value'))
+ app.mount(el)
}
test('supports
+
+
+{
+ "en": {
+ "hello": "Hello!"
+ },
+ "ja": {
+ "hello": "こんにちは!"
+ }
+}
+
diff --git a/e2e/3.x/custom-block/components/Multiple.vue b/e2e/3.x/custom-block/components/Multiple.vue
new file mode 100644
index 00000000..f204d041
--- /dev/null
+++ b/e2e/3.x/custom-block/components/Multiple.vue
@@ -0,0 +1,26 @@
+
+ multiple custom block
+
+
+
+
+
+{
+ "en": {
+ "hello": "Hello!"
+ },
+ "ja": {
+ "hello": "こんにちは!"
+ }
+}
+
+
+
+{
+ "foo": "foo"
+}
+
diff --git a/e2e/3.x/custom-block/package.json b/e2e/3.x/custom-block/package.json
new file mode 100644
index 00000000..33edb595
--- /dev/null
+++ b/e2e/3.x/custom-block/package.json
@@ -0,0 +1,41 @@
+{
+ "name": "vue3-custom-block",
+ "version": "1.0.0",
+ "license": "MIT",
+ "private": true,
+ "scripts": {
+ "test": "jest --no-cache --coverage test.js"
+ },
+ "dependencies": {
+ "vue": "^3.0.3"
+ },
+ "devDependencies": {
+ "@babel/core": "^7.9.0",
+ "@babel/preset-env": "^7.9.0",
+ "@vue/compiler-sfc": "^3.0.3",
+ "@vue/vue3-jest": "^29.0.0",
+ "jest": "29.x",
+ "jest-environment-jsdom": "29.x"
+ },
+ "jest": {
+ "moduleFileExtensions": [
+ "js",
+ "json",
+ "vue"
+ ],
+ "transform": {
+ "^.+\\.js$": "babel-jest",
+ "^.+\\.vue$": "@vue/vue3-jest"
+ },
+ "moduleNameMapper": {
+ "^~?__styles/(.*)$": "/components/styles/$1"
+ },
+ "globals": {
+ "vue-jest": {
+ "transform": {
+ "custom": "./transformer.js"
+ }
+ }
+ }
+ }
+}
diff --git a/e2e/3.x/custom-block/test.js b/e2e/3.x/custom-block/test.js
new file mode 100644
index 00000000..79556a9c
--- /dev/null
+++ b/e2e/3.x/custom-block/test.js
@@ -0,0 +1,33 @@
+import Basic from './components/Basic.vue'
+import Multiple from './components/Multiple.vue'
+
+test('Basic', () => {
+ expect(Basic.__custom).toMatchObject([
+ {
+ en: {
+ hello: 'Hello!'
+ },
+ ja: {
+ hello: 'こんにちは!'
+ }
+ }
+ ])
+ expect(Basic.__custom).toMatchSnapshot()
+})
+
+test('Multiple blocks', () => {
+ expect(Multiple.__custom).toMatchObject([
+ {
+ en: {
+ hello: 'Hello!'
+ },
+ ja: {
+ hello: 'こんにちは!'
+ }
+ },
+ {
+ foo: 'foo'
+ }
+ ])
+ expect(Multiple.__custom).toMatchSnapshot()
+})
diff --git a/e2e/3.x/custom-block/transformer.js b/e2e/3.x/custom-block/transformer.js
new file mode 100644
index 00000000..e51da0f5
--- /dev/null
+++ b/e2e/3.x/custom-block/transformer.js
@@ -0,0 +1,21 @@
+function convert(content) {
+ return JSON.stringify(JSON.parse(content))
+ .replace(/\u2028/g, '\\u2028') // LINE SEPARATOR
+ .replace(/\u2029/g, '\\u2029') // PARAGRAPH SEPARATOR
+ .replace(/\\/g, '\\\\')
+ .replace(/'/g, "\\'")
+}
+
+module.exports = {
+ process({ blocks, componentNamespace, filename, config }) {
+ const ret = blocks.reduce((codes, block) => {
+ codes.push(
+ `${componentNamespace}.__custom = ${componentNamespace}.__custom || [];${componentNamespace}.__custom.push(${convert(
+ block.content
+ )});`
+ )
+ return codes
+ }, [])
+ return ret
+ }
+}
diff --git a/e2e/3.x/custom-transformers/babel-transformer.js b/e2e/3.x/custom-transformers/babel-transformer.js
index 2be39a8a..193503e5 100644
--- a/e2e/3.x/custom-transformers/babel-transformer.js
+++ b/e2e/3.x/custom-transformers/babel-transformer.js
@@ -1,4 +1,4 @@
-const { createTransformer } = require('babel-jest')
+const { createTransformer } = require('babel-jest').default
module.exports = createTransformer({
presets: ['@babel/preset-env']
})
diff --git a/e2e/3.x/custom-transformers/components/Scss.vue b/e2e/3.x/custom-transformers/components/Scss.vue
index 6b88eb24..474edea9 100644
--- a/e2e/3.x/custom-transformers/components/Scss.vue
+++ b/e2e/3.x/custom-transformers/components/Scss.vue
@@ -1,7 +1,7 @@
-
-
+
+
diff --git a/e2e/3.x/custom-transformers/package.json b/e2e/3.x/custom-transformers/package.json
index 4ba9d191..b09c1a5b 100644
--- a/e2e/3.x/custom-transformers/package.json
+++ b/e2e/3.x/custom-transformers/package.json
@@ -7,21 +7,23 @@
"test": "jest --no-cache --coverage test.js"
},
"dependencies": {
- "@vue/compiler-sfc": "^3.0.3",
- "vue": "^3.0.3"
+ "vue": "^3.2.22"
},
"devDependencies": {
"@babel/core": "^7.9.0",
"@babel/preset-env": "^7.9.0",
- "babel-jest": "^26.0.0",
- "extract-from-css": "^0.4.4",
- "jest": "^26.0.0",
+ "@vue/test-utils": "^2.0.0-rc.10",
+ "@vue/vue3-jest": "^29.0.0",
+ "babel-jest": "29.x",
+ "css-tree": "^2.0.1",
+ "jest": "29.x",
+ "jest-environment-jsdom": "29.x",
"postcss": "^7.0.13",
"postcss-color-function": "^4.0.1",
- "sass": "^1.23.7",
- "vue3-jest": "^26.0.0-alpha.10"
+ "sass": "^1.23.7"
},
"jest": {
+ "testEnvironment": "jsdom",
"moduleFileExtensions": [
"js",
"json",
@@ -29,7 +31,7 @@
],
"transform": {
"^.+\\.js$": "./babel-transformer.js",
- "^.+\\.vue$": "vue3-jest"
+ "^.+\\.vue$": "@vue/vue3-jest"
},
"moduleNameMapper": {
"^~?__styles/(.*)$": "/components/styles/$1"
diff --git a/e2e/3.x/custom-transformers/scss-transformer.js b/e2e/3.x/custom-transformers/scss-transformer.js
index b2ca2848..15eb6cb0 100644
--- a/e2e/3.x/custom-transformers/scss-transformer.js
+++ b/e2e/3.x/custom-transformers/scss-transformer.js
@@ -1,14 +1,18 @@
-const cssExtract = require('extract-from-css')
+const cssTree = require('css-tree')
+
module.exports = {
preprocess: function preprocess(src, filepath, config, attrs) {
return `${src}\n .g{width: 10px}`
},
postprocess: function postprocess(src, filepath, config, attrs) {
- const cssNames = cssExtract.extractClasses(src)
- const obj = {}
- for (let i = 0, l = cssNames.length; i < l; i++) {
- obj[cssNames[i]] = cssNames[i]
- }
+ const ast = cssTree.parse(src)
+ const obj = cssTree
+ .findAll(ast, node => node.type === 'ClassSelector')
+ .reduce((acc, cssNode) => {
+ acc[cssNode.name] = cssNode.name
+
+ return acc
+ }, {})
if (!attrs.themed) {
return JSON.stringify(obj)
diff --git a/e2e/3.x/custom-transformers/test.js b/e2e/3.x/custom-transformers/test.js
index 406e7d6c..8794fe21 100644
--- a/e2e/3.x/custom-transformers/test.js
+++ b/e2e/3.x/custom-transformers/test.js
@@ -1,21 +1,15 @@
-// import { createApp, h } from 'vue'
-
-// import Scss from './components/Scss.vue'
-
-// function mount(Component, props, slots) {
-// document.getElementsByTagName('html')[0].innerHTML = ''
-// const el = document.createElement('div')
-// el.id = 'app'
-// document.body.appendChild(el)
-// const Parent = {
-// render() {
-// return h(Component, props, slots)
-// }
-// }
-// createApp(Parent).mount(el)
-// }
-
-// TODO: Figure this out with Vue 3. `$style` no longer exists.
-test.todo('processes SCSS using user specified post transforms')
-
-test.todo('processes SCSS using user specified pre transforms')
+import { mount } from '@vue/test-utils'
+import Scss from './components/Scss.vue'
+
+test('processes SCSS using user specified post transforms', () => {
+ const wrapper = mount(Scss)
+ expect(wrapper.vm.$style.light.a).toBeUndefined()
+ expect(wrapper.vm.$style.light.f).toEqual('f')
+ expect(wrapper.vm.$style.dark.f).toEqual('f')
+ expect(wrapper.vm.$style.dark.g).toEqual('g')
+})
+
+test('processes SCSS using user specified pre transforms', () => {
+ const wrapper = mount(Scss)
+ expect(wrapper.vm.$style.g).toEqual('g')
+})
diff --git a/e2e/3.x/javascript/package.json b/e2e/3.x/javascript/package.json
index 64b0db6e..a7d1aefb 100644
--- a/e2e/3.x/javascript/package.json
+++ b/e2e/3.x/javascript/package.json
@@ -7,16 +7,18 @@
"test": "jest --no-cache test.js"
},
"dependencies": {
- "vue": "^3.0.3"
+ "vue": "^3.2.22"
},
"devDependencies": {
"@babel/core": "^7.9.0",
"@babel/preset-env": "^7.9.0",
+ "@vue/vue3-jest": "^29.0.0",
"coffeescript": "^2.3.2",
- "jest": "^26.0.0",
- "vue3-jest": "^26.0.0-alpha.10"
+ "jest": "29.x",
+ "jest-environment-jsdom": "29.x"
},
"jest": {
+ "testEnvironment": "jsdom",
"moduleFileExtensions": [
"js",
"json",
@@ -24,7 +26,7 @@
],
"transform": {
"^.+\\.js$": "babel-jest",
- "^.+\\.vue$": "vue3-jest"
+ "^.+\\.vue$": "@vue/vue3-jest"
}
},
"babel": {
diff --git a/e2e/3.x/sass-importer/entry/babel-transformer.js b/e2e/3.x/sass-importer/entry/babel-transformer.js
new file mode 100644
index 00000000..193503e5
--- /dev/null
+++ b/e2e/3.x/sass-importer/entry/babel-transformer.js
@@ -0,0 +1,4 @@
+const { createTransformer } = require('babel-jest').default
+module.exports = createTransformer({
+ presets: ['@babel/preset-env']
+})
diff --git a/e2e/3.x/sass-importer/entry/components/Entry.vue b/e2e/3.x/sass-importer/entry/components/Entry.vue
new file mode 100644
index 00000000..367e3f6b
--- /dev/null
+++ b/e2e/3.x/sass-importer/entry/components/Entry.vue
@@ -0,0 +1,24 @@
+
+
+
Entry
+
+
+
+
+
+
+
diff --git a/e2e/3.x/sass-importer/entry/package.json b/e2e/3.x/sass-importer/entry/package.json
new file mode 100644
index 00000000..da99c925
--- /dev/null
+++ b/e2e/3.x/sass-importer/entry/package.json
@@ -0,0 +1,48 @@
+{
+ "name": "vue3-sass-importer-entry",
+ "version": "1.0.0",
+ "license": "MIT",
+ "private": true,
+ "scripts": {
+ "test": "jest --no-cache --coverage test.js"
+ },
+ "dependencies": {
+ "vue": "^3.2.22",
+ "vue3-sass-importer-lib": "file:../lib",
+ "vue3-sass-importer-sass-lib": "file:../sass-lib-v2"
+ },
+ "devDependencies": {
+ "@babel/core": "^7.9.0",
+ "@babel/preset-env": "^7.9.0",
+ "@vue/test-utils": "^2.0.0-rc.10",
+ "@vue/vue3-jest": "^29.0.0",
+ "babel-jest": "29.x",
+ "jest": "29.x",
+ "jest-environment-jsdom": "29.x",
+ "postcss": "^7.0.13",
+ "postcss-color-function": "^4.0.1",
+ "sass": "^1.23.7"
+ },
+ "jest": {
+ "testEnvironment": "jsdom",
+ "moduleFileExtensions": [
+ "js",
+ "json",
+ "vue"
+ ],
+ "transformIgnorePatterns": [
+ "/node_modules/.*(? {
+ const wrapper = mount(Entry)
+ expect(wrapper).toBeDefined()
+})
diff --git a/e2e/3.x/sass-importer/lib/index.vue b/e2e/3.x/sass-importer/lib/index.vue
new file mode 100644
index 00000000..fc3c0231
--- /dev/null
+++ b/e2e/3.x/sass-importer/lib/index.vue
@@ -0,0 +1,11 @@
+
+ Lib Component
+
+
+
diff --git a/e2e/3.x/sass-importer/lib/package.json b/e2e/3.x/sass-importer/lib/package.json
new file mode 100644
index 00000000..6f19b178
--- /dev/null
+++ b/e2e/3.x/sass-importer/lib/package.json
@@ -0,0 +1,19 @@
+{
+ "name": "vue3-sass-importer-lib",
+ "version": "1.0.0",
+ "license": "MIT",
+ "private": true,
+ "main": "index.vue",
+ "files": [
+ "index.vue"
+ ],
+ "scripts": {
+ "test": "echo 'No tests found.'"
+ },
+ "dependencies": {
+ "vue3-sass-importer-sass-lib": "file:../sass-lib-v1"
+ },
+ "peerDependencies": {
+ "vue": "^3.2.22"
+ }
+}
diff --git a/e2e/3.x/sass-importer/sass-lib-v1/index.scss b/e2e/3.x/sass-importer/sass-lib-v1/index.scss
new file mode 100644
index 00000000..05795e0f
--- /dev/null
+++ b/e2e/3.x/sass-importer/sass-lib-v1/index.scss
@@ -0,0 +1,3 @@
+@mixin my-v1-mixin {
+ color: blue;
+}
diff --git a/e2e/3.x/sass-importer/sass-lib-v1/package.json b/e2e/3.x/sass-importer/sass-lib-v1/package.json
new file mode 100644
index 00000000..5717428c
--- /dev/null
+++ b/e2e/3.x/sass-importer/sass-lib-v1/package.json
@@ -0,0 +1,12 @@
+{
+ "name": "vue3-sass-importer-sass-lib",
+ "version": "1.0.0",
+ "license": "MIT",
+ "private": true,
+ "files": [
+ "index.scss"
+ ],
+ "scripts": {
+ "test": "echo 'No tests found.'"
+ }
+}
diff --git a/e2e/3.x/sass-importer/sass-lib-v2/index.scss b/e2e/3.x/sass-importer/sass-lib-v2/index.scss
new file mode 100644
index 00000000..8f5e144d
--- /dev/null
+++ b/e2e/3.x/sass-importer/sass-lib-v2/index.scss
@@ -0,0 +1,3 @@
+@mixin my-v2-mixin {
+ color: red;
+}
diff --git a/e2e/3.x/sass-importer/sass-lib-v2/package.json b/e2e/3.x/sass-importer/sass-lib-v2/package.json
new file mode 100644
index 00000000..d06a853a
--- /dev/null
+++ b/e2e/3.x/sass-importer/sass-lib-v2/package.json
@@ -0,0 +1,12 @@
+{
+ "name": "vue3-sass-importer-sass-lib",
+ "version": "2.0.0",
+ "license": "MIT",
+ "private": true,
+ "files": [
+ "index.scss"
+ ],
+ "scripts": {
+ "test": "echo 'No tests found.'"
+ }
+}
diff --git a/e2e/3.x/style/colors.less b/e2e/3.x/style/colors.less
new file mode 100644
index 00000000..7b9ea3f9
--- /dev/null
+++ b/e2e/3.x/style/colors.less
@@ -0,0 +1 @@
+@primary-color: "red";
diff --git a/e2e/3.x/style/colors.scss b/e2e/3.x/style/colors.scss
new file mode 100644
index 00000000..d7cf8edb
--- /dev/null
+++ b/e2e/3.x/style/colors.scss
@@ -0,0 +1 @@
+$primary-color: #333;
diff --git a/e2e/3.x/style/components/External.vue b/e2e/3.x/style/components/External.vue
index 90b1df56..55fd7ae4 100644
--- a/e2e/3.x/style/components/External.vue
+++ b/e2e/3.x/style/components/External.vue
@@ -6,6 +6,10 @@
+
+
+
+
+
+
+
+
diff --git a/e2e/3.x/typescript/src/components/ScriptSetup.vue b/e2e/3.x/typescript/src/components/ScriptSetup.vue
new file mode 100644
index 00000000..b5de8edc
--- /dev/null
+++ b/e2e/3.x/typescript/src/components/ScriptSetup.vue
@@ -0,0 +1,18 @@
+
+
+
+ {{ msg! }}
+
+
+
diff --git a/e2e/3.x/typescript/src/shims-vue.d.ts b/e2e/3.x/typescript/src/shims-vue.d.ts
new file mode 100644
index 00000000..64c3fd9e
--- /dev/null
+++ b/e2e/3.x/typescript/src/shims-vue.d.ts
@@ -0,0 +1,5 @@
+declare module '*.vue' {
+ import type { DefineComponent } from 'vue';
+ const component: DefineComponent<{}, {}, any>;
+ export default component;
+}
diff --git a/e2e/3.x/typescript/src/test.ts b/e2e/3.x/typescript/src/test.ts
new file mode 100644
index 00000000..a20b3d77
--- /dev/null
+++ b/e2e/3.x/typescript/src/test.ts
@@ -0,0 +1,30 @@
+import { createApp, h } from 'vue'
+
+import Basic from '@/components/Basic.vue'
+import ScriptSetup from '@/components/ScriptSetup.vue'
+
+function mount(Component: any) {
+ document.getElementsByTagName('html')[0].innerHTML = ''
+ const el = document.createElement('div')
+ el.id = 'app'
+ document.body.appendChild(el)
+ const Parent = {
+ render() {
+ return h(Component)
+ }
+ }
+ createApp(Parent).mount(el)
+}
+
+test('processes .vue files', () => {
+ mount(Basic)
+ expect(document.querySelector('h1')!.textContent).toBe(
+ 'Welcome to Your Vue.js App'
+ )
+})
+
+test('supports