UNPKG

@johanblumenberg/ts-mockito

Version:
283 lines 12.8 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.Mocker = exports.MockPropertyPolicy = void 0; var _ = require("lodash"); var Matcher_1 = require("./matcher/type/Matcher"); var MethodAction_1 = require("./MethodAction"); var MethodStubCollection_1 = require("./MethodStubCollection"); var MethodToStub_1 = require("./MethodToStub"); var ReturnValueMethodStub_1 = require("./stub/ReturnValueMethodStub"); var ts_mockito_1 = require("./ts-mockito"); var MockableFunctionsFinder_1 = require("./utils/MockableFunctionsFinder"); var ObjectInspector_1 = require("./utils/ObjectInspector"); var ObjectPropertyCodeRetriever_1 = require("./utils/ObjectPropertyCodeRetriever"); var MethodCallToStringConverter_1 = require("./utils/MethodCallToStringConverter"); var MockPropertyPolicy; (function (MockPropertyPolicy) { MockPropertyPolicy[MockPropertyPolicy["StubAsProperty"] = 0] = "StubAsProperty"; MockPropertyPolicy[MockPropertyPolicy["StubAsMethod"] = 1] = "StubAsMethod"; MockPropertyPolicy[MockPropertyPolicy["Throw"] = 2] = "Throw"; })(MockPropertyPolicy = exports.MockPropertyPolicy || (exports.MockPropertyPolicy = {})); var Mocker = (function () { function Mocker(clazz, options, instance) { if (instance === void 0) { instance = {}; } var _a, _b; this.clazz = clazz; this.instance = instance; this.objectInspector = new ObjectInspector_1.ObjectInspector(); this.methodStubCollections = {}; this.methodActions = []; this.mock = {}; this.mockableFunctionsFinder = new MockableFunctionsFinder_1.MockableFunctionsFinder(); this.objectPropertyCodeRetriever = new ObjectPropertyCodeRetriever_1.ObjectPropertyCodeRetriever(); this.excludedPropertyNames = ["hasOwnProperty"]; this.mock.__policy = (_a = options.propertyPolicy) !== null && _a !== void 0 ? _a : MockPropertyPolicy.StubAsMethod; this.mock.__logInvocations = (_b = options.logInvocations) !== null && _b !== void 0 ? _b : false; this.mock.__tsmockitoInstance = this.instance; this.mock.__tsmockitoMocker = this; if (_.isObject(this.clazz) && _.isObject(this.instance)) { this.processProperties(this.clazz.prototype); if (typeof Proxy === "undefined") { this.processClassCode(this.clazz); this.processFunctionsCode(this.clazz.prototype); } } if (typeof Proxy !== "undefined") { this.mock.__tsmockitoInstance = new Proxy(this.instance, this.createCatchAllHandlerForRemainingPropertiesWithoutGetters("instance")); } } Mocker.prototype.getMock = function () { if (typeof Proxy === "undefined") { return this.mock; } return new Proxy(this.mock, this.createCatchAllHandlerForRemainingPropertiesWithoutGetters("expectation")); }; Mocker.prototype.createCatchAllHandlerForRemainingPropertiesWithoutGetters = function (origin) { var _this = this; return { get: function (target, name) { var hasMethodStub = name in target; if (!hasMethodStub) { if (origin === "instance") { if (_this.mock.__policy === MockPropertyPolicy.StubAsMethod) { if (name !== "then") { _this.createMethodStub(name.toString()); _this.createInstanceActionListener(name.toString(), {}); } } else if (_this.mock.__policy === MockPropertyPolicy.StubAsProperty) { _this.createPropertyStub(name.toString()); _this.createInstancePropertyDescriptorListener(name.toString(), {}, _this.clazz.prototype); } else if (_this.mock.__policy === MockPropertyPolicy.Throw) { throw new Error("Trying to read property " + name.toString() + " from a mock object, which was not expected."); } else { throw new Error("Invalid MockPolicy value"); } } else if (origin === "expectation") { _this.createMixedStub(name.toString()); } } return target[name]; }, }; }; Mocker.prototype.reset = function () { this.methodStubCollections = {}; this.methodActions = []; }; Mocker.prototype.resetStubs = function () { this.methodStubCollections = {}; }; Mocker.prototype.resetCalls = function () { this.methodActions = []; }; Mocker.prototype.getAllMatchingActions = function (methodName, matchers) { var result = []; this.methodActions.forEach(function (item) { if (item.isApplicable(methodName, matchers)) { result.push(item); } }); return result; }; Mocker.prototype.getFirstMatchingAction = function (methodName, matchers) { return this.getAllMatchingActions(methodName, matchers)[0]; }; Mocker.prototype.getActionsByName = function (name) { return this.methodActions.filter(function (action) { return action.methodName === name; }); }; Mocker.prototype.processProperties = function (object) { var _this = this; this.objectInspector.getObjectPrototypes(object).forEach(function (obj) { _this.objectInspector.getObjectOwnPropertyNames(obj).forEach(function (name) { if (_this.excludedPropertyNames.indexOf(name) >= 0) { return; } var descriptor = Object.getOwnPropertyDescriptor(obj, name); if (descriptor.get) { _this.createPropertyStub(name); _this.createInstancePropertyDescriptorListener(name, descriptor, obj); } else if (typeof descriptor.value === "function") { _this.createMethodStub(name); _this.createInstanceActionListener(name, obj); } else { } }); }); }; Mocker.prototype.createInstancePropertyDescriptorListener = function (key, descriptor, prototype) { if (this.instance.hasOwnProperty(key)) { return; } Object.defineProperty(this.instance, key, { enumerable: true, get: this.createActionListener(key), }); }; Mocker.prototype.createInstanceActionListener = function (key, prototype) { var _this = this; if (this.instance.hasOwnProperty(key)) { return; } Object.defineProperty(this.instance, key, { enumerable: false, get: function () { return _this.createActionListener(key); }, }); }; Mocker.prototype.createActionListener = function (key) { var _this = this; var actionListener = function (thisArg, args) { var action = new MethodAction_1.MethodAction(key, args); _this.methodActions.push(action); if (_this.mock.__logInvocations) { console.log("call: " + MethodCallToStringConverter_1.MethodCallToStringConverter.convertActualCalls([action])[0]); } var methodStub = _this.getMethodStub(key, args); methodStub.execute(args, thisArg); return methodStub.getValue(); }; return function () { return actionListener(this, Array.from(arguments)); }; }; Mocker.prototype.getEmptyMethodStub = function (key, args) { return new ReturnValueMethodStub_1.ReturnValueMethodStub(-1, [], null); }; Mocker.prototype.processClassCode = function (clazz) { var _this = this; var classCode = typeof clazz.toString !== "undefined" ? clazz.toString() : ""; var functionNames = this.mockableFunctionsFinder.find(classCode); functionNames.forEach(function (functionName) { _this.createMethodStub(functionName); _this.createInstanceActionListener(functionName, _this.clazz.prototype); }); }; Mocker.prototype.processFunctionsCode = function (object) { var _this = this; this.objectInspector.getObjectPrototypes(object).forEach(function (obj) { _this.objectInspector.getObjectOwnPropertyNames(obj).forEach(function (propertyName) { var functionNames = _this.mockableFunctionsFinder.find(_this.objectPropertyCodeRetriever.get(obj, propertyName)); functionNames.forEach(function (functionName) { _this.createMethodStub(functionName); _this.createInstanceActionListener(functionName, _this.clazz.prototype); }); }); }); }; Mocker.prototype.createMixedStub = function (key) { var _this = this; if (this.mock.hasOwnProperty(key)) { return; } var isProperty = true; Object.defineProperty(this.instance, key, { enumerable: true, configurable: true, get: function () { return _this.createActionListener(key)(); }, set: function (value) { return value; }, }); var propertyMock = function () { if (!_this.methodStubCollections[key]) { _this.methodStubCollections[key] = new MethodStubCollection_1.MethodStubCollection(); } var methodToMock = new MethodToStub_1.MethodToStub(_this.methodStubCollections[key], [], _this, key); var methodMock = function () { var args = []; for (var _i = 0; _i < arguments.length; _i++) { args[_i] = arguments[_i]; } if (isProperty) { isProperty = false; Object.defineProperty(_this.instance, key, { enumerable: _this.mock.__policy === MockPropertyPolicy.StubAsProperty, get: function () { return _this.createActionListener(key); }, }); } methodToMock.matchers = args.map(function (arg) { return Matcher_1.Matcher.is(arg) ? arg : ts_mockito_1.strictEqual(arg); }); return methodToMock; }; return Object.assign(methodMock, methodToMock); }; Object.defineProperty(this.mock, key, { get: propertyMock, }); }; Mocker.prototype.createPropertyStub = function (key) { if (this.mock.hasOwnProperty(key)) { return; } Object.defineProperty(this.mock, key, { get: this.createMethodToStub(key), }); }; Mocker.prototype.createMethodStub = function (key) { if (this.mock.hasOwnProperty(key)) { return; } this.mock[key] = this.createMethodToStub(key); }; Mocker.prototype.createMethodToStub = function (key) { var _this = this; return function () { var args = []; for (var _i = 0; _i < arguments.length; _i++) { args[_i] = arguments[_i]; } if (!_this.methodStubCollections[key]) { _this.methodStubCollections[key] = new MethodStubCollection_1.MethodStubCollection(); } var matchers = []; for (var _a = 0, args_1 = args; _a < args_1.length; _a++) { var arg = args_1[_a]; if (!Matcher_1.Matcher.is(arg)) { matchers.push(ts_mockito_1.strictEqual(arg)); } else { matchers.push(arg); } } return new MethodToStub_1.MethodToStub(_this.methodStubCollections[key], matchers, _this, key); }; }; Mocker.prototype.getMethodStub = function (key, args) { var methodStub = this.methodStubCollections[key]; if (methodStub && methodStub.hasMatchingInAnyGroup(args)) { var groupIndex = methodStub.getLastMatchingGroupIndex(args); return methodStub.getFirstMatchingFromGroupAndRemoveIfNotLast(groupIndex, args); } else { return this.getEmptyMethodStub(key, args); } }; Mocker.prototype.proceed = function (methodName, args) { return undefined; }; return Mocker; }()); exports.Mocker = Mocker; //# sourceMappingURL=Mock.js.map