UNPKG

typemoq

Version:

A simple mocking library for TypeScript

255 lines (197 loc) 7.21 kB
import * as _ from "lodash"; import * as common from "../Common/_all"; import { ICallContext, CallType, ProxyType } from "./ICallContext"; export enum InvocationType { NONE, SETUP, EXECUTE } export abstract class BaseInvocation implements ICallContext { returnValue: any; invocationType = InvocationType.NONE; constructor(public readonly proxyType: ProxyType, public callType: CallType) { } abstract get args(): IArguments; abstract set args(value: IArguments); abstract get property(): IPropertyInfo; abstract invokeBase(): void; get isAnUnknownDynamicCallAtExecution(): boolean { return this.proxyType == ProxyType.DYNAMIC && this.callType == CallType.UNKNOWN && this.invocationType == InvocationType.EXECUTE; }; } export class MethodInvocation extends BaseInvocation { private _args: IArguments; constructor( private readonly _that: Object, private readonly _property: MethodInfo, args?: IArguments, proxyType = ProxyType.STATIC, callType = CallType.FUNCTION) { super(proxyType, callType); if (args) { this._args = <any>_.cloneDeep(args); this._args.length = args.length; this._args.callee = args.callee; } } get args(): IArguments { return this._args || <any>{ length: 0, callee: null }; } set args(value: IArguments) { this._args = value; } get property(): IPropertyInfo { return this._property; } invokeBase(): void { let thatClone = {}; if (this._that) common.Utils.clone(thatClone, this._that); else thatClone = this._property.obj; this.returnValue = this._property.toFunc.apply(thatClone, this._args); } toString(): string { const res = `${this.property}(${common.Utils.argsName(this.args)})`; return res; } } export class ValueGetterInvocation extends BaseInvocation { constructor( private readonly _property: IPropertyInfo, readonly value: any, proxyType = ProxyType.STATIC, callType = CallType.PROPERTY) { super(proxyType, callType); this.returnValue = _.cloneDeep(value); } get args(): IArguments { let args: any[] = []; Object.defineProperty(args, "callee", { configurable: true, enumerable: true, writable: false, value: null }); return <any>args; } set args(value: IArguments) { } get property(): IPropertyInfo { return this._property; } invokeBase(): void { this.returnValue = (<any>this._property.obj)[this._property.name]; } toString(): string { const res = `${this.property}`; return res; } } export class DynamicGetInvocation extends ValueGetterInvocation { constructor( property: IPropertyInfo, value: any) { super(property, value, ProxyType.DYNAMIC, CallType.UNKNOWN); this.returnValue = _.cloneDeep(value); } } export class ValueSetterInvocation extends BaseInvocation { private _args: IArguments; constructor( private readonly _property: IPropertyInfo, args: IArguments, proxyType = ProxyType.STATIC, callType = CallType.PROPERTY) { super(proxyType, callType); this._args = <any>_.cloneDeep(args); this._args.length = args.length; this._args.callee = args.callee; } get args(): IArguments { return this._args; } set args(value: IArguments) { this._args = value; } get property(): IPropertyInfo { return this._property; } invokeBase(): void { (<any>this._property.obj)[this._property.name] = this._args[0]; this.returnValue = (<any>this._property.obj)[this._property.name]; } toString(): string { const res = `${this.property} = ${common.Utils.argsName(this.args[0])}`; return res; } } export class MethodGetterInvocation extends BaseInvocation { constructor( private readonly _property: IPropertyInfo, private readonly _getter: () => any, proxyType = ProxyType.STATIC, callType = CallType.FUNCTION) { super(proxyType, callType); } get args(): IArguments { let args: any[] = []; Object.defineProperty(args, "callee", { configurable: true, enumerable: true, writable: false, value: null }); return <any>args; } set args(value: IArguments) { } get property(): IPropertyInfo { return this._property; } invokeBase(): void { this.returnValue = (<any>this._property.obj)[this._property.name]; } toString(): string { const res = `${this.property}`; return res; } } export class MethodSetterInvocation extends BaseInvocation { private _args: IArguments; constructor( private readonly _property: IPropertyInfo, private readonly _setter: (v: any) => void, args: IArguments, proxyType = ProxyType.STATIC, callType = CallType.FUNCTION) { super(proxyType, callType); this._args = <any>_.cloneDeep(args); this._args.length = args.length; this._args.callee = args.callee; } get args(): IArguments { return this._args; } set args(value: IArguments) { this._args = value; } get property(): IPropertyInfo { return this._property; } invokeBase(): void { (<any>this._property.obj)[this._property.name] = this._args[0]; this.returnValue = (<any>this._property.obj)[this._property.name]; } toString(): string { const res = `${this.property}(${common.Utils.argsName(this.args[0])})`; return res; } } export class MethodInfo implements IPropertyInfo { readonly desc: common.PropDescriptor; constructor( public readonly obj: any, public readonly name: string, desc?: common.PropDescriptor) { if (desc) this.desc = _.cloneDeep(desc); } get toFunc(): Function { const func = _.isFunction(this.obj) ? <Function>this.obj : <Function>this.obj[this.name]; return func; } toString(): string { const objName = common.Utils.objectName(this.obj); const res = _.isFunction(this.obj) ? `${objName}` : `${objName}.${this.name}`; return res; } } export class PropertyInfo implements IPropertyInfo { readonly desc: common.PropDescriptor; constructor( public readonly obj: Object, public readonly name: string, desc?: common.PropDescriptor) { if (desc) this.desc = _.cloneDeep(desc); } toString(): string { const objName = common.Utils.objectName(this.obj); const res = `${objName}.${this.name}`; return res; } } export interface IPropertyInfo { obj: Object; name: string; desc?: common.PropDescriptor; }