forked from ffMathy/FluffySpoon.JavaScript.Testing.Faking
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathContext.ts
More file actions
128 lines (108 loc) · 4.8 KB
/
Copy pathContext.ts
File metadata and controls
128 lines (108 loc) · 4.8 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
import { inspect } from 'util'
import { ContextState } from './states/ContextState';
import { InitialState } from './states/InitialState';
import { HandlerKey } from './Substitute';
import { PropertyType } from './Utilities';
import { SetPropertyState } from './states/SetPropertyState';
import { SubstituteJS as SubstituteBase, SubstituteException } from './SubstituteBase'
export class Context {
private _initialState: InitialState;
private _proxy: any;
private _rootProxy: any;
private _receivedProxy: any;
private _getState: ContextState;
private _setState: ContextState;
private _receivedState: ContextState;
constructor() {
this._initialState = new InitialState();
this._setState = this._initialState;
this._getState = this._initialState;
this._proxy = new Proxy(SubstituteBase, {
apply: (_target, _this, args) => this.getStateApply(_target, _this, args),
set: (_target, property, value) => (this.setStateSet(_target, property, value), true),
get: (_target, property) => this._filterAndReturnProperty(_target, property, this.getStateGet)
});
this._rootProxy = new Proxy(SubstituteBase, {
apply: (_target, _this, args) => this.initialState.apply(this, args),
set: (_target, property, value) => (this.initialState.set(this, property, value), true),
get: (_target, property) => this._filterAndReturnProperty(_target, property, this.rootGet)
});
this._receivedProxy = new Proxy(SubstituteBase, {
apply: (_target, _this, args) => this._receivedState === void 0 ? void 0 : this._receivedState.apply(this, args),
set: (_target, property, value) => (this.setStateSet(_target, property, value), true),
get: (_target, property) => {
const state = this.initialState.getPropertyStates.find(getPropertyState => getPropertyState.property === property);
if (state === void 0) return this.handleNotFoundState(property);
if (!state.isFunctionState)
state.get(this, property);
this._receivedState = state;
return this.receivedProxy;
}
});
}
private _filterAndReturnProperty(target: typeof SubstituteBase, property: PropertyKey, getToExecute: ContextState['get']) {
switch (property) {
case 'constructor':
case 'valueOf':
case '$$typeof':
case 'length':
case 'toString':
case 'inspect':
case 'lastRegisteredSubstituteJSMethodOrProperty':
return target.prototype[property];
case Symbol.toPrimitive:
return target.prototype[Symbol.toPrimitive];
case inspect.custom:
return target.prototype[inspect.custom];
case Symbol.iterator:
return target.prototype[Symbol.iterator];
case Symbol.toStringTag:
return target.prototype[Symbol.toStringTag];
default:
target.prototype.lastRegisteredSubstituteJSMethodOrProperty = property.toString()
return getToExecute.bind(this)(target as any, property);
}
}
private handleNotFoundState(property: PropertyKey) {
if (this.initialState.hasExpectations && this.initialState.expectedCount !== null) {
this.initialState.assertCallCountMatchesExpectations([], 0, PropertyType.property, property, []);
return this.receivedProxy;
}
throw SubstituteException.forPropertyNotMocked(property);
}
rootGet(_target: any, property: PropertyKey) {
return this.initialState.get(this, property);
}
getStateApply(_target: any, _this: any, args: any[]) {
return this._getState.apply(this, args);
}
setStateSet(_target: any, property: PropertyKey, value: any) {
return this._setState.set(this, property, value);
}
getStateGet(_target: any, property: PropertyKey) {
if (property === HandlerKey) {
return this;
}
return this._getState.get(this, property);
}
public get proxy() {
return this._proxy;
}
public get rootProxy() {
return this._rootProxy;
}
public get receivedProxy() {
return this._receivedProxy;
}
public get initialState() {
return this._initialState;
}
public set state(state: ContextState) {
if (this._setState === state)
return;
state instanceof SetPropertyState ?
this._setState = state : this._getState = state
if (state.onSwitchedTo)
state.onSwitchedTo(this);
}
}