static-type-js
Advanced tools
Comparing version 0.2.4 to 0.3.0
@@ -5,3 +5,3 @@ { | ||
"description": "Prototype inheritance and type system for js", | ||
"version": "0.2.4", | ||
"version": "0.3.0", | ||
"repository": { | ||
@@ -8,0 +8,0 @@ "type": "git", |
@@ -9,2 +9,6 @@ Type-js [](https://travis-ci.org/igorzg/type-js) | ||
* To define object you must provide two objects to Type.create(type_definition, prototype); | ||
* _construct function is executed when object is constructed to inherit use _super(arguments) inside of _construct | ||
* _invoke is executed before _construct cross inherited objects on each object construction | ||
* _super() use _super(arguments) call to call inherited method. | ||
* _super is not allowed to be executed inside _invoke call | ||
* In IE 8,7,6 inheritance works but extensions and changes are allowed. | ||
@@ -14,6 +18,12 @@ ```js | ||
/// var Child = Parent.inherit([type definition], [prototype]); | ||
var AdminUser, Group, User; | ||
Group = Type.create({ | ||
_group: Type.STRING | ||
_group: Type.STRING, | ||
invoked: Type.STRING | ||
}, { | ||
_invoke: function(group) { | ||
this.invoked = group; | ||
}, | ||
_construct: function(group) { | ||
@@ -20,0 +30,0 @@ this._group = group; |
193
type-spec.js
@@ -465,2 +465,195 @@ describe('Typejs', function () { | ||
it('invoke should be invoked correctly', function () { | ||
Group = Type.create({ | ||
_group: Type.STIRNG, | ||
child: Type.OBJECT | ||
}, { | ||
_invoke: function (group) { | ||
this.child = {current: group}; | ||
return this.child; | ||
}, | ||
_construct: function (group) { | ||
this._group = group; | ||
}, | ||
setGroup: function (value) { | ||
this._group = value; | ||
}, | ||
getGroup: function () { | ||
return this._group; | ||
} | ||
}); | ||
AdminUser = Group.inherit({ | ||
username: Type.STIRNG, | ||
date: Type.DATE | ||
}, { | ||
_invoke: function (parent, username) { | ||
this.child = {parent: parent, current: username}; | ||
try { | ||
this._super('SUPER IS NOT WORKING HERE'); | ||
} catch (e) { | ||
expect(e.message).toBe("undefined is not a function"); | ||
} | ||
return this.child; | ||
}, | ||
_construct: function (username) { | ||
this.username = username; | ||
this.date = new Date; | ||
} | ||
}); | ||
User = AdminUser.inherit({ | ||
username: Type.STIRNG, | ||
date: Type.DATE | ||
}, { | ||
_invoke: function (parent, username) { | ||
this.child = {parent: parent, current: username}; | ||
return this.child; | ||
}, | ||
_construct: function (username) { | ||
this.username = username; | ||
} | ||
}); | ||
var us = new User('igor'); | ||
expect(Type.isObject(us.child)).toBe(true); | ||
expect(us.child.parent.parent.current).toBe('igor'); | ||
expect(us.child.parent.current).toBe('igor'); | ||
expect(us.child.current).toBe('igor'); | ||
}); | ||
it('invoke should be invoked correctly 2', function () { | ||
Group = Type.create({ | ||
_group: Type.STIRNG, | ||
child: Type.OBJECT | ||
}, { | ||
_invoke: function (group) { | ||
this.child = {current: group}; | ||
return this.child; | ||
}, | ||
_construct: function (group) { | ||
this._group = group; | ||
}, | ||
setGroup: function (value) { | ||
this._group = value; | ||
}, | ||
getGroup: function () { | ||
return this._group; | ||
} | ||
}); | ||
AdminUser = Group.inherit({ | ||
username: Type.STIRNG, | ||
date: Type.DATE | ||
}, { | ||
_construct: function (username) { | ||
this.username = username; | ||
this.date = new Date; | ||
} | ||
}); | ||
User = AdminUser.inherit({ | ||
username: Type.STIRNG, | ||
date: Type.DATE | ||
}, { | ||
_invoke: function (parent, username) { | ||
this.child = {parent: parent, current: username}; | ||
return this.child; | ||
}, | ||
_construct: function (username) { | ||
this.username = username; | ||
} | ||
}); | ||
var us = new User('igor'); | ||
expect(Type.isObject(us.child)).toBe(true); | ||
expect(us.child.parent.current.current).toBe('igor'); | ||
expect(us.child.current).toBe('igor'); | ||
}); | ||
it('invoke should be invoked correctly 3', function () { | ||
Group = Type.create({ | ||
_group: Type.STIRNG, | ||
child: Type.OBJECT | ||
}, { | ||
_invoke: function (group) { | ||
this.child = {current: group}; | ||
return this.child; | ||
}, | ||
_construct: function (group) { | ||
this._group = group; | ||
}, | ||
setGroup: function (value) { | ||
this._group = value; | ||
}, | ||
getGroup: function () { | ||
return this._group; | ||
} | ||
}); | ||
AdminUser = Group.inherit({ | ||
username: Type.STIRNG, | ||
date: Type.DATE | ||
}, { | ||
_construct: function (username) { | ||
this.username = username; | ||
this.date = new Date; | ||
} | ||
}); | ||
User = AdminUser.inherit({ | ||
username: Type.STIRNG, | ||
date: Type.DATE | ||
}, { | ||
_construct: function (username) { | ||
this.username = username; | ||
} | ||
}); | ||
var us = new User('igor'); | ||
expect(Type.isObject(us.child)).toBe(true); | ||
expect(us.child.current.current.current.current).toBe('igor'); | ||
}); | ||
it('invoke should be invoked correctly 4', function () { | ||
Group = Type.create({ | ||
_group: Type.STIRNG, | ||
child: Type.OBJECT | ||
}, { | ||
_invoke: function (group) { | ||
this.child = {current: group}; | ||
}, | ||
_construct: function (group) { | ||
this._group = group; | ||
}, | ||
setGroup: function (value) { | ||
this._group = value; | ||
}, | ||
getGroup: function () { | ||
return this._group; | ||
} | ||
}); | ||
AdminUser = Group.inherit({ | ||
username: Type.STIRNG, | ||
date: Type.DATE | ||
}, { | ||
_construct: function (username) { | ||
this.username = username; | ||
this.date = new Date; | ||
} | ||
}); | ||
User = AdminUser.inherit({ | ||
username: Type.STIRNG, | ||
date: Type.DATE | ||
}, { | ||
_construct: function (username) { | ||
this.username = username; | ||
} | ||
}); | ||
var us = new User('igor'); | ||
expect(Type.isObject(us.child)).toBe(true); | ||
expect(us.child.current).toBe('igor'); | ||
}); | ||
xit('benchmark group', function () { | ||
@@ -467,0 +660,0 @@ var Test = Type.create({ |
47
type.js
@@ -14,3 +14,3 @@ (function (root, factory) { | ||
"use strict"; | ||
var initializing = false, prototype, superRegx = /\b_super\b/; | ||
var initializing = false, superRegx = /\b_super\b/; | ||
@@ -28,4 +28,4 @@ if (!Object.preventExtensions) { | ||
*/ | ||
function handleSuper(name, fn, _super) { | ||
return function () { | ||
function _handleSuper(name, fn, _super) { | ||
return function _superCall() { | ||
this._super = _super[name]; | ||
@@ -35,3 +35,2 @@ return fn.apply(this, arguments); | ||
} | ||
/** | ||
@@ -41,2 +40,20 @@ * @license Mit Licence 2014 | ||
* @author Igor Ivanovic | ||
* @name _handleConstruct | ||
* @description | ||
* Handle construct | ||
*/ | ||
function _handleInvoke(invoke, inherited) { | ||
return function _invokeCall() { | ||
var args = Array.prototype.slice.call(arguments), data; | ||
data = inherited.apply(this, args); | ||
if (!!data) { | ||
args.unshift(data); | ||
} | ||
return invoke.apply(this, args); | ||
} | ||
} | ||
/** | ||
* @license Mit Licence 2014 | ||
* @since 0.0.1 | ||
* @author Igor Ivanovic | ||
* @name Type | ||
@@ -59,3 +76,3 @@ * | ||
Type.create = function (def, prop) { | ||
var _super = this.prototype, prototype; | ||
var _super = this.prototype, prototype, _inv = "_invoke"; | ||
@@ -73,4 +90,4 @@ if (!Type.assert(Type.OBJECT, prop)) { | ||
Object.keys(prop).forEach(function it(key) { | ||
if (Type.isFunction(prop[key]) && Type.isFunction(_super[key]) && superRegx.test(prop[key])) { | ||
prototype[key] = handleSuper(key, prop[key], _super); | ||
if (key !== _inv && Type.isFunction(prop[key]) && Type.isFunction(_super[key]) && superRegx.test(prop[key])) { | ||
prototype[key] = _handleSuper(key, prop[key], _super); | ||
} else { | ||
@@ -80,2 +97,8 @@ prototype[key] = prop[key]; | ||
}); | ||
if (Type.isFunction(_super[_inv]) && Type.isFunction(prototype[_inv])) { | ||
prototype[_inv] = _handleInvoke(prototype[_inv], _super[_inv]); | ||
} else if (Type.isFunction(_super[_inv])) { | ||
prototype[_inv] = _super[_inv]; | ||
} | ||
// create definition | ||
@@ -87,3 +110,6 @@ Object.keys(def).forEach(function (key) { | ||
Type.defineProperty(Type.FUNCTION, prototype, "_super"); | ||
/** | ||
* @returns {Type.Class} | ||
* @constructor | ||
*/ | ||
function Class() { | ||
@@ -95,7 +121,8 @@ if (initializing) { | ||
Object.preventExtensions(this); // prevent extensions | ||
if (Type.isFunction(this._invoke)) { | ||
this._invoke.apply(this, arguments); | ||
} | ||
if (Type.isFunction(this._construct)) { | ||
this._construct.apply(this, arguments); | ||
} | ||
} | ||
@@ -102,0 +129,0 @@ |
40208
1015
78