'stampit' module definitions and tests.

This commit is contained in:
koresar
2014-09-14 20:21:54 +10:00
parent 50dd84eb5d
commit 938f6b41bc
3 changed files with 309 additions and 0 deletions
+1
View File
@@ -342,6 +342,7 @@ All definitions files include a header with the author and editors, so at some p
* [source-map](https://github.com/mozilla/source-map) (by [Morten Houston Ludvigsen](https://github.com/MortenHoustonLudvigsen))
* [Spin](http://fgnass.github.com/spin.js/) (by [Boris Yankov](https://github.com/borisyankov))
* [sqlite3](https://github.com/mapbox/node-sqlite3) (by [Nick Malaguti](https://github.com/nmalaguti))
* [stampit](https://github.com/ericelliott/stampit) (by [Vasyl Boroviak](https://github.com/koresar))
* [status-bar](https://github.com/atom/status-bar) (by [vvakame](https://github.com/vvakame))
* [stripe](https://stripe.com/) (by [Eric J. Smith](https://github.com/ejsmith/))
* [Store.js](https://github.com/marcuswestin/store.js/) (by [Vincent Bortone](https://github.com/vbortone))
+168
View File
@@ -0,0 +1,168 @@
/// <reference path="stampit.d.ts" />
var a = stampit().enclose(() => {
var a = 'a';
this.getA = () => {
return a;
};
});
a(); // Object -- so far so good.
a().getA(); // "a"
var b = stampit().enclose(function () {
var a = 'b';
this.getB = function () {
return a;
};
});
var c = stampit.compose(a, b);
var foo = c(); // we won't throw this one away...
foo.getA(); // "a"
foo.getB(); // "b"
// Some more privileged methods, with some private data.
// Use stampit.mixIn() to make this feel declarative:
var availability = stampit().enclose(function () {
var isOpen = false; // private
return stampit.mixIn(this, {
open: function open() {
isOpen = true;
return this;
},
close: function close() {
isOpen = false;
return this;
},
isOpen: function isOpenMethod() {
return isOpen;
}
});
});
// Hre's a mixin with public methods, and some state:
var membership = stampit({
members: {},
add: function (member: any) {
this.members[member.name] = member;
return this;
},
getMember: function (name: any) {
return this.members[name];
}
},
{
members: {}
});
// Let's set some defaults:
var defaults = stampit().state({
name: 'The Saloon',
specials: 'Whisky, Gin, Tequila'
});
// Classical inheritance has nothing on this. No parent/child coupling. No deep inheritance hierarchies.
// Just good, clean code reusability.
var bar = stampit.compose(defaults, availability, membership);
// Note that you can override state on instantiation:
var myBar = bar({name: 'Moe\'s'});
// Silly, but proves that everything is as it should be.
myBar.add({name: 'Homer' }).open().getMember('Homer');
var myStamp = stampit().methods({
foo: function () {
return 'foo';
},
methodOverride: function () {
return false;
}
}).methods({
bar: function () {
return 'bar'
},
methodOverride: function () {
return true;
}
});
myStamp.state({
foo: {bar: 'bar'},
stateOverride: false
}).state({
bar: 'bar',
stateOverride: true
});
myStamp.enclose(function () {
var secret = 'foo';
this.getSecret = function () {
return secret;
};
}).enclose(function () {
this.a = true;
}).enclose({
bar: function bar() {
this.b = true;
}
}, {
baz: function baz() {
this.c = true;
}
});
var obj = myStamp.create();
obj.getSecret && obj.a && obj.b && obj.c; // true
var newStamp = stampit(null, { defaultNum: 1 }).compose(myStamp);
var obj1 = stampit().methods({
a: function () { return 'a'; }
}, {
b: function () { return 'b'; }
}).create();
var obj2 = stampit().state({
a: 'a'
}, {
b: 'b'
}).create();
var obj = defaults.compose(newStamp, membership, availability).create();
// The old constructor / class thing...
var Constructor = function Constructor() {
this.thing = 'initialized';
};
Constructor.prototype.foo = function foo() { return 'foo'; };
// The conversion
var oldskool = stampit.convertConstructor(Constructor);
// A new stamp to compose with...
var newskool = stampit().methods({
bar: function bar() { return 'bar'; }
// your methods here...
}).enclose(function () {
this.baz = 'baz';
});
// Now you can compose those old constructors just like you could
// with any other stamp...
var myThing = stampit.compose(oldskool, newskool);
var t = myThing();
t.thing; // 'initialized',
t.foo(); // 'foo',
t.bar(); // 'bar'
+140
View File
@@ -0,0 +1,140 @@
// Type definitions for stampit
// Project: https://github.com/ericelliott/stampit
// Definitions by: Vasyl Boroviak <https://github.com/koresar>
// Definitions: https://github.com/borisyankov/DefinitelyTyped
declare var stampit: stampit.Stampit;
declare module stampit {
interface Stampit {
/**
* Return a factory function that will produce new objects using the
* prototypes that are passed in or composed.
* @param methods Object containing methods which will be part of
* the .prototype of a resulting object.
* @param state Object which properties will be copied over to
* a resulting object.
* @param enclose Function properties of these objects will be run
* once per each new object.
* */
(methods?:{}, state?:{}, enclose?:{(...encloseArgs:any[]): void}[]):stampit.Stamp;
/**
* Take two or more Stamps and combine them to produce a new Stamp.
* Combining overrides properties with last-in priority.
* @param stamps Stamps produced by stampit.
* @return A new Stamp made of all the given.
*/
compose(...stamps:Stamp[]): Stamp;
/**
* Take a destination object followed by one or more source objects,
* and copy the source object properties to the destination object,
* with last in priority overrides.
* @param destination An object to copy properties to.
* @param source Objects to copy properties from.
* @return The destination object.
*/
mixIn(destination:any, ...source:any[]): any;
/**
* Alias for mixIn.
* Take a destination object followed by one or more source objects,
* and copy the source object properties to the destination object,
* with last in priority overrides.
* @param destination An object to copy properties to.
* @param source Objects to copy properties from.
* @return The destination object.
*/
extend(destination:any, ...source:any[]): any;
/**
* Check if an object is a Stamp.
* @param obj An object to check.
* @return true if the object is a Stamp; otherwise - false.
*/
isStamp(obj:any): boolean;
/**
* Take an old-fashioned JS constructor and return a Stamp
* that you can freely compose with other Stamps.
* @param Constructor Old-fashioned constructor function.
* @return A new Stamp based on the given constructor.
*/
convertConstructor(Constructor:any): Stamp;
}
/**
* A factory function that will produce new objects using the
* prototypes that are passed in or composed.
*/
export interface Stamp {
(state?:{}, ...encloseArgs:any[]): any;
/**
*
* @param state State passed
* @param encloseArgs
* @return A new object composed of the Stamps and prototypes provided.
*/
create(state?:{}, ...encloseArgs:any[]): any;
/**
* An object map containing the fixed prototypes.
*/
fixed: Fixed;
/**
* Add methods to the methods prototype. Chainable.
* @param methods Object(s) containing methods which will be part of
* the .prototype of a resulting object.
* @return Self.
*/
methods(...methods:{}[]): Stamp;
/**
* Add properties to the state prototype. Chainable.
* @param states Object(s) which properties will be copied over to
* a resulting object.
* @return Self.
*/
state(...states:{}[]): Stamp;
/**
* Add properties to the state prototype. Chainable.
* @param functions These function will be run once per each new object.
* @return Self.
*/
enclose(...functions:{(...encloseArgs:any[]): void}[]): Stamp;
/**
* Add properties to the state prototype. Chainable.
* @param methods Function properties of these objects will be run
* once per each new object.
* @return Self.
*/
enclose(...methods:{}[]): Stamp;
/**
* Take one or more Stamps and
* combine them with `this` to produce and return a new factory.
* Combining overrides properties with last-in priority.
* @param stamps Stampit factories, aka Stamps.
* @return A new Stamp composed from arguments and `this`.
*/
compose(...stamps:Stamp[]): Stamp;
}
/**
* An object map containing the fixed prototypes.
*/
interface Fixed {
methods: {};
state: {};
enclose: {(...encloseArgs:any[]): void}[];
}
}
declare module "stampit" {
export = stampit;
}