UNPKG

declare.js

Version:

OO system from node and browser

465 lines (385 loc) 17.1 kB
"use strict"; var it = require('it'), assert = require('assert'), declare = require("../declare"), singleton = declare.singleton; it.describe("declare",function (it) { //Super of other classes var Mammal = declare({ instance: { constructor: function (options) { options = options || {}; this._super(arguments); this._type = options.type || "mammal"; }, speak: function () { return "A mammal of type " + this._type + " sounds like"; }, //Define your getters getters: { type: function () { return this._type; } }, setters: { type: function (type) { this._type = type; } } }, //Define your static methods static: { mammalInheritedProp: "mammalInheritedProp", soundOff: function () { return "Im a mammal!!"; } } }); //Show singular inheritance var Wolf = Mammal.extend({ instance: { constructor: function (options) { options = options || {}; //call your super constructor you can call this after you initialize or not //call it at all to prevent the supers from initilizing things this._super(arguments); this._sound = "growl"; this._color = options.color || "grey"; }, speak: function () { return this._super(arguments) + " a " + this._sound; }, getters: { color: function () { return this._color; }, sound: function () { return this._sound; } }, setters: { color: function (color) { this._color = color; }, sound: function (sound) { this._sound = sound; } } }, static: { soundOff: function () { //You can even call super in your statics!!! return this._super(arguments) + " that growls"; } } }); //Typical heirachical inheritance // Mammal->Wolf->Dog var Dog = Wolf.extend({ instance: { constructor: function (options) { options = options || {}; this._super(arguments); this._sound = "woof"; }, speak: function () { return this._super(arguments) + " thats domesticated"; } }, static: { soundOff: function () { return this._super(arguments) + " but now barks"; } } }); // Mammal->Wolf->Dog->Breed var Breed = Dog.extend({ instance: { _pitch: "high", constructor: function (options) { options = options || {}; this._super(arguments); this.breed = options.breed || "lab"; }, speak: function () { return this._super(arguments) + " with a " + this._pitch + " pitch!"; }, getters: { pitch: function () { return this._pitch; } }, setters: { pitch: function (pitch) { this._pitch = pitch; } } }, static: { soundOff: function () { return this._super(arguments).toUpperCase() + "!"; } } }); //Example of multiple inheritace //What really happens is you mixin Wold, Dog, and Breed //However you are only truely an instance of Mammal //However the inheritance chain will look like //Mammal->Wolf->Dog->Breed //So if you call this.get("_super"), it will check breed then dog then wolf then mammal //be found through inheritance var Lab = declare([Mammal, Wolf, Dog, Breed]); var MyLab = singleton(Lab); var MyLabWithConstructor = singleton([Mammal, Wolf, Dog, Breed], { instance: { constructor: function () { this._super(arguments); } } }); var StaticInitClass = declare([Mammal, Wolf, Dog, Breed], { static: { initCalled: false, init: function () { this.initCalled = true; } } }); var SingletonInit = singleton([Mammal, Wolf, Dog, Breed], { static: { initCalled: false, init: function () { this.initCalled = true; } } }); var WrappedClass = declare([Mammal, Wolf, Dog, Breed], { static: { DogMammal: Dog } }); it.describe("Dog", function (it) { var dog = new Dog({color: "gold"}); it.should("sound like a dog", function () { //This is true because they inherit from eachother! assert.isTrue(dog instanceof Wolf); assert.isTrue(dog instanceof Mammal); assert.equal(Dog.get("mammalInheritedProp"), "mammalInheritedProp"); assert.equal(dog.speak(), "A mammal of type mammal sounds like a woof thats domesticated"); assert.equal(dog.get("type"), "mammal"); assert.equal(dog.get("color"), "gold"); assert.equal(dog.get("sound"), "woof"); assert.equal(Dog.soundOff(), "Im a mammal!! that growls but now barks"); }); it.should("be a DOG after setting type", function () { dog.set("type", "DOG"); assert.equal(dog.speak(), "A mammal of type DOG sounds like a woof thats domesticated"); assert.equal(dog.get("type"), "DOG"); assert.equal(dog.get("color"), "gold"); assert.equal(dog.get("sound"), "woof"); assert.equal(Dog.soundOff(), "Im a mammal!! that growls but now barks"); }); }); it.describe("a Breed ", function (it) { var breed = new Breed({color: "gold", type: "lab"}); it.should("sound like a lab", function () { //the next three are true because they inherit from each other assert.isTrue(breed instanceof Dog); assert.isTrue(breed instanceof Wolf); assert.isTrue(breed instanceof Mammal); assert.equal(Dog.get("mammalInheritedProp"), "mammalInheritedProp"); assert.equal(breed.speak(), "A mammal of type lab sounds like a woof thats domesticated with a high pitch!"); assert.equal(breed.get("type"), "lab"); assert.equal(breed.get("color"), "gold"); assert.equal(breed.get("sound"), "woof"); assert.equal(breed.get("pitch"), "high"); assert.equal(Breed.soundOff(), "IM A MAMMAL!! THAT GROWLS BUT NOW BARKS!"); }); it.should("but after setting the type it should be a collie", function () { breed.set("type", "collie"); assert.isTrue(breed instanceof Dog); assert.isTrue(breed instanceof Wolf); assert.isTrue(breed instanceof Mammal); assert.equal(Dog.get("mammalInheritedProp"), "mammalInheritedProp"); assert.equal(breed.speak(), "A mammal of type collie sounds like a woof thats domesticated with a high pitch!"); assert.equal(breed.get("type"), "collie"); assert.equal(breed.get("color"), "gold"); assert.equal(breed.get("sound"), "woof"); assert.equal(breed.get("pitch"), "high"); assert.equal(Breed.soundOff(), "IM A MAMMAL!! THAT GROWLS BUT NOW BARKS!"); }); it.should("but after setting the color it should be grey", function () { breed.set("color", "grey"); assert.isTrue(breed instanceof Dog); assert.isTrue(breed instanceof Wolf); assert.isTrue(breed instanceof Mammal); assert.equal(Dog.get("mammalInheritedProp"), "mammalInheritedProp"); assert.equal(breed.speak(), "A mammal of type collie sounds like a woof thats domesticated with a high pitch!"); assert.equal(breed.get("type"), "collie"); assert.equal(breed.get("color"), "grey"); assert.equal(breed.get("sound"), "woof"); assert.equal(breed.get("pitch"), "high"); assert.equal(Breed.soundOff(), "IM A MAMMAL!! THAT GROWLS BUT NOW BARKS!"); }); it.should("but after setting the sound it should sound like a bark", function () { breed.set("sound", "bark"); assert.isTrue(breed instanceof Dog); assert.isTrue(breed instanceof Wolf); assert.isTrue(breed instanceof Mammal); assert.equal(Dog.get("mammalInheritedProp"), "mammalInheritedProp"); assert.equal(breed.speak(), "A mammal of type collie sounds like a bark thats domesticated with a high pitch!"); assert.equal(breed.get("type"), "collie"); assert.equal(breed.get("color"), "grey"); assert.equal(breed.get("sound"), "bark"); assert.equal(breed.get("pitch"), "high"); assert.equal(Breed.soundOff(), "IM A MAMMAL!! THAT GROWLS BUT NOW BARKS!"); }); it.should("but after setting the pitch it should be low pitched", function () { breed.set("pitch", "low"); assert.isTrue(breed instanceof Dog); assert.isTrue(breed instanceof Wolf); assert.isTrue(breed instanceof Mammal); assert.equal(Dog.get("mammalInheritedProp"), "mammalInheritedProp"); assert.equal(breed.speak(), "A mammal of type collie sounds like a bark thats domesticated with a low pitch!"); assert.equal(breed.get("type"), "collie"); assert.equal(breed.get("color"), "grey"); assert.equal(breed.get("sound"), "bark"); assert.equal(breed.get("pitch"), "low"); assert.equal(Breed.soundOff(), "IM A MAMMAL!! THAT GROWLS BUT NOW BARKS!"); }); }); it.describe("a LAB ", function (it) { var lab = new Lab(); it.should("sound like a lab", function () { //the next three are false because they are mixins assert.isFalse(lab instanceof Breed); assert.isFalse(lab instanceof Dog); assert.isFalse(lab instanceof Wolf); assert.isTrue(lab instanceof Mammal); assert.equal(Dog.get("mammalInheritedProp"), "mammalInheritedProp"); assert.equal(lab.speak(), "A mammal of type mammal sounds like a woof thats domesticated with a high pitch!"); assert.equal(lab.get("type"), "mammal"); assert.equal(lab.get("color"), "grey"); assert.equal(lab.get("sound"), "woof"); assert.equal(Lab.soundOff(), "IM A MAMMAL!! THAT GROWLS BUT NOW BARKS!"); }); }); it.describe("Singletons", function (it) { it.describe("when in creating my lab singleton", function (it) { var lab = new MyLab({type: "dog"}); it.should("still be a dog", function () { var myLab = new MyLab(); assert.isTrue(lab == myLab); assert.equal(lab.get("type"), "dog"); assert.equal(myLab.get("type"), "dog"); assert.equal(Dog.get("mammalInheritedProp"), "mammalInheritedProp"); assert.equal(lab.speak(), "A mammal of type dog sounds like a woof thats domesticated with a high pitch!"); assert.equal(myLab.speak(), "A mammal of type dog sounds like a woof thats domesticated with a high pitch!"); assert.equal(lab.get("type"), "dog"); assert.equal(myLab.get("type"), "dog"); assert.equal(lab.get("color"), "grey"); assert.equal(myLab.get("color"), "grey"); assert.equal(lab.get("sound"), "woof"); assert.equal(myLab.get("sound"), "woof"); assert.equal(MyLab.soundOff(), "IM A MAMMAL!! THAT GROWLS BUT NOW BARKS!"); }); }); it.describe("when in creating my lab singleton with a constructor", function (it) { var lab = new MyLabWithConstructor({type: "dog"}); it.should("still be a dog", function () { var myLab = new MyLabWithConstructor(); assert.isTrue(lab == myLab); assert.equal(lab.get("type"), "dog"); assert.equal(myLab.get("type"), "dog"); assert.equal(Dog.get("mammalInheritedProp"), "mammalInheritedProp"); assert.equal(lab.speak(), "A mammal of type dog sounds like a woof thats domesticated with a high pitch!"); assert.equal(myLab.speak(), "A mammal of type dog sounds like a woof thats domesticated with a high pitch!"); assert.equal(lab.get("type"), "dog"); assert.equal(myLab.get("type"), "dog"); assert.equal(lab.get("color"), "grey"); assert.equal(myLab.get("color"), "grey"); assert.equal(lab.get("sound"), "woof"); assert.equal(myLab.get("sound"), "woof"); assert.equal(MyLab.soundOff(), "IM A MAMMAL!! THAT GROWLS BUT NOW BARKS!"); }); }); it.describe("when in creating my lab singleton with params", function (it) { var lab = new MyLab(); it.should("still be a dog", function () { var myLab = new MyLab(); assert.isTrue(lab == myLab); assert.equal(lab.get("type"), "dog"); assert.equal(myLab.get("type"), "dog"); assert.equal(Dog.get("mammalInheritedProp"), "mammalInheritedProp"); assert.equal(lab.speak(), "A mammal of type dog sounds like a woof thats domesticated with a high pitch!"); assert.equal(myLab.speak(), "A mammal of type dog sounds like a woof thats domesticated with a high pitch!"); assert.equal(lab.get("type"), "dog"); assert.equal(myLab.get("type"), "dog"); assert.equal(lab.get("color"), "grey"); assert.equal(myLab.get("color"), "grey"); assert.equal(lab.get("sound"), "woof"); assert.equal(myLab.get("sound"), "woof"); assert.equal(MyLab.soundOff(), "IM A MAMMAL!! THAT GROWLS BUT NOW BARKS!"); }); }); }); it.should("call static init methods", function () { assert.isTrue(StaticInitClass.initCalled); assert.isTrue(SingletonInit.initCalled); assert.deepEqual(WrappedClass.get("DogMammal"), Dog); assert.instanceOf(new WrappedClass.DogMammal(), Dog); }); it.describe("#_super", function (it) { it.should("allow calling with out arguments", function () { var Cls = Mammal.extend({ instance: { speak: function () { return this._super(); } } }); assert.equal(new Cls().speak(), "A mammal of type mammal sounds like") }); it.should("allow calling super a string argument", function () { var Cls = Mammal.extend({ instance: { speak: function () { return this._super("hello"); } } }); assert.equal(new Cls().speak(), "A mammal of type mammal sounds like") }); it.should("allow calling super with null", function () { var Cls = Mammal.extend({ instance: { speak: function () { return this._super(null); } } }); assert.equal(new Cls().speak(), "A mammal of type mammal sounds like") }); it.should("allow calling super with undefined", function () { var x; var Cls = Mammal.extend({ instance: { speak: function () { return this._super(x); } } }); assert.equal(new Cls().speak(), "A mammal of type mammal sounds like") }); }); it.describe("#as", function (it) { it.should("add to the exports ", function () { Mammal.as(exports, "Mammal"); assert.equal(exports.Mammal, Mammal); }); it.should("export as module", function () { Mammal.as(module); assert.equal(module.exports, Mammal); }); }); }).as(module);