OSDN Git Service

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