259 lines
		
	
	
		
			6.9 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
	
	
			
		
		
	
	
			259 lines
		
	
	
		
			6.9 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
	
	
| import { parse } from '../src/parse'
 | |
| import { SFCBlock } from '../src/parseComponent'
 | |
| import { compileTemplate } from '../src/compileTemplate'
 | |
| import Vue from 'vue'
 | |
| 
 | |
| function mockRender(code: string, mocks: Record<string, any> = {}) {
 | |
|   const fn = new Function(
 | |
|     `require`,
 | |
|     `${code}; return { render, staticRenderFns }`
 | |
|   )
 | |
|   const vm = new Vue(
 | |
|     Object.assign(
 | |
|       {},
 | |
|       fn((id: string) => mocks[id])
 | |
|     )
 | |
|   )
 | |
|   vm.$mount()
 | |
|   return (vm as any)._vnode
 | |
| }
 | |
| 
 | |
| test('should work', () => {
 | |
|   const source = `<div><p>{{ render }}</p></div>`
 | |
| 
 | |
|   const result = compileTemplate({
 | |
|     filename: 'example.vue',
 | |
|     source
 | |
|   })
 | |
| 
 | |
|   expect(result.errors.length).toBe(0)
 | |
|   expect(result.source).toBe(source)
 | |
|   // should expose render fns
 | |
|   expect(result.code).toMatch(`var render = function`)
 | |
|   expect(result.code).toMatch(`var staticRenderFns = []`)
 | |
|   // should mark with stripped
 | |
|   expect(result.code).toMatch(`render._withStripped = true`)
 | |
|   // should prefix bindings
 | |
|   expect(result.code).toMatch(`_vm.render`)
 | |
|   expect(result.ast).not.toBeUndefined()
 | |
| })
 | |
| 
 | |
| test('preprocess pug', () => {
 | |
|   const template = parse({
 | |
|     source:
 | |
|       '<template lang="pug">\n' +
 | |
|       'body\n' +
 | |
|       ' h1 Pug Examples\n' +
 | |
|       ' div.container\n' +
 | |
|       '   p Cool Pug example!\n' +
 | |
|       '</template>\n',
 | |
|     filename: 'example.vue',
 | |
|     sourceMap: true
 | |
|   }).template as SFCBlock
 | |
| 
 | |
|   const result = compileTemplate({
 | |
|     filename: 'example.vue',
 | |
|     source: template.content,
 | |
|     preprocessLang: template.lang
 | |
|   })
 | |
| 
 | |
|   expect(result.errors.length).toBe(0)
 | |
| })
 | |
| 
 | |
| /**
 | |
|  * vuejs/component-compiler-utils#22 Support uri fragment in transformed require
 | |
|  */
 | |
| test('supports uri fragment in transformed require', () => {
 | |
|   const source = '<svg>\
 | |
|     <use href="~@svg/file.svg#fragment"></use>\
 | |
|   </svg>' //
 | |
|   const result = compileTemplate({
 | |
|     filename: 'svgparticle.html',
 | |
|     source: source,
 | |
|     transformAssetUrls: {
 | |
|       use: 'href'
 | |
|     }
 | |
|   })
 | |
|   expect(result.errors.length).toBe(0)
 | |
|   expect(result.code).toMatch(
 | |
|     /href: require\("@svg\/file.svg"\) \+ "#fragment"/
 | |
|   )
 | |
| })
 | |
| 
 | |
| /**
 | |
|  * vuejs/component-compiler-utils#22 Support uri fragment in transformed require
 | |
|  */
 | |
| test('when too short uri then empty require', () => {
 | |
|   const source = '<svg>\
 | |
|     <use href="~"></use>\
 | |
|   </svg>' //
 | |
|   const result = compileTemplate({
 | |
|     filename: 'svgparticle.html',
 | |
|     source: source,
 | |
|     transformAssetUrls: {
 | |
|       use: 'href'
 | |
|     }
 | |
|   })
 | |
|   expect(result.errors.length).toBe(0)
 | |
|   expect(result.code).toMatch(/href: require\(""\)/)
 | |
| })
 | |
| 
 | |
| test('warn missing preprocessor', () => {
 | |
|   const template = parse({
 | |
|     source: '<template lang="unknownLang">\n' + '</template>\n',
 | |
| 
 | |
|     filename: 'example.vue',
 | |
|     sourceMap: true
 | |
|   }).template as SFCBlock
 | |
| 
 | |
|   const result = compileTemplate({
 | |
|     filename: 'example.vue',
 | |
|     source: template.content,
 | |
|     preprocessLang: template.lang
 | |
|   })
 | |
| 
 | |
|   expect(result.errors.length).toBe(1)
 | |
| })
 | |
| 
 | |
| test('transform assetUrls', () => {
 | |
|   const source = `
 | |
| <div>
 | |
|   <img src="./logo.png">
 | |
|   <img src="~fixtures/logo.png">
 | |
|   <img src="~/fixtures/logo.png">
 | |
| </div>
 | |
| `
 | |
|   const result = compileTemplate({
 | |
|     filename: 'example.vue',
 | |
|     source,
 | |
|     transformAssetUrls: true
 | |
|   })
 | |
|   expect(result.errors.length).toBe(0)
 | |
| 
 | |
|   const vnode = mockRender(result.code, {
 | |
|     './logo.png': 'a',
 | |
|     'fixtures/logo.png': 'b'
 | |
|   })
 | |
| 
 | |
|   expect(vnode.children[0].data.attrs.src).toBe('a')
 | |
|   expect(vnode.children[2].data.attrs.src).toBe('b')
 | |
|   expect(vnode.children[4].data.attrs.src).toBe('b')
 | |
| })
 | |
| 
 | |
