@suffolklitlab/alkiln 5.13.2 → 5.13.3-feat-random-2

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 (51) hide show
  1. package/.github/workflows/github_server.yml +10 -8
  2. package/.github/workflows/playground.yml +5 -2
  3. package/.github/workflows/unit_tests.yml +1 -1
  4. package/CHANGELOG.md +32 -1
  5. package/_alkiln_meta/shift_logs.js +75 -0
  6. package/action.yml +89 -31
  7. package/action_for_github_server/action.yml +65 -29
  8. package/docs/4_environments.md +243 -0
  9. package/docs/artifacts_folder_name.md +135 -0
  10. package/docs/constrained_random_tests.md +254 -0
  11. package/docs/decisions/006_which_log_level_to_pick_2024_09_5.md +70 -0
  12. package/docs/decisions/007_getting_and_storing_logs.md +179 -0
  13. package/docs/decisions/move_runtime_config_to_sources_folder.md +5 -0
  14. package/docs/decisions/reports_and_logs_2024_08_11.md +161 -0
  15. package/docs/kinds_of_errors.md +26 -0
  16. package/docs/prioritize_constrained_random_tests.md +60 -0
  17. package/lib/docassemble/docassemble_api_interface.js +77 -51
  18. package/lib/docassemble/server_install.js +32 -9
  19. package/lib/docassemble/setup.js +40 -25
  20. package/lib/docassemble/takedown.js +33 -10
  21. package/lib/globals.js +10 -0
  22. package/lib/run_cucumber.js +141 -69
  23. package/lib/scope.js +101 -77
  24. package/lib/setup/TestGenerator.js +1755 -0
  25. package/lib/setup/artifacts.js +20 -0
  26. package/lib/setup/generate.js +42 -0
  27. package/lib/setup/get_Gherkin_AST.js +26 -0
  28. package/lib/setup/validate.js +89 -0
  29. package/lib/steps.js +132 -54
  30. package/lib/utils/Log.js +1145 -0
  31. package/lib/utils/_alkiln-constrained_random_tests_old.js +1776 -0
  32. package/lib/utils/files.js +18 -11
  33. package/lib/utils/get_error_stacks.js +16 -0
  34. package/lib/utils/reports.js +100 -34
  35. package/lib/utils/session_vars.js +107 -73
  36. package/lib/utils/set_sources_paths.js +98 -0
  37. package/lib/utils/time.js +44 -0
  38. package/package.json +18 -7
  39. package/tests/log_codes/check_codes.sh +18 -13
  40. package/tests/log_codes/log_code_expected_instances.txt +91 -9
  41. package/tests/unit_tests/constrained_random_answers/invalid.fixtures.js +177 -0
  42. package/tests/unit_tests/constrained_random_answers/invalid.test.js +251 -0
  43. package/tests/unit_tests/constrained_random_answers/valid.fixtures.js +936 -0
  44. package/tests/unit_tests/constrained_random_answers/valid.test.js +541 -0
  45. package/tests/unit_tests/example_of_chai_test_lifecycle.js +78 -0
  46. package/tests/unit_tests/getAllFields.test.js +5 -0
  47. package/tests/unit_tests/getMatchingRows.test.js +5 -0
  48. package/tests/unit_tests/log.test.js +557 -0
  49. package/tests/unit_tests/normalizeTable.test.js +5 -0
  50. package/lib/utils/log.js +0 -96
  51. /package/docs/{expected_inernal_results.md → expected_internal_results.md} +0 -0
