OSDN Git Service

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