@suffolklitlab/alkiln 5.14.0 → 5.15.0

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.
Files changed (35) hide show
  1. package/.github/workflows/github_server.yml +1 -1
  2. package/.github/workflows/playground.yml +2 -1
  3. package/CHANGELOG.md +29 -0
  4. package/action.yml +26 -10
  5. package/action_for_github_server/action.yml +31 -27
  6. package/docs/4_environments.md +2 -2
  7. package/docs/artifacts_folder_name.md +121 -71
  8. package/lib/docassemble/server_install.js +0 -2
  9. package/lib/docassemble/setup.js +1 -3
  10. package/lib/docassemble/takedown.js +2 -2
  11. package/lib/globals.js +10 -0
  12. package/lib/run_cucumber.js +40 -53
  13. package/lib/scope.js +32 -0
  14. package/lib/setup/TestGenerator.js +1757 -0
  15. package/lib/setup/artifacts.js +20 -0
  16. package/lib/setup/generate.js +42 -0
  17. package/lib/setup/get_Gherkin_AST.js +26 -0
  18. package/lib/setup/validate.js +89 -0
  19. package/lib/steps.js +53 -19
  20. package/lib/utils/Log.js +302 -149
  21. package/lib/utils/get_error_stacks.js +16 -0
  22. package/lib/utils/reports.js +43 -23
  23. package/lib/utils/session_vars.js +77 -57
  24. package/lib/utils/set_sources_paths.js +98 -0
  25. package/package.json +18 -7
  26. package/tests/log_codes/check_codes.sh +17 -13
  27. package/tests/log_codes/log_code_expected_instances.txt +58 -0
  28. package/tests/unit_tests/constrained_random_answers/invalid.fixtures.js +178 -0
  29. package/tests/unit_tests/constrained_random_answers/invalid.test.js +251 -0
  30. package/tests/unit_tests/constrained_random_answers/valid.fixtures.js +957 -0
  31. package/tests/unit_tests/constrained_random_answers/valid.test.js +563 -0
  32. package/tests/unit_tests/log.test.js +17 -41
  33. package/_alkiln_meta/gherkin_parsed_example.json +0 -1546
  34. package/_alkiln_meta/shift_logs.js +0 -75
  35. /package/docs/{expected_inernal_results.md → expected_internal_results.md} +0 -0