@@ -0,0 +1,541 @@
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.+))/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
+ // Fresh namespace
100
+ let generator = new TestGenerator();
101
+ // Mutates `fixture`
102
+ fixture = testing_vals;
103
+
104
+ let generators = fixture.arg;
105
+ if ( !Array.isArray( generators )) {
106
+ generators = [ fixture.arg ];
107
+ }
108
+
109
+ // Mutates `errors` and `num_Scenarios`
110
+ errors = [];
111
+ num_Scenarios = 0;
112
+ let new_files = [];
113
+ for ( let generator_text of generators ) {
114
+
115
+ let { new_contents: new_file, errors: new_errors } = generator.parse_file({
116
+ file_text: generator_text,
117
+ generator_path: `used_in_warning_logs`,
118
+ logger
119
+ });
120
+
121
+ new_files.push( new_file );
122
+ errors.push( ...new_errors );
123
+
124
+ // Validate new file. Should always be valid
125
+ let { AST: doc_AST, errors: file_errs } = get_Gherkin_AST({
126
+ file_text: new_file
127
+ });
128
+
129
+ let scenarios = doc_AST.feature.children;
130
+ num_Scenarios += scenarios.length;
131
+
132
+ }
133
+
134
+ // Mutates `new_contents`
135
+ new_contents = new_files.join(`\n\n`);
136
+
137
+ if ( do_compare ) {
138
+ // Mutates `comparable`
139
+ comparable = comparable_text( new_contents );
140
+ // Mutates `text_matches`
141
+ text_matches = comparable === fixture.expected;
142
+ }
143
+ };
144
+
145
+
146
+ describe(`Constrained random answers parser, when given a valid generator Scenario`, function () {
147
+
148
+ describe(`that is simple and normal`, function () {
149
+
150
+ before(function () { mutate_globals_with({ testing_vals: fixtures.simple }); });
151
+
152
+ let outer = fixtures.simple;
153
+ it(`has these exact log codes: ${ JSON.stringify( outer.exact_log_codes )}`, function () {
154
+ expect( get_log_codes({ logger }) ).to.have.all.members( fixture.exact_log_codes );
155
+ });
156
+
157
+ it(`returns no errors`, function () { expect( errors ).to.have.lengthOf( 0 ); });
158
+
159
+ it(`generates 2 Scenarios`, function() {
160
+ expect( num_Scenarios ).to.equal( fixture.num_Scenarios, `Wrong # of Scenarios: ${ num_Scenarios }/${ fixture.num_Scenarios }` );
161
+ });
162
+
163
+ it(`has the right non-random text`, function () {
164
+ expect( comparable_text( new_contents ) ).to.equal( fixture.expected );
165
+ });
166
+
167
+ });
168
+
169
+ describe(`that has "constrain" and "generat" minimal Steps text`, function() {
170
+ before(function () { mutate_globals_with({ testing_vals: fixtures.generat }); });
171
+
172
+ let outer = fixtures.generat;
173
+ it(`has these exact log codes: ${ JSON.stringify( outer.exact_log_codes )}`, function () {
174
+ expect( get_log_codes({ logger }) ).to.have.all.members( fixture.exact_log_codes );
175
+ });
176
+ it(`returns no errors`, function () { expect( errors ).to.have.lengthOf( 0 ); });
177
+ it(`has the right non-random text`, function () {
178
+ expect( comparable_text( new_contents ) ).to.equal( fixture.expected );
179
+ });
180
+ });
181
+
182
+ describe(`that has "constrain" and "rand" minimal Steps text`, function() {
183
+ before(function () { mutate_globals_with({ testing_vals: fixtures.rand }); });
184
+
185
+ let outer = fixtures.rand;
186
+ it(`has these exact log codes: ${ JSON.stringify( outer.exact_log_codes )}`, function () {
187
+ expect( get_log_codes({ logger }) ).to.have.all.members( fixture.exact_log_codes );
188
+ });
189
+ it(`returns no errors`, function () { expect( errors ).to.have.lengthOf( 0 ); });
190
+ it(`has the right non-random text`, function () {
191
+ expect( comparable_text( new_contents ) ).to.equal( fixture.expected );
192
+ });
193
+ });
194
+
195
+ describe(`that has "constrain" and "make" minimal Steps text`, function() {
196
+ before(function () { mutate_globals_with({ testing_vals: fixtures.make }); });
197
+
198
+ let outer = fixtures.make;
199
+ it(`has these exact log codes: ${ JSON.stringify( outer.exact_log_codes )}`, function () {
200
+ expect( get_log_codes({ logger }) ).to.have.all.members( fixture.exact_log_codes );
201
+ });
202
+ it(`returns no errors`, function () { expect( errors ).to.have.lengthOf( 0 ); });
203
+ it(`has the right non-random text`, function () {
204
+ expect( comparable_text( new_contents ) ).to.equal( fixture.expected );
205
+ });
206
+ });
207
+
208
+ describe(`that has "constrain" and "made" minimal Steps text`, function() {
209
+ before(function () { mutate_globals_with({ testing_vals: fixtures.made }); });
210
+
211
+ let outer = fixtures.made;
212
+ it(`has these exact log codes: ${ JSON.stringify( outer.exact_log_codes )}`, function () {
213
+ expect( get_log_codes({ logger }) ).to.have.all.members( fixture.exact_log_codes );
214
+ });
215
+ it(`returns no errors`, function () { expect( errors ).to.have.lengthOf( 0 ); });
216
+ it(`has the right non-random text`, function () {
217
+ expect( comparable_text( new_contents ) ).to.equal( fixture.expected );
218
+ });
219
+ });
220
+
221
+ describe(`that has various complexities with 1 generator asking for 2 tests,`, function () {
222
+
223
+ before(function () { mutate_globals_with({
224
+ testing_vals: fixtures.complex, do_compare: true
225
+ }); });
226
+
227
+ let outer = fixtures.complex;
228
+ it(`includes these log codes: ${ JSON.stringify( outer.included_log_codes )}`, function () {
229
+ expect( get_log_codes({ logger }) ).to.include.members( fixture.included_log_codes );
230
+ });
231
+
232
+ it(`returns no errors`, function () { expect( errors ).to.have.lengthOf( 0 ); });
233
+
234
+ it(`generates 2 Scenarios (skipping the extra appearance of "Scenario:")`, function() {
235
+ expect( num_Scenarios ).to.equal( fixture.num_Scenarios, `Wrong # of Scenarios: ${ num_Scenarios }/${ fixture.num_Scenarios }` );
236
+ });
237
+
238
+ 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 () {
239
+ expect( comparable ).to.equal( fixture.expected );
240
+ });
241
+
242
+ });
243
+
244
+ describe(`with an author's weird tag spacing`, function () {
245
+
246
+ before(function () { mutate_globals_with({ testing_vals: fixtures.tags }); });
247
+
248
+ let outer = fixtures.tags;
249
+ it(`has these exact log codes: ${ JSON.stringify( outer.exact_log_codes )}`, function () {
250
+ expect( get_log_codes({ logger }) ).to.have.all.members( fixture.exact_log_codes );
251
+ });
252
+
253
+ it(`returns no errors`, function () { expect( errors ).to.have.lengthOf( 0 ); });
254
+
255
+ it(`keeps those tags`, function () {
256
+ expect( comparable_text( new_contents ) ).to.equal( fixture.expected );
257
+ });
258
+ });
259
+
260
+ describe(`with author's tags on line 2`, function () {
261
+
262
+ before(function () { mutate_globals_with({ testing_vals: fixtures.weird_spacing.tags_line_2 }); });
263
+
264
+ let outer = fixtures.weird_spacing.tags_line_2;
265
+ it(`has these exact log codes: ${ JSON.stringify( outer.exact_log_codes )}`, function () {
266
+ expect( get_log_codes({ logger }) ).to.have.all.members( fixture.exact_log_codes );
267
+ });
268
+
269
+ it(`returns no errors`, function () { expect( errors ).to.have.lengthOf( 0 ); });
270
+
271
+ it(`keeps those tags and spacing`, function () {
272
+ expect( comparable_text( new_contents ) ).to.equal( fixture.expected );
273
+ });
274
+ });
275
+
276
+ describe(`with weird spacing in author's tags`, function () {
277
+
278
+ before(function () { mutate_globals_with({ testing_vals: fixtures.weird_spacing.tags }); });
279
+
280
+ let outer = fixtures.weird_spacing.tags;
281
+ it(`has these exact log codes: ${ JSON.stringify( outer.exact_log_codes )}`, function () {
282
+ expect( get_log_codes({ logger }) ).to.have.all.members( fixture.exact_log_codes );
283
+ });
284
+
285
+ it(`returns no errors`, function () { expect( errors ).to.have.lengthOf( 0 ); });
286
+
287
+ it(`keeps that spacing`, function () {
288
+ expect( comparable_text( new_contents ) ).to.equal( fixture.expected );
289
+ });
290
+ });
291
+
292
+ describe(`with weird indentations`, function () {
293
+
294
+ before(function () { mutate_globals_with({ testing_vals: fixtures.weird_spacing.indents }); });
295
+
296
+ let outer = fixtures.weird_spacing.indents;
297
+ it(`has these exact log codes: ${ JSON.stringify( outer.exact_log_codes )}`, function () {
298
+ expect( get_log_codes({ logger }) ).to.have.all.members( fixture.exact_log_codes );
299
+ });
300
+
301
+ it(`returns no errors`, function () { expect( errors ).to.have.lengthOf( 0 ); });
302
+
303
+ it(`keeps those indentation levels`, function () {
304
+ expect( comparable_text( new_contents ) ).to.equal( fixture.expected );
305
+ });
306
+ });
307
+
308
+ describe(`with no spacing in choices`, function () {
309
+
310
+ before(function () { mutate_globals_with({ testing_vals: fixtures.weird_spacing.choices }); });
311
+
312
+ let outer = fixtures.weird_spacing.choices;
313
+ it(`has these exact log codes: ${ JSON.stringify( outer.exact_log_codes )}`, function () {
314
+ expect( get_log_codes({ logger }) ).to.have.all.members( fixture.exact_log_codes );
315
+ });
316
+
317
+ it(`returns no errors`, function () { expect( errors ).to.have.lengthOf( 0 ); });
318
+
319
+ it(`gets a choice correctly`, function () {
320
+ expect( new_contents ).to.match( fixture.find_1 );
321
+ });
322
+ });
323
+
324
+ describe(`with 3 columns`, function () {
325
+
326
+ before(function () { mutate_globals_with({ testing_vals: fixtures.columns_3 }); });
327
+
328
+ let outer = fixtures.columns_3;
329
+ it(`has these exact log codes: ${ JSON.stringify( outer.exact_log_codes )}`, function () {
330
+ expect( get_log_codes({ logger }) ).to.have.all.members( fixture.exact_log_codes );
331
+ });
332
+
333
+ it(`returns no errors`, function () { expect( errors ).to.have.lengthOf( 0 ); });
334
+
335
+ it(`adds a "trigger" column with those values`, function () {
336
+ expect( new_contents ).to.equal( fixture.expected );
337
+ });
338
+ });
339
+
340
+ describe(`with 4 columns`, function () {
341
+
342
+ before(function () { mutate_globals_with({ testing_vals: fixtures.columns_4 }); });
343
+
344
+ let outer = fixtures.columns_4;
345
+ it(`has these exact log codes: ${ JSON.stringify( outer.exact_log_codes )}`, function () {
346
+ expect( get_log_codes({ logger }) ).to.have.all.members( fixture.exact_log_codes );
347
+ });
348
+
349
+ it(`returns no errors`, function () { expect( errors ).to.have.lengthOf( 0 ); });
350
+
351
+ it(`ignores the 4th column`, function () {
352
+ expect( new_contents ).to.equal( fixture.expected );
353
+ });
354
+ });
355
+
356
+ describe(`with comments before and in the table`, function () {
357
+
358
+ before(function () { mutate_globals_with({ testing_vals: fixtures.rows_comments }); });
359
+
360
+ let outer = fixtures.rows_comments;
361
+ it(`has these exact log codes: ${ JSON.stringify( outer.exact_log_codes )}`, function () {
362
+ expect( get_log_codes({ logger }) ).to.have.all.members( fixture.exact_log_codes );
363
+ });
364
+
365
+ it(`returns no errors`, function () { expect( errors ).to.have.lengthOf( 0 ); });
366
+
367
+ it(`removes the comments`, function () {
368
+ expect( comparable_text( new_contents )).to.equal( fixture.expected );
369
+ });
370
+ });
371
+
372
+ describe(`with a comment after the table`, function () {
373
+
374
+ before(function () { mutate_globals_with({ testing_vals: fixtures.comment_after_last_row }); });
375
+
376
+ let outer = fixtures.comment_after_last_row;
377
+ it(`has these exact log codes: ${ JSON.stringify( outer.included_log_codes )}`, function () {
378
+ expect( get_log_codes({ logger }) ).to.include.members( fixture.included_log_codes );
379
+ });
380
+
381
+ it(`returns no errors`, function () { expect( errors ).to.have.lengthOf( 0 ); });
382
+
383
+ it(`keeps and repeats the comment`, function () {
384
+ expect( comparable_text( new_contents )).to.equal( fixture.expected );
385
+ });
386
+ });
387
+
388
+ describe(`with empty rows before and in the table`, function () {
389
+
390
+ before(function () { mutate_globals_with({ testing_vals: fixtures.rows_empty }); });
391
+
392
+ let outer = fixtures.rows_empty;
393
+ it(`has these exact log codes: ${ JSON.stringify( outer.exact_log_codes )}`, function () {
394
+ expect( get_log_codes({ logger }) ).to.have.all.members( fixture.exact_log_codes );
395
+ });
396
+
397
+ it(`returns no errors`, function () { expect( errors ).to.have.lengthOf( 0 ); });
398
+
399
+ it(`removes the empty rows`, function () {
400
+ expect( comparable_text( new_contents )).to.equal( fixture.expected );
401
+ });
402
+ });
403
+
404
+ describe(`with no number value`, function () {
405
+
406
+ before(function () { mutate_globals_with({ testing_vals: fixtures.warnings.no_number }); });
407
+
408
+ let outer = fixtures.warnings.no_number;
409
+ it(`has these exact log codes with warnings: ${ JSON.stringify( outer.exact_log_codes )}`, function () {
410
+ expect( get_log_codes({ logger }) ).to.have.all.members( fixture.exact_log_codes );
411
+ });
412
+
413
+ it(`returns no errors`, function () { expect( errors ).to.have.lengthOf( 0 ); });
414
+
415
+ it(`generates 1 test`, function () {
416
+ expect( comparable_text( new_contents )).to.equal( fixture.expected );
417
+ });
418
+ });
419
+
420
+ describe(`with too many number values in one Step`, function () {
421
+
422
+ before(function () { mutate_globals_with({ testing_vals: fixtures.warnings.multiple_numbers }); });
423
+
424
+ let outer = fixtures.warnings.multiple_numbers;
425
+ it(`has these exact log codes with warnings: ${ JSON.stringify( outer.exact_log_codes )}`, function () {
426
+ expect( get_log_codes({ logger }) ).to.have.all.members( fixture.exact_log_codes );
427
+ });
428
+
429
+ it(`returns no errors`, function () { expect( errors ).to.have.lengthOf( 0 ); });
430
+
431
+ it(`uses the last number given`, function () {
432
+ expect( comparable_text( new_contents )).to.equal( fixture.expected );
433
+ });
434
+ });
435
+
436
+ describe(`with too many "number" Steps in one Scenario`, function () {
437
+
438
+ before(function () { mutate_globals_with({ testing_vals: fixtures.warnings.multiple_number_Steps }); });
439
+
440
+ let outer = fixtures.warnings.multiple_number_Steps;
441
+ it(`has these exact log codes with warnings: ${ JSON.stringify( outer.exact_log_codes )}`, function () {
442
+ expect( get_log_codes({ logger }) ).to.have.all.members( fixture.exact_log_codes );
443
+ });
444
+
445
+ it(`returns no errors`, function () { expect( errors ).to.have.lengthOf( 0 ); });
446
+
447
+ it(`uses the last Step given`, function () {
448
+ expect( comparable_text( new_contents )).to.equal( fixture.expected );
449
+ });
450
+ });
451
+
452
+ describe(`with 2 "number" Steps in one Scenario and both have multiple numbers`, function () {
453
+
454
+ before(function () { mutate_globals_with({ testing_vals: fixtures.warnings.multiple_number_Steps_and_numbers }); });
455
+
456
+ let outer = fixtures.warnings.multiple_number_Steps_and_numbers;
457
+ it(`has these exact log codes with warnings: ${ JSON.stringify( outer.exact_log_codes )}`, function () {
458
+ expect( get_log_codes({ logger }) ).to.have.all.members( fixture.exact_log_codes );
459
+ });
460
+
461
+ it(`returns no errors`, function () { expect( errors ).to.have.lengthOf( 0 ); });
462
+
463
+ it(`uses the last Step and number given`, function () {
464
+ expect( comparable_text( new_contents )).to.equal( fixture.expected );
465
+ });
466
+ });
467
+
468
+ describe(`that asks for 3 tests when only 2 unique tests are possible`, function () {
469
+
470
+ before(function () { mutate_globals_with({ testing_vals: fixtures.warnings.fewer_unique_than_requested }); });
471
+
472
+ let outer = fixtures.warnings.fewer_unique_than_requested;
473
+ it(`has these exact log codes with warnings: ${ JSON.stringify( outer.included_log_codes )}`, function () {
474
+ expect( get_log_codes({ logger }) ).to.include.members( fixture.included_log_codes );
475
+ });
476
+
477
+ it(`returns no errors`, function () { expect( errors ).to.have.lengthOf( 0 ); });
478
+
479
+ it(`returns the right text`, function () {
480
+ expect( comparable_text( new_contents )).to.equal( fixture.expected );
481
+ });
482
+
483
+ it(`only makes 2 tests`, function () {
484
+ expect( num_Scenarios ).to.equal( fixture.num_Scenarios, `Wrong # of Scenarios: ${ num_Scenarios }/${ fixture.num_Scenarios }` );
485
+ });
486
+
487
+ it(`the 2 tests are unique`, function () {
488
+ for ( let to_find_1_of of fixture.find_1_of ) {
489
+ let text_regex = new RegExp( to_find_1_of, `g` );
490
+ let matches = new_contents.match( text_regex );
491
+ expect( matches ).to.be.an(`array`);
492
+ expect( matches.length ).to.equal( 1 );
493
+ }
494
+ });
495
+
496
+ it(`tries at least 10 times`, function(){
497
+ let codes = get_log_codes({ logger });
498
+ // I'm curious about what the big O value of this methodology is
499
+ // Other methods: https://stackoverflow.com/questions/5667888/counting-the-occurrences-frequency-of-array-elements
500
+ let codes_regex = new RegExp( fixture.repeat.code, `g` );
501
+ let codes_str = codes.join(`;`);
502
+ let code_matches = codes_str.match( codes_regex );
503
+ expect( code_matches ).to.be.an(`array`);
504
+ expect( code_matches.length ).to.be.above( fixture.repeat.count - 1 );
505
+ });
506
+ });
507
+
508
+ describe(`that has a blank var value in a generator column`, function () {
509
+
510
+ before(function () { mutate_globals_with({ testing_vals: fixtures.empty_string_value }); });
511
+
512
+ let outer = fixtures.empty_string_value;
513
+ it(`includes at least one of all these log codes with warnings: ${ JSON.stringify( outer.included_log_codes )}`, function () {
514
+ expect( get_log_codes({ logger }) ).to.include.members( fixture.included_log_codes );
515
+ });
516
+
517
+ it(`returns no errors`, function () { expect( errors ).to.have.lengthOf( 0 ); });
518
+
519
+ it(`has the right non-random text`, function () {
520
+ expect( comparable_text( new_contents ) ).to.equal( fixture.expected );
521
+ });
522
+
523
+ it(`makes 2 tests`, function () {
524
+ expect( num_Scenarios ).to.equal( fixture.num_Scenarios, `Wrong # of Scenarios: ${ num_Scenarios }/${ fixture.num_Scenarios }` );
525
+ });
526
+
527
+ describe(`the "" value does get its own Scenario`, function () {
528
+
529
+ for ( let to_find_1_of of outer.find_1_of ) {
530
+ let text_regex = new RegExp( to_find_1_of, `g` );
531
+ it(`for the var value "${ to_find_1_of }"`, function () {
532
+ let matches = new_contents.match( text_regex );
533
+ expect( matches, `Unable to find column matching ${ to_find_1_of }` ).to.be.an(`array`);
534
+ expect( matches.length ).to.equal( 1 );
535
+ })
536
+ }
537
+
538
+ });
539
+ });
540
+
541
+ });
@@ -0,0 +1,78 @@
1
+ const chai = require(`chai`);
2
+
3
+ describe('chaijs before hooks', function () {
4
+ console.log(1);
5
+ before(() => console.log('--top-level before()'));
6
+ console.log(2);
7
+ beforeEach(() => console.log('--top-level beforeEach()'));
8
+ console.log(3);
9
+ describe('nesting 1', function () {
10
+ console.log(4);
11
+ before(() => console.log('--1. nested before()'));
12
+ console.log(5);
13
+ beforeEach(() => console.log('--1. nested beforeEach()'));
14
+ console.log(6);
15
+ it('is 1st nested spec', () => { console.log(7); return true; });
16
+ console.log(8);
17
+ it('is 2nd nested spec', () => { console.log(9); return true; });
18
+ console.log(10);
19
+ });
20
+ console.log(11);
21
+ describe('nesting 2', function () {
22
+ console.log(12);
23
+ before(() => console.log('--2. nested before()'));
24
+ console.log(13);
25
+ beforeEach(() => console.log('--2. nested beforeEach()'));
26
+ console.log(14);
27
+ it('is 1st nested spec', () => { console.log(15); return true; });
28
+ console.log(16);
29
+ it('is 2nd nested spec', () => { console.log(17); return true; });
30
+ console.log(18);
31
+ });
32
+ console.log(19);
33
+ });
34
+
35
+ /** Result:
36
+ 1
37
+ 2
38
+ 3
39
+ 4
40
+ 5
41
+ 6
42
+ 8
43
+ 10
44
+ 11
45
+ 12
46
+ 13
47
+ 14
48
+ 16
49
+ 18
50
+ 19
51
+
52
+
53
+ chaijs before hooks
54
+ --top-level before()
55
+ nesting 1
56
+ --1. nested before()
57
+ --top-level beforeEach()
58
+ --1. nested beforeEach()
59
+ 7
60
+ ✓ is 1st nested spec
61
+ --top-level beforeEach()
62
+ --1. nested beforeEach()
63
+ 9
64
+ ✓ is 2nd nested spec
65
+ nesting 2
66
+ --2. nested before()
67
+ --top-level beforeEach()
68
+ --2. nested beforeEach()
69
+ 15
70
+ ✓ is 1st nested spec
71
+ --top-level beforeEach()
72
+ --2. nested beforeEach()
73
+ 17
74
+ ✓ is 2nd nested spec
75
+
76
+
77
+ 4 passing (6ms)
78
+ * */
@@ -7,6 +7,11 @@ chai.use(deepEqualInAnyOrder);
7
7
  const html = require('./html.fixtures.js');
