| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211 |
- import { parseComponent } from 'sfc/parser'
- describe('Single File Component parser', () => {
- it('should parse', () => {
- const res = parseComponent(`
- <template>
- <div>hi</div>
- </template>
- <style src="./test.css"></style>
- <style lang="stylus" scoped>
- h1
- color red
- h2
- color green
- </style>
- <style module>
- h1 { font-weight: bold }
- </style>
- <style bool-attr val-attr="test"></style>
- <script>
- export default {}
- </script>
- <div>
- <style>nested should be ignored</style>
- </div>
- `)
- expect(res.template.content.trim()).toBe('<div>hi</div>')
- expect(res.styles.length).toBe(4)
- expect(res.styles[0].src).toBe('./test.css')
- expect(res.styles[1].lang).toBe('stylus')
- expect(res.styles[1].scoped).toBe(true)
- expect(res.styles[1].content.trim()).toBe('h1\n color red\nh2\n color green')
- expect(res.styles[2].module).toBe(true)
- expect(res.styles[3].attrs['bool-attr']).toBe(true)
- expect(res.styles[3].attrs['val-attr']).toBe('test')
- expect(res.script.content.trim()).toBe('export default {}')
- })
- it('should parse template with closed input', () => {
- const res = parseComponent(`
- <template>
- <input type="text"/>
- </template>
- `)
- expect(res.template.content.trim()).toBe('<input type="text"/>')
- })
- it('should handle nested template', () => {
- const res = parseComponent(`
- <template>
- <div><template v-if="ok">hi</template></div>
- </template>
- `)
- expect(res.template.content.trim()).toBe('<div><template v-if="ok">hi</template></div>')
- })
- it('deindent content', () => {
- const content = `
- <template>
- <div></div>
- </template>
- <script>
- export default {}
- </script>
- <style>
- h1 { color: red }
- </style>
- `
- const deindentDefault = parseComponent(content.trim(), { pad: false })
- const deindentEnabled = parseComponent(content.trim(), { pad: false, deindent: true })
- const deindentDisabled = parseComponent(content.trim(), { pad: false, deindent: false })
- expect(deindentDefault.template.content).toBe('\n<div></div>\n')
- expect(deindentDefault.script.content).toBe('\nexport default {}\n')
- expect(deindentDefault.styles[0].content).toBe('\nh1 { color: red }\n')
- expect(deindentEnabled.template.content).toBe('\n<div></div>\n')
- expect(deindentEnabled.script.content).toBe('\nexport default {}\n')
- expect(deindentEnabled.styles[0].content).toBe('\nh1 { color: red }\n')
- expect(deindentDisabled.template.content).toBe('\n <div></div>\n ')
- expect(deindentDisabled.script.content).toBe('\n export default {}\n ')
- expect(deindentDisabled.styles[0].content).toBe('\n h1 { color: red }\n ')
- })
- it('pad content', () => {
- const content = `
- <template>
- <div></div>
- </template>
- <script>
- export default {}
- </script>
- <style>
- h1 { color: red }
- </style>
- `
- const padDefault = parseComponent(content.trim(), { pad: true })
- const padLine = parseComponent(content.trim(), { pad: 'line' })
- const padSpace = parseComponent(content.trim(), { pad: 'space' })
- expect(padDefault.script.content).toBe(Array(3 + 1).join('//\n') + '\nexport default {}\n')
- expect(padDefault.styles[0].content).toBe(Array(6 + 1).join('\n') + '\nh1 { color: red }\n')
- expect(padLine.script.content).toBe(Array(3 + 1).join('//\n') + '\nexport default {}\n')
- expect(padLine.styles[0].content).toBe(Array(6 + 1).join('\n') + '\nh1 { color: red }\n')
- expect(padSpace.script.content).toBe(`<template>
- <div></div>
- </template>
- <script>`.replace(/./g, ' ') + '\nexport default {}\n')
- expect(padSpace.styles[0].content).toBe(`<template>
- <div></div>
- </template>
- <script>
- export default {}
- </script>
- <style>`.replace(/./g, ' ') + '\nh1 { color: red }\n')
- })
- it('should handle template blocks with lang as special text', () => {
- const res = parseComponent(`
- <template lang="pug">
- div
- h1(v-if='1 < 2') hello
- </template>
- `)
- expect(res.template.content.trim()).toBe(`div\n h1(v-if='1 < 2') hello`)
- })
- it('should handle component contains "<" only', () => {
- const res = parseComponent(`
- <template>
- <span><</span>
- </template>
- `)
- expect(res.template.content.trim()).toBe(`<span><</span>`)
- })
- it('should handle custom blocks without parsing them', () => {
- const res = parseComponent(`
- <template>
- <div></div>
- </template>
- <example name="simple">
- <my-button ref="button">Hello</my-button>
- </example>
- <example name="with props">
- <my-button color="red">Hello</my-button>
- </example>
- <test name="simple" foo="bar">
- export default function simple (vm) {
- describe('Hello', () => {
- it('should display Hello', () => {
- this.vm.$refs.button.$el.innerText.should.equal('Hello')
- }))
- }))
- }
- </test>
- `)
- expect(res.customBlocks.length).toBe(3)
- const simpleExample = res.customBlocks[0]
- expect(simpleExample.type).toBe('example')
- expect(simpleExample.content.trim()).toBe('<my-button ref="button">Hello</my-button>')
- expect(simpleExample.attrs.name).toBe('simple')
- const withProps = res.customBlocks[1]
- expect(withProps.type).toBe('example')
- expect(withProps.content.trim()).toBe('<my-button color="red">Hello</my-button>')
- expect(withProps.attrs.name).toBe('with props')
- const simpleTest = res.customBlocks[2]
- expect(simpleTest.type).toBe('test')
- expect(simpleTest.content.trim()).toBe(`export default function simple (vm) {
- describe('Hello', () => {
- it('should display Hello', () => {
- this.vm.$refs.button.$el.innerText.should.equal('Hello')
- }))
- }))
- }`)
- expect(simpleTest.attrs.name).toBe('simple')
- expect(simpleTest.attrs.foo).toBe('bar')
- })
- // Regression #4289
- it('accepts nested template tag', () => {
- const raw = `<div>
- <template v-if="true === true">
- <section class="section">
- <div class="container">
- Should be shown
- </div>
- </section>
- </template>
- <template v-else>
- <p>Should not be shown</p>
- </template>
- </div>`
- const res = parseComponent(`<template>${raw}</template>`)
- expect(res.template.content.trim()).toBe(raw)
- })
- it('should not hang on trailing text', () => {
- const res = parseComponent(`<template>hi</`)
- expect(res.template.content).toBe('hi')
- })
- it('should collect errors with source range', () => {
- const res = parseComponent(`<template>hi</`, { outputSourceRange: true })
- expect(res.errors.length).toBe(1)
- expect(res.errors[0].start).toBe(0)
- })
- })
|