From 3e1cdba9db04062a796af79b1b1f40f6bdb51d27 Mon Sep 17 00:00:00 2001 From: Evan You Date: Wed, 8 Jul 2020 21:11:57 -0400 Subject: [PATCH] wip: tests for compileScriptSetup --- .../src/transforms/transformExpression.ts | 6 +- .../__snapshots__/compileScript.spec.ts.snap | 248 ++++++++++++ .../__tests__/compileScript.spec.ts | 366 ++++++++++++++++++ packages/compiler-sfc/src/compileScript.ts | 94 +++-- packages/compiler-sfc/src/index.ts | 1 + packages/shared/src/index.ts | 2 +- 6 files changed, 668 insertions(+), 49 deletions(-) create mode 100644 packages/compiler-sfc/__tests__/__snapshots__/compileScript.spec.ts.snap create mode 100644 packages/compiler-sfc/__tests__/compileScript.spec.ts diff --git a/packages/compiler-core/src/transforms/transformExpression.ts b/packages/compiler-core/src/transforms/transformExpression.ts index 97e8fece..1e223067 100644 --- a/packages/compiler-core/src/transforms/transformExpression.ts +++ b/packages/compiler-core/src/transforms/transformExpression.ts @@ -30,7 +30,6 @@ import { import { createCompilerError, ErrorCodes } from '../errors' import { Node, Function, Identifier, ObjectProperty } from '@babel/types' import { validateBrowserExpression } from '../validateExpression' -import { ParserPlugin } from '@babel/parser' const isLiteralWhitelisted = /*#__PURE__*/ makeMap('true,false,null,this') @@ -130,10 +129,7 @@ export function processExpression( : `(${rawExp})${asParams ? `=>{}` : ``}` try { ast = parseJS(source, { - plugins: [ - ...context.expressionPlugins, - ...(babelParserDefautPlugins as ParserPlugin[]) - ] + plugins: [...context.expressionPlugins, ...babelParserDefautPlugins] }).program } catch (e) { context.onError( diff --git a/packages/compiler-sfc/__tests__/__snapshots__/compileScript.spec.ts.snap b/packages/compiler-sfc/__tests__/__snapshots__/compileScript.spec.ts.snap new file mode 100644 index 00000000..cf681ef1 --- /dev/null +++ b/packages/compiler-sfc/__tests__/__snapshots__/compileScript.spec.ts.snap @@ -0,0 +1,248 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`SFC compile `).code) + }) + + test('explicit setup signature', () => { + assertCode( + compile(``).code + ) + }) + + test('import dedupe between + + `).code + assertCode(code) + expect(code.indexOf(`import { x }`)).toEqual( + code.lastIndexOf(`import { x }`) + ) + }) + + describe('exports', () => { + test('export const x = ...', () => { + const { code, bindings } = compile( + `` + ) + assertCode(code) + expect(bindings).toStrictEqual({ + x: 'setup' + }) + }) + + test('export const { x } = ... (destructuring)', () => { + const { code, bindings } = compile(``) + assertCode(code) + expect(bindings).toStrictEqual({ + a: 'setup', + b: 'setup', + c: 'setup', + d: 'setup', + e: 'setup', + f: 'setup' + }) + }) + + test('export function x() {}', () => { + const { code, bindings } = compile( + `` + ) + assertCode(code) + expect(bindings).toStrictEqual({ + x: 'setup' + }) + }) + + test('export class X() {}', () => { + const { code, bindings } = compile( + `` + ) + assertCode(code) + expect(bindings).toStrictEqual({ + X: 'setup' + }) + }) + + test('export { x }', () => { + const { code, bindings } = compile( + `` + ) + assertCode(code) + expect(bindings).toStrictEqual({ + x: 'setup', + y: 'setup' + }) + }) + + test(`export { x } from './x'`, () => { + const { code, bindings } = compile( + `` + ) + assertCode(code) + expect(bindings).toStrictEqual({ + x: 'setup', + y: 'setup' + }) + }) + + test(`export default from './x'`, () => { + const { code, bindings } = compile( + ``, + { + parserPlugins: ['exportDefaultFrom'] + } + ) + assertCode(code) + expect(bindings).toStrictEqual({}) + }) + + test(`export { x as default }`, () => { + const { code, bindings } = compile( + `` + ) + assertCode(code) + expect(bindings).toStrictEqual({ + y: 'setup' + }) + }) + + test(`export { x as default } from './x'`, () => { + const { code, bindings } = compile( + `` + ) + assertCode(code) + expect(bindings).toStrictEqual({ + y: 'setup' + }) + }) + + test(`export * from './x'`, () => { + const { code, bindings } = compile( + `` + ) + assertCode(code) + expect(bindings).toStrictEqual({ + y: 'setup' + // in this case we cannot extract bindings from ./x so it falls back + // to runtime proxy dispatching + }) + }) + + test('export default in ` + ) + assertCode(code) + expect(bindings).toStrictEqual({ + y: 'setup' + }) + }) + }) + + describe('`) + assertCode(code) + expect(bindings).toStrictEqual({ a: 'setup' }) + }) + + test('extract props', () => {}) + + test('extract emits', () => {}) + }) + + describe('errors', () => { + test('must have `)).toThrow( + `SFC has no `) + ).toThrow(``) + ).toThrow(`Cannot export locally defined variable as default`) + }) + + test('export default referencing local var', () => { + expect(() => + compile(``) + ).toThrow(`cannot reference locally declared variables`) + }) + + test('export default referencing exports', () => { + expect(() => + compile(``) + ).toThrow(`cannot reference locally declared variables`) + }) + + test('should allow export default referencing scope var', () => { + assertCode( + compile(``).code + ) + }) + + test('should allow export default referencing imported binding', () => { + assertCode( + compile(``).code + ) + }) + + test('should allow export default referencing re-exported binding', () => { + assertCode( + compile(``).code + ) + }) + + test('error on duplicated defalut export', () => { + expect(() => + compile(` + + + `) + ).toThrow(`Default export is already declared`) + + expect(() => + compile(` + + + `) + ).toThrow(`Default export is already declared`) + + expect(() => + compile(` + + + `) + ).toThrow(`Default export is already declared`) + + expect(() => + compile(` + + + `) + ).toThrow(`Default export is already declared`) + + expect(() => + compile(` + + + `) + ).toThrow(`Default export is already declared`) + }) + }) +}) diff --git a/packages/compiler-sfc/src/compileScript.ts b/packages/compiler-sfc/src/compileScript.ts index bc789e25..aabf4b3a 100644 --- a/packages/compiler-sfc/src/compileScript.ts +++ b/packages/compiler-sfc/src/compileScript.ts @@ -51,7 +51,21 @@ export function compileScriptSetup( const setupExports: Record = {} let exportAllIndex = 0 let defaultExport: Node | undefined - let needDefaultExportCheck: boolean = false + let needDefaultExportRefCheck: boolean = false + + const checkDuplicateDefaultExport = (node: Node) => { + if (defaultExport) { + //