Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor: 2.0 readiness #280

Draft
wants to merge 9 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 8 additions & 8 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

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"
}
}
48 changes: 6 additions & 42 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 } from '../src'
import { SubstituteNode } from '../src/SubstituteNode'
import { Substitute, SubstituteOf, clearReceivedCalls, received, returns } from '../src'
import { SubstituteNode, instance } from '../src/SubstituteNode'

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

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

test('clears everything on a substitute', t => {
const calculator = Substitute.for<Calculator>() as InstanceReturningSubstitute<Calculator>
calculator.add(1, 1)
calculator.received().add(1, 1)
calculator.clearSubstitute()

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

t.throws(() => calculator.received().add(1, 1))

// explicitly using 'all'
calculator.add(1, 1)
calculator.received().add(1, 1)
calculator.clearSubstitute('all')

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

t.throws(() => calculator.received().add(1, 1))
})

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.clearSubstitute('receivedCalls')
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.is(2, calculator.add(1, 1))
})

test('clears return values on a substitute', t => {
const calculator = Substitute.for<Calculator>() as InstanceReturningSubstitute<Calculator>
calculator.add(1, 1)
calculator.add(1, 1).returns(2)
calculator.clearSubstitute('substituteValues')

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

t.notThrows(() => calculator.received().add(1, 1))
// @ts-expect-error
t.true(calculator.add(1, 1)[SubstituteNode.instance] instanceof SubstituteNode)
})
1 change: 1 addition & 0 deletions spec/Recorder.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { Recorder } from '../src/Recorder'
import { RecordsSet } from '../src/RecordsSet'
import { Substitute } from '../src/Substitute'
import { SubstituteNodeBase } from '../src/SubstituteNodeBase'
import { returns } from '../src'

const nodeFactory = (key: string) => {
const node = Substitute.for<SubstituteNodeBase>()
Expand Down
4 changes: 2 additions & 2 deletions spec/regression/didNotReceive.spec.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import test from 'ava'
import { Substitute, Arg } from '../../src'
import { Substitute, Arg, didNotReceive, received, returns } from '../../src'
import { SubstituteException } from '../../src/SubstituteException'

interface Calculator {
Expand All @@ -13,7 +13,7 @@ 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(1).add(1, 1), { instanceOf: SubstituteException })
t.throws(() => calculator.received().add(1, 1), { instanceOf: SubstituteException })
t.throws(() => calculator.received().add(Arg.all()), { instanceOf: SubstituteException })
})

Expand Down
59 changes: 25 additions & 34 deletions spec/regression/index.test.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import test from 'ava'

import { Substitute, Arg, SubstituteOf } from '../../src'
import { Substitute, Arg, SubstituteOf, received, mimicks, resolves, returns } from '../../src'