| test('transform srcset', () => {
 | |
|   const source = `
 | |
| <div>
 | |
|   <img src="./logo.png">
 | |
|   <svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink= "http://www.w3.org/1999/xlink">
 | |
|     <image xlink:href="./logo.png" />
 | |
|   </svg>
 | |
|   <svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink= "http://www.w3.org/1999/xlink">
 | |
|     <use xlink:href="./logo.png"/>
 | |
|   </svg>
 | |
|   </svg>
 | |
|   <img src="./logo.png" srcset="./logo.png">
 | |
|   <img src="./logo.png" srcset="./logo.png 2x">
 | |
|   <img src="./logo.png" srcset="./logo.png, ./logo.png 2x">
 | |
|   <img src="./logo.png" srcset="./logo.png 2x, ./logo.png">
 | |
|   <img src="./logo.png" srcset="./logo.png 2x, ./logo.png 3x">
 | |
|   <img src="./logo.png" srcset="./logo.png, ./logo.png 2x, ./logo.png 3x">
 | |
|   <img
 | |
|     src="./logo.png"
 | |
|     srcset="
 | |
|       ./logo.png 2x,
 | |
|       ./logo.png 3x
 | |
|   ">
 | |
| </div>
 | |
| `
 | |
|   const result = compileTemplate({
 | |
|     filename: 'example.vue',
 | |
|     source,
 | |
|     transformAssetUrls: true
 | |
|   })
 | |
|   expect(result.errors.length).toBe(0)
 | |
| 
 | |
|   const vnode = mockRender(result.code, {
 | |
|     './logo.png': 'test-url'
 | |
|   })
 | |
| 
 | |
|   // img tag
 | |
|   expect(vnode.children[0].data.attrs.src).toBe('test-url')
 | |
|   // image tag (SVG)
 | |
|   expect(vnode.children[2].children[0].data.attrs['xlink:href']).toBe(
 | |
|     'test-url'
 | |
|   )
 | |
|   // use tag (SVG)
 | |
|   expect(vnode.children[4].children[0].data.attrs['xlink:href']).toBe(
 | |
|     'test-url'
 | |
|   )
 | |
| 
 | |
|   // image tag with srcset
 | |
|   expect(vnode.children[6].data.attrs.srcset).toBe('test-url')
 | |
|   expect(vnode.children[8].data.attrs.srcset).toBe('test-url 2x')
 | |
|   // image tag with multiline srcset
 | |
|   expect(vnode.children[10].data.attrs.srcset).toBe('test-url, test-url 2x')
 | |
|   expect(vnode.children[12].data.attrs.srcset).toBe('test-url 2x, test-url')
 | |
|   expect(vnode.children[14].data.attrs.srcset).toBe('test-url 2x, test-url 3x')
 | |
|   expect(vnode.children[16].data.attrs.srcset).toBe(
 | |
|     'test-url, test-url 2x, test-url 3x'
 | |
|   )
 | |
|   expect(vnode.children[18].data.attrs.srcset).toBe('test-url 2x, test-url 3x')
 | |
| })
 | |
| 
 | |
| test('transform assetUrls and srcset with base option', () => {
 | |
|   const source = `
 | |
| <div>
 | |
|   <img src="./logo.png">
 | |
|   <img src="~fixtures/logo.png">
 | |
|   <img src="~/fixtures/logo.png">
 | |
|   <img src="./logo.png" srcset="./logo.png 2x, ./logo.png 3x">
 | |
|   <img src="@/fixtures/logo.png">
 | |
| </div>
 | |
| `
 | |
|   const result = compileTemplate({
 | |
|     filename: 'example.vue',
 | |
|     source,
 | |
|     transformAssetUrls: true,
 | |
|     transformAssetUrlsOptions: { base: '/base/' }
 | |
|   })
 | |
| 
 | |
|   expect(result.errors.length).toBe(0)
 | |
| 
 | |
|   const vnode = mockRender(result.code, {
 | |
|     '@/fixtures/logo.png': 'aliased'
 | |
|   })
 | |
|   expect(vnode.children[0].data.attrs.src).toBe('/base/logo.png')
 | |
|   expect(vnode.children[2].data.attrs.src).toBe('/base/fixtures/logo.png')
 | |
|   expect(vnode.children[4].data.attrs.src).toBe('/base/fixtures/logo.png')
 | |
|   expect(vnode.children[6].data.attrs.srcset).toBe(
 | |
|     '/base/logo.png 2x, /base/logo.png 3x'
 | |
|   )
 | |
|   expect(vnode.children[8].data.attrs.src).toBe('aliased')
 | |
| })
 | |
| 
 | |
| test('transform with includeAbsolute', () => {
 | |
|   const source = `
 | |
|   <div>
 | |
|     <img src="./logo.png">
 | |
|     <img src="/logo.png">
 | |
|     <img src="https://foo.com/logo.png">
 | |
|   </div>
 | |
|   `
 | |
|   const result = compileTemplate({
 | |
|     filename: 'example.vue',
 | |
|     source,
 | |
|     transformAssetUrls: true,
 | |
|     transformAssetUrlsOptions: { includeAbsolute: true }
 | |
|   })
 | |
| 
 | |
|   expect(result.errors.length).toBe(0)
 | |
| 
 | |
|   const vnode = mockRender(result.code, {
 | |
|     './logo.png': 'relative',
 | |
|     '/logo.png': 'absolute'
 | |
|   })
 | |
|   expect(vnode.children[0].data.attrs.src).toBe('relative')
 | |
|   expect(vnode.children[2].data.attrs.src).toBe('absolute')
 | |
|   expect(vnode.children[4].data.attrs.src).toBe('https://foo.com/logo.png')
 | |
| })
 | 
