Skip to content

Commit c452f8a

Browse files
committed
chore: increase test coverage
1 parent 5c330df commit c452f8a

32 files changed

Lines changed: 434 additions & 430 deletions

packages/template/src/compiler.test.ts

Lines changed: 35 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import { compile } from '../test/__helper'
44
describe('stripComments', async () => {
55
it('on', async () => {
66
expect(await compile('{{! this is a comment }}')).toMatchInlineSnapshot(
7-
'""use strict";return(async()=>{let s="";s+="<!--this is a comment-->";return s;})();"',
7+
`""use strict";return(async()=>{let s="";s+="<!--this is a comment-->";return s;})();"`,
88
)
99
})
1010

@@ -14,15 +14,15 @@ describe('stripComments', async () => {
1414
stripComments: false,
1515
}),
1616
).toMatchInlineSnapshot(
17-
'""use strict";return(async()=>{let s="";s+="<!--this is a comment-->";return s;})();"',
17+
`""use strict";return(async()=>{let s="";s+="<!--this is a comment-->";return s;})();"`,
1818
)
1919
})
2020
})
2121

2222
describe('strictMode', async () => {
2323
it('on', async () => {
2424
expect(await compile('')).toMatchInlineSnapshot(
25-
'""use strict";return(async()=>{let s="";return s;})();"',
25+
`""use strict";return(async()=>{let s="";return s;})();"`,
2626
)
2727
})
2828

@@ -31,66 +31,78 @@ describe('strictMode', async () => {
3131
await compile('', {
3232
strictMode: false,
3333
}),
34-
).toMatchInlineSnapshot('"return(async()=>{let s="";return s;})();"')
34+
).toMatchInlineSnapshot(`"return(async()=>{let s="";return s;})();"`)
3535
})
3636
})
3737

3838
it('empty', async () => {
3939
expect(await compile('')).toMatchInlineSnapshot(
40-
'""use strict";return(async()=>{let s="";return s;})();"',
40+
`""use strict";return(async()=>{let s="";return s;})();"`,
4141
)
4242
})
4343

4444
it('html tags', async () => {
4545
expect(await compile('<foo>foo</foo>')).toMatchInlineSnapshot(
46-
'""use strict";return(async()=>{let s="";s+="<foo>foo</foo>";return s;})();"',
46+
`""use strict";return(async()=>{let s="";s+="<foo>foo</foo>";return s;})();"`,
4747
)
4848
})
4949

5050
it('quotes', async () => {
5151
expect(await compile('"\'foo\'"')).toMatchInlineSnapshot(
52-
'""use strict";return(async()=>{let s="";s+="\\"\'foo\'\\"";return s;})();"',
52+
`""use strict";return(async()=>{let s="";s+="\\"'foo'\\"";return s;})();"`,
5353
)
5454
})
5555

5656
it('line break feed', async () => {
5757
expect(await compile('\nfoo\n')).toMatchInlineSnapshot(
58-
'""use strict";return(async()=>{let s="";s+="\\nfoo\\n";return s;})();"',
58+
`""use strict";return(async()=>{let s="";s+="\\nfoo\\n";return s;})();"`,
5959
)
6060
})
6161

6262
it('translate', async () => {
6363
expect(
6464
await compile('{{ "hello, {name}" | t name="JianJia" }}'),
6565
).toMatchInlineSnapshot(
66-
'""use strict";return(async()=>{let s="";return s;})();"',
67-
)
68-
})
69-
70-
it('invalid', async () => {
71-
expect(await compile('{{ /if }}', { debug: true })).toMatchInlineSnapshot(
72-
`
73-
" JianJia Unexpected /if
74-
75-
{{ /if }}
76-
77-
0:9"
78-
`,
66+
`""use strict";return(async()=>{let s="";return s;})();"`,
7967
)
8068
})
8169

8270
it('if/elif/else', async () => {
8371
expect((await compile(
8472
'{{ #if x }}x{{ elif y }}y{{ else }}z{{ /if }}',
8573
))).toMatchInlineSnapshot(
86-
'""use strict";return(async()=>{let s="";if(c.x){s+="x";}else if(c.y){s+="y";}else{s+="z";}return s;})();"',
74+
`""use strict";return(async()=>{let s="";if(c.x){s+="x";}else if(c.y){s+="y";}else{s+="z";}return s;})();"`,
8775
)
8876
})
8977

