From e3b21b25b1fdd57aa1e44a15255ff60db0e36151 Mon Sep 17 00:00:00 2001 From: Rizumu Ayaka Date: Sat, 9 Dec 2023 03:29:38 +0800 Subject: [PATCH] test: split test files (#38) --- ...pile.test.ts.snap => compile.spec.ts.snap} | 218 --------- .../compiler-vapor/__tests__/compile.spec.ts | 210 +++++++++ .../compiler-vapor/__tests__/compile.test.ts | 434 ------------------ .../__snapshots__/vBind.spec.ts.snap | 81 ++++ .../__snapshots__/vHtml.spec.ts.snap | 41 ++ .../transforms/__snapshots__/vOn.spec.ts.snap | 46 ++ .../__snapshots__/vOnce.spec.ts.snap | 28 ++ .../__snapshots__/vText.spec.ts.snap | 27 ++ .../transforms/transformElement.spec.ts | 2 + .../transforms/transformInterpolation.spec.ts | 2 + .../__tests__/transforms/vBind.spec.ts | 88 ++++ .../__tests__/transforms/vHtml.spec.ts | 44 ++ .../__tests__/transforms/vOn.spec.ts | 73 +++ .../__tests__/transforms/vOnce.spec.ts | 35 ++ .../__tests__/transforms/vText.spec.ts | 31 ++ 15 files changed, 708 insertions(+), 652 deletions(-) rename packages/compiler-vapor/__tests__/__snapshots__/{compile.test.ts.snap => compile.spec.ts.snap} (50%) create mode 100644 packages/compiler-vapor/__tests__/compile.spec.ts delete mode 100644 packages/compiler-vapor/__tests__/compile.test.ts create mode 100644 packages/compiler-vapor/__tests__/transforms/__snapshots__/vBind.spec.ts.snap create mode 100644 packages/compiler-vapor/__tests__/transforms/__snapshots__/vHtml.spec.ts.snap create mode 100644 packages/compiler-vapor/__tests__/transforms/__snapshots__/vOn.spec.ts.snap create mode 100644 packages/compiler-vapor/__tests__/transforms/__snapshots__/vOnce.spec.ts.snap create mode 100644 packages/compiler-vapor/__tests__/transforms/__snapshots__/vText.spec.ts.snap create mode 100644 packages/compiler-vapor/__tests__/transforms/transformElement.spec.ts create mode 100644 packages/compiler-vapor/__tests__/transforms/transformInterpolation.spec.ts create mode 100644 packages/compiler-vapor/__tests__/transforms/vBind.spec.ts create mode 100644 packages/compiler-vapor/__tests__/transforms/vHtml.spec.ts create mode 100644 packages/compiler-vapor/__tests__/transforms/vOn.spec.ts create mode 100644 packages/compiler-vapor/__tests__/transforms/vOnce.spec.ts create mode 100644 packages/compiler-vapor/__tests__/transforms/vText.spec.ts diff --git a/packages/compiler-vapor/__tests__/__snapshots__/compile.test.ts.snap b/packages/compiler-vapor/__tests__/__snapshots__/compile.spec.ts.snap similarity index 50% rename from packages/compiler-vapor/__tests__/__snapshots__/compile.test.ts.snap rename to packages/compiler-vapor/__tests__/__snapshots__/compile.spec.ts.snap index 5e3b020fa..02c09554e 100644 --- a/packages/compiler-vapor/__tests__/__snapshots__/compile.test.ts.snap +++ b/packages/compiler-vapor/__tests__/__snapshots__/compile.spec.ts.snap @@ -100,86 +100,6 @@ export function render(_ctx) { }" `; -exports[`compile > directives > v-bind > .camel modifier 1`] = ` -"import { template as _template, children as _children, effect as _effect, setAttr as _setAttr } from 'vue/vapor'; - -export function render(_ctx) { - const t0 = _template("
") - const n0 = t0() - const { 0: [n1],} = _children(n0) - _effect(() => { - _setAttr(n1, "foo-bar", undefined, _ctx.id) - }) - return n0 -}" -`; - -exports[`compile > directives > v-bind > dynamic arg 1`] = ` -"import { template as _template, children as _children, effect as _effect, setAttr as _setAttr } from 'vue/vapor'; - -export function render(_ctx) { - const t0 = _template("
") - const n0 = t0() - const { 0: [n1],} = _children(n0) - _effect(() => { - _setAttr(n1, _ctx.id, undefined, _ctx.id) - }) - return n0 -}" -`; - -exports[`compile > directives > v-bind > no expression (shorthand) 1`] = ` -"import { template as _template, children as _children, effect as _effect, setAttr as _setAttr } from 'vue/vapor'; - -export function render(_ctx) { - const t0 = _template("
") - const n0 = t0() - const { 0: [n1],} = _children(n0) - _effect(() => { - _setAttr(n1, "camel-case", undefined, _ctx.camelCase) - }) - return n0 -}" -`; - -exports[`compile > directives > v-bind > no expression 1`] = ` -"import { template as _template, children as _children, effect as _effect, setAttr as _setAttr } from 'vue/vapor'; - -export function render(_ctx) { - const t0 = _template("
") - const n0 = t0() - const { 0: [n1],} = _children(n0) - _effect(() => { - _setAttr(n1, "id", undefined, _ctx.id) - }) - return n0 -}" -`; - -exports[`compile > directives > v-bind > should error if no expression 1`] = ` -"import { template as _template } from 'vue/vapor'; - -export function render(_ctx) { - const t0 = _template("
") - const n0 = t0() - return n0 -}" -`; - -exports[`compile > directives > v-bind > simple expression 1`] = ` -"import { template as _template, children as _children, effect as _effect, setAttr as _setAttr } from 'vue/vapor'; - -export function render(_ctx) { - const t0 = _template("
") - const n0 = t0() - const { 0: [n1],} = _children(n0) - _effect(() => { - _setAttr(n1, "id", undefined, _ctx.id) - }) - return n0 -}" -`; - exports[`compile > directives > v-cloak > basic 1`] = ` "import { template as _template } from 'vue/vapor'; @@ -190,118 +110,6 @@ export function render(_ctx) { }" `; -exports[`compile > directives > v-html > should raise error and ignore children when v-html is present 1`] = ` -"import { template as _template, children as _children, effect as _effect, setHtml as _setHtml } from 'vue/vapor'; - -export function render(_ctx) { - const t0 = _template("
") - const n0 = t0() - const { 0: [n1],} = _children(n0) - _effect(() => { - _setHtml(n1, undefined, _ctx.test) - }) - return n0 -}" -`; - -exports[`compile > directives > v-html > should raise error if has no expression 1`] = ` -"import { template as _template, children as _children, setHtml as _setHtml } from 'vue/vapor'; - -export function render(_ctx) { - const t0 = _template("
") - const n0 = t0() - const { 0: [n1],} = _children(n0) - _setHtml(n1, undefined, "") - return n0 -}" -`; - -exports[`compile > directives > v-html > simple expression 1`] = ` -"import { template as _template, children as _children, effect as _effect, setHtml as _setHtml } from 'vue/vapor'; - -export function render(_ctx) { - const t0 = _template("
") - const n0 = t0() - const { 0: [n1],} = _children(n0) - _effect(() => { - _setHtml(n1, undefined, _ctx.code) - }) - return n0 -}" -`; - -exports[`compile > directives > v-on > event modifier 1`] = ` -"import { template as _template, children as _children, on as _on, withModifiers as _withModifiers, withKeys as _withKeys } from 'vue/vapor'; - -export function render(_ctx) { - const t0 = _template("
") - const n0 = t0() - const { 0: [n1], 1: [n2], 2: [n3], 3: [n4], 4: [n5], 5: [n6], 6: [n7], 7: [n8], 8: [n9], 9: [n10], 10: [n11], 11: [n12], 12: [n13], 13: [n14], 14: [n15], 15: [n16], 16: [n17], 17: [n18], 18: [n19], 19: [n20], 20: [n21], 21: [n22],} = _children(n0) - _on(n1, "click", _withModifiers((...args) => (_ctx.handleEvent && _ctx.handleEvent(...args)), ["stop"])) - _on(n2, "submit", _withModifiers((...args) => (_ctx.handleEvent && _ctx.handleEvent(...args)), ["prevent"])) - _on(n3, "click", _withModifiers((...args) => (_ctx.handleEvent && _ctx.handleEvent(...args)), ["stop", "prevent"])) - _on(n4, "click", _withModifiers((...args) => (_ctx.handleEvent && _ctx.handleEvent(...args)), ["self"])) - _on(n5, "click", (...args) => (_ctx.handleEvent && _ctx.handleEvent(...args)), { capture: true }) - _on(n6, "click", (...args) => (_ctx.handleEvent && _ctx.handleEvent(...args)), { once: true }) - _on(n7, "scroll", (...args) => (_ctx.handleEvent && _ctx.handleEvent(...args)), { passive: true }) - _on(n8, "contextmenu", _withModifiers((...args) => (_ctx.handleEvent && _ctx.handleEvent(...args)), ["right"])) - _on(n9, "click", _withModifiers((...args) => (_ctx.handleEvent && _ctx.handleEvent(...args)), ["left"])) - _on(n10, "mouseup", _withModifiers((...args) => (_ctx.handleEvent && _ctx.handleEvent(...args)), ["middle"])) - _on(n11, "contextmenu", _withModifiers((...args) => (_ctx.handleEvent && _ctx.handleEvent(...args)), ["right"])) - _on(n12, "keyup", _withKeys((...args) => (_ctx.handleEvent && _ctx.handleEvent(...args)), ["enter"])) - _on(n13, "keyup", _withKeys((...args) => (_ctx.handleEvent && _ctx.handleEvent(...args)), ["tab"])) - _on(n14, "keyup", _withKeys((...args) => (_ctx.handleEvent && _ctx.handleEvent(...args)), ["delete"])) - _on(n15, "keyup", _withKeys((...args) => (_ctx.handleEvent && _ctx.handleEvent(...args)), ["esc"])) - _on(n16, "keyup", _withKeys((...args) => (_ctx.handleEvent && _ctx.handleEvent(...args)), ["space"])) - _on(n17, "keyup", _withKeys((...args) => (_ctx.handleEvent && _ctx.handleEvent(...args)), ["up"])) - _on(n18, "keyup", _withKeys((...args) => (_ctx.handleEvent && _ctx.handleEvent(...args)), ["down"])) - _on(n19, "keyup", _withKeys((...args) => (_ctx.handleEvent && _ctx.handleEvent(...args)), ["left"])) - _on(n20, "keyup", _withModifiers((...args) => (_ctx.submit && _ctx.submit(...args)), ["middle"])) - _on(n21, "keyup", _withModifiers((...args) => (_ctx.submit && _ctx.submit(...args)), ["middle", "self"])) - _on(n22, "keyup", _withKeys(_withModifiers((...args) => (_ctx.handleEvent && _ctx.handleEvent(...args)), ["self"]), ["enter"])) - return n0 -}" -`; - -exports[`compile > directives > v-on > simple expression 1`] = ` -"import { template as _template, children as _children, on as _on } from 'vue/vapor'; - -export function render(_ctx) { - const t0 = _template("
") - const n0 = t0() - const { 0: [n1],} = _children(n0) - _on(n1, "click", (...args) => (_ctx.handleClick && _ctx.handleClick(...args))) - return n0 -}" -`; - -exports[`compile > directives > v-once > as root node 1`] = ` -"import { template as _template, children as _children, setAttr as _setAttr } from 'vue/vapor'; - -export function render(_ctx) { - const t0 = _template("
") - const n0 = t0() - const { 0: [n1],} = _children(n0) - _setAttr(n1, "id", undefined, _ctx.foo) - return n0 -}" -`; - -exports[`compile > directives > v-once > basic 1`] = ` -"import { template as _template, children as _children, createTextNode as _createTextNode, setText as _setText, setAttr as _setAttr, prepend as _prepend } from 'vue/vapor'; - -export function render(_ctx) { - const t0 = _template("
") - const n0 = t0() - const { 0: [n3, { 1: [n2],}],} = _children(n0) - const n1 = _createTextNode(_ctx.msg) - _setText(n1, undefined, _ctx.msg) - _setAttr(n2, "class", undefined, _ctx.clz) - _prepend(n3, n1) - return n0 -}" -`; - exports[`compile > directives > v-pre > basic 1`] = ` "import { template as _template } from 'vue/vapor'; @@ -350,32 +158,6 @@ export function render(_ctx) { }" `; -exports[`compile > directives > v-text > no expression 1`] = ` -"import { template as _template, children as _children, setText as _setText } from 'vue/vapor'; - -export function render(_ctx) { - const t0 = _template("
") - const n0 = t0() - const { 0: [n1],} = _children(n0) - _setText(n1, undefined, "") - return n0 -}" -`; - -exports[`compile > directives > v-text > simple expression 1`] = ` -"import { template as _template, children as _children, effect as _effect, setText as _setText } from 'vue/vapor'; - -export function render(_ctx) { - const t0 = _template("
") - const n0 = t0() - const { 0: [n1],} = _children(n0) - _effect(() => { - _setText(n1, undefined, _ctx.str) - }) - return n0 -}" -`; - exports[`compile > dynamic root 1`] = ` "import { fragment as _fragment, createTextNode as _createTextNode, append as _append, effect as _effect, setText as _setText } from 'vue/vapor'; diff --git a/packages/compiler-vapor/__tests__/compile.spec.ts b/packages/compiler-vapor/__tests__/compile.spec.ts new file mode 100644 index 000000000..3c7cf9562 --- /dev/null +++ b/packages/compiler-vapor/__tests__/compile.spec.ts @@ -0,0 +1,210 @@ +import { type RootNode, BindingTypes } from '@vue/compiler-dom' +import { type CompilerOptions, compile as _compile } from '../src' + +function compile(template: string | RootNode, options: CompilerOptions = {}) { + let { code } = _compile(template, { + ...options, + mode: 'module', + prefixIdentifiers: true, + }) + return code +} + +describe('compile', () => { + test('static template', () => { + const code = compile( + `
+

hello

+ + +
`, + ) + expect(code).matchSnapshot() + }) + + test('dynamic root', () => { + const code = compile(`{{ 1 }}{{ 2 }}`) + expect(code).matchSnapshot() + }) + + test('dynamic root nodes and interpolation', () => { + const code = compile( + ``, + ) + expect(code).matchSnapshot() + }) + + test('static + dynamic root', () => { + const code = compile( + `{{ 1 }}{{ 2 }}3{{ 4 }}{{ 5 }}6{{ 7 }}{{ 8 }}9{{ 'A' }}{{ 'B' }}`, + ) + expect(code).matchSnapshot() + }) + + test('fragment', () => { + const code = compile(`

`) + expect(code).matchSnapshot() + }) + + test('bindings', () => { + const code = compile(`
count is {{ count }}.
`, { + bindingMetadata: { + count: BindingTypes.SETUP_REF, + }, + }) + expect(code).matchSnapshot() + }) + + describe('directives', () => { + describe('v-pre', () => { + test('basic', () => { + const code = compile(`
{{ bar }}
\n`, { + bindingMetadata: { + foo: BindingTypes.SETUP_REF, + bar: BindingTypes.SETUP_REF, + }, + }) + + expect(code).toMatchSnapshot() + expect(code).contains( + JSON.stringify('
{{ bar }}
'), + ) + expect(code).not.contains('effect') + }) + + // TODO: support multiple root nodes and components + test('should not affect siblings after it', () => { + const code = compile( + `
{{ bar }}
\n` + + `
{{ bar }}
`, + { + bindingMetadata: { + foo: BindingTypes.SETUP_REF, + bar: BindingTypes.SETUP_REF, + }, + }, + ) + + expect(code).toMatchSnapshot() + // Waiting for TODO, There should be more here. + }) + + // TODO: support multiple root nodes and components + test('self-closing v-pre', () => { + const code = compile( + `
\n
{{ bar }}
`, + ) + + expect(code).toMatchSnapshot() + expect(code).contains('
') + // Waiting for TODO, There should be more here. + }) + }) + + describe('v-cloak', () => { + test('basic', () => { + const code = compile(`
test
`) + expect(code).toMatchSnapshot() + expect(code).not.contains('v-cloak') + }) + }) + + describe('custom directive', () => { + test('basic', () => { + const code = compile(`
`, { + bindingMetadata: { + vExample: BindingTypes.SETUP_CONST, + }, + }) + expect(code).matchSnapshot() + }) + + test('binding value', () => { + const code = compile(`
`, { + bindingMetadata: { + msg: BindingTypes.SETUP_REF, + vExample: BindingTypes.SETUP_CONST, + }, + }) + expect(code).matchSnapshot() + }) + + test('static parameters', () => { + const code = compile(`
`, { + bindingMetadata: { + msg: BindingTypes.SETUP_REF, + vExample: BindingTypes.SETUP_CONST, + }, + }) + expect(code).matchSnapshot() + }) + + test('modifiers', () => { + const code = compile(`
`, { + bindingMetadata: { + msg: BindingTypes.SETUP_REF, + vExample: BindingTypes.SETUP_CONST, + }, + }) + expect(code).matchSnapshot() + }) + + test('modifiers w/o binding', () => { + const code = compile(`
`, { + bindingMetadata: { + vExample: BindingTypes.SETUP_CONST, + }, + }) + expect(code).matchSnapshot() + }) + + test('static parameters and modifiers', () => { + const code = compile(`
`, { + bindingMetadata: { + msg: BindingTypes.SETUP_REF, + vExample: BindingTypes.SETUP_CONST, + }, + }) + expect(code).matchSnapshot() + }) + + test('dynamic parameters', () => { + const code = compile(`
`, { + bindingMetadata: { + foo: BindingTypes.SETUP_REF, + vExample: BindingTypes.SETUP_CONST, + }, + }) + expect(code).matchSnapshot() + }) + }) + }) + + describe('expression parsing', () => { + test('interpolation', () => { + const code = compile(`{{ a + b }}`, { + inline: true, + bindingMetadata: { + b: BindingTypes.SETUP_REF, + }, + }) + expect(code).matchSnapshot() + expect(code).contains('a + b.value') + }) + + test('v-bind', () => { + const code = compile(`
`, { + inline: true, + bindingMetadata: { + key: BindingTypes.SETUP_REF, + foo: BindingTypes.SETUP_MAYBE_REF, + }, + }) + expect(code).matchSnapshot() + expect(code).contains('key.value+1') + expect(code).contains('_unref(foo)[key.value+1]()') + }) + + // TODO: add more test for expression parsing (v-on, v-slot, v-for) + }) +}) diff --git a/packages/compiler-vapor/__tests__/compile.test.ts b/packages/compiler-vapor/__tests__/compile.test.ts deleted file mode 100644 index 95f74715e..000000000 --- a/packages/compiler-vapor/__tests__/compile.test.ts +++ /dev/null @@ -1,434 +0,0 @@ -import { - type RootNode, - BindingTypes, - ErrorCodes, - DOMErrorCodes, -} from '@vue/compiler-dom' -import { type CompilerOptions, compile as _compile } from '../src' - -function compile(template: string | RootNode, options: CompilerOptions = {}) { - let { code } = _compile(template, { - ...options, - mode: 'module', - prefixIdentifiers: true, - }) - return code -} - -describe('compile', () => { - test('static template', async () => { - const code = await compile( - `
-

hello

- - -
`, - ) - expect(code).matchSnapshot() - }) - - test('dynamic root', async () => { - const code = await compile(`{{ 1 }}{{ 2 }}`) - expect(code).matchSnapshot() - }) - - test('dynamic root nodes and interpolation', async () => { - const code = await compile( - ``, - ) - expect(code).matchSnapshot() - }) - - test('static + dynamic root', async () => { - const code = await compile( - `{{ 1 }}{{ 2 }}3{{ 4 }}{{ 5 }}6{{ 7 }}{{ 8 }}9{{ 'A' }}{{ 'B' }}`, - ) - expect(code).matchSnapshot() - }) - - test('fragment', async () => { - const code = await compile(`

`) - expect(code).matchSnapshot() - }) - - test('bindings', async () => { - const code = await compile(`
count is {{ count }}.
`, { - bindingMetadata: { - count: BindingTypes.SETUP_REF, - }, - }) - expect(code).matchSnapshot() - }) - - describe('directives', () => { - describe('v-bind', () => { - test('simple expression', async () => { - const code = await compile(`
`, { - bindingMetadata: { - id: BindingTypes.SETUP_REF, - }, - }) - expect(code).matchSnapshot() - }) - - test('should error if no expression', async () => { - const onError = vi.fn() - const code = await compile(`
`, { onError }) - - expect(onError.mock.calls[0][0]).toMatchObject({ - code: ErrorCodes.X_V_BIND_NO_EXPRESSION, - loc: { - start: { - line: 1, - column: 6, - }, - end: { - line: 1, - column: 19, - }, - }, - }) - - expect(code).matchSnapshot() - // the arg is static - expect(code).contains(JSON.stringify('
')) - }) - - test('no expression', async () => { - const code = await compile('
', { - bindingMetadata: { - id: BindingTypes.SETUP_REF, - }, - }) - - expect(code).matchSnapshot() - expect(code).contains('_setAttr(n1, "id", undefined, _ctx.id)') - }) - - test('no expression (shorthand)', async () => { - const code = await compile('
', { - bindingMetadata: { - camelCase: BindingTypes.SETUP_REF, - }, - }) - - expect(code).matchSnapshot() - expect(code).contains( - '_setAttr(n1, "camel-case", undefined, _ctx.camelCase)', - ) - }) - - test('dynamic arg', async () => { - const code = await compile('
', { - bindingMetadata: { - id: BindingTypes.SETUP_REF, - }, - }) - - expect(code).matchSnapshot() - expect(code).contains('_setAttr(n1, _ctx.id, undefined, _ctx.id)') - }) - - // TODO: camel modifier for v-bind - test.fails('.camel modifier', async () => { - const code = await compile(`
`) - - expect(code).matchSnapshot() - expect(code).contains('fooBar') - }) - }) - - describe('v-on', () => { - test('simple expression', async () => { - const code = await compile(`
`, { - bindingMetadata: { - handleClick: BindingTypes.SETUP_CONST, - }, - }) - expect(code).matchSnapshot() - }) - - test('should error if no expression AND no modifier', async () => { - const onError = vi.fn() - await compile(`
`, { onError }) - expect(onError.mock.calls[0][0]).toMatchObject({ - code: ErrorCodes.X_V_ON_NO_EXPRESSION, - loc: { - start: { - line: 1, - column: 6, - }, - end: { - line: 1, - column: 16, - }, - }, - }) - }) - - test('event modifier', async () => { - const code = await compile( - ` -
- -
-
- -
- - - - - - - - - - - - - - - `, - { - bindingMetadata: { - handleEvent: BindingTypes.SETUP_CONST, - }, - }, - ) - expect(code).matchSnapshot() - }) - }) - - describe('v-html', () => { - test('simple expression', async () => { - const code = await compile(`
`, { - bindingMetadata: { - code: BindingTypes.SETUP_REF, - }, - }) - expect(code).matchSnapshot() - }) - - test('should raise error and ignore children when v-html is present', async () => { - const onError = vi.fn() - const code = await compile(`
hello
`, { - onError, - }) - expect(code).matchSnapshot() - expect(onError.mock.calls).toMatchObject([ - [{ code: DOMErrorCodes.X_V_HTML_WITH_CHILDREN }], - ]) - }) - - test('should raise error if has no expression', async () => { - const onError = vi.fn() - const code = await compile(`
`, { - onError, - }) - expect(code).matchSnapshot() - expect(onError.mock.calls).toMatchObject([ - [{ code: DOMErrorCodes.X_V_HTML_NO_EXPRESSION }], - ]) - }) - }) - - describe('v-text', () => { - test('simple expression', async () => { - const code = await compile(`
`, { - bindingMetadata: { - str: BindingTypes.SETUP_REF, - }, - }) - expect(code).matchSnapshot() - }) - - test('no expression', async () => { - const onError = vi.fn() - const code = await compile(`
`, { onError }) - expect(code).matchSnapshot() - expect(onError.mock.calls).toMatchObject([ - [{ code: DOMErrorCodes.X_V_TEXT_NO_EXPRESSION }], - ]) - }) - }) - - describe('v-once', () => { - test('basic', async () => { - const code = await compile( - `
- {{ msg }} - -
`, - { - bindingMetadata: { - msg: BindingTypes.SETUP_REF, - clz: BindingTypes.SETUP_REF, - }, - }, - ) - expect(code).matchSnapshot() - }) - - test('as root node', async () => { - const code = await compile(`
`) - expect(code).toMatchSnapshot() - expect(code).not.contains('effect') - }) - }) - - describe('v-pre', () => { - test('basic', async () => { - const code = await compile( - `
{{ bar }}
\n`, - { - bindingMetadata: { - foo: BindingTypes.SETUP_REF, - bar: BindingTypes.SETUP_REF, - }, - }, - ) - - expect(code).toMatchSnapshot() - expect(code).contains( - JSON.stringify('
{{ bar }}
'), - ) - expect(code).not.contains('effect') - }) - - // TODO: support multiple root nodes and components - test('should not affect siblings after it', async () => { - const code = await compile( - `
{{ bar }}
\n` + - `
{{ bar }}
`, - { - bindingMetadata: { - foo: BindingTypes.SETUP_REF, - bar: BindingTypes.SETUP_REF, - }, - }, - ) - - expect(code).toMatchSnapshot() - // Waiting for TODO, There should be more here. - }) - - // TODO: support multiple root nodes and components - test('self-closing v-pre', async () => { - const code = await compile( - `
\n
{{ bar }}
`, - ) - - expect(code).toMatchSnapshot() - expect(code).contains('
') - // Waiting for TODO, There should be more here. - }) - }) - - describe('v-cloak', () => { - test('basic', async () => { - const code = await compile(`
test
`) - expect(code).toMatchSnapshot() - expect(code).not.contains('v-cloak') - }) - }) - - describe('custom directive', () => { - test('basic', async () => { - const code = await compile(`
`, { - bindingMetadata: { - vExample: BindingTypes.SETUP_CONST, - }, - }) - expect(code).matchSnapshot() - }) - - test('binding value', async () => { - const code = await compile(`
`, { - bindingMetadata: { - msg: BindingTypes.SETUP_REF, - vExample: BindingTypes.SETUP_CONST, - }, - }) - expect(code).matchSnapshot() - }) - - test('static parameters', async () => { - const code = await compile(`
`, { - bindingMetadata: { - msg: BindingTypes.SETUP_REF, - vExample: BindingTypes.SETUP_CONST, - }, - }) - expect(code).matchSnapshot() - }) - - test('modifiers', async () => { - const code = await compile(`
`, { - bindingMetadata: { - msg: BindingTypes.SETUP_REF, - vExample: BindingTypes.SETUP_CONST, - }, - }) - expect(code).matchSnapshot() - }) - - test('modifiers w/o binding', async () => { - const code = await compile(`
`, { - bindingMetadata: { - vExample: BindingTypes.SETUP_CONST, - }, - }) - expect(code).matchSnapshot() - }) - - test('static parameters and modifiers', async () => { - const code = await compile(`
`, { - bindingMetadata: { - msg: BindingTypes.SETUP_REF, - vExample: BindingTypes.SETUP_CONST, - }, - }) - expect(code).matchSnapshot() - }) - - test('dynamic parameters', async () => { - const code = await compile(`
`, { - bindingMetadata: { - foo: BindingTypes.SETUP_REF, - vExample: BindingTypes.SETUP_CONST, - }, - }) - expect(code).matchSnapshot() - }) - }) - }) - - describe('expression parsing', () => { - test('interpolation', async () => { - const code = await compile(`{{ a + b }}`, { - inline: true, - bindingMetadata: { - b: BindingTypes.SETUP_REF, - }, - }) - expect(code).matchSnapshot() - expect(code).contains('a + b.value') - }) - - test('v-bind', async () => { - const code = compile(`
`, { - inline: true, - bindingMetadata: { - key: BindingTypes.SETUP_REF, - foo: BindingTypes.SETUP_MAYBE_REF, - }, - }) - expect(code).matchSnapshot() - expect(code).contains('key.value+1') - expect(code).contains('_unref(foo)[key.value+1]()') - }) - - // TODO: add more test for expression parsing (v-on, v-slot, v-for) - }) -}) diff --git a/packages/compiler-vapor/__tests__/transforms/__snapshots__/vBind.spec.ts.snap b/packages/compiler-vapor/__tests__/transforms/__snapshots__/vBind.spec.ts.snap new file mode 100644 index 000000000..379d8c21d --- /dev/null +++ b/packages/compiler-vapor/__tests__/transforms/__snapshots__/vBind.spec.ts.snap @@ -0,0 +1,81 @@ +// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html + +exports[`v-bind > .camel modifier 1`] = ` +"import { template as _template, children as _children, effect as _effect, setAttr as _setAttr } from 'vue/vapor'; + +export function render(_ctx) { + const t0 = _template("
") + const n0 = t0() + const { 0: [n1],} = _children(n0) + _effect(() => { + _setAttr(n1, "foo-bar", undefined, _ctx.id) + }) + return n0 +}" +`; + +exports[`v-bind > dynamic arg 1`] = ` +"import { template as _template, children as _children, effect as _effect, setAttr as _setAttr } from 'vue/vapor'; + +export function render(_ctx) { + const t0 = _template("
") + const n0 = t0() + const { 0: [n1],} = _children(n0) + _effect(() => { + _setAttr(n1, _ctx.id, undefined, _ctx.id) + }) + return n0 +}" +`; + +exports[`v-bind > no expression (shorthand) 1`] = ` +"import { template as _template, children as _children, effect as _effect, setAttr as _setAttr } from 'vue/vapor'; + +export function render(_ctx) { + const t0 = _template("
") + const n0 = t0() + const { 0: [n1],} = _children(n0) + _effect(() => { + _setAttr(n1, "camel-case", undefined, _ctx.camelCase) + }) + return n0 +}" +`; + +exports[`v-bind > no expression 1`] = ` +"import { template as _template, children as _children, effect as _effect, setAttr as _setAttr } from 'vue/vapor'; + +export function render(_ctx) { + const t0 = _template("
") + const n0 = t0() + const { 0: [n1],} = _children(n0) + _effect(() => { + _setAttr(n1, "id", undefined, _ctx.id) + }) + return n0 +}" +`; + +exports[`v-bind > should error if no expression 1`] = ` +"import { template as _template } from 'vue/vapor'; + +export function render(_ctx) { + const t0 = _template("
") + const n0 = t0() + return n0 +}" +`; + +exports[`v-bind > simple expression 1`] = ` +"import { template as _template, children as _children, effect as _effect, setAttr as _setAttr } from 'vue/vapor'; + +export function render(_ctx) { + const t0 = _template("
") + const n0 = t0() + const { 0: [n1],} = _children(n0) + _effect(() => { + _setAttr(n1, "id", undefined, _ctx.id) + }) + return n0 +}" +`; diff --git a/packages/compiler-vapor/__tests__/transforms/__snapshots__/vHtml.spec.ts.snap b/packages/compiler-vapor/__tests__/transforms/__snapshots__/vHtml.spec.ts.snap new file mode 100644 index 000000000..459741e9a --- /dev/null +++ b/packages/compiler-vapor/__tests__/transforms/__snapshots__/vHtml.spec.ts.snap @@ -0,0 +1,41 @@ +// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html + +exports[`v-html > should raise error and ignore children when v-html is present 1`] = ` +"import { template as _template, children as _children, effect as _effect, setHtml as _setHtml } from 'vue/vapor'; + +export function render(_ctx) { + const t0 = _template("
") + const n0 = t0() + const { 0: [n1],} = _children(n0) + _effect(() => { + _setHtml(n1, undefined, _ctx.test) + }) + return n0 +}" +`; + +exports[`v-html > should raise error if has no expression 1`] = ` +"import { template as _template, children as _children, setHtml as _setHtml } from 'vue/vapor'; + +export function render(_ctx) { + const t0 = _template("
") + const n0 = t0() + const { 0: [n1],} = _children(n0) + _setHtml(n1, undefined, "") + return n0 +}" +`; + +exports[`v-html > simple expression 1`] = ` +"import { template as _template, children as _children, effect as _effect, setHtml as _setHtml } from 'vue/vapor'; + +export function render(_ctx) { + const t0 = _template("
") + const n0 = t0() + const { 0: [n1],} = _children(n0) + _effect(() => { + _setHtml(n1, undefined, _ctx.code) + }) + return n0 +}" +`; diff --git a/packages/compiler-vapor/__tests__/transforms/__snapshots__/vOn.spec.ts.snap b/packages/compiler-vapor/__tests__/transforms/__snapshots__/vOn.spec.ts.snap new file mode 100644 index 000000000..df47f1598 --- /dev/null +++ b/packages/compiler-vapor/__tests__/transforms/__snapshots__/vOn.spec.ts.snap @@ -0,0 +1,46 @@ +// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html + +exports[`v-on > event modifier 1`] = ` +"import { template as _template, children as _children, on as _on, withModifiers as _withModifiers, withKeys as _withKeys } from 'vue/vapor'; + +export function render(_ctx) { + const t0 = _template("
") + const n0 = t0() + const { 0: [n1], 1: [n2], 2: [n3], 3: [n4], 4: [n5], 5: [n6], 6: [n7], 7: [n8], 8: [n9], 9: [n10], 10: [n11], 11: [n12], 12: [n13], 13: [n14], 14: [n15], 15: [n16], 16: [n17], 17: [n18], 18: [n19], 19: [n20], 20: [n21], 21: [n22],} = _children(n0) + _on(n1, "click", _withModifiers((...args) => (_ctx.handleEvent && _ctx.handleEvent(...args)), ["stop"])) + _on(n2, "submit", _withModifiers((...args) => (_ctx.handleEvent && _ctx.handleEvent(...args)), ["prevent"])) + _on(n3, "click", _withModifiers((...args) => (_ctx.handleEvent && _ctx.handleEvent(...args)), ["stop", "prevent"])) + _on(n4, "click", _withModifiers((...args) => (_ctx.handleEvent && _ctx.handleEvent(...args)), ["self"])) + _on(n5, "click", (...args) => (_ctx.handleEvent && _ctx.handleEvent(...args)), { capture: true }) + _on(n6, "click", (...args) => (_ctx.handleEvent && _ctx.handleEvent(...args)), { once: true }) + _on(n7, "scroll", (...args) => (_ctx.handleEvent && _ctx.handleEvent(...args)), { passive: true }) + _on(n8, "contextmenu", _withModifiers((...args) => (_ctx.handleEvent && _ctx.handleEvent(...args)), ["right"])) + _on(n9, "click", _withModifiers((...args) => (_ctx.handleEvent && _ctx.handleEvent(...args)), ["left"])) + _on(n10, "mouseup", _withModifiers((...args) => (_ctx.handleEvent && _ctx.handleEvent(...args)), ["middle"])) + _on(n11, "contextmenu", _withModifiers((...args) => (_ctx.handleEvent && _ctx.handleEvent(...args)), ["right"])) + _on(n12, "keyup", _withKeys((...args) => (_ctx.handleEvent && _ctx.handleEvent(...args)), ["enter"])) + _on(n13, "keyup", _withKeys((...args) => (_ctx.handleEvent && _ctx.handleEvent(...args)), ["tab"])) + _on(n14, "keyup", _withKeys((...args) => (_ctx.handleEvent && _ctx.handleEvent(...args)), ["delete"])) + _on(n15, "keyup", _withKeys((...args) => (_ctx.handleEvent && _ctx.handleEvent(...args)), ["esc"])) + _on(n16, "keyup", _withKeys((...args) => (_ctx.handleEvent && _ctx.handleEvent(...args)), ["space"])) + _on(n17, "keyup", _withKeys((...args) => (_ctx.handleEvent && _ctx.handleEvent(...args)), ["up"])) + _on(n18, "keyup", _withKeys((...args) => (_ctx.handleEvent && _ctx.handleEvent(...args)), ["down"])) + _on(n19, "keyup", _withKeys((...args) => (_ctx.handleEvent && _ctx.handleEvent(...args)), ["left"])) + _on(n20, "keyup", _withModifiers((...args) => (_ctx.submit && _ctx.submit(...args)), ["middle"])) + _on(n21, "keyup", _withModifiers((...args) => (_ctx.submit && _ctx.submit(...args)), ["middle", "self"])) + _on(n22, "keyup", _withKeys(_withModifiers((...args) => (_ctx.handleEvent && _ctx.handleEvent(...args)), ["self"]), ["enter"])) + return n0 +}" +`; + +exports[`v-on > simple expression 1`] = ` +"import { template as _template, children as _children, on as _on } from 'vue/vapor'; + +export function render(_ctx) { + const t0 = _template("
") + const n0 = t0() + const { 0: [n1],} = _children(n0) + _on(n1, "click", (...args) => (_ctx.handleClick && _ctx.handleClick(...args))) + return n0 +}" +`; diff --git a/packages/compiler-vapor/__tests__/transforms/__snapshots__/vOnce.spec.ts.snap b/packages/compiler-vapor/__tests__/transforms/__snapshots__/vOnce.spec.ts.snap new file mode 100644 index 000000000..b255f5d0b --- /dev/null +++ b/packages/compiler-vapor/__tests__/transforms/__snapshots__/vOnce.spec.ts.snap @@ -0,0 +1,28 @@ +// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html + +exports[`v-once > as root node 1`] = ` +"import { template as _template, children as _children, setAttr as _setAttr } from 'vue/vapor'; + +export function render(_ctx) { + const t0 = _template("
") + const n0 = t0() + const { 0: [n1],} = _children(n0) + _setAttr(n1, "id", undefined, _ctx.foo) + return n0 +}" +`; + +exports[`v-once > basic 1`] = ` +"import { template as _template, children as _children, createTextNode as _createTextNode, setText as _setText, setAttr as _setAttr, prepend as _prepend } from 'vue/vapor'; + +export function render(_ctx) { + const t0 = _template("
") + const n0 = t0() + const { 0: [n3, { 1: [n2],}],} = _children(n0) + const n1 = _createTextNode(_ctx.msg) + _setText(n1, undefined, _ctx.msg) + _setAttr(n2, "class", undefined, _ctx.clz) + _prepend(n3, n1) + return n0 +}" +`; diff --git a/packages/compiler-vapor/__tests__/transforms/__snapshots__/vText.spec.ts.snap b/packages/compiler-vapor/__tests__/transforms/__snapshots__/vText.spec.ts.snap new file mode 100644 index 000000000..f2b62b2ee --- /dev/null +++ b/packages/compiler-vapor/__tests__/transforms/__snapshots__/vText.spec.ts.snap @@ -0,0 +1,27 @@ +// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html + +exports[`v-text > no expression 1`] = ` +"import { template as _template, children as _children, setText as _setText } from 'vue/vapor'; + +export function render(_ctx) { + const t0 = _template("
") + const n0 = t0() + const { 0: [n1],} = _children(n0) + _setText(n1, undefined, "") + return n0 +}" +`; + +exports[`v-text > simple expression 1`] = ` +"import { template as _template, children as _children, effect as _effect, setText as _setText } from 'vue/vapor'; + +export function render(_ctx) { + const t0 = _template("
") + const n0 = t0() + const { 0: [n1],} = _children(n0) + _effect(() => { + _setText(n1, undefined, _ctx.str) + }) + return n0 +}" +`; diff --git a/packages/compiler-vapor/__tests__/transforms/transformElement.spec.ts b/packages/compiler-vapor/__tests__/transforms/transformElement.spec.ts new file mode 100644 index 000000000..42c304f46 --- /dev/null +++ b/packages/compiler-vapor/__tests__/transforms/transformElement.spec.ts @@ -0,0 +1,2 @@ +// TODO: add tests for this transform +test('baisc', () => {}) diff --git a/packages/compiler-vapor/__tests__/transforms/transformInterpolation.spec.ts b/packages/compiler-vapor/__tests__/transforms/transformInterpolation.spec.ts new file mode 100644 index 000000000..42c304f46 --- /dev/null +++ b/packages/compiler-vapor/__tests__/transforms/transformInterpolation.spec.ts @@ -0,0 +1,2 @@ +// TODO: add tests for this transform +test('baisc', () => {}) diff --git a/packages/compiler-vapor/__tests__/transforms/vBind.spec.ts b/packages/compiler-vapor/__tests__/transforms/vBind.spec.ts new file mode 100644 index 000000000..6a990c786 --- /dev/null +++ b/packages/compiler-vapor/__tests__/transforms/vBind.spec.ts @@ -0,0 +1,88 @@ +import { type RootNode, BindingTypes, ErrorCodes } from '@vue/compiler-dom' +import { type CompilerOptions, compile as _compile } from '../../src' + +function compile(template: string | RootNode, options: CompilerOptions = {}) { + let { code } = _compile(template, { + ...options, + mode: 'module', + prefixIdentifiers: true, + }) + return code +} + +describe('v-bind', () => { + test('simple expression', () => { + const code = compile(`
`, { + bindingMetadata: { + id: BindingTypes.SETUP_REF, + }, + }) + expect(code).matchSnapshot() + }) + + test('should error if no expression', () => { + const onError = vi.fn() + const code = compile(`
`, { onError }) + + expect(onError.mock.calls[0][0]).toMatchObject({ + code: ErrorCodes.X_V_BIND_NO_EXPRESSION, + loc: { + start: { + line: 1, + column: 6, + }, + end: { + line: 1, + column: 19, + }, + }, + }) + + expect(code).matchSnapshot() + // the arg is static + expect(code).contains(JSON.stringify('
')) + }) + + test('no expression', () => { + const code = compile('
', { + bindingMetadata: { + id: BindingTypes.SETUP_REF, + }, + }) + + expect(code).matchSnapshot() + expect(code).contains('_setAttr(n1, "id", undefined, _ctx.id)') + }) + + test('no expression (shorthand)', () => { + const code = compile('
', { + bindingMetadata: { + camelCase: BindingTypes.SETUP_REF, + }, + }) + + expect(code).matchSnapshot() + expect(code).contains( + '_setAttr(n1, "camel-case", undefined, _ctx.camelCase)', + ) + }) + + test('dynamic arg', () => { + const code = compile('
', { + bindingMetadata: { + id: BindingTypes.SETUP_REF, + }, + }) + + expect(code).matchSnapshot() + expect(code).contains('_setAttr(n1, _ctx.id, undefined, _ctx.id)') + }) + + // TODO: camel modifier for v-bind + test.fails('.camel modifier', () => { + const code = compile(`
`) + + expect(code).matchSnapshot() + expect(code).contains('fooBar') + }) +}) diff --git a/packages/compiler-vapor/__tests__/transforms/vHtml.spec.ts b/packages/compiler-vapor/__tests__/transforms/vHtml.spec.ts new file mode 100644 index 000000000..6d0492fa6 --- /dev/null +++ b/packages/compiler-vapor/__tests__/transforms/vHtml.spec.ts @@ -0,0 +1,44 @@ +import { type RootNode, BindingTypes, DOMErrorCodes } from '@vue/compiler-dom' +import { type CompilerOptions, compile as _compile } from '../../src' + +function compile(template: string | RootNode, options: CompilerOptions = {}) { + let { code } = _compile(template, { + ...options, + mode: 'module', + prefixIdentifiers: true, + }) + return code +} + +describe('v-html', () => { + test('simple expression', () => { + const code = compile(`
`, { + bindingMetadata: { + code: BindingTypes.SETUP_REF, + }, + }) + expect(code).matchSnapshot() + }) + + test('should raise error and ignore children when v-html is present', () => { + const onError = vi.fn() + const code = compile(`
hello
`, { + onError, + }) + expect(code).matchSnapshot() + expect(onError.mock.calls).toMatchObject([ + [{ code: DOMErrorCodes.X_V_HTML_WITH_CHILDREN }], + ]) + }) + + test('should raise error if has no expression', () => { + const onError = vi.fn() + const code = compile(`
`, { + onError, + }) + expect(code).matchSnapshot() + expect(onError.mock.calls).toMatchObject([ + [{ code: DOMErrorCodes.X_V_HTML_NO_EXPRESSION }], + ]) + }) +}) diff --git a/packages/compiler-vapor/__tests__/transforms/vOn.spec.ts b/packages/compiler-vapor/__tests__/transforms/vOn.spec.ts new file mode 100644 index 000000000..353396ba1 --- /dev/null +++ b/packages/compiler-vapor/__tests__/transforms/vOn.spec.ts @@ -0,0 +1,73 @@ +import { type RootNode, BindingTypes, ErrorCodes } from '@vue/compiler-dom' +import { type CompilerOptions, compile as _compile } from '../../src' + +function compile(template: string | RootNode, options: CompilerOptions = {}) { + let { code } = _compile(template, { + ...options, + mode: 'module', + prefixIdentifiers: true, + }) + return code +} + +describe('v-on', () => { + test('simple expression', () => { + const code = compile(`
`, { + bindingMetadata: { + handleClick: BindingTypes.SETUP_CONST, + }, + }) + expect(code).matchSnapshot() + }) + + test('should error if no expression AND no modifier', () => { + const onError = vi.fn() + compile(`
`, { onError }) + expect(onError.mock.calls[0][0]).toMatchObject({ + code: ErrorCodes.X_V_ON_NO_EXPRESSION, + loc: { + start: { + line: 1, + column: 6, + }, + end: { + line: 1, + column: 16, + }, + }, + }) + }) + + test('event modifier', () => { + const code = compile( + ` +
+ +
+
+ +
+ + + + + + + + + + + + + + + `, + { + bindingMetadata: { + handleEvent: BindingTypes.SETUP_CONST, + }, + }, + ) + expect(code).matchSnapshot() + }) +}) diff --git a/packages/compiler-vapor/__tests__/transforms/vOnce.spec.ts b/packages/compiler-vapor/__tests__/transforms/vOnce.spec.ts new file mode 100644 index 000000000..8c87f3b2a --- /dev/null +++ b/packages/compiler-vapor/__tests__/transforms/vOnce.spec.ts @@ -0,0 +1,35 @@ +import { type RootNode, BindingTypes } from '@vue/compiler-dom' +import { type CompilerOptions, compile as _compile } from '../../src' + +function compile(template: string | RootNode, options: CompilerOptions = {}) { + let { code } = _compile(template, { + ...options, + mode: 'module', + prefixIdentifiers: true, + }) + return code +} + +describe('v-once', () => { + test('basic', () => { + const code = compile( + `
+ {{ msg }} + +
`, + { + bindingMetadata: { + msg: BindingTypes.SETUP_REF, + clz: BindingTypes.SETUP_REF, + }, + }, + ) + expect(code).matchSnapshot() + }) + + test('as root node', () => { + const code = compile(`
`) + expect(code).toMatchSnapshot() + expect(code).not.contains('effect') + }) +}) diff --git a/packages/compiler-vapor/__tests__/transforms/vText.spec.ts b/packages/compiler-vapor/__tests__/transforms/vText.spec.ts new file mode 100644 index 000000000..0989ef19f --- /dev/null +++ b/packages/compiler-vapor/__tests__/transforms/vText.spec.ts @@ -0,0 +1,31 @@ +import { type RootNode, BindingTypes, DOMErrorCodes } from '@vue/compiler-dom' +import { type CompilerOptions, compile as _compile } from '../../src' + +function compile(template: string | RootNode, options: CompilerOptions = {}) { + let { code } = _compile(template, { + ...options, + mode: 'module', + prefixIdentifiers: true, + }) + return code +} + +describe('v-text', () => { + test('simple expression', () => { + const code = compile(`
`, { + bindingMetadata: { + str: BindingTypes.SETUP_REF, + }, + }) + expect(code).matchSnapshot() + }) + + test('no expression', () => { + const onError = vi.fn() + const code = compile(`
`, { onError }) + expect(code).matchSnapshot() + expect(onError.mock.calls).toMatchObject([ + [{ code: DOMErrorCodes.X_V_TEXT_NO_EXPRESSION }], + ]) + }) +})