q5 2.10.7 → 2.10.8

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 (69) hide show
  1. package/deno.json +35 -0
  2. package/package.json +3 -6
  3. package/q5-deno-server.js +38 -0
  4. package/q5-server.js +3 -3
  5. package/q5.js +14 -8
  6. package/q5.min.js +1 -1
  7. package/src/q5-canvas.js +14 -8
  8. package/test/core.test.js +33 -0
  9. package/test/readme.md +5 -0
  10. package/.vscode/launch.json +0 -26
  11. package/.vscode/settings.json +0 -3
  12. package/bun.lockb +0 -0
  13. package/p5-tests/js/chai_helpers.js +0 -20
  14. package/p5-tests/js/mocha_setup.js +0 -2
  15. package/p5-tests/js/modernizr.js +0 -5
  16. package/p5-tests/js/p5_helpers.js +0 -135
  17. package/p5-tests/js/sinon.js +0 -5949
  18. package/p5-tests/mocha.css +0 -289
  19. package/p5-tests/test.html +0 -71
  20. package/p5-tests/unit/color/color_conversion.js +0 -68
  21. package/p5-tests/unit/color/creating_reading.js +0 -217
  22. package/p5-tests/unit/color/p5.Color.js +0 -1000
  23. package/p5-tests/unit/color/setting.js +0 -289
  24. package/p5-tests/unit/core/2d_primitives.js +0 -490
  25. package/p5-tests/unit/core/attributes.js +0 -115
  26. package/p5-tests/unit/core/curves.js +0 -139
  27. package/p5-tests/unit/core/environment.js +0 -248
  28. package/p5-tests/unit/core/error_helpers.js +0 -1158
  29. package/p5-tests/unit/core/main.js +0 -340
  30. package/p5-tests/unit/core/p5.Element.js +0 -773
  31. package/p5-tests/unit/core/p5.Graphics.js +0 -179
  32. package/p5-tests/unit/core/preload.js +0 -285
  33. package/p5-tests/unit/core/rendering.js +0 -116
  34. package/p5-tests/unit/core/structure.js +0 -293
  35. package/p5-tests/unit/core/transform.js +0 -144
  36. package/p5-tests/unit/core/version.js +0 -28
  37. package/p5-tests/unit/core/vertex.js +0 -137
  38. package/p5-tests/unit/dom/dom.js +0 -2146
  39. package/p5-tests/unit/events/acceleration.js +0 -213
  40. package/p5-tests/unit/events/keyboard.js +0 -179
  41. package/p5-tests/unit/events/mouse.js +0 -487
  42. package/p5-tests/unit/events/touch.js +0 -180
  43. package/p5-tests/unit/image/downloading.js +0 -379
  44. package/p5-tests/unit/image/filters.js +0 -92
  45. package/p5-tests/unit/image/loading.js +0 -413
  46. package/p5-tests/unit/image/p5.Image.js +0 -201
  47. package/p5-tests/unit/image/pixels.js +0 -234
  48. package/p5-tests/unit/io/files.js +0 -378
  49. package/p5-tests/unit/io/loadBytes.js +0 -149
  50. package/p5-tests/unit/io/loadImage.js +0 -123
  51. package/p5-tests/unit/io/loadJSON.js +0 -185
  52. package/p5-tests/unit/io/loadModel.js +0 -215
  53. package/p5-tests/unit/io/loadShader.js +0 -176
  54. package/p5-tests/unit/io/loadStrings.js +0 -140
  55. package/p5-tests/unit/io/loadTable.js +0 -183
  56. package/p5-tests/unit/io/loadXML.js +0 -127
  57. package/p5-tests/unit/io/saveModel.js +0 -113
  58. package/p5-tests/unit/io/saveTable.js +0 -142
  59. package/p5-tests/unit/math/calculation.js +0 -452
  60. package/p5-tests/unit/math/noise.js +0 -66
  61. package/p5-tests/unit/math/p5.Vector.js +0 -1886
  62. package/p5-tests/unit/math/random.js +0 -177
  63. package/p5-tests/unit/math/trigonometry.js +0 -144
  64. package/p5-tests/unit/spec.js +0 -50
  65. package/p5-tests/unit/typography/attributes.js +0 -120
  66. package/p5-tests/unit/typography/loadFont.js +0 -162
  67. package/p5-tests/unit/typography/p5.Font.js +0 -63
  68. package/p5-tests/unit/utilities/conversion.js +0 -329
  69. package/p5-tests/unit/utilities/time_date.js +0 -133