9078
it('if/elif/else nested', async () => {
9179
expect((await compile(
9280
'{{ #if x }}{{ #if x }}x{{ elif y }}y{{ else }}z{{ /if }}{{ elif y }}{{ #if x }}x{{ elif y }}y{{ else }}z{{ /if }}{{ else }}{{ #if x }}x{{ elif y }}y{{ else }}z{{ /if }}{{ /if }}',
9381
))).toMatchInlineSnapshot(
94-
'""use strict";return(async()=>{let s="";if(c.x){if(c.x){s+="x";}else if(c.y){s+="y";}else{s+="z";}}else if(c.y){if(c.x){s+="x";}else if(c.y){s+="y";}else{s+="z";}}else{if(c.x){s+="x";}else if(c.y){s+="y";}else{s+="z";}}return s;})();"',
82+
`""use strict";return(async()=>{let s="";if(c.x){if(c.x){s+="x";}else if(c.y){s+="y";}else{s+="z";}}else if(c.y){if(c.x){s+="x";}else if(c.y){s+="y";}else{s+="z";}}else{if(c.x){s+="x";}else if(c.y){s+="y";}else{s+="z";}}return s;})();"`,
83+
)
84+
})
85+
86+
it('invalid', async () => {
87+
expect(await compile('{{ if }}', { debug: true })).toMatchInlineSnapshot(
88+
`
89+
" JianJia if tag must have a value
90+
91+
{{ if }}
92+
93+
0:8"
94+
`,
95+
)
96+
expect(await compile('{{ if x }}', { debug: true })).toMatchInlineSnapshot(
97+
`"expected tokens end_if, endif, /if, but got nothing"`,
98+
)
99+
expect(await compile('{{ /if }}', { debug: true })).toMatchInlineSnapshot(
100+
`
101+
" JianJia Unexpected /if
102+
103+
{{ /if }}
104+
105+
0:9"
106+
`,
95107
)
96108
})

packages/template/src/compiler.ts

Lines changed: 4 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
1-
import type { EngineOptions, Script, Token } from './types'
1+
import type { Config, Token } from './types'
22
import { CompileError } from './compile-error'
33
import { Context } from './context'
44
import { OutScript } from './out-script'
55
import { SourceMap } from './source-map'
66
import { Validator } from './validator'
77

88
export class Compiler {
9-
constructor(public options: Required<EngineOptions>) {}
9+
constructor(public options: Required<Config>) {}
1010

1111
async compile(token: Token | null, filepath?: string) {
1212
const ctx = new Context(this.options)
@@ -41,27 +41,14 @@ export class Compiler {
4141
}
4242
}
4343
catch (error: any) {
44-
if (this.options.debug) {
45-
throw new CompileError(error.message, token, filepath)
46-
}
47-
48-
return { value: '', script: (async () => 'invalid template') as unknown as Script, sourcemap }
44+
throw new CompileError(error.message, token, filepath)
4945
}
5046
}
5147

5248
token = token.next
5349
}
5450

55-
try {
56-
validator.validate()
57-
}
58-
catch (error: any) {
59-
if (this.options.debug) {
60-
throw error
61-
}
62-
63-
return { value: '', script: (async () => 'invalid template') as unknown as Script, sourcemap }
64-
}
51+
validator.validate()
6552

6653
out.end()
6754

packages/template/src/config.ts

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,24 @@
1+
import type { Config } from './types'
2+
import * as filters from './filters'
3+
import { loader } from './loaders/url-loader'
4+
import { tags } from './tags'
5+
16
export const CONTEXT = 'c'
27
export const FILTERS = 'f' // Filters can be async
38
export const ESCAPE = 'e'
49
export const HELPERS = 'h'
10+
11+
export const config: Required<Config> = {
12+
debug: false,
13+
globals: {
14+
translations: {},
15+
},
16+
filters: { ...filters },
17+
tags: { ...tags },
18+
autoEscape: true,
19+
strictMode: true,
20+
stripComments: false,
21+
trimWhitespace: false,
22+
loader,
23+
cache: false,
24+
}

packages/template/src/context.test.ts

Lines changed: 14 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,30 @@
11
import { describe, expect, it } from 'vitest'
2-
import { CONTEXT } from './config'
2+
import { config, CONTEXT } from './config'
33
import { Context } from './context'
4-
import { defaultOptions } from './engine'
54