@@ -0,0 +1,563 @@
1
+ const chai = require(`chai`);
2
+ const expect = chai.expect;
3
+
4
+ /**
5
+ * Discuss:
6
+ * - Test making more than one file?
7
+ * - Test deleting the files from the sources folder?
8
+ * - Test having multiple sources folders? (overdue)
9
+ * - Allow single quotes?
10
+ * */
11
+
12
+ const TestGenerator = require(`../../../lib/setup/TestGenerator.js`);
13
+ const Log = require(`../../../lib/utils/Log.js`);
14
+ const fixtures = require(`./valid.fixtures.js`);
15
+ const get_Gherkin_AST = require(`../../../lib/setup/get_Gherkin_AST`);
16
+
17
+
18
+ const RANDOM_TABLE_PLACEHOLDER = fixtures.RANDOM_TABLE_PLACEHOLDER;
19
+ const TABLE_ROW_REGEX = /^(?!(?:.*\| var \| value \|))(.*\| .* \|)/gm;
20
+ const TABLE_PLACEHOLDER_REGEX = new RegExp(`(${ RANDOM_TABLE_PLACEHOLDER }(\n)?)+`, `g`);
21
+
22
+ const WARNING_PLACEHOLDER = fixtures.WARNING_PLACEHOLDER;
23
+ const WARNING_MSG_REGEX = /(ALK\d{4} )(.*\d{4}-\d\d-\d\d \d\d:\d\d:\d\dUTC.*(?!\n ―)(?:\n)?.+)/g;
24
+
25
+ const FLUB_PLACEHOLDER = fixtures.FLUB_PLACEHOLDER;
26
+ const FLUB_REGEX = fixtures.FLUB_OPTIONS_REGEX;
27
+ function comparable_text( text ) {
28
+ /** Replaces unimportant dynamic strings with placeholder strings
29
+ *
30
+ * We need to check that the contents of the file match the expected contents,
31
+ * but the table contains random values, so we need to discount the table.
32
+ * Same for warning timestamps and message text.
33
+ * */
34
+ let with_placeholders = text.replaceAll(
35
+ TABLE_ROW_REGEX,
36
+ RANDOM_TABLE_PLACEHOLDER
37
+ );
38
+ // Collapse multiple consecutive placeholders into one placeholder
39
+ let with_reduced_placeholders = with_placeholders.replaceAll(
40
+ TABLE_PLACEHOLDER_REGEX,
41
+ `${ RANDOM_TABLE_PLACEHOLDER }$2`
42
+ );
43
+
44
+ let without_warnings = with_reduced_placeholders.replace(
45
+ WARNING_MSG_REGEX, `$1${ WARNING_PLACEHOLDER }`
46
+ );
47
+
48
+ let without_random_flub_words = without_warnings.replaceAll(
49
+ FLUB_REGEX, FLUB_PLACEHOLDER
50
+ );
51
+
52
+ return without_random_flub_words;
53
+ };
54
+
55
+
56
+ function get_log_codes({ logger }) {
57
+ /** Returns a list of ALKiln codes from arguments sent to a Log instance
58
+ *
59
+ * @params {object} obj - Named arguments
60
+ * @params {Log} obj.logger - An instance of Log
61
+ * @params {object} obj.logger.opts - Options passed to the Log instance
62
+ * @params {str} obj.logger.opts.code - ALK#### formatted log code
63
+ * @params {[str]} obj.logger.logs - Additional messages to be logged
64
+ *
65
+ * @returns {[str]} - List of ALKiln log codes in the collection of logs
66
+ * */
67
+ let codes = [];
68
+
69
+ for ( let record of logger.internal_log_records ) {
70
+ codes.push( record.opts.code );
71
+ }
72
+
73
+ return codes;
74
+ }
75
+
76
+
77
+ /** Variables that will change their values for each `it()` */
78
+ const logger = new Log({ context: `valid generators unit tests` });
79
+ let fixture = null;
80
+ let new_contents = null;
81
+ let errors = null;
82
+ let actual = null;
83
+ let comparable = null;
84
+ let num_Scenarios = null;
85
+ let text_matches = null;
86
+ function mutate_globals_with({ testing_vals, do_compare=false }) {
87
+ /** Set up values for parsing, parse, record values. Mutates in-scope
88
+ * variables in a way that helps chaijs (mocha really) get the right
89
+ * values to the right places.
90
+ *
91
+ * @params {object} testing_vals - Arguments to pass to the function and
92
+ * expected values
93
+ *
94
+ * @returns {undefined}
95
+ * */
96
+ // Reset log codes
97
+ logger.clear_internal_log_records();
98
+
99
+ process.env.ALKILN_MAX_RANDOM_TESTS_PER_SCENARIO = 40;
100
+ if ( testing_vals.max_num_allowed ) {
101
+ process.env.ALKILN_MAX_RANDOM_TESTS_PER_SCENARIO = testing_vals.max_num_allowed;
102
+ }
103
+
104
+ // Fresh namespace
105
+ let generator = new TestGenerator();
106
+ // Mutates `fixture`
107
+ fixture = testing_vals;
108
+
109
+ let generators = fixture.arg;
110
+ if ( !Array.isArray( generators )) {
111
+ generators = [ fixture.arg ];
112
+ }
113
+
114
+ // Mutates `errors` and `num_Scenarios`
115
+ errors = [];
116
+ num_Scenarios = 0;
117
+ let new_files = [];
118
+ for ( let generator_text of generators ) {
119
+
120
+ let { new_contents: new_file, errors: new_errors } = generator.parse_file({
121
+ file_text: generator_text,
122
+ generator_path: `used_in_warning_logs`,
123
+ logger
124
+ });
125
+
126
+ new_files.push( new_file );
127
+ errors.push( ...new_errors );
128
+
129
+ // Validate new file. Should always be valid
130
+ let { AST: doc_AST, errors: file_errs } = get_Gherkin_AST({
131
+ file_text: new_file
132
+ });
133
+
134
+ let scenarios = doc_AST.feature.children;
135
+ num_Scenarios += scenarios.length;
136
+
137
+ }
138
+
139
+ // Mutates `new_contents`
140
+ new_contents = new_files.join(`\n\n`);
141
+
142
+ if ( do_compare ) {
143
+ // Mutates `comparable`
144
+ comparable = comparable_text( new_contents );
145
+ // Mutates `text_matches`
146
+ text_matches = comparable === fixture.expected;
147
+ }
148
+ };
149
+
150
+
151
+ describe(`Constrained random answers parser, when given a valid generator Scenario`, function () {
152
+
153
+ describe(`that is simple and normal`, function () {
154
+
155
+ before(function () { mutate_globals_with({ testing_vals: fixtures.simple }); });
156
+
157
+ let outer = fixtures.simple;
158
+ it(`has these exact log codes: ${ JSON.stringify( outer.exact_log_codes )}`, function () {
159
+ expect( get_log_codes({ logger }) ).to.have.all.members( fixture.exact_log_codes );
160
+ });
161
+
162
+ it(`returns no errors`, function () { expect( errors ).to.have.lengthOf( 0 ); });
163
+
164
+ it(`generates 2 Scenarios`, function() {
165
+ expect( num_Scenarios ).to.equal( fixture.num_Scenarios, `Wrong # of Scenarios: ${ num_Scenarios }/${ fixture.num_Scenarios }` );
166
+ });
167
+
168
+ it(`has the right non-random text`, function () {
169
+ expect( comparable_text( new_contents ) ).to.equal( fixture.expected );
170
+ });
171
+
172
+ });
173
+
174
+ describe(`that has "constrain" and "generat" minimal Steps text`, function() {
175
+ before(function () { mutate_globals_with({ testing_vals: fixtures.generat }); });
176
+
177
+ let outer = fixtures.generat;
178
+ it(`has these exact log codes: ${ JSON.stringify( outer.exact_log_codes )}`, function () {
179
+ expect( get_log_codes({ logger }) ).to.have.all.members( fixture.exact_log_codes );
180
+ });
181
+ it(`returns no errors`, function () { expect( errors ).to.have.lengthOf( 0 ); });
182
+ it(`has the right non-random text`, function () {
183
+ expect( comparable_text( new_contents ) ).to.equal( fixture.expected );
184
+ });
185
+ });
186
+
187
+ describe(`that has "constrain" and "rand" minimal Steps text`, function() {
188
+ before(function () { mutate_globals_with({ testing_vals: fixtures.rand }); });
189
+
190
+ let outer = fixtures.rand;
191
+ it(`has these exact log codes: ${ JSON.stringify( outer.exact_log_codes )}`, function () {
192
+ expect( get_log_codes({ logger }) ).to.have.all.members( fixture.exact_log_codes );
193
+ });
194
+ it(`returns no errors`, function () { expect( errors ).to.have.lengthOf( 0 ); });
195
+ it(`has the right non-random text`, function () {
196
+ expect( comparable_text( new_contents ) ).to.equal( fixture.expected );
197
+ });
198
+ });
199
+
200
+ describe(`that has "constrain" and "make" minimal Steps text`, function() {
201
+ before(function () { mutate_globals_with({ testing_vals: fixtures.make }); });
202
+
203
+ let outer = fixtures.make;
204
+ it(`has these exact log codes: ${ JSON.stringify( outer.exact_log_codes )}`, function () {
205
+ expect( get_log_codes({ logger }) ).to.have.all.members( fixture.exact_log_codes );
206
+ });
207
+ it(`returns no errors`, function () { expect( errors ).to.have.lengthOf( 0 ); });
208
+ it(`has the right non-random text`, function () {
209
+ expect( comparable_text( new_contents ) ).to.equal( fixture.expected );
210
+ });
211
+ });
212
+
213
+ describe(`that has "constrain" and "made" minimal Steps text`, function() {
214
+ before(function () { mutate_globals_with({ testing_vals: fixtures.made }); });
215
+
216
+ let outer = fixtures.made;
217
+ it(`has these exact log codes: ${ JSON.stringify( outer.exact_log_codes )}`, function () {
218
+ expect( get_log_codes({ logger }) ).to.have.all.members( fixture.exact_log_codes );
219
+ });
220
+ it(`returns no errors`, function () { expect( errors ).to.have.lengthOf( 0 ); });
221
+ it(`has the right non-random text`, function () {
222
+ expect( comparable_text( new_contents ) ).to.equal( fixture.expected );
223
+ });
224
+ });
225
+
226
+ describe(`that has various complexities with 1 generator asking for 2 tests,`, function () {
227
+
228
+ before(function () { mutate_globals_with({
229
+ testing_vals: fixtures.complex, do_compare: true
230
+ }); });
231
+
232
+ let outer = fixtures.complex;
233
+ it(`includes these log codes: ${ JSON.stringify( outer.included_log_codes )}`, function () {
234
+ expect( get_log_codes({ logger }) ).to.include.members( fixture.included_log_codes );
235
+ });
236
+
237
+ it(`returns no errors`, function () { expect( errors ).to.have.lengthOf( 0 ); });
238
+
239
+ it(`generates 2 Scenarios (skipping the extra appearance of "Scenario:")`, function() {
240
+ expect( num_Scenarios ).to.equal( fixture.num_Scenarios, `Wrong # of Scenarios: ${ num_Scenarios }/${ fixture.num_Scenarios }` );
241
+ });
242
+
243
+ it(`retains the text after the Feature, retains the comments before the table, retains the comments after the table, retains the Step after the table, retains and ignores a commented extraneous generator Step, keeps the comments in the table, has an extra line on the end`, function () {
244
+ expect( comparable ).to.equal( fixture.expected );
245
+ });
246
+
247
+ });
248
+
249
+ describe(`with an author's weird tag spacing`, function () {
250
+
251
+ before(function () { mutate_globals_with({ testing_vals: fixtures.tags }); });
252
+
253
+ let outer = fixtures.tags;
254
+ it(`has these exact log codes: ${ JSON.stringify( outer.exact_log_codes )}`, function () {
255
+ expect( get_log_codes({ logger }) ).to.have.all.members( fixture.exact_log_codes );
256
+ });
257
+
258
+ it(`returns no errors`, function () { expect( errors ).to.have.lengthOf( 0 ); });
259
+
260
+ it(`keeps those tags`, function () {
261
+ expect( comparable_text( new_contents ) ).to.equal( fixture.expected );
262
+ });
263
+ });
264
+
265
+ describe(`with author's tags on line 2`, function () {
266
+
267
+ before(function () { mutate_globals_with({ testing_vals: fixtures.weird_spacing.tags_line_2 }); });
268
+
269
+ let outer = fixtures.weird_spacing.tags_line_2;
270
+ it(`has these exact log codes: ${ JSON.stringify( outer.exact_log_codes )}`, function () {
271
+ expect( get_log_codes({ logger }) ).to.have.all.members( fixture.exact_log_codes );
272
+ });
273
+
274
+ it(`returns no errors`, function () { expect( errors ).to.have.lengthOf( 0 ); });
275
+
276
+ it(`keeps those tags and spacing`, function () {
277
+ expect( comparable_text( new_contents ) ).to.equal( fixture.expected );
278
+ });
279
+ });
280
+
281
+ describe(`with weird spacing in author's tags`, function () {
282
+
283
+ before(function () { mutate_globals_with({ testing_vals: fixtures.weird_spacing.tags }); });
284
+
285
+ let outer = fixtures.weird_spacing.tags;
286
+ it(`has these exact log codes: ${ JSON.stringify( outer.exact_log_codes )}`, function () {
287
+ expect( get_log_codes({ logger }) ).to.have.all.members( fixture.exact_log_codes );
288
+ });
289
+
290
+ it(`returns no errors`, function () { expect( errors ).to.have.lengthOf( 0 ); });
291
+
292
+ it(`keeps that spacing`, function () {
293
+ expect( comparable_text( new_contents ) ).to.equal( fixture.expected );
294
+ });
295
+ });
296
+
297
+ describe(`with weird indentations`, function () {
298
+
299
+ before(function () { mutate_globals_with({ testing_vals: fixtures.weird_spacing.indents }); });
300
+
301
+ let outer = fixtures.weird_spacing.indents;
302
+ it(`has these exact log codes: ${ JSON.stringify( outer.exact_log_codes )}`, function () {
303
+ expect( get_log_codes({ logger }) ).to.have.all.members( fixture.exact_log_codes );
304
+ });
305
+
306
+ it(`returns no errors`, function () { expect( errors ).to.have.lengthOf( 0 ); });
307
+
308
+ it(`keeps those indentation levels`, function () {
309
+ expect( comparable_text( new_contents ) ).to.equal( fixture.expected );
310
+ });
311
+ });
312
+
313
+ describe(`with no spacing in choices`, function () {
314
+
315
+ before(function () { mutate_globals_with({ testing_vals: fixtures.weird_spacing.choices }); });
316
+
317
+ let outer = fixtures.weird_spacing.choices;
318
+ it(`has these exact log codes: ${ JSON.stringify( outer.exact_log_codes )}`, function () {
319
+ expect( get_log_codes({ logger }) ).to.have.all.members( fixture.exact_log_codes );
320
+ });
321
+
322
+ it(`returns no errors`, function () { expect( errors ).to.have.lengthOf( 0 ); });
323
+
324
+ it(`gets a choice correctly`, function () {
325
+ expect( new_contents ).to.match( fixture.find_1 );
326
+ });
327
+ });
328
+
329
+ describe(`with 3 columns`, function () {
330
+
331
+ before(function () { mutate_globals_with({ testing_vals: fixtures.columns_3 }); });
332
+
333
+ let outer = fixtures.columns_3;
334
+ it(`has these exact log codes: ${ JSON.stringify( outer.exact_log_codes )}`, function () {
335
+ expect( get_log_codes({ logger }) ).to.have.all.members( fixture.exact_log_codes );
336
+ });
337
+
338
+ it(`returns no errors`, function () { expect( errors ).to.have.lengthOf( 0 ); });
339
+
340
+ it(`adds a "trigger" column with those values`, function () {
341
+ expect( new_contents ).to.equal( fixture.expected );
342
+ });
343
+ });
344
+
345
+ describe(`with 4 columns`, function () {
346
+
347
+ before(function () { mutate_globals_with({ testing_vals: fixtures.columns_4 }); });
348
+
349
+ let outer = fixtures.columns_4;
350
+ it(`has these exact log codes: ${ JSON.stringify( outer.exact_log_codes )}`, function () {
351
+ expect( get_log_codes({ logger }) ).to.have.all.members( fixture.exact_log_codes );
352
+ });
353
+
354
+ it(`returns no errors`, function () { expect( errors ).to.have.lengthOf( 0 ); });
355
+
356
+ it(`ignores the 4th column`, function () {
357
+ expect( new_contents ).to.equal( fixture.expected );
358
+ });
359
+ });
360
+
361
+ describe(`with comments before and in the table`, function () {
362
+
363
+ before(function () { mutate_globals_with({ testing_vals: fixtures.rows_comments }); });
364
+
365
+ let outer = fixtures.rows_comments;
366
+ it(`has these exact log codes: ${ JSON.stringify( outer.exact_log_codes )}`, function () {
367
+ expect( get_log_codes({ logger }) ).to.have.all.members( fixture.exact_log_codes );
368
+ });
369
+
370
+ it(`returns no errors`, function () { expect( errors ).to.have.lengthOf( 0 ); });
371
+
372
+ it(`removes the comments`, function () {
373
+ expect( comparable_text( new_contents )).to.equal( fixture.expected );
374
+ });
375
+ });
376
+
377
+ describe(`with a comment after the table`, function () {
378
+
379
+ before(function () { mutate_globals_with({ testing_vals: fixtures.comment_after_last_row }); });
380
+
381
+ let outer = fixtures.comment_after_last_row;
382
+ it(`has these exact log codes: ${ JSON.stringify( outer.included_log_codes )}`, function () {
383
+ expect( get_log_codes({ logger }) ).to.include.members( fixture.included_log_codes );
384
+ });
385
+
386
+ it(`returns no errors`, function () { expect( errors ).to.have.lengthOf( 0 ); });
387
+
388
+ it(`keeps and repeats the comment`, function () {
389
+ expect( comparable_text( new_contents )).to.equal( fixture.expected );
390
+ });
391
+ });
392
+
393
+ describe(`with empty rows before and in the table`, function () {
394
+
395
+ before(function () { mutate_globals_with({ testing_vals: fixtures.rows_empty }); });
396
+
397
+ let outer = fixtures.rows_empty;
398
+ it(`has these exact log codes: ${ JSON.stringify( outer.exact_log_codes )}`, function () {
399
+ expect( get_log_codes({ logger }) ).to.have.all.members( fixture.exact_log_codes );
400
+ });
401
+
402
+ it(`returns no errors`, function () { expect( errors ).to.have.lengthOf( 0 ); });
403
+
404
+ it(`removes the empty rows`, function () {
405
+ expect( comparable_text( new_contents )).to.equal( fixture.expected );
406
+ });
407
+ });
408
+
409
+ describe(`with no number value`, function () {
410
+
411
+ before(function () { mutate_globals_with({ testing_vals: fixtures.warnings.no_number }); });
412
+
413
+ let outer = fixtures.warnings.no_number;
414
+ it(`has these exact log codes with warnings: ${ JSON.stringify( outer.exact_log_codes )}`, function () {
415
+ expect( get_log_codes({ logger }) ).to.have.all.members( fixture.exact_log_codes );
416
+ });
417
+
418
+ it(`returns no errors`, function () { expect( errors ).to.have.lengthOf( 0 ); });
419
+
420
+ it(`generates 1 test`, function () {
421
+ expect( comparable_text( new_contents )).to.equal( fixture.expected );
422
+ });
423
+ });
424
+
425
+ describe(`with too many number values in one Step`, function () {
426
+
427
+ before(function () { mutate_globals_with({ testing_vals: fixtures.warnings.multiple_numbers }); });
428
+
429
+ let outer = fixtures.warnings.multiple_numbers;
430
+ it(`has these exact log codes with warnings: ${ JSON.stringify( outer.exact_log_codes )}`, function () {
431
+ expect( get_log_codes({ logger }) ).to.have.all.members( fixture.exact_log_codes );
432
+ });
433
+
434
+ it(`returns no errors`, function () { expect( errors ).to.have.lengthOf( 0 ); });
435
+
436
+ it(`uses the last number given`, function () {
437
+ expect( comparable_text( new_contents )).to.equal( fixture.expected );
438
+ });
439
+ });
440
+
441
+ describe(`with too many "number" Steps in one Scenario`, function () {
442
+
443
+ before(function () { mutate_globals_with({ testing_vals: fixtures.warnings.multiple_number_Steps }); });
444
+
445
+ let outer = fixtures.warnings.multiple_number_Steps;
446
+ it(`has these exact log codes with warnings: ${ JSON.stringify( outer.exact_log_codes )}`, function () {
447
+ expect( get_log_codes({ logger }) ).to.have.all.members( fixture.exact_log_codes );
448
+ });
449
+
450
+ it(`returns no errors`, function () { expect( errors ).to.have.lengthOf( 0 ); });
451
+
452
+ it(`uses the last Step given`, function () {
453
+ expect( comparable_text( new_contents )).to.equal( fixture.expected );
454
+ });
455
+ });
456
+
457
+ describe(`with 2 "number" Steps in one Scenario and both have multiple numbers`, function () {
458
+
459
+ before(function () { mutate_globals_with({ testing_vals: fixtures.warnings.multiple_number_Steps_and_numbers }); });
460
+
461
+ let outer = fixtures.warnings.multiple_number_Steps_and_numbers;
462
+ it(`has these exact log codes with warnings: ${ JSON.stringify( outer.exact_log_codes )}`, function () {
463
+ expect( get_log_codes({ logger }) ).to.have.all.members( fixture.exact_log_codes );
464
+ });
465
+
466
+ it(`returns no errors`, function () { expect( errors ).to.have.lengthOf( 0 ); });
467
+
468
+ it(`uses the last Step and number given`, function () {
469
+ expect( comparable_text( new_contents )).to.equal( fixture.expected );
470
+ });
471
+ });
472
+
473
+ describe(`that asks for 3 tests when only 2 unique tests are possible`, function () {
474
+
475
+ before(function () { mutate_globals_with({ testing_vals: fixtures.warnings.fewer_unique_than_requested }); });
476
+
477
+ let outer = fixtures.warnings.fewer_unique_than_requested;
478
+ it(`has these exact log codes with warnings: ${ JSON.stringify( outer.included_log_codes )}`, function () {
479
+ expect( get_log_codes({ logger }) ).to.include.members( fixture.included_log_codes );
480
+ });
481
+
482
+ it(`returns no errors`, function () { expect( errors ).to.have.lengthOf( 0 ); });
483
+
484
+ it(`returns the right text`, function () {
485
+ expect( comparable_text( new_contents )).to.equal( fixture.expected );
486
+ });
487
+
488
+ it(`only makes 2 tests`, function () {
489
+ expect( num_Scenarios ).to.equal( fixture.num_Scenarios, `Wrong # of Scenarios: ${ num_Scenarios }/${ fixture.num_Scenarios }` );
490
+ });
491
+
492
+ it(`the 2 tests are unique`, function () {
493
+ for ( let to_find_1_of of fixture.find_1_of ) {
494
+ let text_regex = new RegExp( to_find_1_of, `g` );
495
+ let matches = new_contents.match( text_regex );
496
+ expect( matches ).to.be.an(`array`);
497
+ expect( matches.length ).to.equal( 1 );
498
+ }
499
+ });
500
+
501
+ it(`tries at least 10 times`, function(){
502
+ let codes = get_log_codes({ logger });
503
+ // I'm curious about what the big O value of this methodology is
504
+ // Other methods: https://stackoverflow.com/questions/5667888/counting-the-occurrences-frequency-of-array-elements
505
+ let codes_regex = new RegExp( fixture.repeat.code, `g` );
506
+ let codes_str = codes.join(`;`);
507
+ let code_matches = codes_str.match( codes_regex );
508
+ expect( code_matches ).to.be.an(`array`);
509
+ expect( code_matches.length ).to.be.above( fixture.repeat.count - 1 );
510
+ });
511
+ });
512
+
513
+ describe(`that asks for over max # of tests allowed - 1 -`, function () {
514
+
515
+ before(function () { mutate_globals_with({ testing_vals: fixtures.warnings.over_max }); });
516
+
517
+ let outer = fixtures.warnings.over_max;
518
+ it(`has these exact log codes with warnings: ${ JSON.stringify( outer.exact_log_codes )}`, function () {
519
+ expect( get_log_codes({ logger }) ).to.have.all.members( fixture.exact_log_codes );
520
+ });
521
+
522
+ it(`returns no errors`, function () { expect( errors ).to.have.lengthOf( 0 ); });
523
+
524
+ it(`has max # of tests - 1`, function () {
525
+ expect( comparable_text( new_contents )).to.equal( fixture.expected );
526
+ });
527
+
528
+ });
529
+
530
+ describe(`that has a blank var value in a generator column`, function () {
531
+
532
+ before(function () { mutate_globals_with({ testing_vals: fixtures.empty_string_value }); });
533
+
534
+ let outer = fixtures.empty_string_value;
535
+ it(`includes at least one of all these log codes with warnings: ${ JSON.stringify( outer.included_log_codes )}`, function () {
536
+ expect( get_log_codes({ logger }) ).to.include.members( fixture.included_log_codes );
537
+ });
538
+
539
+ it(`returns no errors`, function () { expect( errors ).to.have.lengthOf( 0 ); });
540
+
541
+ it(`has the right non-random text`, function () {
542
+ expect( comparable_text( new_contents ) ).to.equal( fixture.expected );
543
+ });
544
+
545
+ it(`makes 2 tests`, function () {
546
+ expect( num_Scenarios ).to.equal( fixture.num_Scenarios, `Wrong # of Scenarios: ${ num_Scenarios }/${ fixture.num_Scenarios }` );
547
+ });
548
+
549
+ describe(`the "" value does get its own Scenario`, function () {
550
+
551
+ for ( let to_find_1_of of outer.find_1_of ) {
552
+ let text_regex = new RegExp( to_find_1_of, `g` );
553
+ it(`for the var value "${ to_find_1_of }"`, function () {
554
+ let matches = new_contents.match( text_regex );
555
+ expect( matches, `Unable to find column matching ${ to_find_1_of }` ).to.be.an(`array`);
556
+ expect( matches.length ).to.equal( 1 );
557
+ })
558
+ }
559
+
560
+ });
561
+ });
562
+
563
+ });
@@ -169,6 +169,10 @@ describe(`An instance of log`, function () {
169
169
  })
