OSDN Git Service

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