OSDN Git Service

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