@@ -64,24 +64,27 @@ module.exports = {
64
64
// the first language is the main language to highlight
65
65
const simplifiedTokenStream = this . simpleTokenize ( Prism , testCase . testSource , usedLanguages . mainLanguage ) ;
66
66
67
- const tzd = JSON . stringify ( simplifiedTokenStream ) ;
68
- const exp = JSON . stringify ( testCase . expectedTokenStream ) ;
69
- let i = 0 ;
70
- let j = 0 ;
71
- let diff = "" ;
72
- while ( j < tzd . length ) {
73
- if ( exp [ i ] != tzd [ j ] || i == exp . length )
74
- diff += tzd [ j ] ;
75
- else
76
- i ++ ;
77
- j ++ ;
67
+ const actual = JSON . stringify ( simplifiedTokenStream ) ;
68
+ const expected = JSON . stringify ( testCase . expectedTokenStream ) ;
69
+
70
+ if ( actual === expected ) {
71
+ // no difference
72
+ return ;
78
73
}
79
74
80
- const tokenStreamStr = pretty ? TokenStreamTransformer . prettyprint ( simplifiedTokenStream ) : tzd ;
81
- const message = "\nToken Stream: \n" + tokenStreamStr +
75
+ // The index of the first difference between the expected token stream and the actual token stream.
76
+ // The index is in the raw expected token stream JSON of the test case.
77
+ const diffIndex = translateIndexIgnoreSpaces ( testCase . expectedJson , expected , firstDiff ( expected , actual ) ) ;
78
+ const expectedJsonLines = testCase . expectedJson . substr ( 0 , diffIndex ) . split ( / \r \n ? | \n / g) ;
79
+ const columnNumber = expectedJsonLines . pop ( ) . length + 1 ;
80
+ const lineNumber = testCase . expectedLineOffset + expectedJsonLines . length ;
81
+
82
+ const tokenStreamStr = pretty ? TokenStreamTransformer . prettyprint ( simplifiedTokenStream ) : actual ;
83
+ const message = "\n\nActual Token Stream:" +
84
+ "\n-----------------------------------------\n" +
85
+ tokenStreamStr +
82
86
"\n-----------------------------------------\n" +
83
- "Expected Token Stream: \n" + exp +
84
- "\n-----------------------------------------\n" + diff ;
87
+ "File: " + filePath + ":" + lineNumber + ":" + columnNumber + "\n\n" ;
85
88
86
89
assert . deepEqual ( simplifiedTokenStream , testCase . expectedTokenStream , testCase . comment + message ) ;
87
90
} ,
@@ -158,7 +161,6 @@ module.exports = {
158
161
*
159
162
* @private
160
163
* @param {string } filePath
161
- * @returns {{testSource: string, expectedTokenStream: Array.<Array.<string>>, comment:string?}|null }
162
164
*/
163
165
parseTestCaseFile ( filePath ) {
164
166
const testCaseSource = fs . readFileSync ( filePath , "utf8" ) ;
@@ -167,6 +169,8 @@ module.exports = {
167
169
try {
168
170
const testCase = {
169
171
testSource : testCaseParts [ 0 ] . trim ( ) ,
172
+ expectedJson : testCaseParts [ 1 ] ,
173
+ expectedLineOffset : testCaseParts [ 0 ] . split ( / \r \n ? | \n / g) . length ,
170
174
expectedTokenStream : JSON . parse ( testCaseParts [ 1 ] ) ,
171
175
comment : null
172
176
} ;
@@ -217,3 +221,54 @@ module.exports = {
217
221
}
218
222
}
219
223
} ;
224
+
225
+ /**
226
+ * Returns the index at which the given expected string differs from the given actual string.
227
+ *
228
+ * This will returns `undefined` if the strings are equal.
229
+ *
230
+ * @param {string } expected
231
+ * @param {string } actual
232
+ * @returns {number | undefined }
233
+ */
234
+ function firstDiff ( expected , actual ) {
235
+ let i = 0 ;
236
+ let j = 0 ;
237
+ while ( i < expected . length && j < actual . length ) {
238
+ if ( expected [ i ] !== actual [ j ] ) {
239
+ return i ;
240
+ }
241
+ i ++ ; j ++ ;
242
+ }
243
+
244
+ if ( i == expected . length && j == actual . length ) {
245
+ return undefined ;
246
+ }
247
+ return i ;
248
+ }
249
+
250
+ /**
251
+ * Translates an index within a string (`withoutSpaces`) to the index of another string (`spacey`) where the only
252
+ * difference between the two strings is that the other string can have any number of additional white spaces at any
253
+ * position.
254
+ *
255
+ * In out use case, the `withoutSpaces` string is an unformatted JSON string and the `spacey` string is a formatted JSON
256
+ * string.
257
+ *
258
+ * @param {string } spacey
259
+ * @param {string } withoutSpaces
260
+ * @param {number } withoutSpaceIndex
261
+ * @returns {number | undefined }
262
+ */
263
+ function translateIndexIgnoreSpaces ( spacey , withoutSpaces , withoutSpaceIndex ) {
264
+ let i = 0 ;
265
+ let j = 0 ;
266
+ while ( i < spacey . length && j < withoutSpaces . length ) {
267
+ while ( spacey [ i ] !== withoutSpaces [ j ] ) i ++ ;
268
+ if ( j === withoutSpaceIndex ) {
269
+ return i ;
270
+ }
271
+ i ++ ; j ++ ;
272
+ }
273
+ return undefined ;
274
+ }
0 commit comments