class Dummy {

Expand All @@ -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 @@ -47,22 +47,13 @@ function initialize() {

const textModifierRegex = /\x1b\[\d+m/g

test('class with method called \'received\' can be used for call count verification when proxies are suspended', t => {
initialize()

Substitute.disableFor(substitute).received(2)

t.throws(() => substitute.received(2).received(2))
t.notThrows(() => substitute.received(1).received(2))
})

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

Substitute.disableFor(substitute).received('foo')
substitute.received("foo")

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

test('class string field set received', t => {
Expand All @@ -79,16 +70,16 @@ test('class string field set received', t => {
runLogic(substitute)


t.notThrows(() => substitute.received().v = 'hello')
t.notThrows(() => substitute.received(5).v = Arg.any())
t.notThrows(() => substitute.received().v = Arg.any())
t.notThrows(() => substitute.received(2).v = 'hello')
t.notThrows(() => substitute.received(2).v = Arg.is(x => typeof x === 'string' && x.indexOf('ll') > -1))
t.notThrows(() => substitute[received]().v = 'hello')
t.notThrows(() => substitute[received](5).v = Arg.any())
t.notThrows(() => substitute[received]().v = Arg.any())
t.notThrows(() => substitute[received](2).v = 'hello')
t.notThrows(() => substitute[received](2).v = Arg.is(x => typeof x === 'string' && x.indexOf('ll') > -1))

t.throws(() => substitute.received(2).v = Arg.any())
t.throws(() => substitute.received(1).v = Arg.any())
t.throws(() => substitute.received(1).v = Arg.is(x => typeof x === 'string' && x.indexOf('ll') > -1))
t.throws(() => substitute.received(3).v = 'hello')
t.throws(() => substitute[received](2).v = Arg.any())
t.throws(() => substitute[received](1).v = Arg.any())
t.throws(() => substitute[received](1).v = Arg.is(x => typeof x === 'string' && x.indexOf('ll') > -1))
t.throws(() => substitute[received](3).v = 'hello')
})

test('resolving promises works', async t => {
Expand Down Expand Up @@ -117,9 +108,9 @@ test('class method received', t => {
void substitute.c('hi', 'there')
void substitute.c('hi', 'there')

t.notThrows(() => substitute.received(4).c('hi', 'there'))
t.notThrows(() => substitute.received(1).c('hi', 'the1re'))
t.notThrows(() => substitute.received().c('hi', 'there'))
t.notThrows(() => substitute[received](4).c('hi', 'there'))
t.notThrows(() => substitute[received](1).c('hi', 'the1re'))
t.notThrows(() => substitute[received]().c('hi', 'there'))

const expectedMessage = 'Expected 7 calls to the method c with arguments [\'hi\', \'there\'], but received 4 of such calls.\n' +
'All calls received to method c:\n' +
Expand All @@ -128,7 +119,7 @@ test('class method received', t => {
'-> call with arguments [\'hi\', \'there\']\n' +
'-> call with arguments [\'hi\', \'there\']\n' +
'-> call with arguments [\'hi\', \'there\']'
const { message } = t.throws(() => { substitute.received(7).c('hi', 'there') })
const { message } = t.throws(() => { substitute[received](7).c('hi', 'there') })
t.is(message.replace(textModifierRegex, ''), expectedMessage)
})

Expand All @@ -138,14 +129,14 @@ test('received call matches after partial mocks using property instance mimicks'
substitute.d.mimicks(() => instance.d)
substitute.c('lala', 'bar')

substitute.received(1).c('lala', 'bar')
substitute.received(1).c('lala', 'bar')
substitute[received](1).c('lala', 'bar')
substitute[received](1).c('lala', 'bar')

t.notThrows(() => substitute.received(1).c('lala', 'bar'))
t.notThrows(() => substitute[received](1).c('lala', 'bar'))
const expectedMessage = 'Expected 2 calls to the method c with arguments [\'lala\', \'bar\'], but received 1 of such calls.\n' +
'All calls received to method c:\n' +
'-> call with arguments [\'lala\', \'bar\']'
const { message } = t.throws(() => substitute.received(2).c('lala', 'bar'))
const { message } = t.throws(() => substitute[received](2).c('lala', 'bar'))
t.is(message.replace(textModifierRegex, ''), expectedMessage)
t.deepEqual(substitute.d, 1337)
})
Expand Down
2 changes: 1 addition & 1 deletion spec/regression/issues/11.test.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import test from 'ava'
import { Substitute, Arg } from '../../../src'
import { Substitute, Arg, received, returns } from '../../../src'

type Addands = {
op1: number
Expand Down
2 changes: 1 addition & 1 deletion spec/regression/issues/178.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import test, { ExecutionContext, ThrowsExpectation } from 'ava'
import * as fakeTimers from '@sinonjs/fake-timers'
import { types } from 'util'

import { Substitute } from '../../../src'
import { Substitute, didNotReceive, received, returns } from '../../../src'
import { SubstituteException } from '../../../src/SubstituteException'

interface Library {
Expand Down
2 changes: 1 addition & 1 deletion spec/regression/issues/23.test.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import test from 'ava'

import { Substitute, Arg } from '../../../src'
import { Substitute, Arg, received, mimicks } from '../../../src'

interface CalculatorInterface {
add(a: number, b: number): number
Expand Down
2 changes: 1 addition & 1 deletion spec/regression/issues/36.test.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import test from 'ava'

import { Substitute, Arg } from '../../../src'
import { Substitute, Arg, received, returns } from '../../../src'

class Key {
private constructor(private _value: string) { }
Expand Down
2 changes: 1 addition & 1 deletion spec/regression/issues/45.test.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import test from 'ava'

import { Substitute, Arg } from '../../../src'
import { Substitute, Arg, received } from '../../../src'

class DependencyClass {
public methodOne() { }
Expand Down
2 changes: 1 addition & 1 deletion spec/regression/issues/59.test.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import test from 'ava'

import { Substitute } from '../../../src'
import { Substitute, received, returns } from '../../../src'

interface IEcho {
echo(a: string): string
Expand Down
2 changes: 1 addition & 1 deletion spec/regression/mimicks.spec.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import test from 'ava'
import { Substitute, Arg } from '../../src'
import { Substitute, Arg, mimicks } from '../../src'

interface Calculator {
add(a: number, b: number): number
Expand Down
2 changes: 1 addition & 1 deletion spec/regression/received.spec.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import test from 'ava'
import { Substitute, Arg } from '../../src'
import { Substitute, Arg, received, returns } from '../../src'
import { SubstituteException } from '../../src/SubstituteException'

interface Calculator {
Expand Down
2 changes: 1 addition & 1 deletion spec/regression/rejects.spec.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import test from 'ava'

import { Substitute, Arg } from '../../src'
import { Substitute, Arg, rejects } from '../../src'

interface Calculator {
getMemory(): Promise<number>
Expand Down
2 changes: 1 addition & 1 deletion spec/regression/resolves.spec.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import test from 'ava'

import { Substitute, Arg } from '../../src'
import { Substitute, Arg, resolves } from '../../src'

interface Calculator {
getMemory(): Promise<number>
Expand Down
5 changes: 1 addition & 4 deletions spec/regression/returns.spec.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import test from 'ava'
import { types } from 'util'

import { Substitute, Arg } from '../../src'
import { Substitute, Arg, returns } from '../../src'

interface Calculator {
add(a: number, b: number): number
Expand All @@ -19,9 +19,6 @@ interface Calculator {
test('returns a primitive value for method with no arguments', t => {
const calculator = Substitute.for<Calculator>()
calculator.clear().returns()
// calculator.add(1, 2).toExponential()
// calculator.isEnabled2.viewResult().returns(3)
// calculator.other().viewResult().returns(2)

t.is(void 0 as void, calculator.clear())
})
Expand Down
2 changes: 1 addition & 1 deletion spec/regression/throws.spec.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import test from 'ava'

import { Substitute, Arg } from '../../src'
import { Substitute, Arg, returns, throws } from '../../src'

interface Calculator {
add(a: number, b: number): number
Expand Down
Loading
Loading