Skip to content

Commit

Permalink
support serialization in different contexts
Browse files Browse the repository at this point in the history
  • Loading branch information
notanengineercom committed Mar 21, 2024
1 parent 8bc9cde commit dadeecd
Show file tree
Hide file tree
Showing 3 changed files with 56 additions and 2 deletions.
13 changes: 13 additions & 0 deletions spec/regression/issues/138.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import test from 'ava'

import { Substitute } from '../../../src'

interface Library { }

test('issue 138: serializes to JSON compatible data', t => {
const lib = Substitute.for<Library>()
const result = JSON.stringify(lib)

t.true(typeof result === 'string')
t.is(result, '"@Substitute {\\n}"')
})
39 changes: 39 additions & 0 deletions spec/regression/issues/27.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import test from 'ava'
import { types } from 'util'

import { Substitute } from '../../../src'

interface Library {
subSection: () => string
}

// Adapted snipped extracted from https://github.com/angular/angular/blob/main/packages/compiler/src/parse_util.ts#L176
// This is to reproduce the behavior of the Angular compiler. This function tries to extract the id from a reference.
const identifierName = (compileIdentifier: { reference: any } | null | undefined): string | null => {
if (!compileIdentifier || !compileIdentifier.reference) {
return null
}
const ref = compileIdentifier.reference
if (ref['__anonymousType']) {
return ref['__anonymousType']
}
}

test('issue 27: mocks should work with Angular TestBed', t => {
const lib = Substitute.for<Library>()
lib.subSection().returns('This is the mocked value')
const result = identifierName({ reference: lib })

t.not(result, null)
t.true(types.isProxy(result))

const jitId = `jit_${result}`
t.is(jitId, 'jit_property<__anonymousType>: ')
})

test('issue 27: subsitute node can be coerced to a primitive value', t => {
const lib = Substitute.for<Library>()
t.true(typeof `${lib}` === 'string')
t.true(typeof (lib + '') === 'string')
t.is(`${lib}`, '@Substitute {\n}')
})
6 changes: 4 additions & 2 deletions src/SubstituteNode.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ const clearTypeToFilterMap: Record<ClearType, FilterFunction<SubstituteNodeModel
substituteValues: node => is.CONTEXT.substitution(node.context)
}

type SpecialProperty = typeof instance | typeof inspect.custom | 'then'
type SpecialProperty = typeof instance | typeof inspect.custom | typeof Symbol.toPrimitive | 'then' | 'toJSON'
type RootContext = { substituteMethodsEnabled: boolean }

export class SubstituteNode extends SubstituteNodeBase implements ObjectSubstitute<unknown>, SubstituteNodeModel {
Expand Down Expand Up @@ -259,14 +259,16 @@ export class SubstituteNode extends SubstituteNodeBase implements ObjectSubstitu
}

private isSpecialProperty(property: PropertyKey): property is SpecialProperty {
return property === SubstituteNode.instance || property === inspect.custom || property === 'then'
return property === SubstituteNode.instance || property === inspect.custom || property === Symbol.toPrimitive || property === 'then' || property === 'toJSON'
}

private evaluateSpecialProperty(property: SpecialProperty) {
switch (property) {
case SubstituteNode.instance:
return this
case 'toJSON':
case inspect.custom:
case Symbol.toPrimitive:
return this.printableForm.bind(this)
case 'then':
return
Expand Down

0 comments on commit dadeecd

Please sign in to comment.