UNPKG

33.5 kBHTMLView Raw
1<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
2 "http://www.w3.org/TR/html4/loose.dtd">
3<html>
4<head>
5
6 <link rel="stylesheet" href="qunit.css" type="text/css" media="screen"/>
7 <script type="text/javascript" src="qunit.js"></script>
8 <script type="text/javascript" src="jquery.js"></script>
9
10 <script type="text/javascript" src="../build/dat.gui.js"></script>
11 <script type="text/javascript">
12
13 $.noConflict();
14 jQuery(document).ready(function($) {
15 var math = dat.color.math;
16 var interpret = dat.color.interpret;
17 var Color = dat.color.Color;
18 var dom = dat.dom.dom;
19 var Controller = dat.controllers.Controller;
20 var BooleanController = dat.controllers.BooleanController;
21 var OptionController = dat.controllers.OptionController;
22 var StringController = dat.controllers.StringController;
23 var NumberController = dat.controllers.NumberController;
24 var NumberControllerBox = dat.controllers.NumberControllerBox;
25 var NumberControllerSlider = dat.controllers.NumberControllerSlider;
26 var FunctionController = dat.controllers.FunctionController;
27 var ColorController = dat.controllers.ColorController;
28 var GUI = dat.gui.GUI;
29
30
31 module("Color Math");
32
33 test("rgb_to_hex", function() {
34
35 equal(
36 math.rgb_to_hex(100, 255, 20),
37 0x64ff14
38 );
39
40 });
41
42 test("component_from_hex", function() {
43
44 equal(
45 math.component_from_hex(0xff3366, 0),
46 0x66,
47 'get blue'
48 );
49
50 equal(
51 math.component_from_hex(0xff3366, 1),
52 0x33,
53 'get green'
54 );
55
56 equal(
57 math.component_from_hex(0xff3366, 2),
58 0xff,
59 'get red'
60 );
61
62 });
63
64 test("hex_with_component", function() {
65
66 equal(
67 math.hex_with_component(0x002203, 0, 0x32),
68 0x002232,
69 'replace blue'
70 );
71
72 equal(
73 math.hex_with_component(0x002203, 1, 0x32),
74 0x003203,
75 'replace green'
76 );
77
78 equal(
79 math.hex_with_component(0x002203, 2, 0x32),
80 0x322203,
81 'replace red'
82 );
83
84 });
85
86 test("rgb_to_hsv", function() {
87
88 match(
89 math.rgb_to_hsv(173, 52, 141),
90 {
91 h: 315.86776859504135,
92 s: 0.6994219653179191,
93 v: 0.6784313725490196
94 });
95
96 match(
97 math.rgb_to_hsv(10, 10, 10),
98 {
99 h: NaN,
100 s: 0,
101 v: 0.0392156862745098
102 }, 'grayscale');
103
104 match(
105 math.rgb_to_hsv(0, 0, 0),
106 {
107 h: NaN,
108 s: 0,
109 v: 0
110 }, 'black');
111
112 });
113
114 test("hsv_to_rgb", function() {
115
116 match(
117 math.hsv_to_rgb(255, 0.85, 0.46),
118 {
119 r: 42.52125000000001,
120 g: 17.595000000000006,
121 b: 117.30000000000001
122 });
123
124 match(
125 math.hsv_to_rgb(0, 0, 0.46),
126 {
127 r: 117.30000000000001,
128 g: 117.30000000000001,
129 b: 117.30000000000001
130 }, 'grayscale');
131
132 });
133
134 module("Color Interpretations");
135
136 test("CSS Strings", function() {
137
138 match(
139 interpret('#ccc'),
140 {
141 hex: 0xcccccc,
142 space: 'HEX',
143 conversionName: 'THREE_CHAR_HEX'
144 },
145 'THREE_CHAR_HEX'
146 );
147
148 match(
149 interpret('#f09'),
150 {
151 hex: 0xff0099,
152 space: 'HEX',
153 conversionName: 'THREE_CHAR_HEX'
154 },
155 'THREE_CHAR_HEX'
156 );
157
158 match(
159 interpret('#0f93cd'),
160 {
161 hex: 0x0f93cd,
162 space: 'HEX',
163 conversionName: 'SIX_CHAR_HEX'
164 },
165 'SIX_CHAR_HEX'
166 );
167
168 match(
169 interpret('rgba(255,10,200,0.3)'),
170 {
171 r: 255,
172 g: 10,
173 b: 200,
174 a: 0.3,
175 space: 'RGB',
176 conversionName: 'CSS_RGBA'
177 },
178 'CSS_RGBA'
179 );
180
181 match(
182 interpret('rgb(255,10,200)'),
183 {
184 r: 255,
185 g: 10,
186 b: 200,
187 space: 'RGB',
188 conversionName: 'CSS_RGB'
189 },
190 'CSS_RGB'
191 );
192
193 });
194
195 test("Other", function() {
196
197 match(
198 interpret(0xff3322),
199 {
200 hex: 0xff3322,
201 space: 'HEX',
202 conversionName: 'HEX'
203 },
204 'HEX'
205 );
206
207 match(
208 interpret([255, 255, 0]),
209 {
210 r: 255,
211 g: 255,
212 b: 0,
213 space: 'RGB',
214 conversionName: 'RGB_ARRAY'
215 },
216 'RGB_ARRAY'
217 );
218
219
220 match(
221 interpret([0, 110, 255, 0.3]),
222 {
223 r: 0,
224 g: 110,
225 b: 255,
226 a: 0.3,
227 space: 'RGB',
228 conversionName: 'RGBA_ARRAY'
229 },
230 'RGBA_ARRAY'
231 );
232
233 match(
234 interpret({
235 r: 255,
236 g: 255,
237 b: 200
238 }),
239 {
240 r: 255,
241 g: 255,
242 b: 200,
243 space: 'RGB',
244 conversionName: 'RGB_OBJ'
245 },
246 'RGB_OBJ'
247 );
248
249 match(
250 interpret({
251 r: 255,
252 g: 255,
253 b: 200,
254 a: 0.2
255 }),
256 {
257 r: 255,
258 g: 255,
259 b: 200,
260 a: 0.2,
261 space: 'RGB',
262 conversionName: 'RGBA_OBJ'
263 },
264 'RGBA_OBJ'
265 );
266
267 match(
268 interpret({
269 h: 360,
270 s: 1,
271 v: 0.5
272 }),
273 {
274 h: 360,
275 s: 1,
276 v: 0.5,
277 space: 'HSV',
278 conversionName: 'HSV_OBJ'
279 },
280 'HSV_OBJ'
281 );
282
283 match(
284 interpret({
285 h: 360,
286 s: 1,
287 v: 0.5,
288 a: 0.8
289 }),
290 {
291 h: 360,
292 s: 1,
293 v: 0.5,
294 a: 0.8,
295 space: 'HSV',
296 conversionName: 'HSVA_OBJ'
297 },
298 'HSVA_OBJ'
299 );
300
301 match(
302 interpret('Failuuureeee'),
303 false,
304 'FAIL'
305 );
306
307 });
308
309 module("Color Objects");
310
311 test("Creation", function() {
312
313 var c = new Color(255, 100, 20, 0.3);
314
315 equal(c.r, 255, 'red');
316 equal(c.g, 100, 'green');
317 equal(c.b, 20, 'blue');
318 equal(c.a, 0.3, 'alpha');
319
320 equal(c.hex, 0xff6414, 'hex');
321
322 equal(Math.round(c.h), 20, 'hue');
323 equal(Math.round(c.s * 100), 92, 'saturation');
324 equal(Math.round(c.v * 100), 100, 'value');
325
326 });
327
328 test("RGB Modification", function() {
329
330 var c = new Color(255, 100, 20, 0.3);
331
332 c.r -= 100;
333
334 equal(c.r, 155, 'green');
335 equal(c.g, 100, 'green');
336 equal(c.b, 20, 'blue');
337 equal(c.a, 0.3, 'alpha');
338
339 equal(c.hex, 0x9b6414, 'hex');
340
341 equal(Math.round(c.h), 36, 'hue');
342 equal(Math.round(c.s * 100), 87, 'saturation');
343 equal(Math.round(c.v * 100), 61, 'value');
344
345 });
346
347 test("RGB Modification", function() {
348
349 var c = new Color(255, 100, 20, 0.3);
350
351 c.r -= 100;
352
353 equal(c.r, 155, 'green');
354 equal(c.g, 100, 'green');
355 equal(c.b, 20, 'blue');
356 equal(c.a, 0.3, 'alpha');
357
358 equal(c.hex, 0x9b6414, 'hex');
359
360 equal(Math.round(c.h), 36, 'hue');
361 equal(Math.round(c.s * 100), 87, 'saturation');
362 equal(Math.round(c.v * 100), 61, 'value');
363
364 });
365
366 test("Setting RGB, Modifying HSV", function() {
367
368 var c = new Color(255, 0, 100);
369
370 c.s = 1;
371
372 equal(c.r, 255);
373 equal(c.g, 0);
374 equalish(c.b, 100, 0.00001);
375 equal(c.a, 1);
376
377 });
378
379
380 test("Setting HSV, Modifying RGB", function() {
381
382 var c = new Color({ h: 340, s: 0.3, v: 0.9 });
383
384 c.g = 0;
385
386 equal(c.h, 312);
387 equal(c.s, 1);
388 equal(c.v, 0.9);
389 equal(c.a, 1);
390
391 });
392
393 test("Grayscale Hue", function() {
394
395 var c = new Color(120, 100, 20, 0.3);
396
397 var prevHue = c.h;
398
399 equal(typeof c.h, 'number');
400
401 // Make graysale
402 c.g = c.b = c.r;
403
404 equal(c.h, prevHue, 'grayscale, hue intact');
405
406 });
407
408 test("Black Hue", function() {
409
410 var c = new Color(120, 100, 20, 0.3);
411
412 var prevHue = c.h;
413 console.log('heh?');
414
415 c.r = 0;
416 c.b = 0;
417 c.g = 0;
418
419 equal(c.h, prevHue, 'black, hue intact');
420
421 });
422
423 function match(a, b, msg) {
424
425 for (var i in b) {
426 if (b[i] !== b[i]) {
427 ok(a[i] !== a[i], msg)
428 } else {
429 equal(b[i], a[i], msg);
430 }
431 }
432
433 }
434
435 function equalish(a, b, tolerance, label) {
436 return ok(Math.abs(a - b) < tolerance, label);
437 }
438
439
440
441
442 function initObject() {
443 return {
444 numberProperty: 10,
445 stringProperty: 'foo',
446 booleanProperty: false,
447 functionProperty: function() {
448 // do something
449 },
450 anotherBooleanProperty: true,
451 colorProperty: "#ffffff"
452 };
453 }
454
455 var hidden = document.createElement('div');
456 hidden.style.display = 'none';
457 document.body.appendChild(hidden);
458
459 module("Controller");
460
461 test("Retrieves values", function() {
462
463 var object = initObject();
464
465 var c1 = new Controller(object, 'numberProperty');
466 var c2 = new Controller(object, 'stringProperty');
467 var c3 = new Controller(object, 'booleanProperty');
468 var c4 = new Controller(object, 'functionProperty');
469
470 equal(c1.getValue(), object.numberProperty, "Number property");
471 equal(c2.getValue(), object.stringProperty, "String property");
472 equal(c3.getValue(), object.booleanProperty, "Boolean property");
473 equal(c4.getValue(), object.functionProperty, "Function property");
474
475 });
476
477 test("Sets values", function() {
478 var object = initObject();
479
480 var c1 = new Controller(object, 'numberProperty');
481 c1.setValue(40);
482
483 equal(40, object.numberProperty);
484
485 });
486
487 module("BooleanController");
488
489 test("Acknowledges original values", function() {
490
491 var object = initObject();
492 var c1 = new BooleanController(object, 'booleanProperty');
493 var c2 = new BooleanController(object, 'anotherBooleanProperty');
494
495 equal(c1.__checkbox.checked,
496 object.booleanProperty);
497
498console.log(c2.__checkbox.getAttribute('checked'));
499
500 equal(c2.__checkbox.getAttribute('checked') === 'checked',
501 object.anotherBooleanProperty);
502
503 });
504
505 test("Modifies values (starting true)", function() {
506
507 var object = { booleanProperty: true };
508
509 var c1 = new BooleanController(object, 'booleanProperty');
510
511 // Must append this to body for click to work
512 hidden.appendChild(c1.domElement);
513
514 dom.fakeEvent(c1.__checkbox, 'click');
515 equal(false, object.booleanProperty, 'changes');
516 equal(false, c1.__checkbox.checked, 'checkbox valid');
517
518 dom.fakeEvent(c1.__checkbox, 'click');
519 equal(true, object.booleanProperty, 'changes back');
520
521 equal(true, c1.__checkbox.checked, 'checkbox valid');
522
523
524
525 object.booleanProperty = false;
526 dom.fakeEvent(c1.__checkbox, 'click');
527 equal(false, object.booleanProperty, 'maintains sync');
528 equal(false, c1.__checkbox.checked, 'checkbox valid');
529
530 });
531
532 test("Modifies values (starting false)", function() {
533
534 var object = { booleanProperty: false };
535
536 var c1 = new BooleanController(object, 'booleanProperty');
537
538 // Must append this to body for click to work
539 hidden.appendChild(c1.domElement);
540
541 dom.fakeEvent(c1.__checkbox, 'click');
542 equal(true, object.booleanProperty, 'changes');
543 equal(true, c1.__checkbox.checked, 'checkbox valid');
544
545 dom.fakeEvent(c1.__checkbox, 'click');
546 equal(false, object.booleanProperty, 'changes back');
547 equal(false, c1.__checkbox.checked, 'checkbox valid');
548
549 object.booleanProperty = true;
550 dom.fakeEvent(c1.__checkbox, 'click');
551 equal(true, object.booleanProperty, 'maintains sync');
552 equal(true, c1.__checkbox.checked, 'checkbox valid');
553
554
555 });
556
557 module("OptionController");
558
559 test("Populates with string array", function() {
560 var object = initObject();
561 var options = ['Jono', 'Doug', 'George'];
562
563 var c1 = new OptionController(object, 'stringProperty',
564 options);
565
566// hidden.appendChild(c1.domElement);
567
568 $(c1.__select).children().each(function(index) {
569 equal(options[index], this.innerHTML);
570 equal(options[index], $(this).attr('value'));
571 });
572
573 });
574
575 test("Populates with map", function() {
576 var object = initObject();
577 var options = {
578 'Small': 0,
579 'Medium': 2,
580 'Large': 10
581 };
582
583 var c1 = new OptionController(object, 'stringProperty',
584 options);
585
586// hidden.appendChild(c1.domElement);
587
588 $(c1.__select).children().each(function(index) {
589 equal(options[this.innerHTML], $(this).attr('value'));
590 });
591
592 });
593
594 test("Acknowledges original value", function() {
595 var object = initObject();
596 var options = {
597 'Small': 0,
598 'Medium': 2,
599 'Large': object.numberProperty
600 };
601
602 var c1 = new OptionController(object, 'numberProperty',
603 options);
604
605// hidden.appendChild(c1.domElement);
606
607 equal($(c1.__select).val(), object.numberProperty);
608
609 });
610
611 test("Modifies values", function() {
612 var object = initObject();
613 var options = {
614 'Small': 0,
615 'Medium': 2,
616 'Large': 10
617 };
618
619 var c1 = new OptionController(object, 'numberProperty',
620 options);
621
622 var c2 = new OptionController(object, 'stringProperty', ['a', 'b', 'c']);
623
624// hidden.appendChild(c1.domElement);
625
626 var elem = $(c1.__select).val(options['Medium'])[0];
627 dom.fakeEvent(elem, 'change');
628
629 equal(options['Medium'], object.numberProperty, 'Number property');
630
631 elem = $(c2.__select).val('b')[0];
632 dom.fakeEvent(elem, 'change');
633
634 equal('b', object.stringProperty, 'String property');
635
636 });
637
638 module("StringController");
639
640 test("Acknowledges original value", function() {
641 var object = initObject();
642 var c1 = new StringController(object, 'stringProperty');
643
644 equal($(c1.__input).val(), object.stringProperty);
645
646 });
647
648 test("Modifies values", function() {
649 var object = initObject();
650 var c1 = new StringController(object, 'stringProperty');
651
652 var newVal = (new Date()).toJSON();
653
654 var elem = $(c1.__input).val(newVal)[0];
655 dom.fakeEvent(elem, 'change');
656
657 equal(newVal, object.stringProperty);
658
659 });
660
661 module("NumberController");
662
663 test("Constraints", function() {
664 var object = initObject();
665 var params = { min: 0, max: 10, step: 2 };
666
667 var c1 = new NumberController(object,
668 'numberProperty', params);
669
670 c1.setValue(12);
671 equal(object.numberProperty, params.max, "Maximum values");
672
673 c1.setValue(-20);
674 equal(object.numberProperty, params.min, "Minimum values");
675
676 c1.setValue(1);
677 equal(object.numberProperty, 2, "Steps");
678
679 });
680
681 module("NumberControllerBox");
682
683 test("Acknowledges original value", function() {
684 var object = initObject();
685 var c1 = new NumberControllerBox(object,
686 'numberProperty');
687
688// var newVal = Date.now();
689//
690// $(c1.__input).val(newVal).trigger('change');
691//
692 equal($(c1.__input).val(), object.numberProperty.toString());
693
694 });
695
696 test("Modifies value", function() {
697 var object = initObject();
698 var c1 = new NumberControllerBox(object,
699 'numberProperty');
700
701 var newVal = Date.now();
702
703 var elem = $(c1.__input).val(newVal)[0];
704 dom.fakeEvent(elem, 'change');
705
706 equal(typeof object.numberProperty, 'number');
707 equal(object.numberProperty, newVal);
708
709 });
710
711
712 test("Handles invalid input", function() {
713 var object = initObject();
714 var c1 = new NumberControllerBox(object,
715 'numberProperty');
716
717 var newVal = '~! I98* omg this is not a N&^&*^umber.e-083.9';
718 var prevVal = object.numberProperty;
719
720 var elem = $(c1.__input).val(newVal)[0];
721 dom.fakeEvent(elem, 'change');
722
723 equal(typeof object.numberProperty, 'number');
724 equal(object.numberProperty, prevVal);
725
726 });
727
728
729 test("Handles drag", function() {
730
731 var object = { numberProperty: 0 };
732 var params = { step: Math.random() * 21 };
733
734 var c1 = new NumberControllerBox(object,
735 'numberProperty', params);
736
737 var prevVal = object.numberProperty;
738 var disp = Math.round(Math.random() * 100);
739
740 var elem = c1.__input;
741
742 dom.fakeEvent(elem, 'mousedown', {
743 x: 0,
744 y: 0
745 });
746 dom.fakeEvent(window, 'mousemove', {
747 x: 0,
748 y: disp
749 });
750 dom.fakeEvent(window, 'mouseup');
751
752 equal(object.numberProperty, prevVal + params.step * -disp);
753
754 });
755
756 module("NumberControllerSlider");
757
758 test("Acknowledges original value", function() {
759
760 var object = initObject();
761
762 var min = 0, max = 50;
763
764 var c1 = new NumberControllerSlider(object, 'numberProperty', min, max);
765
766 document.body.appendChild(c1.domElement);
767
768 var bw = dom.getWidth(c1.__background);
769 var fw = dom.getWidth(c1.__foreground);
770
771 document.body.removeChild(c1.domElement);
772
773 equalish(fw/bw, (object.numberProperty - min) / (max - min), 0.01, 'Slider width indicative of value.');
774
775 });
776
777 test("Modifies values", function() {
778
779 var object = initObject();
780
781 var min = 0, max = 50;
782
783 var c1 = new NumberControllerSlider(object, 'numberProperty', min, max, 1);
784
785 document.body.appendChild(c1.domElement);
786
787 var o = dom.getOffset(c1.domElement);
788 var w = dom.getWidth(c1.domElement);
789
790 dom.fakeEvent(c1.__background, 'mousedown', {
791 x: o.left + w/2,
792 y: o.top
793 });
794
795 var bw = dom.getWidth(c1.__background);
796 var fw = dom.getWidth(c1.__foreground);
797
798 equal(object.numberProperty, (min+max)/2, 'Mouse down');
799
800 equalish(fw/bw, (object.numberProperty - min) / (max - min), 0.01, 'Slider width still indicative of value.');
801
802 dom.fakeEvent(window, 'mousemove', {
803 x: o.left,
804 y: o.top
805 });
806
807 fw = dom.getWidth(c1.__foreground);
808
809
810 equal(object.numberProperty, min, 'Mouse move');
811
812 equal(fw/bw, (object.numberProperty - min) / (max - min), 'Slider width still indicative of value.');
813
814
815 dom.fakeEvent(window, 'mouseup');
816
817 dom.fakeEvent(window, 'mousemove', {
818 x: o.left+w,
819 y: o.top
820 });
821
822 equal(object.numberProperty, min, 'Mouse releases drag');
823
824 document.body.removeChild(c1.domElement);
825
826
827 });
828
829 module("ColorController");
830
831 test("Get Color", function() {
832 var object = initObject();
833 var c1 = new ColorController(object, 'colorProperty');
834 document.body.appendChild(c1.domElement);
835
836 var input = c1.domElement.getElementsByTagName("input")[0];
837 equal(input.value, object.colorProperty, "Input value is the same as the colorProperty");
838
839 document.body.removeChild(c1.domElement);
840 });
841
842/*
843 test("Set Color", function() {
844 // get from click, get from hover
845 var object = initObject();
846 var c1 = new ColorController(object, 'colorProperty');
847
848 document.body.appendChild(c1.domElement);
849 var input = c1.domElement.getElementsByTagName("input")[0];
850
851 // type in color
852 input.value = "#ff0";
853
854 // TODO fake events for keys not working
855 dom.fakeEvent(input, 'keydown', { keyCode: 13 });
856
857 // click sv field
858
859 // click hue slider
860
861 equal(1,0, "TODO: add set color tests.");
862
863 document.body.removeChild(c1.domElement);
864 });
865*/
866 module("Controller Events");
867
868 test("onChange", function() {
869
870 var object = initObject();
871
872 var c0 = new NumberControllerSlider(object, 'numberProperty');
873 var c1 = new NumberControllerBox(object, 'numberProperty');
874 var c2 = new StringController(object, 'stringProperty');
875 var c3 = new BooleanController(object, 'booleanProperty');
876 var c4 = new FunctionController(object, 'functionProperty');
877 var c5 = new OptionController(object, 'stringProperty', [0,1,2]);
878
879 var c0_changed = false;
880 var c1_changed = false;
881 var c2_changed = false;
882 var c3_changed = false;
883 var c4_changed = false;
884 var c5_changed = false;
885
886 c0.onChange(function() {
887 c0_changed = true;
888 });
889
890 c1.onChange(function() {
891 c1_changed = true;
892 });
893
894 c2.onChange(function() {
895 c2_changed = true;
896 });
897
898 c3.onChange(function() {
899 c3_changed = true;
900 });
901
902 c4.onChange(function() {
903 c4_changed = true;
904 });
905
906 c5.onChange(function() {
907 c5_changed = true;
908 });
909
910 hidden.appendChild(c3.domElement);
911
912 c0.setValue(0.5);
913 c1.setValue(10);
914 c2.setValue('hey');
915 c3.setValue(false);
916 c4.fire();
917 c5.setValue('yo');
918
919 ok(c1_changed, 'NumberControllerSlider');
920 ok(c1_changed, 'NumberControllerBox');
921 ok(c2_changed, 'StringController');
922 ok(c3_changed, 'BooleanController');
923 ok(c4_changed, 'FunctionController');
924 ok(c5_changed, 'OptionController');
925
926 });
927
928 test("onFinishChange", function() {
929
930 var object = initObject();
931
932 var min = 0, max = 100;
933
934 var c0 = new NumberControllerSlider(object, 'numberProperty', min, max);
935 var c1 = new NumberControllerBox(object, 'numberProperty');
936 var c2 = new StringController(object, 'stringProperty');
937
938 var c0_changed = false;
939 var c1_changed = false;
940 var c2_changed = false;
941
942 c0.onFinishChange(function() {
943 c0_changed = true;
944 });
945
946 document.body.appendChild(c0.domElement);
947
948 var o = dom.getOffset(c0.domElement);
949 var w = dom.getWidth(c0.domElement);
950
951 dom.fakeEvent(c0.__background, 'mousedown', {
952 x: o.left + w/2,
953 y: o.top
954 });
955
956 ok(!c0_changed, 'NumberControllerSlider didn\'t jump the gun ...');
957
958 dom.fakeEvent(window, 'mousemove', {
959 x: o.left,
960 y: o.top
961 });
962 dom.fakeEvent(window, 'mouseup', {
963 x: o.left,
964 y: o.top
965 });
966
967 ok(c0_changed, 'NumberControllerSlider fires when needed.');
968
969 document.body.removeChild(c0.domElement);
970
971 c1.onFinishChange(function() {
972 c1_changed = true;
973 });
974
975 document.body.appendChild(c1.domElement);
976
977 c1.__input.focus();
978 c1.__input.value = '1';
979 ok(!c1_changed, 'NumberControllerBox didn\'t jump the gun ...');
980 c1.__input.value += '2';
981 c1.__input.blur();
982
983 document.body.removeChild(c1.domElement);
984
985 ok(c1_changed, 'NumberControllerBox fires when needed.');
986
987 c2.onFinishChange(function() {
988 c2_changed = true;
989 });
990
991 document.body.appendChild(c2.domElement);
992
993 c2.__input.focus();
994 c2.__input.value = 'friendBudd';
995 ok(!c2_changed, 'StringController didn\'t jump the gun ...');
996 c2.__input.value += 'y';
997 c2.__input.blur();
998
999 document.body.removeChild(c2.domElement);
1000
1001 ok(c2_changed, 'StringController fires when needed.');
1002
1003 });
1004
1005 function equalish(a, b, tolerance, label) {
1006 return ok(Math.abs(a - b) < tolerance, label);
1007 }
1008
1009
1010
1011 module('GUI Appearance');
1012
1013 test('Auto placement', function() {
1014
1015 var gui = new GUI();
1016 gui.add({ x: 0 }, 'x');
1017
1018 var gui2 = new GUI();
1019 gui2.add({ x: 0 }, 'x');
1020
1021 equal($('.dg.ac').length, 1, 'A single auto-place container created');
1022 equal($('.dg.ac').children().length, 2, 'Containing two GUI\'s');
1023
1024 equal(gui.parent, undefined);
1025 equal(gui2.parent, undefined);
1026
1027 $('.dg.ac').children().each(function(key, value) {
1028 ok($(value).hasClass(GUI.CLASS_AUTO_PLACE), 'GUI has auto-place class');
1029 ok($(value).hasClass(GUI.CLASS_MAIN), 'GUI has main class');
1030
1031 });
1032
1033 gui.destroy();
1034 gui2.destroy();
1035
1036 });
1037
1038 test('Auto placement scroll', function() {
1039
1040 var gui = new GUI();
1041
1042 // Add a lot of controllers. This will fail if you have some freakishly tall monitor.
1043 for (var i = 0; i < 100; i++) {
1044 gui.add({ x: 0 }, 'x');
1045 }
1046
1047
1048 setTimeout(function() {
1049 ok($(gui.domElement).hasClass(GUI.CLASS_TOO_TALL), 'GUI has too tall class');
1050 notEqual($(gui.domElement).children('ul')[0].style.height, 'auto');
1051
1052 gui.destroy();
1053 }, 0);
1054 });
1055
1056 test('close/open button position', function() {
1057
1058 var gui = new GUI({closeOnTop:true});
1059 var gui2 = new GUI({closeOnTop:false});
1060 var gui3 = new GUI();
1061
1062 ok($(gui.domElement).find('ul').prev().hasClass(GUI.CLASS_CLOSE_BUTTON) && $(gui.domElement).find('ul').prev().hasClass(GUI.CLASS_CLOSE_TOP), 'GUI has close/open button on top');
1063 ok($(gui2.domElement).find('ul').next().hasClass(GUI.CLASS_CLOSE_BUTTON) && $(gui2.domElement).find('ul').next().hasClass(GUI.CLASS_CLOSE_BOTTOM), 'GUI has close/open button on bottom');
1064 ok($(gui3.domElement).find('ul').next().hasClass(GUI.CLASS_CLOSE_BUTTON) && $(gui3.domElement).find('ul').next().hasClass(GUI.CLASS_CLOSE_BOTTOM), 'GUI has close/open button on bottom by default');
1065
1066 gui.destroy();
1067 gui2.destroy();
1068 gui3.destroy();
1069
1070 });
1071
1072 test('Folders', function() {
1073
1074 var gui = new GUI();
1075 gui.add({x:0}, 'x');
1076
1077 var name1 = 'name';
1078 var f1 = gui.addFolder(name1);
1079
1080 f1.add({ x: 0 }, 'x');
1081
1082 equal(f1.name, name1, "Accepts name");
1083 equal($(f1.domElement).find('li.title').html(), name1, "Displays name");
1084
1085 equal(f1.closed, true, "Closed by default");
1086 ok($(f1.domElement).find('ul').hasClass(GUI.CLASS_CLOSED), "Has closed class");
1087
1088 var title = $(f1.domElement).find('li.title')[0];
1089
1090 dom.fakeEvent(title, 'click');
1091
1092 equal(f1.closed, false, "Opens on click");
1093 ok(!$(f1.domElement).find('ul').hasClass(GUI.CLASS_CLOSED), "Opens on click");
1094
1095 dom.fakeEvent(title, 'click');
1096
1097 equal(f1.closed, true, "Closes back up");
1098 ok($(f1.domElement).find('ul').hasClass(GUI.CLASS_CLOSED), "Closes back up");
1099
1100 gui.destroy();
1101
1102 });
1103
1104
1105 module("GUI Controller Methods");
1106
1107 test('options', function() {
1108
1109 var gui = new GUI();
1110
1111 var controller = gui.add({ x: 0 }, 'x').options(0, 1, 2, 3, 4);
1112
1113 $(controller.__select).children().each(function(key, value) {
1114 equals(value.innerHTML, key, 'By array name okay');
1115 equals(value.value, key, 'By array value okay');
1116 });
1117
1118 controller = gui.add({ x: 0 }, 'x').options(
1119 {
1120 0: '0',
1121 1: '1',
1122 2: '2',
1123 3: '3',
1124 4: '4'
1125 }
1126 );
1127
1128 $(controller.__select).children().each(function(key, value) {
1129 equals(value.innerHTML, key, 'By array name okay');
1130 equals(value.value, key, 'By array value okay');
1131 });
1132
1133 gui.destroy();
1134
1135 });
1136
1137 test('name', function() {
1138
1139 var gui = new GUI();
1140
1141 var name = 'hey man';
1142 var name2 = 'yoyoo';
1143
1144 var controller = gui.add({ x: 0 }, 'x').name(name);
1145
1146 equals($(controller.__li).find('.property-name').html(), name);
1147
1148 controller.name(name2);
1149 equals($(controller.__li).find('.property-name').html(), name2);
1150
1151 gui.destroy();
1152
1153 });
1154
1155 test('listen', function() {
1156
1157 var gui = new GUI();
1158
1159 var obj = { x: 0 };
1160
1161 var returned1 = gui.add(obj, 'x');
1162 var returned2 = returned1.listen();
1163
1164 obj.x = 10;
1165
1166 setTimeout(function() {
1167 ok(returned1 === returned2, 'Returns self');
1168
1169 equal(returned1.__input.value, obj.x, 'Updates display');
1170 gui.destroy();
1171 }, 0);
1172
1173 });
1174
1175 test('remove', function() {
1176
1177 var gui = new GUI();
1178
1179 var c = gui.add({x:0}, 'x');
1180
1181 ok($.contains(gui.domElement, c.domElement), "Now you see it");
1182 c.remove();
1183
1184 ok(!$.contains(gui.domElement, c.domElement), "Now you don't.");
1185
1186 gui.destroy();
1187
1188 });
1189
1190 test('removeFolder', function() {
1191
1192 var gui = new GUI();
1193
1194 var f = gui.addFolder('Temporary folder');
1195
1196 ok($.contains(gui.domElement, f.domElement), "Now you see it");
1197 gui.removeFolder(f);
1198
1199 ok(!$.contains(gui.domElement, f.domElement), "Now you don't.");
1200
1201 gui.destroy();
1202
1203 });
1204
1205 test('min, max & step', function() {
1206
1207 var gui = new GUI();
1208
1209 var min = -10;
1210 var max = 200;
1211 var step = 5;
1212
1213 var c = gui.add({ x: 0 }, 'x');
1214
1215 c.min(min);
1216 equals(c.__min, min, 'min');
1217
1218 c.step(step);
1219 equals(c.__step, step, 'step');
1220
1221 var c2 = c.max(max);
1222 equals(c.__max, max, 'max');
1223
1224 notEqual(c2, c, 'Controller has changed.');
1225
1226 ok($(c2.__li).find('.slider').length > 0, 'Slider added');
1227
1228 equals(c.__step, step, 'step intact');
1229
1230 gui.destroy();
1231
1232 });
1233
1234 module("GUI Controller Augmentation");
1235
1236 test('Adds NumberControllerBox to sliders', function() {
1237 var gui = new GUI();
1238
1239 var c = gui.add({ x: 0 }, 'x', 0, 10);
1240
1241 ok($(c.__li).find('input').length > 0, 'NumberControllerBox added');
1242
1243 gui.destroy();
1244
1245 });
1246
1247 test('Clickable rows for BooleanControllers', function() {
1248
1249 var gui = new GUI();
1250
1251 var c = gui.add({ x: false }, 'x');
1252
1253 equal(c.__checkbox.checked, false, 'Acknowledges original');
1254
1255 dom.fakeEvent(c.__li, 'click');
1256
1257 equal($(c.__checkbox).attr('checked'), 'checked', 'Changes when I click the row');
1258
1259 dom.fakeEvent(c.__li, 'click');
1260
1261 equal(c.__checkbox.checked, false, 'Changes back');
1262
1263 gui.destroy();
1264
1265 });
1266
1267 test('Clickable rows for FunctionControllers', function() {
1268
1269 expect(3);
1270
1271 var gui = new GUI();
1272
1273 var c = gui.add({ x: function() {
1274 ok(true)
1275 } }, 'x');
1276
1277 dom.fakeEvent(c.__li, 'click');
1278 c.fire();
1279 dom.fakeEvent(c.__li, 'click');
1280
1281 gui.destroy();
1282
1283 });
1284
1285 module('GUI Saving');
1286
1287 test('Remembering values', function() {
1288
1289 var object = {
1290 number: 0,
1291 boolean: false,
1292 string: 'hey'
1293 };
1294
1295 var controllers = {};
1296
1297 var changed = {
1298 number: -20,
1299 boolean: true,
1300 string: 'hang'
1301 };
1302
1303 var gui = new GUI();
1304 gui.remember(object);
1305
1306 for (var i in object) {
1307 controllers[i] = gui.add(object, i);
1308 }
1309
1310 for (i in controllers) {
1311 controllers[i].setValue(changed[i]);
1312 }
1313
1314 var saveObject = gui.getSaveObject();
1315
1316 gui.destroy();
1317
1318 gui = new GUI({
1319 load: saveObject
1320 });
1321
1322 gui.remember(object);
1323
1324 for (i in object) {
1325 controllers[i] = gui.add(object, i);
1326 equal(object[i], changed[i]);
1327 }
1328
1329 ensurePresetSelectDisplay(gui);
1330
1331 gui.destroy();
1332
1333 });
1334
1335 test('Presets', function() {
1336
1337 var presetName = 'New Preset';
1338
1339 var object = {
1340 number: 0,
1341 boolean: false,
1342 string: 'hey'
1343 };
1344
1345 var original = {};
1346
1347 for (var i in object) {
1348 original[i] = object[i];
1349 }
1350
1351 var controllers = {};
1352
1353 var changed = {
1354 number: -20,
1355 boolean: true,
1356 string: 'hang'
1357 };
1358
1359 var gui = new GUI();
1360 gui.remember(object);
1361
1362 for (i in object) {
1363 controllers[i] = gui.add(object, i);
1364 }
1365
1366 for (i in controllers) {
1367 controllers[i].setValue(changed[i]);
1368 }
1369
1370 ensurePresetSelectDisplay(gui);
1371
1372 gui.saveAs(presetName);
1373
1374 ensurePresetSelectDisplay(gui);
1375
1376 var saveObject = gui.getSaveObject();
1377 console.log(saveObject);
1378
1379 gui.destroy();
1380
1381 gui = new GUI({
1382 load: saveObject
1383 });
1384
1385 gui.remember(object);
1386
1387 for (i in object) {
1388 controllers[i] = gui.add(object, i);
1389 equal(object[i], changed[i], "Uses last defined preset");
1390 }
1391
1392 equal(gui.preset, presetName, "Preset value correct");
1393 ensurePresetSelectDisplay(gui);
1394
1395 gui.destroy();
1396
1397 gui = new GUI({
1398 preset: "Default",
1399 load: saveObject
1400 });
1401
1402 gui.remember(object);
1403
1404 for (i in object) {
1405 controllers[i] = gui.add(object, i);
1406 equal(object[i], original[i], "Loads with explicitly set preset");
1407 }
1408
1409 equal(gui.preset, "Default", "Preset value correct");
1410 ensurePresetSelectDisplay(gui);
1411
1412 gui.preset = presetName;
1413
1414 for (i in object) {
1415 equal(object[i], changed[i], "Changes via gui.preset property");
1416 }
1417
1418 $(gui.__preset_select).val('Default');
1419 dom.fakeEvent(gui.__preset_select, 'change');
1420
1421 for (i in object) {
1422 equal(object[i], original[i], "Changes via dropdown");
1423 }
1424
1425 gui.destroy();
1426
1427 });
1428
1429 function ensurePresetSelectDisplay(gui) {
1430
1431 equal($(gui.__preset_select).children('option:selected')[0].value, gui.preset, "Dropdown display matches preset value");
1432
1433 }
1434
1435
1436});
1437</script>
1438
1439</head>
1440<body>
1441<h1 id="qunit-header"></h1>
1442
1443<h2 id="qunit-banner"></h2>
1444
1445<div id="qunit-testrunner-toolbar"></div>
1446<h2 id="qunit-userAgent"></h2>
1447<ol id="qunit-tests"></ol>
1448<div id="qunit-fixture">test markup, will be hidden</div>
1449</body>
1450</html>