1 /*SIE under the MIT Lisence
\r
2 *公式ページは http://sie.osdn.jp/
\r
5 *Copyright (c) 2008-2010 Pivotal Labs
\r
7 Permission is hereby granted, free of charge, to any person obtaining
\r
8 a copy of this software and associated documentation files (the
\r
9 "Software"), to deal in the Software without restriction, including
\r
10 without limitation the rights to use, copy, modify, merge, publish,
\r
11 distribute, sublicense, and/or sell copies of the Software, and to
\r
12 permit persons to whom the Software is furnished to do so, subject to
\r
13 the following conditions:
\r
15 The above copyright notice and this permission notice shall be
\r
16 included in all copies or substantial portions of the Software.
\r
18 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
\r
19 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
\r
20 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
\r
21 NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
\r
22 LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
\r
23 OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
\r
24 WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
\r
27 describe("SMIL Animation Spec", function() {
\r
28 describe("$frame object", function() {
\r
29 var frame = base("$frame");
\r
30 beforeEach( function() {
\r
31 frame.timelines = [];
\r
32 frame.isPaused = false;
\r
34 afterEach( function() {
\r
35 frame.timelines = [];
\r
37 /*境界条件を調べておく (limit value analysis)*/
\r
38 it("should be this for the value (limit value analysis)", function() {
\r
39 expect(typeof frame.setFrame).toBe("function");
\r
40 expect(frame.timelines.length).toBe(0);
\r
41 expect(frame.isBegin).toBeFalsy();
\r
42 expect(frame.startAnimation()).toBeUndefined();
\r
48 expect(frame.addLine()).toBe(false);
\r
49 expect(frame.addLine({})).toBe(false);
\r
50 expect(frame.addLine({
\r
53 expect(frame.addLine({
\r
57 expect(frame.removeLine()).toBeUndefined();
\r
58 expect(frame.removeLine({})).toBeUndefined();
\r
61 expect(frame.currentFrame).toBe(0);
\r
63 expect(frame.currentFrame).toBe(1);
\r
65 expect(frame.isPaused).toBeFalsy();
\r
66 expect(frame.pauseAnimation()).toBeUndefined();
\r
67 expect(frame.isPaused).toBeTruthy();
\r
70 /*同値分割をして、有効同値クラスを調べておく (Equivalence partitioning, the following is the valid partion)*/
\r
71 it("should be this for the value (the valid partion)", function() {
\r
73 expect(frame.currentFrame).toBe(0);
\r
74 frame.startTime = Date.now();
\r
75 for (var i=0;i<100000;i++) {
\r
79 expect(frame.begin).toBe(0);
\r
80 expect(frame.activeTime).toBe(Number.MAX_VALUE);
\r
86 expect(frame.addLine( {
\r
90 expect(frame.addLine( {
\r
94 expect(frame.addLine( {
\r
98 expect(frame.addLine( {
\r
103 expect(frame.timelines.length).toBe(1);
\r
104 var timeline = frame.timelines[0];
\r
105 expect(timeline.begin).toBe(0);
\r
106 expect(timeline.activeTime).toBe(0);
\r
108 expect(frame.timelines[0]).toBe(timeline);
\r
109 frame.addLine({begin:1, activeTime:1});
\r
110 expect(frame.timelines[1]).not.toBe(timeline);
\r
111 frame.addLine(timeline);
\r
112 expect(frame.timelines[0]).not.toBe(timeline);
\r
113 expect(frame.timelines[1]).toBe(timeline);
\r
115 timeline = frame.timelines[0];
\r
116 frame.removeLine({});
\r
117 expect(frame.timelines[0]).toBe(timeline);
\r
118 frame.removeLine(timeline);
\r
119 expect(frame.timelines[0]).not.toBe(timeline);
\r
121 frame.addLine(frame.up().mix( {
\r
124 expect(frame.timelines).not.toBe(frame.$1.timelines);
\r
126 frame.timelines.length = 0;
\r
139 expect(frame.timelines[2].activeTime).toBe(2);
\r
141 /*無効同値クラスを調べておく (Equivalence partitioning, the following is the invalid partion)*/
\r
142 it("should be this for the value (the invalid partion)", function() {
\r
143 expect(frame.addLine(12)).toBeFalsy();
\r
144 /*循環参照にならず、スタック領域不足にならない*/
\r
145 frame.addLine(frame);
\r
149 describe("the $frame.$list object", function() {
\r
150 var frame = base("$frame").$list.up("$2");
\r
151 beforeEach( function() {
\r
152 frame.timelines = [];
\r
153 frame.isPaused = false;
\r
154 frame.state = frame.WAITING;
\r
157 afterEach( function() {
\r
158 frame.timelines = [];
\r
160 /*境界条件を調べておく (limit value analysis)*/
\r
161 it("should be this for the value (limit value analysis)", function() {
\r
163 expect(frame.WAITING).toBe(0);
\r
164 expect(frame.BEGINNING).toBe(1);
\r
165 expect(frame.PLAYING).toBe(2);
\r
166 expect(frame.ENDING).toBe(3);
\r
167 expect(frame.POSTWAITING).toBe(4);
\r
168 expect(frame.state).toBe(frame.WAITING);
\r
170 expect(frame.beginList).toEqual({
\r
172 value: Number.MAX_VALUE
\r
174 expect(frame.endList).toEqual({
\r
176 value: Number.MAX_VALUE
\r
179 expect(typeof frame.getMaxList).toBe("function");
\r
181 expect(typeof frame.updateState).toBe("function");
\r
182 expect(frame.updateState(0).state).toBe(frame.WAITING);
\r
183 expect(frame.state).toBe(frame.WAITING);
\r
184 expect(frame.updateState(0).state).toBe(frame.WAITING);
\r
185 expect(frame.state).toBe(frame.WAITING);
\r
186 expect(frame.updateState(0).state).toBe(frame.WAITING);
\r
187 expect(frame.state).toBe(frame.WAITING);
\r
188 expect(frame.updateState(0).state).toBe(frame.WAITING);
\r
189 expect(frame.state).toBe(frame.WAITING);
\r
192 expect(frame.updateState(0).state).toBe(frame.BEGINNING);
\r
193 expect(frame.state).toBe(frame.BEGINNING);
\r
194 expect(frame.updateState().state).toBe(frame.BEGINNING);
\r
195 expect(frame.state).toBe(frame.BEGINNING);
\r
197 expect(frame.beginList).toEqual({
\r
199 value: Number.MAX_VALUE
\r
201 expect(frame.endList).toEqual({
\r
203 value: Number.MAX_VALUE
\r
206 expect(frame.getMaxList(0, frame.beginList)).toBe(-1);
\r
207 expect(frame.getMaxList(0, frame.endList)).toBe(-1);
\r
209 /*同値分割をして、有効同値クラスを調べておく (Equivalence partitioning, the following is the valid partion)*/
\r
210 it("should be this for the value (the valid partion)", function() {
\r
212 function appendBegin(num) {
\r
213 frame.state = frame.WAITING;
\r
214 frame.beginList = {
\r
216 next: frame.beginList
\r
220 expect(frame.getMaxList(0, frame.beginList)).toBe(0);
\r
221 expect(frame.updateState(0).state).toBe(frame.BEGINNING);
\r
222 expect(frame.begin).toBe(0);
\r
223 expect(frame.updateState(0).state).toBe(frame.PLAYING);
\r
224 expect(frame.state).toBe(frame.PLAYING);
\r
225 expect(frame.updateState(0).state).toBe(frame.PLAYING);
\r
226 expect(frame.state).toBe(frame.PLAYING);
\r
228 frame.state = frame.WAITING;
\r
229 expect(frame.getMaxList(0, frame.beginList)).toBe(0);
\r
230 expect(frame.updateState(0).state).toBe(frame.BEGINNING);
\r
231 expect(frame.state).toBe(frame.BEGINNING);
\r
232 expect(frame.updateState(1).state).toBe(frame.PLAYING);
\r
233 expect(frame.state).toBe(frame.PLAYING);
\r
234 expect(frame.updateState(2).state).toBe(frame.PLAYING);
\r
235 expect(frame.state).toBe(frame.PLAYING);
\r
236 expect(frame.updateState(3).state).toBe(frame.PLAYING);
\r
237 expect(frame.state).toBe(frame.PLAYING);
\r
238 expect(frame.updateState(4).state).toBe(frame.PLAYING);
\r
239 expect(frame.state).toBe(frame.PLAYING);
\r
242 expect(frame.getMaxList(1, frame.beginList)).toBe(1);
\r
243 expect(frame.updateState(0).state).toBe(frame.BEGINNING);
\r
244 expect(frame.updateState(0).state).toBe(frame.PLAYING);
\r
245 expect(frame.updateState(0).state).toBe(frame.PLAYING);
\r
246 expect(frame.updateState(1).state).toBe(frame.ENDING);
\r
247 expect(frame.updateState(1).state).toBe(frame.BEGINNING);
\r
248 expect(frame.state).toBe(frame.BEGINNING);
\r
249 expect(frame.updateState(1).state).toBe(frame.PLAYING);
\r
250 expect(frame.state).toBe(frame.PLAYING);
\r
251 expect(frame.updateState(1).state).toBe(frame.PLAYING);
\r
252 expect(frame.state).toBe(frame.PLAYING);
\r
253 expect(frame.updateState(2).state).toBe(frame.PLAYING);
\r
256 frame.state = frame.WAITING;
\r
257 expect(frame.updateState(0).state).toBe(frame.BEGINNING);
\r
258 expect(frame.begin).toBe(0);
\r
259 expect(frame.updateState(0).state).toBe(frame.PLAYING);
\r
260 expect(frame.updateState(0).state).toBe(frame.PLAYING);
\r
261 expect(frame.begin).toBe(0);
\r
262 expect(frame.updateState(1).state).toBe(frame.ENDING);
\r
263 expect(frame.updateState(1).state).toBe(frame.BEGINNING);
\r
264 expect(frame.begin).toBe(1);
\r
265 expect(frame.updateState(1).state).toBe(frame.PLAYING);
\r
266 expect(frame.updateState(1).state).toBe(frame.PLAYING);
\r
268 function appendEnd(num) {
\r
269 frame.state = frame.WAITING;
\r
273 next: frame.endList
\r
277 expect(frame.updateState(1).state).toBe(frame.BEGINNING);
\r
278 expect(frame.state).toBe(frame.BEGINNING);
\r
279 expect(frame.updateState(2).state).toBe(frame.PLAYING);
\r
280 expect(frame.updateState(2).state).toBe(frame.PLAYING);
\r
281 expect(frame.state).toBe(frame.PLAYING);
\r
282 expect(frame.updateState(3).state).toBe(frame.ENDING);
\r
283 expect(frame.state).toBe(frame.ENDING);
\r
284 expect(frame.updateState(4).state).toBe(frame.POSTWAITING);
\r
285 expect(frame.state).toBe(frame.POSTWAITING);
\r
288 expect(frame.updateState(1).state).toBe(frame.BEGINNING);
\r
289 expect(frame.state).toBe(frame.BEGINNING);
\r
290 expect(frame.updateState(2).state).toBe(frame.PLAYING);
\r
291 expect(frame.updateState(2).state).toBe(frame.PLAYING);
\r
292 expect(frame.state).toBe(frame.PLAYING);
\r
293 expect(frame.updateState(3).state).toBe(frame.ENDING);
\r
294 expect(frame.state).toBe(frame.ENDING);
\r
295 expect(frame.updateState(4).state).toBe(frame.POSTWAITING);
\r
296 expect(frame.state).toBe(frame.POSTWAITING);
\r
297 expect(frame.updateState(4).state).toBe(frame.POSTWAITING);
\r
298 expect(frame.state).toBe(frame.POSTWAITING);
\r
301 describe("$begin object", function() {
\r
302 var begin = base("$frame").$begin.up();
\r
303 /*境界条件を調べておく (limit value analysis)*/
\r
304 it("should be this for the value (limit value analysis)", function() {
\r
305 expect(begin.string).toBe("");
\r
306 expect(begin.isResolved).toBeFalsy();
\r
307 expect(begin.eventTarget).toBe(document.documentElement);
\r
308 expect(typeof begin.listener).toBe("function");
\r
309 expect(begin.eventOffset).toBe(0);
\r
310 expect(begin.repeat).toBe(0);
\r
311 expect(begin.accessKey).toBe("");
\r
313 /*同値分割をして、有効同値クラスを調べておく (Equivalence partitioning, the following is the valid partion)*/
\r
314 it("should be this for the value (the valid partion)", function() {
\r
315 begin.string = " hoge ";
\r
316 expect(begin.string).toBe(" hoge ");
\r
318 /*無効同値クラスを調べておく (Equivalence partitioning, the following is the invalid partion)*/
\r
319 it("should be this for the value (the invalid partion)", function() {
\r
322 describe("A trim method in $begin object", function() {
\r
323 /*境界条件を調べておく (limit value analysis)*/
\r
324 beforeEach( function() {
\r
327 it("should be this for the value (limit value analysis)", function() {
\r
328 delete begin.string;
\r
329 expect(begin.trim(" ")).toBe("");
\r
330 expect( function() {
\r
334 /*同値分割をして、有効同値クラスを調べておく (Equivalence partitioning, the following is the valid partion)*/
\r
335 it("should be this for the value (the valid partion)", function() {
\r
336 expect(begin.trim(" hoge ")).toBe("hoge");
\r
337 expect(begin.trim(" h o g e ")).toBe("hoge");
\r
338 expect(begin.trim(" h o g e ")).toBe("hoge");
\r
339 expect(begin.trim(" h o g 12 + e ")).toBe("hog12+e");
\r
341 /*無効同値クラスを調べておく (Equivalence partitioning, the following is the invalid partion)*/
\r
342 it("should be this for the value (the invalid partion)", function() {
\r
343 expect( function() {
\r
346 expect( function() {
\r
352 describe("An offset method in $begin object", function() {
\r
353 beforeEach( function() {
\r
356 /*境界条件を調べておく (limit value analysis)*/
\r
357 it("should be this for the value (limit value analysis)", function() {
\r
358 expect(begin.offset(begin.trim(" "))).toBe(0);
\r
359 expect(begin.offset(begin.trim(" 0 "))).toBe(0);
\r
360 expect(begin.offset(begin.trim("+0ms"))).toBe(0);
\r
361 expect(begin.offset(begin.trim("-0ms"))).toBe(0);
\r
362 expect(begin.offset(begin.trim("1ms"))).toBe(1);
\r
363 expect(begin.offset(begin.trim("-1ms"))).toBe(-1);
\r
365 expect(begin.offset("+0s")).toBe(0);
\r
366 expect(begin.offset("-0s")).toBe(0);
\r
367 expect(begin.offset("1s")).toBe(1000);
\r
368 expect(begin.offset("-1s")).toBe(-1000);
\r
370 expect(begin.offset("+0min")).toBe(0);
\r
371 expect(begin.offset("-0min")).toBe(0);
\r
372 expect(begin.offset("1min")).toBe(60000);
\r
373 expect(begin.offset("-1min")).toBe(-60000);
\r
375 expect(begin.offset("+0h")).toBe(0);
\r
376 expect(begin.offset("-0h")).toBe(0);
\r
377 expect(begin.offset("1h")).toBe(60*60*1000);
\r
378 expect(begin.offset("-1h")).toBe(-3600000);
\r
380 expect(begin.offset("00:0")).toBe(0);
\r
381 expect(begin.offset("00:00:0.0")).toBe(0);
\r
382 expect(begin.offset("-00:0")).toBe(0);
\r
383 expect(begin.offset("-00:00:0.0")).toBe(0);
\r
384 expect(begin.offset("00:1")).toBe(1000);
\r
385 expect(begin.offset("-00:1")).toBe(-1000);
\r
386 expect(begin.offset("00:00:1")).toBe(1000);
\r
387 expect(begin.offset("-00:00:1")).toBe(-1000);
\r
389 expect(begin.offset()).toBe(0);
\r
391 /*同値分割をして、有効同値クラスを調べておく (Equivalence partitioning, the following is the valid partion)*/
\r
392 it("should be this for the value (the valid partion)", function() {
\r
393 expect(begin.offset(begin.trim(" + 0 ms"))).toBe(0);
\r
394 expect(begin.offset(begin.trim(" -1m s "))).toBe(-1);
\r
395 expect(begin.offset(begin.trim("1000ms"))).toBe(1000);
\r
396 expect(begin.offset(begin.trim(" -1212ms"))).toBe(-1212);
\r
398 expect(begin.offset("+100s")).toBe(100 * 1000);
\r
399 expect(begin.offset("-121s")).toBe(-121 * 1000);
\r
400 expect(begin.offset("1.25s")).toBe(1.25 * 1000);
\r
401 expect(begin.offset("-0.20s")).toBe(-0.20 * 1000);
\r
402 expect(begin.offset(".20s")).toBe(0.20 * 1000);
\r
404 expect(begin.offset("+100min")).toBe(100 * 60000);
\r
405 expect(begin.offset("-121min")).toBe(-121 * 60000);
\r
406 expect(begin.offset("1.25min")).toBe(1.25 * 60000);
\r
407 expect(begin.offset("-0.20min")).toBe(-0.20 * 60000);
\r
408 expect(begin.offset(".20min")).toBe(0.20 * 60000);
\r
410 expect(begin.offset("+100h")).toBe(100 * 3600000);
\r
411 expect(begin.offset("-121h")).toBe(-121 * 3600000);
\r
412 expect(begin.offset("1.25h")).toBe(1.25 * 3600000);
\r
413 expect(begin.offset("-0.20h")).toBe(-0.20 * 3600000);
\r
414 expect(begin.offset(".20h")).toBe(0.20 * 3600000);
\r
416 expect(begin.offset("01:0")).toBe(60000);
\r
417 expect(begin.offset("-01:0")).toBe(-60000);
\r
418 expect(begin.offset("00:00:1")).toBe(1000);
\r
419 expect(begin.offset("-00:00:1")).toBe(-1000);
\r
420 expect(begin.offset("00:01:0")).toBe(60000);
\r
421 expect(begin.offset("-00:01:0")).toBe(-60000);
\r
422 expect(begin.offset("01:00:0")).toBe(3600000);
\r
423 expect(begin.offset("-01:00:0")).toBe(-3600000);
\r
424 expect(begin.offset("00:10")).toBe(10000);
\r
425 expect(begin.offset("00:0.01")).toBe(10);
\r
426 expect(begin.offset("01:0.01")).toBe(60010);
\r
427 expect(begin.offset("10:0")).toBe(600000);
\r
428 expect(begin.offset("-00:10")).toBe(-10000);
\r
429 expect(begin.offset("-00:0.01")).toBe(-10);
\r
430 expect(begin.offset("-01:0.01")).toBe(-60010);
\r
431 expect(begin.offset("-10:0")).toBe(-600000);
\r
432 expect(begin.offset("00:00:20")).toBe(20000);
\r
433 expect(begin.offset("00:11:20")).toBe(11*60*1000 + 20000);
\r
434 expect(begin.offset("12:11:20")).toBe(12*60*60*1000 + 11*60*1000 + 20000);
\r
435 expect(begin.offset("-10:0")).toBe(-600000);
\r
436 expect(begin.offset("-01:01:0.1")).toBe(-1*60*60*1000 - 60000 - 100);
\r
438 /*無効同値クラスを調べておく (Equivalence partitioning, the following is the invalid partion)*/
\r
439 it("should be this for the value (the invalid partion)", function() {
\r
440 expect(begin.offset(begin.trim(" h o g 1e "))).toBe(0);
\r
441 expect(begin.offset("ms")).toBe(0);
\r
442 expect(begin.offset(".s")).toBe(0);
\r
443 expect(begin.offset("10:")).toBe(0);
\r
444 expect(begin.offset("::")).toBe(0);
\r
445 expect(begin.offset("-:0")).toBe(0);
\r
446 expect(begin.offset("-::0")).toBe(0);
\r
449 describe("An event method in $begin object", function() {
\r
450 /*境界条件を調べておく (limit value analysis)*/
\r
451 it("should be this for the value (limit value analysis)", function() {
\r
452 var evt = begin.event();
\r
453 expect(evt.id).toBe("");
\r
454 expect(evt.event).toBe("");
\r
455 evt = begin.event("");
\r
456 expect(evt.id).toBe("");
\r
457 expect(evt.event).toBe("");
\r
458 evt = begin.event(".");
\r
459 expect(evt.id).toBe("");
\r
460 expect(evt.event).toBe("");
\r
462 evt = begin.event("a");
\r
463 expect(evt.id).toBe("");
\r
464 expect(evt.event).toBe("a");
\r
465 evt = begin.event("a.b");
\r
466 expect(evt.id).toBe("a");
\r
467 expect(evt.event).toBe("b");
\r
469 /*同値分割をして、有効同値クラスを調べておく (Equivalence partitioning, the following is the valid partion)*/
\r
470 it("should be this for the value (the valid partion)", function() {
\r
471 var evt = begin.event("id.event");
\r
472 expect(evt.id).toBe("id");
\r
473 expect(evt.event).toBe("event");
\r
474 evt = begin.event("event");
\r
475 expect(evt.id).toBe("");
\r
476 expect(evt.event).toBe("event");
\r
478 evt = begin.event("event+0s");
\r
479 expect(evt.id).toBe("");
\r
480 expect(evt.event).toBe("event");
\r
481 evt = begin.event("event-0s");
\r
482 expect(evt.id).toBe("");
\r
483 expect(evt.event).toBe("event");
\r
485 /*無効同値クラスを調べておく (Equivalence partitioning, the following is the invalid partion)*/
\r
486 it("should be this for the value (the invalid partion)", function() {
\r
487 evt = begin.event("...");
\r
488 expect(evt.id).toBe("");
\r
489 expect(evt.event).toBe("");
\r
490 evt = begin.event(".event");
\r
491 expect(evt.id).toBe("");
\r
492 expect(evt.event).toBe("");
\r
493 evt = begin.event("id.");
\r
494 expect(evt.id).toBe("");
\r
495 expect(evt.event).toBe("");
\r
499 describe("An parse method in $begin object", function() {
\r
500 beforeEach( function() {
\r
503 /*境界条件を調べておく (limit value analysis)*/
\r
504 it("should be this for the value (limit value analysis)", function() {
\r
505 expect(begin.parse().begin).toBe(0);
\r
506 expect(begin.isResolved).toBeTruthy();
\r
508 expect(begin.parse().begin).toBe(0);
\r
509 begin.string = "+1";
\r
510 expect(begin.parse().begin).toBe(1000*begin.fpms);
\r
511 begin.string = " ";
\r
512 expect(begin.parse().begin).toBe(0);
\r
513 begin.string = "1";
\r
514 expect(begin.parse().begin).toBe(1000*begin.fpms);
\r
515 begin.string = "+0ms";
\r
516 expect(begin.parse().begin).toBe(0);
\r
517 begin.string = "-0ms";
\r
518 expect(begin.parse().begin).toBe(0);
\r
520 expect(begin.eventOffset).toBe(0);
\r
521 begin.string = "click";
\r
522 expect(begin.parse().begin).toBe(0);
\r
523 expect(begin.eventOffset).toBe(0);
\r
524 expect(begin.repeat).toBe(0);
\r
525 expect(begin.accessKey).toBe("");
\r
526 begin.string = "id.click";
\r
527 expect(begin.parse().begin).toBe(0);
\r
528 expect(begin.eventOffset).toBe(0);
\r
529 expect(begin.repeat).toBe(0);
\r
530 expect(begin.accessKey).toBe("");
\r
532 begin.string = "repeat";
\r
533 expect(begin.parse().begin).toBe(0);
\r
534 expect(begin.eventOffset).toBe(0);
\r
535 expect(begin.repeat).toBe(0);
\r
536 expect(begin.accessKey).toBe("");
\r
537 begin.string = "repeat(1)";
\r
538 expect(begin.parse().begin).toBe(0);
\r
539 expect(begin.eventOffset).toBe(0);
\r
540 expect(begin.repeat).toBe(1);
\r
541 expect(begin.accessKey).toBe("");
\r
543 begin.string = "accessKey(a)";
\r
544 expect(begin.parse().begin).toBe(0);
\r
545 expect(begin.eventOffset).toBe(0);
\r
546 expect(begin.repeat).toBe(0);
\r
547 expect(begin.accessKey).toBe("a");
\r
549 /*同値分割をして、有効同値クラスを調べておく (Equivalence partitioning, the following is the valid partion)*/
\r
550 it("should be this for the value (the valid partion)", function() {
\r
551 begin.string = " 1 0 0 m s";
\r
552 expect(begin.parse().begin).toBe(Math.floor(100*begin.fpms));
\r
554 begin.string = "1ms";
\r
555 begin.isResolved = false;
\r
556 expect(begin.parse().begin).toBe(Math.floor(1*begin.fpms));
\r
557 expect(begin.isResolved).toBeTruthy();
\r
558 expect(begin.eventOffset).toBe(0);
\r
560 begin.string="click+0";
\r
561 expect(begin.parse().begin).toBe(0);
\r
562 expect(begin.eventOffset).toBe(0);
\r
563 expect(begin.isResolved).toBeFalsy();
\r
564 begin.string = "click+1";
\r
565 expect(begin.parse().begin).toBe(1000*begin.fpms);
\r
566 expect(begin.eventOffset).toBe(1000*begin.fpms);
\r
567 begin.string = " click ";
\r
568 expect(begin.parse().begin).toBe(0);
\r
569 expect(begin.eventOffset).toBe(0);
\r
570 begin.string = "click+0ms";
\r
571 expect(begin.parse().begin).toBe(0);
\r
572 expect(begin.eventOffset).toBe(0);
\r
573 expect(begin.isResolved).toBeFalsy();
\r
574 begin.string = "click-0ms";
\r
575 expect(begin.parse().begin).toBe(0);
\r
576 expect(begin.eventOffset).toBe(0);
\r
577 begin.string = "click+100ms";
\r
578 expect(begin.parse().begin).toBe(Math.floor(100*begin.fpms));
\r
579 expect(begin.eventOffset).toBe(Math.floor(100*begin.fpms));
\r
580 begin.string = "click-100ms";
\r
581 expect(begin.parse().begin).toBe(Math.floor(-100*begin.fpms));
\r
582 expect(begin.eventOffset).toBe(Math.floor(-100*begin.fpms));
\r
584 begin.string="id.click+0";
\r
585 expect(begin.parse().begin).toBe(0);
\r
586 expect(begin.eventOffset).toBe(0);
\r
587 expect(begin.isResolved).toBeFalsy();
\r
588 begin.string = "id.click+1";
\r
589 expect(begin.parse().begin).toBe(1000*begin.fpms);
\r
590 expect(begin.eventOffset).toBe(1000*begin.fpms);
\r
591 expect(begin.isResolved).toBeFalsy();
\r
592 begin.string = " id . click ";
\r
593 expect(begin.parse().begin).toBe(0);
\r
594 expect(begin.eventOffset).toBe(0);
\r
595 expect(begin.isResolved).toBeFalsy();
\r
596 begin.string = "id.click+0ms";
\r
597 expect(begin.parse().begin).toBe(0);
\r
598 expect(begin.eventOffset).toBe(0);
\r
599 begin.string = "id.click-0ms";
\r
600 expect(begin.parse().begin).toBe(0);
\r
601 expect(begin.eventOffset).toBe(0);
\r
602 begin.string = "id.click+100ms";
\r
603 expect(begin.parse().begin).toBe(Math.floor(100*begin.fpms));
\r
604 expect(begin.eventOffset).toBe(Math.floor(100*begin.fpms));
\r
605 begin.string = "id.click-100ms";
\r
606 expect(begin.parse().begin).toBe(Math.floor(-100*begin.fpms));
\r
607 expect(begin.eventOffset).toBe(Math.floor(-100*begin.fpms));
\r
609 /*無効同値クラスを調べておく (Equivalence partitioning, the following is the invalid partion)*/
\r
610 it("should be this for the value (the invalid partion)", function() {
\r
611 begin.string = "ms";
\r
612 begin.isResolved = false;
\r
613 expect(begin.parse().begin).toBe(0);
\r
614 expect(begin.isResolved).toBeFalsy();
\r
616 begin.isResolved = true;
\r
617 begin.string = "indefinite";
\r
618 expect(begin.parse().begin).toBe(Math.floor( Number.MAX_VALUE * begin.fpms));
\r
619 expect(begin.isResolved).toBeFalsy();
\r
623 describe("A listener method in $begin object", function() {
\r
624 var obj = begin.up();
\r
625 beforeEach( function() {
\r
628 begin.timelines.length = 0;
\r
629 obj.$activate = begin.$activate.up();
\r
630 obj.startTime = Date.now();
\r
633 /*境界条件を調べておく (limit value analysis)*/
\r
634 it("should be this for the value (limit value analysis)", function() {
\r
635 obj.isResolved = true;
\r
637 expect(obj.begin).toBe(0);
\r
640 timeStamp: Date.now()
\r
642 expect(obj.begin).toBe(0);
\r
643 expect(obj.activeTime).toBeGreaterThan(0);
\r
644 expect(obj.timelines.length).toBe(1);
\r
646 obj.isResolved = false;
\r
648 timeStamp: Date.now()
\r
650 expect(obj.begin).toBe(0);
\r
651 expect(obj.activeTime).toBeGreaterThan(0);
\r
652 expect(obj.timelines.length).toBe(1);
\r
654 obj.timelines.length = 0;
\r
659 $activate: begin.$activate.up().mix( {
\r
664 timeStamp: Date.now()
\r
666 expect(obj.$1.begin).toBe(1);
\r
667 expect(obj.$1.activeTime).toBe(Math.floor(12000*obj.fpms));
\r
668 expect(obj.$1.$activate.begin).toBe(obj.$1.begin);
\r
669 expect(obj.timelines[0]).toBe(obj.$1);
\r
671 /*同値分割をして、有効同値クラスを調べておく (Equivalence partitioning, the following is the valid partion)*/
\r
672 it("should be this for the value (the valid partion)", function() {
\r
676 $activate: begin.$activate.up().mix( {
\r
677 end: begin.$activate.end.up().mix( {
\r
683 timeStamp: Date.now()
\r
685 expect(obj.$1.begin).toBe(1);
\r
686 expect(obj.$1.activeTime).toBe(Math.floor(1000*obj.fpms) - 1);
\r
687 expect(obj.$1.$activate.begin).toBe(obj.$1.begin);
\r
688 expect(obj.timelines[0]).toBe(obj.$1);
\r
693 $activate: begin.$activate.up().mix( {
\r
694 end: begin.$activate.end.up().mix( {
\r
700 timeStamp: Date.now()
\r
702 expect(obj.$1.begin).toBe(1);
\r
703 expect(obj.$1.activeTime).toBe(Math.floor(1000*obj.fpms) - 1);
\r
704 expect(obj.$1.$activate.begin).toBe(obj.$1.begin);
\r
705 expect(obj.timelines[1]).toBe(obj.$1);
\r
707 timeStamp: (Date.now() + 500)
\r
709 expect(obj.$1.begin).toBe(1);
\r
710 expect(obj.$1.activeTime).toBe(Math.floor(1000*obj.fpms) - 1);
\r
711 expect(obj.$1.$activate.begin).toBe(obj.$1.begin);
\r
712 expect(obj.timelines[1]).toBe(obj.$1);
\r
714 /*無効同値クラスを調べておく (Equivalence partitioning, the following is the invalid partion)*/
\r
715 it("should be this for the value (the invalid partion)", function() {
\r
719 describe("A $end object", function() {
\r
720 var end = base("$frame").$begin.$end.up();
\r
722 beforeEach( function() {
\r
724 end.startTime = Date.now();
\r
727 /*境界条件を調べておく (limit value analysis)*/
\r
728 it("should be this for the value (limit value analysis)", function() {
\r
729 expect(end.up().call()).toBeNull();
\r
731 expect(end.up().call()).toBe(0);
\r
732 end.string = "hoge";
\r
733 expect(end.up().call()).toBe("indefinite");
\r
736 /*同値分割をして、有効同値クラスを調べておく (Equivalence partitioning, the following is the valid partion)*/
\r
737 it("should be this for the value (the valid partion)", function() {
\r
738 end.string = "hoge+0";
\r
739 expect(end.up().call()).toBe("indefinite");
\r
740 end.string = "12ms";
\r
741 expect(end.up().call()).toBe(Math.floor(12*end.fpms));
\r
742 end.string = "hoge+12ms";
\r
743 expect(end.up().call()).toBe("indefinite");
\r
746 /*無効同値クラスを調べておく (Equivalence partitioning, the following is the invalid partion)*/
\r
747 it("should be this for the value (the invalid partion)", function() {
\r
749 expect(end.up().call()).toBeNull();
\r
752 describe("A listener method in $end object", function() {
\r
754 begin = base("$frame").$begin;
\r
755 beforeEach( function() {
\r
758 end.timelines.length = 0;
\r
760 obj.$begin = begin.up().mix( {
\r
764 obj.$begin.$activate = begin.$activate.up();
\r
765 obj.addLine(obj.$begin);
\r
767 /*境界条件を調べておく (limit value analysis)*/
\r
768 it("should be this for the value (limit value analysis)", function() {
\r
769 expect(obj.timelines[0]).toBe(obj.$begin);
\r
770 expect(obj.timelines[0]).not.toBe(obj);
\r
772 expect(obj.timelines[0]).not.toBe(obj.$begin);
\r
774 obj.addLine(obj.$begin.mix( {
\r
779 timeStamp: (Date.now() + 12)
\r
781 expect(obj.timelines[0]).not.toBe(obj.$begin);
\r
783 /*同値分割をして、有効同値クラスを調べておく (Equivalence partitioning, the following is the valid partion)*/
\r
784 it("should be this for the value (the valid partion)", function() {
\r
785 obj.$begin.$activate.begin = 0;
\r
790 timeStamp: (Date.now() + 120)
\r
792 expect(obj.timelines[0]).not.toBe(obj.$begin);
\r
793 expect(obj.begin).toBe(0);
\r
794 expect(obj.$begin.activeTime).toBe(0);
\r
796 obj.addLine(obj.$begin.mix( {
\r
800 obj.$begin.$activate.begin = 0;
\r
802 string: "event+1000ms"
\r
805 timeStamp: (Date.now() + 12)
\r
807 expect(obj.timelines[0]).toBe(obj.$begin);
\r
808 expect(obj.begin).toBe(Math.ceil(1000*obj.fpms));
\r
809 expect(obj.$begin.activeTime).toBe(Math.ceil(1000*obj.fpms));
\r
811 /*無効同値クラスを調べておく (Equivalence partitioning, the following is the invalid partion)*/
\r
812 it("should be this for the value (the invalid partion)", function() {
\r
816 describe("A $activate object", function() {
\r
817 var act = base("$frame").$begin.$activate.up();
\r
818 beforeEach( function() {
\r
819 act.dur = "indefinite";
\r
821 act.repeatCount = null;
\r
822 act.repeatDur = null;
\r
823 act.end = act.$begin.$end;
\r
824 act.simpleDur = base("$frame").$begin.$activate.simpleDur;
\r
826 /*境界条件を調べておく (limit value analysis)*/
\r
827 it("should be this for the value (limit value analysis)", function() {
\r
828 expect(act.dur).toBe("indefinite");
\r
829 expect(typeof act.resolvedTime).toBe("function");
\r
830 expect(act.end).toBe(act.$begin.$end);
\r
831 expect(act.repeatCount).toBeNull();
\r
832 expect(act.repeatDur).toBeNull();
\r
833 expect(act.simpleDur()).toBeNull();
\r
834 expect(act.min).toBe("0");
\r
835 expect(act.max).toBe("indefinite");
\r
838 expect(act.$a.call()).toBeNull();
\r
839 expect(act.$a.end).toBeNull();
\r
841 /*同値分割をして、有効同値クラスを調べておく (Equivalence partitioning, the following is the valid partion)*/
\r
842 it("should be this for the value (the valid partion)", function() {
\r
843 expect(act.resolvedTime()).toBe((+new Date()));
\r
845 /*Activate Duration = dur*/
\r
847 act.$b.dur = "132ms";
\r
848 var abc = act.$b.call();
\r
849 expect(abc).toBe(Math.floor(132*act.fpms));
\r
850 expect(abc).toBe(act.$b.simpleDur);
\r
852 expect(act.up().call()).toBeNull();
\r
854 /*AD = end -begin*/
\r
856 act.up("$eb").end = act.end.up().mix( {string: "120ms" } );
\r
857 expect( act.$eb.mix( {
\r
859 simpleDur: act.simpleDur,
\r
862 } ).call() ).toBe(Math.floor(120*act.fpms) - 1);
\r
863 expect( act.$eb.mix( {
\r
865 repeatCount: "indefinite",
\r
867 } ).call() ).toBe(Math.floor(120*act.fpms) - 1);
\r
868 expect( act.$eb.mix( {
\r
870 simpleDur: act.simpleDur,
872 repeatDur: "indefinite",
\r
873 } ).call() ).toBe(Math.floor(120*act.fpms) - 1);
\r
875 expect( act.$eb.mix( {
\r
877 simpleDur: act.simpleDur,
878 repeatCount: "indefinite",
\r
879 repeatDur: "indefinite",
\r
880 } ).call() ).toBe(Math.floor(120*act.fpms)*3 - 1);
\r
882 /*AD = Min(dur, end - begin)*/
\r
883 act.up("$c").end = act.end.up().mix( { string: "12" } );
\r
886 simpleDur: act.simpleDur,
890 expect(act.$c.call()).toBe(Math.floor(10000*act.fpms));
\r
891 expect(act.$c.call()).toBe(act.$c.simpleDur);
\r
894 simpleDur: act.simpleDur,
898 expect(act.$c.call()).toBe(Math.floor(12000*act.fpms) - 1);
\r
899 expect(act.$c.simpleDur).toBe(Math.floor(15000*act.fpms));
\r
901 /*AD = Min(repeatCount*dur, end - begin)*/
\r
902 expect(act.$c.end).toBe(Math.floor(12000*act.fpms));
\r
905 simpleDur: act.simpleDur,
909 expect(act.$c.call()).toBe(Math.floor(12000*act.fpms) - 1);
\r
910 expect(act.$c.simpleDur).toBe(Math.floor(10000*act.fpms));
\r
913 simpleDur: act.simpleDur,
917 expect(act.$c.call()).toBe(Math.floor(10000*act.fpms));
\r
918 expect(act.$c.simpleDur).toBe(Math.floor(10000*act.fpms));
\r
920 /*AD = Min(repeatDur, end - begin)*/
\r
923 simpleDur: act.simpleDur,
927 expect(act.$c.call()).toBe(Math.floor(12000*act.fpms) - 1);
\r
928 expect(act.$c.simpleDur).toBeNull();
\r
931 simpleDur: act.simpleDur,
935 expect(act.$c.call()).toBe(Math.floor(10000*act.fpms));
\r
936 expect(act.$c.simpleDur).toBeNull();
\r
939 simpleDur: act.simpleDur,
943 expect(act.$c.call()).toBe(Math.floor(12000*act.fpms) - 1);
\r
944 expect(act.$c.simpleDur).toBe(Math.floor(10000*act.fpms));
\r
947 simpleDur: act.simpleDur,
951 expect(act.$c.call()).toBe(Math.floor(11000*act.fpms));
\r
952 expect(act.$c.simpleDur).toBe(Math.floor(10000*act.fpms));
\r
954 /*AD = Min(repeatCount*d, repeatDur, end - begin)*/
\r
957 simpleDur: act.simpleDur,
961 expect(act.$c.call()).toBe(Math.floor(12000*act.fpms) - 1);
\r
962 expect(act.$c.simpleDur).toBe(Math.floor(10000*act.fpms));
\r
965 simpleDur: act.simpleDur,
969 expect(act.$c.call()).toBe(Math.floor(10000*act.fpms));
\r
970 expect(act.$c.simpleDur).toBe(Math.floor(10000*act.fpms));
\r
973 simpleDur: act.simpleDur,
977 expect(act.$c.call()).toBe(Math.floor(9000*act.fpms));
\r
978 expect(act.$c.simpleDur).toBe(Math.floor(11000*act.fpms));
\r
980 /*AD = repeatDur,*/
\r
984 simpleDur: act.simpleDur,
988 expect(act.$c.call()).toBe(Math.floor(15000*act.fpms));
\r
989 expect(act.$c.simpleDur).toBe(Math.floor(10000*act.fpms));
\r
992 simpleDur: act.simpleDur,
996 expect(act.$c.call()).toBe(Math.floor(10000*act.fpms));
\r
997 expect(act.$c.simpleDur).toBeNull();
\r
999 act.end.string = null;
\r
1000 act.up("$cd").mix( {
\r
1005 expect(act.$cd.call()).toBe(Math.floor(10000*act.fpms) * 2);
\r
1007 act.$cd.end = act.end;
\r
1008 act.$cd.repeatCount = null;
\r
1009 act.$cd.repeatDur = "12";
\r
1010 expect(act.$cd.call()).toBe(Math.floor(12000*act.fpms));
\r
1012 act.up("$d").mix( {
\r
1016 simpleDur: act.simpleDur
\r
1018 expect(act.$d.call()).toBe(Math.floor(2000*act.fpms));
\r
1019 act.up("$d").mix( {
\r
1023 simpleDur: act.simpleDur
\r
1025 expect(act.$d.call()).toBe(Math.floor(2000*act.fpms));
\r
1027 /*endで0が指定されている場合*/
\r
1030 act.repeatDur = null;
\r
1031 act.repeatCount = "indefinite";
\r
1033 expect(act.call()).toBe(0);
\r
1034 act.repeatCount = null;
\r
1035 act.repeatDur = "indefinite";
\r
1037 expect(act.call()).toBe(0);
\r
1038 act.repeatDur = "indefinite";
\r
1039 act.repeatCount = "indefinite";
\r
1041 expect(act.call()).toBe(0);
\r
1043 /*無効同値クラスを調べておく (Equivalence partitioning, the following is the invalid partion)*/
\r
1044 it("should be this for the value (the invalid partion)", function() {
\r
1046 act.up("$d").mix( {
\r
1050 simpleDur: act.simpleDur
\r
1052 expect(act.$d.call()).toBe(Math.floor(1000*act.fpms));
\r
1054 act.repeatDur = null;
\r
1055 act.repeatCount = "indefinite";
\r
1057 expect(act.call()).toBeNull();
\r
1058 act.repeatCount = null;
\r
1059 act.repeatDur = "indefinite";
\r
1061 expect(act.call()).toBeNull();
\r
1062 act.repeatDur = "indefinite";
\r
1063 act.repeatCount = "indefinite";
\r
1065 expect(act.call()).toBeNull();
\r
1068 describe("A $from object", function() {
\r
1069 var from = base("$from");
\r
1070 beforeEach( function() {
\r
1071 from = base("$from").up();
\r
1072 from.from = from.from.up();
\r
1075 /*境界条件を調べておく (limit value analysis)*/
\r
1076 it("should be this for the value (limit value analysis)", function() {
\r
1077 expect(from.string).toBe("");
\r
1078 expect(from.numList()).toEqual([]);
\r
1079 expect(from.strList()).toBeNull();
\r
1081 from.string = "0";
\r
1082 expect(from.numList()[0]).toBe(0);
\r
1083 expect(from.strList()).toBeNull();
\r
1085 from.string = " 0 ";
\r
1086 expect(from.numList()[0]).toBe(0);
\r
1087 expect(from.strList().join("")).toBe(" ");
\r
1089 from.string = "a";
\r
1090 expect(from.numList()).toEqual([]);
\r
1091 expect(from.strList()[0]).toBe("a");
\r
1093 /*前後の空白を除去する処理をしない。なぜなら、文字列リストの空白は保持するのが望ましいから
\r
1094 * 文字列リストの空白を除去した例: "M 20 20 M M" -> "M20 20 MM"となってしまう*/
\r
1096 from.string = null;
\r
1097 expect( function() {
\r
1100 expect( function() {
\r
1104 expect(from.additive[0]).toBe(0);
\r
1105 expect(from.accumulate[0]).toBe(0);
\r
1107 /*同値分割をして、有効同値クラスを調べておく (Equivalence partitioning, the following is the valid partion)*/
\r
1108 it("should be this for the value (the valid partion)", function() {
\r
1109 from.string = "0a";
\r
1110 expect(from.numList()[0]).toBe(0);
\r
1111 expect(from.strList()[0]).toBe("a");
\r
1113 from.string = "a0";
\r
1114 expect(from.numList()[0]).toBe(0);
\r
1115 expect(from.strList()[0]).toBe("a");
\r
1117 from.string = "0.1";
\r
1118 expect(from.numList()[0]).toBe(0.1);
\r
1119 expect(from.strList()).toBeNull();
\r
1121 from.string = "+0.1";
\r
1122 expect(from.numList()[0]).toBe(0.1);
\r
1123 expect(from.strList()).toBeNull();
\r
1125 from.string = "-0.1";
\r
1126 expect(from.numList()[0]).toBe(-0.1);
\r
1127 expect(from.strList()).toBeNull();
\r
1129 from.string = "1e-1";
\r
1130 expect(from.numList()[0]).toBe(1e-1);
\r
1131 expect(from.strList()).toBeNull();
\r
1133 from.string = "1E-1";
\r
1134 expect(from.numList()[0]).toBe(1E-1);
\r
1135 expect(from.strList()).toBeNull();
\r
1137 from.string = "0,0";
\r
1138 expect(from.numList().toString()).toBe("0,0");
\r
1139 expect(from.strList().join("")).toBe(",");
\r
1141 from.string = "a00a";
\r
1142 expect(from.numList()[0]).toBe(0);
\r
1143 expect(from.strList().join("")).toBe("aa");
\r
1145 from.string = "a0b0a";
\r
1146 expect(from.numList().toString()).toBe("0,0");
\r
1147 expect(from.strList().join("")).toBe("aba");
\r
1149 from.string = "0b0a";
\r
1150 expect(from.numList().toString()).toBe("0,0");
\r
1151 expect(from.strList().join("")).toBe("ba");
\r
1153 from.string = "0b-1.0a";
\r
1154 expect(from.numList()[1]).toBe(-1);
\r
1155 expect(from.strList().join("")).toBe("ba");
\r
1157 expect(from.up().call()).toBe(from.$1.numList);
\r
1158 expect(from.$1.numList[1]).toBe(-1);
\r
1159 expect(from.$1.strList.join("")).toBe("ba");
\r
1161 from.string = "あ 0b-1.0a12";
\r
1162 expect(from.numList()[1]).toBe(-1);
\r
1163 expect(from.strList().join("")).toBe("あ ba12");
\r
1165 from.string = "0b-1.0a0";
\r
1166 expect(from.numList().join(",")).toBe("0,-1,0");
\r
1167 expect(from.strList().join("")).toBe("ba");
\r
1169 from.string = "0b .1a";
\r
1170 expect(from.numList()[1]).toBe(0.1);
\r
1171 expect(from.strList().join("")).toBe("b a");
\r
1173 /*無効同値クラスを調べておく (Equivalence partitioning, the following is the invalid partion)*/
\r
1174 it("should be this for the value (the invalid partion)", function() {
\r
1175 from.string = NaN;
\r
1176 expect(function(){
\r
1179 expect(function(){
\r
1183 from.string = "currentColor";
\r
1184 expect(from.numList()).toEqual([]);
\r
1185 expect(from.strList()[0]).toBe("currentColor");
\r
1187 from.string = "eE";
\r
1188 expect(from.numList()).toEqual([]);
\r
1189 expect(from.strList()[0]).toBe("eE");
\r
1190 expect(from.strList()[0]).toBe("eE");
\r
1193 describe("A $to object", function() {
\r
1194 var from = base("$from");
\r
1195 beforeEach( function() {
\r
1196 from = base("$from").up();
\r
1200 /*境界条件を調べておく (limit value analysis)*/
\r
1201 it("should be this for the value (limit value analysis)", function() {
\r
1202 expect(from.$to instanceof from.constructor).toBeTruthy();
\r
1203 expect(from.up().call()).toBe(from.$1.numList);
\r
1204 expect(from.$to.up().call()).toBe(from.$to.$1.numList);
\r
1206 /*同値分割をして、有効同値クラスを調べておく (Equivalence partitioning, the following is the valid partion)*/
\r
1207 it("should be this for the value (the valid partion)", function() {
\r
1209 from.$to.from = from;
\r
1210 from.$to.string = "12cm-7";
\r
1211 expect(from.$to.numList().join(",")).toBe("12,-7");
\r
1212 expect(from.$to.strList().toString()).toBe("cm");
\r
1214 from.string = "7cm+8";
\r
1216 expect(from.call()).toBe(from.numList);
\r
1217 expect(from.$to.numList.join(",")).toBe("12,-7");
\r
1218 expect(from.$to.strList.join("")).toBe("cm");
\r
1219 expect(from.numList.join(",")).toBe("7,8");
\r
1220 expect(from.strList.join("")).toBe("cm");
\r
1221 expect(from.$to.from).toBe(from.numList);
\r
1224 /*無効同値クラスを調べておく (Equivalence partitioning, the following is the invalid partion)*/
\r
1225 it("should be this for the value (the invalid partion)", function() {
\r
1227 from.up("$to").mix( function() {
\r
1228 this.string = "12cm";
\r
1231 arr.string = this.string;
\r
1232 expect(this.numList).toEqual(arr);
\r
1233 expect(this.strList).toBeNull();
\r
1237 describe("An advance method", function() {
\r
1238 var from = base("$from");
\r
1239 beforeEach( function() {
\r
1240 from = base("$from").up();
\r
1243 from.$to.from = from;
\r
1245 /*境界条件を調べておく (limit value analysis)*/
\r
1246 it("should be this for the value (limit value analysis)", function() {
\r
1247 expect(from.advance()).toBe("");
\r
1248 expect(from.$to.advance()).toBe("");
\r
1249 expect(from.$to.advance(0)).toBe("");
\r
1250 expect(from.$to.advance(1)).toBe("");
\r
1251 expect(function(){
\r
1252 from.$to.advance(1.01);
\r
1253 }).toThrow("An Invalid Number Error");
\r
1254 expect(function(){
\r
1255 from.$to.advance(-0.01);
\r
1256 }).toThrow("An Invalid Number Error");
\r
1260 from = base("$from").up();
\r
1262 from.$to.from = from;
\r
1263 arr.string = from.string = "0";
\r
1264 from.$to.string = "1";
\r
1265 expect(from.$to.call()).toBe(from.$to.numList);
\r
1266 expect(from.$to.numList[0]).toBe(1);
\r
1267 expect(from.$to.strList).toBeNull();
\r
1268 expect(from.numList[0]).toBe(0);
\r
1269 expect(from.strList).toBeNull();
\r
1270 expect(from.advance(0)).toBe("");
\r
1271 expect(from.$to.from).toBe(from.numList);
\r
1272 expect(from.$to.advance(0)).toBe("0");
\r
1273 expect(from.call()).toBe(from.numList);
\r
1275 from = base("$from").up();
\r
1276 f(from.up(), "inline", "block");
\r
1277 f(from.up(), " inline", " block ");
\r
1278 function f(from, inline, block) {
\r
1280 from.$to.from = from;
\r
1281 from.string = inline;
\r
1282 arr.string = from.$to.string = block;
\r
1283 expect(from.$to.call()).toBe(from.$to.numList);
\r
1284 expect(from.$to.numList).toEqual(arr);
\r
1285 expect(from.$to.strList).toEqual([block]);
\r
1286 arr.string = from.string;
\r
1287 expect(from.numList).toEqual(arr);
\r
1288 expect(from.strList).toEqual([inline]);
\r
1289 expect(from.advance(0)).toBe("");
\r
1290 expect(from.$to.from).toBe(from.numList);
\r
1291 expect(from.$to.advance(0)).toBe("inline");
\r
1292 expect(from.$to.advance(1)).toBe("block");
\r
1293 expect(from.call()).toBe(from.numList);
\r
1296 /*同値分割をして、有効同値クラスを調べておく (Equivalence partitioning, the following is the valid partion)*/
\r
1297 it("should be this for the value (the valid partion)", function() {
\r
1300 from.string = "0s";
\r
1301 from.$to.string = "1s";
\r
1302 expect(from.$to.call()).toBe(from.$to.numList);
\r
1303 expect(from.$to.numList[0]).toBe(1);
\r
1304 expect(from.$to.strList[0]).toBe("");
\r
1305 expect(from.numList[0]).toBe(0);
\r
1306 expect(from.strList[0]).toBe("");
\r
1307 expect(from.advance(0)).toBe("");
\r
1308 expect(from.$to.from).toBe(from.numList);
\r
1309 expect(from.$to.advance(0)).toBe("0s");
\r
1310 from.$to.degit = deg;
\r
1311 for (var i=0;i<1;i+=0.01) {
\r
1312 expect(from.$to.advance(i)).toBe(i.toFixed(deg)+"s");
\r
1314 expect(from.call()).toBe(from.numList);
\r
1316 from = base("$from").up();
\r
1318 from.string = "a0S";
\r
1319 from.$to.string = "a1S";
\r
1320 from.$to.from = from;
\r
1321 expect(from.$to.call()).toBe(from.$to.numList);
\r
1322 expect(from.$to.numList[0]).toBe(1);
\r
1323 expect(from.$to.strList[0]).toBe("a");
\r
1324 expect(from.numList[0]).toBe(0);
\r
1325 expect(from.strList[0]).toBe("a");
\r
1326 expect(from.advance(0)).toBe("");
\r
1327 expect(from.$to.from).toBe(from.numList);
\r
1328 expect(from.$to.advance(0)).toBe("a0S");
\r
1330 from.$to.degit = deg;
\r
1331 for (var i=0;i<1;i+=0.01) {
\r
1332 expect(from.$to.advance(i)).toBe("a" +i.toFixed(deg)+ "S");
\r
1334 expect(from.call()).toBe(from.numList);
\r
1336 from = base("$from").up();
\r
1337 f(from.up(), "a-10s1.5", "a10s-3");
\r
1338 f(from.up(), " a-10s1.5", " a10s-3 ");
\r
1339 function f(from, fromString, toString) {
\r
1341 from.string = fromString;
\r
1342 from.$to.string = toString;
\r
1343 from.$to.from = from;
\r
1345 from.$to.degit = 1;
\r
1346 expect(from.$to.advance(0)).toBe("a-10.0s1.5");
\r
1347 expect(from.$to.advance(0.4)).toBe("a-2.0s-0.3");
\r
1348 expect(from.$to.advance(1)).toBe("a10.0s-3.0");
\r
1350 from.$to.additive[0] = 1;
\r
1351 from.$to.accumulate[1] = 2;
\r
1352 expect(from.$to.advance(0.4)).toBe("a-1.0s1.7");
\r
1353 from.$to.additive[0] = 0.5;
\r
1354 from.$to.accumulate[1] = 0.8;
\r
1355 expect(from.$to.advance(1)).toBe("a10.5s-2.2");
\r
1358 /*無効同値クラスを調べておく (Equivalence partitioning, the following is the invalid partion)*/
\r
1359 it("should be this for the value (the invalid partion)", function() {
\r
1360 expect(function(){
\r
1361 from.$to.advance(10);
\r
1362 }).toThrow("An Invalid Number Error");
\r
1363 expect(function(){
\r
1364 from.$to.advance(-10);
\r
1365 }).toThrow("An Invalid Number Error");
\r
1369 describe("A distance method", function() {
\r
1370 var from = base("$from");
\r
1371 beforeEach( function() {
\r
1372 from = base("$from").up();
\r
1376 /*境界条件を調べておく (limit value analysis)*/
\r
1377 it("should be this for the value (limit value analysis)", function() {
\r
1378 expect(from.distance()).toBe(0)
\r
1379 expect(from.$to.distance()).toBe(0);
\r
1381 from.string = "0";
\r
1382 from.$to.string = "1";
\r
1383 expect(from.distance()).toBe(0);
\r
1384 expect(from.$to.distance(from)).toBe(1);
\r
1386 /*同値分割をして、有効同値クラスを調べておく (Equivalence partitioning, the following is the valid partion)*/
\r
1387 it("should be this for the value (the valid partion)", function() {
\r
1388 from.string = "s 0 s 12";
\r
1389 from.$to.string = "s 0 s 0";
\r
1390 expect(from.distance()).toBe(0);
\r
1391 expect(from.$to.distance(from)).toBe(12);
\r
1392 expect(from.$to.distance(from)).toBe(12);
\r
1393 expect(from.$to.distance(from.call())).toBe(12);
\r
1395 from = base("$from").up();
\r
1397 from.string = "rgb(1, 0, 0)";
\r
1398 from.$to.string = "rgb(0, 0, 1)";
\r
1399 expect(from.distance()).toBe(0);
\r
1400 expect(from.$to.distance(from)).toBe(Math.sqrt(2));
\r
1402 /*無効同値クラスを調べておく (Equivalence partitioning, the following is the invalid partion)*/
\r
1403 it("should be this for the value (the invalid partion)", function() {
\r
1404 from.string = "s";
\r
1405 from.$to.string = "s";
\r
1406 expect(from.$to.distance(from)).toBe(0);
\r
1409 describe("A setAdditive method", function() {
\r
1410 var from = base("$from");
\r
1411 beforeEach( function() {
\r
1412 from = base("$from").up();
\r
1416 /*境界条件を調べておく (limit value analysis)*/
\r
1417 it("should be this for the value (limit value analysis)", function() {
\r
1418 expect(from.setAdditive()).toBe(0);
\r
1419 expect(from.setAdditive("")).toBe(0);
\r
1420 expect(from.additive).toEqual([0]);
\r
1423 expect(from.setAdditive("1")).toEqual(arr);
\r
1424 expect(from.additive).toEqual(arr);
\r
1426 /*同値分割をして、有効同値クラスを調べておく (Equivalence partitioning, the following is the valid partion)*/
\r
1427 it("should be this for the value (the valid partion)", function() {
\r
1428 var arr = [1, 2, 3];
\r
1429 arr.string = "1 2, 3";
\r
1430 expect(from.setAdditive("1 2, 3")).toEqual(arr);
\r
1431 expect(from.additive).toEqual(arr);
\r
1433 /*無効同値クラスを調べておく (Equivalence partitioning, the following is the invalid partion)*/
\r
1434 it("should be this for the value (the invalid partion)", function() {
\r
1437 describe("A setAccumulate method", function() {
\r
1438 var from = base("$from");
\r
1439 beforeEach( function() {
\r
1440 from = base("$from").up();
\r
1441 from.string = "0 1";
\r
1445 /*境界条件を調べておく (limit value analysis)*/
\r
1446 it("should be this for the value (limit value analysis)", function() {
\r
1447 expect(from.setAccumulate()).toBe(0);
\r
1448 expect(from.setAccumulate(0)).toBe(0);
\r
1449 expect(from.accumulate).toEqual([0, 0]);
\r
1450 expect(from.setAccumulate(1)).toEqual([0, 1]);
\r
1451 expect(from.accumulate).toEqual([0, 1]);
\r
1453 /*同値分割をして、有効同値クラスを調べておく (Equivalence partitioning, the following is the valid partion)*/
\r
1454 it("should be this for the value (the valid partion)", function() {
\r
1455 expect(from.setAccumulate(2)).toEqual([0, 2]);
\r
1456 expect(from.accumulate).toEqual([0, 2]);
\r
1458 /*無効同値クラスを調べておく (Equivalence partitioning, the following is the invalid partion)*/
\r
1459 it("should be this for the value (the invalid partion)", function() {
\r
1460 expect(from.setAccumulate(NaN)).toEqual(0);
\r
1463 describe("A $calcMode object", function() {
\r
1464 var calc = base("$calcMode"),
\r
1467 beforeEach( function() {
\r
1468 calc = base("$calcMode").up();
\r
1469 calc.to = base("$from").up().mix( {string: "1"} );
\r
1470 from = calc.to.from = base("$from").up().mix( {string: "0"} );
\r
1472 /*境界条件を調べておく (limit value analysis)*/
\r
1473 it("should be this for the value (limit value analysis)", function() {
\r
1474 expect(calc.mode).toBe("linear");
\r
1475 expect(calc.keyTime).toBe(1);
\r
1476 expect(calc.keySplines).toBeNull();
\r
1477 expect(calc.string).toBe("");
\r
1479 expect(calc.call()(0)).toBe("0");
\r
1480 expect(calc.keyTime).toBe(1);
\r
1481 expect(calc.call()(1)).toBe("1");
\r
1484 expect(calc.call()(1)).toBe("0");
\r
1487 calc.mode = "paced";
\r
1488 expect(calc.norm).toBe(1);
\r
1489 calc.to.from = from;
\r
1490 expect(calc.call()(0)).toBe("0");
\r
1491 expect(calc.keyTime).toBe(1);
\r
1492 calc.to.from = from;
\r
1493 expect(calc.call()(1)).toBe("1");
\r
1496 calc.to.from = from;
\r
1497 expect(calc.call()(1)).toBe("1");
\r
1500 calc.mode = "discrete";
\r
1501 calc.to.from = from;
\r
1503 expect(calc.call()(0)).toBe("0");
\r
1504 expect(calc.call()(1)).toBe("1");
\r
1506 /*同値分割をして、有効同値クラスを調べておく (Equivalence partitioning, the following is the valid partion)*/
\r
1507 it("should be this for the value (the valid partion)", function() {
\r
1508 calc.mode = "linear";
\r
1509 calc.keyTime = 0.5;
\r
1510 calc.to.degit = 1;
\r
1511 expect(calc.call()(0.2)).toBe("0.4");
\r
1512 expect(calc.call()(0.3)).toBe("0.6");
\r
1514 expect(calc.call()(0.2)).toBe("0.4");
\r
1516 calc = base("$calcMode").up();
\r
1517 calc.keyTime = 0.2;
\r
1518 calc.to = base("$from").up();
\r
1519 calc.to.from = base("$from").up();
\r
1520 calc.to.from.string = "0s";
\r
1521 calc.to.string = "1s";
\r
1522 calc.to.degit = 1;
\r
1523 expect(calc.call()(0.1)).toBe("0.5s");
\r
1525 calc = base("$calcMode").up();
\r
1526 calc.keyTime = 0.5;
\r
1527 calc.to = base("$from").up();
\r
1528 calc.to.from = base("$from").up();
\r
1529 calc.to.from.string = "rgb(100, 20, 32)";
\r
1530 calc.to.string = "rgb(0, 10, 50)";
\r
1531 expect(calc.call()(0.25)).toBe("rgb(50, 15, 41)");
\r
1534 calc.to = base("$from").up();
\r
1535 calc.to.from = base("$from").up();
\r
1536 calc.mode = "paced";
\r
1538 calc.to.from.string = "0s";
\r
1539 calc.to.string = "20s";
\r
1540 calc.to.degit = 1;
\r
1541 expect(calc.call()(0.1)).toBe("10.0s");
\r
1542 expect(calc.keyTime).toBe(0.2);
\r
1544 calc.to = base("$from").up();
\r
1545 calc.to.from = base("$from").up();
\r
1546 calc.mode = "paced";
\r
1548 calc.to.from.string = "rgb(0, 0, 20)";
\r
1549 calc.to.string = "rgb(0, 0, 0)";
\r
1550 expect(calc.call()(0.1)).toBe("rgb(0, 0, 10)");
\r
1551 expect(calc.keyTime).toBe(0.2);
\r
1554 calc.to = base("$from").up();
\r
1555 calc.to.from = base("$from").up();
\r
1556 calc.mode = "discrete";
\r
1557 calc.keyTime = 0.5;
\r
1558 calc.to.degit = 1;
\r
1559 calc.to.string = "1";
\r
1560 calc.to.from.string = "0.5";
\r
1561 expect(calc.call()(0.2)).toBe("0.5");
\r
1562 expect(calc.call()(0.3)).toBe("0.5");
\r
1564 expect(calc.call()(0.2)).toBe("0.5");
\r
1566 calc.to = base("$from").up();
\r
1567 calc.to.from = base("$from").up();
\r
1568 calc.mode = "discrete";
\r
1569 calc.keyTime = 0.5;
\r
1570 calc.to.degit = 1;
\r
1571 calc.to.string = "block";
\r
1572 calc.to.from.string = "inline";
\r
1573 expect(calc.call()(0.2)).toBe("inline");
\r
1574 expect(calc.call()(0.3)).toBe("inline");
\r
1576 calc.to = base("$from").up();
\r
1577 calc.to.from = base("$from").up();
\r
1578 calc.mode = "linear";
\r
1580 calc.to.degit = 1;
\r
1581 calc.to.string = "1 1";
\r
1582 calc.to.from.string = "0.0 1";
\r
1583 expect(calc.call()(0.2)).toBe("0.2 1.0");
\r
1584 expect(calc.call()(0.3)).toBe("0.3 1.0");
\r
1586 /*無効同値クラスを調べておく (Equivalence partitioning, the following is the invalid partion)*/
\r
1587 it("should be this for the value (the invalid partion)", function() {
\r
1588 calc.keyTime = null;
\r
1589 expect(calc.call()(1)).toBe(calc.string);
\r
1591 calc.keyTime = void 0;
\r
1592 expect(calc.call()(1)).toBe(calc.string);
\r
1594 calc.keyTime = 1/0;
\r
1595 expect(calc.call()(1)).toBe(calc.string);
\r
1597 expect(calc.call()()).toBe(calc.string);
\r
1599 calc = base("$calcMode").up();
\r
1600 calc.mode = "paced";
\r
1601 calc.to.from = from;
\r
1602 expect(calc.call()()).toBe(calc.string);
\r
1604 calc = base("$calcMode").up();
\r
1605 calc.mode = "discrete";
\r
1606 expect(calc.call()()).toBe(calc.string);
\r
1609 /*splineモードの境界条件を調べておく (limit value analysis)*/
\r
1610 it("should be this for the value (spline mode limit value analysis)", function() {
\r
1611 /*3次ベジェ曲線の数式はこのページを参考にした http://opentype.jp/fontguide_doc3.htm*/
\r
1614 bezier = function (x1, y1, x2, y2, x3, y3, x4, y4) {
\r
1615 return function (t) {
\r
1616 x = (x4-3*(x3-x2)-x1)*t*t*t + 3*(x3-2*x2+x1)*t*t + 3*(x2-x1)*t + x1;
\r
1617 y = (y4-3*(y3-y2)-y1)*t*t*t + 3*(y3-2*y2+y1)*t*t + 3*(y2-y1)*t + y1;
\r
1621 expect(calc.keySplines).toBeNull();
\r
1622 calc.mode = "spline";
\r
1623 expect( calc.call()("undef")).toBe(Math.PI);
\r
1624 calc.keySplines = [0, 0, 1, 1];
\r
1625 calc.to.degit = 1;
\r
1626 calc.to.from = from;
\r
1627 expect(calc.call()(0)).toBe(bezier(0,0, 0,0, 1,1, 1,1)(0)+".0");
\r
1628 calc.to.from = from;
\r
1629 expect(calc.call()(1)).toBe(bezier(0,0, 0,0, 1,1, 1,1)(1)+".0");
\r
1630 calc.to.from = from;
\r
1631 expect(calc.call()(0.5)).toBe(bezier(0,0, 0,0, 1,1, 1,1)(0.5)+"");
\r
1633 df(0,0, 0,0, 1,1, 1,1, 0.1);
\r
1634 df(0,0, 0,0, 1,1, 1,1, 0.5);
\r
1635 df(0,0, 0,0, 1,1, 1,1, 0.8);
\r
1636 df(0,0, 0,0, 1,1, 1,1, 0.9);
\r
1637 df(0,0, 0.75,0, 0,0.75, 1,1, 0.1);
\r
1638 df(0,0, 0.75,0, 0,0.75, 1,1, 0.5);
\r
1639 df(0,0, 0.75,0, 0,0.75, 1,1, 0.8);
\r
1640 df(0,0, 0.75,0, 0,0.75, 1,1, 0.9);
\r
1641 function df (x1, y1, x2, y2, x3, y3, x4, y4, t) {
\r
1643 var a = y4-3*(y3-y2)-y1,
\r
1644 b = 3*(y3-2*y2+y1),
\r
1646 d = y1 - bezier.apply(null, arguments)(t);
\r
1647 expect(Math.abs(Math.qubicnewton(a, b, c, d, t) - t)).toBeLessThan(1e-5);
\r
1650 /*同値分割をして、有効同値クラスを調べておく (Equivalence partitioning, the following is the valid partion)*/
\r
1651 it("should be this for the value (the valid partion on a spline mode )", function() {
\r
1654 bezier = function (x1, y1, x2, y2, x3, y3, x4, y4) {
\r
1655 return function (t) {
\r
1657 x: (x4-3*(x3-x2)-x1)*t*t*t + 3*(x3-2*x2+x1)*t*t + 3*(x2-x1)*t + x1,
\r
1658 y: (y4-3*(y3-y2)-y1)*t*t*t + 3*(y3-2*y2+y1)*t*t + 3*(y2-y1)*t + y1
\r
1662 calc.mode = "spline";
\r
1663 calc.keySplines = [0, 0.5, 0.5, 1];
\r
1664 calc.to.degit = 1;
\r
1665 var b = bezier(0,0, 0,0.5, 0.5,1, 1,1);
\r
1666 expect(calc.call()(0)).toBe(b(0).y+".0");
\r
1667 calc.to.from = from;
\r
1668 expect(calc.call()(1)).toBe(b(1).y+".0");
\r
1669 calc.to.from = from;
\r
1670 expect(calc.call()( b(0.5).x )).toBe(b(0.5).y.toFixed(1));
\r
1672 var ff = function(k) {
\r
1673 calc.keySplines = k;
\r
1674 calc.to.degit = 10;
\r
1675 var b = bezier(0,0, k[0],k[1], k[2],k[3], 1,1),
\r
1676 epsilon = 1e-5; //誤差
\r
1677 expect(calc.call()(0)).toBe(b(0).y.toFixed(10));
\r
1678 calc.to.from = from;
\r
1679 expect(calc.call()(1)).toBe(b(1).y.toFixed(10));
\r
1680 calc.to.from = from;
\r
1681 b = b(Math.random());
\r
1682 expect(Math.abs(calc.call()(b.x) - b.y.toFixed(10))).toBeLessThan(epsilon);
\r
1684 for (var i=0;i<10000;++i) {
\r
1685 var rand = [Math.random(), Math.random(), Math.random(), Math.random()].sort(function(a,b){return a-b;});
\r
1689 /*無効同値クラスを調べておく (Equivalence partitioning, the following is the invalid partion)*/
\r
1690 it("should be this for the value (the invalid partion on a spline mode )", function() {
\r
1691 calc.mode = "spline";
\r
1692 calc.keySplines = [0, NaN, 1, 1];
\r
1693 calc.to.degit = 1;
\r
1694 calc.to.from = from;
\r
1695 expect( calc.up().call()("undef")).toBe(Math.PI);
\r
1698 calc.keySplines = [0, 0, 1, 2];
\r
1699 calc.to.degit = 1;
\r
1700 calc.to.from = from;
\r
1701 expect( calc.up().call()("undef")).toBe(Math.PI);
\r
1703 calc.keySplines = null;
\r
1704 calc.to.degit = 1;
\r
1705 calc.to.from = from;
\r
1706 expect( calc.up().call()("undef")).toBe(Math.PI);
\r
1709 describe("A $attribute object", function() {
\r
1710 describe("A push method", function() {
\r
1712 beforeEach( function() {
\r
1713 attr = base("$calcMode").$attribute.up("width");
\r
1714 base("$frame").timelines.length = 0;
\r
1715 s = document.createElementNS("http:///www.w3.org/2000/svg", "animate");
\r
1717 afterEach( function() {
\r
1718 attr.isCSS = false;
\r
1720 /*境界条件を調べておく (limit value analysis)*/
\r
1721 it("should be this for the value (limit value analysis)", function() {
\r
1722 expect(attr.element).toBeNull();
\r
1723 expect(attr.push()).toBeNull();
\r
1724 expect(attr.element).toBeNull();
\r
1725 expect(attr.isCSS).toBeFalsy();
\r
1726 expect(base("$frame").timelines.length).toBe(0);
\r
1728 expect(attr.push(s)).toBeNull();
\r
1729 expect(attr.element).toBeNull();
\r
1730 expect(base("$frame").timelines.length).toBe(0);
\r
1731 expect(attr.hasAttrValues()).toBeFalsy();
\r
1733 var p = document.createElement("g");
\r
1735 expect(attr.push(s)).toBeNull();
\r
1736 expect(attr.element).toBe(p);
\r
1737 expect(base("$frame").timelines.length).toBe(0);
\r
1739 s.setAttribute("end", "0");
\r
1743 check("values", 4);
\r
1744 function check(attrName, num) {
\r
1745 s.setAttribute(attrName, "1");
\r
1746 expect(s.hasAttributeNS(null, attrName)).toBeTruthy();
\r
1747 var l = attr.push(s);
\r
1748 expect(attr.element).toBe(p);
\r
1749 var timelines = base("$frame").timelines;
\r
1750 expect(timelines.length).toBe(num);
\r
1751 var line = timelines[num-1];
\r
1752 expect(line.string).toBe("0");
\r
1753 expect(line).toBe(l); //タイムラインのオブジェクトを返す
\r
1754 var act = line.$activate;
\r
1755 expect(act.dur).toBeNull();
\r
1756 expect(act.end).toBe(0);
\r
1757 expect(act.repeatCount).toBeNull();
\r
1758 expect(act.repeatDur).toBeNull();
\r
1759 expect(act.min).toBe("0");
\r
1760 expect(act.max).toBe("indefinite");
\r
1761 expect(act.simpleDur).toBeNull();
\r
1762 expect(attr.hasAttrValues()).toBeTruthy();
\r
1764 s.removeAttribute(attrName);
\r
1765 expect(s.hasAttributeNS(null, attrName)).toBeFalsy();
\r
1767 expect(attr.element).toBe(p);
\r
1768 expect(timelines.length).toBe(num);
\r
1771 /*targetElement属性のサポート*/
\r
1772 var p2 = document.createElementNS("http://www.w3.org/2000/svg", "g");
\r
1773 document.documentElement.appendChild(p2);
\r
1774 p2.setAttributeNS(null, "id", "p23");
\r
1775 s.setAttributeNS(null, "targetElement", "p23");
\r
1777 expect(attr.element).toBe(p2);
\r
1780 var p3 = document.createElementNS("http://www.w3.org/2000/svg", "a");
\r
1781 document.documentElement.appendChild(p3);
\r
1782 p3.setAttributeNS(null, "id", "p34");
\r
1783 s.setAttributeNS("http://www.w3.org/1999/xlink", "xlink:href", "#p34");
\r
1785 expect(attr.element).toBe(p3);
\r
1787 /*attributeType属性のサポート*/
\r
1788 s.setAttributeNS(null, "attributeType", "CSS");
\r
1789 s.setAttributeNS(null, "values", "a;b;c");
\r
1791 expect(attr.isCSS).toBeTruthy();
\r
1793 /*同値分割をして、有効同値クラスを調べておく (Equivalence partitioning, the following is the valid partion)*/
\r
1794 it("should be this for the value (the valid partion )", function() {
\r
1795 s.setAttribute("from", "1");
\r
1796 var p = document.createElement("g");
\r
1798 var values = [ "0",
\r
1799 "0", null, null, null,
\r
1800 "0", "indefinite", null
\r
1803 check2("dur", "0");
\r
1804 check2("begin", "0");
\r
1806 check2("begin", "1");
\r
1808 check2("end", "0");
\r
1810 check2("repeatCount", "0");
\r
1812 check2("repeatDur", "0");
\r
1814 check2("min", "0");
\r
1816 check2("max", "0");
\r
1818 check2("begin", "12");
\r
1819 values[7] = 1000 * base("$frame").fpms;
\r
1821 check2("dur", "1");
\r
1822 function check2(attrName, value) {
\r
1823 s.setAttribute(attrName, value);
\r
1824 expect(s.hasAttributeNS(null, attrName)).toBeTruthy();
\r
1826 expect(attr.element).toBe(p);
\r
1827 var timelines = base("$frame").timelines;
\r
1828 var line = timelines[timelines.length-1];
\r
1829 expect(line.string).toBe(values[0]);
\r
1830 var act = line.$activate;
\r
1831 expect(act.dur).toBe(values[1]);
\r
1832 expect(act.end).toBe(values[2]);
\r
1833 expect(act.repeatCount).toBe(values[3]);
\r
1834 expect(act.repeatDur).toBe(values[4]);
\r
1835 expect(act.min).toBe(values[5]);
\r
1836 expect(act.max).toBe(values[6]);
\r
1837 expect(act.simpleDur).toBe(values[7]);
\r
1841 var p4 = document.createElementNS("http://www.w3.org/2000/svg", "g");
\r
1842 document.documentElement.appendChild(p4);
\r
1843 p4.appendChild(s);
\r
1844 p4.setAttributeNS(null, "style", "display: none");
\r
1846 expect(attr.setAttribute()).toBeUndefined();
\r
1847 expect(attr.setAttribute("block")).toBeUndefined();
\r
1848 expect(p4.hasAttributeNS(null, "display")).toBeFalsy();
\r
1849 expect(attr.isCSS).toBeFalsy();
\r
1851 s.setAttributeNS(null, "attributeName", "display");
\r
1853 expect(attr.setAttribute("block")).toBeUndefined();
\r
1854 expect(p4.hasAttributeNS(null, "display")).toBeFalsy();
\r
1855 expect(attr.isCSS).toBeTruthy();
\r
1856 expect(p4.style.getPropertyValue("display")).toBe("block");
\r
1858 p4 = document.createElementNS("http://www.w3.org/2000/svg", "g");
\r
1859 document.documentElement.appendChild(p4);
\r
1860 p4.appendChild(s);
\r
1861 p4.setAttributeNS(null, "style", "display: none");
\r
1863 expect(attr.setAttribute("block")).toBeUndefined();
\r
1864 expect(p4.hasAttributeNS(null, "display")).toBeFalsy();
\r
1865 expect(p4.style.getPropertyValue("display")).toBe("block");
\r
1866 expect(attr.removeAttribute()).toBeUndefined();
\r
1867 expect(p4.hasAttributeNS(null, "display")).toBeFalsy();
\r
1868 expect(p4.style.getPropertyValue("display")).toBe("none");
\r
1870 /*attributeType属性のサポート*/
\r
1871 s.setAttributeNS(null, "values", "a;b;c");
\r
1872 s.setAttributeNS(null, "attributeName", "display");
\r
1873 attr.isCSS = false;
\r
1875 expect(attr.isCSS).toBeTruthy();
\r
1877 /*無効同値クラスを調べておく (Equivalence partitioning, the following is the invalid partion)*/
\r
1878 it("should be this for the value (the invalid partion )", function() {
\r
1879 var p = document.createElement("g");
\r
1882 s.setAttributeNS(null, "begin", "1");
\r
1884 var timelines = base("$frame").timelines;
\r
1885 expect(timelines.length).toBe(0);
\r
1886 s.setAttributeNS(null, "from", "0");
\r
1888 expect(timelines.length).toBe(1);
\r
1889 expect(attr.push(12)).toBeNull();
\r
1892 describe("A setValues method", function() {
\r
1894 beforeEach( function() {
\r
1895 attr = base("$calcMode").$attribute.up("width");
\r
1896 base("$frame").timelines.length = 0;
\r
1897 s = document.createElement("animate");
\r
1899 /*境界条件を調べておく (limit value analysis)*/
\r
1900 it("should be this for the value (limit value analysis)", function() {
\r
1901 expect(attr.$from).not.toBeUndefined();
\r
1902 expect(attr.setValues()).toBeNull();
\r
1903 expect(attr.setValues("")).toBeNull();
\r
1905 expect(attr.setValues("0;1")[0].to.string).toBe("1");
\r
1906 expect(attr.setValues("0;1")[0].to.from.string).toBe("0");
\r
1907 expect(attr.setValues("0;1", "0", "1", "1")[0].to.from.string).toBe("0");
\r
1908 expect(attr.setValues("0;1", null, "1", "0")[0].to.from.string).toBe("0");
\r
1910 /*from-to アニメーション*/
\r
1911 expect(attr.setValues(null, "0", "1")[0].to.string).toBe("1");
\r
1912 expect(attr.setValues(null, "0", "1")[0].to.from.string).toBe("0");
\r
1914 /*from-by アニメーション*/
\r
1915 expect(attr.setValues(null, "1", null, "1")[0].to.string).toBe("1");
\r
1916 expect(attr.setValues(null, "1", null, "1")[0].to.from[0]).toBe(1);
\r
1917 expect(attr.setValues(null, "1", null, "1")[0].to.numList[0]).toBe(2);
\r
1919 /*fromなしto アニメーション*/
\r
1920 expect(attr.setValues(null, null, "1")[0].to.string).toBe("1");
\r
1921 expect(attr.setValues(null, null, "1")[0].to.from.string).toBe("0");
\r
1922 var aset = attr.setValues(null, null, "1")[0].to;
\r
1924 expect(aset.from[0]).toBe(0);
\r
1926 /*fromなしby アニメーション*/
\r
1927 expect(attr.setValues(null, null, null, "1")[0].to.string).toBe("1");
\r
1928 expect(attr.setValues(null, null, null, "1")[0].to.from[0]).toBe(0);
\r
1929 var aset = attr.setValues(null, null, null, "1")[0].to;
\r
1931 expect(aset.from[0]).toBe(0);
\r
1933 /*同値分割をして、有効同値クラスを調べておく (Equivalence partitioning, the following is the valid partion)*/
\r
1934 it("should be this for the value (the valid partion on a spline mode )", function() {
\r
1935 attr.$from.degit = 1;
\r
1936 var setv = attr.setValues("0;1")[0].call();
\r
1937 expect(setv(0.5)).toBe("0.5");
\r
1938 expect(setv(1)).toBe("1.0");
\r
1940 setv = attr.setValues(" 0;1; 2 ")[0].call();
\r
1941 expect(setv(0.5)).toBe("0.5");
\r
1942 expect(setv(1)).toBe("1.0");
\r
1943 setv = attr.setValues("0;1;2")[1].call();
\r
1944 expect(setv(0.4)).toBe("1.4");
\r
1945 expect(setv(1)).toBe("2.0");
\r
1947 attr.$from.degit = 2;
\r
1948 setv = attr.setValues("1;1;1;1 ;1;15.1")[4].call();
\r
1949 expect(setv(0.5)).toBe("8.05");
\r
1950 expect(setv(1)).toBe("15.10");
\r
1952 var v = attr.setValues("1;1;2;1;1;15.1");
\r
1953 setv = v[4].mix( {
\r
1956 expect(setv(0.05)).toBe("8.05");
\r
1957 expect(setv(0.1)).toBe("15.10");
\r
1958 setv = v[3].mix( {
\r
1961 expect(setv(0.01)).toBe("1.00");
\r
1962 expect(setv(0.1)).toBe("1.00");
\r
1963 setv = v[2].mix( {
\r
1966 expect(setv(0.25)).toBe("1.50");
\r
1967 expect(setv(0.5)).toBe("1.00");
\r
1969 /*無効同値クラスを調べておく (Equivalence partitioning, the following is the invalid partion)*/
\r
1970 it("should be this for the value (the invalid partion on a spline mode )", function() {
\r
1971 attr.$from.degit = 1;
\r
1972 expect(attr.setValues("")).toBeNull();
\r
1973 expect(attr.setValues(null, null, null, null)).toBeNull();
\r
1976 describe("A setKey method", function() {
\r
1978 beforeEach( function() {
\r
1979 attr = base("$calcMode").$attribute.up("width");
\r
1980 base("$frame").timelines.length = 0;
\r
1981 s = document.createElement("animate");
\r
1982 document.createElement("g").appendChild(s);
\r
1984 /*境界条件を調べておく (limit value analysis)*/
\r
1985 it("should be this for the value (limit value analysis)", function() {
\r
1986 expect(attr.setKey(s)).toBeNull();
\r
1988 s.setAttributeNS(null, "from", "0");
\r
1990 s.setAttributeNS(null, "to", "0");
\r
1991 expect(attr.setKey(s)[0].to.from.string).toBe("0");
\r
1992 expect(attr.setKey(s)[0].to.string).toBe("0");
\r
1993 s.setAttributeNS(null, "by", "0");
\r
1995 s.setAttributeNS(null, "values", "0;2");
\r
1996 expect(attr.setKey(s)[0].to.from.string).toBe("0");
\r
1997 expect(attr.setKey(s)[0].to.string).toBe("2");
\r
1999 s.setAttributeNS(null, "keyTimes", "0;0.1");
\r
2000 expect(attr.setKey(s)[0].keyTime).toBe(0.1);
\r
2002 s.setAttributeNS(null, "keySplines", "0,0.1,0.3,0.4");
\r
2003 expect(attr.setKey(s)[0].keySplines[0]).toBe(0);
\r
2004 expect(attr.setKey(s)[0].keySplines[1]).toBe(0.1);
\r
2005 expect(attr.setKey(s)[0].keySplines[2]).toBe(0.3);
\r
2006 expect(attr.setKey(s)[0].keySplines[3]).toBe(0.4);
\r
2008 s.setAttributeNS(null, "keySplines", "0 0.1 0.3 0.4");
\r
2009 expect(attr.setKey(s)[0].keySplines[0]).toBe(0);
\r
2010 expect(attr.setKey(s)[0].keySplines[1]).toBe(0.1);
\r
2011 expect(attr.setKey(s)[0].keySplines[2]).toBe(0.3);
\r
2012 expect(attr.setKey(s)[0].keySplines[3]).toBe(0.4);
\r
2014 /*同値分割をして、有効同値クラスを調べておく (Equivalence partitioning, the following is the valid partion)*/
\r
2015 it("should be this for the value (the valid partion on a spline mode )", function() {
\r
2016 s.setAttributeNS(null, "values", "0;2;12;30");
\r
2017 expect(attr.setKey(s)[0].keyTime.toFixed(3)).toBe("0.333");
\r
2018 s.setAttributeNS(null, "keyTimes", "0;0.1;0.2;1");
\r
2019 expect(attr.setKey(s)[0].keyTime).toBe(0.1);
\r
2020 expect(attr.setKey(s)[1].keyTime).toBe(0.1);
\r
2021 expect(attr.setKey(s)[2].keyTime).toBe(0.8);
\r
2022 s.setAttributeNS(null, "values", " 0; 2;12 ;30 ");
\r
2023 s.setAttributeNS(null, "keyTimes", " 0; 0.1; 0.2 ; 1 ");
\r
2024 expect(attr.setKey(s)[0].keyTime).toBe(0.1);
\r
2025 expect(attr.setKey(s)[1].keyTime).toBe(0.1);
\r
2026 expect(attr.setKey(s)[2].keyTime).toBe(0.8);
\r
2028 s.setAttributeNS(null, "keyTimes", " 0; .1; .2 ; 1 ");
\r
2029 expect(attr.setKey(s)[0].keyTime).toBe(0.1);
\r
2030 expect(attr.setKey(s)[1].keyTime).toBe(0.1);
\r
2031 expect(attr.setKey(s)[2].keyTime).toBe(0.8);
\r
2033 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
2034 f(0, 0,0.1,0.3,1);
\r
2035 f(1, 0.1,0.4,0.5,0.7);
\r
2036 f(2, 0.2,0.2,0.1,1);
\r
2038 s.setAttributeNS(null, "keySplines", " 0,.1,.3,1; .1,.4, .5,.7; .2, .2, .1 , 1 ;");
\r
2039 f(0, 0,0.1,0.3,1);
\r
2040 f(1, 0.1,0.4,0.5,0.7);
\r
2041 f(2, 0.2,0.2,0.1,1);
\r
2043 s.setAttributeNS(null, "keySplines", " 0 .1 .333,1; .1 .4 .5 .7; .2 .2 .1 1 ;");
\r
2044 f(0, 0,0.1,0.333,1);
\r
2045 f(1, 0.1,0.4,0.5,0.7);
\r
2046 f(2, 0.2,0.2,0.1,1);
\r
2047 function f (i, a, b, c, d) {
\r
2048 var splines = attr.setKey(s)[i].keySplines;
\r
2049 expect(splines[0]).toBe(a);
\r
2050 expect(splines[1]).toBe(b);
\r
2051 expect(splines[2]).toBe(c);
\r
2052 expect(splines[3]).toBe(d);
\r
2055 /*無効同値クラスを調べておく (Equivalence partitioning, the following is the invalid partion)*/
\r
2056 it("should be this for the value (the invalid partion on a spline mode )", function() {
\r
2057 s.setAttributeNS(null, "keyTimes", "0;0.1;0.2;1");
\r
2058 expect(attr.setKey(s)).toBeNull();
\r
2059 s.setAttributeNS(null, "values", "0;2;12");
\r
2060 expect(attr.setKey(s)).toBeNull();
\r
2061 s.setAttributeNS(null, "values", "0;2;12;20");
\r
2062 s.setAttributeNS(null, "keyTimes", "0;0.1;0.2");
\r
2063 expect(attr.setKey(s)).toBeNull();
\r
2067 describe("A $setElement object", function() {
\r
2068 describe("A timeline property", function() {
\r
2069 var $set, ele, frame;
\r
2070 beforeEach( function() {
\r
2071 $set = base("$calcMode").$attribute.$setElement.up();
\r
2072 var p = document.createElementNS("http://www.w3.org/2000/svg", "g");
\r
2073 ele = document.createElementNS("http://www.w3.org/2000/svg", "set");
\r
2074 p.appendChild(ele);
\r
2075 frame = base("$frame");
\r
2077 /*境界条件を調べておく (limit value analysis)*/
\r
2078 it("should be this for the value (limit value analysis)", function() {
\r
2079 expect($set.timeline).toBe(frame.$begin);
\r
2082 expect($set.timeline).toBe(frame.$begin);
\r
2083 expect($set.element).toBeNull();
\r
2086 describe("An checkEnd method", function() {
\r
2087 var $set, ele, frame;
\r
2088 beforeEach( function() {
\r
2089 $set = base("$calcMode").$attribute.$setElement.up();
\r
2090 var p = document.createElementNS("http://www.w3.org/2000/svg", "g");
\r
2091 ele = document.createElementNS("http://www.w3.org/2000/svg", "set");
\r
2092 p.appendChild(ele);
\r
2093 frame = base("$frame");
\r
2095 /*境界条件を調べておく (limit value analysis)*/
\r
2096 it("should be this for the value (limit value analysis)", function() {
\r
2097 expect($set.checkEnd()).toBeFalsy();
\r
2099 frame.setFrame(0);
\r
2100 frame.$endFrame.setFrame(0);
\r
2101 expect($set.checkEnd()).toBeFalsy();
\r
2103 /*同値分割をして、有効同値クラスを調べておく (Equivalence partitioning, the following is the valid partion)*/
\r
2104 it("should be this for the value (the valid partion)", function() {
\r
2105 ele.setAttributeNS(null, "dur", "1s");
\r
2106 ele.setAttributeNS(null, "attributeName", "fill");
\r
2107 ele.setAttributeNS(null, "to", "red");
\r
2109 expect($set.checkEnd(0)).toBeFalsy();
\r
2110 expect($set.checkEnd(24)).toBeFalsy();
\r
2111 $set.state = "playing";
\r
2112 expect($set.checkEnd(25)).toBeTruthy();
\r
2113 expect($set.state).toBe("idling");
\r
2114 expect($set.checkEnd(26)).toBeFalsy();
\r
2116 /*無効同値クラスを調べておく (Equivalence partitioning, the following is the invalid partion)*/
\r
2117 it("should be this for the value (the invalid partion)", function() {
\r
2118 $set.timeline.isResolved = false;
\r
2119 expect($set.checkEnd(0)).toBeFalsy();
\r
2120 $set.timeline.activeTime = null;
\r
2121 expect($set.checkEnd(0)).toBeFalsy();
\r
2122 $set.timeline = null;
\r
2123 expect(function() {
\r
2129 describe("An init method", function() {
\r
2130 var $set, ele, frame;
\r
2131 beforeEach( function() {
\r
2132 $set = base("$calcMode").$attribute.$setElement.up();
\r
2133 var p = document.createElementNS("http://www.w3.org/2000/svg", "g");
\r
2134 ele = document.createElementNS("http://www.w3.org/2000/svg", "set");
\r
2135 p.appendChild(ele);
\r
2136 frame = base("$frame");
\r
2138 /*境界条件を調べておく (limit value analysis)*/
\r
2139 it("should be this for the value (limit value analysis)", function() {
\r
2140 expect($set.to).toBe("");
\r
2141 expect($set.attrName).toBe("");
\r
2142 expect($set.defaultValue).toBe("");
\r
2143 expect($set.isDefault).toBeFalsy();
\r
2144 expect($set.attrNameSpace).toBeNull();
\r
2146 expect($set.timeline).toBe(frame.$begin);
\r
2148 expect($set.to).toBe("");
\r
2149 expect($set.attrName).toBe("");
\r
2150 expect($set.isDefault).toBeFalsy();
\r
2151 expect($set.attrNameSpace).toBeNull();
\r
2152 expect($set.timeline).toBe(frame.$begin);
\r
2154 /*同値分割をして、有効同値クラスを調べておく (Equivalence partitioning, the following is the valid partion)*/
\r
2155 it("should be this for the value (the valid partion )", function() {
\r
2156 ele.setAttributeNS(null, "to", "t1");
\r
2158 expect($set.to).toBe("t1");
\r
2159 expect($set.attrName).toBe("");
\r
2160 expect($set.defaultValue).toBe("");
\r
2162 ele.setAttributeNS(null, "attributeName", "tt1");
\r
2164 expect($set.to).toBe("t1");
\r
2165 expect($set.attrName).toBe("tt1");
\r
2166 expect($set.defaultValue).toBe("");
\r
2168 ele.parentNode.setAttributeNS(null, "tt1", "undef");
\r
2170 expect($set.defaultValue).toBe("undef");
\r
2171 expect($set.isDefault).toBeTruthy();
\r
2173 ele.setAttributeNS(null, "attributeName", "font-size");
\r
2174 ele.parentNode.style.setProperty("font-size", "12px");
\r
2176 expect($set.defaultValue).toBe("12px");
\r
2177 expect($set.isDefault).toBeFalsy();
\r
2179 ele.setAttributeNS(null, "attributeName", "xlink:href");
\r
2181 expect($set.to).toBe("t1");
\r
2182 expect($set.attrName).toBe("xlink:href");
\r
2183 expect($set.defaultValue).toBe("");
\r
2184 ele.parentNode.setAttributeNS("http://www.w3.org/1999/xlink", "xlink:href", "undef");
\r
2186 expect($set.attrNameSpace).toBe("http://www.w3.org/1999/xlink");
\r
2188 /*無効同値クラスを調べておく (Equivalence partitioning, the following is the invalid partion)*/
\r
2189 it("should be this for the value (the invalid partion on a spline mode )", function() {
\r
2191 expect($set.to).toBe("");
\r
2192 expect($set.attrName).toBe("");
\r
2193 expect($set.defaultValue).toBe("");
\r
2196 expect($set.to).toBe("");
\r
2197 expect($set.attrName).toBe("");
\r
2198 expect($set.defaultValue).toBe("");
\r
2201 describe("Frame Set", function() {
\r
2202 var $set, ele, frame;
\r
2203 beforeEach( function() {
\r
2204 $set = base("$calcMode").$attribute.$setElement.up();
\r
2205 var p = document.createElementNS("http://www.w3.org/2000/svg", "g");
\r
2206 ele = document.createElementNS("http://www.w3.org/2000/svg", "set");
\r
2207 p.appendChild(ele);
\r
2208 frame = base("$frame");
\r
2209 frame.timelines.length = frame.$endFrame.timelines.length = 0; //配列の初期化
\r
2210 frame.startTime = Date.now();
\r
2211 frame.setFrame(0);
\r
2212 frame.$endFrame.setFrame(0);
\r
2214 afterEach( function() {
\r
2215 $set.isCSS = false;
\r
2217 /*境界条件を調べておく (limit value analysis)*/
\r
2218 it("should be this for the value (limit value analysis)", function() {
\r
2219 expect($set.isEnd).toBeFalsy();
\r
2220 expect($set.state).toBe("idling");
\r
2221 ele.setAttributeNS(null, "dur", "1s");
\r
2222 ele.setAttributeNS(null, "attributeName", "fill");
\r
2223 ele.setAttributeNS(null, "to", "red");
\r
2225 /*テストしやすくするために、CSSではなくXML属性として扱う*/
\r
2226 $set.isCSS = false;
\r
2227 expect($set.timeline).not.toBe(frame.$begin);
\r
2228 frame.setFrame(0);
\r
2229 frame.$endFrame.setFrame(0);
\r
2230 expect(ele.parentNode.getAttributeNS(null, "fill")).toBe("red");
\r
2231 expect($set.state).toBe("playing");
\r
2233 frame.setFrame(24);
\r
2234 frame.$endFrame.setFrame(24);
\r
2235 expect(ele.parentNode.hasAttributeNS(null, "fill")).toBeFalsy();
\r
2236 expect($set.state).toBe("idling");
\r
2238 /*同値分割をして、有効同値クラスを調べておく (Equivalence partitioning, the following is the valid partion)*/
\r
2239 it("should be this for the value (the valid partion)", function() {
\r
2240 ele.setAttributeNS(null, "begin", "1s");
\r
2241 ele.setAttributeNS(null, "dur", "1s");
\r
2242 ele.setAttributeNS(null, "attributeName", "fill");
\r
2243 ele.setAttributeNS(null, "to", "red");
\r
2245 /*テストしやすくするために、CSSではなくXML属性として扱う*/
\r
2246 $set.isCSS = false;
\r
2247 var f = function(num) {
\r
2248 frame.setFrame(num);
\r
2249 frame.$endFrame.setFrame(num);
\r
2250 expect(ele.parentNode.getAttributeNS(null, "fill") || null).toBeNull();
\r
2255 frame.setFrame(24);
\r
2256 frame.$endFrame.setFrame(24);
\r
2257 expect(ele.parentNode.getAttributeNS(null, "fill")).toBe("red");
\r
2258 frame.setFrame(25);
\r
2259 frame.$endFrame.setFrame(25);
\r
2260 expect(ele.parentNode.getAttributeNS(null, "fill")).toBe("red");
\r
2264 ele.setAttributeNS(null, "fill", "freeze");
\r
2266 $set.isCSS = false;
\r
2270 frame.setFrame(24);
\r
2271 frame.$endFrame.setFrame(24);
\r
2272 expect(ele.parentNode.getAttributeNS(null, "fill")).toBe("red");
\r
2273 frame.setFrame(25);
\r
2274 frame.$endFrame.setFrame(25);
\r
2275 expect(ele.parentNode.getAttributeNS(null, "fill")).toBe("red");
\r
2276 frame.setFrame(48);
\r
2277 frame.$endFrame.setFrame(48);
\r
2278 expect(ele.parentNode.getAttributeNS(null, "fill") || null).toBe("red");
\r
2279 frame.setFrame(49);
\r
2280 frame.$endFrame.setFrame(49);
\r
2281 expect(ele.parentNode.getAttributeNS(null, "fill") || null).toBe("red");
\r
2282 ele.setAttributeNS(null, "begin", "1s");
\r
2283 ele.setAttributeNS(null, "attributeName", "fill");
\r
2284 ele.setAttributeNS(null, "to", "red");
\r
2285 /*eleにはdur属性やendなどが設定されていなくとも、アニメーションが有効*/
\r
2287 $set.isCSS = false;
\r
2288 var f = function(num) {
\r
2289 frame.setFrame(num);
\r
2290 frame.$endFrame.setFrame(num);
\r
2291 expect(ele.parentNode.getAttributeNS(null, "fill") || null).toBe("red");
\r
2299 /*無効同値クラスを調べておく (Equivalence partitioning, the following is the invalid partion)*/
\r
2300 it("should be this for the value (the invalid partion)", function() {
\r
2305 describe("A $animateElement object", function() {
\r
2306 describe("An init method", function() {
\r
2307 var $animate, ele, frame;
\r
2308 beforeEach( function() {
\r
2309 $animate = base("$calcMode").$attribute.$setElement.$animateElement.up();
\r
2310 var p = document.createElementNS("http://www.w3.org/2000/svg", "g");
\r
2311 ele = document.createElementNS("http://www.w3.org/2000/svg", "animate");
\r
2312 p.appendChild(ele);
\r
2313 frame = base("$frame");
\r
2314 frame.timelines.length = 0;
\r
2315 frame.startTime = Date.now();
\r
2316 frame.setFrame(0);
\r
2317 frame.$endFrame.setFrame(0);
\r
2319 /*境界条件を調べておく (limit value analysis)*/
\r
2320 it("should be this for the value (limit value analysis)", function() {
\r
2323 ele.setAttributeNS(null, "begin", "1s");
\r
2324 ele.setAttributeNS(null, "dur", "1s");
\r
2325 ele.setAttributeNS(null, "attributeName", "d");
\r
2326 ele.setAttributeNS(null, "from", "M20 0 L20 30");
\r
2327 ele.setAttributeNS(null, "to", "M20 20 L10 30");
\r
2328 $animate.init(ele);
\r
2329 expect($animate.isCSS).toBeFalsy();
\r
2330 frame.setFrame(0);
\r
2331 frame.$endFrame.setFrame(0);
\r
2332 var p = ele.parentNode;
\r
2333 /*getAttributeNSメソッドは、IE11では空文字列を返す(DOM 2に準拠)のに対して、
\r
2334 * 他のブラウザではnullを返すため、その対策をする*/
\r
2335 expect(p.getAttributeNS(null, "d") || null).toBeNull();
\r
2337 function f(fr, result) {
\r
2338 frame.setFrame(fr);
\r
2339 frame.$endFrame.setFrame(fr);
\r
2340 expect(p.getAttributeNS(null, "d") || "").toBe(result);
\r
2343 f(24, "M20.0 0.0 L20.0 30.0");
\r
2344 f(36, "M20.0 10.0 L15.0 30.0");
\r
2347 ele.setAttributeNS(null, "fill", "freeze");
\r
2348 $animate.init(ele);
\r
2349 f(24, "M20.0 0.0 L20.0 30.0");
\r
2350 f(36, "M20.0 10.0 L15.0 30.0");
\r
2351 f(48, "M20.0 20.0 L10.0 30.0");
\r
2353 frame.timelines.length = 0;
\r
2354 ele.setAttributeNS(null, "calcMode", "discrete");
\r
2355 $animate.init(ele);
\r
2356 expect($animate.isCSS).toBeFalsy();
\r
2357 expect($animate.mode).toBe("discrete");
\r
2358 f(24, "M20.0 0.0 L20.0 30.0");
\r
2359 f(25, "M20.0 0.0 L20.0 30.0");
\r
2360 f(37, "M20.0 20.0 L10.0 30.0");
\r
2361 f(48, "M20.0 20.0 L10.0 30.0");
\r
2363 [ ["display", "inline", "none"],
\r
2364 ["visibility", "hidden", "visible"],
\r
2365 ["stroke-linecap", "round", "square"],
\r
2366 ["font-style", "italic", "normal"]
\r
2367 ].forEach( function(attr) {
\r
2368 var attrName = attr[0],
\r
2371 function g(fr, result) {
\r
2372 frame.setFrame(fr);
\r
2373 frame.$endFrame.setFrame(fr);
\r
2374 expect(p.style.getPropertyValue(attrName) || p.getAttribute(attrName) || "").toBe(result);
\r
2378 ele.setAttributeNS(null, "from", from);
\r
2379 ele.setAttributeNS(null, "to", to);
\r
2380 frame.timelines.length = 0;
\r
2381 ele.setAttributeNS(null, "calcMode", "linear");
\r
2382 ele.setAttributeNS(null, "attributeName", attrName);
\r
2383 $animate.init(ele);
\r
2384 expect($animate.mode).toBe("discrete");
\r
2391 /*同値分割をして、有効同値クラスを調べておく (Equivalence partitioning, the following is the valid partion)*/
\r
2392 it("should be this for the value (the valid partion )", function() {
\r
2394 ele.setAttributeNS(null, "begin", "0s");
\r
2395 ele.setAttributeNS(null, "dur", "100s");
\r
2396 ele.setAttributeNS(null, "attributeName", "d");
\r
2397 ele.setAttributeNS(null, "fill", "freeze");
\r
2398 ele.setAttributeNS(null, "from", "M20 0 L20 30");
\r
2399 ele.setAttributeNS(null, "to", "M20 2400 L20 30");
\r
2400 $animate.init(ele);
\r
2402 var p = ele.parentNode;
\r
2403 expect(p.getAttributeNS(null, "d") || null).toBeNull();
\r
2405 function f(fr, result) {
\r
2406 frame.setFrame(fr);
\r
2407 frame.$endFrame.setFrame(fr);
\r
2408 expect(p.getAttributeNS(null, "d")).toBe(result);
\r
2411 for (var i=0;i<2400;++i) {
\r
2412 f(i, "M20.0 " +i+ ".0 L20.0 30.0");
\r
2414 f(2401, "M20.0 2400.0 L20.0 30.0");
\r
2417 frame.timelines.length = 0;
\r
2418 ele.setAttributeNS(null, "begin", "0s");
\r
2419 ele.setAttributeNS(null, "dur", "1s");
\r
2420 ele.setAttributeNS(null, "repeatDur", "2s");
\r
2421 ele.setAttributeNS(null, "attributeName", "d");
\r
2422 ele.setAttributeNS(null, "fill", "freeze");
\r
2423 ele.setAttributeNS(null, "from", "M20 0 L20 30");
\r
2424 ele.setAttributeNS(null, "to", "M20 24 L20 30");
\r
2425 $animate.init(ele);
\r
2426 f(23, "M20.0 23.0 L20.0 30.0");
\r
2427 f(24, "M20.0 0.0 L20.0 30.0");
\r
2428 f(25, "M20.0 1.0 L20.0 30.0");
\r
2429 f(48, "M20.0 24.0 L20.0 30.0");
\r
2431 frame.timelines.length = 0;
\r
2432 ele.setAttributeNS(null, "begin", "0s");
\r
2433 ele.setAttributeNS(null, "dur", "2s");
\r
2434 ele.setAttributeNS(null, "attributeName", "d");
\r
2435 ele.setAttributeNS(null, "fill", "freeze");
\r
2436 ele.setAttributeNS(null, "values", "M20 0 L20 30;M20 24 L20 30;M20 26.4 L20 30");
\r
2437 $animate.init(ele);
\r
2438 f(0, "M20.0 0.0 L20.0 30.0");
\r
2439 f(1, "M20.0 1.0 L20.0 30.0");
\r
2440 f(24, "M20.0 24.0 L20.0 30.0");
\r
2441 f(25, "M20.0 24.1 L20.0 30.0");
\r
2442 f(47, "M20.0 26.3 L20.0 30.0");
\r
2443 f(48, "M20.0 26.4 L20.0 30.0");
\r
2444 f(49, "M20.0 26.4 L20.0 30.0");
\r
2445 f(50, "M20.0 26.4 L20.0 30.0");
\r
2447 frame.timelines.length = 0;
\r
2448 ele.setAttributeNS(null, "begin", "0s");
\r
2449 ele.setAttributeNS(null, "end", "2s");
\r
2450 ele.removeAttributeNS(null, "dur"); //単純継続時間が設定されていない場合
\r
2451 ele.removeAttributeNS(null, "repeatDur");
\r
2452 ele.setAttributeNS(null, "attributeName", "d");
\r
2453 ele.setAttributeNS(null, "fill", "freeze");
\r
2454 ele.setAttributeNS(null, "values", "M20 0 L20 30;M20 24 L20 30;M20 26.4 L20 30");
\r
2455 $animate.init(ele);
\r
2456 f(0, "M20.0 0.0 L20.0 30.0");
\r
2457 f(1, "M20.0 0.0 L20.0 30.0");
\r
2458 f(24, "M20.0 0.0 L20.0 30.0");
\r
2459 f(25, "M20.0 0.0 L20.0 30.0");
\r
2460 f(47, "M20.0 0.0 L20.0 30.0");
\r
2461 f(48, "M20.0 0.0 L20.0 30.0");
\r
2462 f(49, "M20.0 0.0 L20.0 30.0");
\r
2463 f(50, "M20.0 0.0 L20.0 30.0");
\r
2465 frame.timelines.length = 0;
\r
2466 ele.setAttributeNS(null, "dur", "2s");
\r
2467 ele.setAttributeNS(null, "fill", "remove");
\r
2468 var attrValue = p.getAttributeNS(null, "d");
\r
2469 $animate.init(ele);
\r
2472 frame.timelines.length = 0;
\r
2473 p.removeAttributeNS(null, "d");
\r
2474 ele.setAttributeNS(null, "fill", "freeze");
\r
2475 ele.setAttributeNS(null, "keyTimes", "0;0.1;1");
\r
2476 $animate.init(ele);
\r
2477 f(1, "M20.0 5.0 L20.0 30.0");
\r
2478 f(48, "M20.0 26.4 L20.0 30.0");
\r
2480 frame.timelines.length = 0;
\r
2481 ele.setAttributeNS(null, "fill", "freeze");
\r
2482 ele.setAttributeNS(null, "calcMode", "discrete");
\r
2483 ele.setAttributeNS(null, "keyTimes", "0;0.5;0.6");
\r
2484 $animate.init(ele);
\r
2485 f(1, "M20.0 0.0 L20.0 30.0");
\r
2486 f(4, "M20.0 0.0 L20.0 30.0");
\r
2487 /*本来は24フレーム目で、変化するはずだが、不具合があるため、そうならない
\r
2489 f(24, "M20.0 24.0 L20.0 30.0");
\r
2490 f(25, "M20.0 24.0 L20.0 30.0");
\r
2491 f(29, "M20.0 26.4 L20.0 30.0");
\r
2492 f(48, "M20.0 26.4 L20.0 30.0");
\r
2494 frame.timelines.length = 0;
\r
2495 ele.setAttributeNS(null, "calcMode", "spline");
\r
2496 ele.removeAttributeNS(null, "keyTimes");
\r
2497 ele.setAttributeNS(null, "keySplines", "0,0,1,1;0,0,1,1;.75,0,0,.75");
\r
2498 ele.removeAttributeNS(null, "end");
\r
2499 ele.setAttributeNS(null, "dur", "9s");
\r
2500 ele.setAttributeNS(null, "values", "210;177;121;10");
\r
2501 $animate.init(ele);
\r
2508 frame.timelines.length = 0;
\r
2509 ele.setAttributeNS(null, "calcMode", "spline");
\r
2510 ele.setAttributeNS(null, "keyTimes", "0;.25;.5;1");
\r
2511 ele.setAttributeNS(null, "keySplines", "0,0,1,1;0,0,1,1;1,0,0,1");
\r
2512 ele.setAttributeNS(null, "dur", "8s");
\r
2513 ele.setAttributeNS(null, "values", "300;255;180;30");
\r
2514 $animate.init(ele);
\r
2522 frame.timelines.length = 0;
\r
2523 ele.setAttributeNS(null, "begin", "click");
\r
2524 ele.setAttributeNS(null, "calcMode", "spline");
\r
2525 ele.setAttributeNS(null, "keyTimes", "0;.25;.5;1");
\r
2526 ele.setAttributeNS(null, "keySplines", "0,0,1,1;0,0,1,1;1,0,0,1");
\r
2527 ele.setAttributeNS(null, "dur", "8s");
\r
2528 ele.setAttributeNS(null, "values", "300;255;180;30");
\r
2529 ele.parentNode.setAttributeNS(null, "d", "300");
\r
2530 $animate.init(ele);
\r
2537 ( function(attrName) {
\r
2538 function g(fr, result) {
\r
2539 frame.setFrame(fr);
\r
2540 frame.$endFrame.setFrame(fr);
\r
2541 expect(p.style.getPropertyValue(attrName)).toBe(result);
\r
2544 frame.timelines.length = 0;
\r
2545 ele.setAttributeNS(null, "begin", "0s");
\r
2546 ele.setAttributeNS(null, "calcMode", "linear");
\r
2547 ele.setAttributeNS(null, "attributeName", attrName);
\r
2548 ele.setAttributeNS(null, "keyTimes", "0;.25;.5;1");
\r
2549 ele.setAttributeNS(null, "keySplines", "0,0,1,1;0,0,1,1;1,0,0,1");
\r
2550 ele.setAttributeNS(null, "dur", "8s");
\r
2551 ele.setAttributeNS(null, "values", "inline;block;inline;block");
\r
2552 $animate.init(ele);
\r
2553 expect($animate.mode).toBe("discrete");
\r
2560 frame.timelines.length = 0;
\r
2561 ele.setAttributeNS(null, "begin", "click");
\r
2562 ele.setAttributeNS(null, "calcMode", "linear");
\r
2563 ele.setAttributeNS(null, "attributeName", attrName);
\r
2564 ele.setAttributeNS(null, "keyTimes", "0;.25;.5;1");
\r
2565 ele.setAttributeNS(null, "keySplines", "0,0,1,1;0,0,1,1;1,0,0,1");
\r
2566 ele.setAttributeNS(null, "dur", "8s");
\r
2567 ele.setAttributeNS(null, "values", "inline;block;inline;block");
\r
2568 $animate.init(ele);
\r
2569 var evt = ele.ownerDocument.createEvent("MouseEvents");
\r
2570 evt.initMouseEvent("click",true, true, window, 0, 0, 0, 0, 0, false, false, false, false,0, p);
\r
2571 p.dispatchEvent(evt);
\r
2572 var cur = base("$frame").currentFrame;
\r
2573 expect($animate.mode).toBe("discrete");
\r
2574 g(cur+0, "inline");
\r
2575 g(cur+48, "block");
\r
2576 g(cur+96, "inline");
\r
2577 g(cur+192, "block");
\r
2578 g(cur+300, "block");
\r
2581 /*無効同値クラスを調べておく (Equivalence partitioning, the following is the invalid partion)*/
\r
2582 it("should be this for the value (the invalid partion )", function() {
\r
2583 ele.setAttributeNS(null, "begin", "0s");
\r
2584 ele.setAttributeNS(null, "dur", "100s");
\r
2585 ele.setAttributeNS(null, "attributeName", "d");
\r
2586 ele.setAttributeNS(null, "fill", "freeze");
\r
2587 ele.setAttributeNS(null, "from", "M20 0 L20 30");
\r
2588 ele.setAttributeNS(null, "to", "M20 2400 L20 30");
\r
2589 ele.setAttributeNS(null, "keyTimes", "0;0.1;1");
\r
2590 $animate.init(ele);
\r
2592 var p = ele.parentNode;
\r
2593 expect(p.getAttributeNS(null, "d") || null).toBeNull();
\r
2595 function f(fr, result) {
\r
2596 frame.setFrame(fr);
\r
2597 frame.$endFrame.setFrame(fr);
\r
2598 expect(p.getAttributeNS(null, "d") || null).toBe(result);
\r
2603 frame.timelines.length = 0;
\r
2604 /*keyTimes属性のリストの個数がvaluesリストと合致しない*/
\r
2605 ele.setAttributeNS(null, "keyTimes", "0;0.1;0.5;1");
\r
2606 ele.setAttributeNS(null, "values", "M20 0 L20 30;M20 24 L20 30;M20 26.4 L20 30");
\r
2607 $animate.init(ele);
\r
2611 /*keyTimes属性が0から始まっていない*/
\r
2612 frame.timelines.length = 0;
\r
2613 ele.setAttributeNS(null, "keyTimes", "0.1;0.3;1");
\r
2617 function ff(mode) {
\r
2618 ele.setAttributeNS(null, "calcMode", mode);
\r
2619 $animate.init(ele);
\r
2624 frame.timelines.length = 0;
\r
2625 ele.setAttributeNS(null, "calcMode", "spline");
\r
2626 $animate.init(ele);
\r
2627 expect($animate.mode).toBe("spline");
\r
2633 describe("RGB Color", function() {
\r
2634 var $animate, ele, frame, f;
\r
2635 beforeEach( function() {
\r
2636 $animate = base("$calcMode").$attribute.$setElement.$animateElement.up();
\r
2637 var p = document.createElementNS("http://www.w3.org/2000/svg", "g");
\r
2638 ele = document.createElementNS("http://www.w3.org/2000/svg", "animate");
\r
2639 p.appendChild(ele);
\r
2640 frame = base("$frame");
\r
2641 frame.timelines.length = 0;
\r
2643 f = function (fr, result, attr) {
\r
2644 frame.setFrame(fr);
\r
2645 frame.$endFrame.setFrame(fr);
\r
2646 expect(p.style.getPropertyValue(attr).replace(/\s/g, "")).toBe(result.replace(/\s/g, ""));
\r
2649 /*境界条件を調べておく (limit value analysis)*/
\r
2650 it("should be this for the value (limit value analysis)", function() {
\r
2651 ele.setAttributeNS(null, "begin", "0s");
\r
2652 ele.setAttributeNS(null, "dur", "1s");
\r
2653 ele.setAttributeNS(null, "attributeName", "fill");
\r
2654 ele.setAttributeNS(null, "fill", "remove");
\r
2655 ele.setAttributeNS(null, "from", "rgb(0, 0, 0)");
\r
2656 ele.setAttributeNS(null, "to", "rgb(10, 10, 1)");
\r
2657 $animate.init(ele);
\r
2659 f(0, "rgb(0, 0, 0)", "fill");
\r
2660 f(23, "rgb(10, 10, 1)", "fill");
\r
2662 frame.timelines.length = 0;
\r
2663 ele.setAttributeNS(null, "attributeName", "stroke");
\r
2664 $animate.init(ele);
\r
2665 f(0, "rgb(0, 0, 0)", "stroke");
\r
2666 f(23, "rgb(10, 10, 1)", "stroke");
\r
2668 frame.timelines.length = 0;
\r
2669 ele.setAttributeNS(null, "attributeName", "stop-color");
\r
2670 $animate.init(ele);
\r
2671 f(0, "rgb(0,0,0)", "stop-color");
\r
2672 f(23, "rgb(10,10,1)", "stop-color");
\r
2674 frame.timelines.length = 0;
\r
2675 ele.setAttributeNS(null, "attributeName", "color");
\r
2676 $animate.init(ele);
\r
2677 f(0, "rgb(0,0,0)", "color");
\r
2678 f(23, "rgb(10,10,1)", "color");
\r
2680 /*同値分割をして、有効同値クラスを調べておく (Equivalence partitioning, the following is the valid partion)*/
\r
2681 it("should be this for the value (the valid partion )", function() {
\r
2682 ele.setAttributeNS(null, "begin", "0s");
\r
2683 ele.setAttributeNS(null, "dur", "1s");
\r
2684 ele.setAttributeNS(null, "attributeName", "fill");
\r
2685 ele.setAttributeNS(null, "fill", "remove");
\r
2686 ele.setAttributeNS(null, "values", "rgb(0, 0, 0);rgb(24, 2.4, 1)");
\r
2687 $animate.init(ele);
\r
2689 f(0, "rgb(0, 0, 0)", "fill");
\r
2690 f(1, "rgb(1, 0, 0)", "fill");
\r
2691 f(23, "rgb(23, 2, 1)", "fill");
\r
2693 frame.timelines.length = 0;
\r
2694 ele.setAttributeNS(null, "values", "#00083C;#18203C");
\r
2695 $animate.init(ele);
\r
2698 f(0, "rgb(0, 8, 60)", "fill");
\r
2699 f(1, "rgb(1, 9, 60)", "fill");
\r
2700 f(23, "rgb(23, 31, 60)", "fill");
\r
2702 frame.timelines.length = 0;
\r
2703 ele.setAttributeNS(null, "fill", "freeze");
\r
2704 ele.setAttributeNS(null, "values", "black;white");
\r
2705 $animate.init(ele);
\r
2706 /*色キーワードをrgb形式に変換*/
\r
2708 f(0, "rgb(0, 0, 0)", "fill");
\r
2709 f(12, "rgb(128, 128, 128)", "fill");
\r
2710 f(24, "rgb(255, 255, 255)", "fill");
\r
2712 /*無効同値クラスを調べておく (Equivalence partitioning, the following is the invalid partion)*/
\r
2713 it("should be this for the value (the invalid partion )", function() {
\r
2714 ele.setAttributeNS(null, "begin", "0s");
\r
2715 ele.setAttributeNS(null, "dur", "1s");
\r
2716 ele.setAttributeNS(null, "attributeName", "fi");
\r
2717 ele.setAttributeNS(null, "fill", "remove");
\r
2718 ele.setAttributeNS(null, "values", "#00083C;#00107C");
\r
2719 $animate.init(ele);
\r
2722 function f (fr, result, attr) {
\r
2723 frame.setFrame(fr);
\r
2724 frame.$endFrame.setFrame(fr);
\r
2725 expect(ele.parentNode.getAttributeNS(null,attr)).toBe(result);
\r
2727 f(0, "#83.0C", "fi");
\r
2728 f(1, "#84.0C", "fi");
\r
2729 f(23, "#106.0C", "fi");
\r
2732 describe("$frame.$svgEvent object", function() {
\r
2733 var frame = base("$frame").$svgEvent,
\r
2735 base("$frame").pauseAnimation();
\r
2736 beforeEach( function() {
\r
2737 base("$frame").pauseAnimation();
\r
2738 frame = frame.up().mix( {isResolved: true} );
\r
2739 frame.first = null;
\r
2740 /*firstプロパティとtimelinesプロパティは$frameオブジェクトのフレーム進行に
\r
2741 * 影響を受けるため、新たに初期化しておく*/
\r
2742 base("$frame").timelines = frame.timelines = [];
\r
2743 frame.lastTimeLine = null;
\r
2744 p = document.createElementNS("http://www.w3.org/2000/svg", "g");
\r
2745 ele = document.createElementNS("http://www.w3.org/2000/svg", "animate");
\r
2746 p.appendChild(ele);
\r
2748 /*境界条件を調べておく (limit value analysis)*/
\r
2749 it("should be this for the value (limit value analysis)", function() {
\r
2750 base("$frame").pauseAnimation();
\r
2751 frame.lastTimeLine = null;
\r
2752 expect(frame.lastTimeLine).toBeNull();
\r
2753 expect(frame.first).toBeNull();
\r
2754 frame.setTimeTable();
\r
2755 expect(frame.first).toBeNull();
\r
2756 frame.addLine( base("$frame").$begin.up().mix({
\r
2763 frame.setTimeTable();
\r
2764 expect(frame.first).toEqual(
\r
2766 eventType: "begin",
\r
2777 /*同値分割をして、有効同値クラスを調べておく (Equivalence partitioning, the following is the valid partion)*/
\r
2778 it("should be this for the value (the valid partion )", function() {
\r
2779 base("$frame").pauseAnimation();
\r
2780 frame.addLine( base("$frame").$begin.up().mix({
\r
2787 frame.setTimeTable();
\r
2788 frame.setTimeTable();
\r
2789 expect(frame.first).toEqual(
\r
2791 eventType: "begin",
\r
2801 frame.setTimeTable();
\r
2802 frame.setTimeTable();
\r
2803 expect(frame.first).toEqual(
\r
2805 eventType: "begin",
\r
2816 var isFiredBeginEvent = false;
\r
2817 ele.addEventListener("beginEvent", function(evt) {
\r
2818 isFiredBeginEvent = true;
\r
2819 expect(evt.target).toBe(ele);
\r
2821 ele.addEventListener("endEvent", function(evt) {
\r
2822 expect(evt.target).toBe(ele);
\r
2823 expect(isFiredBeginEvent).toBeTruthy();
\r
2825 frame.setFrame(0);
\r
2826 frame.$endFrame.setFrame(0);
\r
2827 expect(frame.first).toBeNull();
\r
2828 frame.setFrame(0);
\r
2829 frame.$endFrame.setFrame(0);
\r
2830 expect(frame.first).toBeNull();
\r
2832 frame.timelines = [];
\r
2833 frame.addLine( base("$frame").$begin.up().mix({
\r
2840 frame.setTimeTable();
\r
2841 var a = { frame: 0,
\r
2842 eventType: "begin",
\r
2845 next: { frame: 10,
\r
2851 expect(frame.first).toEqual(a);
\r
2853 frame.addLine( base("$frame").$begin.up().mix({
\r
2857 simpleDuration: 9,
\r
2861 frame.setTimeTable();
\r
2862 a.next.next = { frame: 1,
\r
2863 eventType: "begin",
\r
2868 eventType: "repeat",
\r
2872 next: { frame: 12,
\r
2879 expect(frame.first).toEqual(a);
\r
2880 frame.setFrame(11);
\r
2881 frame.$endFrame.setFrame(11);
\r
2882 expect(frame.first).toEqual( {frame: 12,
\r
2888 frame.timelines = [];
\r
2889 frame.first = null;
\r
2890 frame.addLine( base("$frame").$begin.up().mix({
\r
2894 simpleDuration: 4,
\r
2898 frame.setTimeTable();
\r
2900 eventType: "begin",
\r
2905 eventType: "repeat",
\r
2911 eventType: "repeat",
\r
2915 next: { frame: 11,
\r
2923 expect(frame.first).toEqual(a);
\r
2924 frame.setFrame(0);
\r
2925 frame.$endFrame.setFrame(0);
\r
2926 expect(frame.first).toEqual(a);
\r
2927 frame.setFrame(1);
\r
2928 frame.$endFrame.setFrame(1);
\r
2930 expect(frame.first).toEqual(a);
\r
2931 frame.setFrame(5);
\r
2932 frame.$endFrame.setFrame(5);
\r
2933 expect(frame.first).toEqual(a.next);
\r
2935 ele.addEventListener("repeatEvent", function(evt) {
\r
2936 expect(evt.target).toBe(ele);
\r
2938 frame.timelines = [];
\r
2939 frame.first = null;
\r
2940 frame.addLine( base("$frame").$begin.up().mix({
\r
2944 simpleDuration: 4,
\r
2948 frame.setFrame(9);
\r
2949 frame.$endFrame.setFrame(9);
\r
2950 expect(frame.first).toEqual({
\r
2952 eventType: "repeat",
\r
2956 next: { frame: 16,
\r
2963 afterEach( function() {
\r
2964 base("$frame").startAnimation();
\r
2967 describe("A $animateTransformElemenet object", function() {
\r
2968 describe("An init method", function() {
\r
2969 var $animate, ele, frame, p;
\r
2970 beforeEach( function() {
\r
2971 $animate = base("$calcMode").$attribute.$setElement.$animateElement.$animateTransformElement.up();
\r
2972 /*ここでは、データ量を削るため、degitsプロパティを小数点以下1桁に設定*/
\r
2973 $animate.degits = 1;
\r
2974 p = document.createElementNS("http://www.w3.org/2000/svg", "g");
\r
2975 ele = document.createElementNS("http://www.w3.org/2000/svg", "animateTransform");
\r
2976 p.appendChild(ele);
\r
2977 frame = base("$frame");
\r
2978 frame.timelines.length = 0;
\r
2979 frame.startTime = Date.now();
\r
2980 frame.setFrame(0);
\r
2981 frame.$endFrame.setFrame(0);
\r
2983 afterEach( function() {
\r
2984 $animate.numberOfList = -1;
\r
2986 /*境界条件を調べておく (limit value analysis)*/
\r
2987 it("should be this for the value (limit value analysis)", function() {
\r
2988 expect($animate.numberOfList).toBe(-1);
\r
2989 expect($animate.type).toBe("translate");
\r
2990 expect(p.__transformList).toBeUndefined();
\r
2991 expect($animate.isCSS).toBeFalsy();
\r
2992 expect($animate.isSum).toBeFalsy();
\r
2993 expect($animate.attrName).toBe("transform");
\r
2996 expect($animate.numberOfList).toBe(-1);
\r
2997 expect(p.__transformList).toBeUndefined();
\r
2998 expect($animate.isCSS).toBeFalsy();
\r
2999 expect($animate.type).toBe("translate");
\r
3000 expect($animate.attrName).toBe("transform");
\r
3003 expect($animate.numberOfList).toBe(-1);
\r
3004 expect(p.__transformList).toBeUndefined();
\r
3005 expect($animate.isCSS).toBeFalsy();
\r
3006 expect($animate.type).toBe("translate");
\r
3007 expect($animate.attrName).toBe("transform");
\r
3009 $animate.init(ele);
\r
3010 expect($animate.numberOfList).toBe(-1);
\r
3011 expect(p.__transformList).toEqual([]);
\r
3012 expect($animate.isCSS).toBeFalsy();
\r
3013 expect($animate.type).toBe("translate");
\r
3014 expect($animate.attrName).toBe("transform");
\r
3016 ele.setAttributeNS(null, "values", "0;1");
\r
3017 ele.setAttributeNS(null, "attributeName", "");
\r
3018 $animate.init(ele);
\r
3019 expect($animate.isCSS).toBeFalsy();
\r
3020 expect($animate.type).toBe("translate");
\r
3021 expect($animate.type).toBe("translate");
\r
3022 expect($animate.numberOfList).toBe(0);
\r
3023 expect(p.__transformList).toEqual([ {isPlaying: false,
\r
3024 value: "translate(0)",
\r
3029 ele.setAttributeNS(null, "type", "translate");
\r
3030 $animate.init(ele);
\r
3031 expect($animate.numberOfList).toBe(0);
\r
3032 expect($animate.isCSS).toBeFalsy();
\r
3033 expect($animate.type).toBe("translate");
\r
3034 expect(p.__transformList).toEqual([ {isPlaying: false,
\r
3035 value: "translate(0)",
\r
3039 $animate.tocall(0);
\r
3040 expect(p.__transformList[0].isPlaying).toBeTruthy();
\r
3042 ele.parentNode.appendChild(ele.cloneNode(true));
\r
3043 $animate.numberOfList = -1;
\r
3044 $animate.init(ele.parentNode.lastChild);
\r
3045 expect($animate.numberOfList).toBe(1);
\r
3046 expect(p.__transformList[0].isPlaying).toBeTruthy();
\r
3047 expect(p.__transformList[1].isPlaying).toBeFalsy();
\r
3049 expect($animate.type).toBe("translate");
\r
3050 $animate.tocall(0);
\r
3051 expect(p.__transformList[0].isPlaying).toBeTruthy();
\r
3052 expect(p.__transformList[1].isPlaying).toBeTruthy();
\r
3053 $animate._setEndFrame(1);
\r
3054 expect(p.__transformList[0].isPlaying).toBeTruthy();
\r
3055 expect(p.__transformList[1].isPlaying).toBeTruthy();
\r
3057 delete p.__transformList;
\r
3058 ele.setAttributeNS(null, "type", "scale");
\r
3059 $animate.numberOfList = -1;
\r
3060 $animate.init(ele);
\r
3061 expect($animate.numberOfList).toBe(0);
\r
3062 expect(p.__transformList).toEqual([ {isPlaying: false,
\r
3063 value: "translate(0)",
\r
3067 expect($animate.type).toBe("scale");
\r
3069 delete p.__transformList;
\r
3070 $animate.numberOfList = -1;
\r
3071 ele.setAttributeNS(null, "additive", "sum");
\r
3072 ele.setAttributeNS(null, "fill", "freeze");
\r
3073 $animate.init(ele);
\r
3074 expect($animate.isSum).toBeTruthy();
\r
3075 expect(p.__transformList).toEqual([ {isPlaying: false,
\r
3076 value: "translate(0)",
\r
3080 delete p.__transformList;
\r
3081 $animate.numberOfList = -1;
\r
3082 ele.setAttributeNS(null, "additive", "replace");
\r
3083 ele.setAttributeNS(null, "fill", "remove");
\r
3084 $animate.init(ele);
\r
3085 expect(p.__transformList).toEqual([ {isPlaying: false,
\r
3086 value: "translate(0)",
\r
3091 /*同値分割をして、有効同値クラスを調べておく (Equivalence partitioning, the following is the valid partion)*/
\r
3092 it("should be this for the value (the valid partion )", function() {
\r
3093 ele.setAttributeNS(null, "type", "scale");
\r
3094 ele.setAttributeNS(null, "values", "0;1");
\r
3095 $animate.init(ele);
\r
3096 expect($animate.isCSS).toBeFalsy();
\r
3097 expect($animate.numberOfList).toBe(0);
\r
3098 expect($animate.tocall(0)).toBe("scale(0.0)");
\r
3099 expect($animate.tocall(0.5)).toBe("scale(0.5)");
\r
3100 expect($animate.tocall(0.9)).toBe("scale(0.9)");
\r
3101 expect($animate.tocall(1)).toBe("scale(1.0)");
\r
3103 ele.parentNode.appendChild(ele.cloneNode(true));
\r
3104 $animate.numberOfList = -1;
\r
3105 $animate.init(ele.parentNode.lastChild);
\r
3106 expect($animate.numberOfList).toBe(1);
\r
3107 expect($animate.tocall(0)).toBe("scale(0.0)");
\r
3108 expect($animate.tocall(1)).toBe("scale(1.0)");
\r
3110 ele.parentNode.appendChild(ele.cloneNode(true));
\r
3111 $animate.up("$a").numberOfList = -1;
\r
3112 ele.parentNode.setAttribute("transform", "matrix(0 0 0 0 0 0)");
\r
3113 $animate.$a.init(ele.parentNode.lastChild);
\r
3114 expect($animate.$a.numberOfList).toBe(2);
\r
3115 expect($animate.$a.isDefault).toBeTruthy();
\r
3116 expect($animate.$a.defaultValue).toBe("matrix(0 0 0 0 0 0)");
\r
3117 expect($animate.$a.tocall(0)).toBe("scale(0.0)");
\r
3118 expect($animate.$a.tocall(1)).toBe("scale(1.0)");
\r
3119 $animate.defaultValue = $animate.$a.defaultValue;
\r
3120 expect($animate.$a.tocall(0.1)).toBe("scale(0.1)");
\r
3122 ele.setAttributeNS(null, "additive", "sum");
\r
3123 var parentNode = ele.parentNode;
\r
3124 parentNode.appendChild(ele.cloneNode(true));
\r
3125 parentNode.__transformList = [];
\r
3126 /*additive属性のsumとreplaceの混合を避けるため、eleを削除*/
\r
3127 parentNode.removeChild(ele);
\r
3128 $animate.numberOfList = -1;
\r
3129 $animate.init(parentNode.lastChild);
\r
3130 expect($animate.numberOfList).toBe(0);
\r
3131 expect($animate.tocall(0)).toBe("matrix(0 0 0 0 0 0) scale(0.0)");
\r
3132 expect($animate.tocall(1)).toBe("matrix(0 0 0 0 0 0) scale(1.0)");
\r
3134 parentNode.appendChild(ele.cloneNode(true));
\r
3135 $animate.up("$a").numberOfList = -1;
\r
3136 parentNode.__transformList = [];
\r
3137 parentNode.setAttribute("transform", "matrix(0 0 0 0 0 0)");
\r
3138 $animate.$a.init(parentNode.lastChild);
\r
3139 expect($animate.$a.numberOfList).toBe(0);
\r
3140 expect($animate.$a.isDefault).toBeTruthy();
\r
3141 expect($animate.$a.defaultValue).toBe("matrix(0 0 0 0 0 0)");
\r
3142 expect($animate.$a.tocall(0)).toBe("matrix(0 0 0 0 0 0) scale(0.0)");
\r
3143 expect($animate.$a.tocall(1)).toBe("matrix(0 0 0 0 0 0) scale(1.0)");
\r
3144 $animate.defaultValue = $animate.$a.defaultValue;
\r
3145 expect($animate.tocall(0.1)).toBe("matrix(0 0 0 0 0 0) scale(0.1)");
\r
3147 ele.removeAttributeNS(null, "additive");
\r
3148 ad("replace", "sum", "scale(0.0) translate(0)", "scale(0.0) scale(0.0)",
\r
3149 "scale(1.0) scale(0.0)", "scale(1.0) scale(1.0)");
\r
3150 ad("sum", "replace", "matrix(0 0 0 0 0 0) scale(0.0)", "scale(0.0)",
\r
3151 "scale(0.0)", "scale(1.0)");
\r
3152 function ad(first, second, a, b, c, d) {
\r
3154 while (parentNode.firstChild) {
\r
3155 parentNode.removeChild(parentNode.firstChild);
\r
3158 /*additive属性のreplaceとsumの混合*/
\r
3159 ele.setAttributeNS(null, "additive", first);
\r
3160 parentNode.appendChild(ele.cloneNode(true));
\r
3161 ele.setAttributeNS(null, "additive", second);
\r
3162 parentNode.appendChild(ele.cloneNode(true));
\r
3163 parentNode.__transformList = [];
\r
3164 $animate.numberOfList = -1;
\r
3165 parentNode.setAttribute("transform", "matrix(0 0 0 0 0 0)");
\r
3166 $animate.up("$first").init(parentNode.firstChild);
\r
3167 $animate.up("$second").init(parentNode.lastChild);
\r
3168 expect($animate.$first.numberOfList).toBe(0);
\r
3169 expect($animate.$second.numberOfList).toBe(1);
\r
3170 expect($animate.$first.tocall(0)).toBe(a);
\r
3171 expect($animate.$second.tocall(0)).toBe(b);
\r
3172 expect($animate.$first.tocall(1)).toBe(c);
\r
3173 expect($animate.$second.tocall(1)).toBe(d);
\r
3176 /*無効同値クラスを調べておく (Equivalence partitioning, the following is the invalid partion)*/
\r
3177 it("should be this for the value (the invalid partion )", function() {
\r
3178 $animate.init(ele);
\r
3179 ele.parentNode.__transformList = null;
\r
3180 expect( function () {
\r
3181 $animate.tocall(0);
\r
3184 $animate.numberOfList = -1;
\r
3185 $animate.init(ele);
\r
3186 $animate.numberOfList = -1;
\r
3187 expect( function () {
\r
3188 $animate.tocall(0);
\r
3193 describe("A $motionElement object", function() {
\r
3194 describe("An init method", function() {
\r
3195 var $animate, ele, frame, p;
\r
3196 beforeEach( function() {
\r
3197 $animate = base("$calcMode").$attribute.$setElement.$animateElement.$animateTransformElement.$motionElement.up();
\r
3198 /*ここでは、データ量を削るため、degitsプロパティを小数点以下1桁に設定*/
\r
3199 $animate.degits = 1;
\r
3200 p = document.createElementNS("http://www.w3.org/2000/svg", "g");
\r
3201 ele = document.createElementNS("http://www.w3.org/2000/svg", "animateMotion");
\r
3202 p.appendChild(ele);
\r
3203 frame = base("$frame");
\r
3204 frame.timelines.length = 0;
\r
3205 frame.startTime = Date.now();
\r
3206 frame.setFrame(0);
\r
3207 frame.$endFrame.setFrame(0);
\r
3209 afterEach( function() {
\r
3210 $animate.numberOfList = -1;
\r
3211 delete $animate.element;
\r
3212 p.__transformList = null;
\r
3214 /*境界条件を調べておく (limit value analysis)*/
\r
3215 it("should be this for the value (limit value analysis)", function() {
\r
3216 expect($animate.type).toBe("translate");
\r
3217 expect($animate.mode).toBe("paced");
\r
3218 ele.setAttributeNS(null, "type", "scale");
\r
3219 expect($animate.rotate).toBe("0");
\r
3220 $animate.init(ele);
\r
3221 expect($animate.type).toBe("translate");
\r
3222 expect($animate.mode).toBe("paced");
\r
3223 expect($animate.rotate).toBe("0");
\r
3225 ele.setAttributeNS(null, "values", "0,0;1,0");
\r
3226 $animate.up("$a").init(ele);
\r
3227 expect($animate.$a.tocall(0)).toBe("translate(0.0,0.0)");
\r
3228 expect($animate.$a.tocall(0.5)).toBe("translate(0.5,0.0)");
\r
3229 expect($animate.$a.tocall(1)).toBe("translate(1.0,0.0)");
\r
3231 var ec = ele.cloneNode(true);
\r
3232 p.appendChild(ec);
\r
3233 ec.removeAttributeNS(null, "values");
\r
3234 ec.setAttributeNS(null, "from", "0,0");
\r
3235 ec.setAttributeNS(null, "to", "1,0");
\r
3236 $animate.up("$a").init(ec);
\r
3237 expect($animate.$a.tocall(0)).toBe("translate(0.0,0.0)");
\r
3238 expect($animate.$a.tocall(0.5)).toBe("translate(0.5,0.0)");
\r
3239 expect($animate.$a.tocall(1)).toBe("translate(1.0,0.0)");
\r
3241 /*無効同値クラスを調べておく (Equivalence partitioning, the following is the invalid partion)*/
\r
3242 it("should be this for the value (the invalid partion )", function() {
\r
3246 describe("A hasAttrValues method", function() {
\r
3247 var $animate, ele, frame, p;
\r
3248 beforeEach( function() {
\r
3249 $animate = base("$calcMode").$attribute.$setElement.$animateElement.$animateTransformElement.$motionElement.up();
\r
3250 /*ここでは、データ量を削るため、degitsプロパティを小数点以下1桁に設定*/
\r
3251 $animate.degits = 1;
\r
3252 p = document.createElementNS("http://www.w3.org/2000/svg", "g");
\r
3253 ele = document.createElementNS("http://www.w3.org/2000/svg", "animateMotion");
\r
3254 p.appendChild(ele);
\r
3255 frame = base("$frame");
\r
3256 frame.timelines.length = 0;
\r
3257 frame.startTime = Date.now();
\r
3258 frame.setFrame(0);
\r
3259 frame.$endFrame.setFrame(0);
\r
3261 afterEach( function() {
\r
3262 $animate.numberOfList = -1;
\r
3263 delete $animate.element;
\r
3264 p.__transformList = null;
\r
3266 /*境界条件を調べておく (limit value analysis)*/
\r
3267 it("should be this for the value (limit value analysis)", function() {
\r
3269 expect($animate.up("$a").hasAttrValues()).toBeFalsy();
\r
3270 $animate.up("$a").init(ele);
\r
3271 expect($animate.$a.hasAttrValues()).toBeFalsy();
\r
3273 ele.setAttributeNS(null, "path", "M");
\r
3274 expect($animate.$a.hasAttrValues()).toBeTruthy();
\r
3275 $animate.$animateTransformElement.up("$b").init(ele);
\r
3276 expect($animate.$animateTransformElement.$b.hasAttrValues()).toBeFalsy();
\r
3280 describe("Event", function() {
\r
3281 var $animate, ele, frame, p;
\r
3282 beforeEach( function() {
\r
3284 $animate = base("$calcMode").$attribute.$setElement.$animateElement.up();
\r
3285 p = document.createElementNS("http://www.w3.org/2000/svg", "g");
\r
3286 ele = document.createElementNS("http://www.w3.org/2000/svg", "animate");
\r
3287 p.appendChild(ele);
\r
3288 frame = base("$frame");
\r
3289 frame.pauseAnimation();
\r
3290 frame.timelines.length = 0; //配列の初期化
\r
3291 frame.setFrame(0);
\r
3292 frame.$endFrame.setFrame(0);
\r
3294 /*境界条件を調べておく (limit value analysis)*/
\r
3295 it("should be this for the value (limit value analysis)", function() {
\r
3296 ele.addEventListener("beginEvent", function(evt) {
\r
3297 expect(evt.target).toBe(ele);
\r
3299 var evt = ele.ownerDocument.createEvent("MouseEvents");
\r
3300 evt.initMouseEvent("beginEvent",true, true, window, 0, 0, 0, 0, 0, false, false, false, false,0, ele);
\r
3301 ele.dispatchEvent(evt);
\r
3303 ele.setAttributeNS(null, "begin", "mousedown");
\r
3304 ele.setAttributeNS(null, "dur", "1s");
\r
3305 ele.setAttributeNS(null, "attributeName", "fill");
\r
3306 ele.setAttributeNS(null, "fill", "freeze");
\r
3307 ele.setAttributeNS(null, "from", "rgb(0,0,0)");
\r
3308 ele.setAttributeNS(null, "to", "rgb(10,10,1)");
\r
3309 $animate.init(ele);
\r
3310 $animate.isCSS = false;
\r
3311 expect(p.getAttributeNS(null, "fill") || null).toBeNull();
\r
3312 expect($animate.state).toBe("idling");
\r
3313 evt = ele.ownerDocument.createEvent("MouseEvents");
\r
3314 evt.initMouseEvent("beginEvent",true, true, window, 0, 0, 0, 0, 0, false, false, false, false,0, ele);
\r
3315 expect($animate.state).toBe("idling");
\r
3316 p.dispatchEvent(evt);
\r
3317 expect($animate.state).toBe("idling");
\r
3318 expect(p.getAttributeNS(null, "fill") || null).toBeNull();
\r
3320 evt = ele.ownerDocument.createEvent("MouseEvents");
\r
3321 evt.initMouseEvent("mousedown",true, true, window, 0, 0, 0, 0, 0, false, false, false, false,0, p);
\r
3322 frame.setFrame(frame.currentFrame);
\r
3323 frame.$endFrame.setFrame(frame.currentFrame);
\r
3324 expect($animate.isEnd).toBeFalsy();
\r
3325 expect($animate.state).toBe("idling");
\r
3326 p.dispatchEvent(evt);
\r
3327 frame.setFrame(frame.currentFrame + 1);
\r
3328 frame.$endFrame.setFrame(frame.currentFrame + 1);
\r
3329 expect($animate.state).toBe("playing");
\r
3330 frame.setFrame(frame.currentFrame + 24);
\r
3331 frame.$endFrame.setFrame(frame.currentFrame + 24);
\r
3332 expect($animate.state).toBe("idling");
\r
3333 expect(evt.target.getAttributeNS(null, "fill") || null).toBe("rgb(10, 10, 1)");
\r
3336 describe("a beginElement method and an endElement method", function() {
\r
3337 var $animate, ele, frame, p;
\r
3338 beforeEach( function() {
\r
3339 $animate = base("$calcMode").$attribute.$setElement.$animateElement.up();
\r
3340 p = document.createElementNS("http://www.w3.org/2000/svg", "g");
\r
3341 ele = document.createElementNS("http://www.w3.org/2000/svg", "animate");
\r
3342 p.appendChild(ele);
\r
3343 frame = base("$frame");
\r
3344 frame.timelines.length = 0; //配列の初期化
\r
3345 frame.setFrame(0);
\r
3346 frame.$endFrame.setFrame(0);
\r
3347 ele.setAttributeNS(null, "begin", "indefinite");
\r
3348 ele.setAttributeNS(null, "dur", "1s");
\r
3349 ele.setAttributeNS(null, "dur", "1s");
\r
3350 ele.setAttributeNS(null, "attributeName", "fill");
\r
3351 ele.setAttributeNS(null, "fill", "freeze");
\r
3352 ele.setAttributeNS(null, "from", "rgb(0,0,0)");
\r
3353 ele.setAttributeNS(null, "to", "rgb(10,10,1)");
\r
3354 $animate.init(ele);
\r
3356 /*境界条件を調べておく (limit value analysis)*/
\r
3357 it("should be this for the value (limit value analysis)", function() {
\r
3358 expect(ele.beginElement()).toBeUndefined();
\r
3359 var cur = frame.currentFrame,
\r
3360 begin = frame.$begin.$1;
\r
3361 expect(begin.string).toBe("indefinite");
\r
3362 expect(begin.begin).toBe(cur);
\r
3363 expect(ele.endElement()).toBeUndefined();
\r
3365 /*同値分割をして、有効同値クラスを調べておく (Equivalence partitioning, the following is the valid partion)*/
\r
3366 it("should be this for the value (the valid partion )", function() {
\r
3367 ele.addEventListener("beginEvent", function(evt){
\r
3368 expect(evt.target.nodeName).toBe("animate");
\r
3370 ele.beginElement();
\r