root/public/javascripts/scriptaculous/test/unit/effects_test.html @ 11

Revision 1, 20.8 kB (checked in by falcon, 17 years ago)

Version one -> initial work from the laptop.

Line 
1<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
2        "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
3<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
4<head>
5  <title>script.aculo.us Unit test file</title>
6  <meta http-equiv="content-type" content="text/html; charset=utf-8" />
7  <script src="../../lib/prototype.js" type="text/javascript"></script>
8  <script src="../../src/scriptaculous.js" type="text/javascript"></script>
9  <script src="../../src/unittest.js" type="text/javascript"></script>
10  <link rel="stylesheet" href="../test.css" type="text/css" />
11  <style type="text/css" media="screen">
12    #rotfl {
13      color: red;
14      font-family: serif;
15      font-style: italic;
16      font-size: 40px;
17      background: #fed;
18      padding: 1em;
19      width: 400px;
20    } 
21    .final {
22      color: #fff;
23      font-style: italic;
24      background: #000;
25      opacity: 0.5;
26    }
27    body div.final {
28      font-size: 20px;
29    }
30  </style>
31</head>
32<body>
33<h1>script.aculo.us Unit test file</h1>
34<p>
35  Tests for effects.js
36</p>
37
38<!-- generated elements go in here -->
39<div id="sandbox"></div>
40
41<!-- Log output -->
42<div id="testlog"> </div>
43
44<div class="morphing blub" style="font-size:25px;color:#f00">Well</div>
45<div class="morphing">You know</div>
46<div id="blah" style="border:1px solid black;width:100px">Whoo-hoo!</div>
47
48<div id="error_message">ERROR MESSAGE</div>
49<div id="error_message_2">SECOND ERROR MESSAGE</div>
50<div id="error_message_3" style="border:1px solid red; width:100px; color: #f00">THIRD ERROR MESSAGE</div>
51
52<ul class="error-list" id="error_test_ul">
53  <li>Lorem ipsum dolor sit amet, consectetur adipisicing elit,</li>
54  <li>sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.</li>
55  <li>Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris</li>
56  <li>nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in</li>
57  <li>reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur.</li>
58</ul>
59
60<div id="rotfl">ROTFL</div>
61
62<div id="tween">foo!</div>
63
64<!-- Tests follow -->
65<script type="text/javascript" language="javascript" charset="utf-8">
66// <![CDATA[
67
68  var TAGS =
69    ['div','span','ol','ul','table','p','h1','h2','h3','h4','h5','h6'];
70
71  var COMBINED_EFFECTS =
72    ['Fade','Appear','BlindUp','BlindDown','Puff','SwitchOff','DropOut','Shake',
73     'SlideUp','SlideDown','Pulsate','Squish','Fold','Grow','Shrink'];
74 
75  var COMBINED_RJS_EFFECTS = $w('fade appear blind_up blind_down puff switch_off '+
76    'drop_out shake slide_up slide_down pulsate squish fold grow shrink');
77     
78  var tmp, tmp2;
79
80  new Test.Unit.Runner({
81
82    setup: function() { with (this) {
83      $('sandbox').innerHTML = "";
84    }},
85   
86    teardown: function() { with(this) {
87      // remove all queued effects
88      Effect.Queue.each(function(e) { e.cancel() });
89    }},
90   
91    testExceptionOnNonExistingElement: function() { with(this) {
92      assertRaise('ElementDoesNotExistError', 
93        function(){new Effect.Opacity('nothing-to-see-here')});
94      assertRaise('ElementDoesNotExistError', 
95        function(){new Effect.Move('nothing-to-see-here')});
96      assertRaise('ElementDoesNotExistError', 
97        function(){new Effect.Scale('nothing-to-see-here')});
98      assertRaise('ElementDoesNotExistError', 
99        function(){new Effect.Highlight('nothing-to-see-here')});
100    }},
101   
102    testCallbacks: function() { with(this) {
103      tmp = tmp2 = 0;
104      var e1 = new Effect.Opacity('sandbox',{from:1.0,to:0.5,duration:0.5,
105        beforeStart: function() { tmp++ },
106        beforeStartInternal: function() { tmp++ },
107        beforeSetup: function() { tmp++ },
108        beforeSetupInternal: function() { tmp++ },
109        afterSetup: function() { tmp++ },
110        afterSetupInternal: function() { tmp++ },
111        beforeUpdate: function() { tmp2++ },
112        beforeUpdateInternal: function() { tmp2++ },
113        beforeFinish: function() { tmp++ },
114        beforeFinishInternal: function() { tmp++ },
115        afterFinish: function() { tmp++ },
116        afterFinishInternal: function() { tmp++ }
117      });
118      wait(1000, function() {
119        assertEqual(10, tmp);
120        assert(tmp2 > 0);
121      });
122    }},
123   
124    testEvent: function() { with(this) {
125      tmp = 0;
126      new Effect.Event({ afterFinish:function(){ tmp++ }, position:'end'});
127      wait(100, function() {
128        assertEqual(1, tmp);
129      });
130    }},
131   
132    testTransition: function() { with(this) {
133      // false implies linear
134      var e = new Effect.Opacity('sandbox',{transition:false,from:0.0,to:0.25,duration:0.5});
135      assert(e.options.transition == Effect.Transitions.linear);
136     
137      wait(1000, function() {
138        assertEqual(0.25, $('sandbox').getStyle('opacity'));
139        // default to sinoidal
140        var e = new Effect.Opacity('sandbox',{from:0.0,to:0.25,duration:0.5});
141        assert(e.options.transition == Effect.Transitions.sinoidal);
142        wait(1000, function() {
143          assertEqual(0.25, $('sandbox').getStyle('opacity'));
144         
145          var transitions = [
146            { transition: Effect.Transitions.linear,   expected: 1 },
147            { transition: Effect.Transitions.sinoidal, expected: 1 },
148            { transition: Effect.Transitions.reverse,  expected: 0 },
149            { transition: Effect.Transitions.flicker,  expected: 1 },
150            { transition: Effect.Transitions.wobble,   expected: 1 },
151            { transition: Effect.Transitions.pulse,    expected: 1 },
152            { transition: Effect.Transitions.none,     expected: 0 }
153          ];
154         
155          transitions.each(function(t){
156            var e = new Effect.Opacity('sandbox',{sync:true, from:0, to: 1, transition:t.transition});
157            assert(e.options.transition == t.transition);
158            e.render(1.0);
159            assertEqual(t.expected, e.position, t.transition);
160          });
161         
162        });
163      });
164    }},
165   
166    testInspect: function() { with(this) {
167      var e1 = new Effect.Opacity('sandbox',{from:1.0,to:0.5,duration:0.5});
168      info( e1.inspect() );
169      assertEqual(0, e1.inspect().indexOf('#<Effect:'));
170      assert(e1.inspect().indexOf('idle')>0);
171      wait(1000, function() {
172        assert(e1.inspect().indexOf('finished')>0);
173      });
174    }},
175   
176    testDefaultOptions: function() { with(this) {
177      var oldDefaultOptions = Object.extend({},Effect.DefaultOptions);
178     
179      assertEqual(1.0, Effect.DefaultOptions.duration);
180      Effect.DefaultOptions.duration = 0.5;
181      var e1 = new Effect.Opacity('sandbox');
182      assertEqual(0.5, e1.options.duration);
183     
184      wait(750, function() {
185        assertEqual('finished', e1.state);
186        Effect.DefaultOptions = oldDefaultOptions;
187      });
188    }},
189   
190    testEffectsQueue: function() { with(this) {
191      var e1 = new Effect.Highlight('sandbox');
192      var e2 = new Effect.Appear('sandbox');
193     
194      assertEqual(2, Effect.Queue.effects.length);
195     
196      tmp = 0;
197      Effect.Queue.each(function(e) { tmp++ });
198      assertEqual(2, tmp);
199     
200      // the internal interval timer should be active
201      assertNotNull(Effect.Queue.interval);
202      e1.cancel();
203      e2.cancel();
204      assertEqual(0, Effect.Queue.effects.length);
205     
206      // should be inactive after all effects are removed from queue
207      assertNull(Effect.Queue.interval);
208     
209      // should be in e3,e1,e2 order
210      var e1 = new Effect.Highlight('sandbox');
211      var e2 = new Effect.Appear('sandbox',{queue:'end'});
212      var e3 = new Effect.Fade('sandbox',{queue:'front'});
213      assert(e2.startOn > e1.startOn);
214      assert(e3.startOn < e1.startOn);
215      assert(e3.startOn < e2.startOn);
216      assertEqual(3, Effect.Queue.effects.length);
217     
218      Effect.Queue.each(function(e) { e.cancel() });
219      assertEqual(0, Effect.Queue.effects.length);
220    }},
221   
222    testScopedEffectsQueue: function() { with(this) {
223      var e1 = new Effect.Highlight('sandbox', {queue: {scope:'myscope'} } );
224      var e2 = new Effect.Appear('sandbox', {queue: {scope:'myscope'} } );
225      var e3 = new Effect.Highlight('sandbox', {queue: {scope:'secondscope'} } );
226      var e4 = new Effect.Appear('sandbox');
227     
228      assertEqual(2, Effect.Queues.get('myscope').effects.length);
229      assertEqual(1, Effect.Queues.get('secondscope').effects.length);
230      assertEqual(1, Effect.Queues.get('global').effects.length);
231      assertEqual(Effect.Queue.effects.length, Effect.Queues.get('global').effects.length);
232     
233      var tmp = 0;
234      Effect.Queues.get('myscope').effects.each(function(e) { tmp++ });
235      assertEqual(2, tmp);
236     
237      // the internal interval timer should be active
238      assertNotNull(Effect.Queues.get('myscope').interval);
239      assertNotNull(Effect.Queues.get('secondscope').interval);
240      assertNotNull(Effect.Queues.get('global').interval);
241   
242      e1.cancel(); e2.cancel(); e3.cancel(); e4.cancel();
243     
244      assertEqual(0, Effect.Queues.get('myscope').effects.length);
245      assertEqual(0, Effect.Queues.get('secondscope').effects.length);
246      assertEqual(0, Effect.Queues.get('global').effects.length);
247     
248      // should be inactive after all effects are removed from queues
249      assertNull(Effect.Queues.get('myscope').interval);
250      assertNull(Effect.Queues.get('secondscope').interval);
251      assertNull(Effect.Queues.get('global').interval);
252     
253      // should be in e3 and e4 together and then e1,e2 order
254      var e1 = new Effect.Highlight('sandbox', {queue: {scope:'myscope'} } );
255      var e2 = new Effect.Appear('sandbox', {queue: {position: 'end', scope:'myscope'} } );
256      var e3 = new Effect.Fade('sandbox', {queue: {position: 'front', scope:'myscope'} } );
257      var e4 = new Effect.Appear('sandbox');
258      assert(e2.startOn > e1.startOn);
259      assert(e3.startOn < e1.startOn);
260      assert(e3.startOn < e2.startOn);
261      assert(e3.startOn = e4.startOn);
262      assertEqual(3, Effect.Queues.get('myscope').effects.length);
263     
264      Effect.Queues.get('myscope').each(function(e) { e.cancel() });
265      assertEqual(0, Effect.Queues.get('myscope').effects.length);
266   
267      Effect.Queues.get('global').each(function(e) { e.cancel() });
268      assertEqual(0, Effect.Queues.get('global').effects.length);
269     
270      // should only allow the first two effects and ignore the third
271      var e1 = new Effect.Highlight('sandbox', {queue: {scope:'myscope', limit: 2} } );
272      var e2 = new Effect.Appear('sandbox', {queue: {position: 'end', scope:'myscope', limit: 2} } );
273      var e3 = new Effect.Fade('sandbox', {queue: {position: 'front', scope:'myscope', limit: 2} } );
274     
275      assertEqual(2, Effect.Queues.get('myscope').effects.length);
276    }},
277   
278    testEffectMultiple: function() { with(this) {
279      $('sandbox').appendChild(Builder.node('div',{id:'test_1'}));
280      $('sandbox').appendChild(Builder.node('div',{id:'test_2'},[Builder.node('div',{id:'test_2a'})]));
281      $('sandbox').appendChild(Builder.node('div',{id:'test_3'}));
282     
283      // only direct child elements
284      Effect.multiple('sandbox',Effect.Fade);
285      assertEqual(3, Effect.Queue.effects.length);
286     
287      Effect.Queue.each(function(e) { e.cancel() });
288      assertEqual(0, Effect.Queue.effects.length);
289     
290      // call with array
291      Effect.multiple(['test_1','test_3'],Effect.Puff);
292      assertEqual(2, Effect.Queue.effects.length);
293    }},
294   
295    testEffectTagifyText: function() { with(this) {
296      $('sandbox').innerHTML = "Blah<strong>bleb</strong> Blub";
297      assertEqual(3, $('sandbox').childNodes.length);
298      Effect.tagifyText('sandbox');
299      assertEqual(10, $('sandbox').childNodes.length);
300     
301      Effect.multiple('sandbox', Effect.Fade);
302      assertEqual(10, Effect.Queue.effects.length);
303    }},
304   
305    testEffectParallel: function() { with(this) {
306      assert( new Effect.Parallel() );
307      assert( new Effect.Parallel([]) );
308      assert( new Effect.Parallel([],{}) );
309      assert( new Effect.Parallel([
310        new Effect.Event({sync:true})
311      ],{ duration: 2}) );
312    }},
313   
314    testEffectTween: function() { with(this) {
315      // basic initialization
316      assert(new Effect.Tween(null,0,0,function(){}));
317      assert(new Effect.Tween(null,0,0,{duration:0.1},function(){}));
318
319      // fun with objects
320      var object = { 
321        blech: 2, 
322        foo: function(p){
323          this.bar = p;
324        }
325      };
326      assert(new Effect.Tween(object,0,1,{transition:Effect.Transitions.reverse},'blech'));
327      assert(new Effect.Tween(object,0,1,'foo'));
328     
329      // fun with elements
330      assert(new Effect.Tween('tween',50,1,'update'));
331     
332      wait(1500, function(){ 
333        assertEqual(0, object.blech);
334        assertEqual(1, object.bar);
335        assertEqual('1', $('tween').innerHTML);
336      });
337    }},
338
339    // test if all combined effects correctly initialize themselves
340    testCombinedEffectsInitialize: function() { with(this) {
341      COMBINED_EFFECTS.each(function(fx,idx){
342        info('Effect.'+fx);
343        $('sandbox').innerHTML = "";
344        $('sandbox').appendChild(
345          Builder.node('div',{id:'test_element'},
346            Builder.node('span','test'))); //some effects require a child element
347           
348        // should work with new Effect.Blah syntax
349        var effect = new Effect[fx]('test_element');
350        assertEqual(0, effect.currentFrame);
351       
352        // and without the 'new'
353        var effect = Effect[fx]('test_element');
354        assertEqual(0, effect.currentFrame);
355       
356        // visualEffect
357        assert($('test_element') == $('test_element').visualEffect(COMBINED_RJS_EFFECTS[idx]));
358       
359        // direct element extension
360        var method = COMBINED_EFFECTS[idx].charAt(0).toLowerCase() + COMBINED_EFFECTS[idx].substring(1)
361        assert($('test_element') == $('test_element')[method]());
362       
363        // options parsing (shake, squish and grow are special here)
364        if(!['Shake','Squish','Grow'].include(fx)) {
365          var effect = Effect[fx]('test_element',{duration:2.0});
366          assertEqual(2.0, effect.options.duration, fx);
367        }
368      });
369    }},
370   
371    testSynchronizedEffects: function() { with(this) {
372      var e1 = new Effect.Fade('sandbox',{sync:true});
373      wait(250, function() {
374        // effect should still be at frame 0
375        assertEqual(0, e1.currentFrame);
376        assertEqual('idle', e1.state);
377        e1.render(0.01);
378       
379        // no frame count for sync effects
380        assertEqual(0, e1.currentFrame);
381        assertEqual('running', e1.state);
382      });
383    }},
384   
385    testEffectPosition: function() { with(this) {
386      var testeffect = new Effect.Opacity('sandbox',{
387        afterSetup:  function(effect) { effect.frames = 0; },
388        afterUpdate: function(effect) { effect.frames++; $('sandbox').update(effect.position); },
389        duration: 0.5, from: 1.0, to: 0.5
390      });
391      assertNull(testeffect.position);
392      assertEqual('idle', testeffect.state);
393      wait(1000, function() {
394        info('Rendered ' + testeffect.frames + ' frames in .5 seconds ' +
395          '(~' + (testeffect.frames/0.5) + 'fps of a possible 60fps, ' +
396          'note that this can exceed 60fps because of additional last frame rendering)');
397        assertEqual('0.5', $('sandbox').innerHTML);
398        assertEqual(0.5, testeffect.position);
399        assertEqual('finished', testeffect.state);
400      });
401    }},
402   
403    testRenderPerformance: function() { with(this) {
404      info('The render() method is generated on a per-effect basis')
405      var e = new Effect.Opacity('sandbox',{sync:true});
406      benchmark(function(){
407        e.render(0.5);
408      },1000, 'Without events');
409      var e = new Effect.Opacity('sandbox',{sync:true,afterUpdate:function(){return}});
410      benchmark(function(){
411        e.render(0.5);
412      },1000, 'With afterUpdate event');     
413    }},
414   
415    testElementMorph: function() { with(this) {
416      $('error_test_ul').morph('font-size:40px', {duration: 0.5}).setStyle({marginRight:'17px'});
417      $('error_message_2').morph({
418        fontSize:         '20px',
419        color:            '#f00',
420        backgroundColor:  '#ffffff'
421      },
422      {
423        duration:0.5
424      });
425      $('error_message_3').morph('final', {duration:0.5});
426      wait(1000,function(){
427        assertEqual('17px', $('error_test_ul').getStyle('margin-right'));
428        assertEqual('40px', $('error_test_ul').getStyle('font-size'));
429        assertEqual('#ffffff', $('error_message_2').getStyle('background-color').parseColor());
430        assertEqual('20px', $('error_message_2').getStyle('font-size'));
431        assertEqual('italic', $('error_message_3').getStyle('font-style'));
432        assertEqual('20px', $('error_message_3').getStyle('font-size'));
433        assertEqual(.5, $('error_message_3').getStyle('opacity'));
434        assertEqual('', $('error_message_3').style.fontSize);
435      });
436    }},
437
438    testElementMorphChaining: function() { with(this) {
439      $('error_message').morph('font-size:17px').morph('opacity:0',{delay:2});
440      wait(3100,function(){ // 2000ms delay + 1000ms default duration
441        assertEqual(0, $('error_message').getStyle('opacity'));
442      });
443    }},
444
445    testTransformBySelector: function() { with(this) {
446      new Effect.Transform([
447        { 'ul.error-list li': 'font-size:20px;text-indent:40pt' }
448      ],{ duration: 0.5 }).play();
449
450      wait(700,function(){
451        var idx = 0;
452        $A($('error_test_ul').cleanWhitespace().childNodes).each(function(node){
453          assertEqual('20px', $(node).getStyle('font-size'));
454          assertEqual('40pt', $(node).getStyle('text-indent'));
455          idx++;
456        });
457        assertEqual(5, idx);
458      });
459    }},
460
461    testTransformUsesCSSClassPresets: function() { with(this) {
462      assertEqual('40px', $('rotfl').getStyle('font-size'));
463
464      // Render the effect at half-way through, font-size should be
465      // exactly half-way between original and target
466      new Effect.Transform([
467        { 'rotfl': 'font-size:20px;text-indent:40pt;background-color:#888' }
468      ],{ sync:true }).play().render(0.5);
469
470      wait(1100,function(){
471        // should be 30px = 40px + (20px-40px)/2
472        assertEqual('30px', $('rotfl').getStyle('font-size'));
473      });
474    }},
475
476    testTransformMultiple: function() { with(this) {
477      var transformation = new Effect.Transform([
478        { 'div.morphing': 'font-size:20px;padding-left:40em;opacity:0.5' },
479        { 'blah'        : 
480          'width:480px;border-width:10px;border-right-width:20px;' +
481          'margin:20px;margin-bottom:-20px;font-size:30px;' +
482          'background:#954' }
483      ],{ duration: 0.5 });
484
485      var generatedEffect = transformation.play();
486
487      assertEqual(3, generatedEffect.effects.length);
488
489      wait(700, function(){
490        // have a look at the generated color transforms for the 3rd found element
491        // which is the "blah" div
492        assertEqual('blah', generatedEffect.effects[2].element.id);
493        assertEnumEqual([255,255,255], 
494          generatedEffect.effects[2].transforms.detect( function(transform){
495            return (transform.style == 'backgroundColor')
496          }).originalValue);
497        assertEnumEqual([153,85,68], 
498          generatedEffect.effects[2].transforms.detect( function(transform){
499            return (transform.style == 'backgroundColor')
500        }).targetValue);
501
502        assertEqual('20px', $$('div.morphing').first().getStyle('font-size'));
503        assertEqual('20px', $$('div.morphing').last().getStyle('font-size'));
504        assertEqual('30px', $('blah').getStyle('font-size'));
505
506        // border-width/border-right-width should be set independently
507        assertEqual('10px', $('blah').getStyle('border-top-width'));
508        assertEqual('10px', $('blah').getStyle('border-bottom-width'));
509        assertEqual('10px', $('blah').getStyle('border-left-width'));
510        assertEqual('20px', $('blah').getStyle('border-right-width'));
511
512        // colors should assume transition from
513        // #ffffff (white) if original was transparent
514        // we now should have arrived at the given color
515        assertEqual('#995544', $('blah').getStyle('background-color').parseColor());
516
517        // play again = should have same values
518        transformation.play();
519        wait(700, function(){
520          assertEqual('20px', $$('div.morphing').first().getStyle('font-size'));
521          assertEqual('20px', $$('div.morphing').last().getStyle('font-size'));
522          assertEqual('30px', $('blah').getStyle('font-size'));
523
524          $('blah').setStyle({fontSize:'100px'});
525          assertEqual('100px', $('blah').getStyle('font-size'));       
526          transformation.play();
527          wait(700, function(){
528            assertEqual('30px', $('blah').getStyle('font-size'));
529
530            new Effect.Transform([
531              { 'blah': 'color: #80d980; background: #208020' }
532            ],{ duration: 1.1 }).play();
533            wait(1500, function(){
534              assertEqual('#80d980', $('blah').getStyle('color').parseColor());
535              assertEqual('#208020', $('blah').getStyle('background-color').parseColor());
536            });
537          });
538        });
539      });
540    }}
541
542  });
543
544// ]]>
545</script>
546</body>
547</html>
Note: See TracBrowser for help on using the browser.