8
8
  const fields = require('./fields.fixtures.js');
9
9
  const scope = require('../../lib/scope.js');
10
+
11
+ const Log = require(`../../lib/utils/Log.js`);
12
+ const log = new Log({ path: `_alkiln-misc_artifacts/all_fields_${ Date.now() }`, context: `unit_tests getAllFields` });
13
+ scope.set_log({ log_obj: log });
14
+
10
15
  const getAllFields = scope.getAllFields;
11
16
 
12
17
  chai.config.truncateThreshold = 0
@@ -6,6 +6,11 @@ const tables = require('./tables.fixtures.js');
6
6
  const fields = require('./fields.fixtures.js');
7
7
  const matches = require('./matches.fixtures.js');
8
8
  const scope = require('../../lib/scope.js');
9
+
10
+ const Log = require(`../../lib/utils/Log.js`);
11
+ const log = new Log({ path: `_alkiln-misc_artifacts/matching_rows_${ Date.now() }`, context: `unit_tests getMatchingRows` });
12
+ scope.set_log({ log_obj: log });
13
+
9
14
  const getMatchingRows = scope.getMatchingRows;
10
15
  // Match state var instantiated in steps.js. TODO: Add tests for such rows.
11
16
  scope.row_needs_trigger_flag = `ALKiln: no trigger variable needed`;