diff --git a/addons/docs/jest.config.js b/addons/docs/jest.config.js
new file mode 100644
index 000000000000..3303f51ba1b8
--- /dev/null
+++ b/addons/docs/jest.config.js
@@ -0,0 +1,9 @@
+module.exports = {
+ testEnvironment: 'node',
+ transform: {
+ '^.+\\.stories\\.[jt]sx?$': '@storybook/addon-storyshots/injectFileName',
+ '^.+\\.[jt]sx?$': '../../scripts/babel-jest.js',
+ '^.+\\.mdx$': '@storybook/addon-docs/jest-transform-mdx',
+ '^.+\\.vue$': 'vue-jest'
+ }
+};
diff --git a/addons/docs/package.json b/addons/docs/package.json
index 3347b56b8368..ee3c611349fc 100644
--- a/addons/docs/package.json
+++ b/addons/docs/package.json
@@ -87,9 +87,12 @@
"cross-spawn": "^7.0.1",
"jest-specific-snapshot": "^2.0.0",
"lit-html": "^1.0.0",
+ "memory-fs": "^0.5.0",
"require-from-string": "^2.0.2",
"styled-components": "^5.0.1",
"tmp": "^0.1.0",
+ "vue-jest": "^3.0.5",
+ "vue-loader": "^15.9.0",
"web-component-analyzer": "^1.0.3"
},
"peerDependencies": {
diff --git a/addons/docs/src/frameworks/vue/__testfixtures__/sfc-component/input.vue b/addons/docs/src/frameworks/vue/__testfixtures__/sfc-component/input.vue
new file mode 100644
index 000000000000..595bf4017589
--- /dev/null
+++ b/addons/docs/src/frameworks/vue/__testfixtures__/sfc-component/input.vue
@@ -0,0 +1,70 @@
+
+
+
+
+
+
+
diff --git a/addons/docs/src/frameworks/vue/vue-properties.test.ts b/addons/docs/src/frameworks/vue/vue-properties.test.ts
new file mode 100644
index 000000000000..9d1c9c66868e
--- /dev/null
+++ b/addons/docs/src/frameworks/vue/vue-properties.test.ts
@@ -0,0 +1,110 @@
+import 'jest-specific-snapshot';
+import path from 'path';
+import fs from 'fs';
+import Memoryfs from 'memory-fs';
+import VueLoaderPlugin from 'vue-loader/lib/plugin';
+import webpack from 'webpack';
+
+import { transformFileSync, transformSync } from '@babel/core';
+import requireFromString from 'require-from-string';
+
+import { extractProps } from './extractProps';
+
+// File hierarchy:
+// __testfixtures__ / some-test-case / input.*
+const inputRegExp = /^input\..*$/;
+
+const transformToModule = (inputCode: string) => {
+ const options = {
+ presets: [
+ [
+ '@babel/preset-env',
+ {
+ targets: {
+ esmodules: true,
+ },
+ },
+ ],
+ ],
+ };
+ const { code } = transformSync(inputCode, options);
+ return normalizeNewlines(code);
+};
+
+const annotateWithDocgen = (inputPath: string) => {
+ const options = {};
+ const compiler = webpack({
+ context: __dirname,
+ entry: inputPath,
+ output: {
+ path: path.resolve(__dirname),
+ filename: 'bundle.js',
+ },
+ module: {
+ rules: [
+ {
+ test: /\.vue$/,
+ use: [{ loader: 'vue-loader' }],
+ },
+ {
+ test: /\.vue$/,
+ enforce: 'post',
+ loader: 'vue-docgen-loader',
+ options,
+ },
+ {
+ test: /\.vue.js$/,
+ enforce: 'post',
+ loader: 'vue-docgen-loader',
+ options,
+ },
+ ],
+ },
+ plugins: [new VueLoaderPlugin()],
+ });
+
+ compiler.outputFileSystem = new Memoryfs();
+
+ return new Promise((resolve, reject) => {
+ compiler.run((err, stats) => {
+ if (err) {
+ return reject(err);
+ }
+
+ if (stats.hasErrors()) {
+ return reject(new Error(stats.toJson().errors.join(',')));
+ }
+
+ return resolve(stats);
+ });
+ });
+};
+
+const normalizeNewlines = (string: string) => string.replace(/\\r\\n/g, '\\n');
+
+describe('react component properties', () => {
+ const fixturesDir = path.join(__dirname, '__testfixtures__');
+ fs.readdirSync(fixturesDir, { withFileTypes: true }).forEach(testEntry => {
+ if (testEntry.isDirectory()) {
+ const testDir = path.join(fixturesDir, testEntry.name);
+ const testFile = fs.readdirSync(testDir).find(fileName => inputRegExp.test(fileName));
+ if (testFile) {
+ it(testEntry.name, async () => {
+ const inputPath = path.join(testDir, testFile);
+
+ // snapshot the output of babel-plugin-react-docgen
+ const docgenPretty = (await annotateWithDocgen(inputPath)) as string;
+ expect(docgenPretty).toMatchSpecificSnapshot(path.join(testDir, 'docgen.snapshot'));
+
+ // transform into an uglier format that's works with require-from-string
+ const docgenModule = transformToModule(docgenPretty);
+
+ // snapshot the output of component-properties/react
+ const { component } = requireFromString(docgenModule);
+ const properties = extractProps(component);
+ expect(properties).toMatchSpecificSnapshot(path.join(testDir, 'properties.snapshot'));
+ });
+ }
+ }
+ });
+});
diff --git a/addons/docs/src/typings.d.ts b/addons/docs/src/typings.d.ts
index 4a41c83bba2e..be2af1e45b1f 100644
--- a/addons/docs/src/typings.d.ts
+++ b/addons/docs/src/typings.d.ts
@@ -8,6 +8,8 @@ declare module 'remark-slug';
declare module 'remark-external-links';
declare module 'babel-plugin-react-docgen';
declare module 'require-from-string';
+declare module 'memory-fs';
+declare module 'vue-loader/lib/plugin';
declare module 'tmp';
declare module 'cross-spawn';
declare module 'styled-components';
diff --git a/yarn.lock b/yarn.lock
index 6a07d64d0452..15d3506c8fef 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -4288,6 +4288,16 @@
resolved "https://registry.yarnpkg.com/@types/stack-utils/-/stack-utils-1.0.1.tgz#0a851d3bd96498fa25c33ab7278ed3bd65f06c3e"
integrity sha512-l42BggppR6zLmpfU6fq9HEa2oGPEI8yrSPL3GITjfRInppYFahObbIQOQK3UGxEnyQpltZLaPe75046NOZQikw==
+"@types/strip-bom@^3.0.0":
+ version "3.0.0"
+ resolved "https://registry.yarnpkg.com/@types/strip-bom/-/strip-bom-3.0.0.tgz#14a8ec3956c2e81edb7520790aecf21c290aebd2"
+ integrity sha1-FKjsOVbC6B7bdSB5CuzyHCkK69I=
+
+"@types/strip-json-comments@0.0.30":
+ version "0.0.30"
+ resolved "https://registry.yarnpkg.com/@types/strip-json-comments/-/strip-json-comments-0.0.30.tgz#9aa30c04db212a9a0649d6ae6fd50accc40748a1"
+ integrity sha512-7NQmHra/JILCd1QqpSzl8+mJRc8ZHz3uDm8YV1Ks9IhK0epEiTw8aIErbvH9PI+6XbqhyIQy3462nEsn7UVzjQ==
+
"@types/symlink-or-copy@^1.2.0":
version "1.2.0"
resolved "https://registry.yarnpkg.com/@types/symlink-or-copy/-/symlink-or-copy-1.2.0.tgz#4151a81b4052c80bc2becbae09f3a9ec010a9c7a"
@@ -6405,7 +6415,7 @@ babel-plugin-transform-es2015-modules-amd@^6.22.0, babel-plugin-transform-es2015
babel-runtime "^6.22.0"
babel-template "^6.24.1"
-babel-plugin-transform-es2015-modules-commonjs@^6.23.0, babel-plugin-transform-es2015-modules-commonjs@^6.24.1:
+babel-plugin-transform-es2015-modules-commonjs@^6.23.0, babel-plugin-transform-es2015-modules-commonjs@^6.24.1, babel-plugin-transform-es2015-modules-commonjs@^6.26.0:
version "6.26.2"
resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-modules-commonjs/-/babel-plugin-transform-es2015-modules-commonjs-6.26.2.tgz#58a793863a9e7ca870bdc5a881117ffac27db6f3"
integrity sha512-CV9ROOHEdrjcwhIaJNBGMBCodN+1cfkwtM1SbUHmvyy35KGT7fohbpOxkE2uLz1o6odKK2Ck/tz47z+VqQfi9Q==
@@ -8900,16 +8910,16 @@ clone-response@1.0.2, clone-response@^1.0.2:
dependencies:
mimic-response "^1.0.0"
+clone@2.x, clone@^2.0.0, clone@^2.1.1, clone@^2.1.2:
+ version "2.1.2"
+ resolved "https://registry.yarnpkg.com/clone/-/clone-2.1.2.tgz#1b7f4b9f591f1e8f83670401600345a02887435f"
+ integrity sha1-G39Ln1kfHo+DZwQBYANFoCiHQ18=
+
clone@^1.0.1, clone@^1.0.2:
version "1.0.4"
resolved "https://registry.yarnpkg.com/clone/-/clone-1.0.4.tgz#da309cc263df15994c688ca902179ca3c7cd7c7e"
integrity sha1-2jCcwmPfFZlMaIypAheco8fNfH4=
-clone@^2.0.0, clone@^2.1.1, clone@^2.1.2:
- version "2.1.2"
- resolved "https://registry.yarnpkg.com/clone/-/clone-2.1.2.tgz#1b7f4b9f591f1e8f83670401600345a02887435f"
- integrity sha1-G39Ln1kfHo+DZwQBYANFoCiHQ18=
-
closest-file-data@^0.1.4:
version "0.1.4"
resolved "https://registry.yarnpkg.com/closest-file-data/-/closest-file-data-0.1.4.tgz#975f87c132f299d24a0375b9f63ca3fb88f72b3a"
@@ -9270,7 +9280,7 @@ concurrently@^5.0.2, concurrently@^5.1.0:
tree-kill "^1.2.2"
yargs "^13.3.0"
-config-chain@^1.1.11:
+config-chain@^1.1.11, config-chain@^1.1.12:
version "1.1.12"
resolved "https://registry.yarnpkg.com/config-chain/-/config-chain-1.1.12.tgz#0fde8d091200eb5e808caf25fe618c02f48e4efa"
integrity sha512-a1eOIcu8+7lUInge4Rpf/n4Krkf3Dd9lqhljRzII1/Zno/kRtUWnznPO3jOKBmTEktkt3fkxisUcivoj0ebzoA==
@@ -10035,7 +10045,7 @@ css-what@^3.2.1:
resolved "https://registry.yarnpkg.com/css-what/-/css-what-3.2.1.tgz#f4a8f12421064621b456755e34a03a2c22df5da1"
integrity sha512-WwOrosiQTvyms+Ti5ZC5vGEK0Vod3FTt1ca+payZqvKuGJF+dq7bG63DstxtN0dpm6FxY27a/zS3Wten+gEtGw==
-css@^2.0.0, css@^2.2.1, css@^2.2.4:
+css@^2.0.0, css@^2.1.0, css@^2.2.1, css@^2.2.4:
version "2.2.4"
resolved "https://registry.yarnpkg.com/css/-/css-2.2.4.tgz#c646755c73971f2bba6a601e2cf2fd71b1298929"
integrity sha512-oUnjmWpy0niI3x/mPL8dVEI1l7MnG3+HHyRPHf+YFSbK+svOhXpmSOcDURUh2aOCgl2grzrOPt1nHLuCVFULLw==
@@ -11170,6 +11180,16 @@ editions@^1.1.1:
resolved "https://registry.yarnpkg.com/editions/-/editions-1.3.4.tgz#3662cb592347c3168eb8e498a0ff73271d67f50b"
integrity sha512-gzao+mxnYDzIysXKMQi/+M1mjy/rjestjg6OPoYTtI+3Izp23oiGZitsl9lPDPiTGXbcSIk1iJWhliSaglxnUg==
+editorconfig@^0.15.3:
+ version "0.15.3"
+ resolved "https://registry.yarnpkg.com/editorconfig/-/editorconfig-0.15.3.tgz#bef84c4e75fb8dcb0ce5cee8efd51c15999befc5"
+ integrity sha512-M9wIMFx96vq0R4F+gRpY3o2exzb8hEj/n9S8unZtHSvYjibBp/iMufSzvmOcV/laG0ZtuTVGtiJggPOSW2r93g==
+ dependencies:
+ commander "^2.19.0"
+ lru-cache "^4.1.5"
+ semver "^5.6.0"
+ sigmund "^1.0.1"
+
ee-first@1.1.1:
version "1.1.1"
resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d"
@@ -13017,6 +13037,13 @@ extglob@^2.0.4:
snapdragon "^0.8.1"
to-regex "^3.0.1"
+extract-from-css@^0.4.4:
+ version "0.4.4"
+ resolved "https://registry.yarnpkg.com/extract-from-css/-/extract-from-css-0.4.4.tgz#1ea7df2e7c7c6eb9922fa08e8adaea486f6f8f92"
+ integrity sha1-HqffLnx8brmSL6COitrqSG9vj5I=
+ dependencies:
+ css "^2.1.0"
+
extract-zip@1.6.7, extract-zip@^1.6.6:
version "1.6.7"
resolved "https://registry.yarnpkg.com/extract-zip/-/extract-zip-1.6.7.tgz#a840b4b8af6403264c8db57f4f1a74333ef81fe9"
@@ -17758,6 +17785,17 @@ js-base64@^2.1.8:
resolved "https://registry.yarnpkg.com/js-base64/-/js-base64-2.5.1.tgz#1efa39ef2c5f7980bb1784ade4a8af2de3291121"
integrity sha512-M7kLczedRMYX4L8Mdh4MzyAMM9O5osx+4FcOQuTvr3A9F2D9S5JXheN0ewNbrvK2UatkTRhL5ejGmGSjNMiZuw==
+js-beautify@^1.6.14:
+ version "1.10.3"
+ resolved "https://registry.yarnpkg.com/js-beautify/-/js-beautify-1.10.3.tgz#c73fa10cf69d3dfa52d8ed624f23c64c0a6a94c1"
+ integrity sha512-wfk/IAWobz1TfApSdivH5PJ0miIHgDoYb1ugSqHcODPmaYu46rYe5FVuIEkhjg8IQiv6rDNPyhsqbsohI/C2vQ==
+ dependencies:
+ config-chain "^1.1.12"
+ editorconfig "^0.15.3"
+ glob "^7.1.3"
+ mkdirp "~0.5.1"
+ nopt "~4.0.1"
+
js-levenshtein@^1.1.3:
version "1.1.6"
resolved "https://registry.yarnpkg.com/js-levenshtein/-/js-levenshtein-1.1.6.tgz#c6cee58eb3550372df8deb85fad5ce66ce01d59d"
@@ -20704,6 +20742,14 @@ node-ask@^1.0.1:
resolved "https://registry.yarnpkg.com/node-ask/-/node-ask-1.0.1.tgz#caaa1076cc58e0364267a0903e3eadfac158396b"
integrity sha1-yqoQdsxY4DZCZ6CQPj6t+sFYOWs=
+node-cache@^4.1.1:
+ version "4.2.1"
+ resolved "https://registry.yarnpkg.com/node-cache/-/node-cache-4.2.1.tgz#efd8474dee4edec4138cdded580f5516500f7334"
+ integrity sha512-BOb67bWg2dTyax5kdef5WfU3X8xu4wPg+zHzkvls0Q/QpYycIFRLEEIdAx9Wma43DxG6Qzn4illdZoYseKWa4A==
+ dependencies:
+ clone "2.x"
+ lodash "^4.17.15"
+
node-cleanup@^2.1.2:
version "2.1.2"
resolved "https://registry.yarnpkg.com/node-cleanup/-/node-cleanup-2.1.2.tgz#7ac19abd297e09a7f72a71545d951b517e4dde2c"
@@ -20938,7 +20984,7 @@ nodemon@^2.0.2:
dependencies:
abbrev "1"
-nopt@^4.0.1:
+nopt@^4.0.1, nopt@~4.0.1:
version "4.0.1"
resolved "https://registry.yarnpkg.com/nopt/-/nopt-4.0.1.tgz#d0d4685afd5415193c8c7505602d0d17cd64474d"
integrity sha1-0NRoWv1UFRk8jHUFYC0NF81kR00=
@@ -26898,6 +26944,11 @@ side-channel@^1.0.2:
es-abstract "^1.17.0-next.1"
object-inspect "^1.7.0"
+sigmund@^1.0.1:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/sigmund/-/sigmund-1.0.1.tgz#3ff21f198cad2175f9f3b781853fd94d0d19b590"
+ integrity sha1-P/IfGYytIXX587eBhT/ZTQ0ZtZA=
+
signal-exit@^3.0.0, signal-exit@^3.0.2:
version "3.0.2"
resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.2.tgz#b5fdc08f1287ea1178628e415e25132b73646c6d"
@@ -27991,7 +28042,7 @@ strip-indent@^3.0.0:
dependencies:
min-indent "^1.0.0"
-strip-json-comments@^2.0.1, strip-json-comments@~2.0.1:
+strip-json-comments@^2.0.0, strip-json-comments@^2.0.1, strip-json-comments@~2.0.1:
version "2.0.1"
resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a"
integrity sha1-PFMZQukIwml8DsNEhYwobHygpgo=
@@ -29140,6 +29191,16 @@ tsconfig-paths@^3.4.0:
minimist "^1.2.0"
strip-bom "^3.0.0"
+tsconfig@^7.0.0:
+ version "7.0.0"
+ resolved "https://registry.yarnpkg.com/tsconfig/-/tsconfig-7.0.0.tgz#84538875a4dc216e5c4a5432b3a4dec3d54e91b7"
+ integrity sha512-vZXmzPrL+EmC4T/4rVlT2jNVMWCi/O4DIiSj3UHg1OE5kCKbk4mfrXc6dZksLgRM/TZlKnousKH9bbTazUWRRw==
+ dependencies:
+ "@types/strip-bom" "^3.0.0"
+ "@types/strip-json-comments" "0.0.30"
+ strip-bom "^3.0.0"
+ strip-json-comments "^2.0.0"
+
tslib@1.10.0, tslib@^1.10.0, tslib@^1.7.1, tslib@^1.8.1, tslib@^1.9.0, tslib@^1.9.3:
version "1.10.0"
resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.10.0.tgz#c3c19f95973fb0a62973fb09d90d961ee43e5c8a"
@@ -30292,6 +30353,22 @@ vue-hot-reload-api@^2.3.0:
resolved "https://registry.yarnpkg.com/vue-hot-reload-api/-/vue-hot-reload-api-2.3.4.tgz#532955cc1eb208a3d990b3a9f9a70574657e08f2"
integrity sha512-BXq3jwIagosjgNVae6tkHzzIk6a8MHFtzAdwhnV5VlvPTFxDCvIttgSiHWjdGoTJvXtmRu5HacExfdarRcFhog==
+vue-jest@^3.0.5:
+ version "3.0.5"
+ resolved "https://registry.yarnpkg.com/vue-jest/-/vue-jest-3.0.5.tgz#d6f124b542dcbff207bf9296c19413f4c40b70c9"
+ integrity sha512-xWDxde91pDqYBGDlODENZ3ezPgw+IQFoVDtf+5Awlg466w3KvMSqWzs8PxcTeTr+wmAHi0j+a+Lm3R7aUJa1jA==
+ dependencies:
+ babel-plugin-transform-es2015-modules-commonjs "^6.26.0"
+ chalk "^2.1.0"
+ extract-from-css "^0.4.4"
+ find-babel-config "^1.1.0"
+ js-beautify "^1.6.14"
+ node-cache "^4.1.1"
+ object-assign "^4.1.1"
+ source-map "^0.5.6"
+ tsconfig "^7.0.0"
+ vue-template-es2015-compiler "^1.6.0"
+
vue-loader@^15.7.0:
version "15.8.3"
resolved "https://registry.yarnpkg.com/vue-loader/-/vue-loader-15.8.3.tgz#857cb9e30eb5fc25e66db48dce7e4f768602a23c"
@@ -30303,6 +30380,17 @@ vue-loader@^15.7.0:
vue-hot-reload-api "^2.3.0"
vue-style-loader "^4.1.0"
+vue-loader@^15.9.0:
+ version "15.9.0"
+ resolved "https://registry.yarnpkg.com/vue-loader/-/vue-loader-15.9.0.tgz#5d4b0378a4606188fc83e587ed23c94bc3a10998"
+ integrity sha512-FeDHvTSpwyLeF7LIV1PYkvqUQgTJ8UmOxhSlCyRSxaXCKk+M6NF4tDQsLsPPNeDPyR7TfRQ8MLg6v+8PsDV9xQ==
+ dependencies:
+ "@vue/component-compiler-utils" "^3.1.0"
+ hash-sum "^1.0.2"
+ loader-utils "^1.1.0"
+ vue-hot-reload-api "^2.3.0"
+ vue-style-loader "^4.1.0"
+
vue-property-decorator@8.3.0:
version "8.3.0"
resolved "https://registry.yarnpkg.com/vue-property-decorator/-/vue-property-decorator-8.3.0.tgz#536f027dc7d626f37c8d85a2dc02f0a6cb979440"
@@ -30326,7 +30414,7 @@ vue-template-compiler@^2.0.0, vue-template-compiler@^2.6.8:
de-indent "^1.0.2"
he "^1.1.0"
-vue-template-es2015-compiler@^1.9.0:
+vue-template-es2015-compiler@^1.6.0, vue-template-es2015-compiler@^1.9.0:
version "1.9.1"
resolved "https://registry.yarnpkg.com/vue-template-es2015-compiler/-/vue-template-es2015-compiler-1.9.1.tgz#1ee3bc9a16ecbf5118be334bb15f9c46f82f5825"
integrity sha512-4gDntzrifFnCEvyoO8PqyJDmguXgVPxKiIxrBKjIowvL9l+N66196+72XVYR8BBf1Uv1Fgt3bGevJ+sEmxfZzw==