wip: test for runtime props/emits extraction
This commit is contained in:
parent
2c3cdab93d
commit
18c537d3c2
@ -1,5 +1,92 @@
|
|||||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||||
|
|
||||||
|
exports[`SFC compile <script setup> <script setup lang="ts"> extract emits 1`] = `
|
||||||
|
"import { defineComponent as __define__ } from 'vue'
|
||||||
|
import { Slots as __Slots__ } from 'vue'
|
||||||
|
declare function __emit__(e: 'foo' | 'bar'): void
|
||||||
|
declare function __emit__(e: 'baz', id: number): void
|
||||||
|
|
||||||
|
export function setup(_: {}, { emit: myEmit }: {
|
||||||
|
emit: typeof __emit__,
|
||||||
|
slots: __Slots__,
|
||||||
|
attrs: Record<string, any>
|
||||||
|
}) {
|
||||||
|
|
||||||
|
|
||||||
|
return { }
|
||||||
|
}
|
||||||
|
|
||||||
|
export default __define__({
|
||||||
|
emits: [\\"foo\\", \\"bar\\", \\"baz\\"] as unknown as undefined,
|
||||||
|
setup
|
||||||
|
})"
|
||||||
|
`;
|
||||||
|
|
||||||
|
exports[`SFC compile <script setup> <script setup lang="ts"> extract props 1`] = `
|
||||||
|
"import { defineComponent as __define__ } from 'vue'
|
||||||
|
import { Slots as __Slots__ } from 'vue'
|
||||||
|
interface Test {}
|
||||||
|
|
||||||
|
type Alias = number[]
|
||||||
|
|
||||||
|
|
||||||
|
export function setup(myProps: {
|
||||||
|
string: string
|
||||||
|
number: number
|
||||||
|
boolean: boolean
|
||||||
|
object: object
|
||||||
|
objectLiteral: { a: number }
|
||||||
|
fn: (n: number) => void
|
||||||
|
functionRef: Function
|
||||||
|
objectRef: Object
|
||||||
|
array: string[]
|
||||||
|
arrayRef: Array<any>
|
||||||
|
tuple: [number, number]
|
||||||
|
set: Set<string>
|
||||||
|
literal: 'foo'
|
||||||
|
optional?: any
|
||||||
|
recordRef: Record<string, null>
|
||||||
|
interface: Test
|
||||||
|
alias: Alias
|
||||||
|
|
||||||
|
union: string | number
|
||||||
|
literalUnion: 'foo' | 'bar'
|
||||||
|
literalUnionMixed: 'foo' | 1 | boolean
|
||||||
|
intersection: Test & {}
|
||||||
|
}) {
|
||||||
|
|
||||||
|
|
||||||
|
return { }
|
||||||
|
}
|
||||||
|
|
||||||
|
export default __define__({
|
||||||
|
props: {
|
||||||
|
string: { type: String, required: true },
|
||||||
|
number: { type: Number, required: true },
|
||||||
|
boolean: { type: Boolean, required: true },
|
||||||
|
object: { type: Object, required: true },
|
||||||
|
objectLiteral: { type: Object, required: true },
|
||||||
|
fn: { type: Function, required: true },
|
||||||
|
functionRef: { type: Function, required: true },
|
||||||
|
objectRef: { type: Object, required: true },
|
||||||
|
array: { type: Array, required: true },
|
||||||
|
arrayRef: { type: Array, required: true },
|
||||||
|
tuple: { type: Array, required: true },
|
||||||
|
set: { type: Set, required: true },
|
||||||
|
literal: { type: String, required: true },
|
||||||
|
optional: { type: null, required: false },
|
||||||
|
recordRef: { type: Object, required: true },
|
||||||
|
interface: { type: Object, required: true },
|
||||||
|
alias: { type: Array, required: true },
|
||||||
|
union: { type: [String, Number], required: true },
|
||||||
|
literalUnion: { type: [String, String], required: true },
|
||||||
|
literalUnionMixed: { type: [String, Number, Boolean], required: true },
|
||||||
|
intersection: { type: Object, required: true }
|
||||||
|
} as unknown as undefined,
|
||||||
|
setup
|
||||||
|
})"
|
||||||
|
`;
|
||||||
|
|
||||||
exports[`SFC compile <script setup> <script setup lang="ts"> hoist type declarations 1`] = `
|
exports[`SFC compile <script setup> <script setup lang="ts"> hoist type declarations 1`] = `
|
||||||
"import { defineComponent as __define__ } from 'vue'
|
"import { defineComponent as __define__ } from 'vue'
|
||||||
import { Slots as __Slots__ } from 'vue'
|
import { Slots as __Slots__ } from 'vue'
|
||||||
|
@ -205,9 +205,82 @@ describe('SFC compile <script setup>', () => {
|
|||||||
expect(bindings).toStrictEqual({ a: 'setup' })
|
expect(bindings).toStrictEqual({ a: 'setup' })
|
||||||
})
|
})
|
||||||
|
|
||||||
test('extract props', () => {})
|
test('extract props', () => {
|
||||||
|
const { code } = compile(`
|
||||||
|
<script setup="myProps" lang="ts">
|
||||||
|
interface Test {}
|
||||||
|
|
||||||
test('extract emits', () => {})
|
type Alias = number[]
|
||||||
|
|
||||||
|
declare const myProps: {
|
||||||
|
string: string
|
||||||
|
number: number
|
||||||
|
boolean: boolean
|
||||||
|
object: object
|
||||||
|
objectLiteral: { a: number }
|
||||||
|
fn: (n: number) => void
|
||||||
|
functionRef: Function
|
||||||
|
objectRef: Object
|
||||||
|
array: string[]
|
||||||
|
arrayRef: Array<any>
|
||||||
|
tuple: [number, number]
|
||||||
|
set: Set<string>
|
||||||
|
literal: 'foo'
|
||||||
|
optional?: any
|
||||||
|
recordRef: Record<string, null>
|
||||||
|
interface: Test
|
||||||
|
alias: Alias
|
||||||
|
|
||||||
|
union: string | number
|
||||||
|
literalUnion: 'foo' | 'bar'
|
||||||
|
literalUnionMixed: 'foo' | 1 | boolean
|
||||||
|
intersection: Test & {}
|
||||||
|
}
|
||||||
|
</script>`)
|
||||||
|
assertCode(code)
|
||||||
|
expect(code).toMatch(`string: { type: String, required: true }`)
|
||||||
|
expect(code).toMatch(`number: { type: Number, required: true }`)
|
||||||
|
expect(code).toMatch(`boolean: { type: Boolean, required: true }`)
|
||||||
|
expect(code).toMatch(`object: { type: Object, required: true }`)
|
||||||
|
expect(code).toMatch(`objectLiteral: { type: Object, required: true }`)
|
||||||
|
expect(code).toMatch(`fn: { type: Function, required: true }`)
|
||||||
|
expect(code).toMatch(`functionRef: { type: Function, required: true }`)
|
||||||
|
expect(code).toMatch(`objectRef: { type: Object, required: true }`)
|
||||||
|
expect(code).toMatch(`array: { type: Array, required: true }`)
|
||||||
|
expect(code).toMatch(`arrayRef: { type: Array, required: true }`)
|
||||||
|
expect(code).toMatch(`tuple: { type: Array, required: true }`)
|
||||||
|
expect(code).toMatch(`set: { type: Set, required: true }`)
|
||||||
|
expect(code).toMatch(`literal: { type: String, required: true }`)
|
||||||
|
expect(code).toMatch(`optional: { type: null, required: false }`)
|
||||||
|
expect(code).toMatch(`recordRef: { type: Object, required: true }`)
|
||||||
|
expect(code).toMatch(`interface: { type: Object, required: true }`)
|
||||||
|
expect(code).toMatch(`alias: { type: Array, required: true }`)
|
||||||
|
expect(code).toMatch(`union: { type: [String, Number], required: true }`)
|
||||||
|
expect(code).toMatch(
|
||||||
|
`literalUnion: { type: [String, String], required: true }`
|
||||||
|
)
|
||||||
|
expect(code).toMatch(
|
||||||
|
`literalUnionMixed: { type: [String, Number, Boolean], required: true }`
|
||||||
|
)
|
||||||
|
expect(code).toMatch(`intersection: { type: Object, required: true }`)
|
||||||
|
})
|
||||||
|
|
||||||
|
test('extract emits', () => {
|
||||||
|
const { code } = compile(`
|
||||||
|
<script setup="_, { emit: myEmit }" lang="ts">
|
||||||
|
declare function myEmit(e: 'foo' | 'bar'): void
|
||||||
|
declare function myEmit(e: 'baz', id: number): void
|
||||||
|
</script>
|
||||||
|
`)
|
||||||
|
assertCode(code)
|
||||||
|
expect(code).toMatch(`declare function __emit__(e: 'foo' | 'bar'): void`)
|
||||||
|
expect(code).toMatch(
|
||||||
|
`declare function __emit__(e: 'baz', id: number): void`
|
||||||
|
)
|
||||||
|
expect(code).toMatch(
|
||||||
|
`emits: ["foo", "bar", "baz"] as unknown as undefined`
|
||||||
|
)
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
describe('errors', () => {
|
describe('errors', () => {
|
||||||
|
@ -420,7 +420,7 @@ export function compileScriptSetup(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// check default export to make sure it doesn't reference setup scope
|
// 4. check default export to make sure it doesn't reference setup scope
|
||||||
// variables
|
// variables
|
||||||
if (needDefaultExportRefCheck) {
|
if (needDefaultExportRefCheck) {
|
||||||
checkDefaultExport(
|
checkDefaultExport(
|
||||||
@ -433,7 +433,7 @@ export function compileScriptSetup(
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
// remove non-script content
|
// 5. remove non-script content
|
||||||
if (script) {
|
if (script) {
|
||||||
if (startOffset < scriptStartOffset!) {
|
if (startOffset < scriptStartOffset!) {
|
||||||
// <script setup> before <script>
|
// <script setup> before <script>
|
||||||
@ -451,8 +451,7 @@ export function compileScriptSetup(
|
|||||||
s.remove(endOffset, source.length)
|
s.remove(endOffset, source.length)
|
||||||
}
|
}
|
||||||
|
|
||||||
// wrap setup code with function
|
// 5. finalize setup argument signature.
|
||||||
// finalize the argument signature.
|
|
||||||
let args = ``
|
let args = ``
|
||||||
if (isTS) {
|
if (isTS) {
|
||||||
if (slotsType === '__Slots__') {
|
if (slotsType === '__Slots__') {
|
||||||
@ -480,6 +479,7 @@ export function compileScriptSetup(
|
|||||||
args = hasExplicitSignature ? (scriptSetup.setup as string) : ``
|
args = hasExplicitSignature ? (scriptSetup.setup as string) : ``
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 6. wrap setup code with function.
|
||||||
// export the content of <script setup> as a named export, `setup`.
|
// export the content of <script setup> as a named export, `setup`.
|
||||||
// this allows `import { setup } from '*.vue'` for testing purposes.
|
// this allows `import { setup } from '*.vue'` for testing purposes.
|
||||||
s.appendLeft(startOffset, `\nexport function setup(${args}) {\n`)
|
s.appendLeft(startOffset, `\nexport function setup(${args}) {\n`)
|
||||||
@ -499,7 +499,7 @@ export function compileScriptSetup(
|
|||||||
|
|
||||||
s.appendRight(endOffset, `\nreturn ${returned}\n}\n\n`)
|
s.appendRight(endOffset, `\nreturn ${returned}\n}\n\n`)
|
||||||
|
|
||||||
// finalize default export
|
// 7. finalize default export
|
||||||
if (isTS) {
|
if (isTS) {
|
||||||
// for TS, make sure the exported type is still valid type with
|
// for TS, make sure the exported type is still valid type with
|
||||||
// correct props information
|
// correct props information
|
||||||
@ -520,9 +520,7 @@ export function compileScriptSetup(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
s.trim()
|
// 8. expose bindings for template compiler optimization
|
||||||
|
|
||||||
// analyze bindings for template compiler optimization
|
|
||||||
if (script) {
|
if (script) {
|
||||||
Object.assign(bindings, analyzeScriptBindings(script))
|
Object.assign(bindings, analyzeScriptBindings(script))
|
||||||
}
|
}
|
||||||
@ -530,6 +528,7 @@ export function compileScriptSetup(
|
|||||||
bindings[key] = 'setup'
|
bindings[key] = 'setup'
|
||||||
})
|
})
|
||||||
|
|
||||||
|
s.trim()
|
||||||
return {
|
return {
|
||||||
bindings,
|
bindings,
|
||||||
code: s.toString(),
|
code: s.toString(),
|
||||||
|
Loading…
Reference in New Issue
Block a user