hermione-gemini-migrator
Version:
Plugin for hermione for migration gemini tests.
80 lines (58 loc) • 2.35 kB
JavaScript
const _ = require('lodash');
const DeepProxy = require('proxy-deep');
const EventEmitter = require('events');
const events = {
BEFORE_GET: 'before-get',
AFTER_GET: 'after-get',
BEFORE_APPLY: 'before-apply',
AFTER_APPLY: 'after-apply'
};
module.exports = (proxyTarget, proxyCallback, geminiAPI) => {
const proxyEmitter = new EventEmitter();
proxyEmitter.events = events;
const proxy = new DeepProxy(proxyTarget, {
get(target, key, receiver) {
const desc = Object.getOwnPropertyDescriptor(target, key);
const value = Reflect.get(target, key, receiver);
if ((desc && !desc.writable && !desc.configurable)) {
return value;
}
if ((_.isArray(value) || _.isFunction(value) || _.isObject(value)) && !_.isNull(value) && _.isString(key)) {
const emmiterArgList = [target, key];
let ctx = {};
proxyEmitter.emit(proxyEmitter.events.BEFORE_GET, this, emmiterArgList, ctx);
ctx.result = proxyValue.bind(this)(value);
proxyEmitter.emit(proxyEmitter.events.AFTER_GET, this, emmiterArgList, ctx);
return ctx.result;
}
return value;
},
apply(target, thisArg, argList) {
const emmiterArgList = [target, thisArg, argList];
const proxyArgList = argList.map(proxyValue.bind(this));
let ctx = {};
proxyEmitter.emit(proxyEmitter.events.BEFORE_APPLY, this, emmiterArgList, ctx);
if (!ctx.skip) {
ctx.result = Reflect.apply(target, thisArg, proxyArgList);
} else {
ctx.skip = false;
}
proxyEmitter.emit(proxyEmitter.events.AFTER_APPLY, this, emmiterArgList, ctx);
return ctx.result;
}
});
proxyCallback(proxyEmitter, geminiAPI);
return proxy;
};
function proxyValue(value) {
if ((_.isFunction(value) || _.isObject(value)) && !_.isRegExp(value) && !_.isNull(value)) {
if (value.name === 'call' || value.name === 'toString' || value.name === 'valueOf') {
return value;
}
return this.nest(value);
}
if (_.isArray(value)) {
return value.map(proxyValue.bind(this));
}
return value;
};