Skip to content

Commit

Permalink
New: adds getters and setters support
Browse files Browse the repository at this point in the history
  • Loading branch information
pustovitDmytro committed Oct 29, 2019
1 parent 380691f commit 2c0de2a
Show file tree
Hide file tree
Showing 5 changed files with 102 additions and 25 deletions.
7 changes: 6 additions & 1 deletion .babelrc
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,12 @@
"legacy": true
}
],
"@babel/plugin-proposal-class-properties",
[
"@babel/plugin-proposal-class-properties",
{
"loose": true
}
],
"@babel/plugin-proposal-optional-chaining"
],
"ignore": [
Expand Down
45 changes: 32 additions & 13 deletions src/decorators/class.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,27 +17,45 @@ function getMethodDescriptor(propertyName, target) {
}

export function classMethodDecorator({ target, methodName, descriptor }, config = {}) {
descriptor.value = functionDecorator.call( // eslint-disable-line no-param-reassign
this,
descriptor.value,
{
...config,
methodName,
serviceName : config.serviceName || target.constructor.name
}
);
const methods = [ 'value', 'initializer' ];

if (config.getters) methods.push('get');
if (config.setters) methods.push('set');
const functionDecoratorConfig = {
...config,
methodName,
serviceName : config.serviceName || target.constructor.name
};

methods
.filter(key => descriptor[key] && isFunction(descriptor[key]))
.forEach(key => {
const old = descriptor[key];

descriptor[key] = key === 'initializer'// eslint-disable-line no-param-reassign
? function () {
return functionDecorator(
old.call(target),
functionDecoratorConfig
);
}
: functionDecorator(
descriptor[key],
functionDecoratorConfig
);
});

return descriptor;
}

export default function getClassLoggerDecorator(target, config = {}) {
getMethodNames(target.prototype)
.filter(methodName => {
if (config.include && config.include.includes(methodName)) {
if (config.include?.includes(methodName)) {
return true;
}

if (config.exclude && config.exclude.includes(methodName)) {
if (config.exclude?.includes(methodName)) {
return false;
}

Expand All @@ -48,11 +66,12 @@ export default function getClassLoggerDecorator(target, config = {}) {
.forEach(methodName => {
const descriptor = getMethodDescriptor(methodName, target);

if (!descriptor) return;

Object.defineProperty(
target.prototype,
methodName,
classMethodDecorator.call(
this,
classMethodDecorator(
{ target, methodName, descriptor },
{ serviceName: target.name, ...config }
)
Expand Down
6 changes: 2 additions & 4 deletions src/decorators/function.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@

import defaults from '../defaults';
import {
isPromise,
isFunction,
Expand Down Expand Up @@ -27,14 +26,13 @@ export default function functionDecorator(method, config = {}) {
errorLevel
} = {
methodName : method.name,
...defaults,
...this,
...config
};

const basicLogObject = {
service : config.serviceName,
method : methodName,
application : this.name,
application : config.name,
level
};

Expand Down
17 changes: 10 additions & 7 deletions src/index.js
Original file line number Diff line number Diff line change
@@ -1,26 +1,29 @@
import { isClass, isFunction } from './utils';
import { isClass, isFunction, mergeConfigs } from './utils';
import {
functionDecorator,
classMethodDecorator,
classDecorator
} from './decorators';
import defaultConfig from './defaults';

const dfc = [ defaultConfig ];
// TODO change from log(opts)(func) to log(func, opts)

export class Decorator {
constructor(opts = {}) {
constructor(...opts) {
return (...args) => {
return (target, methodName, descriptor) => {
if (methodName && descriptor) {
return classMethodDecorator.call(
opts,
return classMethodDecorator(
{ target, methodName, descriptor },
...args
...mergeConfigs(args, opts, dfc)
);
}
if (isClass(target)) {
return classDecorator.call(opts, target, ...args);
return classDecorator(target, ...mergeConfigs(args, opts, dfc));
}
if (isFunction(target)) {
return functionDecorator.call(opts, target, ...args);
return functionDecorator(target, ...mergeConfigs(args, opts, dfc));
}
throw new Error(`Can't decorate ${typeof target}, only functions, classes and class methods are allowed`);
};
Expand Down
52 changes: 52 additions & 0 deletions tests/package/classes.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -116,3 +116,55 @@ test('include/exlude methods', function () {
assert.equal(calculator.addOne(15), 16);
verifyStdout(logger, [ { method: '_sum', params: '[ 15, 1 ]', result: '16' } ], { level: 'info', single: false });
});

test('Class with getters and setters', function () {
const logger = new Logger();
const decorator = new Decorator({ logger });
const verbose = decorator({ level: 'verbose', getters: true });

@verbose
class Calculator {
get one() {
return 1;
}
two = 2
addOne = a => {
return this._sum(a, this.one);
}
_sum(a, b) {
return a + b;
}
}
const calculator = new Calculator();
const res = calculator.addOne(13);

assert.equal(res, 14);
verifyStdout(logger, { params: '[]', result: '1', method: 'one' }, { level: 'verbose' });
});


// test('Class with getters and setters', function () {
// const logger = new Logger();
// const decorator = new Decorator({ logger });
// const verbose = decorator({ level: 'verbose' });

// decorator({ level: 'info', getters: false });
// class Calculator {
// get one() {
// return 1;
// }
// two = 2
// @verbose
// addOne = a => {
// return this._sum(a, this.one);
// }
// _sum(a, b) {
// return a + b;
// }
// }
// const calculator = new Calculator();
// const res = calculator.addOne(13);

// assert.equal(res, 14);
// verifyStdout(logger, { params: '[ 13 ]', result: '14', method: 'addOne' }, { level: 'verbose' });
// });

0 comments on commit 2c0de2a

Please sign in to comment.