OSDN Git Service

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