Skip to content

Commit

Permalink
refactor: symbols only when needed
Browse files Browse the repository at this point in the history
  • Loading branch information
ffMathy committed Mar 11, 2024
1 parent ac3983d commit 240682c
Show file tree
Hide file tree
Showing 23 changed files with 1,938 additions and 247 deletions.
1,553 changes: 1,548 additions & 5 deletions package-lock.json

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,6 @@
"@types/node": "^12.20.55",
"@types/sinonjs__fake-timers": "^8.1.5",
"ava": "^4.3.3",
"typescript": "^4.8.4"
"typescript": "^5.4.2"
}
}
14 changes: 7 additions & 7 deletions spec/ClearSubstitute.spec.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import test from 'ava'

import { Substitute, SubstituteOf, clearReceivedCalls, received, returns } from '../src'
import { SubstituteNode } from '../src/SubstituteNode'
import { SubstituteNode, instance } from '../src/SubstituteNode'

interface Calculator {
add(a: number, b: number): number
Expand All @@ -11,18 +11,18 @@ interface Calculator {
}

type InstanceReturningSubstitute<T> = SubstituteOf<T> & {
[SubstituteNode.instance]: SubstituteNode
[instance]: SubstituteNode
}

test('clears received calls on a substitute', t => {
const calculator = Substitute.for<Calculator>() as InstanceReturningSubstitute<Calculator>
calculator.add(1, 1)
calculator.add(1, 1)[returns](2)
calculator[clearReceivedCalls]();
calculator.add(1, 1).returns(2)
calculator.clearReceivedCalls();

t.is(calculator[SubstituteNode.instance].recorder.records.size, 2)
t.is(calculator[SubstituteNode.instance].recorder.indexedRecords.size, 2)
t.is(calculator[instance].recorder.records.size, 2)
t.is(calculator[instance].recorder.indexedRecords.size, 2)

t.throws(() => calculator[received]().add(1, 1))
t.throws(() => calculator.received().add(1, 1))
t.is(2, calculator.add(1, 1))
})
2 changes: 1 addition & 1 deletion spec/Recorder.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import { returns } from '../src'

const nodeFactory = (key: string) => {
const node = Substitute.for<SubstituteNodeBase>()
node.key[returns](key)
node.key.returns(key)
return node
}

Expand Down
34 changes: 17 additions & 17 deletions spec/regression/didNotReceive.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,41 +12,41 @@ interface Calculator {
test('not calling a method correctly asserts the call count', t => {
const calculator = Substitute.for<Calculator>()

calculator[didNotReceive]().add(1, 1)
t.throws(() => calculator[received]().add(1, 1), { instanceOf: SubstituteException })
t.throws(() => calculator[received]().add(Arg.all()), { instanceOf: SubstituteException })
calculator.didNotReceive().add(1, 1)
t.throws(() => calculator.received().add(1, 1), { instanceOf: SubstituteException })
t.throws(() => calculator.received().add(Arg.all()), { instanceOf: SubstituteException })
})

test('not getting a property correctly asserts the call count', t => {
const calculator = Substitute.for<Calculator>()

calculator[didNotReceive]().isEnabled
t.throws(() => calculator[received](1).isEnabled, { instanceOf: SubstituteException })
t.throws(() => calculator[received]().isEnabled, { instanceOf: SubstituteException })
calculator.didNotReceive().isEnabled
t.throws(() => calculator.received(1).isEnabled, { instanceOf: SubstituteException })
t.throws(() => calculator.received().isEnabled, { instanceOf: SubstituteException })
})

test('not setting a property correctly asserts the call count', t => {
const calculator = Substitute.for<Calculator>()

calculator[didNotReceive]().isEnabled = true
t.throws(() => calculator[received](1).isEnabled = true, { instanceOf: SubstituteException })
t.throws(() => calculator[received]().isEnabled = true, { instanceOf: SubstituteException })
calculator.didNotReceive().isEnabled = true
t.throws(() => calculator.received(1).isEnabled = true, { instanceOf: SubstituteException })
t.throws(() => calculator.received().isEnabled = true, { instanceOf: SubstituteException })
})

test('not calling a method with mock correctly asserts the call count', t => {
const calculator = Substitute.for<Calculator>()
calculator.add(1, 1)[returns](2)
calculator.add(1, 1).returns(2)

calculator[didNotReceive]().add(1, 1)
t.throws(() => calculator[received](1).add(1, 1), { instanceOf: SubstituteException })
t.throws(() => calculator[received]().add(Arg.all()), { instanceOf: SubstituteException })
calculator.didNotReceive().add(1, 1)
t.throws(() => calculator.received(1).add(1, 1), { instanceOf: SubstituteException })
t.throws(() => calculator.received().add(Arg.all()), { instanceOf: SubstituteException })
})

test('not getting a property with mock correctly asserts the call count', t => {
const calculator = Substitute.for<Calculator>()
calculator.isEnabled[returns](true)
calculator.isEnabled.returns(true)

calculator[didNotReceive]().isEnabled
t.throws(() => calculator[received](1).isEnabled, { instanceOf: SubstituteException })
t.throws(() => calculator[received]().isEnabled, { instanceOf: SubstituteException })
calculator.didNotReceive().isEnabled
t.throws(() => calculator.received(1).isEnabled, { instanceOf: SubstituteException })
t.throws(() => calculator.received().isEnabled, { instanceOf: SubstituteException })
})
20 changes: 10 additions & 10 deletions spec/regression/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,15 +20,15 @@ export class Example {
set v(x: string | null | undefined) {
}

received(stuff: number | string) {
received(_stuff: string) {

}

returnPromise() {
return Promise.resolve(new Dummy())
}

foo(): string | undefined | null {
foo(_arg?: string): string | undefined | null {
return 'stuff'
}

Expand All @@ -48,12 +48,12 @@ function initialize() {
const textModifierRegex = /\x1b\[\d+m/g

test('class with method called \'received\' can be used for call count verification when using symbols', t => {
initialize()
const substitute = Substitute.for<Example>()

substitute.received(2)
substitute.received("foo")

t.throws(() => substitute[received](2).received(2))
t.notThrows(() => substitute[received](1).received(2))
t.notThrows(() => substitute[received](1).received("foo"))
t.throws(() => substitute[received](2).received("foo"))
})

test('class string field set received', t => {
Expand Down Expand Up @@ -85,15 +85,15 @@ test('class string field set received', t => {
test('resolving promises works', async t => {
initialize()

substitute.returnPromise()[resolves](1338)
substitute.returnPromise().resolves(1338)

t.is(1338, await substitute.returnPromise() as number)
})

test('class void returns', t => {
initialize()

substitute.foo()[returns](void 0, null)
substitute.foo().returns(void 0, null)

t.is(substitute.foo(), void 0)
t.is(substitute.foo(), null)
Expand Down Expand Up @@ -126,7 +126,7 @@ test('class method received', t => {
test('received call matches after partial mocks using property instance mimicks', t => {
initialize()

substitute.d[mimicks](() => instance.d)
substitute.d.mimicks(() => instance.d)
substitute.c('lala', 'bar')

substitute[received](1).c('lala', 'bar')
Expand All @@ -144,7 +144,7 @@ test('received call matches after partial mocks using property instance mimicks'
test('partial mocks using property instance mimicks', t => {
initialize()

substitute.d[mimicks](() => instance.d)
substitute.d.mimicks(() => instance.d)

t.deepEqual(substitute.d, 1337)
})
4 changes: 2 additions & 2 deletions spec/regression/issues/11.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,12 @@ class RealCalculator {

test('issue 11: arg.is is only called once', async t => {
let mockedCalculator = Substitute.for<RealCalculator>()
mockedCalculator.add(Arg.any())[returns](4)
mockedCalculator.add(Arg.any()).returns(4)

let count = 0
mockedCalculator.add({ op1: 1, op2: 2 })

mockedCalculator[received](1).add(Arg.is(a => {
mockedCalculator.received(1).add(Arg.is(a => {
count++
return a.op1 === 1 && a.op2 === 2
}))
Expand Down
16 changes: 8 additions & 8 deletions spec/regression/issues/178.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,17 +24,17 @@ const throwsUncaughtException = (cb: () => any, t: ExecutionContext, expectation

test('can substitute callable interfaces', async t => {
const lib = Substitute.for<Library>()
lib.subSection()[returns]('subSection as method')
lib.subSection[returns]({ subMethod: () => 'subSection as property' } as Subsection)
lib.subSection().returns('subSection as method')
lib.subSection.returns({ subMethod: () => 'subSection as property' } as Subsection)

t.is('subSection as method', lib.subSection())
t.true(types.isProxy(lib.subSection), 'Expected proxy: given the context, it\'s not possible to determine the property type')
t.is('subSection as property', lib.subSection.subMethod())

lib[received]().subSection()
lib[received](1).subSection()
lib[received](2).subSection
t.throws(() => lib[didNotReceive]().subSection(), { instanceOf: SubstituteException })
t.throws(() => lib[received](2).subSection(), { instanceOf: SubstituteException })
throwsUncaughtException(() => lib[received](3).subSection, t, { instanceOf: SubstituteException })
lib.received().subSection()
lib.received(1).subSection()
lib.received(2).subSection
t.throws(() => lib.didNotReceive().subSection(), { instanceOf: SubstituteException })
t.throws(() => lib.received(2).subSection(), { instanceOf: SubstituteException })
throwsUncaughtException(() => lib.received(3).subSection, t, { instanceOf: SubstituteException })
})
4 changes: 2 additions & 2 deletions spec/regression/issues/23.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,12 @@ test('issue 23: mimick received should not call method', t => {

let calls = 0

mockedCalculator.add(Arg.all())[mimicks]((a, b) => {
mockedCalculator.add(Arg.all()).mimicks((a, b) => {
t.deepEqual(++calls, 1, 'mimick called twice')
return a + b
})

mockedCalculator.add(1, 1) // ok

mockedCalculator[received](1).add(1, 1) // not ok, calls mimick func
mockedCalculator.received(1).add(1, 1) // not ok, calls mimick func
})
6 changes: 3 additions & 3 deletions spec/regression/issues/36.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ class Service {

test('issue 36 - promises returning object with properties', async t => {
const emptyFetch = Substitute.for<IFetch>()
emptyFetch.getUpdates(Key.create())[returns](Promise.resolve<IData>(IData.create()))
emptyFetch.getUpdates(Key.create()).returns(Promise.resolve<IData>(IData.create()))
const result = await emptyFetch.getUpdates(Key.create())
t.true(result.serverCheck instanceof Date, 'given date is instanceof Date')
t.deepEqual(result.data, [1], 'arrays are deep equal')
Expand All @@ -58,12 +58,12 @@ test('issue 36 - promises returning object with properties', async t => {
test('using objects or classes as arguments should be able to match mock', async t => {
const db = Substitute.for<IFetch>()
const data = IData.create()
db.getUpdates(Key.create())[returns](Promise.resolve(data))
db.getUpdates(Key.create()).returns(Promise.resolve(data))
const service = new Service(db)

await service.handle(Key.create())

db[received](1).storeUpdates(Arg.is((arg: IData) =>
db.received(1).storeUpdates(Arg.is((arg: IData) =>
arg.serverCheck instanceof Date &&
arg instanceof IData &&
arg.data[0] === 100
Expand Down
4 changes: 2 additions & 2 deletions spec/regression/issues/45.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ test('issue 45 Checking received calls off at times', async t => {
subject.callToMethodTwo()

t.notThrows(() => {
mock[received](1).methodOne()
mock[received](1).methodTwo(Arg.is(x => x === 'string'))
mock.received(1).methodOne()
mock.received(1).methodTwo(Arg.is(x => x === 'string'))
})
})
6 changes: 3 additions & 3 deletions spec/regression/issues/59.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,10 @@ interface IEcho {

test('issue 59 - Mock function with optional parameters', (t) => {
const echoer = Substitute.for<IEcho>()
echoer.maybeEcho('foo')[returns]('bar')
echoer.maybeEcho()[returns]('baz')
echoer.maybeEcho('foo').returns('bar')
echoer.maybeEcho().returns('baz')

t.is('bar', echoer.maybeEcho('foo'))
echoer[received]().maybeEcho('foo')
echoer.received().maybeEcho('foo')
t.is('baz', echoer.maybeEcho())
})
18 changes: 9 additions & 9 deletions spec/regression/mimicks.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,16 +16,16 @@ test('mimicks a method with specific arguments', t => {
const calculator = Substitute.for<Calculator>()
const addMimick = (a: number, b: number) => a + b

calculator.add(1, 1)[mimicks](addMimick)
calculator.add(1, 1).mimicks(addMimick)
t.is(2, calculator.add(1, 1))
})

test('mimicks a method with specific and conditional arguments', t => {
const calculator = Substitute.for<Calculator>()
const addMimick = (a: number, b: number) => a + b

calculator.add(Arg.any('number'), Arg.is((input: number) => input >= 0 && input <= 10))[mimicks](addMimick)
calculator.add(42, -42)[mimicks]((a: number, b: number) => 0)
calculator.add(Arg.any('number'), Arg.is((input: number) => input >= 0 && input <= 10)).mimicks(addMimick)
calculator.add(42, -42).mimicks((a: number, b: number) => 0)

t.is(1240, calculator.add(1234, 6))
t.is(0, calculator.add(42, -42))
Expand All @@ -36,7 +36,7 @@ test('mimicks a method with Arg.all', t => {
const addMimick = (a: number, b: number) => a + b


calculator.add(Arg.all())[mimicks](addMimick)
calculator.add(Arg.all()).mimicks(addMimick)
t.is(100, calculator.add(42, 58))
})

Expand All @@ -45,9 +45,9 @@ test('mimicks a method with optional arguments', t => {
const multiplyOneArgMimicks = (a: number) => a * a
const multiplyMimicks = (a: number, b?: number) => a * (b ?? 0)

calculator.multiply(0, Arg.is((b: number) => b > 10 && b < 20))[mimicks](multiplyMimicks)
calculator.multiply(Arg.any('number'), Arg.is((b: number) => b === 2))[mimicks](multiplyMimicks)
calculator.multiply(2)[mimicks](multiplyOneArgMimicks)
calculator.multiply(0, Arg.is((b: number) => b > 10 && b < 20)).mimicks(multiplyMimicks)
calculator.multiply(Arg.any('number'), Arg.is((b: number) => b === 2)).mimicks(multiplyMimicks)
calculator.multiply(2).mimicks(multiplyOneArgMimicks)

t.is(0, calculator.multiply(0, 13))
t.is(84, calculator.multiply(42, 2))
Expand All @@ -57,8 +57,8 @@ test('mimicks a method with optional arguments', t => {
test('mimicks a method where it\'s only argument is optional', t => {
const calculator = Substitute.for<Calculator>()

calculator.viewResult()[mimicks](() => 0)
calculator.viewResult(3)[mimicks](() => 42)
calculator.viewResult().mimicks(() => 0)
calculator.viewResult(3).mimicks(() => 42)

t.is(0, calculator.viewResult())
t.is(42, calculator.viewResult(3))
Expand Down
Loading

0 comments on commit 240682c

Please sign in to comment.