OSDN Git Service

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