@jdeighan/coffee-utils 2.1.11 → 3.0.0
Sign up to get free protection for your applications and to get access to all the features.
- package/package.json +1 -1
- package/src/UnitTester.coffee +11 -6
- package/src/UnitTester.js +13 -7
- package/src/block_utils.coffee +51 -1
- package/src/block_utils.js +66 -3
- package/src/coffee_utils.coffee +0 -48
- package/src/coffee_utils.js +6 -67
- package/src/debug_utils.coffee +54 -10
- package/src/debug_utils.js +52 -13
- package/src/indent_utils.coffee +11 -9
- package/src/indent_utils.js +14 -10
- package/src/log_utils.coffee +4 -4
- package/src/log_utils.js +7 -4
package/package.json
CHANGED
package/src/UnitTester.coffee
CHANGED
@@ -4,9 +4,10 @@ import {strict as assert} from 'assert'
|
|
4
4
|
import test from 'ava'
|
5
5
|
|
6
6
|
import {
|
7
|
-
undef,
|
7
|
+
undef, pass, error,
|
8
8
|
isString, isFunction, isInteger, isArray,
|
9
9
|
} from '@jdeighan/coffee-utils'
|
10
|
+
import {blockToArray} from '@jdeighan/coffee-utils/block'
|
10
11
|
import {log, currentLogger, setLogger} from '@jdeighan/coffee-utils/log'
|
11
12
|
import {
|
12
13
|
debug, debugging, setDebugging,
|
@@ -25,6 +26,12 @@ export class UnitTester
|
|
25
26
|
|
26
27
|
# ........................................................................
|
27
28
|
|
29
|
+
initialize: () -> # override to do any initialization
|
30
|
+
|
31
|
+
pass
|
32
|
+
|
33
|
+
# ........................................................................
|
34
|
+
|
28
35
|
justshow: (flag) ->
|
29
36
|
|
30
37
|
@justshow = flag
|
@@ -67,10 +74,7 @@ export class UnitTester
|
|
67
74
|
# ........................................................................
|
68
75
|
|
69
76
|
equal: (lineNum, input, expected) ->
|
70
|
-
|
71
|
-
@setWhichTest 'is'
|
72
|
-
else
|
73
|
-
@setWhichTest 'deepEqual'
|
77
|
+
@setWhichTest 'deepEqual'
|
74
78
|
@test lineNum, input, expected
|
75
79
|
return
|
76
80
|
|
@@ -160,7 +164,7 @@ export class UnitTester
|
|
160
164
|
# Remove empty lines
|
161
165
|
|
162
166
|
if isString(input)
|
163
|
-
lLines = for line in
|
167
|
+
lLines = for line in blockToArray(input)
|
164
168
|
line = line.trim()
|
165
169
|
line.replace(/\s+/g, ' ')
|
166
170
|
lLines = lLines.filter (line) -> line != ''
|
@@ -172,6 +176,7 @@ export class UnitTester
|
|
172
176
|
|
173
177
|
test: (lineNum, input, expected) ->
|
174
178
|
|
179
|
+
@initialize()
|
175
180
|
@lineNum = lineNum # set an object property
|
176
181
|
|
177
182
|
if (lineNum < 0) && process.env.FINALTEST
|
package/src/UnitTester.js
CHANGED
@@ -8,14 +8,18 @@ import test from 'ava';
|
|
8
8
|
|
9
9
|
import {
|
10
10
|
undef,
|
11
|
+
pass,
|
11
12
|
error,
|
12
|
-
stringToArray,
|
13
13
|
isString,
|
14
14
|
isFunction,
|
15
15
|
isInteger,
|
16
16
|
isArray
|
17
17
|
} from '@jdeighan/coffee-utils';
|
18
18
|
|
19
|
+
import {
|
20
|
+
blockToArray
|
21
|
+
} from '@jdeighan/coffee-utils/block';
|
22
|
+
|
19
23
|
import {
|
20
24
|
log,
|
21
25
|
currentLogger,
|
@@ -39,6 +43,11 @@ export var UnitTester = class UnitTester {
|
|
39
43
|
this.maxLineNum = undef;
|
40
44
|
}
|
41
45
|
|
46
|
+
// ........................................................................
|
47
|
+
initialize() { // override to do any initialization
|
48
|
+
return pass;
|
49
|
+
}
|
50
|
+
|
42
51
|
// ........................................................................
|
43
52
|
justshow(flag) {
|
44
53
|
this.justshow = flag;
|
@@ -73,11 +82,7 @@ export var UnitTester = class UnitTester {
|
|
73
82
|
|
74
83
|
// ........................................................................
|
75
84
|
equal(lineNum, input, expected) {
|
76
|
-
|
77
|
-
this.setWhichTest('is');
|
78
|
-
} else {
|
79
|
-
this.setWhichTest('deepEqual');
|
80
|
-
}
|
85
|
+
this.setWhichTest('deepEqual');
|
81
86
|
this.test(lineNum, input, expected);
|
82
87
|
}
|
83
88
|
|
@@ -161,7 +166,7 @@ export var UnitTester = class UnitTester {
|
|
161
166
|
if (isString(input)) {
|
162
167
|
lLines = (function() {
|
163
168
|
var i, len, ref, results;
|
164
|
-
ref =
|
169
|
+
ref = blockToArray(input);
|
165
170
|
results = [];
|
166
171
|
for (i = 0, len = ref.length; i < len; i++) {
|
167
172
|
line = ref[i];
|
@@ -182,6 +187,7 @@ export var UnitTester = class UnitTester {
|
|
182
187
|
// ........................................................................
|
183
188
|
test(lineNum, input, expected) {
|
184
189
|
var err, errMsg, got, whichTest;
|
190
|
+
this.initialize();
|
185
191
|
this.lineNum = lineNum; // set an object property
|
186
192
|
if ((lineNum < 0) && process.env.FINALTEST) {
|
187
193
|
error("Negative line numbers not allowed in FINALTEST");
|
package/src/block_utils.coffee
CHANGED
@@ -6,10 +6,60 @@ import {
|
|
6
6
|
import {createInterface} from 'readline'
|
7
7
|
|
8
8
|
import {
|
9
|
-
isEmpty, nonEmpty, error, isComment,
|
9
|
+
isEmpty, nonEmpty, error, isComment, rtrim,
|
10
10
|
} from '@jdeighan/coffee-utils'
|
11
11
|
import {log} from '@jdeighan/coffee-utils/log'
|
12
12
|
|
13
|
+
# ---------------------------------------------------------------------------
|
14
|
+
# blockToArray - split a block into lines
|
15
|
+
|
16
|
+
export blockToArray = (block) ->
|
17
|
+
|
18
|
+
if isEmpty(block)
|
19
|
+
return []
|
20
|
+
else
|
21
|
+
lLines = block.split(/\r?\n/)
|
22
|
+
|
23
|
+
# --- remove trailing empty lines
|
24
|
+
len = lLines.length
|
25
|
+
while (len > 0) && isEmpty(lLines[len-1])
|
26
|
+
lLines.pop()
|
27
|
+
len -= 1
|
28
|
+
return lLines
|
29
|
+
|
30
|
+
# ---------------------------------------------------------------------------
|
31
|
+
# arrayToBlock - block will have no trailing whitespace
|
32
|
+
|
33
|
+
export arrayToBlock = (lLines) ->
|
34
|
+
|
35
|
+
if lLines.length == 0
|
36
|
+
return ''
|
37
|
+
else
|
38
|
+
return rtrim(lLines.join('\n'))
|
39
|
+
|
40
|
+
# ---------------------------------------------------------------------------
|
41
|
+
# normalizeBlock - remove blank lines, trim each line
|
42
|
+
# - collapse internal whitespace to ' '
|
43
|
+
|
44
|
+
export normalizeBlock = (content) ->
|
45
|
+
|
46
|
+
if typeof content != 'string'
|
47
|
+
throw new Error("normalizeBlock(): not a string")
|
48
|
+
lLines = for line in blockToArray(content)
|
49
|
+
line = line.trim()
|
50
|
+
line.replace(/\s+/g, ' ')
|
51
|
+
lLines = lLines.filter (line) -> line != ''
|
52
|
+
return lLines.join('\n')
|
53
|
+
|
54
|
+
# ---------------------------------------------------------------------------
|
55
|
+
# truncateBlock - limit block to a certain number of lines
|
56
|
+
|
57
|
+
export truncateBlock = (str, numLines) ->
|
58
|
+
|
59
|
+
lLines = blockToArray str
|
60
|
+
lLines.length = numLines
|
61
|
+
return arrayToBlock lLines
|
62
|
+
|
13
63
|
# ---------------------------------------------------------------------------
|
14
64
|
|
15
65
|
export joinBlocks = (lBlocks...) ->
|
package/src/block_utils.js
CHANGED
@@ -14,18 +14,81 @@ import {
|
|
14
14
|
isEmpty,
|
15
15
|
nonEmpty,
|
16
16
|
error,
|
17
|
-
isComment
|
17
|
+
isComment,
|
18
|
+
rtrim
|
18
19
|
} from '@jdeighan/coffee-utils';
|
19
20
|
|
20
21
|
import {
|
21
22
|
log
|
22
23
|
} from '@jdeighan/coffee-utils/log';
|
23
24
|
|
25
|
+
// ---------------------------------------------------------------------------
|
26
|
+
// blockToArray - split a block into lines
|
27
|
+
export var blockToArray = function(block) {
|
28
|
+
var lLines, len;
|
29
|
+
if (isEmpty(block)) {
|
30
|
+
return [];
|
31
|
+
} else {
|
32
|
+
lLines = block.split(/\r?\n/);
|
33
|
+
// --- remove trailing empty lines
|
34
|
+
len = lLines.length;
|
35
|
+
while ((len > 0) && isEmpty(lLines[len - 1])) {
|
36
|
+
lLines.pop();
|
37
|
+
len -= 1;
|
38
|
+
}
|
39
|
+
return lLines;
|
40
|
+
}
|
41
|
+
};
|
42
|
+
|
43
|
+
// ---------------------------------------------------------------------------
|
44
|
+
// arrayToBlock - block will have no trailing whitespace
|
45
|
+
export var arrayToBlock = function(lLines) {
|
46
|
+
if (lLines.length === 0) {
|
47
|
+
return '';
|
48
|
+
} else {
|
49
|
+
return rtrim(lLines.join('\n'));
|
50
|
+
}
|
51
|
+
};
|
52
|
+
|
53
|
+
// ---------------------------------------------------------------------------
|
54
|
+
// normalizeBlock - remove blank lines, trim each line
|
55
|
+
// - collapse internal whitespace to ' '
|
56
|
+
export var normalizeBlock = function(content) {
|
57
|
+
var lLines, line;
|
58
|
+
if (typeof content !== 'string') {
|
59
|
+
throw new Error("normalizeBlock(): not a string");
|
60
|
+
}
|
61
|
+
lLines = (function() {
|
62
|
+
var i, len1, ref, results;
|
63
|
+
ref = blockToArray(content);
|
64
|
+
results = [];
|
65
|
+
for (i = 0, len1 = ref.length; i < len1; i++) {
|
66
|
+
line = ref[i];
|
67
|
+
line = line.trim();
|
68
|
+
results.push(line.replace(/\s+/g, ' '));
|
69
|
+
}
|
70
|
+
return results;
|
71
|
+
})();
|
72
|
+
lLines = lLines.filter(function(line) {
|
73
|
+
return line !== '';
|
74
|
+
});
|
75
|
+
return lLines.join('\n');
|
76
|
+
};
|
77
|
+
|
78
|
+
// ---------------------------------------------------------------------------
|
79
|
+
// truncateBlock - limit block to a certain number of lines
|
80
|
+
export var truncateBlock = function(str, numLines) {
|
81
|
+
var lLines;
|
82
|
+
lLines = blockToArray(str);
|
83
|
+
lLines.length = numLines;
|
84
|
+
return arrayToBlock(lLines);
|
85
|
+
};
|
86
|
+
|
24
87
|
// ---------------------------------------------------------------------------
|
25
88
|
export var joinBlocks = function(...lBlocks) {
|
26
|
-
var blk, i,
|
89
|
+
var blk, i, len1, str;
|
27
90
|
str = '';
|
28
|
-
for (i = 0,
|
91
|
+
for (i = 0, len1 = lBlocks.length; i < len1; i++) {
|
29
92
|
blk = lBlocks[i];
|
30
93
|
if (nonEmpty(blk)) {
|
31
94
|
str += "\n" + blk;
|
package/src/coffee_utils.coffee
CHANGED
@@ -233,45 +233,6 @@ export firstLine = (input) ->
|
|
233
233
|
else
|
234
234
|
return input.substring(0, pos)
|
235
235
|
|
236
|
-
# ---------------------------------------------------------------------------
|
237
|
-
# stringToArray - split a string into lines
|
238
|
-
|
239
|
-
export stringToArray = (str) ->
|
240
|
-
|
241
|
-
if isEmpty(str)
|
242
|
-
return []
|
243
|
-
else
|
244
|
-
lLines = str.split(/\r?\n/)
|
245
|
-
len = lLines.length
|
246
|
-
while (len > 0) && isEmpty(lLines[len-1])
|
247
|
-
lLines.pop()
|
248
|
-
len -= 1
|
249
|
-
return lLines
|
250
|
-
|
251
|
-
# ---------------------------------------------------------------------------
|
252
|
-
# arrayToString - every line has trailing newline
|
253
|
-
|
254
|
-
export arrayToString = (lLines) ->
|
255
|
-
|
256
|
-
if lLines.length == 0
|
257
|
-
return ''
|
258
|
-
else
|
259
|
-
return rtrim(lLines.join('\n'))
|
260
|
-
|
261
|
-
# ---------------------------------------------------------------------------
|
262
|
-
# normalize - remove blank lines, trim each line
|
263
|
-
# - collapse internal whitespace to ' '
|
264
|
-
|
265
|
-
export normalize = (content) ->
|
266
|
-
|
267
|
-
if typeof content != 'string'
|
268
|
-
throw new Error("normalize(): not a string")
|
269
|
-
lLines = for line in stringToArray(content)
|
270
|
-
line = line.trim()
|
271
|
-
line.replace(/\s+/g, ' ')
|
272
|
-
lLines = lLines.filter (line) -> line != ''
|
273
|
-
return lLines.join('\n')
|
274
|
-
|
275
236
|
# ---------------------------------------------------------------------------
|
276
237
|
|
277
238
|
export titleLine = (title, char='=', padding=2, linelen=42) ->
|
@@ -353,15 +314,6 @@ export oneline = (obj) ->
|
|
353
314
|
|
354
315
|
export OL = oneline
|
355
316
|
|
356
|
-
# ---------------------------------------------------------------------------
|
357
|
-
# truncateBlock - limit block to a certain number of lines
|
358
|
-
|
359
|
-
export truncateBlock = (str, numLines) ->
|
360
|
-
|
361
|
-
lLines = stringToArray str
|
362
|
-
lLines.length = numLines
|
363
|
-
return arrayToString lLines
|
364
|
-
|
365
317
|
# ---------------------------------------------------------------------------
|
366
318
|
|
367
319
|
export removeCR = (block) ->
|
package/src/coffee_utils.js
CHANGED
@@ -162,11 +162,11 @@ export var words = function(str) {
|
|
162
162
|
|
163
163
|
// ---------------------------------------------------------------------------
|
164
164
|
export var isArrayOfHashes = function(lItems) {
|
165
|
-
var i, item,
|
165
|
+
var i, item, len;
|
166
166
|
if (!isArray(lItems)) {
|
167
167
|
return false;
|
168
168
|
}
|
169
|
-
for (i = 0,
|
169
|
+
for (i = 0, len = lItems.length; i < len; i++) {
|
170
170
|
item = lItems[i];
|
171
171
|
if (!isHash(item)) {
|
172
172
|
return false;
|
@@ -177,11 +177,11 @@ export var isArrayOfHashes = function(lItems) {
|
|
177
177
|
|
178
178
|
// ---------------------------------------------------------------------------
|
179
179
|
export var isArrayOfStrings = function(lItems) {
|
180
|
-
var i, item,
|
180
|
+
var i, item, len;
|
181
181
|
if (!isArray(lItems)) {
|
182
182
|
return false;
|
183
183
|
}
|
184
|
-
for (i = 0,
|
184
|
+
for (i = 0, len = lItems.length; i < len; i++) {
|
185
185
|
item = lItems[i];
|
186
186
|
if (!isString(item)) {
|
187
187
|
return false;
|
@@ -242,58 +242,6 @@ export var firstLine = function(input) {
|
|
242
242
|
}
|
243
243
|
};
|
244
244
|
|
245
|
-
// ---------------------------------------------------------------------------
|
246
|
-
// stringToArray - split a string into lines
|
247
|
-
export var stringToArray = function(str) {
|
248
|
-
var lLines, len;
|
249
|
-
if (isEmpty(str)) {
|
250
|
-
return [];
|
251
|
-
} else {
|
252
|
-
lLines = str.split(/\r?\n/);
|
253
|
-
len = lLines.length;
|
254
|
-
while ((len > 0) && isEmpty(lLines[len - 1])) {
|
255
|
-
lLines.pop();
|
256
|
-
len -= 1;
|
257
|
-
}
|
258
|
-
return lLines;
|
259
|
-
}
|
260
|
-
};
|
261
|
-
|
262
|
-
// ---------------------------------------------------------------------------
|
263
|
-
// arrayToString - every line has trailing newline
|
264
|
-
export var arrayToString = function(lLines) {
|
265
|
-
if (lLines.length === 0) {
|
266
|
-
return '';
|
267
|
-
} else {
|
268
|
-
return rtrim(lLines.join('\n'));
|
269
|
-
}
|
270
|
-
};
|
271
|
-
|
272
|
-
// ---------------------------------------------------------------------------
|
273
|
-
// normalize - remove blank lines, trim each line
|
274
|
-
// - collapse internal whitespace to ' '
|
275
|
-
export var normalize = function(content) {
|
276
|
-
var lLines, line;
|
277
|
-
if (typeof content !== 'string') {
|
278
|
-
throw new Error("normalize(): not a string");
|
279
|
-
}
|
280
|
-
lLines = (function() {
|
281
|
-
var i, len1, ref, results;
|
282
|
-
ref = stringToArray(content);
|
283
|
-
results = [];
|
284
|
-
for (i = 0, len1 = ref.length; i < len1; i++) {
|
285
|
-
line = ref[i];
|
286
|
-
line = line.trim();
|
287
|
-
results.push(line.replace(/\s+/g, ' '));
|
288
|
-
}
|
289
|
-
return results;
|
290
|
-
})();
|
291
|
-
lLines = lLines.filter(function(line) {
|
292
|
-
return line !== '';
|
293
|
-
});
|
294
|
-
return lLines.join('\n');
|
295
|
-
};
|
296
|
-
|
297
245
|
// ---------------------------------------------------------------------------
|
298
246
|
export var titleLine = function(title, char = '=', padding = 2, linelen = 42) {
|
299
247
|
var nLeft, nRight, strLeft, strMiddle, strRight, titleLen;
|
@@ -352,10 +300,10 @@ export var escapeStr = function(str) {
|
|
352
300
|
croak("escapeStr(): not a string", str, 'STRING');
|
353
301
|
}
|
354
302
|
lParts = (function() {
|
355
|
-
var i,
|
303
|
+
var i, len, ref, results;
|
356
304
|
ref = str.split('');
|
357
305
|
results = [];
|
358
|
-
for (i = 0,
|
306
|
+
for (i = 0, len = ref.length; i < len; i++) {
|
359
307
|
ch = ref[i];
|
360
308
|
if (ch === '\n') {
|
361
309
|
results.push('\\n');
|
@@ -385,15 +333,6 @@ export var oneline = function(obj) {
|
|
385
333
|
|
386
334
|
export var OL = oneline;
|
387
335
|
|
388
|
-
// ---------------------------------------------------------------------------
|
389
|
-
// truncateBlock - limit block to a certain number of lines
|
390
|
-
export var truncateBlock = function(str, numLines) {
|
391
|
-
var lLines;
|
392
|
-
lLines = stringToArray(str);
|
393
|
-
lLines.length = numLines;
|
394
|
-
return arrayToString(lLines);
|
395
|
-
};
|
396
|
-
|
397
336
|
// ---------------------------------------------------------------------------
|
398
337
|
export var removeCR = function(block) {
|
399
338
|
return block.replace(/\r/g, '');
|
package/src/debug_utils.coffee
CHANGED
@@ -3,9 +3,11 @@
|
|
3
3
|
import {strict as assert} from 'assert'
|
4
4
|
import {
|
5
5
|
undef, error, croak, warn, words, isString, isFunction,
|
6
|
-
|
6
|
+
oneline, escapeStr, isNumber, isArray,
|
7
7
|
} from '@jdeighan/coffee-utils'
|
8
|
+
import {blockToArray} from '@jdeighan/coffee-utils/block'
|
8
9
|
import {log} from '@jdeighan/coffee-utils/log'
|
10
|
+
import {slurp} from '@jdeighan/coffee-utils/fs'
|
9
11
|
|
10
12
|
vbar = '│' # unicode 2502
|
11
13
|
hbar = '─' # unicode 2500
|
@@ -103,8 +105,9 @@ export resetDebugging = () ->
|
|
103
105
|
export debug = (lArgs...) ->
|
104
106
|
# --- either 1 or 2 args
|
105
107
|
|
106
|
-
|
107
|
-
|
108
|
+
# --- We always need to manipulate the stack when we encounter
|
109
|
+
# either "enter X" or "return from X", so we can't short-circuit
|
110
|
+
# when debugging is off
|
108
111
|
|
109
112
|
nArgs = lArgs.length
|
110
113
|
assert ((nArgs >= 1) && (nArgs <= 2)), "debug(); Bad # args #{nArgs}"
|
@@ -126,7 +129,7 @@ export debug = (lArgs...) ->
|
|
126
129
|
\s*
|
127
130
|
enter
|
128
131
|
\s+
|
129
|
-
([A-Za-z_][A-Za-z0-9_]*)
|
132
|
+
([A-Za-z_][A-Za-z0-9_\.]*)
|
130
133
|
///))
|
131
134
|
entering = true
|
132
135
|
curFunc = lMatches[1]
|
@@ -136,7 +139,7 @@ export debug = (lArgs...) ->
|
|
136
139
|
.*
|
137
140
|
from
|
138
141
|
\s+
|
139
|
-
([A-Za-z_][A-Za-z0-9_]*)
|
142
|
+
([A-Za-z_][A-Za-z0-9_\.]*)
|
140
143
|
///))
|
141
144
|
returning = true
|
142
145
|
curFunc = lMatches[1]
|
@@ -163,15 +166,14 @@ export debug = (lArgs...) ->
|
|
163
166
|
logItem: true,
|
164
167
|
itemPrefix: stripArrow(prefix),
|
165
168
|
}
|
169
|
+
if returning && (debugLevel > 0)
|
170
|
+
debugLevel -= 1
|
166
171
|
|
167
172
|
if returning && lDebugFuncs && funcMatch(curFunc)
|
168
173
|
setDebugging false # revert to previous setting - might still be on
|
169
174
|
|
170
|
-
if debugging
|
171
|
-
|
172
|
-
debugLevel += 1
|
173
|
-
if returning && (debugLevel > 0)
|
174
|
-
debugLevel -= 1
|
175
|
+
if debugging && entering
|
176
|
+
debugLevel += 1
|
175
177
|
return
|
176
178
|
|
177
179
|
# ---------------------------------------------------------------------------
|
@@ -195,3 +197,45 @@ export funcMatch = (curFunc) ->
|
|
195
197
|
return true
|
196
198
|
else
|
197
199
|
return false
|
200
|
+
|
201
|
+
# ---------------------------------------------------------------------------
|
202
|
+
|
203
|
+
export checkTrace = (block) ->
|
204
|
+
|
205
|
+
lStack = []
|
206
|
+
|
207
|
+
for line in blockToArray(block)
|
208
|
+
if lMatches = line.match(///
|
209
|
+
enter
|
210
|
+
\s+
|
211
|
+
([A-Za-z_][A-Za-z0-9_\.]*)
|
212
|
+
///)
|
213
|
+
funcName = lMatches[1]
|
214
|
+
lStack.push funcName
|
215
|
+
else if lMatches = line.match(///
|
216
|
+
return
|
217
|
+
.*
|
218
|
+
from
|
219
|
+
\s+
|
220
|
+
([A-Za-z_][A-Za-z0-9_\.]*)
|
221
|
+
///)
|
222
|
+
funcName = lMatches[1]
|
223
|
+
len = lStack.length
|
224
|
+
if (len == 0)
|
225
|
+
log "return from #{funcName} with empty stack"
|
226
|
+
else if (lStack[len-1] == funcName)
|
227
|
+
lStack.pop()
|
228
|
+
else if (lStack[len-2] == funcName)
|
229
|
+
log "missing return from #{lStack[len-2]}"
|
230
|
+
lStack.pop()
|
231
|
+
lStack.pop()
|
232
|
+
else
|
233
|
+
log "return from #{funcName} - not found on stack"
|
234
|
+
return
|
235
|
+
|
236
|
+
# ---------------------------------------------------------------------------
|
237
|
+
|
238
|
+
export checkTraceFile = (filepath) ->
|
239
|
+
|
240
|
+
checkTrace(slurp(filepath))
|
241
|
+
return
|
package/src/debug_utils.js
CHANGED
@@ -14,17 +14,24 @@ import {
|
|
14
14
|
words,
|
15
15
|
isString,
|
16
16
|
isFunction,
|
17
|
-
stringToArray,
|
18
17
|
oneline,
|
19
18
|
escapeStr,
|
20
19
|
isNumber,
|
21
20
|
isArray
|
22
21
|
} from '@jdeighan/coffee-utils';
|
23
22
|
|
23
|
+
import {
|
24
|
+
blockToArray
|
25
|
+
} from '@jdeighan/coffee-utils/block';
|
26
|
+
|
24
27
|
import {
|
25
28
|
log
|
26
29
|
} from '@jdeighan/coffee-utils/log';
|
27
30
|
|
31
|
+
import {
|
32
|
+
slurp
|
33
|
+
} from '@jdeighan/coffee-utils/fs';
|
34
|
+
|
28
35
|
vbar = '│'; // unicode 2502
|
29
36
|
|
30
37
|
hbar = '─'; // unicode 2500
|
@@ -115,9 +122,10 @@ export var resetDebugging = function() {
|
|
115
122
|
export var debug = function(...lArgs) {
|
116
123
|
var curFunc, entering, item, lMatches, nArgs, prefix, returning, str;
|
117
124
|
// --- either 1 or 2 args
|
118
|
-
|
119
|
-
|
120
|
-
|
125
|
+
|
126
|
+
// --- We always need to manipulate the stack when we encounter
|
127
|
+
// either "enter X" or "return from X", so we can't short-circuit
|
128
|
+
// when debugging is off
|
121
129
|
nArgs = lArgs.length;
|
122
130
|
assert((nArgs >= 1) && (nArgs <= 2), `debug(); Bad # args ${nArgs}`);
|
123
131
|
str = lArgs[0];
|
@@ -130,10 +138,10 @@ export var debug = function(...lArgs) {
|
|
130
138
|
// --- determine if we're entering or returning from a function
|
131
139
|
entering = returning = false;
|
132
140
|
curFunc = undef;
|
133
|
-
if ((lMatches = str.match(/^\s*enter\s+([A-Za-z_][A-Za-z0-9_]*)/))) {
|
141
|
+
if ((lMatches = str.match(/^\s*enter\s+([A-Za-z_][A-Za-z0-9_\.]*)/))) {
|
134
142
|
entering = true;
|
135
143
|
curFunc = lMatches[1];
|
136
|
-
} else if ((lMatches = str.match(/^\s*return.*from\s+([A-Za-z_][A-Za-z0-9_]*)/))) {
|
144
|
+
} else if ((lMatches = str.match(/^\s*return.*from\s+([A-Za-z_][A-Za-z0-9_\.]*)/))) {
|
137
145
|
returning = true;
|
138
146
|
curFunc = lMatches[1];
|
139
147
|
}
|
@@ -160,17 +168,15 @@ export var debug = function(...lArgs) {
|
|
160
168
|
itemPrefix: stripArrow(prefix)
|
161
169
|
});
|
162
170
|
}
|
171
|
+
if (returning && (debugLevel > 0)) {
|
172
|
+
debugLevel -= 1;
|
173
|
+
}
|
163
174
|
}
|
164
175
|
if (returning && lDebugFuncs && funcMatch(curFunc)) {
|
165
176
|
setDebugging(false); // revert to previous setting - might still be on
|
166
177
|
}
|
167
|
-
if (debugging) {
|
168
|
-
|
169
|
-
debugLevel += 1;
|
170
|
-
}
|
171
|
-
if (returning && (debugLevel > 0)) {
|
172
|
-
debugLevel -= 1;
|
173
|
-
}
|
178
|
+
if (debugging && entering) {
|
179
|
+
debugLevel += 1;
|
174
180
|
}
|
175
181
|
};
|
176
182
|
|
@@ -189,3 +195,36 @@ export var funcMatch = function(curFunc) {
|
|
189
195
|
return false;
|
190
196
|
}
|
191
197
|
};
|
198
|
+
|
199
|
+
// ---------------------------------------------------------------------------
|
200
|
+
export var checkTrace = function(block) {
|
201
|
+
var funcName, i, lMatches, lStack, len, len1, line, ref;
|
202
|
+
lStack = [];
|
203
|
+
ref = blockToArray(block);
|
204
|
+
for (i = 0, len1 = ref.length; i < len1; i++) {
|
205
|
+
line = ref[i];
|
206
|
+
if (lMatches = line.match(/enter\s+([A-Za-z_][A-Za-z0-9_\.]*)/)) {
|
207
|
+
funcName = lMatches[1];
|
208
|
+
lStack.push(funcName);
|
209
|
+
} else if (lMatches = line.match(/return.*from\s+([A-Za-z_][A-Za-z0-9_\.]*)/)) {
|
210
|
+
funcName = lMatches[1];
|
211
|
+
len = lStack.length;
|
212
|
+
if (len === 0) {
|
213
|
+
log(`return from ${funcName} with empty stack`);
|
214
|
+
} else if (lStack[len - 1] === funcName) {
|
215
|
+
lStack.pop();
|
216
|
+
} else if (lStack[len - 2] === funcName) {
|
217
|
+
log(`missing return from ${lStack[len - 2]}`);
|
218
|
+
lStack.pop();
|
219
|
+
lStack.pop();
|
220
|
+
} else {
|
221
|
+
log(`return from ${funcName} - not found on stack`);
|
222
|
+
}
|
223
|
+
}
|
224
|
+
}
|
225
|
+
};
|
226
|
+
|
227
|
+
// ---------------------------------------------------------------------------
|
228
|
+
export var checkTraceFile = function(filepath) {
|
229
|
+
checkTrace(slurp(filepath));
|
230
|
+
};
|
package/src/indent_utils.coffee
CHANGED
@@ -2,9 +2,10 @@
|
|
2
2
|
|
3
3
|
import {strict as assert} from 'assert'
|
4
4
|
import {
|
5
|
-
undef, error,
|
5
|
+
undef, error, escapeStr,
|
6
6
|
oneline, isInteger, isString, isArray, isEmpty, rtrim,
|
7
7
|
} from '@jdeighan/coffee-utils'
|
8
|
+
import {arrayToBlock, blockToArray} from '@jdeighan/coffee-utils/block'
|
8
9
|
|
9
10
|
# ---------------------------------------------------------------------------
|
10
11
|
# NOTE: Currently, only TAB indentation is supported
|
@@ -30,6 +31,7 @@ export indentation = (level) ->
|
|
30
31
|
|
31
32
|
# ---------------------------------------------------------------------------
|
32
33
|
# indentLevel - determine indent level of a string
|
34
|
+
# it's OK if the string is ONLY indentation
|
33
35
|
|
34
36
|
export indentLevel = (str) ->
|
35
37
|
|
@@ -51,9 +53,9 @@ export indented = (input, level=0) ->
|
|
51
53
|
"#{toAdd}#{line}"
|
52
54
|
return lLines
|
53
55
|
else
|
54
|
-
lLines = for line in
|
56
|
+
lLines = for line in blockToArray(input)
|
55
57
|
"#{toAdd}#{line}"
|
56
|
-
return
|
58
|
+
return arrayToBlock(lLines)
|
57
59
|
|
58
60
|
# ---------------------------------------------------------------------------
|
59
61
|
# undented - string with 1st line indentation removed for each line
|
@@ -67,7 +69,7 @@ export undented = (text, level=undef) ->
|
|
67
69
|
return text
|
68
70
|
|
69
71
|
if isString(text)
|
70
|
-
lLines =
|
72
|
+
lLines = blockToArray(text)
|
71
73
|
if (lLines.length == 0)
|
72
74
|
return ''
|
73
75
|
else if isArray(text)
|
@@ -97,7 +99,7 @@ export undented = (text, level=undef) ->
|
|
97
99
|
lNewLines.push(line.substr(nToRemove))
|
98
100
|
|
99
101
|
if isString(text)
|
100
|
-
return
|
102
|
+
return arrayToBlock(lNewLines)
|
101
103
|
else
|
102
104
|
return lNewLines
|
103
105
|
|
@@ -109,7 +111,7 @@ export undented = (text, level=undef) ->
|
|
109
111
|
export tabify = (str, numSpaces=undef) ->
|
110
112
|
|
111
113
|
lLines = []
|
112
|
-
for str in
|
114
|
+
for str in blockToArray(str)
|
113
115
|
lMatches = str.match(/^(\s*)(.*)$/)
|
114
116
|
[_, prefix, theRest] = lMatches
|
115
117
|
if prefix == ''
|
@@ -123,7 +125,7 @@ export tabify = (str, numSpaces=undef) ->
|
|
123
125
|
if (n % numSpaces != 0)
|
124
126
|
error "tabify(): Invalid # of leading space chars"
|
125
127
|
lLines.push '\t'.repeat(n / numSpaces) + theRest
|
126
|
-
return
|
128
|
+
return arrayToBlock(lLines)
|
127
129
|
|
128
130
|
# ---------------------------------------------------------------------------
|
129
131
|
# untabify - convert leading TABs to spaces
|
@@ -132,11 +134,11 @@ export untabify = (str, numSpaces=3) ->
|
|
132
134
|
|
133
135
|
oneIndent = ' '.repeat(numSpaces)
|
134
136
|
lLines = []
|
135
|
-
for str in
|
137
|
+
for str in blockToArray(str)
|
136
138
|
lMatches = str.match(/^(\t*)(.*)$/)
|
137
139
|
[_, prefix, theRest] = lMatches
|
138
140
|
if prefix == ''
|
139
141
|
lLines.push theRest
|
140
142
|
else
|
141
143
|
lLines.push oneIndent.repeat(prefix.length) + theRest
|
142
|
-
return
|
144
|
+
return arrayToBlock(lLines)
|
package/src/indent_utils.js
CHANGED
@@ -7,8 +7,6 @@ import {
|
|
7
7
|
import {
|
8
8
|
undef,
|
9
9
|
error,
|
10
|
-
arrayToString,
|
11
|
-
stringToArray,
|
12
10
|
escapeStr,
|
13
11
|
oneline,
|
14
12
|
isInteger,
|
@@ -18,6 +16,11 @@ import {
|
|
18
16
|
rtrim
|
19
17
|
} from '@jdeighan/coffee-utils';
|
20
18
|
|
19
|
+
import {
|
20
|
+
arrayToBlock,
|
21
|
+
blockToArray
|
22
|
+
} from '@jdeighan/coffee-utils/block';
|
23
|
+
|
21
24
|
// ---------------------------------------------------------------------------
|
22
25
|
// NOTE: Currently, only TAB indentation is supported
|
23
26
|
// ---------------------------------------------------------------------------
|
@@ -41,6 +44,7 @@ export var indentation = function(level) {
|
|
41
44
|
|
42
45
|
// ---------------------------------------------------------------------------
|
43
46
|
// indentLevel - determine indent level of a string
|
47
|
+
// it's OK if the string is ONLY indentation
|
44
48
|
export var indentLevel = function(str) {
|
45
49
|
var lMatches;
|
46
50
|
lMatches = str.match(/^\t*/);
|
@@ -70,7 +74,7 @@ export var indented = function(input, level = 0) {
|
|
70
74
|
} else {
|
71
75
|
lLines = (function() {
|
72
76
|
var i, len, ref, results;
|
73
|
-
ref =
|
77
|
+
ref = blockToArray(input);
|
74
78
|
results = [];
|
75
79
|
for (i = 0, len = ref.length; i < len; i++) {
|
76
80
|
line = ref[i];
|
@@ -78,7 +82,7 @@ export var indented = function(input, level = 0) {
|
|
78
82
|
}
|
79
83
|
return results;
|
80
84
|
})();
|
81
|
-
return
|
85
|
+
return arrayToBlock(lLines);
|
82
86
|
}
|
83
87
|
};
|
84
88
|
|
@@ -93,7 +97,7 @@ export var undented = function(text, level = undef) {
|
|
93
97
|
return text;
|
94
98
|
}
|
95
99
|
if (isString(text)) {
|
96
|
-
lLines =
|
100
|
+
lLines = blockToArray(text);
|
97
101
|
if (lLines.length === 0) {
|
98
102
|
return '';
|
99
103
|
}
|
@@ -125,7 +129,7 @@ export var undented = function(text, level = undef) {
|
|
125
129
|
}
|
126
130
|
}
|
127
131
|
if (isString(text)) {
|
128
|
-
return
|
132
|
+
return arrayToBlock(lNewLines);
|
129
133
|
} else {
|
130
134
|
return lNewLines;
|
131
135
|
}
|
@@ -138,7 +142,7 @@ export var undented = function(text, level = undef) {
|
|
138
142
|
export var tabify = function(str, numSpaces = undef) {
|
139
143
|
var _, i, lLines, lMatches, len, n, prefix, ref, theRest;
|
140
144
|
lLines = [];
|
141
|
-
ref =
|
145
|
+
ref = blockToArray(str);
|
142
146
|
for (i = 0, len = ref.length; i < len; i++) {
|
143
147
|
str = ref[i];
|
144
148
|
lMatches = str.match(/^(\s*)(.*)$/);
|
@@ -159,7 +163,7 @@ export var tabify = function(str, numSpaces = undef) {
|
|
159
163
|
lLines.push('\t'.repeat(n / numSpaces) + theRest);
|
160
164
|
}
|
161
165
|
}
|
162
|
-
return
|
166
|
+
return arrayToBlock(lLines);
|
163
167
|
};
|
164
168
|
|
165
169
|
// ---------------------------------------------------------------------------
|
@@ -168,7 +172,7 @@ export var untabify = function(str, numSpaces = 3) {
|
|
168
172
|
var _, i, lLines, lMatches, len, oneIndent, prefix, ref, theRest;
|
169
173
|
oneIndent = ' '.repeat(numSpaces);
|
170
174
|
lLines = [];
|
171
|
-
ref =
|
175
|
+
ref = blockToArray(str);
|
172
176
|
for (i = 0, len = ref.length; i < len; i++) {
|
173
177
|
str = ref[i];
|
174
178
|
lMatches = str.match(/^(\t*)(.*)$/);
|
@@ -179,5 +183,5 @@ export var untabify = function(str, numSpaces = 3) {
|
|
179
183
|
lLines.push(oneIndent.repeat(prefix.length) + theRest);
|
180
184
|
}
|
181
185
|
}
|
182
|
-
return
|
186
|
+
return arrayToBlock(lLines);
|
183
187
|
};
|
package/src/log_utils.coffee
CHANGED
@@ -4,9 +4,9 @@ import {strict as assert} from 'assert'
|
|
4
4
|
import yaml from 'js-yaml'
|
5
5
|
|
6
6
|
import {
|
7
|
-
undef, isNumber, isString, isHash, isFunction,
|
8
|
-
escapeStr, stringToArray,
|
7
|
+
undef, isNumber, isString, isHash, isFunction, escapeStr,
|
9
8
|
} from '@jdeighan/coffee-utils'
|
9
|
+
import {blockToArray} from '@jdeighan/coffee-utils/block'
|
10
10
|
import {tabify} from '@jdeighan/coffee-utils/indent'
|
11
11
|
|
12
12
|
logger = console.log # for strings
|
@@ -120,7 +120,7 @@ export log = (lArgs...) ->
|
|
120
120
|
logger "#{prefix}#{str} = '#{esc}'"
|
121
121
|
else
|
122
122
|
logger "#{prefix}#{str}:"
|
123
|
-
for line in
|
123
|
+
for line in blockToArray(item)
|
124
124
|
logger "#{itemPrefix} #{escapeStr(line)}"
|
125
125
|
else
|
126
126
|
# --- It's some type of object
|
@@ -129,7 +129,7 @@ export log = (lArgs...) ->
|
|
129
129
|
logger "#{prefix}#{str} = #{json}"
|
130
130
|
else
|
131
131
|
logger "#{prefix}#{str}:"
|
132
|
-
for str in
|
132
|
+
for str in blockToArray(stringify(item))
|
133
133
|
logger "#{itemPrefix} #{str}"
|
134
134
|
return
|
135
135
|
|
package/src/log_utils.js
CHANGED
@@ -14,10 +14,13 @@ import {
|
|
14
14
|
isString,
|
15
15
|
isHash,
|
16
16
|
isFunction,
|
17
|
-
escapeStr
|
18
|
-
stringToArray
|
17
|
+
escapeStr
|
19
18
|
} from '@jdeighan/coffee-utils';
|
20
19
|
|
20
|
+
import {
|
21
|
+
blockToArray
|
22
|
+
} from '@jdeighan/coffee-utils/block';
|
23
|
+
|
21
24
|
import {
|
22
25
|
tabify
|
23
26
|
} from '@jdeighan/coffee-utils/indent';
|
@@ -133,7 +136,7 @@ export var log = function(...lArgs) {
|
|
133
136
|
logger(`${prefix}${str} = '${esc}'`);
|
134
137
|
} else {
|
135
138
|
logger(`${prefix}${str}:`);
|
136
|
-
ref =
|
139
|
+
ref = blockToArray(item);
|
137
140
|
for (i = 0, len = ref.length; i < len; i++) {
|
138
141
|
line = ref[i];
|
139
142
|
logger(`${itemPrefix} ${escapeStr(line)}`);
|
@@ -146,7 +149,7 @@ export var log = function(...lArgs) {
|
|
146
149
|
logger(`${prefix}${str} = ${json}`);
|
147
150
|
} else {
|
148
151
|
logger(`${prefix}${str}:`);
|
149
|
-
ref1 =
|
152
|
+
ref1 = blockToArray(stringify(item));
|
150
153
|
for (j = 0, len1 = ref1.length; j < len1; j++) {
|
151
154
|
str = ref1[j];
|
152
155
|
logger(`${itemPrefix} ${str}`);
|