OSDN Git Service

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