170
170
 
171
171
  describe(`given totally custom metadata`, function () {
172
+ let error;
173
+ before(function() {
174
+ error = new Error(`custom_SUCCESS_error`);
175
+ });
172
176
  it(`.success overwrites the right values`, async function() {
173
177
  let options = {
174
178
  before: `custom_SUCCESS_before~`,
@@ -176,17 +180,22 @@ describe(`An instance of log`, function () {
176
180
  icon: `custom_SUCCESS_icon`,
177
181
  code: `custom_SUCCESS_code`,
178
182
  context: `custom_SUCCESS_context`,
183
+ // Discuss: too complex to test right now? Test separately? Test
184
+ // unexpected file contents?
185
+ error,
179
186
  do_throw: true,
180
187
  };
181
188
  let returned = log.success( options, `custom_SUCCESS_log` );
182
189
  // Note the intentional lack of space with `before`
183
190
  expect( returned ).to.include(`custom_SUCCESS_before~🌈 custom_SUCCESS_code custom_SUCCESS_context SUCCESS`);
184
191
  expect( returned ).to.include(`custom_SUCCESS_log`);
192
+ expect( returned ).to.include( error.stack );
185
193
  expect( returned ).to.not.include(`Skip`);
186
194
  });
187
195
  it(`.success stores the right text in the debug file`, async function() {
188
196
  expect_debug_file_to_include(`custom_SUCCESS_before~🌈 custom_SUCCESS_code custom_SUCCESS_context SUCCESS`);
189
197
  expect_debug_file_to_include(`custom_SUCCESS_log`);
198
+ expect_debug_file_to_include( error.stack );
190
199
  expect_debug_file_to_not_include(`Skip`);
191
200
  });
192
201
  })
@@ -313,10 +322,10 @@ describe(`An instance of log`, function () {
313
322
  } catch ( error ) {
314
323
  error_to_test = error;
315
324
  }
316
- // Note: No metadata is included in the error so that we don't have
317
- // to re-throw every error that comes in and they can keep their nice
318
- // stack traces.
319
- // Note: Also excludes logs from error message
325
+ // Note: No metadata is included in the error so that we don't have to
326
+ // re-throw every error that comes in (in order to add the metadata) and
327
+ // they can keep their nice stack traces. Note: Also excludes logs from
328
+ // error message
320
329
  expect( error_to_test.message ).to.include(`CUSTOM_THROW_ERROR_STRING`);
321
330
  expect( error_to_test.stack ).to.include(`at Log.throw`);
322
331
  expect( error_to_test.stack ).to.not.include(`Skip`);
@@ -435,47 +444,14 @@ describe(`An instance of log`, function () {
435
444
  })
436
445
 
437
446
  describe(`with a value for \`error\` and no throw with .debug()`, function () {
438
- it(`returns a value that excludes the error and the error stack`, async function() {
447
+ it(`returns a value that includes the error and the error stack, but does not throw`, async function() {
439
448
  let options = { error: `custom_DEBUG_non_thrown_error`, };
440
449
  let returned = log.debug( options );
441
- expect( returned ).to.not.include(`custom_DEBUG_non_thrown_error`);
450
+ expect( returned ).to.include(`custom_DEBUG_non_thrown_error`);
442
451
  expect( returned ).to.not.include(`at Log.throw`);
443
452
  });
444
- it(`excludes the error in the debug file`, async function() {
445
- expect_debug_file_to_not_include(`custom_DEBUG_non_thrown_error`);
446
- });
447
- it(`stores the warning code in the debug file`, async function() {
448
- expect_debug_file_to_include(`ALK0223`);
449
- });
450
- it(`stores the text 'Skip' in the debug file`, async function() {
451
- expect_debug_file_to_include(`Skip`);
452
- });
453
- it(`excludes the error in the unexpected output file`, async function() {
454
- expect_unexpected_output_file_to_not_include(`custom_DEBUG_non_thrown_error`);
455
- });
456
- it(`stores the warning code in the unexpected output file`, async function() {
457
- expect_unexpected_output_file_to_include(`ALK0223`);
458
- });
459
- it(`stores the text 'Skip' in the unexpected output file`, async function() {
460
- expect_unexpected_output_file_to_include(`Skip`);
461
- });
462
- })
463
-
464
- describe(`given an error without a do_throw`, function () {
465
- it(`.debug saves a warning and ignores the error`, async function() {
466
- let options = {
467
- error: `Illegal error`,
468
- do_throw: false,
469
- };
470
- let returned = log.debug( options, `DEBUG log with illegal error` );
471
- expect( returned ).to.include(`DEBUG log with illegal error`);
472
- expect( returned ).to.not.include(`Illegal error`);
473
- // To not include `Illegal error`
474
- });
475
- it(`.debug stores and excludes the right text in the debug file`, async function() {
476
- expect_debug_file_to_include(`ALK0223`);
477
- expect_debug_file_to_include(`DEBUG log with illegal error`);
478
- expect_debug_file_to_not_include(`Illegal error`);
453
+ it(`includes the error in the debug file`, async function() {
454
+ expect_debug_file_to_include(`custom_DEBUG_non_thrown_error`);
479
455
  });
480
456
  })
481
457