decorator-utils
Advanced tools
Comparing version 0.0.2 to 0.0.3
@@ -14,9 +14,5 @@ "use strict"; | ||
var DecoratorUtils = (function () { | ||
function DecoratorUtils() { | ||
_classCallCheck(this, DecoratorUtils); | ||
} | ||
_createClass(DecoratorUtils, null, [{ | ||
key: "getType", | ||
value: function getType(args) { | ||
key: "getDeclarationType", | ||
value: function getDeclarationType(args) { | ||
var _Array$prototype$slice$call = Array.prototype.slice.call(args); | ||
@@ -31,7 +27,7 @@ | ||
if (args.length === 1 && typeof target === "function") { | ||
return DecoratorUtils.type.CLASS; | ||
return DecoratorUtils.declarationTypes.CLASS; | ||
} else if (args.length === 3 && typeof target === "object" && typeof target.constructor === "function") { | ||
var isObjectLiteral = target.constructor.name === "Object"; | ||
var isAccessor = descriptor.get || descriptor.set; | ||
return DecoratorUtils.type[(isObjectLiteral ? "OBJECT_LITERAL" : "CLASS") + "_" + (isAccessor ? "ACCESSOR" : "METHOD")]; | ||
return DecoratorUtils.declarationTypes[(isObjectLiteral ? "OBJECT_LITERAL" : "CLASS") + "_" + (isAccessor ? "ACCESSOR" : "METHOD")]; | ||
} | ||
@@ -42,3 +38,16 @@ | ||
}, { | ||
key: "type", | ||
key: "createDecorator", | ||
value: function createDecorator(supportedDeclarationTypes, fn) { | ||
supportedDeclarationTypes = new Set([].concat(supportedDeclarationTypes)); | ||
return function () { | ||
if (!supportedDeclarationTypes.has(DecoratorUtils.getDeclarationType(arguments))) { | ||
throw new Error("Decorator must be applied to a supported declaration type."); | ||
} | ||
return fn.apply(this, arguments); | ||
}; | ||
} | ||
}, { | ||
key: "declarationTypes", | ||
value: ["CLASS", "CLASS_METHOD", "CLASS_ACCESSOR", "OBJECT_LITERAL_METHOD", "OBJECT_LITERAL_ACCESSOR"].reduce(function (obj, name) { | ||
@@ -50,2 +59,8 @@ return Object.defineProperty(obj, name, { value: Symbol(name) }); | ||
function DecoratorUtils() { | ||
_classCallCheck(this, DecoratorUtils); | ||
throw new Error("Static class cannot be instantiated."); | ||
} | ||
return DecoratorUtils; | ||
@@ -52,0 +67,0 @@ })(); |
@@ -12,6 +12,18 @@ "use strict"; | ||
describe("DecoratorUtils", function () { | ||
describe("getType()", function () { | ||
describe("constructor()", function () { | ||
it("should not be callable", function () { | ||
(function () { | ||
return new _.DecoratorUtils(); | ||
}).should["throw"]("Static class cannot be instantiated."); | ||
}); | ||
}); | ||
describe("getDeclarationType()", function () { | ||
it("should correctly detect class declarations", function () { | ||
function decorator() { | ||
(_.DecoratorUtils.getType(arguments) === _.DecoratorUtils.type.CLASS).should.be["true"](); | ||
(_.DecoratorUtils.getDeclarationType(arguments) === _.DecoratorUtils.declarationTypes.CLASS).should.be["true"](); | ||
(_.DecoratorUtils.getDeclarationType(arguments) !== _.DecoratorUtils.declarationTypes.CLASS_METHOD).should.be["true"](); | ||
(_.DecoratorUtils.getDeclarationType(arguments) !== _.DecoratorUtils.declarationTypes.CLASS_ACCESSOR).should.be["true"](); | ||
(_.DecoratorUtils.getDeclarationType(arguments) !== _.DecoratorUtils.declarationTypes.OBJECT_LITERAL_METHOD).should.be["true"](); | ||
(_.DecoratorUtils.getDeclarationType(arguments) !== _.DecoratorUtils.declarationTypes.OBJECT_LITERAL_ACCESSOR).should.be["true"](); | ||
} | ||
@@ -32,3 +44,7 @@ | ||
function decorator() { | ||
(_.DecoratorUtils.getType(arguments) === _.DecoratorUtils.type.CLASS_METHOD).should.be["true"](); | ||
(_.DecoratorUtils.getDeclarationType(arguments) !== _.DecoratorUtils.declarationTypes.CLASS).should.be["true"](); | ||
(_.DecoratorUtils.getDeclarationType(arguments) === _.DecoratorUtils.declarationTypes.CLASS_METHOD).should.be["true"](); | ||
(_.DecoratorUtils.getDeclarationType(arguments) !== _.DecoratorUtils.declarationTypes.CLASS_ACCESSOR).should.be["true"](); | ||
(_.DecoratorUtils.getDeclarationType(arguments) !== _.DecoratorUtils.declarationTypes.OBJECT_LITERAL_METHOD).should.be["true"](); | ||
(_.DecoratorUtils.getDeclarationType(arguments) !== _.DecoratorUtils.declarationTypes.OBJECT_LITERAL_ACCESSOR).should.be["true"](); | ||
} | ||
@@ -53,3 +69,7 @@ | ||
function decorator() { | ||
(_.DecoratorUtils.getType(arguments) === _.DecoratorUtils.type.CLASS_ACCESSOR).should.be["true"](); | ||
(_.DecoratorUtils.getDeclarationType(arguments) !== _.DecoratorUtils.declarationTypes.CLASS).should.be["true"](); | ||
(_.DecoratorUtils.getDeclarationType(arguments) !== _.DecoratorUtils.declarationTypes.CLASS_METHOD).should.be["true"](); | ||
(_.DecoratorUtils.getDeclarationType(arguments) === _.DecoratorUtils.declarationTypes.CLASS_ACCESSOR).should.be["true"](); | ||
(_.DecoratorUtils.getDeclarationType(arguments) !== _.DecoratorUtils.declarationTypes.OBJECT_LITERAL_METHOD).should.be["true"](); | ||
(_.DecoratorUtils.getDeclarationType(arguments) !== _.DecoratorUtils.declarationTypes.OBJECT_LITERAL_ACCESSOR).should.be["true"](); | ||
} | ||
@@ -75,3 +95,7 @@ | ||
function decorator() { | ||
(_.DecoratorUtils.getType(arguments) === _.DecoratorUtils.type.OBJECT_LITERAL_METHOD).should.be["true"](); | ||
(_.DecoratorUtils.getDeclarationType(arguments) !== _.DecoratorUtils.declarationTypes.CLASS).should.be["true"](); | ||
(_.DecoratorUtils.getDeclarationType(arguments) !== _.DecoratorUtils.declarationTypes.CLASS_METHOD).should.be["true"](); | ||
(_.DecoratorUtils.getDeclarationType(arguments) !== _.DecoratorUtils.declarationTypes.CLASS_ACCESSOR).should.be["true"](); | ||
(_.DecoratorUtils.getDeclarationType(arguments) === _.DecoratorUtils.declarationTypes.OBJECT_LITERAL_METHOD).should.be["true"](); | ||
(_.DecoratorUtils.getDeclarationType(arguments) !== _.DecoratorUtils.declarationTypes.OBJECT_LITERAL_ACCESSOR).should.be["true"](); | ||
} | ||
@@ -88,3 +112,7 @@ | ||
function decorator() { | ||
(_.DecoratorUtils.getType(arguments) === _.DecoratorUtils.type.OBJECT_LITERAL_ACCESSOR).should.be["true"](); | ||
(_.DecoratorUtils.getDeclarationType(arguments) !== _.DecoratorUtils.declarationTypes.CLASS).should.be["true"](); | ||
(_.DecoratorUtils.getDeclarationType(arguments) !== _.DecoratorUtils.declarationTypes.CLASS_METHOD).should.be["true"](); | ||
(_.DecoratorUtils.getDeclarationType(arguments) !== _.DecoratorUtils.declarationTypes.CLASS_ACCESSOR).should.be["true"](); | ||
(_.DecoratorUtils.getDeclarationType(arguments) !== _.DecoratorUtils.declarationTypes.OBJECT_LITERAL_METHOD).should.be["true"](); | ||
(_.DecoratorUtils.getDeclarationType(arguments) === _.DecoratorUtils.declarationTypes.OBJECT_LITERAL_ACCESSOR).should.be["true"](); | ||
} | ||
@@ -100,2 +128,72 @@ | ||
}); | ||
describe("createDecorator()", function () { | ||
it("should produce a decorator that can only be applied to a subset of declaration types", function () { | ||
var decorator = _.DecoratorUtils.createDecorator([_.DecoratorUtils.declarationTypes.CLASS_METHOD, _.DecoratorUtils.declarationTypes.CLASS_ACCESSOR], function () {}); | ||
decorator.should.be.a.Function(); | ||
(function () { | ||
var Thing = (function () { | ||
function Thing() { | ||
_classCallCheck(this, _Thing2); | ||
} | ||
var _Thing2 = Thing; | ||
Thing = decorator(Thing) || Thing; | ||
return Thing; | ||
})(); | ||
}).should["throw"]("Decorator must be applied to a supported declaration type."); | ||
(function () { | ||
var Thing = (function () { | ||
function Thing() { | ||
_classCallCheck(this, Thing); | ||
} | ||
_createDecoratedClass(Thing, [{ | ||
key: "hello", | ||
decorators: [decorator], | ||
value: function hello() {} | ||
}]); | ||
return Thing; | ||
})(); | ||
}).should.not["throw"]("Decorator must be applied to a supported declaration type."); | ||
(function () { | ||
var Thing = (function () { | ||
function Thing() { | ||
_classCallCheck(this, Thing); | ||
} | ||
_createDecoratedClass(Thing, [{ | ||
key: "hello", | ||
decorators: [decorator, decorator], | ||
get: function get() {}, | ||
set: function set(value) {} | ||
}]); | ||
return Thing; | ||
})(); | ||
}).should.not["throw"]("Decorator must be applied to a supported declaration type."); | ||
(function () { | ||
var thing = _createDecoratedObject([{ | ||
key: "hello", | ||
decorators: [decorator], | ||
value: function hello() {} | ||
}]); | ||
}).should["throw"]("Decorator must be applied to a supported declaration type."); | ||
(function () { | ||
var thing = _createDecoratedObject([{ | ||
key: "hello", | ||
decorators: [decorator, decorator], | ||
get: function get() {}, | ||
set: function set(value) {} | ||
}]); | ||
}).should["throw"]("Decorator must be applied to a supported declaration type."); | ||
}); | ||
}); | ||
}); |
{ | ||
"name": "decorator-utils", | ||
"version": "0.0.2", | ||
"version": "0.0.3", | ||
"description": "Utilities for ES7 decorators.", | ||
@@ -24,4 +24,4 @@ "author": "Luke Horvat", | ||
"devDependencies": { | ||
"babel": "5.6.23", | ||
"husky": "0.8.1", | ||
"babel": "5.8.5", | ||
"husky": "0.9.1", | ||
"mocha": "2.2.5", | ||
@@ -28,0 +28,0 @@ "should": "7.0.2" |
@@ -21,5 +21,9 @@ # decorator-utils [![NPM version](http://img.shields.io/npm/v/decorator-utils.svg?style=flat-square)](https://www.npmjs.org/package/decorator-utils) [![Build status](http://img.shields.io/travis/lukehorvat/decorator-utils.svg?style=flat-square)](https://travis-ci.org/lukehorvat/decorator-utils) | ||
function decorator() { | ||
if (DecoratorUtils.getType(arguments) !== DecoratorUtils.type.CLASS_METHOD) { | ||
throw new Error("Decorator target must be a class method declaration."); | ||
let declarationType = DecoratorUtils.getDeclarationType(arguments); | ||
if (declarationType !== DecoratorUtils.declarationTypes.CLASS_METHOD) { | ||
throw new Error("Decorator must be applied to a class method declaration."); | ||
} | ||
// The rest of the decorator's logic... | ||
} | ||
@@ -38,12 +42,20 @@ | ||
### getType(arguments) | ||
### getDeclarationType() | ||
- A function that can be called from within a decorator to determine the type of declaration that is being targeted. Useful for guarding a decorator against certain declaration types. | ||
- Parameters: | ||
- **arguments** - The `arguments` object the decorator function was called with. Just pass it through! | ||
- Returns one of `DecoratorUtils.type`'s values. | ||
- **arguments** - The [`arguments`](https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Functions/arguments) object of the decorator function. Just pass it through! | ||
- Returns a value from `DecoratorUtils.declarationTypes`. | ||
### type | ||
### createDecorator() | ||
- A property describing the set of possible declaration types that a decorator can target, as key-value pairs of an object (`String` -> [`Symbol`](https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Symbol)). To be used in conjunction with `DecoratorUtils.getType()`. | ||
- A function that produces a decorator that can only be applied to a subset of "supported" declaration types; all "unsupported" ones will throw an error. Handy if you want to create decorators in a factory-like manner. | ||
- Parameters: | ||
- **supportedDeclarationTypes** - An array of values from `DecoratorUtils.declarationTypes`. | ||
- **fn** - A function that contains the rest of the decorator's logic. | ||
- Returns a decorator (function). | ||
### declarationTypes | ||
- A property describing the set of possible declaration types that a decorator can target, as key-value pairs of an object (`String` -> [`Symbol`](https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Symbol)). To be used in conjunction with `DecoratorUtils.getDeclarationType()`. | ||
- Keys: | ||
@@ -50,0 +62,0 @@ - `CLASS` |
export class DecoratorUtils { | ||
static type = [ | ||
static declarationTypes = [ | ||
"CLASS", | ||
@@ -12,11 +12,11 @@ "CLASS_METHOD", | ||
static getType(args) { | ||
static getDeclarationType(args) { | ||
let [target, name, descriptor] = Array.prototype.slice.call(args); | ||
if (args.length === 1 && typeof target === "function") { | ||
return DecoratorUtils.type.CLASS; | ||
return DecoratorUtils.declarationTypes.CLASS; | ||
} else if (args.length === 3 && typeof target === "object" && typeof target.constructor === "function") { | ||
let isObjectLiteral = target.constructor.name === "Object"; | ||
let isAccessor = descriptor.get || descriptor.set; | ||
return DecoratorUtils.type[`${isObjectLiteral ? "OBJECT_LITERAL" : "CLASS"}_${isAccessor ? "ACCESSOR" : "METHOD"}`]; | ||
return DecoratorUtils.declarationTypes[`${isObjectLiteral ? "OBJECT_LITERAL" : "CLASS"}_${isAccessor ? "ACCESSOR" : "METHOD"}`]; | ||
} | ||
@@ -26,2 +26,18 @@ | ||
} | ||
static createDecorator(supportedDeclarationTypes, fn) { | ||
supportedDeclarationTypes = new Set([].concat(supportedDeclarationTypes)); | ||
return function() { | ||
if (!supportedDeclarationTypes.has(DecoratorUtils.getDeclarationType(arguments))) { | ||
throw new Error("Decorator must be applied to a supported declaration type."); | ||
} | ||
return fn.apply(this, arguments); | ||
}; | ||
} | ||
constructor() { | ||
throw new Error("Static class cannot be instantiated."); | ||
} | ||
}; |
import {DecoratorUtils} from "./"; | ||
describe("DecoratorUtils", () => { | ||
describe("getType()", () => { | ||
describe("constructor()", () => { | ||
it("should not be callable", () => { | ||
(() => new DecoratorUtils()).should.throw("Static class cannot be instantiated."); | ||
}); | ||
}); | ||
describe("getDeclarationType()", () => { | ||
it("should correctly detect class declarations", () => { | ||
function decorator() { | ||
(DecoratorUtils.getType(arguments) === DecoratorUtils.type.CLASS).should.be.true(); | ||
(DecoratorUtils.getDeclarationType(arguments) === DecoratorUtils.declarationTypes.CLASS).should.be.true(); | ||
(DecoratorUtils.getDeclarationType(arguments) !== DecoratorUtils.declarationTypes.CLASS_METHOD).should.be.true(); | ||
(DecoratorUtils.getDeclarationType(arguments) !== DecoratorUtils.declarationTypes.CLASS_ACCESSOR).should.be.true(); | ||
(DecoratorUtils.getDeclarationType(arguments) !== DecoratorUtils.declarationTypes.OBJECT_LITERAL_METHOD).should.be.true(); | ||
(DecoratorUtils.getDeclarationType(arguments) !== DecoratorUtils.declarationTypes.OBJECT_LITERAL_ACCESSOR).should.be.true(); | ||
} | ||
@@ -16,3 +26,7 @@ | ||
function decorator() { | ||
(DecoratorUtils.getType(arguments) === DecoratorUtils.type.CLASS_METHOD).should.be.true(); | ||
(DecoratorUtils.getDeclarationType(arguments) !== DecoratorUtils.declarationTypes.CLASS).should.be.true(); | ||
(DecoratorUtils.getDeclarationType(arguments) === DecoratorUtils.declarationTypes.CLASS_METHOD).should.be.true(); | ||
(DecoratorUtils.getDeclarationType(arguments) !== DecoratorUtils.declarationTypes.CLASS_ACCESSOR).should.be.true(); | ||
(DecoratorUtils.getDeclarationType(arguments) !== DecoratorUtils.declarationTypes.OBJECT_LITERAL_METHOD).should.be.true(); | ||
(DecoratorUtils.getDeclarationType(arguments) !== DecoratorUtils.declarationTypes.OBJECT_LITERAL_ACCESSOR).should.be.true(); | ||
} | ||
@@ -28,3 +42,7 @@ | ||
function decorator() { | ||
(DecoratorUtils.getType(arguments) === DecoratorUtils.type.CLASS_ACCESSOR).should.be.true(); | ||
(DecoratorUtils.getDeclarationType(arguments) !== DecoratorUtils.declarationTypes.CLASS).should.be.true(); | ||
(DecoratorUtils.getDeclarationType(arguments) !== DecoratorUtils.declarationTypes.CLASS_METHOD).should.be.true(); | ||
(DecoratorUtils.getDeclarationType(arguments) === DecoratorUtils.declarationTypes.CLASS_ACCESSOR).should.be.true(); | ||
(DecoratorUtils.getDeclarationType(arguments) !== DecoratorUtils.declarationTypes.OBJECT_LITERAL_METHOD).should.be.true(); | ||
(DecoratorUtils.getDeclarationType(arguments) !== DecoratorUtils.declarationTypes.OBJECT_LITERAL_ACCESSOR).should.be.true(); | ||
} | ||
@@ -43,3 +61,7 @@ | ||
function decorator() { | ||
(DecoratorUtils.getType(arguments) === DecoratorUtils.type.OBJECT_LITERAL_METHOD).should.be.true(); | ||
(DecoratorUtils.getDeclarationType(arguments) !== DecoratorUtils.declarationTypes.CLASS).should.be.true(); | ||
(DecoratorUtils.getDeclarationType(arguments) !== DecoratorUtils.declarationTypes.CLASS_METHOD).should.be.true(); | ||
(DecoratorUtils.getDeclarationType(arguments) !== DecoratorUtils.declarationTypes.CLASS_ACCESSOR).should.be.true(); | ||
(DecoratorUtils.getDeclarationType(arguments) === DecoratorUtils.declarationTypes.OBJECT_LITERAL_METHOD).should.be.true(); | ||
(DecoratorUtils.getDeclarationType(arguments) !== DecoratorUtils.declarationTypes.OBJECT_LITERAL_ACCESSOR).should.be.true(); | ||
} | ||
@@ -55,3 +77,7 @@ | ||
function decorator() { | ||
(DecoratorUtils.getType(arguments) === DecoratorUtils.type.OBJECT_LITERAL_ACCESSOR).should.be.true(); | ||
(DecoratorUtils.getDeclarationType(arguments) !== DecoratorUtils.declarationTypes.CLASS).should.be.true(); | ||
(DecoratorUtils.getDeclarationType(arguments) !== DecoratorUtils.declarationTypes.CLASS_METHOD).should.be.true(); | ||
(DecoratorUtils.getDeclarationType(arguments) !== DecoratorUtils.declarationTypes.CLASS_ACCESSOR).should.be.true(); | ||
(DecoratorUtils.getDeclarationType(arguments) !== DecoratorUtils.declarationTypes.OBJECT_LITERAL_METHOD).should.be.true(); | ||
(DecoratorUtils.getDeclarationType(arguments) === DecoratorUtils.declarationTypes.OBJECT_LITERAL_ACCESSOR).should.be.true(); | ||
} | ||
@@ -68,2 +94,52 @@ | ||
}); | ||
describe("createDecorator()", () => { | ||
it("should produce a decorator that can only be applied to a subset of declaration types", () => { | ||
let decorator = DecoratorUtils.createDecorator([ | ||
DecoratorUtils.declarationTypes.CLASS_METHOD, | ||
DecoratorUtils.declarationTypes.CLASS_ACCESSOR | ||
], function() {}); | ||
decorator.should.be.a.Function(); | ||
(() => { | ||
@decorator | ||
class Thing {} | ||
}).should.throw("Decorator must be applied to a supported declaration type."); | ||
(() => { | ||
class Thing { | ||
@decorator | ||
hello() {} | ||
} | ||
}).should.not.throw("Decorator must be applied to a supported declaration type."); | ||
(() => { | ||
class Thing { | ||
@decorator | ||
get hello() {} | ||
@decorator | ||
set hello(value) {} | ||
} | ||
}).should.not.throw("Decorator must be applied to a supported declaration type."); | ||
(() => { | ||
let thing = { | ||
@decorator | ||
hello() {} | ||
}; | ||
}).should.throw("Decorator must be applied to a supported declaration type."); | ||
(() => { | ||
let thing = { | ||
@decorator | ||
get hello() {}, | ||
@decorator | ||
set hello(value) {} | ||
}; | ||
}).should.throw("Decorator must be applied to a supported declaration type."); | ||
}); | ||
}); | ||
}); |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
25006
372
65