bare-script 3.2.2 → 3.2.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/include/args.mds +1 -1
- package/lib/include/diff.bare +155 -0
- package/lib/include/pager.mds +1 -1
- package/lib/include/unittest.mds +59 -21
- package/lib/value.js +1 -3
- package/package.json +1 -1
package/lib/include/args.mds
CHANGED
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
# Licensed under the MIT License
|
|
2
|
+
# https://github.com/craigahobbs/markdown-up/blob/main/LICENSE
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
# Include sentinel
|
|
6
|
+
if systemGlobalGet('diffSentinel'):
|
|
7
|
+
return
|
|
8
|
+
endif
|
|
9
|
+
diffSentinel = true
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
# The text line difference model
|
|
13
|
+
diffTypes = schemaParse( \
|
|
14
|
+
'group "diff.bare"', \
|
|
15
|
+
'', \
|
|
16
|
+
'', \
|
|
17
|
+
'# A list of text line differences', \
|
|
18
|
+
'typedef Difference[] Differences', \
|
|
19
|
+
'', \
|
|
20
|
+
'', \
|
|
21
|
+
'# A difference', \
|
|
22
|
+
'struct Difference', \
|
|
23
|
+
'', \
|
|
24
|
+
' # The type of difference', \
|
|
25
|
+
' DifferenceType type', \
|
|
26
|
+
'', \
|
|
27
|
+
' # The text lines of this difference', \
|
|
28
|
+
' string[] lines', \
|
|
29
|
+
'', \
|
|
30
|
+
'', \
|
|
31
|
+
'# A difference type', \
|
|
32
|
+
'enum DifferenceType', \
|
|
33
|
+
'', \
|
|
34
|
+
' # The lines are identical', \
|
|
35
|
+
' Identical', \
|
|
36
|
+
'', \
|
|
37
|
+
' # The lines were added', \
|
|
38
|
+
' Add', \
|
|
39
|
+
'', \
|
|
40
|
+
' # The lines were removed', \
|
|
41
|
+
' Remove' \
|
|
42
|
+
)
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
# $function: diffLines
|
|
46
|
+
# $group: diff.bare
|
|
47
|
+
# $doc: Compute the line-differences of two strings or arrays of strings
|
|
48
|
+
# $arg left: The "left" string or array of strings
|
|
49
|
+
# $arg right: The "right" string or array of strings
|
|
50
|
+
# $return: The array of [difference models](includeModel.html#var.vName='Differences')
|
|
51
|
+
function diffLines(left, right):
|
|
52
|
+
diffs = arrayNew()
|
|
53
|
+
|
|
54
|
+
# Split the left into an array of lines
|
|
55
|
+
if systemType(left) == 'array':
|
|
56
|
+
leftLines = arrayNew()
|
|
57
|
+
for leftPart in left:
|
|
58
|
+
arrayExtend(leftLines, regexSplit(diffRegexLineSplit, leftPart))
|
|
59
|
+
endfor
|
|
60
|
+
else:
|
|
61
|
+
leftLines = regexSplit(diffRegexLineSplit, left)
|
|
62
|
+
endif
|
|
63
|
+
|
|
64
|
+
# Split the right into an array of lines
|
|
65
|
+
if systemType(right) == 'array':
|
|
66
|
+
rightLines = arrayNew()
|
|
67
|
+
for rightPart in right:
|
|
68
|
+
arrayExtend(rightLines, regexSplit(diffRegexLineSplit, rightPart))
|
|
69
|
+
endfor
|
|
70
|
+
else:
|
|
71
|
+
rightLines = regexSplit(diffRegexLineSplit, right)
|
|
72
|
+
endif
|
|
73
|
+
|
|
74
|
+
# Compute the differences
|
|
75
|
+
ixLeft = 0
|
|
76
|
+
ixRight = 0
|
|
77
|
+
leftLength = arrayLength(leftLines)
|
|
78
|
+
rightLength = arrayLength(rightLines)
|
|
79
|
+
while ixLeft < leftLength || ixRight < rightLength:
|
|
80
|
+
# If we've run out of lines on either side
|
|
81
|
+
if ixLeft >= leftLength:
|
|
82
|
+
if ixRight < rightLength:
|
|
83
|
+
arrayPush(diffs, objectNew('type', 'Add', 'lines', arraySlice(rightLines, ixRight)))
|
|
84
|
+
endif
|
|
85
|
+
break
|
|
86
|
+
endif
|
|
87
|
+
if ixRight >= rightLength:
|
|
88
|
+
if ixLeft < leftLength:
|
|
89
|
+
arrayPush(diffs, objectNew('type', 'Remove', 'lines', arraySlice(leftLines, ixLeft)))
|
|
90
|
+
endif
|
|
91
|
+
break
|
|
92
|
+
endif
|
|
93
|
+
|
|
94
|
+
# Find consecutive identical lines
|
|
95
|
+
identicalLines = arrayNew()
|
|
96
|
+
while ixLeft < leftLength && ixRight < rightLength && arrayGet(leftLines, ixLeft) == arrayGet(rightLines, ixRight):
|
|
97
|
+
arrayPush(identicalLines, arrayGet(leftLines, ixLeft))
|
|
98
|
+
ixLeft = ixLeft + 1
|
|
99
|
+
ixRight = ixRight + 1
|
|
100
|
+
endwhile
|
|
101
|
+
if identicalLines:
|
|
102
|
+
arrayPush(objectdiffs, objectNew('type', 'Identical', 'lines', identicalLines))
|
|
103
|
+
continue
|
|
104
|
+
endif
|
|
105
|
+
|
|
106
|
+
# Look ahead to find next matching point
|
|
107
|
+
foundMatch = False
|
|
108
|
+
ixLeftTmp = ixLeft
|
|
109
|
+
while ixLeftTmp < leftLength:
|
|
110
|
+
ixRightTmp = ixRight
|
|
111
|
+
while ixRightTmp < rightLength:
|
|
112
|
+
if arrayGet(leftLines, ixLeftTmp) == arrayGet(rightLines, ixRightTmp):
|
|
113
|
+
foundMatch = true
|
|
114
|
+
break
|
|
115
|
+
endif
|
|
116
|
+
ixRightTmp = ixRightTmp + 1
|
|
117
|
+
endwhile
|
|
118
|
+
if foundMatch:
|
|
119
|
+
break
|
|
120
|
+
endif
|
|
121
|
+
ixLeftTmp = ixLeftTmp + 1
|
|
122
|
+
endwhile
|
|
123
|
+
|
|
124
|
+
# If no match found, use remaining lines
|
|
125
|
+
if !foundMatch:
|
|
126
|
+
if ixLeft < leftLength:
|
|
127
|
+
arrayPush(diffs, objectNew('type', 'Remove', 'lines', arraySlice(leftLines, ixLeft)))
|
|
128
|
+
ixLeft = leftLength
|
|
129
|
+
endif
|
|
130
|
+
if ixRight < rightLength:
|
|
131
|
+
arrayPush(diffs, objectNew('type', 'Add', 'lines', arraySlice(rightLines, ixRight)))
|
|
132
|
+
ixRight = rightLength
|
|
133
|
+
endif
|
|
134
|
+
continue
|
|
135
|
+
endif
|
|
136
|
+
|
|
137
|
+
# Add removed lines if any
|
|
138
|
+
if ixLeftTmp > ixLeft:
|
|
139
|
+
arrayPush(diffs, objectNew('type', 'Remove', 'lines', arraySlice(leftLines, ixLeft, ixLeftTmp)))
|
|
140
|
+
ixLeft = ixLeftTmp
|
|
141
|
+
endif
|
|
142
|
+
|
|
143
|
+
# Add added lines if any
|
|
144
|
+
if ixRightTmp > ixRight:
|
|
145
|
+
arrayPush(diffs, objectNew('type', 'Add', 'lines', arraySlice(rightLines, ixRight, ixRightTmp)))
|
|
146
|
+
ixRight = ixRightTmp
|
|
147
|
+
endif
|
|
148
|
+
endwhile
|
|
149
|
+
|
|
150
|
+
return diffs
|
|
151
|
+
endfunction
|
|
152
|
+
|
|
153
|
+
|
|
154
|
+
# Regex for splitting lines
|
|
155
|
+
diffRegexLineSplit = regexNew(stringFromCharCode(13) + '?' + stringFromCharCode(10))
|
package/lib/include/pager.mds
CHANGED
package/lib/include/unittest.mds
CHANGED
|
@@ -9,6 +9,9 @@ endif
|
|
|
9
9
|
unittestSentinel = true
|
|
10
10
|
|
|
11
11
|
|
|
12
|
+
include 'diff.bare'
|
|
13
|
+
|
|
14
|
+
|
|
12
15
|
# Test statistics
|
|
13
16
|
unittestTests = objectNew()
|
|
14
17
|
unittestWarnings = arrayNew()
|
|
@@ -116,7 +119,7 @@ function unittestReport():
|
|
|
116
119
|
arrayPush(failureLines, '')
|
|
117
120
|
arrayPush(failureLines, '- ' + errorLine)
|
|
118
121
|
else:
|
|
119
|
-
arrayPush(failureLines, ' ' + errorLine)
|
|
122
|
+
arrayPush(failureLines, if(errorLine, ' ' + errorLine, ''))
|
|
120
123
|
endif
|
|
121
124
|
endfor
|
|
122
125
|
endfor
|
|
@@ -148,8 +151,27 @@ endfunction
|
|
|
148
151
|
# $arg expected: The expected value
|
|
149
152
|
# $arg description: The description of the assertion
|
|
150
153
|
function unittestEqual(actual, expected, description):
|
|
151
|
-
if actual
|
|
152
|
-
|
|
154
|
+
if actual == expected:
|
|
155
|
+
return
|
|
156
|
+
endif
|
|
157
|
+
|
|
158
|
+
# Add the test failure error lines
|
|
159
|
+
testFailures = objectGet(unittestTests, unittestTestName)
|
|
160
|
+
errorLines = arrayNew( \
|
|
161
|
+
'Equal:', \
|
|
162
|
+
'', \
|
|
163
|
+
'```', \
|
|
164
|
+
jsonStringify(actual), \
|
|
165
|
+
'```', \
|
|
166
|
+
'', \
|
|
167
|
+
'```', \
|
|
168
|
+
jsonStringify(expected), \
|
|
169
|
+
'```' \
|
|
170
|
+
)
|
|
171
|
+
if description != null:
|
|
172
|
+
arrayPush(testFailures, arrayExtend(arrayNew(markdownEscape(description), errorLines)))
|
|
173
|
+
else:
|
|
174
|
+
arrayPush(testFailures, errorLines)
|
|
153
175
|
endif
|
|
154
176
|
endfunction
|
|
155
177
|
|
|
@@ -161,28 +183,44 @@ endfunction
|
|
|
161
183
|
# $arg expected: The expected value
|
|
162
184
|
# $arg description: The description of the assertion
|
|
163
185
|
function unittestDeepEqual(actual, expected, description):
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
if
|
|
167
|
-
|
|
186
|
+
# Serialize as JSON
|
|
187
|
+
actualJSON = if(systemType(actual) == 'string', actual, jsonStringify(actual, 4))
|
|
188
|
+
expectedJSON = if(systemType(expected) == 'string', expected, jsonStringify(expected, 4))
|
|
189
|
+
if actualJSON == expectedJSON:
|
|
190
|
+
return
|
|
168
191
|
endif
|
|
169
|
-
endfunction
|
|
170
192
|
|
|
193
|
+
# Compute the difference lines
|
|
194
|
+
errorLines = arrayNew()
|
|
195
|
+
diffErrorLines = arrayNew()
|
|
196
|
+
for diff in diffLines(actualJSON, expectedJSON):
|
|
197
|
+
diffType = objectGet(diff, 'type')
|
|
198
|
+
if diffType == 'Remove':
|
|
199
|
+
for diffLine in objectGet(diff, 'lines'):
|
|
200
|
+
arrayPush(diffErrorLines, '--- ' + diffLine)
|
|
201
|
+
endfor
|
|
202
|
+
elif diffType == 'Add':
|
|
203
|
+
for diffLine in objectGet(diff, 'lines'):
|
|
204
|
+
arrayPush(diffErrorLines, '+++ ' + diffLine)
|
|
205
|
+
endfor
|
|
206
|
+
else:
|
|
207
|
+
# diffType == 'Identical'
|
|
208
|
+
if diffErrorLines:
|
|
209
|
+
arrayExtend(errorLines, arrayNew('Deep-equal:', '', '```'))
|
|
210
|
+
arrayExtend(errorLines, diffErrorLines)
|
|
211
|
+
arrayPush(errorLines, '```')
|
|
212
|
+
diffErrorLines = arrayNew()
|
|
213
|
+
endif
|
|
214
|
+
endif
|
|
215
|
+
endfor
|
|
216
|
+
if diffErrorLines:
|
|
217
|
+
arrayExtend(errorLines, arrayNew('Deep-equal:', '', '```'))
|
|
218
|
+
arrayExtend(errorLines, diffErrorLines)
|
|
219
|
+
arrayPush(errorLines, '```')
|
|
220
|
+
endif
|
|
171
221
|
|
|
172
|
-
#
|
|
173
|
-
function unittestRecordError(actualStr, expectedStr, description):
|
|
222
|
+
# Add the test failure error lines
|
|
174
223
|
testFailures = objectGet(unittestTests, unittestTestName)
|
|
175
|
-
errorLines = arrayNew( \
|
|
176
|
-
'~~~', \
|
|
177
|
-
actualStr, \
|
|
178
|
-
'~~~', \
|
|
179
|
-
'', \
|
|
180
|
-
'!=', \
|
|
181
|
-
'', \
|
|
182
|
-
'~~~', \
|
|
183
|
-
expectedStr, \
|
|
184
|
-
'~~~' \
|
|
185
|
-
)
|
|
186
224
|
if description != null:
|
|
187
225
|
arrayPush(testFailures, arrayExtend(arrayNew(markdownEscape(description), errorLines)))
|
|
188
226
|
else:
|
package/lib/value.js
CHANGED
|
@@ -206,8 +206,7 @@ export function valueCompare(left, right) {
|
|
|
206
206
|
const leftKeyValues = Object.entries(left).sort((kv1, kv2) => kv1[0] < kv2[0] ? -1 : 1);
|
|
207
207
|
const rightKeyValues = Object.entries(right).sort((kv1, kv2) => kv1[0] < kv2[0] ? -1 : 1);
|
|
208
208
|
const ixMax = Math.min(leftKeyValues.length, rightKeyValues.length);
|
|
209
|
-
let ix = 0;
|
|
210
|
-
while (ix < ixMax) {
|
|
209
|
+
for (let ix = 0; ix < ixMax; ix++) {
|
|
211
210
|
const keyCompare = valueCompare(leftKeyValues[ix][0], rightKeyValues[ix][0]);
|
|
212
211
|
if (keyCompare !== 0) {
|
|
213
212
|
return keyCompare;
|
|
@@ -216,7 +215,6 @@ export function valueCompare(left, right) {
|
|
|
216
215
|
if (valCompare !== 0) {
|
|
217
216
|
return valCompare;
|
|
218
217
|
}
|
|
219
|
-
ix += 1;
|
|
220
218
|
}
|
|
221
219
|
return leftKeyValues.length < rightKeyValues.length ? -1 : (leftKeyValues.length === rightKeyValues.length ? 0 : 1);
|
|
222
220
|
}
|