OSDN Git Service

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