@@ -1,1158 +0,0 @@
1
- suite('Error Helpers', function() {
2
- var myp5;
3
-
4
- setup(function(done) {
5
- new p5(function(p) {
6
- p.setup = function() {
7
- myp5 = p;
8
- p5._clearValidateParamsCache();
9
- done();
10
- };
11
- });
12
- });
13
-
14
- teardown(function() {
15
- myp5.remove();
16
- });
17
-
18
- suite('friendly error logger', function() {
19
- test('basic', function() {
20
- assert.doesNotThrow(
21
- function() {
22
- p5._friendlyError('basic', 'basic');
23
- },
24
- Error,
25
- 'got unwanted exception'
26
- );
27
- });
28
- });
29
-
30
- // unit tests for validateParameters
31
- suite('validateParameters: Numbers + optional Constant', function() {
32
- test('arc(): no friendly-err-msg', function() {
33
- assert.doesNotThrow(
34
- function() {
35
- p5._validateParameters('arc', [1, 1, 10.5, 10, 0, Math.PI, 'pie']);
36
- },
37
- Error,
38
- 'got unwanted exception'
39
- );
40
- });
41
- test('arc(): missing param #4, #5', function() {
42
- assert.validationError(function() {
43
- p5._validateParameters('arc', [1, 1, 10.5, 10]);
44
- });
45
- });
46
- test('arc(): missing param #0', function() {
47
- assert.validationError(function() {
48
- p5._validateParameters('arc', [
49
- undefined,
50
- 1,
51
- 10.5,
52
- 10,
53
- 0,
54
- Math.PI,
55
- 'pie'
56
- ]);
57
- });
58
- });
59
- test('arc(): missing param #4', function() {
60
- assert.validationError(function() {
61
- p5._validateParameters('arc', [
62
- 1,
63
- 1,
64
- 10.5,
65
- 10,
66
- undefined,
67
- Math.PI,
68
- 'pie'
69
- ]);
70
- });
71
- });
72
- test('arc(): missing param #5', function() {
73
- assert.validationError(function() {
74
- p5._validateParameters('arc', [1, 1, 10.5, 10, 0, undefined, 'pie']);
75
- });
76
- });
77
- test('arc(): missing param #6, no friendly-err-msg', function() {
78
- assert.doesNotThrow(
79
- function() {
80
- p5._validateParameters('arc', [1, 1, 10.5, 10, 0, Math.PI]);
81
- },
82
- Error,
83
- 'got unwanted exception'
84
- );
85
- });
86
- test('arc(): wrong param type at #0', function() {
87
- assert.validationError(function() {
88
- p5._validateParameters('arc', ['a', 1, 10.5, 10, 0, Math.PI, 'pie']);
89
- });
90
- });
91
- });
92
-
93
- suite('validateParameters: Numbers + optional Constant', function() {
94
- test('rect(): no friendly-err-msg', function() {
95
- assert.doesNotThrow(
96
- function() {
97
- p5._validateParameters('rect', [1, 1, 10.5, 10]);
98
- },
99
- Error,
100
- 'got unwanted exception'
101
- );
102
- });
103
- test('rect(): wrong param type at #0', function() {
104
- assert.validationError(function() {
105
- p5._validateParameters('rect', ['a', 1, 10.5, 10, 0, Math.PI]);
106
- });
107
- });
108
- });
109
-
110
- suite(
111
- 'validateParameters: class, multi-types + optional Numbers',
112
- function() {
113
- test('ambientLight(): no friendly-err-msg', function() {
114
- assert.doesNotThrow(
115
- function() {
116
- var c = myp5.color(255, 204, 0);
117
- p5._validateParameters('ambientLight', [c]);
118
- },
119
- Error,
120
- 'got unwanted exception'
121
- );
122
- });
123
- }
124
- );
125
-
126
- suite('validateParameters: a few edge cases', function() {
127
- // testing for edge cases mentioned in
128
- // https://github.com/processing/p5.js/issues/2740
129
- testUnMinified('color: wrong type for optional parameter', function() {
130
- let err = assert.throws(function() {
131
- p5._validateParameters('color', [0, 0, 0, 'A']);
132
- }, p5.ValidationError);
133
- assert.strictEqual(
134
- err.type,
135
- 'WRONG_TYPE',
136
- 'ValidationError type is correct'
137
- );
138
- });
139
-
140
- testUnMinified('color: superfluous parameter', function() {
141
- assert.throws(function() {
142
- p5._validateParameters('color', [[0, 0, 0], 0]);
143
- }, p5.ValidationError);
144
- // not performing a type check here as it could reasonably fit as
145
- // either WRONG_TYPE or TOO_MANY_ARGUMENTS
146
- });
147
-
148
- testUnMinified('color: wrong element types', function() {
149
- let err = assert.throws(function() {
150
- p5._validateParameters('color', [['A', 'B', 'C']]);
151
- }, p5.ValidationError);
152
- assert.strictEqual(
153
- err.type,
154
- 'WRONG_TYPE',
155
- 'ValidationError type is correct'
156
- );
157
- });
158
-
159
- testUnMinified('rect: null, non-trailing, optional parameter', function() {
160
- let err = assert.throws(function() {
161
- p5._validateParameters('rect', [0, 0, 0, 0, null, 0, 0, 0]);
162
- }, p5.ValidationError);
163
- assert.strictEqual(
164
- err.type,
165
- 'EMPTY_VAR',
166
- 'ValidationError type is correct'
167
- );
168
- });
169
-
170
- testUnMinified('color: too many args + wrong types too', function() {
171
- let err = assert.throws(function() {
172
- p5._validateParameters('color', ['A', 'A', 0, 0, 0, 0, 0, 0, 0, 0]);
173
- }, p5.ValidationError);
174
- assert.strictEqual(
175
- err.type,
176
- 'TOO_MANY_ARGUMENTS',
177
- 'ValidationError type is correct'
178
- );
179
- });
180
-
181
- testUnMinified('line: null string given', function() {
182
- let err = assert.throws(function() {
183
- p5._validateParameters('line', [1, 2, 4, 'null']);
184
- }, p5.ValidationError);
185
- assert.strictEqual(
186
- err.type,
187
- 'WRONG_TYPE',
188
- 'ValidationError type is correct'
189
- );
190
- });
191
-
192
- testUnMinified('line: NaN value given', function() {
193
- let err = assert.throws(function() {
194
- p5._validateParameters('line', [1, 2, 4, NaN]);
195
- }, p5.ValidationError);
196
- assert.strictEqual(
197
- err.type,
198
- 'WRONG_TYPE',
199
- 'ValidationError type is correct'
200
- );
201
- });
202
- });
203
-
204
- suite('validateParameters: trailing undefined arguments', function() {
205
- // see https://github.com/processing/p5.js/issues/4571 for details
206
-
207
- test('color: missing params #1 #2', function() {
208
- // even though color can also be called with one argument, if 3 args
209
- // are passed, it is likely that them being undefined is an accident
210
- assert.validationError(function() {
211
- p5._validateParameters('color', [12, undefined, undefined]);
212
- });
213
- });
214
-
215
- test('random: missing params #0 #1 (both optional)', function() {
216
- // even though the undefined params are optional, since they are passed
217
- // to the function, it is more likely that the user wanted to call the
218
- // function with 2 arguments.
219
- assert.validationError(function() {
220
- p5._validateParameters('random', [undefined, undefined]);
221
- });
222
- });
223
-
224
- // compuslory argument trailing undefined
225
- testUnMinified('circle: missing compulsory param #2', function() {
226
- // should throw an EMPTY_VAR error instead of a TOO_FEW_ARGUMENTS error
227
- let err = assert.throws(function() {
228
- p5._validateParameters('circle', [5, 5, undefined]);
229
- }, p5.ValidationError);
230
- assert.strictEqual(
231
- err.type,
232
- 'EMPTY_VAR',
233
- 'ValidationError type is correct'
234
- );
235
- });
236
- });
237
-
238
- suite('validateParameters: argument tree', function() {
239
- // should not throw a validation error for the same kind of wrong args
240
- // more than once. This prevents repetetive validation logs for a
241
- // function that is called in a loop or draw()
242
- testUnMinified(
243
- 'no repeated validation error for the same wrong arguments',
244
- function() {
245
- assert.validationError(function() {
246
- myp5.color();
247
- });
248
-
249
- assert.doesNotThrow(
250
- function() {
251
- myp5.color(); // Same type of wrong arguments as above
252
- },
253
- p5.ValidationError,
254
- 'got unwanted ValidationError'
255
- );
256
- }
257
- );
258
-
259
- testUnMinified(
260
- 'should throw validation errors for different wrong args',
261
- function() {
262
- assert.validationError(function() {
263
- myp5.color();
264
- });
265
-
266
- assert.validationError(function() {
267
- myp5.color(false);
268
- });
269
- }
270
- );
271
-
272
- testUnMinified('arg tree is built properly', function() {
273
- let myArgTree = p5._getValidateParamsArgTree();
274
- myp5.random();
275
- myp5.random(50);
276
- myp5.random([50, 70, 10]);
277
- assert.strictEqual(
278
- myArgTree.random.seen,
279
- true,
280
- 'tree built correctly for random()'
281
- );
282
- assert.strictEqual(
283
- myArgTree.random.number.seen,
284
- true,
285
- 'tree built correctly for random(min: Number)'
286
- );
287
- assert.strictEqual(
288
- myArgTree.random.as.number.number.number.seen,
289
- true,
290
- 'tree built correctly for random(choices: Array)'
291
- );
292
-
293
- let c = myp5.color(10);
294
- myp5.alpha(c);
295
- assert.strictEqual(
296
- myArgTree.color.number.seen,
297
- true,
298
- 'tree built correctly for color(gray: Number)'
299
- );
300
- assert.strictEqual(
301
- myArgTree.alpha.Color.seen,
302
- true,
303
- 'tree built correctly for alpha(color: p5.Color)'
304
- );
305
- });
306
- });
307
-
308
- suite('validateParameters: multi-format', function() {
309
- test('color(): no friendly-err-msg', function() {
310
- assert.doesNotThrow(
311
- function() {
312
- p5._validateParameters('color', [65]);
313
- },
314
- Error,
315
- 'got unwanted exception'
316
- );
317
- });
318
- test('color(): no friendly-err-msg', function() {
319
- assert.doesNotThrow(
320
- function() {
321
- p5._validateParameters('color', [65, 0.5]);
322
- },
323
- Error,
324
- 'got unwanted exception'
325
- );
326
- });
327
- test('color(): no friendly-err-msg', function() {
328
- assert.doesNotThrow(
329
- function() {
330
- p5._validateParameters('color', [255, 204, 0]);
331
- },
332
- Error,
333
- 'got unwanted exception'
334
- );
335
- });
336
- test('color(): optional parameter, incorrect type', function() {
337
- assert.validationError(function() {
338
- p5._validateParameters('color', [0, 0, 0, 'A']);
339
- });
340
- });
341
- test('color(): extra parameter', function() {
342
- assert.validationError(function() {
343
- p5._validateParameters('color', [[0, 0, 0], 0]);
344
- });
345
- });
346
- test('color(): incorrect element type', function() {
347
- assert.validationError(function() {
348
- p5._validateParameters('color', [['A', 'B', 'C']]);
349
- });
350
- });
351
- test('color(): incorrect parameter count', function() {
352
- assert.validationError(function() {
353
- p5._validateParameters('color', ['A', 'A', 0, 0, 0, 0, 0, 0]);
354
- });
355
- });
356
- });
357
-
358
- suite('helpForMisusedAtTopLevelCode', function() {
359
- var help = function(msg) {
360
- var log = [];
361
- var logger = function(msg) {
362
- log.push(msg);
363
- };
364
-
365
- p5.prototype._helpForMisusedAtTopLevelCode({ message: msg }, logger);
366
- assert.equal(log.length, 1);
367
- return log[0];
368
- };
369
-
370
- test('help for constants is shown', function() {
371
- assert.match(
372
- help("'HALF_PI' is undefined"),
373
- /Did you just try to use p5\.js's HALF_PI constant\?/
374
- );
375
- });
376
-
377
- test('help for functions is shown', function() {
378
- assert.match(
379
- help("'smooth' is undefined"),
380
- /Did you just try to use p5\.js's smooth\(\) function\?/
381
- );
382
- });
383
-
384
- test('help for variables is shown', function() {
385
- assert.match(
386
- help("'focused' is undefined"),
387
- /Did you just try to use p5\.js's focused variable\?/
388
- );
389
- });
390
- });
391
-
392
- suite('misspelling detection', function() {
393
- let log = [];
394
- const logger = function(err) {
395
- log.push(err);
396
- };
397
- let help = function(err) {
398
- p5._fesErrorMonitor(err);
399
- assert.equal(log.length, 1);
400
- return log[0];
401
- };
402
-
403
- setup(function() {
404
- log = [];
405
- p5._fesLogger = logger;
406
- });
407
-
408
- teardown(function() {
409
- p5._fesLogger = null;
410
- });
411
-
412
- testUnMinified('detects capitalization mistakes', function() {
413
- const logMsg = help(new ReferenceError('MouseX is not defined'));
414
- assert.match(
415
- logMsg,
416
- /It seems that you may have accidentally written "MouseX"/
417
- );
418
- assert.match(logMsg, /mouseX/);
419
- });
420
-
421
- testUnMinified('detects spelling mistakes', function() {
422
- const logMsg = help(new ReferenceError('colour is not defined'));
423
- assert.match(
424
- logMsg,
425
- /It seems that you may have accidentally written "colour"/
426
- );
427
- assert.match(logMsg, /color/);
428
- });
429
-
430
- testUnMinified(
431
- 'can give more than one closest matches, if applicable',
432
- function() {
433
- const logMsg = help(new ReferenceError('strok is not defined'));
434
- assert.match(
435
- logMsg,
436
- /It seems that you may have accidentally written "strok"/
437
- );
438
- assert.match(logMsg, /stroke/);
439
- assert.match(logMsg, /STROKE/);
440
- }
441
- );
442
-
443
- testUnMinified('detects spelling + captialization mistakes', function() {
444
- const logMsg = help(new ReferenceError('RandomGossian is not defined'));
445
- assert.match(
446
- logMsg,
447
- /It seems that you may have accidentally written "RandomGossian"/
448
- );
449
- assert.match(logMsg, /randomGaussian/);
450
- });
451
- });
452
-
453
- suite('caps mistakes for user-defined functions (instance mode)', function() {
454
- let myp5;
455
- let log;
456
- const logger = function(err) {
457
- log.push(err);
458
- };
459
- setup(function(done) {
460
- log = [];
461
- p5._fesLogger = logger;
462
- new p5(function(p) {
463
- // intentional capitalization mistake
464
- p.preLoad = function() {};
465
- p.setup = function() {
466
- myp5 = p;
467
- p._fesLogger = logger;
468
- done();
469
- };
470
- });
471
- });
472
-
473
- teardown(function() {
474
- p5._fesLogger = null;
475
- myp5.remove();
476
- });
477
-
478
- testUnMinified(
479
- 'detects capitatilization mistake in instance mode',
480
- function() {
481
- assert.strictEqual(log.length, 1, 'One message is displayed');
482
- assert.match(
483
- log[0],
484
- /It seems that you may have accidentally written preLoad instead of preload/
485
- );
486
- }
487
- );
488
- });
489
-
490
- suite('caps mistakes for user-defined functions (global mode)', function() {
491
- let log;
492
- const logger = function(err) {
493
- log.push(err);
494
- };
495
- testUnMinified(
496
- 'detects capitatilization mistake in global mode',
497
- function() {
498
- return new Promise(function(resolve) {
499
- iframe = createP5Iframe(
500
- [
501
- P5_SCRIPT_TAG,
502
- '<script>',
503
- 'p5._fesLogger = window.logger',
504
- 'function setup() { window.afterSetup();}',
505
- 'function DRAW() {}',
506
- '</script>'
507
- ].join('\n')
508
- );
509
- log = [];
510
- iframe.elt.contentWindow.logger = logger;
511
- iframe.elt.contentWindow.afterSetup = resolve;
512
- }).then(function() {
513
- //let log = iframe.elt.contentWindow.log;
514
- assert.strictEqual(log.length, 1);
515
- assert.match(
516
- log[0],
517
- /It seems that you may have accidentally written DRAW instead of draw/
518
- );
519
- });
520
- }
521
- );
522
- });
523
- });
524
-
525
- // seperating in another suite because these don't need to initialize myp5
526
- // for each test. Instead they initialize p5 in the iframe. These tests are
527
- // also slower than the above ones.
528
- suite('Global Error Handling', function() {
529
- let log;
530
- const WAIT_AND_RESOLVE = [
531
- '<script>',
532
- 'p5._fesLogger = window.logger',
533
- 'let flag = false;',
534
- 'setInterval(() => {',
535
- // just because the log has one element doesn't necessarily mean that the
536
- // handler has finished its job. The flag allows it to take some more time
537
- // after adding the first log message
538
- ' if (window.logger.length > 0) {',
539
- ' if (flag) window.afterSetup();',
540
- ' flag = true;',
541
- ' }',
542
- '}, 50);',
543
- '</script>'
544
- ].join('\n');
545
- const logger = function(err) {
546
- log.push(err);
547
- };
548
- setup(function() {
549
- log = [];
550
- p5._fesLogger = logger;
551
- });
552
-
553
- teardown(function() {
554
- p5._fesLogger = null;
555
- });
556
-
557
- const prepSyntaxTest = (arr, resolve) => {
558
- iframe = createP5Iframe(
559
- [P5_SCRIPT_TAG, WAIT_AND_RESOLVE, '<script>', ...arr, '</script>'].join(
560
- '\n'
561
- )
562
- );
563
- log = [];
564
- iframe.elt.contentWindow.logger = logger;
565
- iframe.elt.contentWindow.afterSetup = resolve;
566
- return iframe;
567
- };
568
-
569
- testUnMinified('identifies errors happenning internally', function() {
570
- return new Promise(function(resolve) {
571
- // quite an unusual way to test, but the error listener doesn't work
572
- // under mocha. Also the stacktrace gets filled with mocha internal
573
- // function calls. Using this method solves both of these problems.
574
- // This method also allows us to test for SyntaxError without messing
575
- // with flow of the other tests
576
- prepSyntaxTest(
577
- [
578
- 'function setup() {',
579
- 'let cnv = createCanvas(400, 400);',
580
- 'cnv.mouseClicked();', // Error in p5 library as no callback passed
581
- '}'
582
- ],
583
- resolve
584
- );
585
- }).then(function() {
586
- assert.strictEqual(log.length, 1);
587
- assert.match(log[0], /inside the p5js library/);
588
- assert.match(log[0], /mouseClicked/);
589
- });
590
- });
591
-
592
- testUnMinified(
593
- 'identifies errors happenning internally in ES6 classes',
594
- function() {
595
- return new Promise(function(resolve) {
596
- prepSyntaxTest(
597
- [
598
- 'function setup() {',
599
- 'let cnv = createCanvas(10, 10, WEBGL);',
600
- 'let fbo = createFramebuffer();',
601
- 'fbo.draw();', // Error in p5 library as no callback passed
602
- '}'
603
- ],
604
- resolve
605
- );
606
- }).then(function() {
607
- assert.strictEqual(log.length, 1);
608
- assert.match(log[0], /inside the p5js library/);
609
- assert.match(log[0], /draw/);
610
- });
611
- }
612
- );
613
-
614
- testUnMinified('identifies errors in preload', function() {
615
- return new Promise(function(resolve) {
616
- prepSyntaxTest(
617
- [
618
- 'function preload() {',
619
- 'circle(5, 5, 2);', // error
620
- '}',
621
- 'function setup() {',
622
- 'createCanvas(10, 10);',
623
- '}'
624
- ],
625
- resolve
626
- );
627
- }).then(function() {
628
- assert.strictEqual(log.length, 1);
629
- assert.match(log[0], /"circle" being called from preload/);
630
- });
631
- });
632
-
633
- testUnMinified("identifies TypeError 'notDefined'", function() {
634
- return new Promise(function(resolve) {
635
- prepSyntaxTest(
636
- [
637
- 'function setup() {',
638
- 'let x = asdfg + 5;', // ReferenceError: asdfg is not defined
639
- '}'
640
- ],
641
- resolve
642
- );
643
- }).then(function() {
644
- assert.strictEqual(log.length, 1);
645
- assert.match(log[0], /asdfg/);
646
- assert.match(log[0], /not defined in the current scope/);
647
- });
648
- });
649
-
650
- testUnMinified(
651
- "identifies SyntaxError 'Invalid or unexpected Token'",
652
- function() {
653
- return new Promise(function(resolve) {
654
- prepSyntaxTest(
655
- [
656
- 'function setup() {',
657
- 'let x = “not a string”', // SyntaxError: Invalid or unexpected token
658
- '}'
659
- ],
660
- resolve
661
- );
662
- }).then(function() {
663
- assert.strictEqual(log.length, 1);
664
- assert.match(log[0], /Syntax Error/);
665
- assert.match(log[0], /JavaScript doesn't recognize/);
666
- });
667
- }
668
- );
669
-
670
- testUnMinified("identifies SyntaxError 'unexpectedToken'", function() {
671
- return new Promise(function(resolve) {
672
- prepSyntaxTest(
673
- [
674
- 'function setup() {',
675
- 'for (let i = 0; i < 5,; ++i) {}', // SyntaxError: Unexpected token
676
- '}'
677
- ],
678
- resolve
679
- );
680
- }).then(function() {
681
- assert.strictEqual(log.length, 1);
682
- assert.match(log[0], /Syntax Error/);
683
- assert.match(log[0], /typo/);
684
- });
685
- });
686
-
687
- testUnMinified("identifies TypeError 'notFunc'", function() {
688
- return new Promise(function(resolve) {
689
- prepSyntaxTest(
690
- [
691
- 'function setup() {',
692
- 'let asdfg = 5',
693
- 'asdfg()', // TypeError: asdfg is not a function
694
- '}'
695
- ],
696
- resolve
697
- );
698
- }).then(function() {
699
- assert.strictEqual(log.length, 1);
700
- assert.match(log[0], /"asdfg" could not be called as a function/);
701
- });
702
- });
703
-
704
- testUnMinified("identifies TypeError 'notFuncObj'", function() {
705
- return new Promise(function(resolve) {
706
- prepSyntaxTest(
707
- [
708
- 'function setup() {',
709
- 'let asdfg = {}',
710
- 'asdfg.abcd()', // TypeError: abcd is not a function
711
- '}'
712
- ],
713
- resolve
714
- );
715
- }).then(function() {
716
- assert.strictEqual(log.length, 1);
717
- assert.match(log[0], /"abcd" could not be called as a function/);
718
- assert.match(log[0], /"asdfg" has "abcd" in it/);
719
- });
720
- });
721
-
722
- testUnMinified("identifies ReferenceError 'cannotAccess'", function() {
723
- return new Promise(function(resolve) {
724
- prepSyntaxTest(
725
- [
726
- 'function setup() {',
727
- 'console.log(x)', // ReferenceError: Cannot access 'x' before initialization
728
- 'let x = 100',
729
- '}'
730
- ],
731
- resolve
732
- );
733
- }).then(function() {
734
- assert.strictEqual(log.length, 1);
735
- assert.match(log[0], /Error/);
736
- assert.match(log[0], /used before declaration/);
737
- });
738
- });
739
-
740
- testUnMinified("identifies SyntaxError 'badReturnOrYield'", function() {
741
- return new Promise(function(resolve) {
742
- prepSyntaxTest(
743
- ['function setup() {', 'let x = 100;', '}', 'return;'],
744
- resolve
745
- );
746
- }).then(function() {
747
- assert.strictEqual(log.length, 1);
748
- assert.match(log[0], /Syntax Error/);
749
- assert.match(log[0], /lies outside of a function/);
750
- });
751
- });
752
-
753
- testUnMinified("identifies SyntaxError 'missingInitializer'", function() {
754
- return new Promise(function(resolve) {
755
- prepSyntaxTest(
756
- [
757
- 'function setup() {',
758
- 'const x;', //SyntaxError: Missing initializer in const declaration
759
- '}'
760
- ],
761
- resolve
762
- );
763
- }).then(function() {
764
- assert.strictEqual(log.length, 1);
765
- assert.match(log[0], /Syntax Error/);
766
- assert.match(log[0], /but not initialized/);
767
- });
768
- });
769
-
770
- testUnMinified("identifies SyntaxError 'redeclaredVariable'", function() {
771
- return new Promise(function(resolve) {
772
- prepSyntaxTest(
773
- [
774
- 'function setup() {',
775
- 'let x=100;',
776
- 'let x=99;', //SyntaxError: Identifier 'x' has already been declared
777
- '}'
778
- ],
779
- resolve
780
- );
781
- }).then(function() {
782
- assert.strictEqual(log.length, 1);
783
- assert.match(log[0], /Syntax Error/);
784
- assert.match(log[0], /JavaScript doesn't allow/);
785
- });
786
- });
787
-
788
- testUnMinified("identifies TypeError 'constAssign'", function() {
789
- return new Promise(function(resolve) {
790
- prepSyntaxTest(
791
- [
792
- 'function setup() {',
793
- 'const x = 100;',
794
- 'x = 10;', //TypeError: Assignment to constant variable
795
- '}'
796
- ],
797
- resolve
798
- );
799
- }).then(function() {
800
- assert.strictEqual(log.length, 1);
801
- assert.match(log[0], /Error/);
802
- assert.match(log[0], /const variable is being/);
803
- });
804
- });
805
-
806
- testUnMinified("identifies TypeError 'readFromNull'", function() {
807
- return new Promise(function(resolve) {
808
- prepSyntaxTest(
809
- [
810
- 'function setup() {',
811
- 'const x = null;',
812
- 'console.log(x.prop);', //TypeError: Cannot read property 'prop' of null
813
- '}'
814
- ],
815
- resolve
816
- );
817
- }).then(function() {
818
- assert.strictEqual(log.length, 1);
819
- assert.match(log[0], /Error/);
820
- assert.match(log[0], /property of null/);
821
- });
822
- });
823
-
824
- testUnMinified("identifies TypeError 'readFromUndefined'", function() {
825
- return new Promise(function(resolve) {
826
- prepSyntaxTest(
827
- [
828
- 'function setup() {',
829
- 'const x = undefined;',
830
- 'console.log(x.prop);', //TypeError: Cannot read property 'prop' of undefined
831
- '}'
832
- ],
833
- resolve
834
- );
835
- }).then(function() {
836
- assert.strictEqual(log.length, 1);
837
- assert.match(log[0], /Error/);
838
- assert.match(log[0], /property of undefined/);
839
- });
840
- });
841
-
842
- testUnMinified('builds friendlyStack', function() {
843
- return new Promise(function(resolve) {
844
- prepSyntaxTest(
845
- [
846
- 'function myfun(){',
847
- 'asdfg()', // ReferenceError
848
- '}',
849
- 'function setup() {',
850
- 'myfun()',
851
- '}'
852
- ],
853
- resolve
854
- );
855
- }).then(function() {
856
- assert.strictEqual(log.length, 2);
857
- let temp = log[1].split('\n');
858
- temp = temp.filter(e => e.trim().length > 0);
859
- assert.strictEqual(temp.length, 4);
860
- assert.match(log[0], /"asdfg" is not defined/);
861
- assert.match(temp[1], /Error at/);
862
- assert.match(temp[1], /myfun/);
863
- assert.match(temp[3], /Called from/);
864
- assert.match(temp[3], /setup/);
865
- });
866
- });
867
-
868
- testUnMinified('indentifies internal error - instance mode', function() {
869
- return new Promise(function(resolve) {
870
- prepSyntaxTest(
871
- [
872
- 'function sketch(p) {',
873
- ' p.setup = function() {',
874
- ' p.stroke();', // error
875
- ' }',
876
- '}',
877
- 'new p5(sketch);'
878
- ],
879
- resolve
880
- );
881
- }).then(function() {
882
- assert.strictEqual(log.length, 1);
883
- assert.match(log[0], /stroke/);
884
- assert.match(log[0], /inside the p5js library/);
885
- });
886
- });
887
-
888
- testUnMinified('indentifies error in preload - instance mode', function() {
889
- return new Promise(function(resolve) {
890
- prepSyntaxTest(
891
- [
892
- 'function sketch(p) {',
893
- ' p.preload = function() {',
894
- ' p.circle(2, 2, 2);', // error
895
- ' }',
896
- ' p.setup = function() {',
897
- ' p.createCanvas(5, 5);',
898
- ' }',
899
- '}',
900
- 'new p5(sketch);'
901
- ],
902
- resolve
903
- );
904
- }).then(function() {
905
- assert.strictEqual(log.length, 1);
906
- assert.match(log[0], /"circle" being called from preload/);
907
- });
908
- });
909
-
910
- testUnMinified('indentifies error in user code - instance mode', function() {
911
- return new Promise(function(resolve) {
912
- prepSyntaxTest(
913
- [
914
- 'function sketch(p) {',
915
- ' p.setup = function() {',
916
- ' myfun();', // ReferenceError: myfun is not defined
917
- ' }',
918
- '}',
919
- 'new p5(sketch);'
920
- ],
921
- resolve
922
- );
923
- }).then(function() {
924
- assert.strictEqual(log.length, 1);
925
- assert.match(log[0], /myfun/);
926
- assert.match(log[0], /is not defined in the current scope/);
927
- });
928
- });
929
- });
930
-
931
- suite('Tests for p5.js sketch_reader', function() {
932
- const WAIT_AND_RESOLVE = [
933
- '<script>',
934
- 'p5._fesLogger = window.logger',
935
- 'let flag = false;',
936
- 'setInterval(() => {',
937
- // just because the log has one element doesn't necessarily mean that the
938
- // handler has finished its job. The flag allows it to take some more time
939
- // after adding the first log message
940
- ' if (window.logger.length > 0) {',
941
- ' if (flag) window.afterSetup();',
942
- ' flag = true;',
943
- ' }',
944
- '}, 50);',
945
- '</script>'
946
- ].join('\n');
947
-
948
- let log;
949
- const logger = function(err) {
950
- log.push(err);
951
- };
952
-
953
- const prepSketchReaderTest = (arr, resolve) => {
954
- iframe = createP5Iframe(
955
- [P5_SCRIPT_TAG, WAIT_AND_RESOLVE, '<script>', ...arr, '</script>'].join(
956
- '\n'
957
- )
958
- );
959
- log = [];
960
- iframe.elt.contentWindow.logger = logger;
961
- iframe.elt.contentWindow.afterSetup = resolve;
962
- return iframe;
963
- };
964
-
965
- testUnMinified(
966
- 'detects reassignment of p5.js constant inside setup',
967
- function() {
968
- return new Promise(function(resolve) {
969
- prepSketchReaderTest(
970
- ['function setup() {', 'let PI = 100', '}'],
971
- resolve
972
- );
973
- }).then(function() {
974
- assert.strictEqual(log.length, 1);
975
- assert.match(log[0], /you have used a p5.js reserved variable/);
976
- });
977
- }
978
- );
979
-
980
- testUnMinified(
981
- 'detects reassignment of p5.js function inside setup',
982
- function() {
983
- return new Promise(function(resolve) {
984
- prepSketchReaderTest(
985
- ['function setup() {', 'let text = 100', '}'],
986
- resolve
987
- );
988
- }).then(function() {
989
- assert.strictEqual(log.length, 1);
990
- assert.match(log[0], /you have used a p5.js reserved function/);
991
- });
992
- }
993
- );
994
-
995
- testUnMinified(
996
- 'detects reassignment of p5.js constant outside setup',
997
- function() {
998
- return new Promise(function(resolve) {
999
- prepSketchReaderTest(['let PI = 100', 'function setup() {}'], resolve);
1000
- }).then(function() {
1001
- assert.strictEqual(log.length, 1);
1002
- assert.match(log[0], /you have used a p5.js reserved variable/);
1003
- });
1004
- }
1005
- );
1006
-
1007
- testUnMinified(
1008
- 'detects reassignment of p5.js function (text) outside setup',
1009
- function() {
1010
- return new Promise(function(resolve) {
1011
- prepSketchReaderTest(
1012
- ['let text = 100', 'function setup() {}'],
1013
- resolve
1014
- );
1015
- }).then(function() {
1016
- assert.strictEqual(log.length, 1);
1017
- assert.match(log[0], /you have used a p5.js reserved function/);
1018
- });
1019
- }
1020
- );
1021
-
1022
- testUnMinified(
1023
- 'detects reassignment of p5.js function (textSize from Typography) outside setup',
1024
- function() {
1025
- return new Promise(function(resolve) {
1026
- prepSketchReaderTest(
1027
- ['let textSize = 100', 'function setup() {}'],
1028
- resolve
1029
- );
1030
- }).then(function() {
1031
- assert.strictEqual(log.length, 1);
1032
- assert.match(log[0], /you have used a p5.js reserved function/);
1033
- });
1034
- }
1035
- );
1036
-
1037
- testUnMinified(
1038
- 'does not detect reassignment of p5.js function (size from TypedDict or Dom) outside setup',
1039
- function() {
1040
- return new Promise(function(resolve) {
1041
- prepSketchReaderTest(
1042
- ['let size = 100', 'function setup() {}'],
1043
- resolve
1044
- );
1045
- }).then(function() {
1046
- assert.strictEqual(log.length, 0);
1047
- });
1048
- }
1049
- );
1050
-
1051
- testUnMinified(
1052
- 'detects reassignment of p5.js function (point from shape) outside setup',
1053
- function() {
1054
- return new Promise(function(resolve) {
1055
- prepSketchReaderTest(
1056
- ['let point = 100', 'function setup() {}'],
1057
- resolve
1058
- );
1059
- }).then(function() {
1060
- assert.strictEqual(log.length, 1);
1061
- assert.match(log[0], /you have used a p5.js reserved function/);
1062
- });
1063
- }
1064
- );
1065
-
1066
- testUnMinified(
1067
- 'detects reassignment of p5.js functions in declaration lists',
1068
- function() {
1069
- return new Promise(function(resolve) {
1070
- prepSketchReaderTest(
1071
- ['function setup() {', 'let x = 2, text = 2;', '}'],
1072
- resolve
1073
- );
1074
- }).then(function() {
1075
- assert.strictEqual(log.length, 1);
1076
- assert.match(log[0], /you have used a p5.js reserved function/);
1077
- });
1078
- }
1079
- );
1080
-
1081
- testUnMinified(
1082
- 'detects reassignment of p5.js functions in declaration lists after function calls',
1083
- function() {
1084
- return new Promise(function(resolve) {
1085
- prepSketchReaderTest(
1086
- [
1087
- 'function setup() {',
1088
- 'let x = constrain(frameCount, 0, 1000), text = 2;',
1089
- '}'
1090
- ],
1091
- resolve
1092
- );
1093
- }).then(function() {
1094
- assert.strictEqual(log.length, 1);
1095
- assert.match(log[0], /you have used a p5.js reserved function/);
1096
- });
1097
- }
1098
- );
1099
-
1100
- testUnMinified(
1101
- 'ignores p5.js functions used in the right hand side of assignment expressions',
1102
- function() {
1103
- return new Promise(function(resolve) {
1104
- prepSketchReaderTest(
1105
- // This will still log an error, as `text` isn't being used correctly
1106
- // here, but the important part is that it doesn't say that we're
1107
- // trying to reassign a reserved function.
1108
- ['function draw() {', 'let x = constrain(100, 0, text);', '}'],
1109
- resolve
1110
- );
1111
- }).then(function() {
1112
- assert.ok(
1113
- !log.some(line =>
1114
- line.match(/you have used a p5.js reserved function/)
1115
- )
1116
- );
1117
- });
1118
- }
1119
- );
1120
-
1121
- testUnMinified(
1122
- 'ignores p5.js function names used as function arguments',
1123
- function() {
1124
- return new Promise(function(resolve) {
1125
- prepSketchReaderTest(
1126
- ['function draw() {', 'let myLog = (text) => print(text);', '}'],
1127
- resolve
1128
- );
1129
- }).then(function() {
1130
- assert.strictEqual(log.length, 0);
1131
- });
1132
- }
1133
- );
1134
-
1135
- testUnMinified(
1136
- 'fails gracefully on inputs too complicated to parse',
1137
- function() {
1138
- return new Promise(function(resolve) {
1139
- prepSketchReaderTest(
1140
- // This technically is redefining text, but it should stop parsing
1141
- // after the double nested brackets rather than try and possibly
1142
- // give a false positive error. This particular assignment will get
1143
- // caught at runtime regardless by
1144
- // `_createFriendlyGlobalFunctionBinder`.
1145
- [
1146
- 'function draw() {',
1147
- 'let x = constrain(millis(), 0, text = 100)',
1148
- '}'
1149
- ],
1150
- resolve
1151
- );
1152
- }).then(function() {
1153
- console.log(log);
1154
- assert.strictEqual(log.length, 0);
1155
- });
1156
- }
1157
- );
1158
- });