65
describe('context', () => {
76
it('should initialize with default context', () => {
8-
const context = new Context(defaultOptions)
7+
const context = new Context(config)
98
expect(context.context).toBe(CONTEXT)
109
})
1110

1211
describe('affix', () => {
1312
it('should affix string to context', () => {
14-
const context = new Context(defaultOptions)
13+
const context = new Context(config)
1514
const result = context.affix('test')
1615
expect(result).toBe('c_test')
1716
expect(context.context).toBe('c_test')
1817
})
1918

2019
it('should affix number to context', () => {
21-
const context = new Context(defaultOptions)
20+
const context = new Context(config)
2221
const result = context.affix(123)
2322
expect(result).toBe('c_123')
2423
expect(context.context).toBe('c_123')
2524
})
2625

2726
it('should support multiple affixes', () => {
28-
const context = new Context(defaultOptions)
27+
const context = new Context(config)
2928

3029
context.affix('first')
3130
expect(context.context).toBe('c_first')
@@ -38,7 +37,7 @@ describe('context', () => {
3837
})
3938

4039
it('should return the new context value', () => {
41-
const context = new Context(defaultOptions)
40+
const context = new Context(config)
4241
const result1 = context.affix('alpha')
4342
const result2 = context.affix('beta')
4443

@@ -50,7 +49,7 @@ describe('context', () => {
5049

5150
describe('reset', () => {
5251
it('should reset to previous context after single affix', () => {
53-
const context = new Context(defaultOptions)
52+
const context = new Context(config)
5453

5554
context.affix('temp')
5655
expect(context.context).toBe('c_temp')
@@ -60,7 +59,7 @@ describe('context', () => {
6059
})
6160

6261
it('should reset to previous context after multiple affixes', () => {
63-
const context = new Context(defaultOptions)
62+
const context = new Context(config)
6463

6564
context.affix('first')
6665
context.affix('second')
@@ -78,7 +77,7 @@ describe('context', () => {
7877
})
7978

8079
it('should handle reset on base context gracefully', () => {
81-
const context = new Context(defaultOptions)
80+
const context = new Context(config)
8281
expect(context.context).toBe('c')
8382

8483
context.reset()
@@ -88,7 +87,7 @@ describe('context', () => {
8887

8988
describe('nested operations', () => {
9089
it('should handle complex affix and reset patterns', () => {
91-
const context = new Context(defaultOptions)
90+
const context = new Context(config)
9291

9392
// Build nested context
9493
context.affix('1')
@@ -111,7 +110,7 @@ describe('context', () => {
111110
})
112111

113112
it('should maintain context stack integrity', () => {
114-
const context = new Context(defaultOptions)
113+
const context = new Context(config)
115114

116115
// Create multiple contexts
117116
const contexts = ['a', 'b', 'c', 'd', 'e']
@@ -130,21 +129,21 @@ describe('context', () => {
130129

131130
describe('edge cases', () => {
132131
it('should handle empty string affix', () => {
133-
const context = new Context(defaultOptions)
132+
const context = new Context(config)
134133
const result = context.affix('')
135134
expect(result).toBe('c_')
136135
expect(context.context).toBe('c_')
137136
})
138137

139138
it('should handle zero as affix', () => {
140-
const context = new Context(defaultOptions)
139+
const context = new Context(config)
141140
const result = context.affix(0)
142141
expect(result).toBe('c_0')
143142
expect(context.context).toBe('c_0')
144143
})
145144

146145
it('should handle special characters in affix', () => {
147-
const context = new Context(defaultOptions)
146+
const context = new Context(config)
148147
const result = context.affix('test-name.property[0]')
149148
expect(result).toBe('c_test-name.property[0]')
150149
expect(context.context).toBe('c_test-name.property[0]')

packages/template/src/context.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
1-
import type { EngineOptions } from './types'
1+
import type { Config } from './types'
22
import { CONTEXT } from './config'
33

44
export class Context {
55
context = CONTEXT
66

77
private contexts: string[] = [CONTEXT]
88

9-
constructor(public options: Required<EngineOptions>) {}
9+
constructor(public options: Required<Config>) {}
1010

1111
affix(affix: string | number) {
1212
const len = this.contexts.push(`${this.context}_${affix}`)

packages/template/src/engine.test.ts

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { describe, expect, it } from 'vitest'
2-
import { compile, render } from '../test/__helper'
2+
import { render } from '../test/__helper'
33
import { loader } from './loaders/file-loader'
44

55
describe('autoEscape', async () => {
@@ -203,18 +203,20 @@ it('custom tag', async () => {
203203
).toMatchInlineSnapshot('"CUSTOM"')
204204
})
205205

206-
it('compile error', async () => {
207-
expect(await compile('{{ #for name in names }}{{ /if }}', { debug: true }))
206+
it('invalid', async () => {
207+
expect(await render('{{ #for name in names }}{{ /if }}', {}))
208+
.toMatchInlineSnapshot(`"compile error"`)
209+
expect(await render('{{ #for name in names }}{{ /if }}', {}, { debug: true }))
208210
.toMatchInlineSnapshot(`
209211
" JianJia Unexpected /if
210212
211213
{{ /if }}
212214
213215
24:33"
214216
`)
215-
})
216-
217-
it('render error', async () => {
217+
expect(
218+
await render('{{ #for name in names }}{{ /for }}', {}),
219+
).toMatchInlineSnapshot(`"render error"`)
218220
expect(
219221
await render('{{ #for name in names }}{{ /for }}', {}, { debug: true }),
220222
).toMatchInlineSnapshot(`

0 commit comments

Comments
 (0)