-
Notifications
You must be signed in to change notification settings - Fork 20
/
case.ts
69 lines (62 loc) · 1.92 KB
/
case.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
/**
* san ssr 测试样例工具,包括:
*
* - 数据部分的提取
* - HTML 部分的判等
* - 顺序无关的数据对象比较
*/
import debugFactory from 'debug'
const debug = debugFactory('case')
export function parseSanHTML (str: string) {
const begin = str.indexOf('<!--s-data:')
let data = {}
let html = str
if (begin !== -1) {
const end = str.indexOf('-->', begin)
if (end !== -1) {
// eslint-disable-next-line no-new-func
data = (new Function('return ' + str.slice(begin + 11, end)))()
html = str.slice(0, begin) + str.slice(end + 3)
}
}
return [data, html]
}
export function assertSanHTMLEqual (expected: string, got: string) {
const result = compareSanHTML(expected, got)
if (result) {
throw new Error(result)
}
}
export function assertDeepEqual (lhs: any, rhs: any) {
if (!deepEqual(lhs, rhs)) {
const msg = `San Data not equal, Expected:\n${JSON.stringify(lhs)}\nReceived\n${JSON.stringify(rhs)}`
throw new Error(msg)
}
}
/**
* San HTML 数据和 DOM 部分比较(不依赖 Object key 顺序)
*
* @returns 相等时返回空(undefined),不相等时返回信息(比如 "data not equal")
*/
export function compareSanHTML (expected: string, got: string) {
const [data0, html0] = parseSanHTML(expected)
const [data1, html1] = parseSanHTML(got)
if (!deepEqual(data0, data1)) {
return 'data not equal'
}
if (html0 !== html1) {
return 'html not equal'
}
}
export function deepEqual (lhs: any, rhs: any) {
if (!isObject(lhs)) return lhs === rhs
if (!isObject(rhs)) return false
const keys = new Set([...Object.keys(lhs), ...Object.keys(rhs)])
for (const key of keys) {
if (!deepEqual(lhs[key], rhs[key])) return false
}
return true
}
function isObject (val: any) {
return typeof val === 'object' && val !== null
}