1 describe("base.js", function() {
\r
2 var gl = (function(){return this;})(); //グローバルオブジェクト
\r
4 it("cascading inherit", function() {
\r
5 /*カスケード継承 (cascading inherit)に関するスペック*/
\r
6 base("$parent").mix( function() {
\r
7 this.hoge = function() {
\r
10 this.up("$child").mix( function() {
\r
11 this.hoge = function() {
\r
12 return this.$parent.hoge();
\r
16 expect(base("$parent")).toEqual(gl.$parent);
\r
17 expect(base("$parent").$child).toEqual(gl.$parent.$child);
\r
18 expect(base("$parent").$child.hoge()).toEqual(12);
\r
19 expect(base("$parent").hoge()).toEqual(12);
\r
20 expect(gl.$parent.$child.hoge()).toEqual(12);
\r
21 expect(base("$parent").$child.hoge).not.toEqual(base("$parent").hoge());
\r
24 it("a function base", function() {
\r
25 var falsyList = ["", null, 0, undefined],
\r
26 i = falsyList.length;
\r
35 expect(typeof base("$wo")).toBe("object");
\r
36 expect(base("$w")).toBe(base("$w"));
\r
37 expect(base("$w")).toBe(gl.$w);
\r
40 it("a mix method", function() {
\r
41 /*mixメソッドはオブジェクトの合成ができる*/
\r
42 expect(typeof base("$a").mix).toBe("function");
\r
44 expect(base("$a").mix({})).toBe(base("$a"));
\r
45 expect(base("$a").mix(function(){})).toBe(base("$a"));
\r
46 expect(base("$a").mix({}).mix({})).toBe(base("$a"));
\r
47 expect(base("$a").mix(function(){}).mix({}).mix(function(){})).toBe(base("$a"));
\r
49 var falsyList = ["", null, 0, undefined],
\r
50 i = falsyList.length;
\r
56 base("$a").mix(falsyList[i]);
\r
60 /*argument to object*/
\r
70 expect(base("$a").a).toEqual(12);
\r
71 expect(base("$a").b.d).toEqual(12);
\r
72 expect(base("$a").c()).toEqual(15);
\r
74 /*argument to function*/
\r
75 base("$b").mix( function() {
\r
80 this.c = function(){
\r
84 expect(base("$b").a).toEqual(12);
\r
85 expect(base("$b").b.d).toEqual(12);
\r
86 expect(base("$b").c()).toEqual(15);
\r
97 expect(base("$a").a).toEqual(0);
\r
98 expect(base("$a").b.d).toEqual(-12);
\r
99 expect(base("$a").c()).toEqual(3);
\r
101 base("$a").mix(Math);
\r
102 expect(base("$a").pi).toEqual(Math.pi);
\r
110 return (this.a+"hoge");
\r
113 expect(base("$a").a).toBe("hogehoge");
\r
114 expect(base("$a").b.d).toEqual(0);
\r
115 expect(base("$a").c()).toBe("hogehogehoge");
\r
117 for (var i=0, arr = [];i<500;++i) {
\r
120 for (i=0;i<100;++i) {
\r
121 base("$a").mix(arr);
\r
123 expect(base("$a")[0]).toEqual(0);
\r
124 expect(base("$a")[499]).toEqual(499);
\r
127 it("an up method", function() {
\r
128 /*upメソッドは、プロトタイプ継承した新しいオブジェクトを作り、引数で指定された名前のプロパティに格納する*/
\r
129 expect(typeof base("$c").up).toEqual("function");
\r
131 expect(base("$c").up("$a")).not.toBe(base("$a"));
\r
133 expect(base("$c").up("$c")).not.toBe(base("$c"));
\r
134 /*もう一度繰り返す (reapeat)*/
\r
135 expect(base("$c").up("$c")).not.toBe(base("$c"));
\r
137 expect(base("$c").$c).toBe(gl.$c.$c);
\r
138 expect(base("$c").$c.up("$c")).not.toBe(base("$c"));
\r
139 expect(gl.$c.$c.up("$c")).toBe(base("$c").$c.$c.$c);
\r
141 /*オブジェクト$cのhogeプロパティの継承*/
\r
142 base("$c").hoge = 12;
\r
143 expect(base("$c").$c.hoge).toEqual(12);
\r
144 expect(base("$c").$c.$c.hoge).toEqual(12);
\r
145 expect(base("$c").$c.$c.$c.hoge).toEqual(12);
\r
147 /*プロトタイプチェーン上のオブジェクトも合成できるようにする*/
\r
153 base("$d").mix(base("$c").$1);
\r
154 expect(base("$d").aa).toEqual(12);
\r
155 expect(base("$d").bb).toEqual(15);
\r
156 expect(base("$d").$1).toBe(base("$c").$1);
\r
157 base("$d").mix(function() {
\r
158 expect(this.$c.aa).toEqual(12);
\r
159 expect(this.$1.aa).toEqual(12);
\r
160 expect(this.$1.bb).toEqual(15);
\r
163 for (var i=0;i<5000;++i) {
\r
164 base("$c").up("$dd");
\r
166 expect(base("$c").$dd.hoge).toEqual(12);
\r
168 /*引数を省略した場合、引数に文字列"$1"を入れたのと同じ効果が得られる*/
\r
169 expect(base("$up").$1).toBeUndefined();
\r
170 expect(base("$up").up()).toBe(base("$up").$1);
\r
173 it("a mix method function", function() {
\r
174 /*mixメソッドの引数に指定された関数と、mixメソッドのレシーバオブジェクトについて*/
\r
175 base("$mmf").mix(function(_) {
\r
176 expect(_).toBe(base("$mmf"));
\r
177 expect(this).toBe(_);
\r
181 it("an on method", function() {
\r
182 /*onメソッドは同一名メソッドの合成ができる*/
\r
183 base("$a").on("met", function() {return 12;});
\r
184 /*メソッドチェーンかどうかのチェック*/
\r
185 expect(base("$a").on("met", function(a) {
\r
189 base("$a").met(12);
\r
190 expect(base("$a").a).toEqual(12);
\r
192 base("$a").on("met", function(a) {
\r
195 expect(base("$a").a).toEqual(12);
\r
196 expect(base("$a").b).toEqual(12);
\r
198 /*返り値は、最初に指定しておいたメソッド*/
\r
199 expect(base("$a").met()).toEqual(12);
\r
201 base("$a").mix( function() {
\r
205 base("$a").up("$b").on("met", function() {
\r
209 expect(base("$a").$b.a).toEqual(15);
\r
210 expect(base("$a").$b.b).toEqual(15);
\r
212 base("$a").on("metmet", function() {
\r
216 expect(base("$a").a).toEqual(12);
\r
217 expect(base("$a").b).toEqual(12);
\r
218 /*別のmetメソッドを設定しても、影響を与えないかどうかをチェック*/
\r
219 base("$a").on("met", function() {
\r
223 expect(base("$a").a).toEqual(12);
\r
224 expect(base("$a").b).toEqual(12);
\r
226 expect(base("$a").met()).toEqual(12);
\r
227 expect(base("$a").metmet()).toBeUndefined();
\r
230 base("$a").on("o", function(){})
\r
232 expect(base("$a").on("o", function(){return 12;})
\r
233 .o()).toBeUndefined();
\r
235 /*通常のメソッドが入っていた場合*/
\r
236 base("$a").mix( {aa: function() {
\r
240 .on("aa", function(){
\r
243 expect(base("$a").aa()).toEqual(15);
\r
244 expect(base("$a").__t).toEqual(12);
\r
245 expect(base("$a").__n).toEqual(12);
\r
252 }).up("$b").on("aaa", function() {
\r
255 expect(base("$a").aaa()).toEqual(15);
\r
256 expect(base("$a").$b.__n).toEqual(18);
\r
257 expect(base("$a").$b.aaa()).toEqual(15);
\r
258 expect(base("$a").$b.__n).toEqual(15);
\r
267 }).up("$b").up("$c").on("am", function() {
\r
270 expect(base("$a").am()).toEqual(15);
\r
271 expect(base("$a").$b.$c.__n).toEqual(18);
\r
272 expect(base("$a").$b.$c.am()).toEqual(15);
\r
273 expect(base("$a").$b.$c.__n).toEqual(15);
\r
275 "am", function(f) {
\r
279 ).up("$b").up("$c").on("am", function(f) {
\r
282 expect(base("$a").am(12)).toEqual(15);
\r
283 expect(base("$a").__t).toEqual(12);
\r
284 expect(base("$a").$b.$c.__n).toEqual(18);
\r
285 expect(base("$a").$b.$c.am()).toEqual(15);
\r
286 expect(base("$a").$b.$c.__n).toEqual(15);
\r
289 expect(function() {
\r
290 base("$a").on("met");
\r
292 expect(function() {
\r
293 base("$a").on("met", "met");
\r
295 expect(function() {
\r
296 base("$a").on("met", 12);
\r
298 expect(function() {
\r
299 base("$a").on("", function(){});
\r
302 /*up、on、mix、ofメソッドは自己参照の矛盾を引き出すので、例外を投げておく*/
\r
303 var message = "Invalid method name error";
\r
304 expect(function() {
\r
305 base("$a").on("up", function(){});
\r
306 }).toThrow(message);
\r
307 expect(function() {
\r
308 base("$a").on("on", function(){});
\r
309 }).toThrow(message);
\r
310 expect(function() {
\r
311 base("$a").on("mix", function(){});
\r
312 }).toThrow(message);
\r
313 expect(function() {
\r
314 base("$a").on("of", function(){});
\r
315 }).toThrow(message);
\r
317 base("$a").on("upon", function(){}); //これは正常に作動
\r
319 /*無関係のオブジェクトを返さないようにするためのチェック*/
\r
321 base("_ddd").up("$1");
\r
324 describe("an 'of' method", function() {
\r
326 it("limit value analysis", function() {
\r
327 expect(typeof base("$fp").of).toBe("function");
\r
329 expect(base("$fp").of({})).toBe(base("$fp"));
\r
331 /*同じオブジェクトで再度、ofメソッドを呼び出すことはできない*/
\r
332 expect(function() {
\r
333 base("$fp").of({});
\r
334 }).toThrow("Reset error");
\r
335 /*upメソッドで継承したオブジェクトは再度呼び出せる*/
\r
336 base("$fp").up().of( {} );
\r
338 base("$fp").up().of ( {
\r
347 call: function() {}
\r
350 base("$fp").$1.mix( function(_) {
\r
351 expect(_.a).toEqual(0);
\r
352 expect(_.b).toEqual(1);
\r
353 expect(_.c).toBeTruthy();
\r
354 expect(_.d).toBeFalsy();
\r
355 expect(typeof _.e).toBe("object");
\r
356 /*callメソッドのあるオブジェクトや関数が指定された時だけ、未定義値
\r
357 * ただし、callメソッドは指定されても未定義とならない*/
\r
358 expect(_.f).toBeUndefined();
\r
359 expect(typeof _.call).toBe("function");
\r
360 expect(_.g.length).toEqual(0);
\r
361 expect(_.h).toBeNull();
\r
365 it("Equivalence partitioning, the following is the valid partion", function() {
\r
371 return this.a + this.b;
\r
374 var _ = base("$ffp");
\r
375 expect(_.a).toEqual(10);
\r
376 expect(_.b).toEqual(12);
\r
377 expect(_.c).toBeUndefined();
\r
378 expect(_.call()).toEqual(22);
\r
379 /*upメソッドを使えば、再び、ofメソッドを再設定できる*/
\r
380 _ = base("$ffp").up();
\r
381 expect(_.a).toEqual(10);
\r
382 expect(_.b).toEqual(12);
\r
383 expect(_.c).toBe(base("$afp"));
\r
384 expect(_.call()).toEqual(22);
\r
390 return this.a + this.b;
\r
393 expect(_.a).toEqual(11);
\r
394 expect(_.b).toEqual(13);
\r
395 expect(_.c).toBe("bfp");
\r
396 expect(_.call()).toEqual(24);
\r
398 /*mixメソッドでも、オブジェクト継承の後であれば上書きが可能*/
\r
404 expect(_.$p.a).toEqual(12);
\r
405 expect(_.$p.b).toEqual(13);
\r
406 expect(_.$p.c).toBe(base("$afp"));
\r
407 expect(_.$p.call()).toEqual(25);
\r
411 it("Equivalence partitioning, the following is the invalid partion", function() {
\r
412 expect( function() {
\r
413 base("$ffp").up("$error").of( {
\r
417 } ).toThrow("Reset error");
\r
418 expect( function() {
\r
419 base("$ffp").up("$error").of();
\r
420 } ).toThrow("No arguments error");
\r
424 describe("an 'call' method", function() {
\r
425 it("limit value analysis", function() {
\r
426 expect(typeof base("$bfp").call).toBe("function");
\r
427 expect(base("$bfp").call()).toBe(base("$bfp"));
\r
428 expect(base("$bfp").up().call()).toBe(base("$bfp").$1);
\r
429 base("$bfp").up().of ( {
\r
439 base("$bfp").$1.mix( function(_) {
\r
440 expect(_.a).toEqual(0);
\r
441 expect(_.b).toEqual(1);
\r
442 expect(_.c).toBeTruthy();
\r
443 expect(_.d).toBeFalsy();
\r
444 expect(typeof _.e).toBe("object");
\r
445 /*callメソッドが設定されていないことに注意*/
\r
446 expect(_.f).toBeUndefined();
\r
447 expect(typeof _.call).toBe("function");
\r
448 expect(_.g.length).toEqual(0);
\r
449 expect(_.h).toBeNull();
\r
452 it("Equivalence partitioning, the following is the valid partion", function() {
\r
459 expect(base("$bfp").a).toBeUndefined();
\r
460 base("$abfp").of( {
\r
465 expect(base("$bfp").call()).toEqual(12);
\r
466 /*再度呼び出しても同じ結果となる*/
\r
467 expect(base("$bfp").call()).toEqual(12);
\r
468 base("$bfp").up("$a").of( {
\r
472 expect(base("$bfp").$a.call()).toEqual(12);
\r
473 /*今度は束縛変数としてbプロパティの値を返す*/
\r
474 base("$bfp").up("$b").of( {
\r
480 base("$bbfp").of( {
\r
485 expect(base("$bfp").$b.call()).toEqual(15);
\r
487 for (var i=0;i<1000;++i) {
\r
488 expect(base("$bfp").$b.call()).toEqual(15);
\r
490 /*callメソッドを何も設定していない場合*/
\r
491 expect(base("$cfp").of({a:base("$bfp")}).call()).toBe(base("$cfp"));
\r
492 expect(base("$cfp").up("$bfp").of({a:base("$bfp")}).call()).toBe(base("$cfp").$bfp);
\r
495 expect(base("$bfp").$b.up().of( {b: base("$bfp").$b.$1} ).call()).toBe(base("$bfp").$b.$1);
\r
497 /*ofメソッドで指定されたfuncメソッドなどは、callメソッドで呼び出し時に実行される(thisはcallメソッドのレシーバ)*/
\r
498 expect( base("$cfp").up("$a").of( {
\r
505 } ).call() ).toBe(base("$cfp").$a);
\r
508 base("$bfp").up("$s").of( {
\r
513 return this.lazy.a;
\r
516 expect(base("$bfp").$s.call()).toBe(base("$cfp"));
\r
520 it("Equivalence partitioning, the following is the invalid partion", function() {
\r
527 expect(function() {
\r
528 base("$efp").call();
\r
533 it("should occur an error, if no arguments", function(){
\r
534 var message = "No arguments error";
\r
537 }).toThrow(message);
\r
539 base("$error").mix();
\r
540 }).toThrow(message);
\r
542 base("$error").on();
\r
543 }).toThrow(message);
\r
545 base("$error").of();
\r
546 }).toThrow(message);
\r