Skip to content

Commit de52c77

Browse files
replace context with contextNode
1 parent c2322c2 commit de52c77

File tree

3 files changed

+123
-129
lines changed

3 files changed

+123
-129
lines changed

src/Context.ts

Lines changed: 0 additions & 128 deletions
This file was deleted.

src/ContextNode.ts

Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
1+
import { Substitute } from './Substitute'
2+
import { PropertyType, isSubstituteMethod } from './Utilities'
3+
import { SubstituteJS as SubstituteBase, SubstituteException } from './SubstituteBase'
4+
import { RecordedArguments } from './RecordedArguments'
5+
6+
import { Node } from './linked-list/Node'
7+
8+
export class ContextNode extends Node<Substitute, ContextNode> {
9+
private _property: PropertyKey
10+
private _propertyType: PropertyType = PropertyType.property
11+
private _arguments: RecordedArguments = RecordedArguments.noArguments()
12+
13+
private _hasSubstitution: boolean = false
14+
private _isSubstitution: boolean = false
15+
16+
private _proxy: typeof SubstituteBase
17+
18+
constructor(property: PropertyKey) {
19+
super()
20+
21+
this._property = property
22+
const nodeProxy: typeof SubstituteBase = new Proxy(SubstituteBase, {
23+
apply: (_target, _this, rawArguments?: any[]) => {
24+
this.handleMethod(rawArguments)
25+
return this.returnProxyOrSubstitution()
26+
},
27+
getPrototypeOf() {
28+
return SubstituteBase.prototype
29+
},
30+
// set: (_target, property, value) => (this.initialState.set(this, property, value), true),
31+
get: (_target, property: PropertyKey) => {
32+
if (property === 'prototype') Reflect.get(_target, property)
33+
34+
const newNode = this.createNewNode(property)
35+
this.child = newNode
36+
37+
return newNode.proxy
38+
}
39+
})
40+
41+
this._proxy = nodeProxy
42+
}
43+
44+
public labelAsSubstitution(): void {
45+
this._isSubstitution = true
46+
}
47+
48+
get isSubstitution(): boolean {
49+
return this._isSubstitution
50+
}
51+
52+
public enableSubstitution(): void {
53+
this._hasSubstitution = true
54+
}
55+
56+
get hasSubstitution(): boolean {
57+
return this._hasSubstitution
58+
}
59+
60+
get property() {
61+
return this._property
62+
}
63+
64+
get propertyType() {
65+
return this._propertyType
66+
}
67+
68+
get proxy() {
69+
return this._proxy
70+
}
71+
72+
get arguments() {
73+
return this._arguments
74+
}
75+
76+
public returnProxyOrSubstitution() {
77+
const allSubstitutions = this.findAllSubstitutions()
78+
const mostSuitableSubstitution = this.getMostSuitableSubstitution(allSubstitutions)
79+
80+
return mostSuitableSubstitution instanceof ContextNode ?
81+
mostSuitableSubstitution.executeSubstitution() :
82+
this.proxy
83+
}
84+
85+
public executeSubstitution() {
86+
return this.child.arguments.value[0] // Todo: support all substitutions, and multiple mockvalues
87+
}
88+
89+
private createNewNode(property: PropertyKey): ContextNode {
90+
const newNode = new ContextNode(property)
91+
newNode.parent = this
92+
newNode.head = this.head
93+
94+
return newNode
95+
}
96+
97+
private handleMethod(rawArguments: any[]): void {
98+
this._propertyType = PropertyType.method
99+
this._arguments = RecordedArguments.from(rawArguments)
100+
101+
if (isSubstituteMethod(this.property)) {
102+
this.labelAsSubstitution()
103+
if (this.isIntermediateNode()) this.parent.enableSubstitution()
104+
}
105+
}
106+
107+
private findAllSubstitutions(): ContextNode[] {
108+
const firstNode = this.head
109+
const root = firstNode.parent
110+
111+
const allSiblings = root.getSiblingsOf(firstNode)
112+
return allSiblings.filter(node => node.hasSubstitution &&
113+
node.propertyType === this.propertyType &&
114+
node.arguments.match(this.arguments)
115+
)
116+
}
117+
118+
private getMostSuitableSubstitution(nodes: ContextNode[]): ContextNode {
119+
const sortedNodes = RecordedArguments.sort(nodes)
120+
return sortedNodes[0]
121+
}
122+
}

src/Substitute.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { ContextNode } from './Context'
1+
import { ContextNode } from './ContextNode'
22
import { Graph } from './linked-list/Graph'
33
import { ObjectSubstitute, OmitProxyMethods } from './Transformations'
44

0 commit comments

Comments
 (0)