OSDN Git Service

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