Socket
Socket
Sign inDemoInstall

class-wrapper

Package Overview
Dependencies
0
Maintainers
1
Versions
17
Alerts
File Explorer

Advanced tools

Install Socket

Detect and block malicious and high-risk dependencies

Install

Comparing version 2.1.2 to 2.1.3

doc/class-wrapper/2.1.3/Class.js.html

56

dest/class-wrapper.amd.js
/**
* class-wrapper v2.1.2
* class-wrapper v2.1.3
* Copyright (c) 2016-2019 Valerii Zinchenko

@@ -116,5 +116,9 @@ * License: MIT http://valerii-zinchenko.gitlab.io/observer/blob/master/LICENSE.txt

* - Native inheritance chain is saved. `instanceof` will give true for all parent classes.
* - Define the classes/functions/objects that are going to be encapsulated into the resulting class. The last encapsulated object will have a precedence over the previous, even the parent properties. Only the new used-defined properties for the new class will have the highest precedence. This gives the possibility to add other methods and properties into the class without touching the inheritance chain.
* - Provide the interface(s) that the class should implement. Interface can be any object with or without the implementation of the methods. It will be used just to get the method name and check if that method is implemented. If it is not, then the default method will be added to the class and it could be treated as an abstract method. By calling this abstract method it will throw an exception with the message, that this method is abstract.
* - Define the classes/functions/objects that are going to be encapsulated into the resulting class. The last encapsulated object will have a precedence over the previous. Only the new used-defined properties for the new class will have the highest precedence. This gives the possibility to add other methods and properties into the class without touching the inheritance chain.
* - Provide the interface(s) that the class should implement. Interface can be any object with or without the implementation of the methods. It will be used just to get the method name and check if that method is implemented. If it is not, then the default method will be added to the class and it could be treated as an abstract method. By calling this abstract method will throw an exception with the message, that this method is abstract.
* - All new user-defined class properties will be stored as default properties and each new instance will receive own copy of them. This is mostly important for properties, which contains simple objects (Object, Array), so they will not be shared between instances. All default properties will be copied into `this` before any user-defined constructor function will be executed.
* - NOTE: It is not analysing or extracting the properties from the parent classes, that were constructed by alternative ways (native `class`, `functions`, or other implementations of class constructors).
* - It is not recommended to use the same object as properties for a new classes, because then "super.someMethod(...)" will have unexpected behavior, it might go into the parent class of other class, where this object is also passed as new class properties and methods (`props`).
*
* @function ClassBuilder
* @see {@link Class}

@@ -131,3 +135,3 @@ * @see {@link Interface}

* @param {Object} props - Object of properties and methods for a new class.
* @param {Object | Function | Class | Array} [props.Encapsulate] - Define which object/function/class or an array of objects/functions/classes should be encapsulated into the new class.
* @param {Object | Function | Class | Array} [props.Encapsulate] - Define which object/function/class or an array of objects/functions/classes should be encapsulated into the new class. Only new metods, that does not exist in props and Parent chain, will be added. "super" in methods keeps its own inheritance chain, so after adding some method into the new class will not alternate the link to "super" of the encapsulated object.
* @param {Object | Object[] | Interface | Interface[]} [props.Implements] - Defines what interface(s) this class is implementing. Only the first level object methods will be taken into account, other properties will be ignored.

@@ -173,3 +177,3 @@ * @param {String} [props.__name = "Class"] - Specify the class name what will be visible near the variables during the debugging.

${constructorTemplate(Parent, Constructor) || ''}
}
};
`);

@@ -182,3 +186,8 @@ // --------------------------------------------------

// Apply parent's defaults
if (Parent.prototype.__defaults) {
encapsulate(Parent.prototype.__defaults, Class);
}
// Prepare an array of what is going to be encapsulated into a new class

@@ -198,9 +207,8 @@ // --------------------------------------------------

}
// Put parent's defaults into an encapsulation stack
if (Parent.prototype.__defaults) {
encapsulations.unshift(Parent.prototype.__defaults);
}
// Put properties and methods for a new class into the encapsulation stack
encapsulations.push(props);
// Add support of "super" for new methods
Object.setPrototypeOf(props, Parent.prototype);
// Apply new props and methods
encapsulate(props, Class, true);
// Validate what is going to be encapsulated

@@ -219,3 +227,3 @@ if (encapsulations.some(function(item) {

encapsulations.forEach(item => {
ClassBuilder.encapsulate(item, Class);
encapsulate(item, Class);
});

@@ -261,6 +269,9 @@ // --------------------------------------------------

*
* @ignore
*
* @param {Class | Object | Function} from - Object or Class that will be encapsulated.
* @param {Class} to - Class where the methods and properties will be encapsulated.
* @param {Boolean} [force=false] - Ignore the fact, that the prototype of "to" can already have a method, that is adding. This allows to a set new method with "super" inside.
*/
ClassBuilder.encapsulate = function(from, to) {
function encapsulate(from, to, force = false) {
if (Object.prototype.toString.call(from) === '[object Function]') {

@@ -271,2 +282,6 @@ from = from.prototype;

for (let key in from) {
if (!from.hasOwnProperty(key)) {
return;
}
const value = from[key];

@@ -276,3 +291,5 @@ switch (Object.prototype.toString.call(value)) {

case '[object Function]':
to.prototype[key] = value;
if (force || !to.prototype[key]) {
to.prototype[key] = value;
}
break;

@@ -298,4 +315,3 @@

}
};
}
ClassBuilder.utils = utils;

@@ -322,5 +338,7 @@

* - Native inheritance chain is saved. `instanceof` will give true for all parent classes.
* - Define the classes/functions/objects that are going to be encapsulated into the resulting class. The last encapsulated object will have a precedence over the previous, even the parent properties. Only the new used-defined properties for the new class will have the highest precedence. This gives the possibility to add other methods and properties into the class without touching the inheritance chain.
* - Define the classes/functions/objects that are going to be encapsulated into the resulting class. The last encapsulated object will have a precedence over the previous. Only the new used-defined properties for the new class will have the highest precedence. This gives the possibility to add other methods and properties into the class without touching the inheritance chain.
* - Provide the interface(s) that the class should implement. Interface can be any object with or without the implementation of the methods. It will be used just to get the method name and check if that method is implemented. If it is not, then the default method will be added to the class and it could be treated as an abstract method. By calling this abstract method will throw an exception with the message, that this method is abstract.
* - All new user-defined class properties will be stored as default properties and each new instance will receive own copy of them. This is mostly important for properties, which contains simple objects (Object, Array), so they will not be shared between instances. All default properties will be copied into `this` before any user-defined constructor function will be executed.
* - NOTE: It is not analysing or extracting the properties from the parent classes, that were constructed by alternative ways (native `class`, `functions`, or other implementations of class constructors).
* - It is not recommended to use the same object as properties for a new classes, because then "super.someMethod(...)" will have unexpected behavior, it might go into the parent class of other class, where this object is also passed as new class properties and methods (`props`).
*

@@ -337,3 +355,3 @@ * @function Class

* @param {Object} props - Object of properties and methods for a new class.
* @param {Object | Function | Class | Array} [props.Encapsulate] - Define which object/function/class or an array of objects/functions/classes should be encapsulated into the new class.
* @param {Object | Function | Class | Array} [props.Encapsulate] - Define which object/function/class or an array of objects/functions/classes should be encapsulated into the new class. Only new metods, that does not exist in props and Parent chain, will be added. "super" in methods keeps its own inheritance chain, so after adding some method into the new class will not alternate the link to "super" of the encapsulated object.
* @param {Object | Object[] | Interface | Interface[]} [props.Implements] - Defines what interface(s) this class is implementing. Only the first level object methods will be taken into account, other properties will be ignored.

@@ -349,3 +367,3 @@ * @param {String} [props.__name = "Class"] - Specify the class name what will be visible near the variables during the debugging.

return `constructor(...args) {
return !Constructor && BaseParent ? '' : `constructor(...args) {
super(...args);

@@ -352,0 +370,0 @@ ${!BaseParent && 'ClassBuilder.utils.deepExtend(this, this.constructor.prototype.__defaults);' || ''}

/**
* class-wrapper v2.1.2
* class-wrapper v2.1.3
* Copyright (c) 2016-2019 Valerii Zinchenko

@@ -7,2 +7,2 @@ * License: MIT http://valerii-zinchenko.gitlab.io/observer/blob/master/LICENSE.txt

*/
!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?e(exports):"function"==typeof define&&define.amd?define(["exports"],e):e((t=t||self)["class-wrapper"]={})}(this,function(exports){"use strict";const utils={deepCopy:function(t,e){var s,o;for(s in e)switch(o=e[s],Object.prototype.toString.call(o)){case"[object Object]":t[s]||(t[s]={}),utils.deepCopy(t[s],o);break;default:t[s]=o}return t},deepExtend:function(t,e){var s,o;for(s in e)if(o=e[s],t.hasOwnProperty(s))"object"==typeof t[s]&&utils.deepExtend(t[s],o);else switch(Object.prototype.toString.call(o)){case"[object Object]":t[s]={},utils.deepExtend(t[s],o);break;case"[object Array]":t[s]=o.map(t=>t);break;default:t[s]=o}return t}};function ClassBuilder(constructorTemplate,Parent,Constructor,props){if(props=arguments[arguments.length-1],Constructor=arguments[arguments.length-2],3!==arguments.length&&null!==Parent||(Parent=Object),arguments.length<3||"function"!=typeof constructorTemplate||null!==Constructor&&"function"!=typeof Constructor||"[object Object]"!==Object.prototype.toString.call(props))throw new TypeError("Incorrect input arguments. It should be: ClassBuilder(Function, [Function], Function | null, Object)");const name="string"==typeof props.__name&&props.__name||"Class";let Class;delete props.__name,eval(`\nClass = class ${name} extends Parent {\n\t${constructorTemplate(Parent,Constructor)||""}\n}\n`),Class.prototype.__defaults={};var encapsulations=[];if(props.Encapsulate&&("[object Array]"===Object.prototype.toString.call(props.Encapsulate)?encapsulations=encapsulations.concat(props.Encapsulate):encapsulations.push(props.Encapsulate),delete props.Encapsulate),Parent.prototype.__defaults&&encapsulations.unshift(Parent.prototype.__defaults),encapsulations.push(props),encapsulations.some(function(t){var e=Object.prototype.toString.call(t);return"[object Function]"!==e&&"[object Object]"!==e}))throw new TypeError("Some of the items for encapsulation are incorrect. An item can be: Object, Function, Class");return encapsulations.forEach(t=>{ClassBuilder.encapsulate(t,Class)}),props.Implements instanceof Array||(props.Implements=[props.Implements]),props.Implements.forEach(t=>{if(t instanceof Object)for(let e in t){t[e]instanceof Function&&!(Class.prototype[e]instanceof Function)&&(Class.prototype.__defaults[e],Class.prototype[e]=function(){throw new Error(`"${name}::${e}" is not implemented`)},console.warn(`Implementation of "${name}::${e}" is not found. This method will be treated as abstract method and will throw an error by execution.`))}}),Class}ClassBuilder.encapsulate=function(t,e){"[object Function]"===Object.prototype.toString.call(t)&&(t=t.prototype);for(let s in t){const o=t[s];switch(Object.prototype.toString.call(o)){case"[object Function]":e.prototype[s]=o;break;case"[object Object]":"__defaults"===s?utils.deepCopy(e.prototype.__defaults,o):(e.prototype.__defaults[s]||(e.prototype.__defaults[s]={}),utils.deepCopy(e.prototype.__defaults[s],o));break;default:e.prototype.__defaults[s]=o}}},ClassBuilder.utils=utils;const baseClasses=[];var Class=ClassBuilder.bind(null,function(t,e){const s=baseClasses.find(e=>t.prototype instanceof e);return s||-1!==baseClasses.indexOf(t)||baseClasses.push(t),`constructor(...args) {\n\t\tsuper(...args);\n\t\t${s?"":"ClassBuilder.utils.deepExtend(this, this.constructor.prototype.__defaults);"}\n\t\t${e?"Constructor.call(this, ...args);":""}\n\t}`});function Interface(t,e){return e?{...t,...e}:t}exports.utils=utils,exports.ClassBuilder=ClassBuilder,exports.Class=Class,exports.Interface=Interface,Object.defineProperty(exports,"__esModule",{value:!0})});
!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?e(exports):"function"==typeof define&&define.amd?define(["exports"],e):e((t=t||self)["class-wrapper"]={})}(this,function(exports){"use strict";const utils={deepCopy:function(t,e){var o,s;for(o in e)switch(s=e[o],Object.prototype.toString.call(s)){case"[object Object]":t[o]||(t[o]={}),utils.deepCopy(t[o],s);break;default:t[o]=s}return t},deepExtend:function(t,e){var o,s;for(o in e)if(s=e[o],t.hasOwnProperty(o))"object"==typeof t[o]&&utils.deepExtend(t[o],s);else switch(Object.prototype.toString.call(s)){case"[object Object]":t[o]={},utils.deepExtend(t[o],s);break;case"[object Array]":t[o]=s.map(t=>t);break;default:t[o]=s}return t}};function ClassBuilder(constructorTemplate,Parent,Constructor,props){if(props=arguments[arguments.length-1],Constructor=arguments[arguments.length-2],3!==arguments.length&&null!==Parent||(Parent=Object),arguments.length<3||"function"!=typeof constructorTemplate||null!==Constructor&&"function"!=typeof Constructor||"[object Object]"!==Object.prototype.toString.call(props))throw new TypeError("Incorrect input arguments. It should be: ClassBuilder(Function, [Function], Function | null, Object)");const name="string"==typeof props.__name&&props.__name||"Class";let Class;delete props.__name,eval(`\nClass = class ${name} extends Parent {\n\t${constructorTemplate(Parent,Constructor)||""}\n};\n`),Class.prototype.__defaults={},Parent.prototype.__defaults&&encapsulate(Parent.prototype.__defaults,Class);var encapsulations=[];if(props.Encapsulate&&("[object Array]"===Object.prototype.toString.call(props.Encapsulate)?encapsulations=encapsulations.concat(props.Encapsulate):encapsulations.push(props.Encapsulate),delete props.Encapsulate),Object.setPrototypeOf(props,Parent.prototype),encapsulate(props,Class,!0),encapsulations.some(function(t){var e=Object.prototype.toString.call(t);return"[object Function]"!==e&&"[object Object]"!==e}))throw new TypeError("Some of the items for encapsulation are incorrect. An item can be: Object, Function, Class");return encapsulations.forEach(t=>{encapsulate(t,Class)}),props.Implements instanceof Array||(props.Implements=[props.Implements]),props.Implements.forEach(t=>{if(t instanceof Object)for(let e in t){t[e]instanceof Function&&!(Class.prototype[e]instanceof Function)&&(Class.prototype.__defaults[e],Class.prototype[e]=function(){throw new Error(`"${name}::${e}" is not implemented`)},console.warn(`Implementation of "${name}::${e}" is not found. This method will be treated as abstract method and will throw an error by execution.`))}}),Class}function encapsulate(t,e,o=!1){"[object Function]"===Object.prototype.toString.call(t)&&(t=t.prototype);for(let s in t){if(!t.hasOwnProperty(s))return;const n=t[s];switch(Object.prototype.toString.call(n)){case"[object Function]":!o&&e.prototype[s]||(e.prototype[s]=n);break;case"[object Object]":"__defaults"===s?utils.deepCopy(e.prototype.__defaults,n):(e.prototype.__defaults[s]||(e.prototype.__defaults[s]={}),utils.deepCopy(e.prototype.__defaults[s],n));break;default:e.prototype.__defaults[s]=n}}}ClassBuilder.utils=utils;const baseClasses=[];var Class=ClassBuilder.bind(null,function(t,e){const o=baseClasses.find(e=>t.prototype instanceof e);return o||-1!==baseClasses.indexOf(t)||baseClasses.push(t),!e&&o?"":`constructor(...args) {\n\t\tsuper(...args);\n\t\t${o?"":"ClassBuilder.utils.deepExtend(this, this.constructor.prototype.__defaults);"}\n\t\t${e?"Constructor.call(this, ...args);":""}\n\t}`});function Interface(t,e){return e?{...t,...e}:t}exports.utils=utils,exports.ClassBuilder=ClassBuilder,exports.Class=Class,exports.Interface=Interface,Object.defineProperty(exports,"__esModule",{value:!0})});

@@ -31,5 +31,7 @@ /*

* - Native inheritance chain is saved. `instanceof` will give true for all parent classes.
* - Define the classes/functions/objects that are going to be encapsulated into the resulting class. The last encapsulated object will have a precedence over the previous, even the parent properties. Only the new used-defined properties for the new class will have the highest precedence. This gives the possibility to add other methods and properties into the class without touching the inheritance chain.
* - Define the classes/functions/objects that are going to be encapsulated into the resulting class. The last encapsulated object will have a precedence over the previous. Only the new used-defined properties for the new class will have the highest precedence. This gives the possibility to add other methods and properties into the class without touching the inheritance chain.
* - Provide the interface(s) that the class should implement. Interface can be any object with or without the implementation of the methods. It will be used just to get the method name and check if that method is implemented. If it is not, then the default method will be added to the class and it could be treated as an abstract method. By calling this abstract method will throw an exception with the message, that this method is abstract.
* - All new user-defined class properties will be stored as default properties and each new instance will receive own copy of them. This is mostly important for properties, which contains simple objects (Object, Array), so they will not be shared between instances. All default properties will be copied into `this` before any user-defined constructor function will be executed.
* - NOTE: It is not analysing or extracting the properties from the parent classes, that were constructed by alternative ways (native `class`, `functions`, or other implementations of class constructors).
* - It is not recommended to use the same object as properties for a new classes, because then "super.someMethod(...)" will have unexpected behavior, it might go into the parent class of other class, where this object is also passed as new class properties and methods (`props`).
*

@@ -46,3 +48,3 @@ * @function Class

* @param {Object} props - Object of properties and methods for a new class.
* @param {Object | Function | Class | Array} [props.Encapsulate] - Define which object/function/class or an array of objects/functions/classes should be encapsulated into the new class.
* @param {Object | Function | Class | Array} [props.Encapsulate] - Define which object/function/class or an array of objects/functions/classes should be encapsulated into the new class. Only new metods, that does not exist in props and Parent chain, will be added. "super" in methods keeps its own inheritance chain, so after adding some method into the new class will not alternate the link to "super" of the encapsulated object.
* @param {Object | Object[] | Interface | Interface[]} [props.Implements] - Defines what interface(s) this class is implementing. Only the first level object methods will be taken into account, other properties will be ignored.

@@ -58,3 +60,3 @@ * @param {String} [props.__name = "Class"] - Specify the class name what will be visible near the variables during the debugging.

return `constructor(...args) {
return !Constructor && BaseParent ? '' : `constructor(...args) {
super(...args);

@@ -61,0 +63,0 @@ ${!BaseParent && 'ClassBuilder.utils.deepExtend(this, this.constructor.prototype.__defaults);' || ''}

@@ -9,3 +9,2 @@ /*

/**

@@ -31,5 +30,9 @@ * @file Implementation of [ClassBuilder]{@link ClassBuilder}

* - Native inheritance chain is saved. `instanceof` will give true for all parent classes.
* - Define the classes/functions/objects that are going to be encapsulated into the resulting class. The last encapsulated object will have a precedence over the previous, even the parent properties. Only the new used-defined properties for the new class will have the highest precedence. This gives the possibility to add other methods and properties into the class without touching the inheritance chain.
* - Provide the interface(s) that the class should implement. Interface can be any object with or without the implementation of the methods. It will be used just to get the method name and check if that method is implemented. If it is not, then the default method will be added to the class and it could be treated as an abstract method. By calling this abstract method it will throw an exception with the message, that this method is abstract.
* - Define the classes/functions/objects that are going to be encapsulated into the resulting class. The last encapsulated object will have a precedence over the previous. Only the new used-defined properties for the new class will have the highest precedence. This gives the possibility to add other methods and properties into the class without touching the inheritance chain.
* - Provide the interface(s) that the class should implement. Interface can be any object with or without the implementation of the methods. It will be used just to get the method name and check if that method is implemented. If it is not, then the default method will be added to the class and it could be treated as an abstract method. By calling this abstract method will throw an exception with the message, that this method is abstract.
* - All new user-defined class properties will be stored as default properties and each new instance will receive own copy of them. This is mostly important for properties, which contains simple objects (Object, Array), so they will not be shared between instances. All default properties will be copied into `this` before any user-defined constructor function will be executed.
* - NOTE: It is not analysing or extracting the properties from the parent classes, that were constructed by alternative ways (native `class`, `functions`, or other implementations of class constructors).
* - It is not recommended to use the same object as properties for a new classes, because then "super.someMethod(...)" will have unexpected behavior, it might go into the parent class of other class, where this object is also passed as new class properties and methods (`props`).
*
* @function ClassBuilder
* @see {@link Class}

@@ -46,3 +49,3 @@ * @see {@link Interface}

* @param {Object} props - Object of properties and methods for a new class.
* @param {Object | Function | Class | Array} [props.Encapsulate] - Define which object/function/class or an array of objects/functions/classes should be encapsulated into the new class.
* @param {Object | Function | Class | Array} [props.Encapsulate] - Define which object/function/class or an array of objects/functions/classes should be encapsulated into the new class. Only new metods, that does not exist in props and Parent chain, will be added. "super" in methods keeps its own inheritance chain, so after adding some method into the new class will not alternate the link to "super" of the encapsulated object.
* @param {Object | Object[] | Interface | Interface[]} [props.Implements] - Defines what interface(s) this class is implementing. Only the first level object methods will be taken into account, other properties will be ignored.

@@ -52,3 +55,3 @@ * @param {String} [props.__name = "Class"] - Specify the class name what will be visible near the variables during the debugging.

*/
function ClassBuilder(constructorTemplate, Parent, Constructor, props) {
export default function ClassBuilder(constructorTemplate, Parent, Constructor, props) {
// Last input argument is an object of properties for a new class

@@ -89,3 +92,3 @@ props = arguments[arguments.length - 1];

${constructorTemplate(Parent, Constructor) || ''}
}
};
`);

@@ -98,3 +101,8 @@ // --------------------------------------------------

// Apply parent's defaults
if (Parent.prototype.__defaults) {
encapsulate(Parent.prototype.__defaults, Class);
}
// Prepare an array of what is going to be encapsulated into a new class

@@ -114,9 +122,8 @@ // --------------------------------------------------

}
// Put parent's defaults into an encapsulation stack
if (Parent.prototype.__defaults) {
encapsulations.unshift(Parent.prototype.__defaults);
}
// Put properties and methods for a new class into the encapsulation stack
encapsulations.push(props);
// Add support of "super" for new methods
Object.setPrototypeOf(props, Parent.prototype);
// Apply new props and methods
encapsulate(props, Class, true);
// Validate what is going to be encapsulated

@@ -135,3 +142,3 @@ if (encapsulations.some(function(item) {

encapsulations.forEach(item => {
ClassBuilder.encapsulate(item, Class);
encapsulate(item, Class);
});

@@ -179,6 +186,9 @@ // --------------------------------------------------

*
* @ignore
*
* @param {Class | Object | Function} from - Object or Class that will be encapsulated.
* @param {Class} to - Class where the methods and properties will be encapsulated.
* @param {Boolean} [force=false] - Ignore the fact, that the prototype of "to" can already have a method, that is adding. This allows to a set new method with "super" inside.
*/
ClassBuilder.encapsulate = function(from, to) {
function encapsulate(from, to, force = false) {
if (Object.prototype.toString.call(from) === '[object Function]') {

@@ -189,2 +199,6 @@ from = from.prototype;

for (let key in from) {
if (!from.hasOwnProperty(key)) {
return;
}
const value = from[key];

@@ -194,3 +208,5 @@ switch (Object.prototype.toString.call(value)) {

case '[object Function]':
to.prototype[key] = value;
if (force || !to.prototype[key]) {
to.prototype[key] = value;
}
break;

@@ -219,4 +235,1 @@

ClassBuilder.utils = utils;
export default ClassBuilder;

@@ -29,4 +29,4 @@ /*

*/
export default function(Parent, props) {
export default function Interface(Parent, props) {
return props ? {...Parent, ...props} : Parent;
};
{
"name": "class-wrapper",
"version": "2.1.2",
"version": "2.1.3",
"description": "Set of wrappers to create classes like in C++ and other components",

@@ -20,3 +20,3 @@ "main": "main.js",

"doc-versioned": "grunt jsdoc:version",
"preversion": "npm test",
"preversion": "npm test && npm run clean && npm run doc-versioned",
"prepublishOnly": "npm run clean && npm run build && npm run doc-versioned"

@@ -29,6 +29,6 @@ },

"chai": "^4.1.2",
"grunt": "1.x",
"grunt": "^1.0.4",
"grunt-cli": "^1.3.2",
"grunt-contrib-copy": "1.x",
"grunt-jsdoc": "^2.1.0",
"grunt-contrib-copy": "^1.0.0",
"grunt-jsdoc": "^2.4.0",
"http-server": "^0.11.1",

@@ -39,3 +39,3 @@ "load-grunt-tasks": "^3.5.2",

"portfinder": "^1.0.20",
"puppeteer": "^1.12.1",
"puppeteer": "^1.19.0",
"puppeteer-to-istanbul": "^1.2.2",

@@ -42,0 +42,0 @@ "rollup": "^1.1.2",

@@ -8,6 +8,6 @@ # {class}

* `ClassBuilder` - is the main wrapper that realizes the inheritance, data encapsulation, stores the default values and in result it returns a class. This builder is useful to define custom pre-construction routines by setting the class constructor template.
* `Class` - is a `ClassBuilder` with already predefined construction routines. The resulting behavior of how the objects are constructing is similar to the behaviour in C++ - all parent constructors are executing first, starting from the root parent constructor, only then the constructor of the class will be executed. With this there is no need to always explicitly call the parent constructor in each constructor function and pass there all the arguments. The constructor function can contain only the effective code that is needed for a new class.
* `Class` - is a `ClassBuilder` with already predefined construction routines. The resulting behavior of how the objects are constructing is similar to the behaviour in C++ - all parent constructors are executing first, starting from the root parent constructor, without any possibility to alternate the input arguments, only then the constructor function provided for the class will be executed. With this there is no need to always explicitly call the parent constructor in each constructor function and pass there all the arguments. The constructor function can contain only the effective code that is needed for a new class.
* `Interface` - is a simple builder of interfaces, that will be passed into Class under property `Implements`. It allows to extend some parent interface.
Defined class properties are treated as default values for a new instance and they are isolated between instances. For example, if some class has a simple object in properties (Object or Array), then each instance will have its own copy of that object.
Defined class properties are treated as default values for a new instance and they are isolated between instances. For example, if some class has a simple object in properties (Object or Array), then each instance will have its own copy of that object. But this works good only for standard built-in objects, for other objects, created by more complex classes, it will try to copy the whole structure into the object. For such cases it is recommended to set the default value to `null` and create the needed instance in the constructor function.

@@ -14,0 +14,0 @@

@@ -37,3 +37,27 @@ import {Class} from '../main.js';

test('Constructor chain', function(){
test('Iheritance for a function', function(){
const GrandParentClass = Class(function(){}, {});
const ParentClass = Class(GrandParentClass, function(){}, {});
const ChildClass = Class(ParentClass, function(){}, {});
const result = new ChildClass();
assert.instanceOf(result, ChildClass, 'Resulting instance should be an instance of ChildClass');
assert.instanceOf(result, ParentClass, 'Resulting instance should be an instance of ParentClass, because ParentClass is a parent class of the ChildClass');
assert.instanceOf(result, GrandParentClass, 'Resulting instance should be an instance of GrandParentClass, because GrandParentClass is a parent class of ParentClass and ParentClass is a parent class of ChildClass');
});
test('Iheritance for a class', function(){
class GrandParentClass {};
const ParentClass = Class(GrandParentClass, function(){}, {});
const ChildClass = Class(ParentClass, function(){}, {});
const result = new ChildClass();
assert.instanceOf(result, ChildClass, 'Resulting instance should be an instance of ChildClass');
assert.instanceOf(result, ParentClass, 'Resulting instance should be an instance of ParentClass, because ParentClass is a parent class of the ChildClass');
assert.instanceOf(result, GrandParentClass, 'Resulting instance should be an instance of GrandParentClass, because GrandParentClass is a parent class of ParentClass and ParentClass is a parent class of ChildClass');
});
test('Constructor chain for functions', function(){
const grandParentConstructor = sinon.spy();

@@ -52,6 +76,6 @@ const parentConstructor = sinon.spy();

assert.isTrue(childConstructor.calledOnce, 'Constructor of child class was not called');
assert.isTrue(parentConstructor.calledOnce, 'Constructor of parent class was not called');
assert.isTrue(grandParentConstructor.calledOnce, 'Constructor of grand parent class was not called');
assert.isTrue(childConstructor.calledOnce, 'Constructor of child class must be called');
assert.isTrue(parentConstructor.calledOnce, 'Constructor of parent class must be called');
assert.isTrue(grandParentConstructor.calledOnce, 'Constructor of grand parent class must be called');
assert.isTrue(childConstructor.calledAfter(parentConstructor), 'Constructor of child and parent class were called in incorrect order');

@@ -65,20 +89,148 @@ assert.isTrue(parentConstructor.calledAfter(grandParentConstructor), 'Constructor of parent and grand parent class were called in incorrect order');

test('Iheritance', function(){
var GrandParentClass;
var ParentClass;
var ChildClass;
test('Constructor chain for classes', function(){
const parentConstructor = sinon.spy();
const ParentClass = class {
constructor(...args) {
parentConstructor(...args);
}
};
const childConstructor = sinon.spy();
const arg0 = 'abc';
const arg1 = {};
var result;
assert.doesNotThrow(function(){
GrandParentClass = Class(function(){}, {});
ParentClass = Class(GrandParentClass, function(){}, {});
ChildClass = Class(ParentClass, function(){}, {});
const ChildClass = Class(ParentClass, childConstructor, {});
result = new ChildClass();
const result = new ChildClass(arg0, arg1);
assert.isTrue(childConstructor.calledOnce, 'Constructor of child class must be called');
assert.isTrue(parentConstructor.calledOnce, 'Constructor of parent class must be called');
assert.isTrue(childConstructor.calledAfter(parentConstructor), 'Constructor of child and parent class were called in incorrect order');
assert.isTrue(childConstructor.calledWith(arg0, arg1), 'Child constructucor was called with incorrect input arguments');
assert.isTrue(parentConstructor.calledWith(arg0, arg1), 'Parent constructucor was called with incorrect input arguments');
});
test('Support of "super" inside of the method', function() {
const fn1 = sinon.spy();
const fn2 = sinon.spy();
const fn3 = sinon.spy();
const GrandParent = class {
method() {
fn1();
}
}
const Parent = Class(GrandParent, null, {
method() {
super.method();
fn2();
}
});
const Child = Class(Parent, null, {
method() {
super.method();
fn3();
}
});
assert.instanceOf(result, ChildClass, 'Resulting instance should be an instance of ChildClass');
assert.instanceOf(result, ParentClass, 'Resulting instance should be an instance of ParentClass, because ParentClass is a parent class of the ChildClass');
assert.instanceOf(result, GrandParentClass, 'Resulting instance should be an instance of GrandParentClass, because GrandParentClass is a parent class of ParentClass and ParentClass is a parent class of ChildClass');
const child = new Child();
child.method();
assert.isTrue(fn1.calledOnce, 'GrandParent\'s method must be called');
assert.isTrue(fn2.calledOnce, 'Parent\'s method must be called');
assert.isTrue(fn3.calledOnce, 'Child\'s method must be called');
assert.isTrue(fn2.calledAfter(fn1), 'Parent\'s method must be called after GrandParent\'s method');
assert.isTrue(fn3.calledAfter(fn2), 'Child\'s method must be called after Parent\'s method');
});
test('Support of "super" in encapsulated object without a parent class must not be supported', function() {
const fn1 = sinon.spy();
const fn2 = sinon.spy();
const Parent = Class(null, {});
const Child = Class(Parent, null, {
Encapsulate: {
method() {
super.method();
fn2();
}
}
});
const child = new Child();
assert.throws(function() {
child.method();
}, TypeError, '(intermediate value).method is not a function', 'This means that encapsulated object is incorrectly created. If encapsulated objectd executes somepthing with "super", then this object must have own parent class with this method');
});
test('"super" in encapsulated method must keep his inheritance chain', function() {
const fn1 = sinon.spy();
const fn2 = sinon.spy();
const Parent = Class(null, {
method() {
fn1();
}
});
const ToEncapsulate = Class(Parent, null, {
method() {
super.method();
fn2();
}
});
const Child = Class(null, {
Encapsulate: ToEncapsulate
});
const child = new Child();
child.method();
assert.isTrue(fn1.called, 'Method of the encapsulated parent class must be called');
assert.isTrue(fn2.called, 'Method of the encapsulated class must be called');
assert.isTrue(fn2.calledAfter(fn1), 'Encapsulated method must be called after Parent\'s method');
});
test('"super" in encapsulated method must not interfere with class where it is encapsulating', function() {
const fn1 = sinon.spy();
const fn2 = sinon.spy();
const fn3 = sinon.spy();
const fn4 = sinon.spy();
const Parent1 = Class(null, {
method() {
fn1();
}
});
const ToEncapsulate = Class(Parent1, null, {
method() {
super.method();
fn3();
}
});
const Parent2 = Class(null, {
method() {
fn2();
}
});
const Child = Class(Parent2, null, {
Encapsulate: ToEncapsulate,
method() {
super.method();
fn4();
}
});
const child = new Child();
child.method();
assert.isFalse(fn1.called, 'Method of the encapsulated parent class must not be called');
assert.isFalse(fn3.called, 'Method of the encapsulated class must not be called');
assert.isTrue(fn2.called, 'Method of the normal parent class must be called');
assert.isTrue(fn4.called, 'Method of the child must be called');
assert.isTrue(fn4.calledAfter(fn2), 'Child method must be called after Parent\'s method');
});
});

@@ -183,4 +183,3 @@ import {ClassBuilder} from '../main.js';

assert.isArray(ref.__defaults.array, 'Array type was not copied');
assert.isTrue(ref.__defaults.array[0] === properties.array[0] && ref.__defaults.array[1] === properties.array[1], 'Array items were incorrectly copied');
assert.isArray(ref.__defaults.array, 'Array was not initialized');

@@ -187,0 +186,0 @@ assert.isObject(ref.__defaults.nestedObj, 'Object type was not saved');

@@ -0,1 +1,3 @@

const DEBUG = false;
const portfinder = require('portfinder');

@@ -15,2 +17,11 @@ const pti = require('puppeteer-to-istanbul');

let headless = true;
let devtools = false;
let timeout;
if (DEBUG) {
headless = false;
devtools = true;
timeout = 0;
}
portfinder.basePort = 8080;

@@ -26,4 +37,4 @@ portfinder.getPort((err, port) => {

const browser = await puppeteer.launch({
//headless: false,
//devtools: true,
headless,
devtools,
args: ['--no-sandbox']

@@ -55,3 +66,5 @@ });

// wait until testing statistics will be defined on the page (it should happen at the end of the testing)
await page.waitForFunction(getStats);
await page.waitForFunction(getStats, {
timeout
});

@@ -58,0 +71,0 @@ const stats = await page.evaluate(getStats);

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap

Packages

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc