Skip to content

Commit c0d7c6d

Browse files
committed
chore: updated unit test
1 parent 58487a4 commit c0d7c6d

File tree

12 files changed

+294
-101
lines changed

12 files changed

+294
-101
lines changed

packages/core/inject/inject-css.ts

Lines changed: 12 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,38 +1,37 @@
11
import hash from 'hash-sum'
22
import { transformInjectCSS } from '../transform/transform-inject-css'
3-
import {parseCssVars, parseImports} from '../parser'
3+
import { parseCssVars, parseImports } from '../parser'
44
import type { MagicStringBase } from 'magic-string-ast'
55
import type { TInjectCSSContent } from '../runtime/process-css'
66
import type { SFCDescriptor } from '@vue/compiler-sfc'
77
import type { TMatchVariable } from '../parser'
88
declare type PCSSVARARR = Array<{
9-
start: number,
10-
end: number,
11-
offset: number,
12-
variable: string}>
9+
start: number
10+
end: number
11+
offset: number
12+
variable: string }>
1313
export function injectCSSOnServer(
1414
mgcStr: MagicStringBase,
1515
vbindVariableList: TMatchVariable | undefined,
1616
isHMR: boolean,
1717
) {
18-
19-
const pCssVarsArr:PCSSVARARR = []
18+
const pCssVarsArr: PCSSVARARR = []
2019
parseCssVars([mgcStr.toString()], {
2120
getIndex(start: number, end: number, offset, variable) {
22-
pCssVarsArr.push({start, end, offset, variable})
23-
}
21+
pCssVarsArr.push({ start, end, offset, variable })
22+
},
2423
})
2524

