OSDN Git Service

Lighten the updateList method
[sie/sie.git] / tool / Spec / spec / SvgDomSpec.js
1 /*SIE under the MIT Lisence\r
2  *公式ページは http://sie.osdn.jp/\r
3  */\r
4 /*\r
5  *Copyright (c) 2008-2010 Pivotal Labs\r
6 \r
7 Permission is hereby granted, free of charge, to any person obtaining\r
8 a copy of this software and associated documentation files (the\r
9 "Software"), to deal in the Software without restriction, including\r
10 without limitation the rights to use, copy, modify, merge, publish,\r
11 distribute, sublicense, and/or sell copies of the Software, and to\r
12 permit persons to whom the Software is furnished to do so, subject to\r
13 the following conditions:\r
14 \r
15 The above copyright notice and this permission notice shall be\r
16 included in all copies or substantial portions of the Software.\r
17 \r
18 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,\r
19 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\r
20 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\r
21 NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE\r
22 LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\r
23 OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION\r
24 WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\r
25  */\r
26 \r
27 describe("SMIL Animation Spec", function() {\r
28   describe("$frame object", function() {\r
29     var frame = base("$frame");\r
30     beforeEach( function() {\r
31         frame.timelines = [];\r
32         frame.isPaused = false;\r
33     } );\r
34     afterEach( function() {\r
35         frame.timelines = [];\r
36     } );\r
37     /*境界条件を調べておく (limit value analysis)*/\r
38     it("should be this for the value  (limit value analysis)", function() {\r
39       expect(typeof frame.setFrame).toBe("function");\r
40       expect(frame.timelines.length).toBe(0);\r
41       expect(frame.isBegin).toBeFalsy();\r
42       expect(frame.startAnimation()).toBeUndefined();\r
43       frame.setFrame();\r
44       frame.setFrame(0);\r
45       /*負の値も許される*/\r
46       frame.setFrame(-1);\r
47       \r
48       expect(frame.addLine()).toBe(false);\r
49       expect(frame.addLine({})).toBe(false);\r
50       expect(frame.addLine({\r
51         begin: 0\r
52       })).toBe(false);\r
53       expect(frame.addLine({\r
54         activeTime: 1\r
55       })).toBe(false);\r
56       \r
57       expect(frame.removeLine()).toBeUndefined();\r
58       expect(frame.removeLine({})).toBeUndefined();\r
59       \r
60       frame.setFrame(0);\r
61       expect(frame.currentFrame).toBe(0);\r
62       frame.setFrame(1);\r
63       expect(frame.currentFrame).toBe(1);\r
64       \r
65       expect(frame.isPaused).toBeFalsy();\r
66       expect(frame.pauseAnimation()).toBeUndefined();\r
67       expect(frame.isPaused).toBeTruthy();\r
68 \r
69     });\r
70     /*同値分割をして、有効同値クラスを調べておく (Equivalence partitioning, the following is the valid partion)*/\r
71     it("should be this for the value (the valid partion)", function() {\r
72       frame.setFrame(0);\r
73       expect(frame.currentFrame).toBe(0);\r
74       frame.startTime = Date.now();\r
75       for (var i=0;i<100000;i++) {\r
76         /*負荷をかけて、時間を進める*/\r
77         1;\r
78       }\r
79       expect(frame.begin).toBe(0);\r
80       expect(frame.activeTime).toBe(Number.MAX_VALUE);\r
81       frame.begin = 10;\r
82       frame.setFrame(0);\r
83       frame.begin = -10;\r
84       frame.setFrame(0);\r
85 \r
86       expect(frame.addLine( {\r
87         begin: 0,\r
88         activeTime: 0\r
89       })).toBe(true);\r
90       expect(frame.addLine( {\r
91         begin: null,\r
92         activeTime: null\r
93       })).toBe(false);\r
94       expect(frame.addLine( {\r
95         begin: 0,\r
96         activeTime: null\r
97       })).toBe(false);\r
98       expect(frame.addLine( {\r
99         begin: null,\r
100         activeTime: 0\r
101       })).toBe(false);\r
102       \r
103       expect(frame.timelines.length).toBe(1);\r
104       var timeline = frame.timelines[0];\r
105       expect(timeline.begin).toBe(0);\r
106       expect(timeline.activeTime).toBe(0);\r
107       /*timelineの再追加*/\r
108       expect(frame.timelines[0]).toBe(timeline);\r
109       frame.addLine({begin:1, activeTime:1});\r
110       expect(frame.timelines[1]).not.toBe(timeline);\r
111       frame.addLine(timeline);\r
112       expect(frame.timelines[0]).not.toBe(timeline);\r
113       expect(frame.timelines[1]).toBe(timeline);\r
114 \r
115       timeline = frame.timelines[0];\r
116       frame.removeLine({});\r
117       expect(frame.timelines[0]).toBe(timeline);\r
118       frame.removeLine(timeline);\r
119       expect(frame.timelines[0]).not.toBe(timeline);\r
120       \r
121       frame.addLine(frame.up().mix( {\r
122         timelines: [] \r
123         } ));\r
124       expect(frame.timelines).not.toBe(frame.$1.timelines);\r
125       \r
126       frame.timelines.length = 0;\r
127       frame.addLine( {\r
128         begin: 1,\r
129         activeTime: 1\r
130       } );\r
131       frame.addLine( {\r
132         begin: 1,\r
133         activeTime: 1\r
134       } );\r
135       frame.addLine( {\r
136         begin: 1,\r
137         activeTime: 2\r
138       } );\r
139       expect(frame.timelines[2].activeTime).toBe(2);\r
140     });\r
141     /*無効同値クラスを調べておく (Equivalence partitioning, the following is the invalid partion)*/\r
142     it("should be this for the value (the invalid partion)", function() {\r
143       expect(frame.addLine(12)).toBeFalsy();\r
144       /*循環参照にならず、スタック領域不足にならない*/\r
145       frame.addLine(frame);\r
146       frame.setFrame(0);\r
147     });\r
148   } );\r
149   describe("the $frame.$list object", function() {\r
150     var frame = base("$frame").$list.up("$2");\r
151     beforeEach( function() {\r
152         frame.timelines = [];\r
153         frame.isPaused = false;\r
154         frame.state = frame.WAITING;\r
155         frame.begin = 0;\r
156     } );\r
157     afterEach( function() {\r
158         frame.timelines = [];\r
159     } );\r
160     /*境界条件を調べておく (limit value analysis)*/\r
161     it("should be this for the value  (limit value analysis)", function() {\r
162             \r
163       expect(frame.WAITING).toBe(0);\r
164       expect(frame.BEGINNING).toBe(1);\r
165       expect(frame.PLAYING).toBe(2);\r
166       expect(frame.ENDING).toBe(3);\r
167       expect(frame.POSTWAITING).toBe(4);\r
168       expect(frame.state).toBe(frame.WAITING);\r
169       expect(frame.end).toBe(0);\r
170       expect(frame.beginEnd).toBe(Number.MAX_VALUE);\r
171       \r
172       expect(frame.beginList).toEqual({\r
173               next: null,\r
174               value: Number.MAX_VALUE\r
175             });\r
176       expect(frame.endList).toEqual({\r
177               next: null,\r
178               value: Number.MAX_VALUE\r
179             });\r
180             \r
181       expect(typeof frame.getMaxList).toBe("function");\r
182       \r
183       expect(typeof frame.updateState).toBe("function");\r
184       expect(frame.updateState(0).state).toBe(frame.WAITING);\r
185       expect(frame.state).toBe(frame.WAITING);\r
186       expect(frame.updateState(0).state).toBe(frame.WAITING);\r
187       expect(frame.state).toBe(frame.WAITING);\r
188       expect(frame.updateState(0).state).toBe(frame.WAITING);\r
189       expect(frame.state).toBe(frame.WAITING);\r
190       expect(frame.updateState(0).state).toBe(frame.WAITING);\r
191       expect(frame.state).toBe(frame.WAITING);\r
192       \r
193       frame.state = 100;\r
194       expect(frame.updateState(0).state).toBe(frame.BEGINNING);\r
195       expect(frame.state).toBe(frame.BEGINNING);\r
196       expect(frame.updateState().state).toBe(frame.BEGINNING);\r
197       expect(frame.state).toBe(frame.BEGINNING);\r
198       \r
199       expect(frame.beginList).toEqual({\r
200           next: null,\r
201           value: Number.MAX_VALUE\r
202         });\r
203       expect(frame.endList).toEqual({\r
204           next: null,\r
205           value: Number.MAX_VALUE\r
206         });\r
207         \r
208       expect(frame.getMaxList(0, frame.beginList)).toBe(-1);\r
209       expect(frame.getMaxList(0, frame.endList)).toBe(-1);\r
210       \r
211       frame.begin = 12;\r
212       frame.init();\r
213       expect(frame.state).toBe(frame.WAITING);\r
214       expect(frame.begin).toBe(0);\r
215       expect(frame.init()).toBe(frame);\r
216 \r
217     } );\r
218     /*同値分割をして、有効同値クラスを調べておく (Equivalence partitioning, the following is the valid partion)*/\r
219     it("should be this for the value (the valid partion)", function() {\r
220       \r
221       function appendBegin(num) {\r
222         frame.state = frame.WAITING;\r
223         frame.beginList = {\r
224           value: num,\r
225           next: frame.beginList\r
226         };\r
227       };\r
228       appendBegin(0);\r
229       expect(frame.getMaxList(0, frame.beginList)).toBe(0);\r
230       expect(frame.updateState(0).state).toBe(frame.BEGINNING);\r
231       expect(frame.begin).toBe(0);\r
232       expect(frame.updateState(0).state).toBe(frame.PLAYING);\r
233       expect(frame.state).toBe(frame.PLAYING);\r
234       expect(frame.updateState(0).state).toBe(frame.PLAYING);\r
235       expect(frame.state).toBe(frame.PLAYING);\r
236       \r
237       frame.state = frame.WAITING;\r
238       expect(frame.getMaxList(0, frame.beginList)).toBe(0);\r
239       expect(frame.updateState(0).state).toBe(frame.BEGINNING);\r
240       expect(frame.state).toBe(frame.BEGINNING);\r
241       expect(frame.updateState(1).state).toBe(frame.PLAYING);\r
242       expect(frame.state).toBe(frame.PLAYING);\r
243       expect(frame.updateState(2).state).toBe(frame.PLAYING);\r
244       expect(frame.state).toBe(frame.PLAYING);\r
245       expect(frame.updateState(3).state).toBe(frame.PLAYING);\r
246       expect(frame.state).toBe(frame.PLAYING);\r
247       expect(frame.updateState(4).state).toBe(frame.PLAYING);\r
248       expect(frame.state).toBe(frame.PLAYING);\r
249       \r
250       appendBegin(1);\r
251       expect(frame.getMaxList(1, frame.beginList)).toBe(1);\r
252       expect(frame.updateState(0).state).toBe(frame.BEGINNING);\r
253       expect(frame.updateState(0).state).toBe(frame.PLAYING);\r
254       expect(frame.updateState(0).state).toBe(frame.PLAYING);\r
255       expect(frame.updateState(1).state).toBe(frame.ENDING);\r
256       expect(frame.updateState(1).state).toBe(frame.BEGINNING);\r
257       expect(frame.state).toBe(frame.BEGINNING);\r
258       expect(frame.updateState(1).state).toBe(frame.PLAYING);\r
259       expect(frame.state).toBe(frame.PLAYING);\r
260       expect(frame.updateState(1).state).toBe(frame.PLAYING);\r
261       expect(frame.state).toBe(frame.PLAYING);\r
262       expect(frame.updateState(2).state).toBe(frame.PLAYING);\r
263       \r
264       frame.begin = 0;\r
265       frame.state = frame.WAITING;\r
266       expect(frame.updateState(0).state).toBe(frame.BEGINNING);\r
267       expect(frame.begin).toBe(0);\r
268       expect(frame.updateState(0).state).toBe(frame.PLAYING);\r
269       expect(frame.updateState(0).state).toBe(frame.PLAYING);\r
270       expect(frame.begin).toBe(0);\r
271       expect(frame.updateState(1).state).toBe(frame.ENDING);\r
272       expect(frame.end).toBe(0);\r
273       expect(frame.beginEnd).toBe(Number.MAX_VALUE);\r
274       expect(frame.updateState(1).state).toBe(frame.BEGINNING);\r
275       expect(frame.begin).toBe(1);\r
276       expect(frame.updateState(1).state).toBe(frame.PLAYING);\r
277       expect(frame.updateState(1).state).toBe(frame.PLAYING);\r
278       \r
279       function appendEnd(num) {\r
280         frame.state = frame.WAITING;\r
281         frame.begin = 0;\r
282         frame.endList = {\r
283             value: num,\r
284             next: frame.endList\r
285         };\r
286       };\r
287       appendEnd(3);\r
288       expect(frame.updateState(1).state).toBe(frame.BEGINNING);\r
289       expect(frame.state).toBe(frame.BEGINNING);\r
290       expect(frame.updateState(2).state).toBe(frame.PLAYING);\r
291       expect(frame.updateState(2).state).toBe(frame.PLAYING);\r
292       expect(frame.state).toBe(frame.PLAYING);\r
293       expect(frame.updateState(3).state).toBe(frame.ENDING);\r
294       expect(frame.state).toBe(frame.ENDING);\r
295       expect(frame.end).toBe(3);\r
296       expect(frame.beginEnd).toBe(2);\r
297       expect(frame.updateState(4).state).toBe(frame.POSTWAITING);\r
298       expect(frame.state).toBe(frame.POSTWAITING);\r
299       \r
300       appendEnd(4);\r
301       expect(frame.updateState(1).state).toBe(frame.BEGINNING);\r
302       expect(frame.state).toBe(frame.BEGINNING);\r
303       expect(frame.updateState(2).state).toBe(frame.PLAYING);\r
304       expect(frame.updateState(2).state).toBe(frame.PLAYING);\r
305       expect(frame.state).toBe(frame.PLAYING);\r
306       expect(frame.updateState(3).state).toBe(frame.ENDING);\r
307       expect(frame.state).toBe(frame.ENDING);\r
308       expect(frame.end).toBe(3);\r
309       expect(frame.beginEnd).toBe(2);\r
310       expect(frame.updateState(4).state).toBe(frame.POSTWAITING);\r
311       expect(frame.state).toBe(frame.POSTWAITING);\r
312       expect(frame.updateState(4).state).toBe(frame.POSTWAITING);\r
313       expect(frame.state).toBe(frame.POSTWAITING);\r
314       \r
315       appendEnd(1);\r
316       expect(frame.updateState(1).state).toBe(frame.BEGINNING);\r
317       expect(frame.updateState(1).state).toBe(frame.ENDING);\r
318       expect(frame.end).toBe(1);\r
319       expect(frame.beginEnd).toBe(0);\r
320       expect(frame.updateState(1).state).toBe(frame.POSTWAITING);\r
321     } );\r
322     /*無効同値クラスを調べておく (Equivalence partitioning, the following is the invalid partion)*/\r
323     it("should be this for the value (the invalid partion)", function() {\r
324       expect(frame.updateState()).toBe(frame);\r
325       expect(frame.updateState(null)).toBe(frame);\r
326     });\r
327     describe("the setFrame method (override)", function() {\r
328       var frame = base("$frame").$list.up("$3");\r
329       beforeEach( function() {\r
330           frame.timelines = [];\r
331           frame.isPaused = false;\r
332           frame.state = frame.WAITING;\r
333           frame.begin = 0;\r
334       } );\r
335       afterEach( function() {\r
336           frame.timelines = [];\r
337           frame.beginList = frame.$list.beginList;\r
338           frame.endList = frame.$list.endList;\r
339           frame.currentFrame = 0;\r
340       } );\r
341       /*境界条件を調べておく (limit value analysis)*/\r
342       it("should be this for the value  (limit value analysis)", function() {\r
343         expect(typeof frame.setFrame).toBe("function");\r
344         expect(frame.currentFrame).toBe(0);\r
345         \r
346         frame.setFrame(0);\r
347         expect(frame.state).toBe(frame.WAITING);\r
348         expect(frame.currentFrame).toBe(0);\r
349         frame.setFrame(1);\r
350         expect(frame.state).toBe(frame.WAITING);\r
351         expect(frame.currentFrame).toBe(1);\r
352         \r
353         expect(typeof frame.addEvent).toBe("function");\r
354         expect(typeof frame.addBeginList).toBe("function");\r
355         expect(typeof frame.addEndList).toBe("function");\r
356         \r
357         expect(frame.addBeginList(1).value).toBe(1);\r
358         expect(frame.beginList.next.value).toBe(Number.MAX_VALUE);\r
359         expect(frame.addEndList(1).value).toBe(1);\r
360         expect(frame.endList.next.value).toBe(Number.MAX_VALUE);\r
361         \r
362 \r
363 \r
364       } );\r
365       /*同値分割をして、有効同値クラスを調べておく (Equivalence partitioning, the following is the valid partion)*/\r
366       it("should be this for the value (the valid partion)", function() {\r
367         function appendBegin(num) {\r
368           frame.state = frame.WAITING;\r
369           frame.addBeginList(num);\r
370         };\r
371         appendBegin(0);\r
372         expect(frame.currentFrame).toBe(0);\r
373         frame.setFrame(0);\r
374         expect(frame.currentFrame).toBe(0);\r
375         expect(frame.state).toBe(frame.PLAYING);\r
376         frame.setFrame(1);\r
377         expect(frame.currentFrame).toBe(1);\r
378         expect(frame.state).toBe(frame.PLAYING);\r
379         \r
380         frame.begin = 0;\r
381         appendBegin(1);\r
382         frame.setFrame(0);\r
383         expect(frame.state).toBe(frame.PLAYING);\r
384         frame.setFrame(1);\r
385         expect(frame.state).toBe(frame.PLAYING);\r
386         frame.setFrame(2);\r
387         expect(frame.state).toBe(frame.PLAYING);\r
388         \r
389         function appendEnd(num) {\r
390           frame.state = frame.WAITING;\r
391           frame.begin = 0;\r
392           frame.addEndList(num);\r
393         };\r
394         \r
395         appendEnd(3);\r
396         frame.setFrame(0);\r
397         expect(frame.state).toBe(frame.PLAYING);\r
398         frame.setFrame(1);\r
399         expect(frame.state).toBe(frame.PLAYING);\r
400         frame.setFrame(2);\r
401         expect(frame.state).toBe(frame.PLAYING);\r
402         frame.setFrame(3);\r
403         expect(frame.state).toBe(frame.POSTWAITING);\r
404         frame.setFrame(4);\r
405         expect(frame.state).toBe(frame.POSTWAITING);\r
406         \r
407         appendBegin(5);\r
408         frame.setFrame(0);\r
409         expect(frame.state).toBe(frame.PLAYING);\r
410         frame.setFrame(1);\r
411         expect(frame.state).toBe(frame.PLAYING);\r
412         frame.setFrame(2);\r
413         expect(frame.state).toBe(frame.PLAYING);\r
414         frame.setFrame(3);\r
415         expect(frame.state).toBe(frame.POSTWAITING);\r
416         frame.setFrame(4);\r
417         expect(frame.state).toBe(frame.POSTWAITING);\r
418         frame.setFrame(5);\r
419         expect(frame.state).toBe(frame.PLAYING);\r
420         frame.setFrame(6);\r
421         expect(frame.state).toBe(frame.PLAYING);\r
422         \r
423         appendEnd(6);\r
424         frame.setFrame(0);\r
425         expect(frame.state).toBe(frame.PLAYING);\r
426         expect(frame.currentFrame).toBe(0);\r
427         frame.setFrame(1);\r
428         expect(frame.state).toBe(frame.PLAYING);\r
429         expect(frame.currentFrame).toBe(1);\r
430         frame.setFrame(2);\r
431         expect(frame.state).toBe(frame.PLAYING);\r
432         expect(frame.currentFrame).toBe(2);\r
433         frame.setFrame(3);\r
434         expect(frame.state).toBe(frame.POSTWAITING);\r
435         frame.setFrame(4);\r
436         expect(frame.state).toBe(frame.POSTWAITING);\r
437         frame.setFrame(5);\r
438         expect(frame.state).toBe(frame.PLAYING);\r
439         frame.setFrame(6);\r
440         expect(frame.state).toBe(frame.POSTWAITING);\r
441         expect(frame.currentFrame).toBe(6);\r
442         \r
443         /*負荷テスト*/\r
444         for (var i=0;i<10000;++i) {\r
445           frame.setFrame(i);\r
446         }\r
447         \r
448         frame.beginList = base("$frame").$listbeginList;\r
449         frame.endList = base("$frame").$list.endList;\r
450         frame.state = frame.WAITING;\r
451         frame.begin = 0;\r
452         var obj = { name: "", value: 0};\r
453         frame.addEvent("begin", function(evt) { obj.name = "a";});\r
454         frame.beginList = {\r
455             value: 0,\r
456             next: frame.beginList\r
457         };\r
458         frame.setFrame(0);\r
459         expect(frame.currentFrame).toBe(0);\r
460         expect(frame.state).toBe(frame.PLAYING);\r
461         expect(obj.name).toBe("a");\r
462         frame.addEvent("play", function(evt) { obj.name = "b";});\r
463         frame.setFrame(1);\r
464         expect(frame.state).toBe(frame.PLAYING);\r
465         expect(obj.name).toBe("b");\r
466         frame.addEvent("end", function(evt) { obj.value = 1;});\r
467         frame.endList = {\r
468             value: 0,\r
469             next: frame.endList\r
470         };\r
471         frame.setFrame(0);\r
472         expect(frame.currentFrame).toBe(0);\r
473         expect(frame.state).toBe(frame.POSTWAITING);\r
474         expect(obj.value).toBe(1);\r
475         var t = 0;\r
476         frame.addEvent("begin", function(evt) {\r
477           expect(evt.state).toBe(frame.BEGINNING);\r
478           t = 1;\r
479         });\r
480         frame.addEvent("end", function(evt) {\r
481           expect(evt.state).toBe(frame.ENDING);\r
482           t = 2;\r
483         });\r
484         frame.addEvent("play", function(evt) {\r
485           expect(evt.state).toBe(frame.PLAYING);\r
486           t = 3;\r
487         });\r
488         frame.state = frame.WAITING;\r
489         frame.setFrame(0);\r
490         expect(frame.state).toBe(frame.POSTWAITING);\r
491         expect(t).toBe(2);\r
492         \r
493         t=0;\r
494         frame.begin = 0;\r
495         frame.state = frame.WAITING;\r
496         expect(frame.getMaxList(12, frame.endList)).toBe(0);\r
497         frame.setFrame(12);\r
498         expect(frame.state).toBe(frame.POSTWAITING);\r
499         expect(t).toBe(2);\r
500         \r
501         /*addBeginListメソッドのチェックなど*/\r
502         expect(frame.addBeginList(1).value).toBe(1);\r
503         expect(frame.addBeginList(0).value).toBe(0);\r
504         expect(frame.beginList.next.value).toBe(1);\r
505         expect(frame.addBeginList(2).value).toBe(2);\r
506         expect(frame.beginList.next.value).toBe(0);\r
507         \r
508         expect(frame.addEndList(1).value).toBe(1);\r
509         expect(frame.addEndList(0).value).toBe(0);\r
510         expect(frame.endList.next.value).toBe(1);\r
511         expect(frame.addEndList(2).value).toBe(2);\r
512         expect(frame.endList.next.value).toBe(0);\r
513       } );\r
514     } );\r
515   } );\r
516   describe("$begin object", function() {\r
517     var begin = base("$frame").$begin.up();\r
518     /*境界条件を調べておく (limit value analysis)*/\r
519     it("should be this for the value  (limit value analysis)", function() {\r
520       expect(begin.string).toBe("");\r
521       expect(begin.isResolved).toBeFalsy();\r
522       expect(begin.eventTarget).toBe(document.documentElement);\r
523       expect(begin.eventOffset).toBe(0);\r
524       expect(begin.repeat).toBe(0);\r
525       expect(begin.accessKey).toBe("");\r
526     } );\r
527     /*同値分割をして、有効同値クラスを調べておく (Equivalence partitioning, the following is the valid partion)*/\r
528     it("should be this for the value (the valid partion)", function() {\r
529       begin.string = " hoge ";\r
530       expect(begin.string).toBe(" hoge ");\r
531       var $list = begin.$list;\r
532       expect(begin.$list).toBe($list);\r
533       expect(begin.updateList().$list).not.toBe($list);\r
534     } );\r
535     /*無効同値クラスを調べておく (Equivalence partitioning, the following is the invalid partion)*/\r
536     it("should be this for the value (the invalid partion)", function() {\r
537     } );\r
538     \r
539     describe("A trim method in $begin object", function() {\r
540       /*境界条件を調べておく (limit value analysis)*/\r
541       beforeEach( function() {\r
542         begin.string = "";\r
543       } );\r
544       it("should be this for the value  (limit value analysis)", function() {\r
545         delete begin.string;\r
546         expect(begin.trim(" ")).toBe("");\r
547         expect( function() {\r
548           begin.trim();\r
549         } ).toThrow();\r
550       } );\r
551       /*同値分割をして、有効同値クラスを調べておく (Equivalence partitioning, the following is the valid partion)*/\r
552       it("should be this for the value (the valid partion)", function() {\r
553         expect(begin.trim(" hoge ")).toBe("hoge");\r
554         expect(begin.trim(" h o g e ")).toBe("hoge");\r
555         expect(begin.trim(" h  o  g     e ")).toBe("hoge");\r
556         expect(begin.trim("   h  o  g    12 +  e   ")).toBe("hog12+e");\r
557       } );\r
558       /*無効同値クラスを調べておく (Equivalence partitioning, the following is the invalid partion)*/\r
559       it("should be this for the value (the invalid partion)", function() {\r
560         expect( function() {\r
561           begin.trim(1);\r
562         } ).toThrow();\r
563         expect( function() {\r
564           begin.trim({});\r
565         } ).toThrow();\r
566       } );\r
567     } );\r
568 \r
569     describe("An offset method in $begin object", function() {\r
570       beforeEach( function() {\r
571         begin.string = "";\r
572       } );\r
573       /*境界条件を調べておく (limit value analysis)*/\r
574       it("should be this for the value  (limit value analysis)", function() {\r
575         expect(begin.offset(begin.trim(" "))).toBe(0);\r
576         expect(begin.offset(begin.trim(" 0 "))).toBe(0);\r
577         expect(begin.offset(begin.trim("+0ms"))).toBe(0);\r
578         expect(begin.offset(begin.trim("-0ms"))).toBe(0);\r
579         expect(begin.offset(begin.trim("1ms"))).toBe(1);\r
580         expect(begin.offset(begin.trim("-1ms"))).toBe(-1);\r
581 \r
582         expect(begin.offset("+0s")).toBe(0);\r
583         expect(begin.offset("-0s")).toBe(0);\r
584         expect(begin.offset("1s")).toBe(1000);\r
585         expect(begin.offset("-1s")).toBe(-1000);\r
586 \r
587         expect(begin.offset("+0min")).toBe(0);\r
588         expect(begin.offset("-0min")).toBe(0);\r
589         expect(begin.offset("1min")).toBe(60000);\r
590         expect(begin.offset("-1min")).toBe(-60000);\r
591 \r
592         expect(begin.offset("+0h")).toBe(0);\r
593         expect(begin.offset("-0h")).toBe(0);\r
594         expect(begin.offset("1h")).toBe(60*60*1000);\r
595         expect(begin.offset("-1h")).toBe(-3600000);\r
596 \r
597         expect(begin.offset("00:0")).toBe(0);\r
598         expect(begin.offset("00:00:0.0")).toBe(0);\r
599         expect(begin.offset("-00:0")).toBe(0);\r
600         expect(begin.offset("-00:00:0.0")).toBe(0);\r
601         expect(begin.offset("00:1")).toBe(1000);\r
602         expect(begin.offset("-00:1")).toBe(-1000);\r
603         expect(begin.offset("00:00:1")).toBe(1000);\r
604         expect(begin.offset("-00:00:1")).toBe(-1000);\r
605 \r
606         expect(begin.offset()).toBe(0);\r
607       } );\r
608       /*同値分割をして、有効同値クラスを調べておく (Equivalence partitioning, the following is the valid partion)*/\r
609       it("should be this for the value (the valid partion)", function() {\r
610         expect(begin.offset(begin.trim(" + 0 ms"))).toBe(0);\r
611         expect(begin.offset(begin.trim(" -1m s "))).toBe(-1);\r
612         expect(begin.offset(begin.trim("1000ms"))).toBe(1000);\r
613         expect(begin.offset(begin.trim(" -1212ms"))).toBe(-1212);\r
614 \r
615         expect(begin.offset("+100s")).toBe(100 * 1000);\r
616         expect(begin.offset("-121s")).toBe(-121 * 1000);\r
617         expect(begin.offset("1.25s")).toBe(1.25 * 1000);\r
618         expect(begin.offset("-0.20s")).toBe(-0.20 * 1000);\r
619         expect(begin.offset(".20s")).toBe(0.20 * 1000);\r
620 \r
621         expect(begin.offset("+100min")).toBe(100 * 60000);\r
622         expect(begin.offset("-121min")).toBe(-121 * 60000);\r
623         expect(begin.offset("1.25min")).toBe(1.25 * 60000);\r
624         expect(begin.offset("-0.20min")).toBe(-0.20 * 60000);\r
625         expect(begin.offset(".20min")).toBe(0.20 * 60000);\r
626 \r
627         expect(begin.offset("+100h")).toBe(100 * 3600000);\r
628         expect(begin.offset("-121h")).toBe(-121 * 3600000);\r
629         expect(begin.offset("1.25h")).toBe(1.25 * 3600000);\r
630         expect(begin.offset("-0.20h")).toBe(-0.20 * 3600000);\r
631         expect(begin.offset(".20h")).toBe(0.20 * 3600000);\r
632 \r
633         expect(begin.offset("01:0")).toBe(60000);\r
634         expect(begin.offset("-01:0")).toBe(-60000);\r
635         expect(begin.offset("00:00:1")).toBe(1000);\r
636         expect(begin.offset("-00:00:1")).toBe(-1000);\r
637         expect(begin.offset("00:01:0")).toBe(60000);\r
638         expect(begin.offset("-00:01:0")).toBe(-60000);\r
639         expect(begin.offset("01:00:0")).toBe(3600000);\r
640         expect(begin.offset("-01:00:0")).toBe(-3600000);\r
641         expect(begin.offset("00:10")).toBe(10000);\r
642         expect(begin.offset("00:0.01")).toBe(10);\r
643         expect(begin.offset("01:0.01")).toBe(60010);\r
644         expect(begin.offset("10:0")).toBe(600000);\r
645         expect(begin.offset("-00:10")).toBe(-10000);\r
646         expect(begin.offset("-00:0.01")).toBe(-10);\r
647         expect(begin.offset("-01:0.01")).toBe(-60010);\r
648         expect(begin.offset("-10:0")).toBe(-600000);\r
649         expect(begin.offset("00:00:20")).toBe(20000);\r
650         expect(begin.offset("00:11:20")).toBe(11*60*1000 + 20000);\r
651         expect(begin.offset("12:11:20")).toBe(12*60*60*1000 + 11*60*1000 + 20000);\r
652         expect(begin.offset("-10:0")).toBe(-600000);\r
653         expect(begin.offset("-01:01:0.1")).toBe(-1*60*60*1000 - 60000 - 100);\r
654       } );\r
655       /*無効同値クラスを調べておく (Equivalence partitioning, the following is the invalid partion)*/\r
656       it("should be this for the value (the invalid partion)", function() {\r
657         expect(begin.offset(begin.trim(" h  o  g     1e "))).toBe(0);\r
658         expect(begin.offset("ms")).toBe(0);\r
659         expect(begin.offset(".s")).toBe(0);\r
660         expect(begin.offset("10:")).toBe(0);\r
661         expect(begin.offset("::")).toBe(0);\r
662         expect(begin.offset("-:0")).toBe(0);\r
663         expect(begin.offset("-::0")).toBe(0);\r
664       } );\r
665     } );\r
666     describe("An event method in $begin object", function() {\r
667       /*境界条件を調べておく (limit value analysis)*/\r
668       it("should be this for the value  (limit value analysis)", function() {\r
669         var evt = begin.event();\r
670         expect(evt.id).toBe("");\r
671         expect(evt.event).toBe("");\r
672         evt = begin.event("");\r
673         expect(evt.id).toBe("");\r
674         expect(evt.event).toBe("");\r
675         evt = begin.event(".");\r
676         expect(evt.id).toBe("");\r
677         expect(evt.event).toBe("");\r
678 \r
679         evt = begin.event("a");\r
680         expect(evt.id).toBe("");\r
681         expect(evt.event).toBe("a");\r
682         evt = begin.event("a.b");\r
683         expect(evt.id).toBe("a");\r
684         expect(evt.event).toBe("b");\r
685       } );\r
686       /*同値分割をして、有効同値クラスを調べておく (Equivalence partitioning, the following is the valid partion)*/\r
687       it("should be this for the value (the valid partion)", function() {\r
688         var evt = begin.event("id.event");\r
689         expect(evt.id).toBe("id");\r
690         expect(evt.event).toBe("event");\r
691         evt = begin.event("event");\r
692         expect(evt.id).toBe("");\r
693         expect(evt.event).toBe("event");\r
694         \r
695         evt = begin.event("event+0s");\r
696         expect(evt.id).toBe("");\r
697         expect(evt.event).toBe("event");\r
698         evt = begin.event("event-0s");\r
699         expect(evt.id).toBe("");\r
700         expect(evt.event).toBe("event");\r
701       } );\r
702       /*無効同値クラスを調べておく (Equivalence partitioning, the following is the invalid partion)*/\r
703       it("should be this for the value (the invalid partion)", function() {\r
704         evt = begin.event("...");\r
705         expect(evt.id).toBe("");\r
706         expect(evt.event).toBe("");\r
707         evt = begin.event(".event");\r
708         expect(evt.id).toBe("");\r
709         expect(evt.event).toBe("");\r
710         evt = begin.event("id.");\r
711         expect(evt.id).toBe("");\r
712         expect(evt.event).toBe("");\r
713       } );\r
714     } );\r
715     \r
716     describe("An parse method in $begin object", function() {\r
717        beforeEach( function() {\r
718         begin.string = "";\r
719       } );\r
720       /*境界条件を調べておく (limit value analysis)*/\r
721       it("should be this for the value  (limit value analysis)", function() {\r
722         expect(begin.parse().begin).toBe(0);\r
723         expect(begin.isResolved).toBeTruthy();\r
724         begin.string="+0";\r
725         expect(begin.parse().begin).toBe(0);\r
726         begin.string = "+1";\r
727         expect(begin.parse().begin).toBe(1000*begin.fpms);\r
728         begin.string = " ";\r
729         expect(begin.parse().begin).toBe(0);\r
730         begin.string = "1";\r
731         expect(begin.parse().begin).toBe(1000*begin.fpms);\r
732         begin.string = "+0ms";\r
733         expect(begin.parse().begin).toBe(0);\r
734         begin.string = "-0ms";\r
735         expect(begin.parse().begin).toBe(0);\r
736         begin.string = "-0ms;-0ms";\r
737         expect(begin.parse().begin).toBe(0);\r
738         begin.string = "-0ms;1";\r
739         expect(begin.parse().begin).toBe(1000*begin.fpms);\r
740         \r
741         expect(begin.eventOffset).toBe(0);\r
742         begin.string = "click";\r
743         expect(begin.parse().begin).toBe(0);\r
744         expect(begin.eventOffset).toBe(0);\r
745         expect(begin.repeat).toBe(0);\r
746         expect(begin.accessKey).toBe("");\r
747         begin.string = "id.click";\r
748         expect(begin.parse().begin).toBe(0);\r
749         expect(begin.eventOffset).toBe(0);\r
750         expect(begin.repeat).toBe(0);\r
751         expect(begin.accessKey).toBe("");\r
752         \r
753         begin.string = "repeat";\r
754         expect(begin.parse().begin).toBe(0);\r
755         expect(begin.eventOffset).toBe(0);\r
756         expect(begin.repeat).toBe(0);\r
757         expect(begin.accessKey).toBe("");\r
758         begin.string = "repeat(1)";\r
759         expect(begin.parse().begin).toBe(0);\r
760         expect(begin.eventOffset).toBe(0);\r
761         expect(begin.repeat).toBe(1);\r
762         expect(begin.accessKey).toBe("");\r
763         \r
764         begin.string = "accessKey(a)";\r
765         expect(begin.parse().begin).toBe(0);\r
766         expect(begin.eventOffset).toBe(0);\r
767         expect(begin.repeat).toBe(0);\r
768         expect(begin.accessKey).toBe("a");\r
769       } );\r
770       /*同値分割をして、有効同値クラスを調べておく (Equivalence partitioning, the following is the valid partion)*/\r
771       it("should be this for the value (the valid partion)", function() {\r
772         begin.string = " 1 0 0 m s";\r
773         expect(begin.parse().begin).toBe(Math.floor(100*begin.fpms));\r
774 \r
775         begin.string = "1ms";\r
776         begin.isResolved = false;\r
777         expect(begin.parse().begin).toBe(Math.floor(1*begin.fpms));\r
778         expect(begin.isResolved).toBeTruthy();\r
779         expect(begin.eventOffset).toBe(0);\r
780 \r
781         begin.string="click+0";\r
782         expect(begin.parse().begin).toBe(0);\r
783         expect(begin.eventOffset).toBe(0);\r
784         expect(begin.isResolved).toBeFalsy();\r
785         begin.string = "click+1";\r
786         expect(begin.parse().begin).toBe(1000*begin.fpms);\r
787         expect(begin.eventOffset).toBe(1000*begin.fpms);\r
788         begin.string = " click ";\r
789         expect(begin.parse().begin).toBe(0);\r
790         expect(begin.eventOffset).toBe(0);\r
791         begin.string = "click+0ms";\r
792         expect(begin.parse().begin).toBe(0);\r
793         expect(begin.eventOffset).toBe(0);\r
794         expect(begin.isResolved).toBeFalsy();\r
795         begin.string = "click-0ms";\r
796         expect(begin.parse().begin).toBe(0);\r
797         expect(begin.eventOffset).toBe(0);\r
798         begin.string = "click+100ms";\r
799         expect(begin.parse().begin).toBe(Math.floor(100*begin.fpms));\r
800         expect(begin.eventOffset).toBe(Math.floor(100*begin.fpms));\r
801         begin.string = "click-100ms";\r
802         expect(begin.parse().begin).toBe(Math.floor(-100*begin.fpms));\r
803         expect(begin.eventOffset).toBe(Math.floor(-100*begin.fpms));\r
804 \r
805         begin.string="id.click+0";\r
806         expect(begin.parse().begin).toBe(0);\r
807         expect(begin.eventOffset).toBe(0);\r
808         expect(begin.isResolved).toBeFalsy();\r
809         begin.string = "id.click+1";\r
810         expect(begin.parse().begin).toBe(1000*begin.fpms);\r
811         expect(begin.eventOffset).toBe(1000*begin.fpms);\r
812         expect(begin.isResolved).toBeFalsy();\r
813         begin.string = " id . click ";\r
814         expect(begin.parse().begin).toBe(0);\r
815         expect(begin.eventOffset).toBe(0);\r
816         expect(begin.isResolved).toBeFalsy();\r
817         begin.string = "id.click+0ms";\r
818         expect(begin.parse().begin).toBe(0);\r
819         expect(begin.eventOffset).toBe(0);\r
820         begin.string = "id.click-0ms";\r
821         expect(begin.parse().begin).toBe(0);\r
822         expect(begin.eventOffset).toBe(0);\r
823         begin.string = "id.click+100ms";\r
824         expect(begin.parse().begin).toBe(Math.floor(100*begin.fpms));\r
825         expect(begin.eventOffset).toBe(Math.floor(100*begin.fpms));\r
826         begin.string = "id.click-100ms";\r
827         expect(begin.parse().begin).toBe(Math.floor(-100*begin.fpms));\r
828         expect(begin.eventOffset).toBe(Math.floor(-100*begin.fpms));\r
829       } );\r
830       /*無効同値クラスを調べておく (Equivalence partitioning, the following is the invalid partion)*/\r
831       it("should be this for the value (the invalid partion)", function() {\r
832         begin.string = "ms";\r
833         begin.isResolved = false;\r
834         expect(begin.parse().begin).toBe(0);\r
835         expect(begin.isResolved).toBeFalsy();\r
836         \r
837         begin.isResolved = true;\r
838         begin.string = "indefinite";\r
839         expect(begin.parse().begin).toBe(Math.floor( Number.MAX_VALUE * begin.fpms));\r
840         expect(begin.isResolved).toBeFalsy();\r
841       } );\r
842     } );\r
843   } );\r
844   describe("A $end object", function() {\r
845     var end = base("$frame").$begin.$end.up();\r
846     end.startTime = 0;\r
847     beforeEach( function() {\r
848       end.string = "";\r
849       end.startTime = Date.now();\r
850       end.setFrame(0);\r
851     } );\r
852     /*境界条件を調べておく (limit value analysis)*/\r
853     it("should be this for the value  (limit value analysis)", function() {\r
854       expect(end.up().call()).toBeNull();\r
855       end.string = "0";\r
856       expect(end.up().call()).toBe(0);\r
857       end.string = "hoge";\r
858       expect(end.up().call()).toBe("indefinite");\r
859       \r
860     } );\r
861     /*同値分割をして、有効同値クラスを調べておく (Equivalence partitioning, the following is the valid partion)*/\r
862     it("should be this for the value (the valid partion)", function() {\r
863       end.string = "hoge+0";\r
864       expect(end.up().call()).toBe("indefinite");\r
865       end.string = "12ms";\r
866       expect(end.up().call()).toBe(Math.floor(12*end.fpms));\r
867       end.string = "hoge+12ms";\r
868       expect(end.up().call()).toBe("indefinite");\r
869 \r
870     } );\r
871     /*無効同値クラスを調べておく (Equivalence partitioning, the following is the invalid partion)*/\r
872     it("should be this for the value (the invalid partion)", function() {\r
873       end.string = null;\r
874       expect(end.up().call()).toBeNull();\r
875     } );\r
876   } );\r
877   describe("A $activate object", function() {\r
878     var act = base("$frame").$begin.$activate.up();\r
879      beforeEach( function() {\r
880       act.dur = "indefinite";\r
881       act.begin = 0;\r
882       act.repeatCount = null;\r
883       act.repeatDur = null;\r
884       act.end = act.$begin.$end;\r
885       act.simpleDur = base("$frame").$begin.$activate.simpleDur;\r
886     } );\r
887     /*境界条件を調べておく (limit value analysis)*/\r
888     it("should be this for the value  (limit value analysis)", function() {\r
889       expect(act.dur).toBe("indefinite");\r
890       expect(typeof act.resolvedTime).toBe("function");\r
891       expect(act.end).toBe(act.$begin.$end);\r
892       expect(act.repeatCount).toBeNull();\r
893       expect(act.repeatDur).toBeNull();\r
894       expect(act.simpleDur()).toBeNull();\r
895       expect(act.min).toBe("0");\r
896       expect(act.max).toBe("indefinite");\r
897 \r
898       act.up("$a");\r
899       expect(act.$a.call()).toBeNull();\r
900       expect(act.$a.end).toBeNull();\r
901     } );\r
902     /*同値分割をして、有効同値クラスを調べておく (Equivalence partitioning, the following is the valid partion)*/\r
903     it("should be this for the value (the valid partion)", function() {\r
904       expect(act.resolvedTime()).not.toBe(0);\r
905 \r
906       /*Activate Duration = dur*/\r
907       act.up("$b");\r
908       act.$b.dur = "132ms";\r
909       var abc = act.$b.call();\r
910       expect(abc).toBe(Math.floor(132*act.fpms));\r
911       expect(abc).toBe(act.$b.simpleDur);\r
912       act.dur = null;\r
913       expect(act.up().call()).toBeNull();\r
914 \r
915       act.up("$c");\r
916       act.$c.mix( {\r
917         dur: "10",\r
918         simpleDur: act.simpleDur,
919         repeatCount: null,\r
920         repeatDur: null\r
921       } );\r
922       expect(act.$c.call()).toBe(Math.floor(10000*act.fpms));\r
923       expect(act.$c.call()).toBe(act.$c.simpleDur);\r
924       act.$c.mix( {\r
925         dur: "15",\r
926         simpleDur: act.simpleDur,
927         repeatCount: null,\r
928         repeatDur: null\r
929       } );\r
930       expect(act.$c.call()).toBe(Math.floor(15000*act.fpms));\r
931 \r
932       /*AD = repeatCount*dur*/\r
933       act.$c.mix( {\r
934         dur: "10",\r
935         simpleDur: act.simpleDur,
936         repeatCount: 2,\r
937         repeatDur: null\r
938       } );\r
939       act.$c.call();\r
940       expect(act.$c.simpleDur).toBe(Math.floor(10000*act.fpms));\r
941       act.$c.mix( {\r
942         dur: "10",\r
943         simpleDur: act.simpleDur,
944         repeatCount: 1,\r
945         repeatDur: null\r
946       } );\r
947       expect(act.$c.call()).toBe(Math.floor(10000*act.fpms));\r
948       expect(act.$c.simpleDur).toBe(Math.floor(10000*act.fpms));\r
949 \r
950       /*AD = repeatDur*/\r
951       act.$c.mix( {\r
952         dur: "indefinite",\r
953         simpleDur: act.simpleDur,
954         repeatCount: 2,\r
955         repeatDur: "15"\r
956       } );\r
957       act.$c.call();\r
958       expect(act.$c.simpleDur).toBeNull();\r
959       act.$c.mix( {\r
960         dur: "indefinite",\r
961         simpleDur: act.simpleDur,
962         repeatCount: 2,\r
963         repeatDur: "10"\r
964       } );\r
965       expect(act.$c.call()).toBe(Math.floor(10000*act.fpms));\r
966       expect(act.$c.simpleDur).toBeNull();\r
967       act.$c.mix( {\r
968         dur: "10",\r
969         simpleDur: act.simpleDur,
970         repeatCount: null,\r
971         repeatDur: "15"\r
972       } );\r
973       act.$c.call();\r
974       expect(act.$c.simpleDur).toBe(Math.floor(10000*act.fpms));\r
975       act.$c.mix( {\r
976         dur: "10",\r
977         simpleDur: act.simpleDur,
978         repeatCount: null,\r
979         repeatDur: "11"\r
980       } );\r
981       expect(act.$c.call()).toBe(Math.floor(11000*act.fpms));\r
982       expect(act.$c.simpleDur).toBe(Math.floor(10000*act.fpms));\r
983       \r
984       /*AD = Min(repeatCount*d, repeatDur)*/\r
985       act.$c.mix( {\r
986         dur: "10",\r
987         simpleDur: act.simpleDur,
988         repeatCount: 2,\r
989         repeatDur: "15"\r
990       } );\r
991       act.$c.call();\r
992       expect(act.$c.simpleDur).toBe(Math.floor(10000*act.fpms));\r
993       act.$c.mix( {\r
994         dur: "10",\r
995         simpleDur: act.simpleDur,
996         repeatCount: 1,\r
997         repeatDur: "15"\r
998       } );\r
999       expect(act.$c.call()).toBe(Math.floor(10000*act.fpms));\r
1000       expect(act.$c.simpleDur).toBe(Math.floor(10000*act.fpms));\r
1001       act.$c.mix( {\r
1002         dur: "11",\r
1003         simpleDur: act.simpleDur,
1004         repeatCount: 1,\r
1005         repeatDur: "9"\r
1006       } );\r
1007       expect(act.$c.call()).toBe(Math.floor(9000*act.fpms));\r
1008       expect(act.$c.simpleDur).toBe(Math.floor(11000*act.fpms));\r
1009 \r
1010       /*AD = repeatDur,*/\r
1011       act.$c.mix( {\r
1012         end: null,\r
1013         dur: "10",\r
1014         simpleDur: act.simpleDur,
1015         repeatCount: null,\r
1016         repeatDur: "15"\r
1017       } );\r
1018       expect(act.$c.call()).toBe(Math.floor(15000*act.fpms));\r
1019       expect(act.$c.simpleDur).toBe(Math.floor(10000*act.fpms));\r
1020       act.$c.mix( {\r
1021         dur: "indefinite",\r
1022         simpleDur: act.simpleDur,
1023         repeatCount: 2,\r
1024         repeatDur: "10"\r
1025       } );\r
1026       expect(act.$c.call()).toBe(Math.floor(10000*act.fpms));\r
1027       expect(act.$c.simpleDur).toBeNull();\r
1028 \r
1029       act.end.string = null;\r
1030       act.up("$cd").mix( {\r
1031         dur: "10",\r
1032         end: act.end,\r
1033         repeatCount: 2\r
1034       } );\r
1035       expect(act.$cd.call()).toBe(Math.floor(10000*act.fpms) * 2);\r
1036       \r
1037       act.$cd.end = act.end;\r
1038       act.$cd.repeatCount = null;\r
1039       act.$cd.repeatDur = "12";\r
1040       expect(act.$cd.call()).toBe(Math.floor(12000*act.fpms));\r
1041       \r
1042       act.up("$d").mix( {\r
1043         min: "2",\r
1044         max: "3",\r
1045         dur: "1",\r
1046         simpleDur: act.simpleDur\r
1047       } );\r
1048       expect(act.$d.call()).toBe(Math.floor(2000*act.fpms));\r
1049       act.up("$d").mix( {\r
1050         min: "1",\r
1051         max: "2",\r
1052         dur: "12",\r
1053         simpleDur: act.simpleDur\r
1054       } );\r
1055       expect(act.$d.call()).toBe(Math.floor(2000*act.fpms));\r
1056       \r
1057       /*endで0が指定されている場合*/\r
1058       act.begin = 0;\r
1059       act.end = 0;\r
1060       act.repeatDur = null;\r
1061       act.repeatCount = "indefinite";\r
1062       act.dur = "1";\r
1063       expect(act.call()).toBeNull();\r
1064       act.repeatCount = null;\r
1065       act.repeatDur = "indefinite";\r
1066       act.dur = "1";\r
1067       expect(act.call()).toBeNull();\r
1068       act.repeatDur = "indefinite";\r
1069       act.repeatCount = "indefinite";\r
1070       act.dur = "1";\r
1071       expect(act.call()).toBeNull();\r
1072     } );\r
1073     /*無効同値クラスを調べておく (Equivalence partitioning, the following is the invalid partion)*/\r
1074     it("should be this for the value (the invalid partion)", function() {\r
1075       /*min > max*/\r
1076       act.up("$d").mix( {\r
1077         min: "3",\r
1078         max: "2",\r
1079         dur: "1",\r
1080         simpleDur: act.simpleDur\r
1081       } );\r
1082       expect(act.$d.call()).toBe(Math.floor(1000*act.fpms));\r
1083       \r
1084       act.repeatDur = null;\r
1085       act.repeatCount = "indefinite";\r
1086       act.dur = "1";\r
1087       expect(act.call()).toBeNull();\r
1088       act.repeatCount = null;\r
1089       act.repeatDur = "indefinite";\r
1090       act.dur = "1";\r
1091       expect(act.call()).toBeNull();\r
1092       act.repeatDur = "indefinite";\r
1093       act.repeatCount = "indefinite";\r
1094       act.dur = "1";\r
1095       expect(act.call()).toBeNull();\r
1096     } );\r
1097   } );\r
1098   describe("A $from object", function() {\r
1099     var from = base("$from");\r
1100      beforeEach( function() {\r
1101        from = base("$from").up();\r
1102        from.from = from.from.up();\r
1103        from.string = "";\r
1104      } );\r
1105     /*境界条件を調べておく (limit value analysis)*/\r
1106     it("should be this for the value  (limit value analysis)", function() {\r
1107       expect(from.string).toBe("");\r
1108       expect(from.numList()).toEqual([]);\r
1109       expect(from.strList()).toBeNull();\r
1110 \r
1111       from.string = "0";\r
1112       expect(from.numList()[0]).toBe(0);\r
1113       expect(from.strList()).toBeNull();\r
1114       \r
1115       from.string = " 0 ";\r
1116       expect(from.numList()[0]).toBe(0);\r
1117       expect(from.strList().join("")).toBe("  ");\r
1118 \r
1119       from.string = "a";\r
1120       expect(from.numList()).toEqual([]);\r
1121       expect(from.strList()[0]).toBe("a");\r
1122       \r
1123       /*前後の空白を除去する処理をしない。なぜなら、文字列リストの空白は保持するのが望ましいから\r
1124        * 文字列リストの空白を除去した例: "M 20 20 M M" -> "M20 20 MM"となってしまう*/\r
1125       \r
1126       from.string = null;\r
1127       expect( function() {\r
1128         from.numList();\r
1129       } ).toThrow();\r
1130       expect( function() {\r
1131         from.strList();\r
1132       } ).toThrow();\r
1133       \r
1134       expect(from.additive[0]).toBe(0);\r
1135       expect(from.accumulate[0]).toBe(0);\r
1136     } );\r
1137     /*同値分割をして、有効同値クラスを調べておく (Equivalence partitioning, the following is the valid partion)*/\r
1138     it("should be this for the value (the valid partion)", function() {\r
1139       from.string = "0a";\r
1140       expect(from.numList()[0]).toBe(0);\r
1141       expect(from.strList()[0]).toBe("a");\r
1142 \r
1143       from.string = "a0";\r
1144       expect(from.numList()[0]).toBe(0);\r
1145       expect(from.strList()[0]).toBe("a");\r
1146 \r
1147       from.string = "0.1";\r
1148       expect(from.numList()[0]).toBe(0.1);\r
1149       expect(from.strList()).toBeNull();\r
1150 \r
1151       from.string = "+0.1";\r
1152       expect(from.numList()[0]).toBe(0.1);\r
1153       expect(from.strList()).toBeNull();\r
1154 \r
1155       from.string = "-0.1";\r
1156       expect(from.numList()[0]).toBe(-0.1);\r
1157       expect(from.strList()).toBeNull();\r
1158 \r
1159       from.string = "1e-1";\r
1160       expect(from.numList()[0]).toBe(1e-1);\r
1161       expect(from.strList()).toBeNull();\r
1162 \r
1163       from.string = "1E-1";\r
1164       expect(from.numList()[0]).toBe(1E-1);\r
1165       expect(from.strList()).toBeNull();\r
1166 \r
1167       from.string = "0,0";\r
1168       expect(from.numList().toString()).toBe("0,0");\r
1169       expect(from.strList().join("")).toBe(",");\r
1170 \r
1171       from.string = "a00a";\r
1172       expect(from.numList()[0]).toBe(0);\r
1173       expect(from.strList().join("")).toBe("aa");\r
1174 \r
1175       from.string = "a0b0a";\r
1176       expect(from.numList().toString()).toBe("0,0");\r
1177       expect(from.strList().join("")).toBe("aba");\r
1178 \r
1179       from.string = "0b0a";\r
1180       expect(from.numList().toString()).toBe("0,0");\r
1181       expect(from.strList().join("")).toBe("ba");\r
1182 \r
1183       from.string = "0b-1.0a";\r
1184       expect(from.numList()[1]).toBe(-1);\r
1185       expect(from.strList().join("")).toBe("ba");\r
1186 \r
1187       expect(from.up().call()).toBe(from.$1.numList);\r
1188       expect(from.$1.numList[1]).toBe(-1);\r
1189       expect(from.$1.strList.join("")).toBe("ba");\r
1190 \r
1191       from.string = "あ 0b-1.0a12";\r
1192       expect(from.numList()[1]).toBe(-1);\r
1193       expect(from.strList().join("")).toBe("あ ba12");\r
1194 \r
1195       from.string = "0b-1.0a0";\r
1196       expect(from.numList().join(",")).toBe("0,-1,0");\r
1197       expect(from.strList().join("")).toBe("ba");\r
1198 \r
1199       from.string = "0b .1a";\r
1200       expect(from.numList()[1]).toBe(0.1);\r
1201       expect(from.strList().join("")).toBe("b a");\r
1202     } );\r
1203     /*無効同値クラスを調べておく (Equivalence partitioning, the following is the invalid partion)*/\r
1204     it("should be this for the value (the invalid partion)", function() {\r
1205       from.string = NaN;\r
1206       expect(function(){\r
1207         from.numList();\r
1208       } ).toThrow();\r
1209       expect(function(){\r
1210         from.strList();\r
1211       } ).toThrow();      \r
1212       \r
1213       from.string = "currentColor";\r
1214       expect(from.numList()).toEqual([]);\r
1215       expect(from.strList()[0]).toBe("currentColor");\r
1216 \r
1217       from.string = "eE";\r
1218       expect(from.numList()).toEqual([]);\r
1219       expect(from.strList()[0]).toBe("eE");\r
1220       expect(from.strList()[0]).toBe("eE");\r
1221     } )\r
1222   } );\r
1223   describe("A $to object", function() {\r
1224     var from = base("$from");\r
1225      beforeEach( function() {\r
1226        from = base("$from").up();\r
1227        from.up("$to");\r
1228        from.string = "";\r
1229      } );\r
1230     /*境界条件を調べておく (limit value analysis)*/\r
1231     it("should be this for the value  (limit value analysis)", function() {\r
1232       expect(from.$to instanceof from.constructor).toBeTruthy();\r
1233       expect(from.up().call()).toBe(from.$1.numList);\r
1234       expect(from.$to.up().call()).toBe(from.$to.$1.numList);\r
1235     } );\r
1236     /*同値分割をして、有効同値クラスを調べておく (Equivalence partitioning, the following is the valid partion)*/\r
1237     it("should be this for the value (the valid partion)", function() {\r
1238       from.up("$to");\r
1239       from.$to.from = from;\r
1240       from.$to.string = "12cm-7";\r
1241       expect(from.$to.numList().join(",")).toBe("12,-7");\r
1242       expect(from.$to.strList().toString()).toBe("cm");\r
1243       \r
1244       from.string = "7cm+8";\r
1245       from.$to.call();\r
1246       expect(from.call()).toBe(from.numList);\r
1247       expect(from.$to.numList.join(",")).toBe("12,-7");\r
1248       expect(from.$to.strList.join("")).toBe("cm");\r
1249       expect(from.numList.join(",")).toBe("7,8");\r
1250       expect(from.strList.join("")).toBe("cm");\r
1251       expect(from.$to.from).toBe(from.numList);\r
1252 \r
1253     } );\r
1254     /*無効同値クラスを調べておく (Equivalence partitioning, the following is the invalid partion)*/\r
1255     it("should be this for the value (the invalid partion)", function() {\r
1256       from.call();\r
1257       from.up("$to").mix( function() {\r
1258         this.string = "12cm";\r
1259         this.call();\r
1260         var arr = [];\r
1261         arr.string = this.string;\r
1262         expect(this.numList).toEqual(arr);\r
1263         expect(this.strList).toBeNull();\r
1264       } );\r
1265     } );\r
1266     \r
1267     describe("An advance method", function() {\r
1268       var from = base("$from");\r
1269        beforeEach( function() {\r
1270          from = base("$from").up();\r
1271          from.string = "";\r
1272          from.up("$to");\r
1273          from.$to.from = from;\r
1274        } );\r
1275       /*境界条件を調べておく (limit value analysis)*/\r
1276       it("should be this for the value  (limit value analysis)", function() {\r
1277         expect(from.advance()).toBe("");\r
1278         expect(from.$to.advance()).toBe("");\r
1279         expect(from.$to.advance(0)).toBe("");\r
1280         expect(from.$to.advance(1)).toBe("");\r
1281         expect(function(){\r
1282           from.$to.advance(1.01);\r
1283         }).toThrow("An Invalid Number Error");\r
1284         expect(function(){\r
1285           from.$to.advance(-0.01);\r
1286         }).toThrow("An Invalid Number Error");\r
1287         \r
1288         var arr = [];\r
1289         \r
1290         from = base("$from").up();\r
1291         from.up("$to");\r
1292         from.$to.from = from;\r
1293         arr.string = from.string = "0";\r
1294         from.$to.string = "1";\r
1295         expect(from.$to.call()).toBe(from.$to.numList);\r
1296         expect(from.$to.numList[0]).toBe(1);\r
1297         expect(from.$to.strList).toBeNull();\r
1298         expect(from.numList[0]).toBe(0);\r
1299         expect(from.strList).toBeNull();\r
1300         expect(from.advance(0)).toBe("");\r
1301         expect(from.$to.from).toBe(from.numList);\r
1302         expect(from.$to.advance(0)).toBe("0");       \r
1303         expect(from.call()).toBe(from.numList);\r
1304         \r
1305         from = base("$from").up();\r
1306         f(from.up(), "inline", "block");\r
1307         f(from.up(), " inline", " block ");\r
1308         function f(from, inline, block) {\r
1309           from.up("$to");\r
1310           from.$to.from = from;\r
1311           from.string = inline;\r
1312           arr.string = from.$to.string = block;\r
1313           expect(from.$to.call()).toBe(from.$to.numList);\r
1314           expect(from.$to.numList).toEqual(arr);\r
1315           expect(from.$to.strList).toEqual([block]);\r
1316           arr.string = from.string;\r
1317           expect(from.numList).toEqual(arr);\r
1318           expect(from.strList).toEqual([inline]);\r
1319           expect(from.advance(0)).toBe("");\r
1320           expect(from.$to.from).toBe(from.numList);\r
1321           expect(from.$to.advance(0)).toBe("inline");\r
1322           expect(from.$to.advance(1)).toBe("block");\r
1323           expect(from.call()).toBe(from.numList);\r
1324         }\r
1325       } );\r
1326       /*同値分割をして、有効同値クラスを調べておく (Equivalence partitioning, the following is the valid partion)*/\r
1327       it("should be this for the value (the valid partion)", function() {\r
1328         var deg = 3;\r
1329         \r
1330         from.string = "0s";\r
1331         from.$to.string = "1s";\r
1332         expect(from.$to.call()).toBe(from.$to.numList);\r
1333         expect(from.$to.numList[0]).toBe(1);\r
1334         expect(from.$to.strList[0]).toBe("");\r
1335         expect(from.numList[0]).toBe(0);\r
1336         expect(from.strList[0]).toBe("");\r
1337         expect(from.advance(0)).toBe("");\r
1338         expect(from.$to.from).toBe(from.numList);\r
1339         expect(from.$to.advance(0)).toBe("0s");\r
1340         from.$to.degit = deg;\r
1341         for (var i=0;i<1;i+=0.01) {\r
1342           expect(from.$to.advance(i)).toBe(i.toFixed(deg)+"s");\r
1343         }\r
1344         expect(from.call()).toBe(from.numList);\r
1345         \r
1346         from = base("$from").up();\r
1347         from.up("$to");\r
1348         from.string = "a0S";\r
1349         from.$to.string = "a1S";\r
1350         from.$to.from = from;\r
1351         expect(from.$to.call()).toBe(from.$to.numList);\r
1352         expect(from.$to.numList[0]).toBe(1);\r
1353         expect(from.$to.strList[0]).toBe("a");\r
1354         expect(from.numList[0]).toBe(0);\r
1355         expect(from.strList[0]).toBe("a");\r
1356         expect(from.advance(0)).toBe("");\r
1357         expect(from.$to.from).toBe(from.numList);\r
1358         expect(from.$to.advance(0)).toBe("a0S");\r
1359 \r
1360         from.$to.degit = deg;\r
1361         for (var i=0;i<1;i+=0.01) {\r
1362           expect(from.$to.advance(i)).toBe("a" +i.toFixed(deg)+ "S");\r
1363         }\r
1364         expect(from.call()).toBe(from.numList);\r
1365         \r
1366         from = base("$from").up();\r
1367         f(from.up(), "a-10s1.5", "a10s-3");\r
1368         f(from.up(), " a-10s1.5", " a10s-3 ");\r
1369         function f(from, fromString, toString) {\r
1370           from.up("$to");\r
1371           from.string = fromString;\r
1372           from.$to.string = toString;\r
1373           from.$to.from = from;\r
1374           from.$to.call();\r
1375           from.$to.degit = 1;\r
1376           expect(from.$to.advance(0)).toBe("a-10.0s1.5");\r
1377           expect(from.$to.advance(0.4)).toBe("a-2.0s-0.3");\r
1378           expect(from.$to.advance(1)).toBe("a10.0s-3.0");\r
1379 \r
1380           from.$to.additive[0] = 1;\r
1381           from.$to.accumulate[1] = 2;\r
1382           expect(from.$to.advance(0.4)).toBe("a-1.0s1.7");\r
1383           from.$to.additive[0] = 0.5;\r
1384           from.$to.accumulate[1] = 0.8;\r
1385           expect(from.$to.advance(1)).toBe("a10.5s-2.2");\r
1386         }\r
1387       } );\r
1388       /*無効同値クラスを調べておく (Equivalence partitioning, the following is the invalid partion)*/\r
1389       it("should be this for the value (the invalid partion)", function() {\r
1390         expect(function(){\r
1391           from.$to.advance(10);\r
1392         }).toThrow("An Invalid Number Error");\r
1393         expect(function(){\r
1394           from.$to.advance(-10);\r
1395         }).toThrow("An Invalid Number Error");\r
1396       } );\r
1397     } )\r
1398   } );\r
1399   describe("A distance method", function() {\r
1400       var from = base("$from");\r
1401        beforeEach( function() {\r
1402          from = base("$from").up();\r
1403          from.string = "";\r
1404          from.up("$to");\r
1405        } );\r
1406       /*境界条件を調べておく (limit value analysis)*/\r
1407       it("should be this for the value  (limit value analysis)", function() {\r
1408         expect(from.distance()).toBe(0)\r
1409         expect(from.$to.distance()).toBe(0);\r
1410         \r
1411         from.string = "0";\r
1412         from.$to.string = "1";\r
1413         expect(from.distance()).toBe(0);\r
1414         expect(from.$to.distance(from)).toBe(1);\r
1415       } );\r
1416       /*同値分割をして、有効同値クラスを調べておく (Equivalence partitioning, the following is the valid partion)*/\r
1417       it("should be this for the value (the valid partion)", function() {\r
1418         from.string = "s 0 s 12";\r
1419         from.$to.string = "s 0 s 0";\r
1420         expect(from.distance()).toBe(0);\r
1421         expect(from.$to.distance(from)).toBe(12);\r
1422         expect(from.$to.distance(from)).toBe(12);\r
1423         expect(from.$to.distance(from.call())).toBe(12);\r
1424   \r
1425         from = base("$from").up();\r
1426         from.up("$to");\r
1427         from.string = "rgb(1, 0, 0)";\r
1428         from.$to.string = "rgb(0, 0, 1)";\r
1429         expect(from.distance()).toBe(0);\r
1430         expect(from.$to.distance(from)).toBe(Math.sqrt(2));\r
1431       } );\r
1432       /*無効同値クラスを調べておく (Equivalence partitioning, the following is the invalid partion)*/\r
1433       it("should be this for the value (the invalid partion)", function() {\r
1434         from.string = "s";\r
1435         from.$to.string = "s";\r
1436         expect(from.$to.distance(from)).toBe(0);\r
1437       } );\r
1438   } );\r
1439   describe("A setAdditive method", function() {\r
1440       var from = base("$from");\r
1441        beforeEach( function() {\r
1442          from = base("$from").up();\r
1443          from.string = "";\r
1444          from.up("$to");\r
1445        } );\r
1446       /*境界条件を調べておく (limit value analysis)*/\r
1447       it("should be this for the value  (limit value analysis)", function() {\r
1448         expect(from.setAdditive()).toBe(0);\r
1449         expect(from.setAdditive("")).toBe(0);\r
1450         expect(from.additive).toEqual([0]);\r
1451         var arr = [1];\r
1452         arr.string = "1";\r
1453         expect(from.setAdditive("1")).toEqual(arr);\r
1454         expect(from.additive).toEqual(arr);\r
1455       } );\r
1456       /*同値分割をして、有効同値クラスを調べておく (Equivalence partitioning, the following is the valid partion)*/\r
1457       it("should be this for the value (the valid partion)", function() {\r
1458         var arr = [1, 2, 3];\r
1459         arr.string = "1 2, 3";\r
1460         expect(from.setAdditive("1 2, 3")).toEqual(arr);\r
1461         expect(from.additive).toEqual(arr);\r
1462       } );\r
1463       /*無効同値クラスを調べておく (Equivalence partitioning, the following is the invalid partion)*/\r
1464       it("should be this for the value (the invalid partion)", function() {\r
1465       } );\r
1466   } );\r
1467   describe("A setAccumulate method", function() {\r
1468       var from = base("$from");\r
1469        beforeEach( function() {\r
1470          from = base("$from").up();\r
1471          from.string = "0 1";\r
1472          from.up("$to");\r
1473          from.call();\r
1474        } );\r
1475       /*境界条件を調べておく (limit value analysis)*/\r
1476       it("should be this for the value  (limit value analysis)", function() {\r
1477         expect(from.setAccumulate()).toBe(0);\r
1478         expect(from.setAccumulate(0)).toBe(0);\r
1479         expect(from.accumulate).toEqual([0, 0]);\r
1480         expect(from.setAccumulate(1)).toEqual([0, 1]);\r
1481         expect(from.accumulate).toEqual([0, 1]);\r
1482       } );\r
1483       /*同値分割をして、有効同値クラスを調べておく (Equivalence partitioning, the following is the valid partion)*/\r
1484       it("should be this for the value (the valid partion)", function() {\r
1485         expect(from.setAccumulate(2)).toEqual([0, 2]);\r
1486         expect(from.accumulate).toEqual([0, 2]);\r
1487       } );\r
1488       /*無効同値クラスを調べておく (Equivalence partitioning, the following is the invalid partion)*/\r
1489       it("should be this for the value (the invalid partion)", function() {\r
1490         expect(from.setAccumulate(NaN)).toEqual(0);\r
1491       } );\r
1492   } );\r
1493   describe("A $calcMode object", function() {\r
1494     var calc = base("$calcMode"),\r
1495         to = calc.to,\r
1496         from;\r
1497      beforeEach( function() {\r
1498        calc = base("$calcMode").up();\r
1499        calc.to = base("$from").up().mix( {string: "1"} );\r
1500        from = calc.to.from = base("$from").up().mix( {string: "0"} );\r
1501      } );\r
1502     /*境界条件を調べておく (limit value analysis)*/\r
1503     it("should be this for the value  (limit value analysis)", function() {\r
1504       expect(calc.mode).toBe("linear");\r
1505       expect(calc.keyTime).toBe(1);\r
1506       expect(calc.keySplines).toBeNull();\r
1507       expect(calc.string).toBe("");\r
1508 \r
1509       expect(calc.call()(0)).toBe("0");\r
1510       expect(calc.keyTime).toBe(1);\r
1511       expect(calc.call()(1)).toBe("1");\r
1512       \r
1513       calc.keyTime = 0;\r
1514       expect(calc.call()(1)).toBe("0");\r
1515       \r
1516       /*paced mode*/\r
1517       calc.mode = "paced";\r
1518       expect(calc.norm).toBe(1);\r
1519       calc.to.from = from;\r
1520       expect(calc.call()(0)).toBe("0");\r
1521       expect(calc.keyTime).toBe(1);\r
1522       calc.to.from = from;\r
1523       expect(calc.call()(1)).toBe("1");\r
1524       \r
1525       calc.keyTime = 0;\r
1526       calc.to.from = from;\r
1527       expect(calc.call()(1)).toBe("1");\r
1528       \r
1529       /*discrete mode*/\r
1530       calc.mode = "discrete";\r
1531       calc.to.from = from;\r
1532       calc.keyTime = 1;\r
1533       expect(calc.call()(0)).toBe("0");\r
1534       expect(calc.call()(1)).toBe("1");\r
1535     } );\r
1536     /*同値分割をして、有効同値クラスを調べておく (Equivalence partitioning, the following is the valid partion)*/\r
1537     it("should be this for the value (the valid partion)", function() {\r
1538       calc.mode = "linear";\r
1539       calc.keyTime = 0.5;\r
1540       calc.to.degit = 1;\r
1541       expect(calc.call()(0.2)).toBe("0.4");\r
1542       expect(calc.call()(0.3)).toBe("0.6");\r
1543       /*もう一度確かめる*/\r
1544       expect(calc.call()(0.2)).toBe("0.4");\r
1545       \r
1546       calc = base("$calcMode").up();\r
1547       calc.keyTime = 0.2;\r
1548       calc.to = base("$from").up();\r
1549       calc.to.from = base("$from").up();    \r
1550       calc.to.from.string = "0s";\r
1551       calc.to.string = "1s";\r
1552       calc.to.degit = 1;\r
1553       expect(calc.call()(0.1)).toBe("0.5s");\r
1554 \r
1555       calc = base("$calcMode").up();\r
1556       calc.keyTime = 0.5;\r
1557       calc.to = base("$from").up();\r
1558       calc.to.from = base("$from").up();    \r
1559       calc.to.from.string = "rgb(100, 20, 32)";\r
1560       calc.to.string = "rgb(0, 10, 50)";\r
1561       expect(calc.call()(0.25)).toBe("rgb(50, 15, 41)");\r
1562       \r
1563       /*paced mode*/\r
1564       calc.to = base("$from").up();\r
1565       calc.to.from = base("$from").up();    \r
1566       calc.mode = "paced";\r
1567       calc.norm = 100;\r
1568       calc.to.from.string = "0s";\r
1569       calc.to.string = "20s";\r
1570       calc.to.degit = 1;\r
1571       expect(calc.call()(0.1)).toBe("10.0s");\r
1572       expect(calc.keyTime).toBe(0.2);\r
1573 \r
1574       calc.to = base("$from").up();\r
1575       calc.to.from = base("$from").up();    \r
1576       calc.mode = "paced";\r
1577       calc.norm = 100;\r
1578       calc.to.from.string = "rgb(0, 0, 20)";\r
1579       calc.to.string = "rgb(0, 0, 0)";\r
1580       expect(calc.call()(0.1)).toBe("rgb(0, 0, 10)");\r
1581       expect(calc.keyTime).toBe(0.2);\r
1582       \r
1583       /*discrete mode*/\r
1584       calc.to = base("$from").up();\r
1585       calc.to.from = base("$from").up();    \r
1586       calc.mode = "discrete";\r
1587       calc.keyTime = 0.5;\r
1588       calc.to.degit = 1;\r
1589       calc.to.string = "1";\r
1590       calc.to.from.string = "0.5";\r
1591       expect(calc.call()(0.2)).toBe("0.5");\r
1592       expect(calc.call()(0.3)).toBe("0.5");\r
1593       /*もう一度確かめる*/\r
1594       expect(calc.call()(0.2)).toBe("0.5");\r
1595       \r
1596       calc.to = base("$from").up();\r
1597       calc.to.from = base("$from").up();    \r
1598       calc.mode = "discrete";\r
1599       calc.keyTime = 0.5;\r
1600       calc.to.degit = 1;\r
1601       calc.to.string = "block";\r
1602       calc.to.from.string = "inline";\r
1603       expect(calc.call()(0.2)).toBe("inline");\r
1604       expect(calc.call()(0.3)).toBe("inline");\r
1605       \r
1606       calc.to = base("$from").up();\r
1607       calc.to.from = base("$from").up();    \r
1608       calc.mode = "linear";\r
1609       calc.keyTime = 1;\r
1610       calc.to.degit = 1;\r
1611       calc.to.string = "1 1";\r
1612       calc.to.from.string = "0.0 1";\r
1613       expect(calc.call()(0.2)).toBe("0.2 1.0");\r
1614       expect(calc.call()(0.3)).toBe("0.3 1.0");\r
1615     } );\r
1616     /*無効同値クラスを調べておく (Equivalence partitioning, the following is the invalid partion)*/\r
1617     it("should be this for the value (the invalid partion)", function() {\r
1618       calc.keyTime = null;\r
1619       expect(calc.call()(1)).toBe(calc.string);\r
1620       \r
1621       calc.keyTime = void 0;\r
1622       expect(calc.call()(1)).toBe(calc.string);\r
1623       \r
1624       calc.keyTime = 1/0;\r
1625       expect(calc.call()(1)).toBe(calc.string);\r
1626 \r
1627       expect(calc.call()()).toBe(calc.string);\r
1628 \r
1629       calc = base("$calcMode").up();\r
1630       calc.mode = "paced";\r
1631       calc.to.from = from;\r
1632       expect(calc.call()()).toBe(calc.string);\r
1633       \r
1634       calc = base("$calcMode").up();\r
1635       calc.mode = "discrete";\r
1636       expect(calc.call()()).toBe(calc.string);\r
1637     } );\r
1638     \r
1639     /*splineモードの境界条件を調べておく (limit value analysis)*/\r
1640     it("should be this for the value  (spline mode limit value analysis)", function() {\r
1641       /*3次ベジェ曲線の数式はこのページを参考にした http://opentype.jp/fontguide_doc3.htm*/\r
1642       var x = 0,\r
1643           y = 0,\r
1644           bezier = function (x1, y1, x2, y2, x3, y3, x4, y4) {\r
1645             return function (t) {\r
1646               x = (x4-3*(x3-x2)-x1)*t*t*t + 3*(x3-2*x2+x1)*t*t + 3*(x2-x1)*t + x1;\r
1647               y = (y4-3*(y3-y2)-y1)*t*t*t + 3*(y3-2*y2+y1)*t*t + 3*(y2-y1)*t + y1;\r
1648               return y;\r
1649             };\r
1650           };\r
1651       expect(calc.keySplines).toBeNull();\r
1652       calc.mode = "spline";\r
1653       expect( calc.call()("undef")).toBe(Math.PI);\r
1654       calc.keySplines = [0, 0, 1, 1];\r
1655       calc.to.degit = 1;\r
1656       calc.to.from = from;\r
1657       expect(calc.call()(0)).toBe(bezier(0,0, 0,0, 1,1, 1,1)(0)+".0");\r
1658       calc.to.from = from;\r
1659       expect(calc.call()(1)).toBe(bezier(0,0, 0,0, 1,1, 1,1)(1)+".0");\r
1660       calc.to.from = from;\r
1661       expect(calc.call()(0.5)).toBe(bezier(0,0, 0,0, 1,1, 1,1)(0.5)+"");\r
1662       \r
1663       df(0,0, 0,0, 1,1, 1,1, 0.1);\r
1664       df(0,0, 0,0, 1,1, 1,1, 0.5);\r
1665       df(0,0, 0,0, 1,1, 1,1, 0.8);\r
1666       df(0,0, 0,0, 1,1, 1,1, 0.9);\r
1667       df(0,0, 0.75,0, 0,0.75, 1,1, 0.1);\r
1668       df(0,0, 0.75,0, 0,0.75, 1,1, 0.5);\r
1669       df(0,0, 0.75,0, 0,0.75, 1,1, 0.8);\r
1670       df(0,0, 0.75,0, 0,0.75, 1,1, 0.9);\r
1671       function df (x1, y1, x2, y2, x3, y3, x4, y4, t) {\r
1672       /*自作のニュートン法*/\r
1673         var a = y4-3*(y3-y2)-y1,\r
1674             b = 3*(y3-2*y2+y1),\r
1675             c = 3*(y2-y1),\r
1676             d = y1 - bezier.apply(null, arguments)(t);\r
1677         expect(Math.abs(Math.qubicnewton(a, b, c, d, t) - t)).toBeLessThan(1e-5);\r
1678       };\r
1679     } );\r
1680     /*同値分割をして、有効同値クラスを調べておく (Equivalence partitioning, the following is the valid partion)*/\r
1681     it("should be this for the value (the valid partion on a spline mode )", function() {\r
1682       var x = 0,\r
1683           y = 0,\r
1684           bezier = function (x1, y1, x2, y2, x3, y3, x4, y4) {\r
1685             return function (t) {\r
1686               return {\r
1687                   x: (x4-3*(x3-x2)-x1)*t*t*t + 3*(x3-2*x2+x1)*t*t + 3*(x2-x1)*t + x1,\r
1688                   y: (y4-3*(y3-y2)-y1)*t*t*t + 3*(y3-2*y2+y1)*t*t + 3*(y2-y1)*t + y1\r
1689                 };\r
1690             };\r
1691           };\r
1692       calc.mode = "spline";\r
1693       calc.keySplines = [0, 0.5, 0.5, 1];\r
1694       calc.to.degit = 1;\r
1695       var b = bezier(0,0, 0,0.5, 0.5,1, 1,1);\r
1696       expect(calc.call()(0)).toBe(b(0).y+".0");\r
1697       calc.to.from = from;\r
1698       expect(calc.call()(1)).toBe(b(1).y+".0");\r
1699       calc.to.from = from;\r
1700       expect(calc.call()( b(0.5).x )).toBe(b(0.5).y.toFixed(1));\r
1701       \r
1702       var ff = function(k) {\r
1703         calc.keySplines = k;\r
1704         calc.to.degit = 10;\r
1705         var b = bezier(0,0, k[0],k[1], k[2],k[3], 1,1),\r
1706             epsilon = 1e-5; //誤差\r
1707         expect(calc.call()(0)).toBe(b(0).y.toFixed(10));\r
1708         calc.to.from = from;\r
1709         expect(calc.call()(1)).toBe(b(1).y.toFixed(10));\r
1710         calc.to.from = from;\r
1711         b = b(Math.random());\r
1712         expect(Math.abs(calc.call()(b.x) - b.y.toFixed(10))).toBeLessThan(epsilon);\r
1713       };\r
1714       for (var i=0;i<10000;++i) {\r
1715         var rand = [Math.random(), Math.random(), Math.random(), Math.random()].sort(function(a,b){return a-b;});\r
1716         ff(rand);\r
1717       }\r
1718     } );\r
1719     /*無効同値クラスを調べておく (Equivalence partitioning, the following is the invalid partion)*/\r
1720     it("should be this for the value (the invalid partion on a spline mode )", function() {\r
1721       calc.mode = "spline";\r
1722       calc.keySplines = [0, NaN, 1, 1];\r
1723       calc.to.degit = 1;\r
1724       calc.to.from = from;\r
1725       expect( calc.up().call()("undef")).toBe(Math.PI);\r
1726 \r
1727       \r
1728       calc.keySplines = [0, 0, 1, 2];\r
1729       calc.to.degit = 1;\r
1730       calc.to.from = from;\r
1731       expect( calc.up().call()("undef")).toBe(Math.PI);\r
1732       \r
1733       calc.keySplines = null;\r
1734       calc.to.degit = 1;\r
1735       calc.to.from = from;\r
1736       expect( calc.up().call()("undef")).toBe(Math.PI);\r
1737     } );\r
1738   } );\r
1739   describe("A $attribute object", function() {\r
1740     describe("A push method", function() {\r
1741       var attr, s;\r
1742       beforeEach( function() {\r
1743         attr = base("$calcMode").$attribute.up("width");\r
1744         base("$frame").timelines.length = 0;\r
1745         s = document.createElementNS("http:///www.w3.org/2000/svg", "animate");\r
1746       } );\r
1747       afterEach( function() {\r
1748         attr.isCSS = false;\r
1749       } );\r
1750       /*境界条件を調べておく (limit value analysis)*/\r
1751       it("should be this for the value  (limit value analysis)", function() {\r
1752         expect(attr.element).toBeNull();\r
1753         expect(attr.push()).toBeNull();\r
1754         expect(attr.element).toBeNull();\r
1755         expect(attr.isCSS).toBeFalsy();\r
1756         expect(base("$frame").timelines.length).toBe(0);\r
1757         \r
1758         expect(attr.push(s)).toBeNull();\r
1759         expect(attr.element).toBeNull();\r
1760         expect(base("$frame").timelines.length).toBe(0);\r
1761         expect(attr.hasAttrValues()).toBeFalsy();\r
1762         \r
1763         var p = document.createElement("g");\r
1764         p.appendChild(s);\r
1765         expect(attr.push(s)).toBeNull();\r
1766         expect(attr.element).toBe(p);\r
1767         expect(base("$frame").timelines.length).toBe(0);\r
1768         \r
1769         s.setAttribute("end", "0");\r
1770         check("from", 1);\r
1771         check("to", 2);\r
1772         check("by", 3);\r
1773         check("values", 4);\r
1774         function check(attrName, num) {\r
1775           s.setAttribute(attrName, "1");\r
1776           expect(s.hasAttributeNS(null, attrName)).toBeTruthy();\r
1777           var fr = attr.push(s);\r
1778           expect(attr.element).toBe(p);\r
1779           var timelines = base("$frame").timelines;\r
1780           expect(timelines.length).toBe(num);\r
1781           var line = timelines[num-1];\r
1782           expect(line).not.toBe(fr);\r
1783           var act = fr.$activate;\r
1784           expect(act.dur).toBeNull();\r
1785           expect(act.repeatCount).toBeNull();\r
1786           expect(act.repeatDur).toBeNull();\r
1787           expect(act.min).toBe("0");\r
1788           expect(act.max).toBe("indefinite");\r
1789           expect(act.simpleDur).toBeNull();\r
1790           expect(attr.hasAttrValues()).toBeTruthy();\r
1791           \r
1792           s.removeAttribute(attrName);\r
1793           expect(s.hasAttributeNS(null, attrName)).toBeFalsy();\r
1794           attr.push(s);\r
1795           expect(attr.element).toBe(p);\r
1796           expect(timelines.length).toBe(num);\r
1797         };\r
1798           \r
1799         /*targetElement属性のサポート*/\r
1800         var p2 = document.createElementNS("http://www.w3.org/2000/svg", "g");\r
1801         document.documentElement.appendChild(p2);\r
1802         p2.setAttributeNS(null, "id", "p23");\r
1803         s.setAttributeNS(null, "targetElement", "p23");\r
1804         attr.push(s);\r
1805         expect(attr.element).toBe(p2);\r
1806         \r
1807         /*ハイパーリンクのサポート*/\r
1808         var p3 = document.createElementNS("http://www.w3.org/2000/svg", "a");\r
1809         document.documentElement.appendChild(p3);\r
1810         p3.setAttributeNS(null, "id", "p34");\r
1811         s.setAttributeNS("http://www.w3.org/1999/xlink", "xlink:href", "#p34");\r
1812         attr.push(s);\r
1813         expect(attr.element).toBe(p3);\r
1814         \r
1815         /*attributeType属性のサポート*/\r
1816         s.setAttributeNS(null, "attributeType", "CSS");\r
1817         s.setAttributeNS(null, "values", "a;b;c");\r
1818         attr.push(s);\r
1819         expect(attr.isCSS).toBeTruthy();\r
1820       } );\r
1821       /*同値分割をして、有効同値クラスを調べておく (Equivalence partitioning, the following is the valid partion)*/\r
1822       it("should be this for the value (the valid partion )", function() {\r
1823         s.setAttribute("from", "1");\r
1824         var p = document.createElement("g");\r
1825         p.appendChild(s);\r
1826         var values = [ "0",\r
1827                       "0", null, null, null, \r
1828                       "0", "indefinite", null\r
1829                     ];\r
1830         values[7] = 0;\r
1831         check2("dur", "0");\r
1832         check2("begin", "0");\r
1833         values[0] = "1";\r
1834         check2("begin", "1");\r
1835         values[2] = 0;\r
1836         check2("end", "0");\r
1837         values[3] = "0";\r
1838         check2("repeatCount", "0");\r
1839         values[4] = "0";\r
1840         check2("repeatDur", "0");\r
1841         values[5] = "0";\r
1842         check2("min", "0");\r
1843         values[6] = "0";\r
1844         check2("max", "0");\r
1845         values[0] = "12";\r
1846         check2("begin", "12");\r
1847         values[7] = 1000 * base("$frame").fpms;\r
1848         values[1] = "1";\r
1849         check2("dur", "1");\r
1850         function check2(attrName, value) {\r
1851           s.setAttribute(attrName, value);\r
1852           expect(s.hasAttributeNS(null, attrName)).toBeTruthy();\r
1853           var fr = attr.push(s);\r
1854           expect(attr.element).toBe(p);\r
1855           var timelines = base("$frame").timelines;\r
1856           var line = timelines[timelines.length-1];\r
1857           expect(fr.string).toBe(values[0]);\r
1858           var act = fr.$activate;\r
1859           expect(act.dur).toBe(values[1]);\r
1860           expect(act.repeatCount).toBe(values[3]);\r
1861           expect(act.repeatDur).toBe(values[4]);\r
1862           expect(act.min).toBe(values[5]);\r
1863           expect(act.max).toBe(values[6]);\r
1864           expect(act.simpleDur).toBe(values[7]);\r
1865         };\r
1866         \r
1867                 \r
1868         var p4 = document.createElementNS("http://www.w3.org/2000/svg", "g");\r
1869         document.documentElement.appendChild(p4);\r
1870         p4.appendChild(s);\r
1871         p4.setAttributeNS(null, "style", "display: none");\r
1872         attr.push(s);\r
1873         expect(attr.setAttribute()).toBeUndefined();\r
1874         expect(attr.setAttribute("block")).toBeUndefined();\r
1875         expect(p4.hasAttributeNS(null, "display")).toBeFalsy();\r
1876         expect(attr.isCSS).toBeFalsy();\r
1877         \r
1878         s.setAttributeNS(null, "attributeName", "display");\r
1879         attr.push(s);\r
1880         expect(attr.setAttribute("block")).toBeUndefined();\r
1881         expect(p4.hasAttributeNS(null, "display")).toBeFalsy();\r
1882         expect(attr.isCSS).toBeTruthy();\r
1883         expect(p4.style.getPropertyValue("display")).toBe("block");\r
1884         \r
1885         p4 = document.createElementNS("http://www.w3.org/2000/svg", "g");\r
1886         document.documentElement.appendChild(p4);\r
1887         p4.appendChild(s);\r
1888         p4.setAttributeNS(null, "style", "display: none");\r
1889         attr.push(s);\r
1890         expect(attr.setAttribute("block")).toBeUndefined();\r
1891         expect(p4.hasAttributeNS(null, "display")).toBeFalsy();\r
1892         expect(p4.style.getPropertyValue("display")).toBe("block");\r
1893         expect(attr.removeAttribute()).toBeUndefined();\r
1894         expect(p4.hasAttributeNS(null, "display")).toBeFalsy();\r
1895         expect(p4.style.getPropertyValue("display")).toBe("none");\r
1896         \r
1897         /*attributeType属性のサポート*/\r
1898         s.setAttributeNS(null, "values", "a;b;c");\r
1899         s.setAttributeNS(null, "attributeName", "display");\r
1900         attr.isCSS = false;\r
1901         attr.push(s);\r
1902         expect(attr.isCSS).toBeTruthy();\r
1903       } );\r
1904       /*無効同値クラスを調べておく (Equivalence partitioning, the following is the invalid partion)*/\r
1905       it("should be this for the value (the invalid partion )", function() {\r
1906         var p = document.createElement("g");\r
1907         p.appendChild(s);\r
1908         \r
1909         s.setAttributeNS(null, "begin", "1");\r
1910         attr.push(s);\r
1911         var timelines = base("$frame").timelines;\r
1912         expect(timelines.length).toBe(0);\r
1913         s.setAttributeNS(null, "from", "0");\r
1914         attr.push(s);\r
1915         expect(timelines.length).toBe(1);\r
1916         expect(attr.push(12)).toBeNull();\r
1917       } );\r
1918     } );\r
1919     describe("A setValues method", function() {\r
1920       var attr, s;\r
1921       beforeEach( function() {\r
1922         attr = base("$calcMode").$attribute.up("width");\r
1923         base("$frame").timelines.length = 0;\r
1924         s = document.createElement("animate");\r
1925       } );\r
1926       /*境界条件を調べておく (limit value analysis)*/\r
1927       it("should be this for the value  (limit value analysis)", function() {\r
1928         expect(attr.$from).not.toBeUndefined();\r
1929         expect(attr.setValues()).toBeNull();\r
1930         expect(attr.setValues("")).toBeNull();\r
1931 \r
1932         expect(attr.setValues("0;1")[0].to.string).toBe("1");\r
1933         expect(attr.setValues("0;1")[0].to.from.string).toBe("0");\r
1934         expect(attr.setValues("0;1", "0", "1", "1")[0].to.from.string).toBe("0");\r
1935         expect(attr.setValues("0;1", null, "1", "0")[0].to.from.string).toBe("0"); \r
1936                \r
1937         /*from-to アニメーション*/\r
1938         expect(attr.setValues(null, "0", "1")[0].to.string).toBe("1");\r
1939         expect(attr.setValues(null, "0", "1")[0].to.from.string).toBe("0");\r
1940         \r
1941         /*from-by アニメーション*/\r
1942         expect(attr.setValues(null, "1", null, "1")[0].to.string).toBe("1");\r
1943         expect(attr.setValues(null, "1", null, "1")[0].to.from[0]).toBe(1);\r
1944         expect(attr.setValues(null, "1", null, "1")[0].to.numList[0]).toBe(2);\r
1945         \r
1946         /*fromなしto アニメーション*/\r
1947         expect(attr.setValues(null, null, "1")[0].to.string).toBe("1");\r
1948         expect(attr.setValues(null, null, "1")[0].to.from.string).toBe("0");\r
1949         var aset = attr.setValues(null, null, "1")[0].to;\r
1950         aset.call();\r
1951         expect(aset.from[0]).toBe(0);\r
1952         \r
1953         /*fromなしby アニメーション*/\r
1954         expect(attr.setValues(null, null, null, "1")[0].to.string).toBe("1");\r
1955         expect(attr.setValues(null, null, null, "1")[0].to.from[0]).toBe(0);\r
1956         var aset = attr.setValues(null, null, null, "1")[0].to;\r
1957         aset.call();\r
1958         expect(aset.from[0]).toBe(0);\r
1959       } );\r
1960       /*同値分割をして、有効同値クラスを調べておく (Equivalence partitioning, the following is the valid partion)*/\r
1961       it("should be this for the value (the valid partion on a spline mode )", function() {\r
1962         attr.$from.degit = 1;\r
1963         var setv = attr.setValues("0;1")[0].call();\r
1964         expect(setv(0.5)).toBe("0.5");\r
1965         expect(setv(1)).toBe("1.0");\r
1966         \r
1967         setv = attr.setValues(" 0;1; 2 ")[0].call();\r
1968         expect(setv(0.5)).toBe("0.5");\r
1969         expect(setv(1)).toBe("1.0");\r
1970         setv = attr.setValues("0;1;2")[1].call();\r
1971         expect(setv(0.4)).toBe("1.4");\r
1972         expect(setv(1)).toBe("2.0");\r
1973         \r
1974         attr.$from.degit = 2;\r
1975         setv = attr.setValues("1;1;1;1 ;1;15.1")[4].call();\r
1976         expect(setv(0.5)).toBe("8.05");\r
1977         expect(setv(1)).toBe("15.10");\r
1978         \r
1979         var v = attr.setValues("1;1;2;1;1;15.1");\r
1980         setv = v[4].mix( {\r
1981          keyTime: 0.1\r
1982         } ).call();\r
1983         expect(setv(0.05)).toBe("8.05");\r
1984         expect(setv(0.1)).toBe("15.10");\r
1985         setv = v[3].mix( {\r
1986          keyTime: 0.1\r
1987         } ).call();\r
1988         expect(setv(0.01)).toBe("1.00");\r
1989         expect(setv(0.1)).toBe("1.00");\r
1990         setv = v[2].mix( {\r
1991          keyTime: 0.5\r
1992         } ).call();\r
1993         expect(setv(0.25)).toBe("1.50");\r
1994         expect(setv(0.5)).toBe("1.00");\r
1995       } );\r
1996       /*無効同値クラスを調べておく (Equivalence partitioning, the following is the invalid partion)*/\r
1997       it("should be this for the value (the invalid partion on a spline mode )", function() {\r
1998         attr.$from.degit = 1;\r
1999         expect(attr.setValues("")).toBeNull();\r
2000         expect(attr.setValues(null, null, null, null)).toBeNull();\r
2001       } );\r
2002     } );\r
2003     describe("A setKey method", function() {\r
2004       var attr, s;\r
2005       beforeEach( function() {\r
2006         attr = base("$calcMode").$attribute.up("width");\r
2007         base("$frame").timelines.length = 0;\r
2008         s = document.createElement("animate");\r
2009         document.createElement("g").appendChild(s);\r
2010       } );\r
2011       /*境界条件を調べておく (limit value analysis)*/\r
2012       it("should be this for the value  (limit value analysis)", function() {\r
2013         expect(attr.setKey(s)).toBeNull();\r
2014         \r
2015         s.setAttributeNS(null, "from", "0");\r
2016         attr.setKey(s);\r
2017         s.setAttributeNS(null, "to", "0");\r
2018         expect(attr.setKey(s)[0].to.from.string).toBe("0");\r
2019         expect(attr.setKey(s)[0].to.string).toBe("0");\r
2020         s.setAttributeNS(null, "by", "0");\r
2021         attr.setKey(s);\r
2022         s.setAttributeNS(null, "values", "0;2");\r
2023         expect(attr.setKey(s)[0].to.from.string).toBe("0");\r
2024         expect(attr.setKey(s)[0].to.string).toBe("2");\r
2025         \r
2026         s.setAttributeNS(null, "keyTimes", "0;0.1");\r
2027         expect(attr.setKey(s)[0].keyTime).toBe(0.1);\r
2028         \r
2029         s.setAttributeNS(null, "keySplines", "0,0.1,0.3,0.4");\r
2030         expect(attr.setKey(s)[0].keySplines[0]).toBe(0);\r
2031         expect(attr.setKey(s)[0].keySplines[1]).toBe(0.1);\r
2032         expect(attr.setKey(s)[0].keySplines[2]).toBe(0.3);\r
2033         expect(attr.setKey(s)[0].keySplines[3]).toBe(0.4);\r
2034         \r
2035         s.setAttributeNS(null, "keySplines", "0 0.1 0.3 0.4");\r
2036         expect(attr.setKey(s)[0].keySplines[0]).toBe(0);\r
2037         expect(attr.setKey(s)[0].keySplines[1]).toBe(0.1);\r
2038         expect(attr.setKey(s)[0].keySplines[2]).toBe(0.3);\r
2039         expect(attr.setKey(s)[0].keySplines[3]).toBe(0.4);\r
2040       } );\r
2041       /*同値分割をして、有効同値クラスを調べておく (Equivalence partitioning, the following is the valid partion)*/\r
2042       it("should be this for the value (the valid partion on a spline mode )", function() {\r
2043         s.setAttributeNS(null, "values", "0;2;12;30");\r
2044         expect(attr.setKey(s)[0].keyTime.toFixed(3)).toBe("0.333");\r
2045         s.setAttributeNS(null, "keyTimes", "0;0.1;0.2;1");\r
2046         expect(attr.setKey(s)[0].keyTime).toBe(0.1);\r
2047         expect(attr.setKey(s)[1].keyTime).toBe(0.1);\r
2048         expect(attr.setKey(s)[2].keyTime).toBe(0.8);\r
2049         s.setAttributeNS(null, "values", " 0; 2;12 ;30 ");\r
2050         s.setAttributeNS(null, "keyTimes", " 0; 0.1; 0.2 ; 1 ");\r
2051         expect(attr.setKey(s)[0].keyTime).toBe(0.1);\r
2052         expect(attr.setKey(s)[1].keyTime).toBe(0.1);\r
2053         expect(attr.setKey(s)[2].keyTime).toBe(0.8);\r
2054         \r
2055         s.setAttributeNS(null, "keyTimes", " 0; .1; .2 ; 1 ");\r
2056         expect(attr.setKey(s)[0].keyTime).toBe(0.1);\r
2057         expect(attr.setKey(s)[1].keyTime).toBe(0.1);\r
2058         expect(attr.setKey(s)[2].keyTime).toBe(0.8);\r
2059         \r
2060         s.setAttributeNS(null, "keySplines", " 0,0.1,0.3,1; 0.1,0.4,0.5,0.7; 0.2,0.2,0.1  , 1 ;");\r
2061         f(0, 0,0.1,0.3,1);\r
2062         f(1, 0.1,0.4,0.5,0.7);\r
2063         f(2, 0.2,0.2,0.1,1);\r
2064         \r
2065         s.setAttributeNS(null, "keySplines", " 0,.1,.3,1; .1,.4, .5,.7; .2,  .2, .1  , 1 ;");\r
2066         f(0, 0,0.1,0.3,1);\r
2067         f(1, 0.1,0.4,0.5,0.7);\r
2068         f(2, 0.2,0.2,0.1,1);\r
2069         \r
2070         s.setAttributeNS(null, "keySplines", " 0 .1 .333,1; .1 .4  .5 .7; .2   .2  .1    1 ;");\r
2071         f(0, 0,0.1,0.333,1);\r
2072         f(1, 0.1,0.4,0.5,0.7);\r
2073         f(2, 0.2,0.2,0.1,1);\r
2074         function f (i, a, b, c, d) {\r
2075           var splines = attr.setKey(s)[i].keySplines;\r
2076           expect(splines[0]).toBe(a);\r
2077           expect(splines[1]).toBe(b);\r
2078           expect(splines[2]).toBe(c);\r
2079           expect(splines[3]).toBe(d);\r
2080         };\r
2081       } );\r
2082       /*無効同値クラスを調べておく (Equivalence partitioning, the following is the invalid partion)*/\r
2083       it("should be this for the value (the invalid partion on a spline mode )", function() {\r
2084         s.setAttributeNS(null, "keyTimes", "0;0.1;0.2;1");\r
2085         expect(attr.setKey(s)).toBeNull();\r
2086         s.setAttributeNS(null, "values", "0;2;12");\r
2087         expect(attr.setKey(s)).toBeNull();\r
2088         s.setAttributeNS(null, "values", "0;2;12;20");\r
2089         s.setAttributeNS(null, "keyTimes", "0;0.1;0.2");\r
2090         expect(attr.setKey(s)).toBeNull();\r
2091       } );\r
2092     } );\r
2093   } );\r
2094   describe("A $setElement object", function() {\r
2095     describe("A timeline property", function() {\r
2096       var $set, ele, frame;\r
2097       beforeEach( function() {\r
2098         $set = base("$calcMode").$attribute.$setElement.up();\r
2099         var p = document.createElementNS("http://www.w3.org/2000/svg", "g");\r
2100         ele = document.createElementNS("http://www.w3.org/2000/svg", "set");\r
2101         p.appendChild(ele);\r
2102         frame = base("$frame");\r
2103       } );\r
2104       /*境界条件を調べておく (limit value analysis)*/\r
2105       it("should be this for the value  (limit value analysis)", function() {\r
2106         expect($set.timeline).toBe(frame.$begin);\r
2107         \r
2108         $set.init();\r
2109         expect($set.timeline).toBe(frame.$begin);\r
2110         expect($set.element).toBeNull();\r
2111       } );\r
2112     } );\r
2113     \r
2114       describe("An init method", function() {\r
2115       var $set, ele, frame;\r
2116       beforeEach( function() {\r
2117         $set = base("$calcMode").$attribute.$setElement.up();\r
2118         var p = document.createElementNS("http://www.w3.org/2000/svg", "g");\r
2119         ele = document.createElementNS("http://www.w3.org/2000/svg", "set");\r
2120         p.appendChild(ele);\r
2121         frame = base("$frame");\r
2122       } );\r
2123       /*境界条件を調べておく (limit value analysis)*/\r
2124       it("should be this for the value  (limit value analysis)", function() {\r
2125         expect($set.to).toBe("");\r
2126         expect($set.attrName).toBe("");\r
2127         expect($set.defaultValue).toBe("");\r
2128         expect($set.isDefault).toBeFalsy();\r
2129         expect($set.attrNameSpace).toBeNull();\r
2130         $set.init();\r
2131         expect($set.timeline).toBe(frame.$begin);\r
2132         $set.init(ele);\r
2133         expect($set.to).toBe("");\r
2134         expect($set.attrName).toBe("");\r
2135         expect($set.isDefault).toBeFalsy();\r
2136         expect($set.attrNameSpace).toBeNull();\r
2137         expect($set.timeline).toBe(frame.$begin);\r
2138       } );\r
2139       /*同値分割をして、有効同値クラスを調べておく (Equivalence partitioning, the following is the valid partion)*/\r
2140       it("should be this for the value (the valid partion  )", function() {\r
2141         ele.setAttributeNS(null, "to", "t1");\r
2142         $set.init(ele);\r
2143         expect($set.to).toBe("t1");\r
2144         expect($set.attrName).toBe("");\r
2145         expect($set.defaultValue).toBe("");\r
2146 \r
2147         ele.setAttributeNS(null, "attributeName", "tt1");\r
2148         $set.init(ele);\r
2149         expect($set.to).toBe("t1");\r
2150         expect($set.attrName).toBe("tt1");\r
2151         expect($set.defaultValue).toBe("");\r
2152 \r
2153         ele.parentNode.setAttributeNS(null, "tt1", "undef");\r
2154         $set.init(ele);\r
2155         expect($set.defaultValue).toBe("undef");\r
2156         expect($set.isDefault).toBeTruthy();\r
2157 \r
2158         ele.setAttributeNS(null, "attributeName", "font-size");\r
2159         ele.parentNode.style.setProperty("font-size", "12px");\r
2160         $set.init(ele);\r
2161         expect($set.defaultValue).toBe("12px");\r
2162         expect($set.isDefault).toBeFalsy();\r
2163         \r
2164         ele.setAttributeNS(null, "attributeName", "xlink:href");\r
2165         $set.init(ele);\r
2166         expect($set.to).toBe("t1");\r
2167         expect($set.attrName).toBe("xlink:href");\r
2168         expect($set.defaultValue).toBe("");\r
2169         ele.parentNode.setAttributeNS("http://www.w3.org/1999/xlink", "xlink:href", "undef");\r
2170         $set.init(ele);\r
2171         expect($set.attrNameSpace).toBe("http://www.w3.org/1999/xlink");\r
2172       } );\r
2173       /*無効同値クラスを調べておく (Equivalence partitioning, the following is the invalid partion)*/\r
2174       it("should be this for the value (the invalid partion on a spline mode )", function() {\r
2175         $set.init(null);\r
2176         expect($set.to).toBe("");\r
2177         expect($set.attrName).toBe("");\r
2178         expect($set.defaultValue).toBe("");\r
2179 \r
2180         $set.init(12);\r
2181         expect($set.to).toBe("");\r
2182         expect($set.attrName).toBe("");\r
2183         expect($set.defaultValue).toBe("");\r
2184       } );\r
2185     } );\r
2186     describe("Frame Set", function() {\r
2187       var $set, ele, frame;\r
2188       beforeEach( function() {\r
2189         $set = base("$calcMode").$attribute.$setElement.up();\r
2190         var p = document.createElementNS("http://www.w3.org/2000/svg", "g");\r
2191         ele = document.createElementNS("http://www.w3.org/2000/svg", "set");\r
2192         p.appendChild(ele);\r
2193         frame = base("$frame");\r
2194         frame.timelines.length = 0; //配列の初期化\r
2195         frame.startTime = Date.now();\r
2196         frame.setFrame(0);\r
2197       } );\r
2198       afterEach( function() {\r
2199         $set.isCSS = false;\r
2200       } );\r
2201       /*境界条件を調べておく (limit value analysis)*/\r
2202       it("should be this for the value  (limit value analysis)", function() {\r
2203         expect($set.isEnd).toBeFalsy();\r
2204         ele.setAttributeNS(null, "dur", "1s");\r
2205         ele.setAttributeNS(null, "attributeName", "fill");\r
2206         ele.setAttributeNS(null, "to", "red");\r
2207         $set.init(ele);\r
2208         /*テストしやすくするために、CSSではなくXML属性として扱う*/\r
2209         $set.isCSS = false;\r
2210         expect($set.timeline).not.toBe(frame.$begin);\r
2211         frame.setFrame(0);\r
2212         expect(ele.parentNode.getAttributeNS(null, "fill")).toBe("red");\r
2213         \r
2214         var line = $set.timeline;\r
2215         expect(line.$list.state).toBe(line.$list.PLAYING);\r
2216         frame.setFrame(24);\r
2217         expect(line.$list.state).toBe(line.$list.POSTWAITING);\r
2218         expect(ele.parentNode.hasAttributeNS(null, "fill")).toBeFalsy();\r
2219       } );\r
2220       /*同値分割をして、有効同値クラスを調べておく (Equivalence partitioning, the following is the valid partion)*/\r
2221       it("should be this for the value (the valid partion)", function() {\r
2222         ele.setAttributeNS(null, "begin", "1s");\r
2223         ele.setAttributeNS(null, "dur", "1s");\r
2224         ele.setAttributeNS(null, "attributeName", "fill");\r
2225         ele.setAttributeNS(null, "to", "red");\r
2226         $set.init(ele);\r
2227         /*テストしやすくするために、CSSではなくXML属性として扱う*/\r
2228         $set.isCSS = false;\r
2229         var f = function(num) {\r
2230           frame.setFrame(num);\r
2231           expect(ele.parentNode.getAttributeNS(null, "fill") || null).toBeNull();\r
2232         }\r
2233         f(0);\r
2234         f(1);\r
2235         f(23);\r
2236         frame.setFrame(24);\r
2237         expect(ele.parentNode.getAttributeNS(null, "fill")).toBe("red");\r
2238         frame.setFrame(25);\r
2239         expect(ele.parentNode.getAttributeNS(null, "fill")).toBe("red");\r
2240         f(48);\r
2241         f(49);\r
2242         \r
2243         ele.setAttributeNS(null, "fill", "freeze");\r
2244         $set.init(ele);\r
2245         $set.isCSS = false;\r
2246         f(0);\r
2247         f(1);\r
2248         f(23);\r
2249         frame.setFrame(24);\r
2250         expect(ele.parentNode.getAttributeNS(null, "fill")).toBe("red");\r
2251         frame.setFrame(25);\r
2252         expect(ele.parentNode.getAttributeNS(null, "fill")).toBe("red");\r
2253         frame.setFrame(48);\r
2254         expect(ele.parentNode.getAttributeNS(null, "fill") || null).toBe("red");\r
2255         frame.setFrame(49);\r
2256         expect(ele.parentNode.getAttributeNS(null, "fill") || null).toBe("red");\r
2257         ele.setAttributeNS(null, "begin", "1s");\r
2258         ele.setAttributeNS(null, "attributeName", "fill");\r
2259         ele.setAttributeNS(null, "to", "red");\r
2260         /*eleにはdur属性やendなどが設定されていなくとも、アニメーションが有効*/\r
2261         $set.init(ele);\r
2262         $set.isCSS = false;\r
2263         var f = function(num) {\r
2264           frame.setFrame(num);\r
2265           expect(ele.parentNode.getAttributeNS(null, "fill") || null).toBe("red");\r
2266         }\r
2267         f(0);\r
2268         f(1);\r
2269         f(23);\r
2270         f(24);\r
2271         f(25);\r
2272         f(48);      } );\r
2273       /*無効同値クラスを調べておく (Equivalence partitioning, the following is the invalid partion)*/\r
2274       it("should be this for the value (the invalid partion)", function() {\r
2275 \r
2276       } );\r
2277     } );\r
2278   } );\r
2279     describe("A $animateElement object", function() {\r
2280       describe("An init method", function() {\r
2281         var $animate, ele, frame;\r
2282         beforeEach( function() {\r
2283           $animate = base("$calcMode").$attribute.$setElement.$animateElement.up();\r
2284           var p = document.createElementNS("http://www.w3.org/2000/svg", "g");\r
2285           ele = document.createElementNS("http://www.w3.org/2000/svg", "animate");\r
2286           p.appendChild(ele);\r
2287           frame = base("$frame");\r
2288           frame.pauseAnimation();\r
2289           frame.timelines.length = 0;\r
2290           frame.startTime = Date.now();\r
2291           frame.setFrame(0);\r
2292         } );\r
2293         /*境界条件を調べておく (limit value analysis)*/\r
2294         it("should be this for the value  (limit value analysis)", function() {\r
2295           $animate.init();\r
2296           \r
2297           ele.setAttributeNS(null, "begin", "1s");\r
2298           ele.setAttributeNS(null, "dur", "1s");\r
2299           ele.setAttributeNS(null, "attributeName", "d");\r
2300           ele.setAttributeNS(null, "from", "M20 0 L20 30");\r
2301           ele.setAttributeNS(null, "to", "M20 20 L10 30");\r
2302           $animate.init(ele);\r
2303           expect($animate.isCSS).toBeFalsy();\r
2304           frame.setFrame(0);\r
2305           var p = ele.parentNode;\r
2306           /*getAttributeNSメソッドは、IE11では空文字列を返す(DOM 2に準拠)のに対して、\r
2307            * 他のブラウザではnullを返すため、その対策をする*/\r
2308           expect(p.getAttributeNS(null, "d") || null).toBeNull();\r
2309           \r
2310           function f(fr, result) {\r
2311             frame.setFrame(fr);\r
2312             expect(p.getAttributeNS(null, "d") || "").toBe(result);\r
2313           };\r
2314           \r
2315           f(24, "M20.0 0.0 L20.0 30.0");\r
2316           f(36, "M20.0 10.0 L15.0 30.0");\r
2317           f(48, "");\r
2318                     \r
2319           ele.setAttributeNS(null, "fill", "freeze");\r
2320           $animate.init(ele);\r
2321           f(24, "M20.0 0.0 L20.0 30.0");\r
2322           f(36, "M20.0 10.0 L15.0 30.0");\r
2323           f(48, "M20.0 20.0 L10.0 30.0");\r
2324           \r
2325           frame.timelines.length = 0;\r
2326           ele.setAttributeNS(null, "calcMode", "discrete");\r
2327           $animate.init(ele);\r
2328           expect($animate.isCSS).toBeFalsy();\r
2329           expect($animate.mode).toBe("discrete");\r
2330           f(24, "M20.0 0.0 L20.0 30.0");\r
2331           f(25, "M20.0 0.0 L20.0 30.0");\r
2332           f(37, "M20.0 20.0 L10.0 30.0");\r
2333           f(48, "M20.0 20.0 L10.0 30.0");\r
2334           \r
2335           [ ["display", "inline", "none"],\r
2336             ["visibility", "hidden", "visible"],\r
2337             ["stroke-linecap", "round", "square"],\r
2338             ["font-style", "italic", "normal"]\r
2339           ].forEach( function(attr) {\r
2340             var attrName = attr[0],\r
2341                 from = attr[1],\r
2342                 to = attr[2];\r
2343             function g(fr, result) {\r
2344               frame.setFrame(fr);\r
2345               expect(p.style.getPropertyValue(attrName) || p.getAttribute(attrName) || "").toBe(result);\r
2346             };\r
2347 \r
2348             \r
2349             ele.setAttributeNS(null, "from", from);\r
2350             ele.setAttributeNS(null, "to", to);\r
2351             frame.timelines.length = 0;\r
2352             ele.setAttributeNS(null, "calcMode", "linear");\r
2353             ele.setAttributeNS(null, "attributeName", attrName);\r
2354             $animate.init(ele);\r
2355             expect($animate.mode).toBe("discrete");\r
2356             g(24, from);\r
2357             g(25, from);\r
2358             g(37, to);\r
2359             g(48, to);\r
2360           } );\r
2361         } );\r
2362         /*同値分割をして、有効同値クラスを調べておく (Equivalence partitioning, the following is the valid partion)*/\r
2363         it("should be this for the value (the valid partion )", function() {\r
2364           /*24FPSが前提*/\r
2365           ele.setAttributeNS(null, "begin", "0s");\r
2366           ele.setAttributeNS(null, "dur", "100s");\r
2367           ele.setAttributeNS(null, "attributeName", "d");\r
2368           ele.setAttributeNS(null, "fill", "freeze");\r
2369           ele.setAttributeNS(null, "from", "M20 0 L20 30");\r
2370           ele.setAttributeNS(null, "to", "M20 2400 L20 30");\r
2371           $animate.init(ele);\r
2372           \r
2373           var p = ele.parentNode;\r
2374           expect(p.getAttributeNS(null, "d") || null).toBeNull();\r
2375           \r
2376           function f(fr, result) {\r
2377             frame.setFrame(fr);\r
2378             expect(p.getAttributeNS(null, "d")).toBe(result);\r
2379           };\r
2380           \r
2381           for (var i=0;i<2400;++i) {\r
2382             f(i, "M20.0 " +i+ ".0 L20.0 30.0");\r
2383           }\r
2384           f(2401, "M20.0 2400.0 L20.0 30.0");\r
2385           \r
2386           \r
2387           frame.timelines.length = 0;\r
2388           ele.setAttributeNS(null, "begin", "0s");\r
2389           ele.setAttributeNS(null, "dur", "1s");\r
2390           ele.setAttributeNS(null, "repeatDur", "2s");\r
2391           ele.setAttributeNS(null, "attributeName", "d");\r
2392           ele.setAttributeNS(null, "fill", "freeze");\r
2393           ele.setAttributeNS(null, "from", "M20 0 L20 30");\r
2394           ele.setAttributeNS(null, "to", "M20 24 L20 30");\r
2395           $animate.init(ele);\r
2396           f(23, "M20.0 23.0 L20.0 30.0");\r
2397           f(24, "M20.0 0.0 L20.0 30.0");\r
2398           f(25, "M20.0 1.0 L20.0 30.0");\r
2399           f(48, "M20.0 24.0 L20.0 30.0");\r
2400 \r
2401           frame.timelines.length = 0;\r
2402           ele.setAttributeNS(null, "begin", "0s");\r
2403           ele.setAttributeNS(null, "dur", "2s");\r
2404           ele.setAttributeNS(null, "attributeName", "d");\r
2405           ele.setAttributeNS(null, "fill", "freeze");\r
2406           ele.setAttributeNS(null, "values", "M20 0 L20 30;M20 24 L20 30;M20 26.4 L20 30");\r
2407           $animate.init(ele);\r
2408           f(0, "M20.0 0.0 L20.0 30.0");\r
2409           f(1, "M20.0 1.0 L20.0 30.0");\r
2410           f(24, "M20.0 24.0 L20.0 30.0");\r
2411           f(25, "M20.0 24.1 L20.0 30.0");\r
2412           f(47, "M20.0 26.3 L20.0 30.0");\r
2413           f(48, "M20.0 26.4 L20.0 30.0");\r
2414           console.log($animate.timeline.$list);\r
2415           f(49, "M20.0 26.4 L20.0 30.0");\r
2416           console.log($animate.timeline.$list);\r
2417           f(50, "M20.0 26.4 L20.0 30.0");\r
2418           \r
2419           frame.timelines.length = 0;\r
2420           ele.setAttributeNS(null, "begin", "0s");\r
2421           ele.setAttributeNS(null, "end", "2s");\r
2422           ele.removeAttributeNS(null, "dur"); //単純継続時間が設定されていない場合\r
2423           ele.removeAttributeNS(null, "repeatDur");\r
2424           ele.setAttributeNS(null, "attributeName", "d");\r
2425           ele.setAttributeNS(null, "fill", "freeze");\r
2426           ele.setAttributeNS(null, "values", "M20 0 L20 30;M20 24 L20 30;M20 26.4 L20 30");\r
2427           $animate.init(ele);\r
2428           f(0, "M20.0 0.0 L20.0 30.0");\r
2429           f(1, "M20.0 0.0 L20.0 30.0");\r
2430           f(24, "M20.0 0.0 L20.0 30.0");\r
2431           f(25, "M20.0 0.0 L20.0 30.0");\r
2432           f(47, "M20.0 0.0 L20.0 30.0");\r
2433           f(48, "M20.0 0.0 L20.0 30.0");\r
2434           f(49, "M20.0 0.0 L20.0 30.0");\r
2435           f(50, "M20.0 0.0 L20.0 30.0");\r
2436           \r
2437           frame.timelines.length = 0;\r
2438           ele.setAttributeNS(null, "dur", "2s");\r
2439           ele.setAttributeNS(null, "fill", "remove");\r
2440           var attrValue = p.getAttributeNS(null, "d");\r
2441           $animate.init(ele);\r
2442           f(48, attrValue);\r
2443           \r
2444           frame.timelines.length = 0;\r
2445           p.removeAttributeNS(null, "d");\r
2446           ele.setAttributeNS(null, "fill", "freeze");\r
2447           ele.setAttributeNS(null, "keyTimes", "0;0.1;1");\r
2448           $animate.init(ele);\r
2449           f(1, "M20.0 5.0 L20.0 30.0");\r
2450           f(48, "M20.0 26.4 L20.0 30.0");\r
2451           \r
2452           frame.timelines.length = 0;\r
2453           ele.setAttributeNS(null, "fill", "freeze");\r
2454           ele.setAttributeNS(null, "calcMode", "discrete");\r
2455           ele.setAttributeNS(null, "keyTimes", "0;0.5;0.6");\r
2456           $animate.init(ele);\r
2457           f(1, "M20.0 0.0 L20.0 30.0");\r
2458           f(4, "M20.0 0.0 L20.0 30.0");\r
2459           /*本来は24フレーム目で、変化するはずだが、不具合があるため、そうならない\r
2460            * 修正の余地あり*/\r
2461           f(24, "M20.0 24.0 L20.0 30.0");\r
2462           f(25, "M20.0 24.0 L20.0 30.0");\r
2463           f(29, "M20.0 26.4 L20.0 30.0");\r
2464           f(48, "M20.0 26.4 L20.0 30.0");\r
2465           \r
2466           frame.timelines.length = 0;\r
2467           ele.setAttributeNS(null, "calcMode", "spline");\r
2468           ele.removeAttributeNS(null, "keyTimes");\r
2469           ele.setAttributeNS(null, "keySplines", "0,0,1,1;0,0,1,1;.75,0,0,.75");\r
2470           ele.removeAttributeNS(null, "end");\r
2471           ele.setAttributeNS(null, "dur", "9s");\r
2472           ele.setAttributeNS(null, "values", "210;177;121;10");\r
2473           $animate.init(ele);\r
2474           f(0, "210.0");\r
2475           f(72, "177.0");\r
2476           f(144, "121.0");\r
2477           f(216, "10.0");\r
2478           f(300, "10.0");\r
2479           \r
2480           frame.timelines.length = 0;\r
2481           ele.setAttributeNS(null, "calcMode", "spline");\r
2482           ele.setAttributeNS(null, "keyTimes", "0;.25;.5;1");\r
2483           ele.setAttributeNS(null, "keySplines", "0,0,1,1;0,0,1,1;1,0,0,1");\r
2484           ele.setAttributeNS(null, "dur", "8s");\r
2485           ele.setAttributeNS(null, "values", "300;255;180;30");\r
2486           $animate.init(ele);\r
2487           f(0, "300.0");\r
2488           f(48, "255.0");\r
2489           f(96, "180.0");\r
2490           f(192, "30.0");\r
2491           f(300, "30.0");\r
2492           \r
2493           /*開始時刻が未解決の場合*/\r
2494           frame.timelines.length = 0;\r
2495           ele.setAttributeNS(null, "begin", "click");\r
2496           ele.setAttributeNS(null, "calcMode", "spline");\r
2497           ele.setAttributeNS(null, "keyTimes", "0;.25;.5;1");\r
2498           ele.setAttributeNS(null, "keySplines", "0,0,1,1;0,0,1,1;1,0,0,1");\r
2499           ele.setAttributeNS(null, "dur", "8s");\r
2500           ele.setAttributeNS(null, "values", "300;255;180;30");\r
2501           ele.parentNode.setAttributeNS(null, "d", "300");\r
2502           $animate.init(ele);\r
2503           f(0, "300");\r
2504           f(48, "300");\r
2505           f(96, "300");\r
2506           f(192, "300");\r
2507           f(300, "300");\r
2508           \r
2509           ( function(attrName) {\r
2510             function g(fr, result) {\r
2511               frame.setFrame(fr);\r
2512               expect(p.style.getPropertyValue(attrName)).toBe(result);\r
2513             };\r
2514 \r
2515             frame.timelines.length = 0;\r
2516             ele.setAttributeNS(null, "begin", "0s");\r
2517             ele.setAttributeNS(null, "calcMode", "linear");\r
2518             ele.setAttributeNS(null, "attributeName", attrName);\r
2519             ele.setAttributeNS(null, "keyTimes", "0;.25;.5;1");\r
2520             ele.setAttributeNS(null, "keySplines", "0,0,1,1;0,0,1,1;1,0,0,1");\r
2521             ele.setAttributeNS(null, "dur", "8s");\r
2522             ele.setAttributeNS(null, "values", "inline;block;inline;block");\r
2523             $animate.init(ele);\r
2524             expect($animate.mode).toBe("discrete");\r
2525             g(0, "inline");\r
2526             g(48, "block");\r
2527             g(96, "inline");\r
2528             g(192, "block");\r
2529             g(300, "block");\r
2530             \r
2531             frame.timelines.length = 0;\r
2532             ele.setAttributeNS(null, "begin", "click");\r
2533             ele.setAttributeNS(null, "calcMode", "linear");\r
2534             ele.setAttributeNS(null, "attributeName", attrName);\r
2535             ele.setAttributeNS(null, "keyTimes", "0;.25;.5;1");\r
2536             ele.setAttributeNS(null, "keySplines", "0,0,1,1;0,0,1,1;1,0,0,1");\r
2537             ele.setAttributeNS(null, "dur", "8s");\r
2538             ele.setAttributeNS(null, "values", "inline;block;inline;block");\r
2539             $animate.init(ele);\r
2540             var evt = ele.ownerDocument.createEvent("MouseEvents");\r
2541             evt.initMouseEvent("click",true, true, window, 0, 0, 0, 0, 0, false, false, false, false,0, p);\r
2542             p.dispatchEvent(evt);\r
2543             var cur = base("$frame").currentFrame;\r
2544             expect($animate.mode).toBe("discrete");\r
2545             g(cur+0, "inline");\r
2546             g(cur+48, "block");\r
2547             g(cur+96, "inline");\r
2548             g(cur+192, "block");\r
2549             g(cur+300, "block");\r
2550           } )("display");\r
2551         } );\r
2552         /*無効同値クラスを調べておく (Equivalence partitioning, the following is the invalid partion)*/\r
2553         it("should be this for the value (the invalid partion )", function() {\r
2554           ele.setAttributeNS(null, "begin", "0s");\r
2555           ele.setAttributeNS(null, "dur", "100s");\r
2556           ele.setAttributeNS(null, "attributeName", "d");\r
2557           ele.setAttributeNS(null, "fill", "freeze");\r
2558           ele.setAttributeNS(null, "from", "M20 0 L20 30");\r
2559           ele.setAttributeNS(null, "to", "M20 2400 L20 30");\r
2560           ele.setAttributeNS(null, "keyTimes", "0;0.1;1");\r
2561           $animate.init(ele);\r
2562           \r
2563           var p = ele.parentNode;\r
2564           expect(p.getAttributeNS(null, "d") || null).toBeNull();\r
2565           \r
2566           function f(fr, result) {\r
2567             frame.setFrame(fr);\r
2568             expect(p.getAttributeNS(null, "d") || null).toBe(result);\r
2569           };\r
2570           f(0, null);\r
2571           f(1, null);\r
2572           \r
2573            frame.timelines.length = 0;\r
2574           /*keyTimes属性のリストの個数がvaluesリストと合致しない*/\r
2575           ele.setAttributeNS(null, "keyTimes", "0;0.1;0.5;1");\r
2576           ele.setAttributeNS(null, "values", "M20 0 L20 30;M20 24 L20 30;M20 26.4 L20 30");\r
2577           $animate.init(ele);\r
2578           f(0, null);\r
2579           f(1, null);\r
2580           \r
2581           /*keyTimes属性が0から始まっていない*/\r
2582           frame.timelines.length = 0;\r
2583           ele.setAttributeNS(null, "keyTimes", "0.1;0.3;1");\r
2584           ff("linear");\r
2585           ff("splines");\r
2586           ff("discrete");\r
2587           function ff(mode) {\r
2588             ele.setAttributeNS(null, "calcMode", mode);\r
2589             $animate.init(ele);\r
2590             f(0, null);\r
2591             f(1, null);\r
2592           }\r
2593           \r
2594           frame.timelines.length = 0;\r
2595           ele.setAttributeNS(null, "calcMode", "spline");\r
2596           $animate.init(ele);\r
2597           expect($animate.mode).toBe("spline");\r
2598           f(0, null);\r
2599           f(0.2, null);\r
2600           f(1, null); \r
2601         } );\r
2602       } );\r
2603       describe("RGB Color", function() {\r
2604         var $animate, ele, frame, f;\r
2605         beforeEach( function() {\r
2606           $animate = base("$calcMode").$attribute.$setElement.$animateElement.up();\r
2607           var p = document.createElementNS("http://www.w3.org/2000/svg", "g");\r
2608           ele = document.createElementNS("http://www.w3.org/2000/svg", "animate");\r
2609           p.appendChild(ele);\r
2610           frame = base("$frame");\r
2611           frame.timelines.length = 0;\r
2612           \r
2613           f = function (fr, result, attr) {\r
2614             frame.setFrame(fr);\r
2615             expect(p.style.getPropertyValue(attr).replace(/\s/g, "")).toBe(result.replace(/\s/g, ""));\r
2616           };\r
2617         } );\r
2618         /*境界条件を調べておく (limit value analysis)*/\r
2619         it("should be this for the value  (limit value analysis)", function() {\r
2620           ele.setAttributeNS(null, "begin", "0s");\r
2621           ele.setAttributeNS(null, "dur", "1s");\r
2622           ele.setAttributeNS(null, "attributeName", "fill");\r
2623           ele.setAttributeNS(null, "fill", "remove");\r
2624           ele.setAttributeNS(null, "from", "rgb(0, 0, 0)");\r
2625           ele.setAttributeNS(null, "to", "rgb(10, 10, 1)");\r
2626           $animate.init(ele);\r
2627           \r
2628           f(0, "rgb(0, 0, 0)", "fill");\r
2629           f(23, "rgb(10, 10, 1)", "fill");\r
2630           \r
2631           frame.timelines.length = 0;\r
2632           ele.setAttributeNS(null, "attributeName", "stroke");\r
2633           $animate.init(ele);\r
2634           f(0, "rgb(0, 0, 0)", "stroke");\r
2635           f(23, "rgb(10, 10, 1)", "stroke");\r
2636 \r
2637           frame.timelines.length = 0;\r
2638           ele.setAttributeNS(null, "attributeName", "stop-color");\r
2639           $animate.init(ele);\r
2640           f(0, "rgb(0,0,0)", "stop-color");\r
2641           f(23, "rgb(10,10,1)", "stop-color");\r
2642 \r
2643           frame.timelines.length = 0;\r
2644           ele.setAttributeNS(null, "attributeName", "color");\r
2645           $animate.init(ele);\r
2646           f(0, "rgb(0,0,0)", "color");\r
2647           f(23, "rgb(10,10,1)", "color");\r
2648         } );\r
2649         /*同値分割をして、有効同値クラスを調べておく (Equivalence partitioning, the following is the valid partion)*/\r
2650         it("should be this for the value (the valid partion )", function() {\r
2651           ele.setAttributeNS(null, "begin", "0s");\r
2652           ele.setAttributeNS(null, "dur", "1s");\r
2653           ele.setAttributeNS(null, "attributeName", "fill");\r
2654           ele.setAttributeNS(null, "fill", "remove");\r
2655           ele.setAttributeNS(null, "values", "rgb(0, 0, 0);rgb(24, 2.4, 1)");\r
2656           $animate.init(ele);\r
2657           \r
2658           f(0, "rgb(0, 0, 0)", "fill");\r
2659           f(1, "rgb(1, 0, 0)", "fill");\r
2660           f(23, "rgb(23, 2, 1)", "fill");\r
2661 \r
2662           frame.timelines.length = 0;\r
2663           ele.setAttributeNS(null, "values", "#00083C;#18203C");\r
2664           $animate.init(ele);\r
2665           /*rgb形式に変換*/\r
2666           \r
2667           f(0, "rgb(0, 8, 60)", "fill");\r
2668           f(1, "rgb(1, 9, 60)", "fill");\r
2669           f(23, "rgb(23, 31, 60)", "fill");\r
2670           \r
2671           frame.timelines.length = 0;\r
2672           ele.setAttributeNS(null, "fill", "freeze");\r
2673           ele.setAttributeNS(null, "values", "black;white");\r
2674           $animate.init(ele);\r
2675           /*色キーワードをrgb形式に変換*/\r
2676           \r
2677           f(0, "rgb(0, 0, 0)", "fill");\r
2678           f(12, "rgb(128, 128, 128)", "fill");\r
2679           f(24, "rgb(255, 255, 255)", "fill");\r
2680         } );\r
2681         /*無効同値クラスを調べておく (Equivalence partitioning, the following is the invalid partion)*/\r
2682         it("should be this for the value (the invalid partion )", function() {\r
2683           ele.setAttributeNS(null, "begin", "0s");\r
2684           ele.setAttributeNS(null, "dur", "1s");\r
2685           ele.setAttributeNS(null, "attributeName", "fi");\r
2686           ele.setAttributeNS(null, "fill", "remove");\r
2687           ele.setAttributeNS(null, "values", "#00083C;#00107C");\r
2688           $animate.init(ele);\r
2689           /*rgb形式に変換しない*/\r
2690           \r
2691           function f (fr, result, attr) {\r
2692             frame.setFrame(fr);\r
2693             expect(ele.parentNode.getAttributeNS(null,attr)).toBe(result);\r
2694           };\r
2695           f(0, "#83.0C", "fi");\r
2696           f(1, "#84.0C", "fi");\r
2697           f(23, "#106.0C", "fi");   \r
2698         } );\r
2699       } );\r
2700     describe("$frame.$svgEvent object", function() {\r
2701       var frame = base("$frame").$svgEvent,\r
2702           p, ele;\r
2703       base("$frame").pauseAnimation();\r
2704       beforeEach( function() {\r
2705         base("$frame").pauseAnimation();\r
2706         frame = frame.up().mix( {isResolved: true} );\r
2707         frame.first = null;\r
2708         /*firstプロパティとtimelinesプロパティは$frameオブジェクトのフレーム進行に\r
2709          * 影響を受けるため、新たに初期化しておく*/\r
2710         base("$frame").timelines = frame.timelines = [];\r
2711         frame.lastTimeLine = null;\r
2712         p = document.createElementNS("http://www.w3.org/2000/svg", "g");\r
2713         ele = document.createElementNS("http://www.w3.org/2000/svg", "animate");\r
2714         p.appendChild(ele);\r
2715       } );\r
2716       /*境界条件を調べておく (limit value analysis)*/\r
2717       it("should be this for the value  (limit value analysis)", function() {\r
2718         base("$frame").pauseAnimation();\r
2719         frame.lastTimeLine = null;\r
2720         expect(frame.lastTimeLine).toBeNull();\r
2721         expect(frame.first).toBeNull();\r
2722         frame.setTimeTable();\r
2723         expect(frame.first).toBeNull();\r
2724         frame.addLine( base("$frame").$begin.up().mix({\r
2725           isResolved: true,\r
2726           timelines: [],\r
2727           begin: 0,\r
2728           activeTime: 0,\r
2729           target: ele\r
2730         }) );\r
2731         frame.setTimeTable();\r
2732         expect(frame.first).toEqual(\r
2733           { frame: 0,\r
2734             eventType: "begin",\r
2735             target: ele,\r
2736           \r
2737             next: { frame: 0,\r
2738               eventType: "end",\r
2739               target: ele,\r
2740               next: null\r
2741             }\r
2742           }\r
2743         );\r
2744       } );\r
2745       /*同値分割をして、有効同値クラスを調べておく (Equivalence partitioning, the following is the valid partion)*/\r
2746       it("should be this for the value (the valid partion )", function() {\r
2747         base("$frame").pauseAnimation();\r
2748         frame.addLine( base("$frame").$begin.up().mix({\r
2749           isResolved: true,\r
2750           timelines: [],\r
2751           begin: 0,\r
2752           activeTime: 0,\r
2753           target: ele\r
2754         }) );\r
2755         frame.setTimeTable();\r
2756         frame.setTimeTable();\r
2757         expect(frame.first).toEqual(\r
2758           { frame: 0,\r
2759             eventType: "begin",\r
2760             target: ele,\r
2761           \r
2762             next: { frame: 0,\r
2763               eventType: "end",\r
2764               target: ele,\r
2765               next: null\r
2766             }\r
2767           }\r
2768         );\r
2769         frame.setTimeTable();\r
2770         frame.setTimeTable();\r
2771         expect(frame.first).toEqual(\r
2772           { frame: 0,\r
2773             eventType: "begin",\r
2774             target: ele,\r
2775           \r
2776             next: { frame: 0,\r
2777               eventType: "end",\r
2778               target: ele,\r
2779               next: null\r
2780             }\r
2781           }\r
2782         );\r
2783         \r
2784         var isFiredBeginEvent = false;\r
2785         ele.addEventListener("beginEvent", function(evt) {\r
2786           isFiredBeginEvent = true;\r
2787           expect(evt.target).toBe(ele);\r
2788         } );\r
2789         ele.addEventListener("endEvent", function(evt) {\r
2790           expect(evt.target).toBe(ele);\r
2791           expect(isFiredBeginEvent).toBeTruthy();\r
2792         } );\r
2793         frame.setFrame(0);\r
2794         expect(frame.first).toBeNull();\r
2795         frame.setFrame(0);\r
2796         expect(frame.first).toBeNull();\r
2797         \r
2798         frame.timelines = [];\r
2799         frame.addLine( base("$frame").$begin.up().mix({\r
2800           isResolved: true,\r
2801           timelines: [],\r
2802           begin: 0,\r
2803           activeTime: 10,\r
2804           target: ele\r
2805         }) );\r
2806         frame.setTimeTable();\r
2807         var a = { frame: 0,\r
2808             eventType: "begin",\r
2809             target: ele,\r
2810           \r
2811             next: { frame: 10,\r
2812               eventType: "end",\r
2813               target: ele,\r
2814               next: null\r
2815             }\r
2816           };\r
2817         expect(frame.first).toEqual(a);\r
2818         \r
2819         frame.addLine( base("$frame").$begin.up().mix({\r
2820           isResolved: true,\r
2821           timelines: [],\r
2822           begin: 1,\r
2823           simpleDuration: 9,\r
2824           activeTime: 11,\r
2825           target: ele\r
2826         }) );\r
2827         frame.setTimeTable();\r
2828         a.next.next = { frame: 1,\r
2829             eventType: "begin",\r
2830             target: ele,\r
2831           \r
2832             next: {\r
2833               frame: 10,\r
2834               eventType: "repeat",\r
2835               count: 1,\r
2836               target: ele,\r
2837             \r
2838               next: { frame: 12,\r
2839                 eventType: "end",\r
2840                 target: ele,\r
2841                 next: null\r
2842               }\r
2843             }\r
2844           };\r
2845         expect(frame.first).toEqual(a);\r
2846         frame.setFrame(11);\r
2847         expect(frame.first).toEqual( {frame: 12,\r
2848                 eventType: "end",\r
2849                 target: ele,\r
2850                 next: null\r
2851               } );\r
2852               \r
2853         frame.timelines = [];\r
2854         frame.first = null;\r
2855         frame.addLine( base("$frame").$begin.up().mix({\r
2856           isResolved: true,\r
2857           timelines: [],\r
2858           begin: 1,\r
2859           simpleDuration: 4,\r
2860           activeTime: 10,\r
2861           target: ele\r
2862         }) );\r
2863         frame.setTimeTable();\r
2864         a =  { frame: 1,\r
2865             eventType: "begin",\r
2866             target: ele,\r
2867           \r
2868             next: {\r
2869               frame: 5,\r
2870               eventType: "repeat",\r
2871               count: 1,\r
2872               target: ele,\r
2873             \r
2874               next: {\r
2875                 frame: 9,\r
2876                 eventType: "repeat",\r
2877                 count: 2,\r
2878                 target: ele,\r
2879               \r
2880                 next: { frame: 11,\r
2881                   eventType: "end",\r
2882                   target: ele,\r
2883                   next: null\r
2884                 }\r
2885               }\r
2886             }\r
2887           };\r
2888         expect(frame.first).toEqual(a);\r
2889         frame.setFrame(0);\r
2890         expect(frame.first).toEqual(a);\r
2891         frame.setFrame(1);\r
2892         a = a.next;\r
2893         expect(frame.first).toEqual(a);\r
2894         frame.setFrame(5);\r
2895         expect(frame.first).toEqual(a.next);\r
2896 \r
2897         ele.addEventListener("repeatEvent", function(evt) {\r
2898           expect(evt.target).toBe(ele);\r
2899         } );\r
2900         frame.timelines = [];\r
2901         frame.first = null;\r
2902         frame.addLine( base("$frame").$begin.up().mix({\r
2903           isResolved: true,\r
2904           timelines: [],\r
2905           begin: 1,\r
2906           simpleDuration: 4,\r
2907           activeTime: 15,\r
2908           target: ele\r
2909         }) );\r
2910         frame.setFrame(9);\r
2911         expect(frame.first).toEqual({\r
2912                 frame: 13,\r
2913                 eventType: "repeat",\r
2914                 count: 3,\r
2915                 target: ele,\r
2916               \r
2917                 next: { frame: 16,\r
2918                   eventType: "end",\r
2919                   target: ele,\r
2920                   next: null\r
2921                 }\r
2922               } );\r
2923       } );\r
2924       afterEach( function() {\r
2925         base("$frame").startAnimation();\r
2926       } );\r
2927     } );\r
2928     describe("A $animateTransformElemenet object", function() {\r
2929       describe("An init method", function() {\r
2930         var $animate, ele, frame, p;\r
2931         beforeEach( function() {\r
2932           $animate = base("$calcMode").$attribute.$setElement.$animateElement.$animateTransformElement.up();\r
2933           /*ここでは、データ量を削るため、degitsプロパティを小数点以下1桁に設定*/\r
2934           $animate.degits = 1;\r
2935           p = document.createElementNS("http://www.w3.org/2000/svg", "g");\r
2936           ele = document.createElementNS("http://www.w3.org/2000/svg", "animateTransform");\r
2937           p.appendChild(ele);\r
2938           frame = base("$frame");\r
2939           frame.timelines.length = 0;\r
2940           frame.startTime = Date.now();\r
2941           frame.setFrame(0);\r
2942         } );\r
2943         afterEach( function() {\r
2944           $animate.numberOfList = -1;\r
2945         } );\r
2946         /*境界条件を調べておく (limit value analysis)*/\r
2947         it("should be this for the value  (limit value analysis)", function() {\r
2948           expect($animate.numberOfList).toBe(-1);\r
2949           expect($animate.type).toBe("translate");\r
2950           expect(p.__transformList).toBeUndefined();\r
2951           expect($animate.isCSS).toBeFalsy();\r
2952           expect($animate.isSum).toBeFalsy();\r
2953           expect($animate.attrName).toBe("transform");\r
2954           \r
2955           $animate.init();\r
2956           expect($animate.numberOfList).toBe(-1);\r
2957           expect(p.__transformList).toBeUndefined();\r
2958           expect($animate.isCSS).toBeFalsy();\r
2959           expect($animate.type).toBe("translate");\r
2960           expect($animate.attrName).toBe("transform");\r
2961           \r
2962           $animate.init(p);\r
2963           expect($animate.numberOfList).toBe(-1);\r
2964           expect(p.__transformList).toBeUndefined();\r
2965           expect($animate.isCSS).toBeFalsy();\r
2966           expect($animate.type).toBe("translate");\r
2967           expect($animate.attrName).toBe("transform");\r
2968           \r
2969           $animate.init(ele);\r
2970           expect($animate.numberOfList).toBe(-1);\r
2971           expect(p.__transformList).toEqual([]);\r
2972           expect($animate.isCSS).toBeFalsy();\r
2973           expect($animate.type).toBe("translate");\r
2974           expect($animate.attrName).toBe("transform");\r
2975           \r
2976           ele.setAttributeNS(null, "values", "0;1");\r
2977           ele.setAttributeNS(null, "attributeName", "");\r
2978           $animate.init(ele);\r
2979           expect($animate.isCSS).toBeFalsy();\r
2980           expect($animate.type).toBe("translate");\r
2981           expect($animate.type).toBe("translate");\r
2982           expect($animate.numberOfList).toBe(0);\r
2983           expect(p.__transformList).toEqual([ {isPlaying: false,\r
2984                                                value: "translate(0)",\r
2985                                                isSum: false,\r
2986                                                isRemove: true\r
2987                                               } ]);\r
2988           \r
2989           ele.setAttributeNS(null, "type", "translate");\r
2990           $animate.init(ele);\r
2991           expect($animate.numberOfList).toBe(0);\r
2992           expect($animate.isCSS).toBeFalsy();\r
2993           expect($animate.type).toBe("translate");\r
2994           expect(p.__transformList).toEqual([ {isPlaying: false,\r
2995                                                value: "translate(0)",\r
2996                                                isSum: false,\r
2997                                                isRemove: true\r
2998                                               } ]);\r
2999           $animate.tocall(0);\r
3000           expect(p.__transformList[0].isPlaying).toBeTruthy();\r
3001           \r
3002           ele.parentNode.appendChild(ele.cloneNode(true));\r
3003           $animate.numberOfList = -1;\r
3004           $animate.init(ele.parentNode.lastChild);\r
3005           expect($animate.numberOfList).toBe(1);\r
3006           expect(p.__transformList[0].isPlaying).toBeTruthy();\r
3007           expect(p.__transformList[1].isPlaying).toBeFalsy();\r
3008 \r
3009           expect($animate.type).toBe("translate");\r
3010           $animate.tocall(0);\r
3011           expect(p.__transformList[0].isPlaying).toBeTruthy();\r
3012           expect(p.__transformList[1].isPlaying).toBeTruthy();\r
3013           $animate._setEndFrame(1);\r
3014           expect(p.__transformList[0].isPlaying).toBeTruthy();\r
3015           expect(p.__transformList[1].isPlaying).toBeFalsy();\r
3016           \r
3017           delete p.__transformList;\r
3018           ele.setAttributeNS(null, "type", "scale");\r
3019           $animate.numberOfList = -1;\r
3020           $animate.init(ele);\r
3021           expect($animate.numberOfList).toBe(0);\r
3022           expect(p.__transformList).toEqual([ {isPlaying: false,\r
3023                                                value: "translate(0)",\r
3024                                                isSum: false,\r
3025                                                isRemove: true\r
3026                                               } ]);\r
3027           expect($animate.type).toBe("scale");\r
3028 \r
3029           delete p.__transformList;\r
3030           $animate.numberOfList = -1;\r
3031           ele.setAttributeNS(null, "additive", "sum");\r
3032           ele.setAttributeNS(null, "fill", "freeze");\r
3033           $animate.init(ele);\r
3034           expect($animate.isSum).toBeTruthy();\r
3035           expect(p.__transformList).toEqual([ {isPlaying: false,\r
3036                                                value: "translate(0)",\r
3037                                                isSum: true,\r
3038                                                isRemove: false\r
3039                                               } ]);\r
3040           delete p.__transformList;\r
3041           $animate.numberOfList = -1;\r
3042           ele.setAttributeNS(null, "additive", "replace");\r
3043           ele.setAttributeNS(null, "fill", "remove");\r
3044           $animate.init(ele);\r
3045           expect(p.__transformList).toEqual([ {isPlaying: false,\r
3046                                                value: "translate(0)",\r
3047                                                isSum: false,\r
3048                                                isRemove: true\r
3049                                               } ]);\r
3050         } );\r
3051         /*同値分割をして、有効同値クラスを調べておく (Equivalence partitioning, the following is the valid partion)*/\r
3052         it("should be this for the value (the valid partion )", function() {\r
3053           ele.setAttributeNS(null, "type", "scale");\r
3054           ele.setAttributeNS(null, "values", "0;1");\r
3055           $animate.init(ele);\r
3056           expect($animate.isCSS).toBeFalsy();\r
3057           expect($animate.numberOfList).toBe(0);\r
3058           expect($animate.tocall(0)).toBe("scale(0.0)");\r
3059           expect($animate.tocall(0.5)).toBe("scale(0.5)");\r
3060           expect($animate.tocall(0.9)).toBe("scale(0.9)");\r
3061           expect($animate.tocall(1)).toBe("scale(1.0)");\r
3062 \r
3063           ele.parentNode.appendChild(ele.cloneNode(true));\r
3064           $animate.numberOfList = -1;\r
3065           $animate.init(ele.parentNode.lastChild);\r
3066           expect($animate.numberOfList).toBe(1);\r
3067           expect($animate.tocall(0)).toBe("scale(0.0)");\r
3068           expect($animate.tocall(1)).toBe("scale(1.0)");\r
3069           \r
3070           ele.parentNode.appendChild(ele.cloneNode(true));\r
3071           $animate.up("$a").numberOfList = -1;\r
3072           ele.parentNode.setAttribute("transform", "matrix(0 0 0 0 0 0)");\r
3073           $animate.$a.init(ele.parentNode.lastChild);\r
3074           expect($animate.$a.numberOfList).toBe(2);\r
3075           expect($animate.$a.isDefault).toBeTruthy();\r
3076           expect($animate.$a.defaultValue).toBe("matrix(0 0 0 0 0 0)");\r
3077           expect($animate.$a.tocall(0)).toBe("scale(0.0)");\r
3078           expect($animate.$a.tocall(1)).toBe("scale(1.0)");\r
3079           $animate.defaultValue = $animate.$a.defaultValue;\r
3080           expect($animate.$a.tocall(0.1)).toBe("scale(0.1)");\r
3081           \r
3082           ele.setAttributeNS(null, "additive", "sum");\r
3083           var parentNode = ele.parentNode;\r
3084           parentNode.appendChild(ele.cloneNode(true));\r
3085           parentNode.__transformList = [];\r
3086           /*additive属性のsumとreplaceの混合を避けるため、eleを削除*/\r
3087           parentNode.removeChild(ele);\r
3088           $animate.numberOfList = -1;\r
3089           $animate.init(parentNode.lastChild);\r
3090           expect($animate.numberOfList).toBe(0);\r
3091           expect($animate.tocall(0)).toBe("matrix(0 0 0 0 0 0) scale(0.0)");\r
3092           expect($animate.tocall(1)).toBe("matrix(0 0 0 0 0 0) scale(1.0)");\r
3093           \r
3094           parentNode.appendChild(ele.cloneNode(true));\r
3095           $animate.up("$a").numberOfList = -1;\r
3096           parentNode.__transformList = [];\r
3097           parentNode.setAttribute("transform", "matrix(0 0 0 0 0 0)");\r
3098           $animate.$a.init(parentNode.lastChild);\r
3099           expect($animate.$a.numberOfList).toBe(0);\r
3100           expect($animate.$a.isDefault).toBeTruthy();\r
3101           expect($animate.$a.defaultValue).toBe("matrix(0 0 0 0 0 0)");\r
3102           expect($animate.$a.tocall(0)).toBe("matrix(0 0 0 0 0 0) scale(0.0)");\r
3103           expect($animate.$a.tocall(1)).toBe("matrix(0 0 0 0 0 0) scale(1.0)");\r
3104           $animate.defaultValue = $animate.$a.defaultValue;\r
3105           expect($animate.tocall(0.1)).toBe("matrix(0 0 0 0 0 0) scale(0.1)");\r
3106           \r
3107           ele.removeAttributeNS(null, "additive");\r
3108           ad("replace", "sum", "scale(0.0) translate(0)", "scale(0.0) scale(0.0)",\r
3109            "scale(1.0) scale(0.0)", "scale(1.0) scale(1.0)");\r
3110           ad("sum", "replace", "matrix(0 0 0 0 0 0) scale(0.0)", "scale(0.0)",\r
3111            "scale(0.0)", "scale(1.0)");\r
3112           function ad(first, second, a, b, c, d) {\r
3113             /*子要素を全部消す*/\r
3114             while (parentNode.firstChild) {\r
3115               parentNode.removeChild(parentNode.firstChild);\r
3116             }\r
3117             \r
3118             /*additive属性のreplaceとsumの混合*/\r
3119             ele.setAttributeNS(null, "additive", first);\r
3120             parentNode.appendChild(ele.cloneNode(true));\r
3121             ele.setAttributeNS(null, "additive", second);\r
3122             parentNode.appendChild(ele.cloneNode(true));\r
3123             parentNode.__transformList = [];\r
3124             $animate.numberOfList = -1;\r
3125             parentNode.setAttribute("transform", "matrix(0 0 0 0 0 0)");\r
3126             $animate.up("$first").init(parentNode.firstChild);\r
3127             $animate.up("$second").init(parentNode.lastChild);\r
3128             expect($animate.$first.numberOfList).toBe(0);\r
3129             expect($animate.$second.numberOfList).toBe(1);\r
3130             expect($animate.$first.tocall(0)).toBe(a);\r
3131             expect($animate.$second.tocall(0)).toBe(b);\r
3132             expect($animate.$first.tocall(1)).toBe(c);\r
3133             expect($animate.$second.tocall(1)).toBe(d);\r
3134           };\r
3135         } );\r
3136         /*無効同値クラスを調べておく (Equivalence partitioning, the following is the invalid partion)*/\r
3137         it("should be this for the value (the invalid partion )", function() {\r
3138           $animate.init(ele);\r
3139           ele.parentNode.__transformList = null;\r
3140           expect( function () {\r
3141             $animate.tocall(0);\r
3142           } ).toThrow();\r
3143           \r
3144           $animate.numberOfList = -1;\r
3145           $animate.init(ele);\r
3146           $animate.numberOfList = -1;\r
3147           expect( function () {\r
3148             $animate.tocall(0);\r
3149           } ).toThrow();\r
3150         } );\r
3151       } );\r
3152     } );\r
3153     describe("A $motionElement object", function() {\r
3154       describe("An init method", function() {\r
3155         var $animate, ele, frame, p;\r
3156         beforeEach( function() {\r
3157           $animate = base("$calcMode").$attribute.$setElement.$animateElement.$animateTransformElement.$motionElement.up();\r
3158           /*ここでは、データ量を削るため、degitsプロパティを小数点以下1桁に設定*/\r
3159           $animate.degits = 1;\r
3160           p = document.createElementNS("http://www.w3.org/2000/svg", "g");\r
3161           ele = document.createElementNS("http://www.w3.org/2000/svg", "animateMotion");\r
3162           p.appendChild(ele);\r
3163           frame = base("$frame");\r
3164           frame.timelines.length = 0;\r
3165           frame.startTime = Date.now();\r
3166           frame.setFrame(0);\r
3167         } );\r
3168         afterEach( function() {\r
3169           $animate.numberOfList = -1;\r
3170           delete $animate.element;\r
3171           p.__transformList = null;\r
3172         } );\r
3173         /*境界条件を調べておく (limit value analysis)*/\r
3174         it("should be this for the value  (limit value analysis)", function() {\r
3175           expect($animate.type).toBe("translate");\r
3176           expect($animate.mode).toBe("paced");\r
3177           ele.setAttributeNS(null, "type", "scale");\r
3178           expect($animate.rotate).toBe("0");\r
3179           $animate.init(ele);\r
3180           expect($animate.type).toBe("translate");\r
3181           expect($animate.mode).toBe("paced");\r
3182           expect($animate.rotate).toBe("0");\r
3183           \r
3184           ele.setAttributeNS(null, "values", "0,0;1,0");\r
3185           $animate.up("$a").init(ele);\r
3186           expect($animate.$a.tocall(0)).toBe("translate(0.0,0.0)");\r
3187           expect($animate.$a.tocall(0.5)).toBe("translate(0.5,0.0)");\r
3188           expect($animate.$a.tocall(1)).toBe("translate(1.0,0.0)");\r
3189           \r
3190           var ec = ele.cloneNode(true);\r
3191           p.appendChild(ec);\r
3192           ec.removeAttributeNS(null, "values");\r
3193           ec.setAttributeNS(null, "from", "0,0");\r
3194           ec.setAttributeNS(null, "to", "1,0");\r
3195           $animate.up("$a").init(ec);\r
3196           expect($animate.$a.tocall(0)).toBe("translate(0.0,0.0)");\r
3197           expect($animate.$a.tocall(0.5)).toBe("translate(0.5,0.0)");\r
3198           expect($animate.$a.tocall(1)).toBe("translate(1.0,0.0)");\r
3199         } );\r
3200         /*無効同値クラスを調べておく (Equivalence partitioning, the following is the invalid partion)*/\r
3201         it("should be this for the value (the invalid partion )", function() {\r
3202           $animate.init();\r
3203         } );\r
3204       } );\r
3205       describe("A hasAttrValues method", function() {\r
3206         var $animate, ele, frame, p;\r
3207         beforeEach( function() {\r
3208           $animate = base("$calcMode").$attribute.$setElement.$animateElement.$animateTransformElement.$motionElement.up();\r
3209           /*ここでは、データ量を削るため、degitsプロパティを小数点以下1桁に設定*/\r
3210           $animate.degits = 1;\r
3211           p = document.createElementNS("http://www.w3.org/2000/svg", "g");\r
3212           ele = document.createElementNS("http://www.w3.org/2000/svg", "animateMotion");\r
3213           p.appendChild(ele);\r
3214           frame = base("$frame");\r
3215           frame.timelines.length = 0;\r
3216           frame.startTime = Date.now();\r
3217           frame.setFrame(0);\r
3218         } );\r
3219         afterEach( function() {\r
3220           $animate.numberOfList = -1;\r
3221           delete $animate.element;\r
3222           p.__transformList = null;\r
3223         } );\r
3224         /*境界条件を調べておく (limit value analysis)*/\r
3225         it("should be this for the value  (limit value analysis)", function() {\r
3226                     \r
3227           expect($animate.up("$a").hasAttrValues()).toBeFalsy();\r
3228           $animate.up("$a").init(ele);\r
3229           expect($animate.$a.hasAttrValues()).toBeFalsy();\r
3230           \r
3231           ele.setAttributeNS(null, "path", "M");\r
3232           expect($animate.$a.hasAttrValues()).toBeTruthy();\r
3233           $animate.$animateTransformElement.up("$b").init(ele);\r
3234           expect($animate.$animateTransformElement.$b.hasAttrValues()).toBeFalsy();\r
3235         } );\r
3236       } );\r
3237     } );\r
3238     describe("Event", function() {\r
3239       var $animate, ele, frame, p;\r
3240       beforeEach( function() {\r
3241         \r
3242         $animate = base("$calcMode").$attribute.$setElement.$animateElement.up();\r
3243         p = document.createElementNS("http://www.w3.org/2000/svg", "g");\r
3244         ele = document.createElementNS("http://www.w3.org/2000/svg", "animate");\r
3245         p.appendChild(ele);\r
3246         frame = base("$frame");\r
3247         frame.pauseAnimation();\r
3248         frame.timelines.length = 0; //配列の初期化\r
3249         frame.setFrame(0);\r
3250       } );\r
3251       /*境界条件を調べておく (limit value analysis)*/\r
3252       it("should be this for the value  (limit value analysis)", function() {\r
3253         ele.addEventListener("beginEvent", function(evt) {\r
3254           expect(evt.target).toBe(ele);\r
3255         } );\r
3256         var evt = ele.ownerDocument.createEvent("MouseEvents");\r
3257         evt.initMouseEvent("beginEvent",true, true, window, 0, 0, 0, 0, 0, false, false, false, false,0, ele);\r
3258         ele.dispatchEvent(evt);\r
3259         \r
3260         ele.setAttributeNS(null, "begin", "mousedown");\r
3261         ele.setAttributeNS(null, "dur", "1s");\r
3262         ele.setAttributeNS(null, "attributeName", "fill");\r
3263         ele.setAttributeNS(null, "fill", "freeze");\r
3264         ele.setAttributeNS(null, "from", "rgb(0,0,0)");\r
3265         ele.setAttributeNS(null, "to", "rgb(10,10,1)");\r
3266         $animate.init(ele);\r
3267         $animate.isCSS = false;\r
3268         expect(p.getAttributeNS(null, "fill") || null).toBeNull();\r
3269         evt = ele.ownerDocument.createEvent("MouseEvents");\r
3270         evt.initMouseEvent("beginEvent",true, true, window, 0, 0, 0, 0, 0, false, false, false, false,0, ele);\r
3271         p.dispatchEvent(evt);\r
3272         expect(p.getAttributeNS(null, "fill") || null).toBeNull();\r
3273         \r
3274         evt = ele.ownerDocument.createEvent("MouseEvents");\r
3275         evt.initMouseEvent("mousedown",true, true, window, 0, 0, 0, 0, 0, false, false, false, false,0, p);\r
3276         frame.setFrame(frame.currentFrame);\r
3277         expect($animate.isEnd).toBeFalsy();\r
3278         p.dispatchEvent(evt);\r
3279         frame.setFrame(frame.currentFrame + 1);\r
3280         frame.setFrame(frame.currentFrame + 24);\r
3281         expect(evt.target.getAttributeNS(null, "fill") || null).toBe("rgb(10, 10, 1)");\r
3282       } );\r
3283     } );\r
3284       describe("a beginElement method and an endElement method", function() {\r
3285         var $animate, ele, frame, p;\r
3286         beforeEach( function() {\r
3287           $animate = base("$calcMode").$attribute.$setElement.$animateElement.up();\r
3288           p = document.createElementNS("http://www.w3.org/2000/svg", "g");\r
3289           ele = document.createElementNS("http://www.w3.org/2000/svg", "animate");\r
3290           p.appendChild(ele);\r
3291           frame = base("$frame");\r
3292           frame.timelines.length = 0; //配列の初期化\r
3293           frame.setFrame(0);\r
3294           ele.setAttributeNS(null, "begin", "indefinite");\r
3295           ele.setAttributeNS(null, "dur", "1s");\r
3296           ele.setAttributeNS(null, "dur", "1s");\r
3297           ele.setAttributeNS(null, "attributeName", "fill");\r
3298           ele.setAttributeNS(null, "fill", "freeze");\r
3299           ele.setAttributeNS(null, "from", "rgb(0,0,0)");\r
3300           ele.setAttributeNS(null, "to", "rgb(10,10,1)");\r
3301           $animate.init(ele);\r
3302         } );\r
3303         /*境界条件を調べておく (limit value analysis)*/\r
3304         it("should be this for the value  (limit value analysis)", function() {\r
3305           expect(ele.beginElement()).toBeUndefined();\r
3306           var cur = frame.currentFrame,\r
3307               begin = frame.$begin.$1;\r
3308           expect(begin.string).toBe("indefinite");\r
3309           expect(begin.begin).toBe(cur);\r
3310           expect(ele.endElement()).toBeUndefined();\r
3311         } );\r
3312         /*同値分割をして、有効同値クラスを調べておく (Equivalence partitioning, the following is the valid partion)*/\r
3313         it("should be this for the value (the valid partion )", function() {\r
3314           ele.addEventListener("beginEvent", function(evt){\r
3315             expect(evt.target.nodeName).toBe("animate");\r
3316           }, false );\r
3317           ele.beginElement();\r
3318         } );\r
3319       });\r
3320     } );\r
3321 } );\r