q5 2.9.21 → 2.9.23
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.
- package/.vscode/launch.json +26 -0
- package/bun.lockb +0 -0
- package/p5-tests/js/chai_helpers.js +20 -0
- package/p5-tests/js/mocha_setup.js +2 -0
- package/p5-tests/js/modernizr.js +5 -0
- package/p5-tests/js/p5_helpers.js +135 -0
- package/p5-tests/js/sinon.js +5949 -0
- package/p5-tests/mocha.css +289 -0
- package/p5-tests/test.html +71 -0
- package/p5-tests/unit/color/color_conversion.js +68 -0
- package/p5-tests/unit/color/creating_reading.js +217 -0
- package/p5-tests/unit/color/p5.Color.js +1000 -0
- package/p5-tests/unit/color/setting.js +289 -0
- package/p5-tests/unit/core/2d_primitives.js +490 -0
- package/p5-tests/unit/core/attributes.js +115 -0
- package/p5-tests/unit/core/curves.js +139 -0
- package/p5-tests/unit/core/environment.js +248 -0
- package/p5-tests/unit/core/error_helpers.js +1158 -0
- package/p5-tests/unit/core/main.js +340 -0
- package/p5-tests/unit/core/p5.Element.js +773 -0
- package/p5-tests/unit/core/p5.Graphics.js +179 -0
- package/p5-tests/unit/core/preload.js +285 -0
- package/p5-tests/unit/core/rendering.js +116 -0
- package/p5-tests/unit/core/structure.js +293 -0
- package/p5-tests/unit/core/transform.js +144 -0
- package/p5-tests/unit/core/version.js +28 -0
- package/p5-tests/unit/core/vertex.js +137 -0
- package/p5-tests/unit/dom/dom.js +2146 -0
- package/p5-tests/unit/events/acceleration.js +213 -0
- package/p5-tests/unit/events/keyboard.js +179 -0
- package/p5-tests/unit/events/mouse.js +487 -0
- package/p5-tests/unit/events/touch.js +180 -0
- package/p5-tests/unit/image/downloading.js +379 -0
- package/p5-tests/unit/image/filters.js +92 -0
- package/p5-tests/unit/image/loading.js +413 -0
- package/p5-tests/unit/image/p5.Image.js +201 -0
- package/p5-tests/unit/image/pixels.js +234 -0
- package/p5-tests/unit/io/files.js +378 -0
- package/p5-tests/unit/io/loadBytes.js +149 -0
- package/p5-tests/unit/io/loadImage.js +123 -0
- package/p5-tests/unit/io/loadJSON.js +185 -0
- package/p5-tests/unit/io/loadModel.js +215 -0
- package/p5-tests/unit/io/loadShader.js +176 -0
- package/p5-tests/unit/io/loadStrings.js +140 -0
- package/p5-tests/unit/io/loadTable.js +183 -0
- package/p5-tests/unit/io/loadXML.js +127 -0
- package/p5-tests/unit/io/saveModel.js +113 -0
- package/p5-tests/unit/io/saveTable.js +142 -0
- package/p5-tests/unit/math/calculation.js +452 -0
- package/p5-tests/unit/math/noise.js +66 -0
- package/p5-tests/unit/math/p5.Vector.js +1886 -0
- package/p5-tests/unit/math/random.js +177 -0
- package/p5-tests/unit/math/trigonometry.js +144 -0
- package/p5-tests/unit/spec.js +50 -0
- package/p5-tests/unit/typography/attributes.js +120 -0
- package/p5-tests/unit/typography/loadFont.js +162 -0
- package/p5-tests/unit/typography/p5.Font.js +63 -0
- package/p5-tests/unit/utilities/conversion.js +329 -0
- package/p5-tests/unit/utilities/time_date.js +133 -0
- package/package.json +1 -1
- package/q5.js +158 -54
- package/q5.min.js +1 -1
- package/src/q5-2d-canvas.js +8 -2
- package/src/q5-2d-drawing.js +20 -7
- package/src/q5-2d-image.js +4 -1
- package/src/q5-2d-text.js +7 -0
- package/src/q5-canvas.js +6 -5
- package/src/q5-color.js +5 -0
- package/src/q5-core.js +3 -1
- package/src/q5-input.js +12 -0
- package/src/q5-math.js +11 -3
- package/src/q5-record.js +2 -0
- package/src/q5-vector.js +33 -0
- package/src/q5-webgpu-canvas.js +11 -7
- package/src/q5-webgpu-drawing.js +15 -12
- package/src/q5-webgpu-image.js +1 -1
- package/src/q5-webgpu-text.js +22 -15
|
@@ -0,0 +1,2146 @@
|
|
|
1
|
+
suite('DOM', function() {
|
|
2
|
+
suite('p5.prototype.select', function() {
|
|
3
|
+
/**
|
|
4
|
+
* Uses p5 in instance-mode inside a custom container.
|
|
5
|
+
* All elements are attached inside the container for testing
|
|
6
|
+
* And cleaned up on teardown.
|
|
7
|
+
*/
|
|
8
|
+
let myp5;
|
|
9
|
+
let myp5Container;
|
|
10
|
+
|
|
11
|
+
setup(function(done) {
|
|
12
|
+
myp5Container = document.createElement('div');
|
|
13
|
+
document.body.appendChild(myp5Container);
|
|
14
|
+
new p5(function(p) {
|
|
15
|
+
p.setup = function() {
|
|
16
|
+
myp5 = p;
|
|
17
|
+
done();
|
|
18
|
+
};
|
|
19
|
+
}, myp5Container);
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
teardown(function() {
|
|
23
|
+
myp5.remove();
|
|
24
|
+
if (myp5Container && myp5Container.parentNode) {
|
|
25
|
+
myp5Container.parentNode.removeChild(myp5Container);
|
|
26
|
+
}
|
|
27
|
+
p5Container = null;
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
test('should return only one p5.element if match is found', function() {
|
|
31
|
+
// Adding 2 buttons to container
|
|
32
|
+
myp5.createCheckbox('Text 1');
|
|
33
|
+
myp5.createCheckbox('Text 2');
|
|
34
|
+
const result = myp5.select('input');
|
|
35
|
+
|
|
36
|
+
assert.instanceOf(result, p5.Element);
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
const generateButton = (name, className = null) => {
|
|
40
|
+
const button = myp5.createButton(name);
|
|
41
|
+
if (className) {
|
|
42
|
+
button.class(className);
|
|
43
|
+
}
|
|
44
|
+
return button;
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
test('should find element by class name', function() {
|
|
48
|
+
// Creates 2 buttons with same class and test if it selects only one.
|
|
49
|
+
const testClassName = 'test-button';
|
|
50
|
+
const testButton = generateButton('Button 1', testClassName);
|
|
51
|
+
generateButton('Button 2', testClassName);
|
|
52
|
+
|
|
53
|
+
const result = myp5.select(`.${testClassName}`);
|
|
54
|
+
assert.deepEqual(result.elt, testButton.elt);
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
test('should find element by class name from given container', function() {
|
|
58
|
+
// Creates 2 buttons with same class in a container and test if it selects only one.
|
|
59
|
+
const testClassName = 'test-button';
|
|
60
|
+
generateButton('Button 1', testClassName);
|
|
61
|
+
const testButton = generateButton('Button 2', testClassName);
|
|
62
|
+
const testContainer = myp5.createDiv();
|
|
63
|
+
testButton.parent(testContainer);
|
|
64
|
+
|
|
65
|
+
const result = myp5.select(`.${testClassName}`, testContainer);
|
|
66
|
+
assert.deepEqual(testButton.elt, result.elt);
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
test('should return null when no matches are found by class name', function() {
|
|
70
|
+
// Gives unused className and tests if it returns null
|
|
71
|
+
const testClassName = 'test-button';
|
|
72
|
+
generateButton('Test Button', testClassName);
|
|
73
|
+
const result = myp5.select('.classNameWithTypo');
|
|
74
|
+
assert.isNull(result);
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
test('should find element by tag name', function() {
|
|
78
|
+
// Creates 2 similar elements and tests if it selects only one.
|
|
79
|
+
const testButton = generateButton('Button 1');
|
|
80
|
+
generateButton('Button 2');
|
|
81
|
+
const result = myp5.select('button');
|
|
82
|
+
assert.deepEqual(result.elt, testButton.elt);
|
|
83
|
+
});
|
|
84
|
+
|
|
85
|
+
test('should find element by tag name from given container', function() {
|
|
86
|
+
// Creates 2 elements inside and outside of a container and tests if it
|
|
87
|
+
// selects inside the container
|
|
88
|
+
generateButton('Button 1');
|
|
89
|
+
const testButton = generateButton('Button 2');
|
|
90
|
+
const testDiv = myp5.createDiv();
|
|
91
|
+
testButton.parent(testDiv);
|
|
92
|
+
|
|
93
|
+
const result = myp5.select('button', testDiv);
|
|
94
|
+
assert.deepEqual(result.elt, testButton.elt);
|
|
95
|
+
});
|
|
96
|
+
|
|
97
|
+
test('should return null when no matches are found by tag name', function() {
|
|
98
|
+
generateButton('Test Button');
|
|
99
|
+
const result = myp5.select('video', myp5Container);
|
|
100
|
+
assert.isNull(result);
|
|
101
|
+
});
|
|
102
|
+
|
|
103
|
+
const generateDiv = (id = null, className = null) => {
|
|
104
|
+
const div = myp5.createDiv();
|
|
105
|
+
if (id) {
|
|
106
|
+
div.id(id);
|
|
107
|
+
}
|
|
108
|
+
if (className) {
|
|
109
|
+
div.class(className);
|
|
110
|
+
}
|
|
111
|
+
return div;
|
|
112
|
+
};
|
|
113
|
+
|
|
114
|
+
test('should select element in container using CSS selector with ID', function() {
|
|
115
|
+
const divID = 'divId';
|
|
116
|
+
const testDiv = generateDiv(divID);
|
|
117
|
+
const testButton = generateButton('Button 1');
|
|
118
|
+
generateButton('Button 2');
|
|
119
|
+
testButton.parent(testDiv);
|
|
120
|
+
|
|
121
|
+
const result = myp5.select(`#${divID} button`);
|
|
122
|
+
assert.deepEqual(result.elt, testButton.elt);
|
|
123
|
+
});
|
|
124
|
+
|
|
125
|
+
test('should select element in container using CSS selector with class name', function() {
|
|
126
|
+
const divClass = 'divClass';
|
|
127
|
+
const testDiv = generateDiv(null, divClass);
|
|
128
|
+
const testButton = generateButton('Button 1');
|
|
129
|
+
generateButton('Button 2');
|
|
130
|
+
testButton.parent(testDiv);
|
|
131
|
+
|
|
132
|
+
const result = myp5.select(`.${divClass} button`);
|
|
133
|
+
assert.deepEqual(result.elt, testButton.elt);
|
|
134
|
+
});
|
|
135
|
+
});
|
|
136
|
+
|
|
137
|
+
suite('p5.prototype.selectAll', function() {
|
|
138
|
+
let myp5;
|
|
139
|
+
let myp5Container;
|
|
140
|
+
|
|
141
|
+
setup(function(done) {
|
|
142
|
+
myp5Container = document.createElement('div');
|
|
143
|
+
document.body.appendChild(myp5Container);
|
|
144
|
+
new p5(function(p) {
|
|
145
|
+
p.setup = function() {
|
|
146
|
+
myp5 = p;
|
|
147
|
+
let mydiv = document.createElement('div');
|
|
148
|
+
mydiv.setAttribute('id', 'main');
|
|
149
|
+
let childbutton = document.createElement('button');
|
|
150
|
+
childbutton.setAttribute('class', 'p5button');
|
|
151
|
+
mydiv.append(childbutton);
|
|
152
|
+
let otherbutton = document.createElement('button');
|
|
153
|
+
otherbutton.setAttribute('class', 'p5button');
|
|
154
|
+
myp5Container.append(mydiv, otherbutton);
|
|
155
|
+
done();
|
|
156
|
+
};
|
|
157
|
+
}, myp5Container);
|
|
158
|
+
});
|
|
159
|
+
|
|
160
|
+
teardown(function() {
|
|
161
|
+
myp5.remove();
|
|
162
|
+
if (myp5Container && myp5Container.parentNode) {
|
|
163
|
+
myp5Container.parentNode.removeChild(myp5Container);
|
|
164
|
+
}
|
|
165
|
+
myp5Container = null;
|
|
166
|
+
});
|
|
167
|
+
|
|
168
|
+
test('should return an array', function() {
|
|
169
|
+
const elements = myp5.selectAll('button');
|
|
170
|
+
assert.isArray(elements);
|
|
171
|
+
});
|
|
172
|
+
|
|
173
|
+
test('should return empty array when no matching classes are found', function() {
|
|
174
|
+
const elements = myp5.selectAll('.randomElements');
|
|
175
|
+
assert.isArray(elements);
|
|
176
|
+
assert.lengthOf(elements, 0);
|
|
177
|
+
});
|
|
178
|
+
|
|
179
|
+
const matchResults = (p5Results, domResults) => {
|
|
180
|
+
assert.lengthOf(p5Results, domResults.length);
|
|
181
|
+
for (let i = 0; i < p5Results.length; i += 1) {
|
|
182
|
+
assert.deepEqual(p5Results[i].elt, domResults[i]);
|
|
183
|
+
}
|
|
184
|
+
};
|
|
185
|
+
|
|
186
|
+
test('should find all elements with matching class name', function() {
|
|
187
|
+
const testClassName = 'p5button';
|
|
188
|
+
const p5Results = myp5.selectAll(`.${testClassName}`);
|
|
189
|
+
const domResults = myp5Container.getElementsByClassName(testClassName);
|
|
190
|
+
matchResults(p5Results, domResults);
|
|
191
|
+
});
|
|
192
|
+
|
|
193
|
+
test('should find all elements with matching class name in given container', function() {
|
|
194
|
+
const testClassName = 'p5button';
|
|
195
|
+
const parentContainerId = 'main';
|
|
196
|
+
const p5Results = myp5.selectAll(
|
|
197
|
+
`.${testClassName}`,
|
|
198
|
+
`#${parentContainerId}`
|
|
199
|
+
);
|
|
200
|
+
const containerElement = document.getElementById(parentContainerId);
|
|
201
|
+
const domResults = containerElement.getElementsByClassName(testClassName);
|
|
202
|
+
matchResults(p5Results, domResults);
|
|
203
|
+
});
|
|
204
|
+
|
|
205
|
+
test('should find all elements with matching tag name', function() {
|
|
206
|
+
const testTagName = 'button';
|
|
207
|
+
const p5Results = myp5.selectAll(testTagName);
|
|
208
|
+
const domResults = myp5Container.getElementsByTagName(testTagName);
|
|
209
|
+
matchResults(p5Results, domResults);
|
|
210
|
+
});
|
|
211
|
+
|
|
212
|
+
test('should find all elements with matching tag name in given container', function() {
|
|
213
|
+
const testTagName = 'button';
|
|
214
|
+
const parentContainerId = 'main';
|
|
215
|
+
const p5Results = myp5.selectAll(testTagName, `#${parentContainerId}`);
|
|
216
|
+
const containerElement = document.getElementById(parentContainerId);
|
|
217
|
+
const domResults = containerElement.getElementsByTagName(testTagName);
|
|
218
|
+
matchResults(p5Results, domResults);
|
|
219
|
+
});
|
|
220
|
+
|
|
221
|
+
test('should find all elements in container using CSS selector with id', function() {
|
|
222
|
+
const testTagName = 'button';
|
|
223
|
+
const parentContainerId = 'main';
|
|
224
|
+
const p5Results = myp5.selectAll(`#${parentContainerId} ${testTagName}`);
|
|
225
|
+
const containerElement = document.getElementById(parentContainerId);
|
|
226
|
+
const domResults = containerElement.getElementsByTagName(testTagName);
|
|
227
|
+
matchResults(p5Results, domResults);
|
|
228
|
+
});
|
|
229
|
+
});
|
|
230
|
+
|
|
231
|
+
suite('p5.prototype.removeElements', function() {
|
|
232
|
+
let myp5;
|
|
233
|
+
let myp5Container;
|
|
234
|
+
|
|
235
|
+
setup(function(done) {
|
|
236
|
+
myp5Container = document.createElement('div');
|
|
237
|
+
document.body.appendChild(myp5Container);
|
|
238
|
+
new p5(function(p) {
|
|
239
|
+
p.setup = function() {
|
|
240
|
+
// configure p5 to not add a canvas by default.
|
|
241
|
+
p.noCanvas();
|
|
242
|
+
myp5 = p;
|
|
243
|
+
done();
|
|
244
|
+
};
|
|
245
|
+
}, myp5Container);
|
|
246
|
+
});
|
|
247
|
+
|
|
248
|
+
teardown(function() {
|
|
249
|
+
myp5.remove();
|
|
250
|
+
if (myp5Container && myp5Container.parentNode) {
|
|
251
|
+
myp5Container.parentNode.removeChild(myp5Container);
|
|
252
|
+
}
|
|
253
|
+
myp5Container = null;
|
|
254
|
+
});
|
|
255
|
+
|
|
256
|
+
test('should remove all elements created by p5 except Canvas', function() {
|
|
257
|
+
// creates 6 elements one of which is a canvas, then calls
|
|
258
|
+
// removeElements and tests if only canvas is left.
|
|
259
|
+
const tags = ['a', 'button', 'canvas', 'div', 'p', 'video'];
|
|
260
|
+
for (const tag of tags) {
|
|
261
|
+
myp5.createElement(tag);
|
|
262
|
+
}
|
|
263
|
+
// Check if all elements are created.
|
|
264
|
+
assert.deepEqual(myp5Container.childElementCount, tags.length);
|
|
265
|
+
|
|
266
|
+
// Call removeElements and check if only canvas is remaining
|
|
267
|
+
myp5.removeElements();
|
|
268
|
+
assert.deepEqual(myp5Container.childElementCount, 1);
|
|
269
|
+
const remainingElement = myp5Container.children[0];
|
|
270
|
+
assert.instanceOf(remainingElement, HTMLCanvasElement);
|
|
271
|
+
});
|
|
272
|
+
});
|
|
273
|
+
|
|
274
|
+
suite('p5.Element.prototype.changed', function() {
|
|
275
|
+
testSketchWithPromise(
|
|
276
|
+
'should trigger callback when element changes',
|
|
277
|
+
function(sketch, resolve, reject) {
|
|
278
|
+
sketch.setup = function() {
|
|
279
|
+
const testElement = sketch.createSlider(0, 100, 50, 10);
|
|
280
|
+
testElement.changed(resolve);
|
|
281
|
+
testElement.elt.dispatchEvent(new Event('change'));
|
|
282
|
+
};
|
|
283
|
+
}
|
|
284
|
+
);
|
|
285
|
+
|
|
286
|
+
testSketchWithPromise(
|
|
287
|
+
'should not trigger callback after changed(false) is called',
|
|
288
|
+
function(sketch, resolve, reject) {
|
|
289
|
+
sketch.setup = function() {
|
|
290
|
+
const testElement = sketch.createSlider(0, 100, 50, 10);
|
|
291
|
+
// if callback is called, there is some error. so reject
|
|
292
|
+
testElement.changed(reject);
|
|
293
|
+
testElement.changed(false);
|
|
294
|
+
testElement.elt.dispatchEvent(new Event('change'));
|
|
295
|
+
resolve();
|
|
296
|
+
};
|
|
297
|
+
}
|
|
298
|
+
);
|
|
299
|
+
});
|
|
300
|
+
|
|
301
|
+
suite('p5.Element.prototype.input', function() {
|
|
302
|
+
testSketchWithPromise(
|
|
303
|
+
'should trigger callback when input is provided',
|
|
304
|
+
function(sketch, resolve, reject) {
|
|
305
|
+
sketch.setup = function() {
|
|
306
|
+
const testElement = sketch.createElement('input');
|
|
307
|
+
testElement.input(resolve);
|
|
308
|
+
testElement.elt.dispatchEvent(new Event('input'));
|
|
309
|
+
};
|
|
310
|
+
}
|
|
311
|
+
);
|
|
312
|
+
|
|
313
|
+
testSketchWithPromise(
|
|
314
|
+
'should not trigger callback after input(false) is called',
|
|
315
|
+
function(sketch, resolve, reject) {
|
|
316
|
+
sketch.setup = function() {
|
|
317
|
+
const testElement = sketch.createElement('input');
|
|
318
|
+
// if callback is called, there is some error. so reject
|
|
319
|
+
testElement.input(reject);
|
|
320
|
+
testElement.input(false);
|
|
321
|
+
testElement.elt.dispatchEvent(new Event('input'));
|
|
322
|
+
resolve();
|
|
323
|
+
};
|
|
324
|
+
}
|
|
325
|
+
);
|
|
326
|
+
});
|
|
327
|
+
|
|
328
|
+
suite('p5.prototype.createDiv', function() {
|
|
329
|
+
let myp5;
|
|
330
|
+
let testElement;
|
|
331
|
+
|
|
332
|
+
setup(function(done) {
|
|
333
|
+
new p5(function(p) {
|
|
334
|
+
p.setup = function() {
|
|
335
|
+
myp5 = p;
|
|
336
|
+
done();
|
|
337
|
+
};
|
|
338
|
+
});
|
|
339
|
+
});
|
|
340
|
+
|
|
341
|
+
teardown(function() {
|
|
342
|
+
myp5.remove();
|
|
343
|
+
if (testElement && testElement.parentNode) {
|
|
344
|
+
testElement.parentNode.removeChild(testElement);
|
|
345
|
+
}
|
|
346
|
+
testElement = null;
|
|
347
|
+
});
|
|
348
|
+
|
|
349
|
+
test('should be a function', function() {
|
|
350
|
+
assert.isFunction(myp5.createDiv);
|
|
351
|
+
});
|
|
352
|
+
|
|
353
|
+
test('should return a p5.Element of div type', function() {
|
|
354
|
+
testElement = myp5.createDiv();
|
|
355
|
+
assert.instanceOf(testElement, p5.Element);
|
|
356
|
+
assert.instanceOf(testElement.elt, HTMLDivElement);
|
|
357
|
+
});
|
|
358
|
+
|
|
359
|
+
test('should set given param as innerHTML of div', function() {
|
|
360
|
+
const testHTML = '<p>Hello</p>';
|
|
361
|
+
testElement = myp5.createDiv(testHTML);
|
|
362
|
+
assert.deepEqual(testElement.elt.innerHTML, testHTML);
|
|
363
|
+
});
|
|
364
|
+
});
|
|
365
|
+
|
|
366
|
+
suite('p5.prototype.createP', function() {
|
|
367
|
+
let myp5;
|
|
368
|
+
let testElement;
|
|
369
|
+
|
|
370
|
+
setup(function(done) {
|
|
371
|
+
new p5(function(p) {
|
|
372
|
+
p.setup = function() {
|
|
373
|
+
myp5 = p;
|
|
374
|
+
done();
|
|
375
|
+
};
|
|
376
|
+
});
|
|
377
|
+
});
|
|
378
|
+
|
|
379
|
+
teardown(function() {
|
|
380
|
+
myp5.remove();
|
|
381
|
+
if (testElement && testElement.parentNode) {
|
|
382
|
+
testElement.parentNode.removeChild(testElement);
|
|
383
|
+
}
|
|
384
|
+
testElement = null;
|
|
385
|
+
});
|
|
386
|
+
|
|
387
|
+
test('should be a function', function() {
|
|
388
|
+
assert.isFunction(myp5.createP);
|
|
389
|
+
});
|
|
390
|
+
|
|
391
|
+
test('should return a p5.Element of p type', function() {
|
|
392
|
+
testElement = myp5.createP();
|
|
393
|
+
assert.instanceOf(testElement, p5.Element);
|
|
394
|
+
assert.instanceOf(testElement.elt, HTMLParagraphElement);
|
|
395
|
+
});
|
|
396
|
+
|
|
397
|
+
test('should set given param as innerHTML of p', function() {
|
|
398
|
+
const testHTML = '<b>Hello</b>';
|
|
399
|
+
testElement = myp5.createP(testHTML);
|
|
400
|
+
assert.deepEqual(testElement.elt.innerHTML, testHTML);
|
|
401
|
+
});
|
|
402
|
+
});
|
|
403
|
+
|
|
404
|
+
suite('p5.prototype.createSpan', function() {
|
|
405
|
+
let myp5;
|
|
406
|
+
let testElement;
|
|
407
|
+
|
|
408
|
+
setup(function(done) {
|
|
409
|
+
new p5(function(p) {
|
|
410
|
+
p.setup = function() {
|
|
411
|
+
myp5 = p;
|
|
412
|
+
done();
|
|
413
|
+
};
|
|
414
|
+
});
|
|
415
|
+
});
|
|
416
|
+
|
|
417
|
+
teardown(function() {
|
|
418
|
+
myp5.remove();
|
|
419
|
+
if (testElement && testElement.parentNode) {
|
|
420
|
+
testElement.parentNode.removeChild(testElement);
|
|
421
|
+
}
|
|
422
|
+
testElement = null;
|
|
423
|
+
});
|
|
424
|
+
|
|
425
|
+
test('should be a function', function() {
|
|
426
|
+
assert.isFunction(myp5.createSpan);
|
|
427
|
+
});
|
|
428
|
+
|
|
429
|
+
test('should return a p5.Element of span type', function() {
|
|
430
|
+
testElement = myp5.createSpan();
|
|
431
|
+
assert.instanceOf(testElement, p5.Element);
|
|
432
|
+
assert.instanceOf(testElement.elt, HTMLSpanElement);
|
|
433
|
+
});
|
|
434
|
+
|
|
435
|
+
test('should set given param as innerHTML of span', function() {
|
|
436
|
+
const testHTML = '<em>Hello</em>';
|
|
437
|
+
testElement = myp5.createSpan(testHTML);
|
|
438
|
+
assert.deepEqual(testElement.elt.innerHTML, testHTML);
|
|
439
|
+
});
|
|
440
|
+
});
|
|
441
|
+
|
|
442
|
+
suite('p5.prototype.createImg', function() {
|
|
443
|
+
let myp5;
|
|
444
|
+
let testElement;
|
|
445
|
+
const imagePath = 'unit/assets/cat.jpg';
|
|
446
|
+
|
|
447
|
+
setup(function(done) {
|
|
448
|
+
new p5(function(p) {
|
|
449
|
+
p.setup = function() {
|
|
450
|
+
myp5 = p;
|
|
451
|
+
done();
|
|
452
|
+
};
|
|
453
|
+
});
|
|
454
|
+
});
|
|
455
|
+
|
|
456
|
+
teardown(function() {
|
|
457
|
+
myp5.remove();
|
|
458
|
+
if (testElement && testElement.parentNode) {
|
|
459
|
+
testElement.parentNode.removeChild(testElement);
|
|
460
|
+
}
|
|
461
|
+
testElement = null;
|
|
462
|
+
});
|
|
463
|
+
|
|
464
|
+
test('should be a function', function() {
|
|
465
|
+
assert.isFunction(myp5.createImg);
|
|
466
|
+
});
|
|
467
|
+
|
|
468
|
+
test('should return p5.Element of image type', function() {
|
|
469
|
+
testElement = myp5.createImg(imagePath, '');
|
|
470
|
+
assert.instanceOf(testElement, p5.Element);
|
|
471
|
+
assert.instanceOf(testElement.elt, HTMLImageElement);
|
|
472
|
+
});
|
|
473
|
+
|
|
474
|
+
test('should set src of image from params', function() {
|
|
475
|
+
testElement = myp5.createImg(imagePath, '');
|
|
476
|
+
assert.isTrue(testElement.elt.src.endsWith(imagePath));
|
|
477
|
+
});
|
|
478
|
+
|
|
479
|
+
test('should set alt from params if given', function() {
|
|
480
|
+
const alternativeText = 'Picture of a cat';
|
|
481
|
+
testElement = myp5.createImg(imagePath, alternativeText);
|
|
482
|
+
assert.deepEqual(testElement.elt.alt, alternativeText);
|
|
483
|
+
});
|
|
484
|
+
|
|
485
|
+
test('should set crossOrigin from params if given', function() {
|
|
486
|
+
const crossOrigin = 'anonymous';
|
|
487
|
+
testElement = myp5.createImg(imagePath, '', crossOrigin);
|
|
488
|
+
assert.deepEqual(testElement.elt.crossOrigin, crossOrigin);
|
|
489
|
+
});
|
|
490
|
+
|
|
491
|
+
testSketchWithPromise(
|
|
492
|
+
'should trigger callback when image is loaded',
|
|
493
|
+
function(sketch, resolve, reject) {
|
|
494
|
+
sketch.setup = function() {
|
|
495
|
+
testElement = sketch.createImg(imagePath, '', '', resolve);
|
|
496
|
+
testElement.elt.dispatchEvent(new Event('load'));
|
|
497
|
+
};
|
|
498
|
+
}
|
|
499
|
+
);
|
|
500
|
+
});
|
|
501
|
+
|
|
502
|
+
suite('p5.prototype.createA', function() {
|
|
503
|
+
let myp5;
|
|
504
|
+
let testElement;
|
|
505
|
+
|
|
506
|
+
setup(function(done) {
|
|
507
|
+
new p5(function(p) {
|
|
508
|
+
p.setup = function() {
|
|
509
|
+
myp5 = p;
|
|
510
|
+
done();
|
|
511
|
+
};
|
|
512
|
+
});
|
|
513
|
+
});
|
|
514
|
+
|
|
515
|
+
teardown(function() {
|
|
516
|
+
myp5.remove();
|
|
517
|
+
if (testElement && testElement.parentNode) {
|
|
518
|
+
testElement.parentNode.removeChild(testElement);
|
|
519
|
+
testElement = null;
|
|
520
|
+
}
|
|
521
|
+
});
|
|
522
|
+
|
|
523
|
+
test('should return a p5.Element of anchor type', () => {
|
|
524
|
+
testElement = myp5.createA('', '');
|
|
525
|
+
assert.instanceOf(testElement, p5.Element);
|
|
526
|
+
assert.instanceOf(testElement.elt, HTMLAnchorElement);
|
|
527
|
+
});
|
|
528
|
+
|
|
529
|
+
test('creates anchor with given link & text', function() {
|
|
530
|
+
const testUrl = 'http://p5js.org/';
|
|
531
|
+
const testText = 'p5js website';
|
|
532
|
+
testElement = myp5.createA(testUrl, testText);
|
|
533
|
+
|
|
534
|
+
assert.deepEqual(testElement.elt.href, testUrl);
|
|
535
|
+
assert.deepEqual(testElement.elt.text, testText);
|
|
536
|
+
});
|
|
537
|
+
|
|
538
|
+
test('creates anchor with given target', function() {
|
|
539
|
+
const testTarget = 'blank';
|
|
540
|
+
testElement = myp5.createA('http://p5js.org', 'p5js website', testTarget);
|
|
541
|
+
assert.deepEqual(testElement.elt.target, testTarget);
|
|
542
|
+
});
|
|
543
|
+
});
|
|
544
|
+
|
|
545
|
+
suite('p5.prototype.createSlider', function() {
|
|
546
|
+
let myp5;
|
|
547
|
+
let testElement;
|
|
548
|
+
|
|
549
|
+
setup(function(done) {
|
|
550
|
+
new p5(function(p) {
|
|
551
|
+
p.setup = function() {
|
|
552
|
+
myp5 = p;
|
|
553
|
+
done();
|
|
554
|
+
};
|
|
555
|
+
});
|
|
556
|
+
});
|
|
557
|
+
|
|
558
|
+
teardown(function() {
|
|
559
|
+
myp5.remove();
|
|
560
|
+
if (testElement && testElement.parentNode) {
|
|
561
|
+
testElement.parentNode.removeChild(testElement);
|
|
562
|
+
}
|
|
563
|
+
testElement = null;
|
|
564
|
+
});
|
|
565
|
+
|
|
566
|
+
test('should return a p5.Element of slider type', () => {
|
|
567
|
+
testElement = myp5.createSlider(0, 100, 0, 1);
|
|
568
|
+
assert.instanceOf(testElement, p5.Element);
|
|
569
|
+
assert.instanceOf(testElement.elt, HTMLInputElement);
|
|
570
|
+
assert.deepEqual(testElement.elt.type, 'range');
|
|
571
|
+
});
|
|
572
|
+
|
|
573
|
+
test('should set min and max values', function() {
|
|
574
|
+
let testElement = myp5.createSlider(20, 80);
|
|
575
|
+
assert.deepEqual(testElement.elt.min, '20');
|
|
576
|
+
assert.deepEqual(testElement.elt.max, '80');
|
|
577
|
+
});
|
|
578
|
+
|
|
579
|
+
test('should set slider position', function() {
|
|
580
|
+
let testElement = myp5.createSlider(20, 80, 50);
|
|
581
|
+
assert.deepEqual(testElement.elt.value, '50');
|
|
582
|
+
});
|
|
583
|
+
|
|
584
|
+
test('should set step value', function() {
|
|
585
|
+
testElement = myp5.createSlider(20, 80, 10, 5);
|
|
586
|
+
assert.deepEqual(testElement.elt.step, '5');
|
|
587
|
+
});
|
|
588
|
+
});
|
|
589
|
+
|
|
590
|
+
suite('p5.prototype.createButton', function() {
|
|
591
|
+
let myp5;
|
|
592
|
+
let testElement;
|
|
593
|
+
|
|
594
|
+
setup(function(done) {
|
|
595
|
+
new p5(function(p) {
|
|
596
|
+
p.setup = function() {
|
|
597
|
+
myp5 = p;
|
|
598
|
+
done();
|
|
599
|
+
};
|
|
600
|
+
});
|
|
601
|
+
});
|
|
602
|
+
teardown(function() {
|
|
603
|
+
myp5.remove();
|
|
604
|
+
if (testElement && testElement.parentNode) {
|
|
605
|
+
testElement.parentNode.removeChild(testElement);
|
|
606
|
+
}
|
|
607
|
+
testElement = null;
|
|
608
|
+
});
|
|
609
|
+
|
|
610
|
+
test('should return a p5.Element of button type', function() {
|
|
611
|
+
testElement = myp5.createButton('testButton', 'testButton');
|
|
612
|
+
assert.instanceOf(testElement, p5.Element);
|
|
613
|
+
assert.instanceOf(testElement.elt, HTMLButtonElement);
|
|
614
|
+
});
|
|
615
|
+
|
|
616
|
+
testSketchWithPromise(
|
|
617
|
+
'should trigger callback when mouse is pressed',
|
|
618
|
+
function(sketch, resolve, reject) {
|
|
619
|
+
sketch.setup = function() {
|
|
620
|
+
const testElement = sketch.createButton('test');
|
|
621
|
+
testElement.mousePressed(resolve);
|
|
622
|
+
testElement.elt.dispatchEvent(new Event('mousedown'));
|
|
623
|
+
};
|
|
624
|
+
}
|
|
625
|
+
);
|
|
626
|
+
});
|
|
627
|
+
|
|
628
|
+
// Tests for createCheckbox
|
|
629
|
+
suite('p5.prototype.createCheckbox', function() {
|
|
630
|
+
let myp5;
|
|
631
|
+
let testElement;
|
|
632
|
+
|
|
633
|
+
setup(function(done) {
|
|
634
|
+
new p5(function(p) {
|
|
635
|
+
p.setup = function() {
|
|
636
|
+
myp5 = p;
|
|
637
|
+
done();
|
|
638
|
+
};
|
|
639
|
+
});
|
|
640
|
+
});
|
|
641
|
+
teardown(function() {
|
|
642
|
+
myp5.remove();
|
|
643
|
+
if (testElement && testElement.parentNode) {
|
|
644
|
+
testElement.parentNode.removeChild(testElement);
|
|
645
|
+
}
|
|
646
|
+
testElement = null;
|
|
647
|
+
});
|
|
648
|
+
|
|
649
|
+
// helper functions
|
|
650
|
+
const getSpanElement = el =>
|
|
651
|
+
el.elt.firstElementChild.getElementsByTagName('span').length
|
|
652
|
+
? el.elt.firstElementChild.getElementsByTagName('span')[0]
|
|
653
|
+
: null;
|
|
654
|
+
|
|
655
|
+
const getCheckboxElement = el =>
|
|
656
|
+
el.elt.firstElementChild.getElementsByTagName('input').length
|
|
657
|
+
? el.elt.firstElementChild.getElementsByTagName('input')[0]
|
|
658
|
+
: null;
|
|
659
|
+
|
|
660
|
+
test('should be a function', function() {
|
|
661
|
+
assert.isFunction(myp5.createCheckbox);
|
|
662
|
+
});
|
|
663
|
+
|
|
664
|
+
test('should return a p5.Element with checkbox as descendant', function() {
|
|
665
|
+
testElement = myp5.createCheckbox();
|
|
666
|
+
const checkboxElement = getCheckboxElement(testElement);
|
|
667
|
+
|
|
668
|
+
assert.instanceOf(testElement, p5.Element);
|
|
669
|
+
assert.instanceOf(checkboxElement, HTMLInputElement);
|
|
670
|
+
});
|
|
671
|
+
|
|
672
|
+
test('calling createCheckbox(label) should create checkbox and set its label', function() {
|
|
673
|
+
const labelValue = 'label';
|
|
674
|
+
testElement = myp5.createCheckbox(labelValue);
|
|
675
|
+
const spanElement = getSpanElement(testElement);
|
|
676
|
+
const testElementLabelValue = getSpanElement(testElement)
|
|
677
|
+
? getSpanElement(testElement).innerHTML
|
|
678
|
+
: '';
|
|
679
|
+
|
|
680
|
+
assert.instanceOf(testElement, p5.Element);
|
|
681
|
+
assert.instanceOf(spanElement, HTMLSpanElement);
|
|
682
|
+
assert.deepEqual(testElementLabelValue, labelValue);
|
|
683
|
+
});
|
|
684
|
+
|
|
685
|
+
test('calling createCheckbox(label, true) should create a checked checkbox and set its label', function() {
|
|
686
|
+
const labelValue = 'label';
|
|
687
|
+
testElement = myp5.createCheckbox(labelValue, true);
|
|
688
|
+
|
|
689
|
+
const spanElement = getSpanElement(testElement);
|
|
690
|
+
const testElementLabelValue = getSpanElement(testElement)
|
|
691
|
+
? getSpanElement(testElement).innerHTML
|
|
692
|
+
: '';
|
|
693
|
+
|
|
694
|
+
assert.instanceOf(testElement, p5.Element);
|
|
695
|
+
assert.instanceOf(spanElement, HTMLSpanElement);
|
|
696
|
+
assert.deepEqual(testElementLabelValue, labelValue);
|
|
697
|
+
assert.isTrue(testElement.checked());
|
|
698
|
+
});
|
|
699
|
+
|
|
700
|
+
test('calling checked() should return checked value of checkbox', function() {
|
|
701
|
+
testElement = myp5.createCheckbox('', true);
|
|
702
|
+
assert.isTrue(testElement.checked());
|
|
703
|
+
});
|
|
704
|
+
|
|
705
|
+
test('calling checked(true) should set checked value of checkbox', function() {
|
|
706
|
+
testElement = myp5.createCheckbox('', false);
|
|
707
|
+
testElement.checked(true);
|
|
708
|
+
assert.isTrue(testElement.checked());
|
|
709
|
+
});
|
|
710
|
+
});
|
|
711
|
+
|
|
712
|
+
suite('p5.prototype.createSelect', function() {
|
|
713
|
+
let myp5;
|
|
714
|
+
let testElement;
|
|
715
|
+
|
|
716
|
+
setup(function(done) {
|
|
717
|
+
new p5(function(p) {
|
|
718
|
+
p.setup = function() {
|
|
719
|
+
myp5 = p;
|
|
720
|
+
done();
|
|
721
|
+
};
|
|
722
|
+
});
|
|
723
|
+
});
|
|
724
|
+
|
|
725
|
+
teardown(function() {
|
|
726
|
+
myp5.remove();
|
|
727
|
+
if (testElement && testElement.parentNode) {
|
|
728
|
+
testElement.parentNode.removeChild(testElement);
|
|
729
|
+
testElement = null;
|
|
730
|
+
}
|
|
731
|
+
});
|
|
732
|
+
|
|
733
|
+
const createHTMLSelect = options => {
|
|
734
|
+
const selectElement = document.createElement('select');
|
|
735
|
+
for (const optionName of options) {
|
|
736
|
+
const option = document.createElement('option');
|
|
737
|
+
option.setAttribute('label', optionName);
|
|
738
|
+
option.setAttribute('value', optionName);
|
|
739
|
+
selectElement.add(option);
|
|
740
|
+
}
|
|
741
|
+
return selectElement;
|
|
742
|
+
};
|
|
743
|
+
|
|
744
|
+
test('should be a function', function() {
|
|
745
|
+
assert.isFunction(myp5.createSelect);
|
|
746
|
+
});
|
|
747
|
+
|
|
748
|
+
test('should return p5.Element of select HTML Element', function() {
|
|
749
|
+
testElement = myp5.createSelect();
|
|
750
|
+
assert.instanceOf(testElement, p5.Element);
|
|
751
|
+
assert.instanceOf(testElement.elt, HTMLSelectElement);
|
|
752
|
+
});
|
|
753
|
+
|
|
754
|
+
test('should return p5.Element when select element is passed', function() {
|
|
755
|
+
selectElement = createHTMLSelect(['option1', 'option2']);
|
|
756
|
+
testElement = myp5.createSelect(selectElement);
|
|
757
|
+
assert.deepEqual(testElement.elt, selectElement);
|
|
758
|
+
});
|
|
759
|
+
|
|
760
|
+
test('calling option(newName) should add a new option', function() {
|
|
761
|
+
const testOptions = ['John', 'Bethany', 'Dwayne'];
|
|
762
|
+
testElement = myp5.createSelect();
|
|
763
|
+
for (const optionName of testOptions) testElement.option(optionName);
|
|
764
|
+
|
|
765
|
+
const htmlOptions = [];
|
|
766
|
+
for (const optionName of testElement.elt.options) {
|
|
767
|
+
assert.deepEqual(optionName.label, optionName.value);
|
|
768
|
+
htmlOptions.push(optionName.label);
|
|
769
|
+
}
|
|
770
|
+
assert.deepEqual(htmlOptions, testOptions);
|
|
771
|
+
});
|
|
772
|
+
|
|
773
|
+
test('calling option(name, newValue) should update value of option', function() {
|
|
774
|
+
const optionName = 'john';
|
|
775
|
+
const testValues = [1, 'abc', true];
|
|
776
|
+
testElement = myp5.createSelect();
|
|
777
|
+
testElement.option(optionName, 0);
|
|
778
|
+
|
|
779
|
+
for (const newValue of testValues) {
|
|
780
|
+
testElement.option(optionName, newValue);
|
|
781
|
+
const htmlValue = testElement.elt.options[0].value;
|
|
782
|
+
assert(htmlValue, newValue);
|
|
783
|
+
}
|
|
784
|
+
});
|
|
785
|
+
|
|
786
|
+
test('calling value() should return current selected option', function() {
|
|
787
|
+
testElement = myp5.createSelect();
|
|
788
|
+
testElement.option('Sunday');
|
|
789
|
+
testElement.option('Monday');
|
|
790
|
+
testElement.elt.options[1].selected = true;
|
|
791
|
+
assert(testElement.value(), 'Monday');
|
|
792
|
+
});
|
|
793
|
+
|
|
794
|
+
test('calling selected() should return all selected options', function() {
|
|
795
|
+
testElement = myp5.createSelect(true);
|
|
796
|
+
options = ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday'];
|
|
797
|
+
for (const optionName of options) testElement.option(optionName);
|
|
798
|
+
|
|
799
|
+
// Select multiple options
|
|
800
|
+
const selectedOptions = options.slice(0, 3);
|
|
801
|
+
for (let i = 0; i < selectedOptions.length; i++) {
|
|
802
|
+
testElement.elt.options[i].selected = true;
|
|
803
|
+
assert.deepEqual(
|
|
804
|
+
testElement.selected(),
|
|
805
|
+
selectedOptions.slice(0, i + 1)
|
|
806
|
+
);
|
|
807
|
+
}
|
|
808
|
+
});
|
|
809
|
+
|
|
810
|
+
test('should update select value when HTML special characters are in the name', function() {
|
|
811
|
+
testElement = myp5.createSelect(true);
|
|
812
|
+
testElement.option('&', 'foo');
|
|
813
|
+
assert.equal(testElement.elt.options.length, 1);
|
|
814
|
+
assert.equal(testElement.elt.options[0].value, 'foo');
|
|
815
|
+
testElement.option('&', 'bar');
|
|
816
|
+
assert.equal(testElement.elt.options[0].value, 'bar');
|
|
817
|
+
});
|
|
818
|
+
|
|
819
|
+
test('calling selected(value) should updated selectedIndex', function() {
|
|
820
|
+
testElement = myp5.createSelect(true);
|
|
821
|
+
options = ['Sunday', 'Monday', 'Tuesday', 'Friday'];
|
|
822
|
+
for (const optionName of options) testElement.option(optionName);
|
|
823
|
+
|
|
824
|
+
// Select multiple options and check if the values get updated
|
|
825
|
+
for (let i = 0; i < options.length; i++) {
|
|
826
|
+
testElement.selected(options[i]);
|
|
827
|
+
const selectedIndexValue =
|
|
828
|
+
testElement.elt.options[testElement.elt.selectedIndex].value;
|
|
829
|
+
assert.deepEqual(selectedIndexValue, options[i]);
|
|
830
|
+
}
|
|
831
|
+
});
|
|
832
|
+
|
|
833
|
+
test('calling disable() should disable the whole dropdown', function() {
|
|
834
|
+
testElement = myp5.createSelect(true);
|
|
835
|
+
testElement.disable();
|
|
836
|
+
|
|
837
|
+
assert.isTrue(testElement.elt.disabled);
|
|
838
|
+
});
|
|
839
|
+
|
|
840
|
+
test('should disable an option when disable() method invoked with option name', function() {
|
|
841
|
+
testElement = myp5.createSelect(true);
|
|
842
|
+
options = ['Sunday', 'Monday', 'Tuesday', 'Friday'];
|
|
843
|
+
for (const optionName of options) testElement.option(optionName);
|
|
844
|
+
|
|
845
|
+
const disabledIndex = 2;
|
|
846
|
+
testElement.disable(options[disabledIndex]);
|
|
847
|
+
assert.isTrue(testElement.elt.options[disabledIndex].disabled);
|
|
848
|
+
assert.isFalse(testElement.elt.options[disabledIndex].selected);
|
|
849
|
+
});
|
|
850
|
+
});
|
|
851
|
+
|
|
852
|
+
suite('p5.prototype.createRadio', function() {
|
|
853
|
+
let myp5;
|
|
854
|
+
let testElement;
|
|
855
|
+
|
|
856
|
+
setup(function(done) {
|
|
857
|
+
new p5(function(p) {
|
|
858
|
+
p.setup = function() {
|
|
859
|
+
myp5 = p;
|
|
860
|
+
done();
|
|
861
|
+
};
|
|
862
|
+
});
|
|
863
|
+
});
|
|
864
|
+
|
|
865
|
+
teardown(function() {
|
|
866
|
+
myp5.remove();
|
|
867
|
+
if (testElement && testElement.parentNode) {
|
|
868
|
+
testElement.parentNode.removeChild(testElement);
|
|
869
|
+
testElement = null;
|
|
870
|
+
}
|
|
871
|
+
});
|
|
872
|
+
|
|
873
|
+
// Helper functions
|
|
874
|
+
const createRadioElement = (options = []) => {
|
|
875
|
+
const radioEl = document.createElement('div');
|
|
876
|
+
for (const option of options) {
|
|
877
|
+
const optionEl = document.createElement('input');
|
|
878
|
+
optionEl.setAttribute('type', 'radio');
|
|
879
|
+
optionEl.setAttribute('value', option);
|
|
880
|
+
radioEl.appendChild(optionEl);
|
|
881
|
+
}
|
|
882
|
+
return radioEl;
|
|
883
|
+
};
|
|
884
|
+
|
|
885
|
+
const isRadioInput = el =>
|
|
886
|
+
el instanceof HTMLInputElement && el.type === 'radio';
|
|
887
|
+
const isLabelElement = el => el instanceof HTMLLabelElement;
|
|
888
|
+
|
|
889
|
+
const getChildren = radioEl =>
|
|
890
|
+
Array.from(radioEl.children)
|
|
891
|
+
.filter(
|
|
892
|
+
el =>
|
|
893
|
+
isRadioInput(el) ||
|
|
894
|
+
(isLabelElement(el) && isRadioInput(el.firstElementChild))
|
|
895
|
+
)
|
|
896
|
+
.map(el => (isRadioInput(el) ? el : el.firstElementChild));
|
|
897
|
+
|
|
898
|
+
test('should be a function', function() {
|
|
899
|
+
assert.isFunction(myp5.createRadio);
|
|
900
|
+
});
|
|
901
|
+
|
|
902
|
+
test('should return p5.Element of radio type', function() {
|
|
903
|
+
testElement = myp5.createRadio();
|
|
904
|
+
assert.instanceOf(testElement, p5.Element);
|
|
905
|
+
assert.instanceOf(testElement.elt, HTMLDivElement);
|
|
906
|
+
});
|
|
907
|
+
|
|
908
|
+
test('should return p5.Element from existing radio Element', function() {
|
|
909
|
+
const options = ['Saturday', 'Sunday'];
|
|
910
|
+
const radioElement = createRadioElement(options);
|
|
911
|
+
testElement = myp5.createRadio(radioElement);
|
|
912
|
+
|
|
913
|
+
assert.deepEqual(testElement.elt, radioElement);
|
|
914
|
+
});
|
|
915
|
+
|
|
916
|
+
test('calling option(value) should return existing radio element', function() {
|
|
917
|
+
const options = ['Saturday', 'Sunday'];
|
|
918
|
+
const radioElement = createRadioElement(options);
|
|
919
|
+
testElement = myp5.createRadio(radioElement);
|
|
920
|
+
for (const radioInput of getChildren(radioElement)) {
|
|
921
|
+
const optionEl = testElement.option(radioInput.value);
|
|
922
|
+
assert.deepEqual(radioInput, optionEl);
|
|
923
|
+
}
|
|
924
|
+
assert.deepEqual(getChildren(testElement.elt).length, options.length);
|
|
925
|
+
});
|
|
926
|
+
|
|
927
|
+
test('calling option(newValue) should create a new radio input', function() {
|
|
928
|
+
const testName = 'defaultRadio';
|
|
929
|
+
const options = ['Saturday', 'Sunday'];
|
|
930
|
+
testElement = myp5.createRadio(testName);
|
|
931
|
+
let count = 0;
|
|
932
|
+
for (const option of options) {
|
|
933
|
+
const optionEl = testElement.option(option);
|
|
934
|
+
assert.instanceOf(optionEl, HTMLInputElement);
|
|
935
|
+
assert.deepEqual(optionEl.type, 'radio');
|
|
936
|
+
assert.deepEqual(optionEl.value, option);
|
|
937
|
+
assert.deepEqual(optionEl.name, testName);
|
|
938
|
+
// Increment by one for every label element
|
|
939
|
+
count += 1;
|
|
940
|
+
|
|
941
|
+
assert.deepEqual(testElement.elt.childElementCount, count);
|
|
942
|
+
}
|
|
943
|
+
});
|
|
944
|
+
|
|
945
|
+
test('calling option(value, label) should set label of option', function() {
|
|
946
|
+
const testName = 'defaultRadio';
|
|
947
|
+
const options = ['Saturday', 'Sunday'];
|
|
948
|
+
testElement = myp5.createRadio(testName);
|
|
949
|
+
for (const option of options) {
|
|
950
|
+
const optionLabel = `${option}-label`;
|
|
951
|
+
const optionEl = testElement.option(option, optionLabel);
|
|
952
|
+
assert.deepEqual(optionEl.value, option);
|
|
953
|
+
assert.deepEqual(optionEl.name, testName);
|
|
954
|
+
const spanEl = optionEl.nextElementSibling;
|
|
955
|
+
assert.deepEqual(spanEl.innerHTML, optionLabel);
|
|
956
|
+
}
|
|
957
|
+
});
|
|
958
|
+
|
|
959
|
+
test('should use given name for all options', function() {
|
|
960
|
+
const testName = 'defaultRadio';
|
|
961
|
+
const options = ['Saturday', 'Sunday'];
|
|
962
|
+
const radioElement = createRadioElement(options);
|
|
963
|
+
testElement = myp5.createRadio(radioElement, testName);
|
|
964
|
+
|
|
965
|
+
for (const option of options) {
|
|
966
|
+
const optionEl = testElement.option(option);
|
|
967
|
+
assert.deepEqual(optionEl.name, testName);
|
|
968
|
+
}
|
|
969
|
+
});
|
|
970
|
+
|
|
971
|
+
test('calling remove(value) should remove option', function() {
|
|
972
|
+
const options = ['Monday', 'Friday', 'Saturday', 'Sunday'];
|
|
973
|
+
const radioElement = createRadioElement(options);
|
|
974
|
+
testElement = myp5.createRadio(radioElement);
|
|
975
|
+
|
|
976
|
+
// Remove element
|
|
977
|
+
const testValue = 'Friday';
|
|
978
|
+
options.splice(options.indexOf(testValue), 1);
|
|
979
|
+
testElement.remove(testValue);
|
|
980
|
+
// Verify remaining options
|
|
981
|
+
const remainingOptions = Array.from(getChildren(testElement.elt)).map(
|
|
982
|
+
el => el.value
|
|
983
|
+
);
|
|
984
|
+
assert.deepEqual(options, remainingOptions);
|
|
985
|
+
});
|
|
986
|
+
|
|
987
|
+
test('calling value() should return selected value', function() {
|
|
988
|
+
const options = ['Monday', 'Friday', 'Saturday', 'Sunday'];
|
|
989
|
+
const selectedValue = options[1];
|
|
990
|
+
testElement = myp5.createRadio();
|
|
991
|
+
for (const option of options) testElement.option(option);
|
|
992
|
+
testElement.selected(selectedValue);
|
|
993
|
+
assert.deepEqual(testElement.value(), selectedValue);
|
|
994
|
+
});
|
|
995
|
+
|
|
996
|
+
test('calling selected(value) should select a value and return it', function() {
|
|
997
|
+
const options = ['Monday', 'Friday', 'Saturday', 'Sunday'];
|
|
998
|
+
testElement = myp5.createRadio();
|
|
999
|
+
for (const option of options) testElement.option(option);
|
|
1000
|
+
|
|
1001
|
+
for (const option of options) {
|
|
1002
|
+
testElement.selected(option);
|
|
1003
|
+
const selectedInput = testElement.option(option);
|
|
1004
|
+
assert.deepEqual(selectedInput.checked, true);
|
|
1005
|
+
}
|
|
1006
|
+
});
|
|
1007
|
+
|
|
1008
|
+
test('calling selected() should return the currently selected option', function() {
|
|
1009
|
+
const options = ['Monday', 'Friday', 'Saturday', 'Sunday'];
|
|
1010
|
+
testElement = myp5.createRadio();
|
|
1011
|
+
for (const option of options) testElement.option(option);
|
|
1012
|
+
|
|
1013
|
+
const testOption = getChildren(testElement.elt)[1];
|
|
1014
|
+
testOption.setAttribute('checked', true);
|
|
1015
|
+
const selectedOption = testElement.selected();
|
|
1016
|
+
assert.deepEqual(selectedOption, testOption);
|
|
1017
|
+
assert.isTrue(selectedOption.checked);
|
|
1018
|
+
});
|
|
1019
|
+
|
|
1020
|
+
test('calling disable() should disable all the radio inputs', function() {
|
|
1021
|
+
const options = ['Monday', 'Friday', 'Saturday', 'Sunday'];
|
|
1022
|
+
testElement = myp5.createRadio();
|
|
1023
|
+
for (const option of options) testElement.option(option);
|
|
1024
|
+
|
|
1025
|
+
testElement.disable();
|
|
1026
|
+
for (const option of options) {
|
|
1027
|
+
assert.isTrue(testElement.option(option).disabled);
|
|
1028
|
+
}
|
|
1029
|
+
});
|
|
1030
|
+
});
|
|
1031
|
+
|
|
1032
|
+
suite('p5.prototype.createColorPicker', function() {
|
|
1033
|
+
let myp5;
|
|
1034
|
+
let testElement;
|
|
1035
|
+
|
|
1036
|
+
setup(function(done) {
|
|
1037
|
+
new p5(function(p) {
|
|
1038
|
+
p.setup = function() {
|
|
1039
|
+
myp5 = p;
|
|
1040
|
+
done();
|
|
1041
|
+
};
|
|
1042
|
+
});
|
|
1043
|
+
});
|
|
1044
|
+
|
|
1045
|
+
teardown(function() {
|
|
1046
|
+
myp5.remove();
|
|
1047
|
+
if (testElement && testElement.parentNode) {
|
|
1048
|
+
testElement.parentNode.removeChild(testElement);
|
|
1049
|
+
}
|
|
1050
|
+
testElement = null;
|
|
1051
|
+
});
|
|
1052
|
+
|
|
1053
|
+
test('should be a function', function() {
|
|
1054
|
+
assert.isFunction(myp5.createColorPicker);
|
|
1055
|
+
});
|
|
1056
|
+
|
|
1057
|
+
test('should return p5.Element of input[color] type', function() {
|
|
1058
|
+
testElement = myp5.createColorPicker();
|
|
1059
|
+
|
|
1060
|
+
assert.instanceOf(testElement, p5.Element);
|
|
1061
|
+
assert.instanceOf(testElement.elt, HTMLInputElement);
|
|
1062
|
+
assert.deepEqual(testElement.elt.type, 'color');
|
|
1063
|
+
});
|
|
1064
|
+
|
|
1065
|
+
test('should accept a p5.Color as param', function() {
|
|
1066
|
+
const testColor = myp5.color('red');
|
|
1067
|
+
testElement = myp5.createColorPicker(testColor);
|
|
1068
|
+
|
|
1069
|
+
assert.deepEqual(testElement.elt.value, testColor.toString('#rrggbb'));
|
|
1070
|
+
});
|
|
1071
|
+
|
|
1072
|
+
test('should accept a string as param', function() {
|
|
1073
|
+
const testColorString = '#f00f00';
|
|
1074
|
+
testElement = myp5.createColorPicker(testColorString);
|
|
1075
|
+
assert.deepEqual(testElement.elt.value, testColorString);
|
|
1076
|
+
});
|
|
1077
|
+
|
|
1078
|
+
test('calling color() should return the current color as p5.color', function() {
|
|
1079
|
+
const testColorString = 'red';
|
|
1080
|
+
const testColor = myp5.color(testColorString);
|
|
1081
|
+
testElement = myp5.createColorPicker(testColorString);
|
|
1082
|
+
assert.deepEqual(testElement.color(), testColor);
|
|
1083
|
+
});
|
|
1084
|
+
|
|
1085
|
+
test('calling value() should return hex string of color', function() {
|
|
1086
|
+
const testColor = myp5.color('aqua');
|
|
1087
|
+
testElement = myp5.createColorPicker(testColor);
|
|
1088
|
+
assert.deepEqual(testElement.value(), testColor.toString('#rrggbb'));
|
|
1089
|
+
});
|
|
1090
|
+
});
|
|
1091
|
+
|
|
1092
|
+
suite('p5.prototype.createInput', function() {
|
|
1093
|
+
let myp5;
|
|
1094
|
+
let testElement;
|
|
1095
|
+
|
|
1096
|
+
setup(function(done) {
|
|
1097
|
+
new p5(function(p) {
|
|
1098
|
+
p.setup = function() {
|
|
1099
|
+
myp5 = p;
|
|
1100
|
+
done();
|
|
1101
|
+
};
|
|
1102
|
+
});
|
|
1103
|
+
});
|
|
1104
|
+
|
|
1105
|
+
teardown(function() {
|
|
1106
|
+
myp5.remove();
|
|
1107
|
+
if (testElement && testElement.parentNode) {
|
|
1108
|
+
testElement.parentNode.removeChild(testElement);
|
|
1109
|
+
}
|
|
1110
|
+
testElement = null;
|
|
1111
|
+
});
|
|
1112
|
+
|
|
1113
|
+
test('should be a function', function() {
|
|
1114
|
+
assert.isFunction(myp5.createInput);
|
|
1115
|
+
});
|
|
1116
|
+
|
|
1117
|
+
test('should return p5.Element of input type', function() {
|
|
1118
|
+
testElement = myp5.createInput();
|
|
1119
|
+
assert.instanceOf(testElement, p5.Element);
|
|
1120
|
+
assert.instanceOf(testElement.elt, HTMLInputElement);
|
|
1121
|
+
});
|
|
1122
|
+
|
|
1123
|
+
test('should set given value as input', function() {
|
|
1124
|
+
const testValues = ['123', '', 'Hello world'];
|
|
1125
|
+
for (const value of testValues) {
|
|
1126
|
+
testElement = myp5.createInput(value);
|
|
1127
|
+
assert.deepEqual(testElement.elt.value, value);
|
|
1128
|
+
}
|
|
1129
|
+
});
|
|
1130
|
+
|
|
1131
|
+
test('should create input of given type and value', function() {
|
|
1132
|
+
const testType = 'password';
|
|
1133
|
+
const testValue = '1234056789';
|
|
1134
|
+
testElement = myp5.createInput(testValue, testType);
|
|
1135
|
+
assert.deepEqual(testElement.elt.type, testType);
|
|
1136
|
+
assert.deepEqual(testElement.elt.value, testValue);
|
|
1137
|
+
});
|
|
1138
|
+
});
|
|
1139
|
+
|
|
1140
|
+
suite('p5.prototype.createFileInput', function() {
|
|
1141
|
+
if (!(window.File && window.FileReader && window.FileList && window.Blob)) {
|
|
1142
|
+
throw Error(
|
|
1143
|
+
'File API not supported in test environment. Cannot run tests'
|
|
1144
|
+
);
|
|
1145
|
+
}
|
|
1146
|
+
|
|
1147
|
+
let myp5;
|
|
1148
|
+
let testElement;
|
|
1149
|
+
|
|
1150
|
+
setup(function(done) {
|
|
1151
|
+
new p5(function(p) {
|
|
1152
|
+
p.setup = function() {
|
|
1153
|
+
myp5 = p;
|
|
1154
|
+
done();
|
|
1155
|
+
};
|
|
1156
|
+
});
|
|
1157
|
+
});
|
|
1158
|
+
|
|
1159
|
+
teardown(function() {
|
|
1160
|
+
if (testElement && testElement.parentNode) {
|
|
1161
|
+
testElement.parentNode.removeChild(testElement);
|
|
1162
|
+
}
|
|
1163
|
+
testElement = null;
|
|
1164
|
+
myp5.remove();
|
|
1165
|
+
});
|
|
1166
|
+
|
|
1167
|
+
const emptyCallback = () => {};
|
|
1168
|
+
const createDummyFile = filename => {
|
|
1169
|
+
return new File(['testFileBlob'], filename, {
|
|
1170
|
+
type: 'text/plain'
|
|
1171
|
+
});
|
|
1172
|
+
};
|
|
1173
|
+
|
|
1174
|
+
test('should be a function', function() {
|
|
1175
|
+
assert.isFunction(myp5.createFileInput);
|
|
1176
|
+
});
|
|
1177
|
+
|
|
1178
|
+
test('should return input of file input', function() {
|
|
1179
|
+
testElement = myp5.createFileInput(emptyCallback);
|
|
1180
|
+
assert.instanceOf(testElement, p5.Element);
|
|
1181
|
+
assert.instanceOf(testElement.elt, HTMLInputElement);
|
|
1182
|
+
assert.deepEqual(testElement.elt.type, 'file');
|
|
1183
|
+
});
|
|
1184
|
+
|
|
1185
|
+
testSketchWithPromise(
|
|
1186
|
+
'should trigger callback on input change event',
|
|
1187
|
+
function(sketch, resolve, reject) {
|
|
1188
|
+
sketch.setup = function() {
|
|
1189
|
+
testElement = myp5.createFileInput(resolve);
|
|
1190
|
+
const testFile = createDummyFile('file');
|
|
1191
|
+
testElement.files = testFile;
|
|
1192
|
+
|
|
1193
|
+
const mockedEvent = new Event('change');
|
|
1194
|
+
const mockedDataTransfer = new DataTransfer();
|
|
1195
|
+
mockedDataTransfer.items.add(testFile);
|
|
1196
|
+
testElement.elt.files = mockedDataTransfer.files;
|
|
1197
|
+
testElement.elt.dispatchEvent(mockedEvent);
|
|
1198
|
+
};
|
|
1199
|
+
}
|
|
1200
|
+
);
|
|
1201
|
+
|
|
1202
|
+
test('should accept multiple files if specified', function() {
|
|
1203
|
+
testElement = myp5.createFileInput(emptyCallback, true);
|
|
1204
|
+
assert.isTrue(testElement.elt.multiple);
|
|
1205
|
+
});
|
|
1206
|
+
|
|
1207
|
+
testSketchWithPromise(
|
|
1208
|
+
'should trigger callback for each file if multiple files are given',
|
|
1209
|
+
function(sketch, resolve, reject) {
|
|
1210
|
+
sketch.setup = function() {
|
|
1211
|
+
let totalTriggers = 0;
|
|
1212
|
+
let filesCount = 7;
|
|
1213
|
+
|
|
1214
|
+
const handleFiles = event => {
|
|
1215
|
+
totalTriggers += 1;
|
|
1216
|
+
if (totalTriggers === filesCount) resolve();
|
|
1217
|
+
};
|
|
1218
|
+
|
|
1219
|
+
const mockedEvent = new Event('change');
|
|
1220
|
+
const mockedDataTransfer = new DataTransfer();
|
|
1221
|
+
for (let i = 0; i < filesCount; i += 1) {
|
|
1222
|
+
mockedDataTransfer.items.add(createDummyFile(i.toString()));
|
|
1223
|
+
}
|
|
1224
|
+
|
|
1225
|
+
testElement = myp5.createFileInput(handleFiles, true);
|
|
1226
|
+
testElement.elt.files = mockedDataTransfer.files;
|
|
1227
|
+
testElement.elt.dispatchEvent(mockedEvent);
|
|
1228
|
+
};
|
|
1229
|
+
}
|
|
1230
|
+
);
|
|
1231
|
+
});
|
|
1232
|
+
|
|
1233
|
+
suite('p5.prototype.createVideo', function() {
|
|
1234
|
+
let myp5;
|
|
1235
|
+
let testElement;
|
|
1236
|
+
|
|
1237
|
+
setup(function(done) {
|
|
1238
|
+
new p5(function(p) {
|
|
1239
|
+
p.setup = function() {
|
|
1240
|
+
myp5 = p;
|
|
1241
|
+
done();
|
|
1242
|
+
};
|
|
1243
|
+
});
|
|
1244
|
+
});
|
|
1245
|
+
|
|
1246
|
+
teardown(function() {
|
|
1247
|
+
myp5.remove();
|
|
1248
|
+
if (testElement && testElement.parentNode) {
|
|
1249
|
+
testElement.parentNode.removeChild(testElement);
|
|
1250
|
+
testElement = null;
|
|
1251
|
+
}
|
|
1252
|
+
});
|
|
1253
|
+
|
|
1254
|
+
const mediaSources = [
|
|
1255
|
+
'/test/unit/assets/nyan_cat.gif',
|
|
1256
|
+
'/test/unit/assets/target.gif'
|
|
1257
|
+
];
|
|
1258
|
+
|
|
1259
|
+
test('should be a function', function() {
|
|
1260
|
+
assert.isFunction(myp5.createVideo);
|
|
1261
|
+
});
|
|
1262
|
+
|
|
1263
|
+
test('should return p5.Element of HTMLVideoElement', function() {
|
|
1264
|
+
testElement = myp5.createVideo('');
|
|
1265
|
+
assert.instanceOf(testElement, p5.MediaElement);
|
|
1266
|
+
assert.instanceOf(testElement.elt, HTMLVideoElement);
|
|
1267
|
+
});
|
|
1268
|
+
|
|
1269
|
+
test('should accept a singular media source', function() {
|
|
1270
|
+
const mediaSource = mediaSources[0];
|
|
1271
|
+
testElement = myp5.createVideo(mediaSource);
|
|
1272
|
+
const sourceEl = testElement.elt.children[0];
|
|
1273
|
+
|
|
1274
|
+
assert.deepEqual(testElement.elt.childElementCount, 1);
|
|
1275
|
+
assert.instanceOf(sourceEl, HTMLSourceElement);
|
|
1276
|
+
assert.isTrue(sourceEl.src.endsWith(mediaSource));
|
|
1277
|
+
});
|
|
1278
|
+
|
|
1279
|
+
test('should accept multiple media sources', function() {
|
|
1280
|
+
testElement = myp5.createVideo(mediaSources);
|
|
1281
|
+
|
|
1282
|
+
assert.deepEqual(testElement.elt.childElementCount, mediaSources.length);
|
|
1283
|
+
for (let index = 0; index < mediaSources.length; index += 1) {
|
|
1284
|
+
const sourceEl = testElement.elt.children[index];
|
|
1285
|
+
assert.instanceOf(sourceEl, HTMLSourceElement);
|
|
1286
|
+
assert.isTrue(sourceEl.src.endsWith(mediaSources[index]));
|
|
1287
|
+
}
|
|
1288
|
+
});
|
|
1289
|
+
|
|
1290
|
+
testSketchWithPromise(
|
|
1291
|
+
'should trigger callback on canplaythrough event',
|
|
1292
|
+
function(sketch, resolve, reject) {
|
|
1293
|
+
sketch.setup = function() {
|
|
1294
|
+
testElement = myp5.createVideo(mediaSources, resolve);
|
|
1295
|
+
testElement.elt.dispatchEvent(new Event('canplaythrough'));
|
|
1296
|
+
};
|
|
1297
|
+
}
|
|
1298
|
+
);
|
|
1299
|
+
|
|
1300
|
+
test('should work with tint()', function(done) {
|
|
1301
|
+
const imgElt = myp5.createImg('/test/unit/assets/cat.jpg', '');
|
|
1302
|
+
testElement = myp5.createVideo('/test/unit/assets/cat.webm', () => {
|
|
1303
|
+
// Workaround for headless tests, where the video data isn't loading
|
|
1304
|
+
// correctly: mock the video element using an image for this test
|
|
1305
|
+
const prevElt = testElement.elt;
|
|
1306
|
+
testElement.elt = imgElt.elt;
|
|
1307
|
+
|
|
1308
|
+
myp5.background(255);
|
|
1309
|
+
myp5.tint(255, 0, 0);
|
|
1310
|
+
myp5.image(testElement, 0, 0);
|
|
1311
|
+
|
|
1312
|
+
testElement.elt = prevElt;
|
|
1313
|
+
imgElt.remove();
|
|
1314
|
+
|
|
1315
|
+
myp5.loadPixels();
|
|
1316
|
+
testElement.loadPixels();
|
|
1317
|
+
assert.equal(myp5.pixels[0], testElement.pixels[0]);
|
|
1318
|
+
assert.equal(myp5.pixels[1], 0);
|
|
1319
|
+
assert.equal(myp5.pixels[2], 0);
|
|
1320
|
+
done();
|
|
1321
|
+
});
|
|
1322
|
+
});
|
|
1323
|
+
|
|
1324
|
+
test('should work with updatePixels()', function(done) {
|
|
1325
|
+
let loaded = false;
|
|
1326
|
+
let prevElt;
|
|
1327
|
+
const imgElt = myp5.createImg('/test/unit/assets/cat.jpg', '');
|
|
1328
|
+
testElement = myp5.createVideo('/test/unit/assets/cat.webm', () => {
|
|
1329
|
+
loaded = true;
|
|
1330
|
+
// Workaround for headless tests, where the video data isn't loading
|
|
1331
|
+
// correctly: mock the video element using an image for this test
|
|
1332
|
+
prevElt = testElement.elt;
|
|
1333
|
+
testElement.elt = imgElt.elt;
|
|
1334
|
+
});
|
|
1335
|
+
|
|
1336
|
+
let drewUpdatedPixels = false;
|
|
1337
|
+
myp5.draw = function() {
|
|
1338
|
+
if (!loaded) return;
|
|
1339
|
+
myp5.background(255);
|
|
1340
|
+
|
|
1341
|
+
if (!drewUpdatedPixels) {
|
|
1342
|
+
// First, update pixels and check that it draws the updated
|
|
1343
|
+
// pixels correctly
|
|
1344
|
+
testElement.loadPixels();
|
|
1345
|
+
for (let i = 0; i < testElement.pixels.length; i += 4) {
|
|
1346
|
+
// Set every pixel to red
|
|
1347
|
+
testElement.pixels[i] = 255;
|
|
1348
|
+
testElement.pixels[i + 1] = 0;
|
|
1349
|
+
testElement.pixels[i + 2] = 0;
|
|
1350
|
+
testElement.pixels[i + 3] = 255;
|
|
1351
|
+
}
|
|
1352
|
+
testElement.updatePixels();
|
|
1353
|
+
myp5.image(testElement, 0, 0);
|
|
1354
|
+
|
|
1355
|
+
// The element should have drawn using the updated red pixels
|
|
1356
|
+
myp5.loadPixels();
|
|
1357
|
+
assert.deepEqual([...myp5.pixels.slice(0, 4)], [255, 0, 0, 255]);
|
|
1358
|
+
|
|
1359
|
+
// Mark that we've done the first check so we can see whether
|
|
1360
|
+
// the video still updates on the next frame
|
|
1361
|
+
drewUpdatedPixels = true;
|
|
1362
|
+
} else {
|
|
1363
|
+
// Next, make sure it still updates with the real pixels from
|
|
1364
|
+
// the next frame of the video on the next frame of animation
|
|
1365
|
+
myp5.image(testElement, 0, 0);
|
|
1366
|
+
|
|
1367
|
+
myp5.loadPixels();
|
|
1368
|
+
testElement.loadPixels();
|
|
1369
|
+
expect([...testElement.pixels.slice(0, 4)])
|
|
1370
|
+
.to.not.deep.equal([255, 0, 0, 255]);
|
|
1371
|
+
assert.deepEqual(
|
|
1372
|
+
[...myp5.pixels.slice(0, 4)],
|
|
1373
|
+
[...testElement.pixels.slice(0, 4)]
|
|
1374
|
+
);
|
|
1375
|
+
testElement.elt = prevElt;
|
|
1376
|
+
imgElt.remove();
|
|
1377
|
+
done();
|
|
1378
|
+
}
|
|
1379
|
+
};
|
|
1380
|
+
});
|
|
1381
|
+
});
|
|
1382
|
+
|
|
1383
|
+
suite('p5.prototype.createAudio', function() {
|
|
1384
|
+
let myp5;
|
|
1385
|
+
let testElement;
|
|
1386
|
+
|
|
1387
|
+
setup(function(done) {
|
|
1388
|
+
new p5(function(p) {
|
|
1389
|
+
p.setup = function() {
|
|
1390
|
+
myp5 = p;
|
|
1391
|
+
done();
|
|
1392
|
+
};
|
|
1393
|
+
});
|
|
1394
|
+
});
|
|
1395
|
+
|
|
1396
|
+
teardown(function() {
|
|
1397
|
+
myp5.remove();
|
|
1398
|
+
if (testElement && testElement.parentNode) {
|
|
1399
|
+
testElement.parentNode.removeChild(testElement);
|
|
1400
|
+
testElement = null;
|
|
1401
|
+
}
|
|
1402
|
+
});
|
|
1403
|
+
|
|
1404
|
+
const mediaSources = [
|
|
1405
|
+
'/test/unit/assets/beat.mp3',
|
|
1406
|
+
'/test/unit/assets/beat.mp3'
|
|
1407
|
+
];
|
|
1408
|
+
|
|
1409
|
+
test('should be a function', function() {
|
|
1410
|
+
assert.isFunction(myp5.createAudio);
|
|
1411
|
+
});
|
|
1412
|
+
|
|
1413
|
+
test('should return p5.Element of HTMLAudioElement', function() {
|
|
1414
|
+
testElement = myp5.createAudio('');
|
|
1415
|
+
assert.instanceOf(testElement, p5.MediaElement);
|
|
1416
|
+
assert.instanceOf(testElement.elt, HTMLAudioElement);
|
|
1417
|
+
});
|
|
1418
|
+
|
|
1419
|
+
test('should accept a singular media source', function() {
|
|
1420
|
+
const mediaSource = mediaSources[0];
|
|
1421
|
+
testElement = myp5.createAudio(mediaSource);
|
|
1422
|
+
const sourceEl = testElement.elt.children[0];
|
|
1423
|
+
|
|
1424
|
+
assert.deepEqual(testElement.elt.childElementCount, 1);
|
|
1425
|
+
assert.instanceOf(sourceEl, HTMLSourceElement);
|
|
1426
|
+
assert.isTrue(sourceEl.src.endsWith(mediaSource));
|
|
1427
|
+
});
|
|
1428
|
+
|
|
1429
|
+
test('should accept multiple media sources', function() {
|
|
1430
|
+
testElement = myp5.createAudio(mediaSources);
|
|
1431
|
+
|
|
1432
|
+
assert.deepEqual(testElement.elt.childElementCount, mediaSources.length);
|
|
1433
|
+
for (let index = 0; index < mediaSources.length; index += 1) {
|
|
1434
|
+
const sourceEl = testElement.elt.children[index];
|
|
1435
|
+
assert.instanceOf(sourceEl, HTMLSourceElement);
|
|
1436
|
+
assert.isTrue(sourceEl.src.endsWith(mediaSources[index]));
|
|
1437
|
+
}
|
|
1438
|
+
});
|
|
1439
|
+
|
|
1440
|
+
testSketchWithPromise(
|
|
1441
|
+
'should trigger callback on canplaythrough event',
|
|
1442
|
+
function(sketch, resolve, reject) {
|
|
1443
|
+
sketch.setup = function() {
|
|
1444
|
+
testElement = myp5.createAudio(mediaSources, resolve);
|
|
1445
|
+
testElement.elt.dispatchEvent(new Event('canplaythrough'));
|
|
1446
|
+
};
|
|
1447
|
+
}
|
|
1448
|
+
);
|
|
1449
|
+
});
|
|
1450
|
+
|
|
1451
|
+
suite('p5.prototype.createCapture', function() {
|
|
1452
|
+
// to run these tests, getUserMedia is required to be supported
|
|
1453
|
+
if (!(navigator.mediaDevices && navigator.mediaDevices.getUserMedia)) {
|
|
1454
|
+
throw Error(
|
|
1455
|
+
'Cannot run tests as getUserMedia not supported in this browser'
|
|
1456
|
+
);
|
|
1457
|
+
}
|
|
1458
|
+
|
|
1459
|
+
let myp5;
|
|
1460
|
+
let testElement;
|
|
1461
|
+
|
|
1462
|
+
setup(function(done) {
|
|
1463
|
+
new p5(function(p) {
|
|
1464
|
+
p.setup = function() {
|
|
1465
|
+
myp5 = p;
|
|
1466
|
+
done();
|
|
1467
|
+
};
|
|
1468
|
+
});
|
|
1469
|
+
});
|
|
1470
|
+
|
|
1471
|
+
teardown(function() {
|
|
1472
|
+
if (testElement && testElement.parentNode) {
|
|
1473
|
+
testElement.parentNode.removeChild(testElement);
|
|
1474
|
+
}
|
|
1475
|
+
testElement = null;
|
|
1476
|
+
myp5.remove();
|
|
1477
|
+
});
|
|
1478
|
+
|
|
1479
|
+
test('should be a function', function() {
|
|
1480
|
+
assert.isFunction(myp5.createCapture);
|
|
1481
|
+
});
|
|
1482
|
+
|
|
1483
|
+
test('should return p5.Element of video type', function() {
|
|
1484
|
+
testElement = myp5.createCapture(myp5.VIDEO);
|
|
1485
|
+
assert.instanceOf(testElement, p5.Element);
|
|
1486
|
+
assert.instanceOf(testElement.elt, HTMLVideoElement);
|
|
1487
|
+
});
|
|
1488
|
+
|
|
1489
|
+
test('should throw error if getUserMedia is not supported', function() {
|
|
1490
|
+
// Remove getUserMedia method and test
|
|
1491
|
+
const backup = navigator.mediaDevices.getUserMedia;
|
|
1492
|
+
navigator.mediaDevices.getUserMedia = undefined;
|
|
1493
|
+
try {
|
|
1494
|
+
testElement = myp5.createCapture(myp5.VIDEO);
|
|
1495
|
+
assert.fail();
|
|
1496
|
+
} catch (error) {
|
|
1497
|
+
assert.instanceOf(error, DOMException);
|
|
1498
|
+
}
|
|
1499
|
+
|
|
1500
|
+
// Restore backup, very important.
|
|
1501
|
+
navigator.mediaDevices.getUserMedia = backup;
|
|
1502
|
+
});
|
|
1503
|
+
|
|
1504
|
+
testSketchWithPromise(
|
|
1505
|
+
'triggers the callback after loading metadata',
|
|
1506
|
+
function(sketch, resolve, reject) {
|
|
1507
|
+
sketch.setup = function() {
|
|
1508
|
+
testElement = myp5.createCapture(myp5.VIDEO, resolve);
|
|
1509
|
+
const mockedEvent = new Event('loadedmetadata');
|
|
1510
|
+
testElement.elt.dispatchEvent(mockedEvent);
|
|
1511
|
+
};
|
|
1512
|
+
}
|
|
1513
|
+
);
|
|
1514
|
+
|
|
1515
|
+
// Required for ios 11 devices
|
|
1516
|
+
test('should have playsinline attribute to empty string on DOM element', function() {
|
|
1517
|
+
testElement = myp5.createCapture(myp5.VIDEO);
|
|
1518
|
+
console.log(testElement.elt);
|
|
1519
|
+
// Weird check, setter accepts : playinline, getter accepts playInline
|
|
1520
|
+
assert.isTrue(testElement.elt.playsInline);
|
|
1521
|
+
});
|
|
1522
|
+
});
|
|
1523
|
+
|
|
1524
|
+
suite('p5.prototype.createElement', function() {
|
|
1525
|
+
let myp5;
|
|
1526
|
+
let testElement;
|
|
1527
|
+
|
|
1528
|
+
setup(function(done) {
|
|
1529
|
+
new p5(function(p) {
|
|
1530
|
+
p.setup = function() {
|
|
1531
|
+
myp5 = p;
|
|
1532
|
+
done();
|
|
1533
|
+
};
|
|
1534
|
+
});
|
|
1535
|
+
});
|
|
1536
|
+
|
|
1537
|
+
teardown(function() {
|
|
1538
|
+
myp5.remove();
|
|
1539
|
+
if (testElement && testElement.parentNode) {
|
|
1540
|
+
testElement.parentNode.removeChild(testElement);
|
|
1541
|
+
testElement = null;
|
|
1542
|
+
}
|
|
1543
|
+
});
|
|
1544
|
+
|
|
1545
|
+
const testData = {
|
|
1546
|
+
div: HTMLDivElement,
|
|
1547
|
+
p: HTMLParagraphElement,
|
|
1548
|
+
button: HTMLButtonElement,
|
|
1549
|
+
input: HTMLInputElement,
|
|
1550
|
+
video: HTMLVideoElement
|
|
1551
|
+
};
|
|
1552
|
+
|
|
1553
|
+
test('should be a function', function() {
|
|
1554
|
+
assert.isFunction(myp5.createElement);
|
|
1555
|
+
});
|
|
1556
|
+
|
|
1557
|
+
test('should return a p5.Element of appropriate type', function() {
|
|
1558
|
+
for (const [tag, domElName] of Object.entries(testData)) {
|
|
1559
|
+
testElement = myp5.createElement(tag);
|
|
1560
|
+
assert.instanceOf(testElement, p5.Element);
|
|
1561
|
+
assert.instanceOf(testElement.elt, domElName);
|
|
1562
|
+
}
|
|
1563
|
+
});
|
|
1564
|
+
|
|
1565
|
+
test('should set given content as innerHTML', function() {
|
|
1566
|
+
const testContent = 'Lorem ipsum';
|
|
1567
|
+
testElement = myp5.createElement('div', testContent);
|
|
1568
|
+
assert.deepEqual(testElement.elt.innerHTML, testContent);
|
|
1569
|
+
});
|
|
1570
|
+
});
|
|
1571
|
+
|
|
1572
|
+
// p5.Element.prototype.addClass
|
|
1573
|
+
suite('p5.Element.prototype.addClass', function() {
|
|
1574
|
+
let myp5;
|
|
1575
|
+
let testElement;
|
|
1576
|
+
|
|
1577
|
+
setup(function(done) {
|
|
1578
|
+
new p5(function(p) {
|
|
1579
|
+
p.setup = function() {
|
|
1580
|
+
myp5 = p;
|
|
1581
|
+
done();
|
|
1582
|
+
};
|
|
1583
|
+
});
|
|
1584
|
+
});
|
|
1585
|
+
|
|
1586
|
+
teardown(function() {
|
|
1587
|
+
myp5.remove();
|
|
1588
|
+
if (testElement && testElement.parentNode) {
|
|
1589
|
+
testElement.parentNode.removeChild(testElement);
|
|
1590
|
+
}
|
|
1591
|
+
testElement = null;
|
|
1592
|
+
});
|
|
1593
|
+
|
|
1594
|
+
test('should be a function', function() {
|
|
1595
|
+
// Create any p5.Element
|
|
1596
|
+
testElement = myp5.createElement('div');
|
|
1597
|
+
assert.isFunction(testElement.addClass);
|
|
1598
|
+
});
|
|
1599
|
+
|
|
1600
|
+
test('should add provided string to class names', function() {
|
|
1601
|
+
const testClassName = 'jumbotron';
|
|
1602
|
+
testElement = myp5.createElement('div');
|
|
1603
|
+
testElement.addClass(testClassName);
|
|
1604
|
+
assert.deepEqual(testElement.elt.className, testClassName);
|
|
1605
|
+
});
|
|
1606
|
+
|
|
1607
|
+
test('should not add class name, if already exists', function() {
|
|
1608
|
+
const testClassName1 = 'jumbotron';
|
|
1609
|
+
const testClassName2 = 'container-fluid';
|
|
1610
|
+
const expectedClassName = testClassName1 + ' ' + testClassName2;
|
|
1611
|
+
|
|
1612
|
+
testElement = myp5.createElement('div');
|
|
1613
|
+
testElement.addClass(testClassName1);
|
|
1614
|
+
testElement.addClass(testClassName2);
|
|
1615
|
+
|
|
1616
|
+
// Should not add the class name again
|
|
1617
|
+
testElement.addClass(testClassName1);
|
|
1618
|
+
assert.deepEqual(testElement.elt.className, expectedClassName);
|
|
1619
|
+
});
|
|
1620
|
+
});
|
|
1621
|
+
|
|
1622
|
+
// p5.Element.prototype.removeClass
|
|
1623
|
+
suite('p5.Element.prototype.removeClass', function() {
|
|
1624
|
+
let myp5;
|
|
1625
|
+
let testElement;
|
|
1626
|
+
|
|
1627
|
+
setup(function(done) {
|
|
1628
|
+
new p5(function(p) {
|
|
1629
|
+
p.setup = function() {
|
|
1630
|
+
myp5 = p;
|
|
1631
|
+
done();
|
|
1632
|
+
};
|
|
1633
|
+
});
|
|
1634
|
+
});
|
|
1635
|
+
|
|
1636
|
+
teardown(function() {
|
|
1637
|
+
myp5.remove();
|
|
1638
|
+
if (testElement && testElement.parentNode) {
|
|
1639
|
+
testElement.parentNode.removeChild(testElement);
|
|
1640
|
+
}
|
|
1641
|
+
testElement = null;
|
|
1642
|
+
});
|
|
1643
|
+
|
|
1644
|
+
test('should be a function', function() {
|
|
1645
|
+
// Create any p5.Element
|
|
1646
|
+
testElement = myp5.createElement('div');
|
|
1647
|
+
assert.isFunction(testElement.removeClass);
|
|
1648
|
+
});
|
|
1649
|
+
|
|
1650
|
+
test('should remove provided string from class names', function() {
|
|
1651
|
+
const defaultClassNames = 'col-md-9 col-sm-12';
|
|
1652
|
+
const testClassName = 'jumbotron';
|
|
1653
|
+
|
|
1654
|
+
testElement = myp5.createElement('div');
|
|
1655
|
+
testElement.addClass(defaultClassNames);
|
|
1656
|
+
testElement.addClass(testClassName);
|
|
1657
|
+
|
|
1658
|
+
// Removing a class name
|
|
1659
|
+
testElement.removeClass(testClassName);
|
|
1660
|
+
assert.deepEqual(testElement.elt.className, defaultClassNames);
|
|
1661
|
+
});
|
|
1662
|
+
|
|
1663
|
+
test('should not throw error if class name not exists', function() {
|
|
1664
|
+
const testClassName1 = 'jumbotron';
|
|
1665
|
+
const testClassName2 = 'container-fluid';
|
|
1666
|
+
|
|
1667
|
+
testElement = myp5.createElement('div');
|
|
1668
|
+
testElement.addClass(testClassName1);
|
|
1669
|
+
|
|
1670
|
+
// Handling the curse of 'this'
|
|
1671
|
+
testElement.removeClass = testElement.removeClass.bind(testElement);
|
|
1672
|
+
assert.doesNotThrow(testElement.removeClass, testClassName2);
|
|
1673
|
+
assert.deepEqual(testElement.elt.className, testClassName1);
|
|
1674
|
+
});
|
|
1675
|
+
});
|
|
1676
|
+
|
|
1677
|
+
// p5.Element.prototype.hasClass
|
|
1678
|
+
suite('p5.Element.prototype.hasClass', function() {
|
|
1679
|
+
let myp5;
|
|
1680
|
+
let testElement;
|
|
1681
|
+
|
|
1682
|
+
setup(function(done) {
|
|
1683
|
+
new p5(function(p) {
|
|
1684
|
+
p.setup = function() {
|
|
1685
|
+
myp5 = p;
|
|
1686
|
+
done();
|
|
1687
|
+
};
|
|
1688
|
+
});
|
|
1689
|
+
});
|
|
1690
|
+
|
|
1691
|
+
teardown(function() {
|
|
1692
|
+
myp5.remove();
|
|
1693
|
+
if (testElement && testElement.parentNode) {
|
|
1694
|
+
testElement.parentNode.removeChild(testElement);
|
|
1695
|
+
}
|
|
1696
|
+
testElement = null;
|
|
1697
|
+
});
|
|
1698
|
+
|
|
1699
|
+
test('should be a function', function() {
|
|
1700
|
+
// Create any p5.Element
|
|
1701
|
+
testElement = myp5.createElement('div');
|
|
1702
|
+
assert.isFunction(testElement.hasClass);
|
|
1703
|
+
});
|
|
1704
|
+
|
|
1705
|
+
test('should return true for existing class name', function() {
|
|
1706
|
+
const defaultClassNames = 'col-md-9 jumbotron';
|
|
1707
|
+
const testClassName = 'jumbotron';
|
|
1708
|
+
|
|
1709
|
+
testElement = myp5.createElement('div');
|
|
1710
|
+
testElement.addClass(defaultClassNames);
|
|
1711
|
+
|
|
1712
|
+
assert.isTrue(testElement.hasClass(testClassName));
|
|
1713
|
+
});
|
|
1714
|
+
|
|
1715
|
+
test('should return false for non-existing class name', function() {
|
|
1716
|
+
const defaultClassNames = 'col-md-9 jumbotron';
|
|
1717
|
+
const testClassName = 'container-fluid';
|
|
1718
|
+
|
|
1719
|
+
testElement = myp5.createElement('div');
|
|
1720
|
+
testElement.addClass(defaultClassNames);
|
|
1721
|
+
|
|
1722
|
+
assert.isFalse(testElement.hasClass(testClassName));
|
|
1723
|
+
});
|
|
1724
|
+
});
|
|
1725
|
+
|
|
1726
|
+
// p5.Element.prototype.toggleClass
|
|
1727
|
+
suite('p5.Element.prototype.toggleClass', function() {
|
|
1728
|
+
let myp5;
|
|
1729
|
+
let testElement;
|
|
1730
|
+
|
|
1731
|
+
setup(function(done) {
|
|
1732
|
+
new p5(function(p) {
|
|
1733
|
+
p.setup = function() {
|
|
1734
|
+
myp5 = p;
|
|
1735
|
+
done();
|
|
1736
|
+
};
|
|
1737
|
+
});
|
|
1738
|
+
});
|
|
1739
|
+
|
|
1740
|
+
teardown(function() {
|
|
1741
|
+
myp5.remove();
|
|
1742
|
+
if (testElement && testElement.parentNode) {
|
|
1743
|
+
testElement.parentNode.removeChild(testElement);
|
|
1744
|
+
}
|
|
1745
|
+
testElement = null;
|
|
1746
|
+
});
|
|
1747
|
+
|
|
1748
|
+
test('should be a function', function() {
|
|
1749
|
+
// Create any p5.Element
|
|
1750
|
+
testElement = myp5.createElement('div');
|
|
1751
|
+
assert.isFunction(testElement.toggleClass);
|
|
1752
|
+
});
|
|
1753
|
+
|
|
1754
|
+
test('should remove an existing class name', function() {
|
|
1755
|
+
const defaultClassName = 'container-fluid';
|
|
1756
|
+
const testClassName = 'jumbotron';
|
|
1757
|
+
|
|
1758
|
+
testElement = myp5.createElement('div');
|
|
1759
|
+
testElement.addClass(defaultClassName);
|
|
1760
|
+
testElement.addClass(testClassName);
|
|
1761
|
+
|
|
1762
|
+
testElement.toggleClass(testClassName);
|
|
1763
|
+
assert.deepEqual(testElement.elt.className, defaultClassName);
|
|
1764
|
+
});
|
|
1765
|
+
|
|
1766
|
+
test('should add an non-existing class name', function() {
|
|
1767
|
+
const defaultClassName = 'container-fluid';
|
|
1768
|
+
const testClassName = 'jumbotron';
|
|
1769
|
+
|
|
1770
|
+
testElement = myp5.createElement('div');
|
|
1771
|
+
testElement.addClass(defaultClassName);
|
|
1772
|
+
|
|
1773
|
+
testElement.toggleClass(testClassName);
|
|
1774
|
+
assert.deepEqual(
|
|
1775
|
+
testElement.elt.className,
|
|
1776
|
+
defaultClassName + ' ' + testClassName
|
|
1777
|
+
);
|
|
1778
|
+
});
|
|
1779
|
+
});
|
|
1780
|
+
|
|
1781
|
+
// p5.Element.prototype.child
|
|
1782
|
+
suite('p5.Element.prototype.child', function() {
|
|
1783
|
+
let myp5;
|
|
1784
|
+
let testElement;
|
|
1785
|
+
|
|
1786
|
+
setup(function(done) {
|
|
1787
|
+
new p5(function(p) {
|
|
1788
|
+
p.setup = function() {
|
|
1789
|
+
myp5 = p;
|
|
1790
|
+
done();
|
|
1791
|
+
};
|
|
1792
|
+
});
|
|
1793
|
+
});
|
|
1794
|
+
|
|
1795
|
+
teardown(function() {
|
|
1796
|
+
myp5.remove();
|
|
1797
|
+
if (testElement && testElement.parentNode) {
|
|
1798
|
+
testElement.parentNode.removeChild(testElement);
|
|
1799
|
+
}
|
|
1800
|
+
testElement = null;
|
|
1801
|
+
});
|
|
1802
|
+
|
|
1803
|
+
test('should be a function', function() {
|
|
1804
|
+
testElement = myp5.createElement('div');
|
|
1805
|
+
assert.isFunction(testElement.child);
|
|
1806
|
+
});
|
|
1807
|
+
|
|
1808
|
+
test('should return all child nodes by default', function() {
|
|
1809
|
+
testElement = myp5.createElement('div');
|
|
1810
|
+
const childElement = myp5.createElement('p');
|
|
1811
|
+
|
|
1812
|
+
// Add child element by using DOM API
|
|
1813
|
+
testElement.elt.appendChild(childElement.elt);
|
|
1814
|
+
|
|
1815
|
+
const childNodes = testElement.child();
|
|
1816
|
+
assert.deepEqual(childNodes.length, testElement.elt.childElementCount);
|
|
1817
|
+
childNodes.forEach((childElement, index) => {
|
|
1818
|
+
const domChild = testElement.elt.children[index];
|
|
1819
|
+
assert.deepEqual(childElement, domChild);
|
|
1820
|
+
});
|
|
1821
|
+
});
|
|
1822
|
+
|
|
1823
|
+
test('should append p5 element as child', function() {
|
|
1824
|
+
testElement = myp5.createElement('div');
|
|
1825
|
+
const childElement = myp5.createElement('p');
|
|
1826
|
+
|
|
1827
|
+
testElement.child(childElement);
|
|
1828
|
+
const childNodes = Array.from(testElement.elt.children);
|
|
1829
|
+
assert.isTrue(childNodes.includes(childElement.elt));
|
|
1830
|
+
});
|
|
1831
|
+
|
|
1832
|
+
test('should append dom element as child', function() {
|
|
1833
|
+
testElement = myp5.createElement('div');
|
|
1834
|
+
const childElement = myp5.createElement('p');
|
|
1835
|
+
|
|
1836
|
+
testElement.child(childElement.elt);
|
|
1837
|
+
const childNodes = Array.from(testElement.elt.children);
|
|
1838
|
+
assert.isTrue(childNodes.includes(childElement.elt));
|
|
1839
|
+
});
|
|
1840
|
+
|
|
1841
|
+
test('should append element as child from a given id', function() {
|
|
1842
|
+
testElement = myp5.createElement('div');
|
|
1843
|
+
const childId = 'testChildElement';
|
|
1844
|
+
const childElement = myp5.createElement('p');
|
|
1845
|
+
childElement.id(childId);
|
|
1846
|
+
|
|
1847
|
+
testElement.child(childId);
|
|
1848
|
+
const childNodes = Array.from(testElement.elt.children);
|
|
1849
|
+
assert.isTrue(childNodes.includes(childElement.elt));
|
|
1850
|
+
});
|
|
1851
|
+
|
|
1852
|
+
test('should not throw error if mathcing element is not found from a given id', function() {
|
|
1853
|
+
testElement = myp5.createElement('div');
|
|
1854
|
+
const randomChildId = 'testChildElement';
|
|
1855
|
+
expect(() => testElement.child(randomChildId)).to.not.throw();
|
|
1856
|
+
});
|
|
1857
|
+
});
|
|
1858
|
+
|
|
1859
|
+
// p5.Element.prototype.center
|
|
1860
|
+
suite('p5.Element.prototype.center', function() {
|
|
1861
|
+
let myp5;
|
|
1862
|
+
let testElement;
|
|
1863
|
+
|
|
1864
|
+
setup(function(done) {
|
|
1865
|
+
new p5(function(p) {
|
|
1866
|
+
p.setup = function() {
|
|
1867
|
+
myp5 = p;
|
|
1868
|
+
done();
|
|
1869
|
+
};
|
|
1870
|
+
});
|
|
1871
|
+
});
|
|
1872
|
+
|
|
1873
|
+
teardown(function() {
|
|
1874
|
+
myp5.remove();
|
|
1875
|
+
if (testElement && testElement.parentNode) {
|
|
1876
|
+
testElement.parentNode.removeChild(testElement);
|
|
1877
|
+
}
|
|
1878
|
+
testElement = null;
|
|
1879
|
+
});
|
|
1880
|
+
|
|
1881
|
+
test('should be a function', function() {
|
|
1882
|
+
testElement = myp5.createElement('div');
|
|
1883
|
+
assert.isFunction(testElement.center);
|
|
1884
|
+
});
|
|
1885
|
+
|
|
1886
|
+
// test('should center an element horizontally', function() {
|
|
1887
|
+
// // center doesn't work.
|
|
1888
|
+
// });
|
|
1889
|
+
|
|
1890
|
+
// test('should center an element vertically', function() {
|
|
1891
|
+
// // center doesn't work.
|
|
1892
|
+
// });
|
|
1893
|
+
|
|
1894
|
+
// test('should center an element horizontally and vertically', function() {
|
|
1895
|
+
// // center doesn't work.
|
|
1896
|
+
// });
|
|
1897
|
+
});
|
|
1898
|
+
|
|
1899
|
+
// p5.Element.prototype.html
|
|
1900
|
+
suite('p5.Element.prototype.html', function() {
|
|
1901
|
+
let myp5;
|
|
1902
|
+
let testElement;
|
|
1903
|
+
|
|
1904
|
+
setup(function(done) {
|
|
1905
|
+
new p5(function(p) {
|
|
1906
|
+
p.setup = function() {
|
|
1907
|
+
myp5 = p;
|
|
1908
|
+
done();
|
|
1909
|
+
};
|
|
1910
|
+
});
|
|
1911
|
+
});
|
|
1912
|
+
|
|
1913
|
+
teardown(function() {
|
|
1914
|
+
myp5.remove();
|
|
1915
|
+
if (testElement && testElement.parentNode) {
|
|
1916
|
+
testElement.parentNode.removeChild(testElement);
|
|
1917
|
+
}
|
|
1918
|
+
testElement = null;
|
|
1919
|
+
});
|
|
1920
|
+
|
|
1921
|
+
test('should be a function', function() {
|
|
1922
|
+
// Create any p5.Element
|
|
1923
|
+
testElement = myp5.createElement('a');
|
|
1924
|
+
assert.isFunction(testElement.position);
|
|
1925
|
+
});
|
|
1926
|
+
|
|
1927
|
+
test('should return the inner HTML of element if no argument is given', function() {
|
|
1928
|
+
testElement = myp5.createElement('div');
|
|
1929
|
+
const testHTML = '<p>Hello World</p>';
|
|
1930
|
+
|
|
1931
|
+
testElement.elt.innerHTML = testHTML;
|
|
1932
|
+
assert.deepEqual(testElement.html(), testHTML);
|
|
1933
|
+
});
|
|
1934
|
+
|
|
1935
|
+
test('should replace the inner HTML of element', function() {
|
|
1936
|
+
testElement = myp5.createElement('div');
|
|
1937
|
+
const initialtestHTML = '<p>Hello World</p>';
|
|
1938
|
+
const modifiedtestHTML = '<p>Hello World !!!</p>';
|
|
1939
|
+
|
|
1940
|
+
testElement.html(initialtestHTML);
|
|
1941
|
+
assert.deepEqual(testElement.elt.innerHTML, initialtestHTML);
|
|
1942
|
+
|
|
1943
|
+
testElement.html(modifiedtestHTML);
|
|
1944
|
+
assert.deepEqual(testElement.elt.innerHTML, modifiedtestHTML);
|
|
1945
|
+
});
|
|
1946
|
+
|
|
1947
|
+
test('should append to the inner HTML if second param is true', function() {
|
|
1948
|
+
testElement = myp5.createElement('div');
|
|
1949
|
+
const testHTML1 = '<p>Hello World</p>';
|
|
1950
|
+
const testHTML2 = '<p>Hello World !!!</p>';
|
|
1951
|
+
|
|
1952
|
+
testElement.html(testHTML1);
|
|
1953
|
+
assert.deepEqual(testElement.elt.innerHTML, testHTML1);
|
|
1954
|
+
|
|
1955
|
+
testElement.html(testHTML2, true);
|
|
1956
|
+
assert.deepEqual(testElement.elt.innerHTML, testHTML1 + testHTML2);
|
|
1957
|
+
});
|
|
1958
|
+
|
|
1959
|
+
test('should replace the inner HTML if second param is false', function() {
|
|
1960
|
+
testElement = myp5.createElement('div');
|
|
1961
|
+
const testHTML1 = '<p>Hello World</p>';
|
|
1962
|
+
const testHTML2 = '<p>Hello World !!!</p>';
|
|
1963
|
+
|
|
1964
|
+
testElement.html(testHTML1);
|
|
1965
|
+
assert.deepEqual(testElement.elt.innerHTML, testHTML1);
|
|
1966
|
+
|
|
1967
|
+
testElement.html(testHTML2, false);
|
|
1968
|
+
assert.deepEqual(testElement.elt.innerHTML, testHTML2);
|
|
1969
|
+
});
|
|
1970
|
+
});
|
|
1971
|
+
|
|
1972
|
+
// p5.Element.prototype.position
|
|
1973
|
+
suite('p5.Element.prototype.position', function() {
|
|
1974
|
+
let myp5;
|
|
1975
|
+
let testElement;
|
|
1976
|
+
|
|
1977
|
+
setup(function(done) {
|
|
1978
|
+
new p5(function(p) {
|
|
1979
|
+
p.setup = function() {
|
|
1980
|
+
myp5 = p;
|
|
1981
|
+
done();
|
|
1982
|
+
};
|
|
1983
|
+
});
|
|
1984
|
+
});
|
|
1985
|
+
|
|
1986
|
+
teardown(function() {
|
|
1987
|
+
myp5.remove();
|
|
1988
|
+
if (testElement && testElement.parentNode) {
|
|
1989
|
+
testElement.parentNode.removeChild(testElement);
|
|
1990
|
+
}
|
|
1991
|
+
testElement = null;
|
|
1992
|
+
});
|
|
1993
|
+
|
|
1994
|
+
test('should be a function', function() {
|
|
1995
|
+
// Create any p5.Element
|
|
1996
|
+
testElement = myp5.createElement('a');
|
|
1997
|
+
assert.isFunction(testElement.position);
|
|
1998
|
+
});
|
|
1999
|
+
|
|
2000
|
+
test('should return current position if no args are given', function() {
|
|
2001
|
+
testElement = myp5.createButton('testButton');
|
|
2002
|
+
const position = testElement.position();
|
|
2003
|
+
assert.deepEqual(position.x, testElement.elt.offsetLeft);
|
|
2004
|
+
assert.deepEqual(position.y, testElement.elt.offsetTop);
|
|
2005
|
+
});
|
|
2006
|
+
|
|
2007
|
+
test('should set default position as absolute', function() {
|
|
2008
|
+
testElement = myp5.createButton('testButton');
|
|
2009
|
+
testElement.position(20, 70);
|
|
2010
|
+
assert.deepEqual(testElement.elt.style.position, 'absolute');
|
|
2011
|
+
});
|
|
2012
|
+
|
|
2013
|
+
test('should set given params as properties', function() {
|
|
2014
|
+
let testElement = myp5.createButton('testButton');
|
|
2015
|
+
testElement.position(20, 80, 'static');
|
|
2016
|
+
|
|
2017
|
+
assert.deepEqual(testElement.elt.style.position, 'static');
|
|
2018
|
+
assert.deepEqual(testElement.elt.style.left, '20px');
|
|
2019
|
+
assert.deepEqual(testElement.elt.style.top, '80px');
|
|
2020
|
+
});
|
|
2021
|
+
});
|
|
2022
|
+
|
|
2023
|
+
// p5.Element.prototype._translate
|
|
2024
|
+
|
|
2025
|
+
// p5.Element.prototype._rotate
|
|
2026
|
+
|
|
2027
|
+
// p5.Element.prototype.style
|
|
2028
|
+
|
|
2029
|
+
// p5.Element.prototype.attribute
|
|
2030
|
+
|
|
2031
|
+
// p5.Element.prototype.removeAttribute
|
|
2032
|
+
|
|
2033
|
+
// p5.Element.prototype.value
|
|
2034
|
+
|
|
2035
|
+
// p5.Element.prototype.show
|
|
2036
|
+
|
|
2037
|
+
// p5.Element.prototype.hide
|
|
2038
|
+
|
|
2039
|
+
// p5.Element.prototype.size
|
|
2040
|
+
|
|
2041
|
+
// p5.Element.prototype.remove
|
|
2042
|
+
|
|
2043
|
+
suite('p5.prototype.drop', function() {
|
|
2044
|
+
testSketchWithPromise('drop fires multiple events', function(
|
|
2045
|
+
sketch,
|
|
2046
|
+
resolve,
|
|
2047
|
+
reject
|
|
2048
|
+
) {
|
|
2049
|
+
let testElement;
|
|
2050
|
+
let fileFnCounter = 0;
|
|
2051
|
+
let eventFnCounter = 0;
|
|
2052
|
+
sketch.setup = function() {
|
|
2053
|
+
testElement = sketch.createDiv('Drop files inside');
|
|
2054
|
+
|
|
2055
|
+
// Setup test functions and constants
|
|
2056
|
+
const file1 = new File(['foo'], 'foo.txt', { type: 'text/plain' });
|
|
2057
|
+
const file2 = new File(['foo'], 'foo.txt', { type: 'text/plain' });
|
|
2058
|
+
const hasFinished = () => {
|
|
2059
|
+
if (fileFnCounter > 1 && eventFnCounter === 1) resolve();
|
|
2060
|
+
};
|
|
2061
|
+
const testFileFn = () => {
|
|
2062
|
+
fileFnCounter += 1;
|
|
2063
|
+
hasFinished();
|
|
2064
|
+
};
|
|
2065
|
+
const testEventFn = () => {
|
|
2066
|
+
eventFnCounter += 1;
|
|
2067
|
+
hasFinished();
|
|
2068
|
+
};
|
|
2069
|
+
testElement.drop(testFileFn, testEventFn);
|
|
2070
|
+
|
|
2071
|
+
// Fire a mock drop and test the method
|
|
2072
|
+
const mockedEvent = new Event('drop');
|
|
2073
|
+
mockedEvent.dataTransfer = { files: [file1, file2] };
|
|
2074
|
+
testElement.elt.dispatchEvent(mockedEvent);
|
|
2075
|
+
};
|
|
2076
|
+
});
|
|
2077
|
+
});
|
|
2078
|
+
|
|
2079
|
+
// p5.MediaElement
|
|
2080
|
+
|
|
2081
|
+
// p5.MediaElement.play
|
|
2082
|
+
|
|
2083
|
+
// p5.MediaElement.stop
|
|
2084
|
+
|
|
2085
|
+
// p5.MediaElement.pause
|
|
2086
|
+
|
|
2087
|
+
// p5.MediaElement.loop
|
|
2088
|
+
|
|
2089
|
+
// p5.MediaElement.noLoop
|
|
2090
|
+
|
|
2091
|
+
// p5.MediaElement.shouldAutoplay
|
|
2092
|
+
|
|
2093
|
+
// p5.MediaElement.autoplay
|
|
2094
|
+
|
|
2095
|
+
// p5.MediaElement.volume
|
|
2096
|
+
|
|
2097
|
+
// p5.MediaElement.speed
|
|
2098
|
+
|
|
2099
|
+
// p5.MediaElement.time
|
|
2100
|
+
|
|
2101
|
+
// p5.MediaElement.prototype.duration
|
|
2102
|
+
|
|
2103
|
+
// p5.MediaElement.prototype._ensureCanvas
|
|
2104
|
+
|
|
2105
|
+
// p5.MediaElement.prototype.loadPixels
|
|
2106
|
+
|
|
2107
|
+
// p5.MediaElement.prototype.updatePixels
|
|
2108
|
+
|
|
2109
|
+
// p5.MediaElement.prototype.get
|
|
2110
|
+
|
|
2111
|
+
// p5.MediaElement.prototype._getPixel
|
|
2112
|
+
|
|
2113
|
+
// p5.MediaElement.prototype.set
|
|
2114
|
+
|
|
2115
|
+
// p5.MediaElement.prototype.copy
|
|
2116
|
+
|
|
2117
|
+
// p5.MediaElement.prototype.mask
|
|
2118
|
+
|
|
2119
|
+
// p5.MediaElement.prototype.isModified
|
|
2120
|
+
|
|
2121
|
+
// p5.MediaElement.prototype.setModified
|
|
2122
|
+
|
|
2123
|
+
// p5.MediaElement.prototype.onended
|
|
2124
|
+
|
|
2125
|
+
// p5.MediaElement.prototype.connect
|
|
2126
|
+
|
|
2127
|
+
// p5.MediaElement.prototype.disconnect
|
|
2128
|
+
|
|
2129
|
+
// p5.MediaElement.prototype.showControls
|
|
2130
|
+
|
|
2131
|
+
// p5.MediaElement.prototype.hideControls
|
|
2132
|
+
|
|
2133
|
+
// p5.MediaElement.prototype.addCue
|
|
2134
|
+
|
|
2135
|
+
// p5.MediaElement.prototype.removeCue
|
|
2136
|
+
|
|
2137
|
+
// p5.MediaElement.prototype.clearCues
|
|
2138
|
+
|
|
2139
|
+
// p5.MediaElement.prototype._onTimeUpdate
|
|
2140
|
+
|
|
2141
|
+
// p5.File
|
|
2142
|
+
|
|
2143
|
+
// p5.File._createLoader
|
|
2144
|
+
|
|
2145
|
+
// p5.File._load
|
|
2146
|
+
});
|