26-
pCssVarsArr.forEach(pca => {
27-
if(vbindVariableList){
25+
pCssVarsArr.forEach((pca) => {
26+
if (vbindVariableList) {
2827
for (let i = 0; i < vbindVariableList.length; i++) {
2928
const vbVar = vbindVariableList[i]
3029
// 样式文件修改后,style热更新可能会先于 sfc 热更新运行,这里先设置hash
3130
// 详见 packages/core/index.ts的 handleHotUpdate
3231
if (!vbVar.hash && isHMR)
3332
vbVar.hash = hash(vbVar.value + vbVar.has)
3433

35-
if(vbVar.value === pca.variable){
34+
if (vbVar.value === pca.variable) {
3635
const offset = pca.offset
3736
const start = pca.start + offset
3837
const end = pca.end + offset
@@ -43,7 +42,7 @@ export function injectCSSOnServer(
4342
}
4443
})
4544

46-
mgcStr = mgcStr.replace(/v-bind-m\s*\(/g, "var(");
45+
mgcStr = mgcStr.replace(/v-bind-m\s*\(/g, 'var(')
4746
return mgcStr
4847
}
4948

packages/core/inject/inject-cssvars.ts

Lines changed: 21 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
import hash from 'hash-sum'
22
import { type MagicStringBase } from 'magic-string-ast'
33
import { ts } from '@ast-grep/napi'
4-
import type { SgNode } from '@ast-grep/napi'
54
import MagicString from 'magic-string'
5+
import { BindingTypes } from '@vue/compiler-dom'
6+
import { CSSVarsBindingTypes } from '../parser/utils'
7+
import type { BindingMetadata } from '@vue/compiler-dom'
68
import type { IParseSFCRes, TMatchVariable } from '../parser'
7-
import {BindingMetadata, BindingTypes} from "@vue/compiler-dom";
8-
import {CSSVarsBindingTypes} from "../parser/utils";
9+
import type { SgNode } from '@ast-grep/napi'
910

1011
const importer = 'import { useCssVars as _useCssVars } from "vue"\n'
1112
const importerUnref = 'import { unref as _unref } from "vue"\n'
@@ -31,7 +32,7 @@ export const injectCSSVars = (
3132
isScriptSetup: boolean,
3233
parserRes: IParseSFCRes,
3334
mgcStr: MagicStringBase,
34-
bindings?: BindingMetadata
35+
bindings?: BindingMetadata,
3536
) => {
3637
if (!vbindVariableList || vbindVariableList.length === 0) return { vbindVariableList, mgcStr }
3738
return injectCSSVarsOnServer(vbindVariableList, isScriptSetup, parserRes, mgcStr, bindings)
@@ -52,7 +53,7 @@ export function injectCSSVarsOnServer(
5253
isScriptSetup: boolean,
5354
parserRes: IParseSFCRes,
5455
mgcStr: MagicStringBase,
55-
bindings?: BindingMetadata
56+
bindings?: BindingMetadata,
5657
) {
5758
let resMgcStr = mgcStr
5859
const hasUseCssVars = parserRes.hasCSSVars
@@ -89,9 +90,8 @@ export function injectUseCssVarsSetup(
8990
parserRes: IParseSFCRes,
9091
) {
9192
let resMgcStr = mgcStr
92-
if(!resMgcStr.toString().includes('_unref')){
93+
if (!resMgcStr.toString().includes('_unref'))
9394
resMgcStr = resMgcStr.prependLeft(0, importerUnref)
94-
}
9595

9696
if (parserRes) {
9797
if (!hasUseCssVars
@@ -118,19 +118,18 @@ export function injectUseCssVarsOption(
118118
parserRes: IParseSFCRes,
119119
) {
120120
let resMgcStr = mgcStr
121-
if(!resMgcStr.toString().includes('_unref')){
121+
if (!resMgcStr.toString().includes('_unref'))
122122
resMgcStr = resMgcStr.prependLeft(0, importerUnref)
123-
}
123+
124124
if (!hasUseCssVars) {
125-
if(resMgcStr.toString().includes('const _sfc_main')){
125+
if (resMgcStr.toString().includes('const _sfc_main'))
126126
resMgcStr = resMgcStr.replaceAll('const _sfc_main', 'const __default__')
127-
} else if(resMgcStr.toString().includes('import _sfc_main')){
127+
else if (resMgcStr.toString().includes('import _sfc_main'))
128128
resMgcStr = resMgcStr.replaceAll('import _sfc_main', 'import __default__')
129-
} else {
129+
else
130130
resMgcStr = resMgcStr.replaceAll('export default {', 'const __default__ = {')
131-
}
132131

133-
if(resMgcStr.toString().includes('function _sfc_render')){
132+
if (resMgcStr.toString().includes('function _sfc_render')) {
134133
resMgcStr = resMgcStr.replaceAll(
135134
'function _sfc_render',
136135
`${useCssVars}\n
@@ -140,7 +139,7 @@ export function injectUseCssVarsOption(
140139
: __injectCSSVars__
141140
const _sfc_main = __default__
142141
function _sfc_render`)
143-
} else if(resMgcStr.toString().includes('const __default__')){
142+
} else if (resMgcStr.toString().includes('const __default__')) {
144143
resMgcStr = resMgcStr.prependRight(
145144
resMgcStr.length(),
146145
`${useCssVars}\n
@@ -167,7 +166,7 @@ export function createCSSVarsObjCode(
167166
vbindVariableList: TMatchVariable,
168167
isScriptSetup: boolean,
169168
mgcStr?: MagicStringBase,
170-
bindings?: BindingMetadata
169+
bindings?: BindingMetadata,
171170
) {
172171
let resCode = ''
173172
vbindVariableList.forEach((vbVar) => {
@@ -185,9 +184,9 @@ export function createCSSVarsObjCode(
185184
range.start.index,
186185
range.end.index,
187186
// non-inline composition api 和 option api 一直帶 _ctx
188-
!isScriptSetup ?
189-
`(_ctx.${node.text()})` :
190-
genCSSVarsValue(node, bindings),
187+
!isScriptSetup
188+
? `(_ctx.${node.text()})`
189+
: genCSSVarsValue(node, bindings),
191190
)
192191
})
193192
varStr = ms.toString()
@@ -235,11 +234,11 @@ export function createUseCssVarsCode(
235234
// TODO unit test
236235
function genCSSVarsValue(
237236
node: SgNode,
238-
bindings?: BindingMetadata){
237+
bindings?: BindingMetadata) {
239238
let res = `_ctx.${node.text()}`
240-
if(bindings){
239+
if (bindings) {
241240
const binding = bindings[node.text()]
242-
switch (binding){
241+
switch (binding) {
243242
case CSSVarsBindingTypes.PROPS:
244243
case CSSVarsBindingTypes.SETUP_CONST:
245244
case CSSVarsBindingTypes.SETUP_REACTIVE_CONST:
Lines changed: 188 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,188 @@
1+
import { describe, expect, test } from 'vitest'
2+
import { parse } from '@vue/compiler-sfc'
3+
import { getObjectExpressionReturnNode } from '../parser-variable'
4+
import { analyzeScriptBindings } from '../parser-script-bindings'
5+
6+
describe('parse sfc to set bindings type', () => {
7+
test('ref', () => {
8+
const mockSFC = `
9+
<script lang="ts" setup>
10+
const color = ref('red')
11+
let foo = ref('foo')
12+
</script>
13+
`
14+
const { descriptor } = parse(mockSFC)
15+
const bindings = analyzeScriptBindings(descriptor)
16+
expect(bindings).toMatchObject({
17+
color: 'setup-ref',
18+
foo: 'setup-let',
19+
})
20+
})
21+
22+
test('reactive', () => {
23+
const mockSFC = `
24+
<script lang="ts" setup>
25+
const color = reactive({ color: 'red' })
26+
let foo = reactive({ foo: 'foo' })
27+
</script>
28+
`
29+
const { descriptor } = parse(mockSFC)
30+
const bindings = analyzeScriptBindings(descriptor)
31+
expect(bindings).toMatchObject({
32+
color: 'setup-reactive-const',
33+
foo: 'setup-let',
34+
})
35+
})
36+
37+
test('normal variable', () => {
38+
const mockSFC = `
39+
<script lang="ts" setup>
40+
const head2 = new Map()
41+
const color = 'red'
42+
const foo = { foo: 'foo' }
43+
const bar = 100
44+
const head = [1]
45+
46+
let color1 = 'red'
47+
let foo1 = { foo: 'foo' }
48+
let bar1 = 100
49+
let head1 = [1]
50+
</script>
51+
`
52+
const { descriptor } = parse(mockSFC)
53+
const bindings = analyzeScriptBindings(descriptor)
54+
expect(bindings).toMatchObject({
55+
color: 'literal-const',
56+
foo: 'setup-const',
57+
bar: 'literal-const',
58+
head: "setup-const",
59+
color1: 'setup-let',
60+
foo1: 'setup-let',
61+
bar1: 'setup-let',
62+
head1: 'setup-let',
63+
head2: "setup-maybe-ref",
64+
})
65+
})
66+
67+
test('define function', () => {
68+
const mockSFC = `
69+
<script lang="ts" setup>
70+
const fn = () => {}
71+
const fn2 = function (){}
72+
function fn3(){}
73+
74+
let fn4 = () => {}
75+
let fn5 = function (){}
76+
</script>
77+
`
78+
const { descriptor } = parse(mockSFC)
79+
const bindings = analyzeScriptBindings(descriptor)
80+
expect(bindings).toMatchObject({
81+
fn: 'setup-const',
82+
fn2: 'setup-const',
83+
fn3: 'setup-const',
84+
fn4: 'setup-let',
85+
fn5: 'setup-let',
86+
})
87+
})
88+
89+
test('function call', () => {
90+
const mockSFC = `
91+
<script lang="ts" setup>
92+
const fn = () => {}
93+
const fn2 = fn()
94+
95+
let fn4 = () => {}
96+
let fn5 = fn4()
97+
</script>
98+
`
99+
const { descriptor } = parse(mockSFC)
100+
const bindings = analyzeScriptBindings(descriptor)
101+
expect(bindings).toMatchObject({
102+
fn: 'setup-const',
103+
fn2: 'setup-maybe-ref',
104+
fn4: 'setup-let',
105+
fn5: 'setup-let',
106+
})
107+
})
108+
109+
test('Object deconstruct', () => {
110+
const mockSFC = `
111+
<script lang="ts" setup>
112+
const {foo: fooAlias, bar, head: {heads: hh} } = a
113+
</script>
114+
`
115+
const { descriptor } = parse(mockSFC)
116+
const bindings = analyzeScriptBindings(descriptor)
117+
expect(bindings).toMatchObject({
118+
"fooAlias": "setup-maybe-ref",
119+
"bar": "setup-maybe-ref",
120+
"hh": "setup-maybe-ref"
121+
})
122+
})
123+
124+
test('define props', () => {
125+
const mockSFC = `
126+
<script lang="ts" setup>
127+
const props = defineProps(
128+
{
129+
color: {
130+
type: String
131+
}
132+
}
133+
)
134+
</script>
135+
`
136+
const { descriptor } = parse(mockSFC)
137+
const bindings = analyzeScriptBindings(descriptor)
138+
expect(bindings).toMatchObject({
139+
color: 'props',
140+
props: 'setup-reactive-const',
141+
})
142+
})
143+
144+
test('define props & default value', () => {
145+
const mockSFC = `
146+
<script lang="ts" setup>
147+
interface Props {
148+
msg?: string
149+
labels?: string[]
150+
}
151+
const propsAlias = withDefaults(defineProps<Props>(), {
152+
msg: 'hello',
153+
labels: () => ['one', 'two'],
154+
});
155+
</script>
156+
`
157+
const { descriptor } = parse(mockSFC)
158+
const bindings = analyzeScriptBindings(descriptor)
159+
expect(bindings).toMatchObject({
160+
propsAlias: 'setup-const',
161+
msg: 'props',
162+
labels: 'props',
163+
})
164+
})
165+
166+
test('define props & default value & deconstruct', () => {
167+
const mockSFC = `
168+
<script lang="ts" setup>
169+
interface Props {
170+
msg?: string
171+
labels?: string[]
172+
}
173+
const propsAlias = withDefaults(defineProps<Props>(), {
174+
msg: 'hello',
175+
labels: () => ['one', 'two'],
176+
});
177+
const { msg, labels } = propsAlias
178+
</script>
179+
`
180+
const { descriptor } = parse(mockSFC)
181+
const bindings = analyzeScriptBindings(descriptor)
182+
expect(bindings).toMatchObject({
183+
propsAlias: 'setup-const',
184+
msg: 'setup-maybe-ref',
185+
labels: 'setup-maybe-ref',
186+
})
187+
})
188+
})

0 commit comments

Comments
 (0)