New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

@fluffy-spoon/substitute

Package Overview
Dependencies
Maintainers
1
Versions
123
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@fluffy-spoon/substitute - npm Package Compare versions

Comparing version 1.0.52 to 1.0.53

2

dist/spec/index.test.d.ts

@@ -6,3 +6,3 @@ export declare class Example {

v: string;
foo(): void;
foo(): string;
}

@@ -28,3 +28,3 @@ "use strict";

Example.prototype.foo = function () {
console.log('stuff');
return 'stuff';
};

@@ -34,10 +34,52 @@ return Example;

exports.Example = Example;
var instance;
var substitute;
ava_1.default.beforeEach(function () {
instance = new Example();
substitute = Index_1.Substitute.for();
});
ava_1.default('are arguments equal', function (t) {
t.true(Utilities_1.areArgumentsEqual(Index_1.Arg.any(), 'hi'));
t.true(Utilities_1.areArgumentsEqual(Index_1.Arg.any('array'), ['foo', 'bar']));
t.false(Utilities_1.areArgumentsEqual(['foo', 'bar'], ['foo', 'bar']));
t.true(Utilities_1.areArgumentsEqual(Index_1.Arg.any('array'), ['foo', 'bar']));
t.false(Utilities_1.areArgumentsEqual(Index_1.Arg.any('array'), 1337));
});
ava_1.default('class method returns with placeholder args', function (t) {
substitute.c(Index_1.Arg.any(), "there").returns("blah", "haha");
t.deepEqual(substitute.c("hi", "there"), 'blah');
t.deepEqual(substitute.c("hi", "the1re"), void 0);
t.deepEqual(substitute.c("his", "there"), 'haha');
t.deepEqual(substitute.c("his", "there"), void 0);
t.deepEqual(substitute.c("hi", "there"), void 0);
});
ava_1.default('partial mocks using function mimicks with specific args', function (t) {
substitute.c('a', 'b').mimicks(instance.c);
t.deepEqual(substitute.c('c', 'b'), void 0);
t.deepEqual(substitute.c('a', 'b'), 'hello a world (b)');
});
ava_1.default('class method returns with specific args', function (t) {
substitute.c("hi", "there").returns("blah", "haha");
t.deepEqual(substitute.c("hi", "there"), 'blah');
t.deepEqual(substitute.c("hi", "the1re"), void 0);
t.deepEqual(substitute.c("hi", "there"), 'haha');
t.deepEqual(substitute.c("hi", "there"), void 0);
t.deepEqual(substitute.c("hi", "there"), void 0);
});
ava_1.default('class string field get received', function (t) {
void substitute.a;
void substitute.a;
void substitute.a;
void substitute.a;
t.throws(function () { return substitute.received(3).a; });
t.notThrows(function () { return substitute.received().a; });
t.notThrows(function () { return substitute.received(4).a; });
});
ava_1.default('partial mocks using function mimicks with all args', function (t) {
substitute.c(Index_1.Arg.all()).mimicks(instance.c);
t.deepEqual(substitute.c('a', 'b'), 'hello a world (b)');
});
ava_1.default('partial mocks using property instance mimicks', function (t) {
substitute.d.mimicks(function () { return instance.d; });
t.deepEqual(substitute.d, 1337);
});
ava_1.default('class void returns', function (t) {

@@ -71,19 +113,2 @@ substitute.foo().returns(void 0, null);

});
ava_1.default('class string field get received', function (t) {
void substitute.a;
void substitute.a;
void substitute.a;
void substitute.a;
t.throws(function () { return substitute.received(3).a; });
t.notThrows(function () { return substitute.received().a; });
t.notThrows(function () { return substitute.received(4).a; });
});
ava_1.default('class method returns', function (t) {
substitute.c("hi", "there").returns("blah", "haha");
t.deepEqual(substitute.c("hi", "there"), 'blah');
t.deepEqual(substitute.c("hi", "the1re"), void 0);
t.deepEqual(substitute.c("hi", "there"), 'haha');
t.deepEqual(substitute.c("hi", "there"), void 0);
t.deepEqual(substitute.c("hi", "there"), void 0);
});
ava_1.default('class method received', function (t) {

@@ -90,0 +115,0 @@ void substitute.c("hi", "there");

@@ -0,2 +1,14 @@

export declare class Argument<T> {
private description;
private matchingFunction;
constructor(description: string, matchingFunction: (arg: T) => boolean);
matches(arg: T): boolean;
toString(): string;
inspect(): string;
}
export declare class AllArguments extends Argument<any> {
constructor();
}
export declare class Arg {
static all(): AllArguments;
static any(): any;

@@ -12,9 +24,1 @@ static any<T extends 'string'>(type: T): Argument<string> & string;

}
export declare class Argument<T> {
private description;
private matchingFunction;
constructor(description: string, matchingFunction: (arg: T) => boolean);
matches(arg: T): boolean;
toString(): string;
inspect(): string;
}
"use strict";
var __extends = (this && this.__extends) || (function () {
var extendStatics = function (d, b) {
extendStatics = Object.setPrototypeOf ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
return extendStatics(d, b);
}
return function (d, b) {
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
})();
Object.defineProperty(exports, "__esModule", { value: true });
var Argument = /** @class */ (function () {
function Argument(description, matchingFunction) {
this.description = description;
this.matchingFunction = matchingFunction;
}
Argument.prototype.matches = function (arg) {
return this.matchingFunction(arg);
};
Argument.prototype.toString = function () {
return this.description;
};
Argument.prototype.inspect = function () {
return this.description;
};
return Argument;
}());
exports.Argument = Argument;
var AllArguments = /** @class */ (function (_super) {
__extends(AllArguments, _super);
function AllArguments() {
return _super.call(this, '{all arguments}', function () { return true; }) || this;
}
return AllArguments;
}(Argument));
exports.AllArguments = AllArguments;
var Arg = /** @class */ (function () {
function Arg() {
}
Arg.all = function () {
return new AllArguments();
};
Arg.any = function (type) {
var description = !type ? '{any arg}' : '{arg matching ' + type + '}';
return new Argument(description, function (x) {
if (typeof type === 'string')
if (!type)
return true;
if (typeof type === 'undefined')
if (typeof x === 'undefined')
return true;

@@ -31,19 +72,2 @@ if (type === 'array')

exports.Arg = Arg;
var Argument = /** @class */ (function () {
function Argument(description, matchingFunction) {
this.description = description;
this.matchingFunction = matchingFunction;
}
Argument.prototype.matches = function (arg) {
return this.matchingFunction(arg);
};
Argument.prototype.toString = function () {
return this.description;
};
Argument.prototype.inspect = function () {
return this.description;
};
return Argument;
}());
exports.Argument = Argument;
//# sourceMappingURL=Arguments.js.map

@@ -8,2 +8,3 @@ export declare abstract class ProxyPropertyContextBase {

type: 'object';
mimicks: Function;
returnValues: any[];

@@ -21,2 +22,3 @@ constructor();

returnValues: any[];
mimicks: Function;
constructor();

@@ -44,3 +46,3 @@ }

getLastCall(): ProxyCallRecord;
addActualPropertyCall(): ProxyCallRecord;
addActualPropertyCall(): void;
}

@@ -47,0 +49,0 @@ export declare class ProxyCallRecord {

@@ -17,2 +17,3 @@ "use strict";

var Utilities_1 = require("./Utilities");
var Arguments_1 = require("./Arguments");
var ProxyPropertyContextBase = /** @class */ (function () {

@@ -100,2 +101,6 @@ function ProxyPropertyContextBase() {

return false;
var firstArg1 = args1[0];
var firstArg2 = args2[0];
if (firstArg1 instanceof Arguments_1.AllArguments || firstArg2 instanceof Arguments_1.AllArguments)
return true;
if (args1.length !== args2.length)

@@ -132,9 +137,7 @@ return false;

}
if (existingCall) {
existingCall.callCount++;
return;
if (!existingCall) {
existingCall = new ProxyCallRecord(this.property);
this.calls.actual.push(existingCall);
}
var newCall = new ProxyCallRecord(this.property);
this.calls.actual.push(newCall);
return newCall;
existingCall.callCount++;
};

@@ -141,0 +144,0 @@ return ProxyObjectContext;

@@ -15,6 +15,5 @@ "use strict";

var propertyContext = objectContext.property;
var existingCalls = objectContext.findActualMethodCalls(propertyContext.name, argumentsList);
var existingCall = existingCalls[0];
if (propertyContext.type === 'function') {
var existingCalls = objectContext.findActualMethodCalls(propertyContext.name, argumentsList);
if (existingCalls.length === 0)
return void 0;
var expected = objectContext.calls.expected;

@@ -25,8 +24,14 @@ if (expected && expected.callCount !== void 0) {

_this.assertCallMatchCount('method', expected, existingCalls);
return thisProxy;
return void 0;
}
var existingCall = existingCalls[0];
if (existingCall) {
existingCall.callCount++;
if (existingCall.property.type === 'function') {
var mimicks = existingCall.property.method.mimicks;
if (mimicks)
return mimicks.call.apply(mimicks, [_target].concat(argumentsList));
}
}
if (!existingCall)
return propertyContext.method.returnValues[0];
existingCall.callCount++;
return void 0;
if (propertyContext.method.returnValues)

@@ -63,4 +68,3 @@ return propertyContext.method.returnValues[existingCall.callCount - 1];

objectContext.property = newMethodPropertyContext;
var call = objectContext.addActualPropertyCall();
call.callCount = 1;
objectContext.addActualPropertyCall();
return true;

@@ -84,3 +88,3 @@ },

if (property === 'returns') {
if (currentPropertyContext.type === 'object') {
var createReturnsFunction = function (context) {
return function () {

@@ -91,15 +95,24 @@ var args = [];

}
currentPropertyContext.returnValues = args;
context.returnValues = args;
context.mimicks = void 0;
objectContext.getLastCall().callCount--;
};
}
if (currentPropertyContext.type === 'function') {
return function () {
var args = [];
for (var _i = 0; _i < arguments.length; _i++) {
args[_i] = arguments[_i];
}
currentPropertyContext.method.returnValues = args;
};
if (currentPropertyContext.type === 'object')
return createReturnsFunction(currentPropertyContext);
if (currentPropertyContext.type === 'function')
return createReturnsFunction(currentPropertyContext.method);
}
if (property === 'mimicks') {
var createMimicksFunction = function (context) {
return function (value) {
context.returnValues = void 0;
context.mimicks = value;
objectContext.getLastCall().callCount--;
};
};
if (currentPropertyContext.type === 'object')
return createMimicksFunction(currentPropertyContext);
if (currentPropertyContext.type === 'function') {
return createMimicksFunction(currentPropertyContext.method);
}

@@ -127,5 +140,8 @@ }

existingCall.callCount++;
if (!existingCallProperty.returnValues)
return void 0;
return existingCallProperty.returnValues[existingCall.callCount - 1];
if (existingCallProperty.returnValues)
return existingCallProperty.returnValues[existingCall.callCount - 1];
var mimicks = existingCallProperty.mimicks;
if (mimicks)
return mimicks();
return void 0;
}

@@ -137,4 +153,3 @@ var newPropertyContext = new Context_1.ProxyPropertyContext();

objectContext.property = newPropertyContext;
var call = objectContext.addActualPropertyCall();
call.callCount++;
objectContext.addActualPropertyCall();
return thisProxy;

@@ -141,0 +156,0 @@ }

@@ -1,12 +0,21 @@

export declare type FunctionSubstitute<F extends any[], T> = (...args: F) => (T & MockObjectMixin<T>);
export declare type PropertySubstitute<T> = T & Partial<MockObjectMixin<T>>;
declare type MockObjectMixin<T> = {
returns: (...args: T[]) => void;
import { AllArguments } from "./Arguments";
export declare type NoArgumentFunctionSubstitute<TReturnType> = (() => (TReturnType & NoArgumentMockObjectMixin<TReturnType>));
export declare type FunctionSubstitute<TArguments extends any[], TReturnType> = ((...args: TArguments) => (TReturnType & MockObjectMixin<TArguments, TReturnType>)) & ((allArguments: AllArguments) => (TReturnType & MockObjectMixin<TArguments, TReturnType>));
export declare type PropertySubstitute<TReturnType> = TReturnType & Partial<NoArgumentMockObjectMixin<TReturnType>>;
declare type BaseMockObjectMixin<TReturnType> = {
returns: (...args: TReturnType[]) => void;
};
declare type NoArgumentMockObjectMixin<TReturnType> = BaseMockObjectMixin<TReturnType> & {
mimicks: (func: () => TReturnType) => void;
};
declare type MockObjectMixin<TArguments extends any[], TReturnType> = BaseMockObjectMixin<TReturnType> & {
mimicks: (func: (...args: TArguments) => TReturnType) => void;
};
export declare type ObjectSubstitute<T extends Object> = ObjectSubstituteTransformation<T> & {
received(amount?: number): T;
mimick(instance: T): void;
};
declare type ObjectSubstituteTransformation<T extends Object> = {
[P in keyof T]: T[P] extends (...args: infer F) => infer R ? FunctionSubstitute<F, R> : PropertySubstitute<T[P]>;
[P in keyof T]: T[P] extends () => infer R ? NoArgumentFunctionSubstitute<R> : T[P] extends (...args: infer F) => infer R ? FunctionSubstitute<F, R> : PropertySubstitute<T[P]>;
};
export {};

@@ -26,2 +26,4 @@ "use strict";

function areArgumentsEqual(a, b) {
if (a instanceof Arguments_1.AllArguments || b instanceof Arguments_1.AllArguments)
return true;
if (a instanceof Arguments_1.Argument && b instanceof Arguments_1.Argument)

@@ -35,6 +37,2 @@ return a.matches(b) && b.matches(a);

return true;
if ((!a || !b) && a !== b)
return false;
if (Array.isArray(a) !== Array.isArray(b))
return false;
return a === b;

@@ -41,0 +39,0 @@ }

{
"name": "@fluffy-spoon/substitute",
"version": "1.0.52",
"version": "1.0.53",
"description": "An NSubstitute port to TypeScript called substitute.js.",

@@ -5,0 +5,0 @@ "main": "dist/src/Index.js",

@@ -15,2 +15,4 @@ [`@fluffy-spoon/substitute`](https://www.npmjs.com/package/@fluffy-spoon/substitute) is a TypeScript port of [NSubstitute](http://nsubstitute.github.io), which aims to provide a much more fluent mocking opportunity for strong-typed languages.

add(a: number, b: number): number;
subtract(a: number, b: number): number;
divide(a: number, b: number): number;
}

@@ -52,6 +54,7 @@

### Matching specific arguments
```typescript
import { Arg } from '@fluffy-spoon/substitute';
//ignoring arguments
//ignoring first argument
calculator.add(Arg.any(), 2).returns(10);

@@ -65,2 +68,60 @@ console.log(calculator.add(1337, 3)); //prints undefined since second argument doesn't match

### Ignoring all arguments
```typescript
//ignoring all arguments
calculator.add(Arg.all()).returns(10);
console.log(calculator.add(1, 3)); //prints 10
console.log(calculator.add(5, 2)); //prints 10
```
### Match order
The order of argument matchers matters. The first matcher that matches will always be used. Below are two examples.
```typescript
calculator.add(Arg.all()).returns(10);
calculator.add(1, 3).returns(1337);
console.log(calculator.add(1, 3)); //prints 10
console.log(calculator.add(5, 2)); //prints 10
```
```typescript
calculator.add(1, 3).returns(1337);
calculator.add(Arg.all()).returns(10);
console.log(calculator.add(1, 3)); //prints 1337
console.log(calculator.add(5, 2)); //prints 10
```
## Partial mocks
With partial mocks you always start with a true substitute where everything is mocked and then opt-out of substitutions in certain scenarios.
```typescript
import { Substitute, Arg } from '@fluffy-spoon/substitute';
class RealCalculator implements Calculator {
add(a: number, b: number) => a + b;
subtract(a: number, b: number) => a - b;
}
var realCalculator = new RealCalculator();
var fakeCalculator = Substitute.for<Calculator>();
//let the subtract method always use the real method
fakeCalculator.subtract(Arg.all()).mimicks(realCalculator.subtract);
console.log(fakeCalculator.subtract(20, 10)); //prints 10
console.log(fakeCalculator.subtract(1, 2)); //prints 10
//for the add method, we only use the real method when the first arg is less than 10
//else, we always return 1337
fakeCalculator.add(Arg.is(x < 10), Arg.any()).mimicks(realCalculator.add);
fakeCalculator.add(Arg.is(x >= 10), Arg.any()).returns(1337);
console.log(fakeCalculator.add(5, 100)); //prints 105 via real method
console.log(fakeCalculator.add(210, 7)); //prints 1337 via fake method
//for the divide method, we only use the real method for explicit arguments
fakeCalculator.divide(10, 2).mimicks(realCalculator.divide);
fakeCalculator.divide(Arg.all()).returns(1338);
console.log(fakeCalculator.divide(10, 5)); //prints 5
console.log(fakeCalculator.divide(9, 5)); //prints 1338
```
# Benefits over other mocking libraries

@@ -67,0 +128,0 @@ - Easier-to-understand fluent syntax.

@@ -20,9 +20,11 @@ import test from 'ava';

foo(): void {
console.log('stuff');
foo() {
return 'stuff';
}
}
let instance: Example;
let substitute: ObjectSubstitute<Example>;
test.beforeEach(() => {
instance = new Example();
substitute = Substitute.for<Example>();

@@ -32,7 +34,59 @@ });

test('are arguments equal', t => {
t.true(areArgumentsEqual(Arg.any(), 'hi'));
t.true(areArgumentsEqual(Arg.any('array'), ['foo', 'bar']));
t.false(areArgumentsEqual(['foo', 'bar'], ['foo', 'bar']));
t.false(areArgumentsEqual(Arg.any('array'), 1337));
});
t.true(areArgumentsEqual(Arg.any('array'), ['foo', 'bar']));
test('class method returns with placeholder args', t => {
substitute.c(Arg.any(), "there").returns("blah", "haha");
t.deepEqual(substitute.c("hi", "there"), 'blah');
t.deepEqual(substitute.c("hi", "the1re"), void 0);
t.deepEqual(substitute.c("his", "there"), 'haha');
t.deepEqual(substitute.c("his", "there"), void 0);
t.deepEqual(substitute.c("hi", "there"), void 0);
});
test('partial mocks using function mimicks with specific args', t => {
substitute.c('a', 'b').mimicks(instance.c);
t.deepEqual(substitute.c('c', 'b'), void 0);
t.deepEqual(substitute.c('a', 'b'), 'hello a world (b)');
});
test('class method returns with specific args', t => {
substitute.c("hi", "there").returns("blah", "haha");
t.deepEqual(substitute.c("hi", "there"), 'blah');
t.deepEqual(substitute.c("hi", "the1re"), void 0);
t.deepEqual(substitute.c("hi", "there"), 'haha');
t.deepEqual(substitute.c("hi", "there"), void 0);
t.deepEqual(substitute.c("hi", "there"), void 0);
});
test('class string field get received', t => {
void substitute.a;
void substitute.a;
void substitute.a;
void substitute.a;
t.throws(() => substitute.received(3).a);
t.notThrows(() => substitute.received().a);
t.notThrows(() => substitute.received(4).a);
});
test('partial mocks using function mimicks with all args', t => {
substitute.c(Arg.all()).mimicks(instance.c);
t.deepEqual(substitute.c('a', 'b'), 'hello a world (b)');
});
test('partial mocks using property instance mimicks', t => {
substitute.d.mimicks(() => instance.d);
t.deepEqual(substitute.d, 1337);
});
test('class void returns', t => {

@@ -72,23 +126,2 @@ substitute.foo().returns(void 0, null);

test('class string field get received', t => {
void substitute.a;
void substitute.a;
void substitute.a;
void substitute.a;
t.throws(() => substitute.received(3).a);
t.notThrows(() => substitute.received().a);
t.notThrows(() => substitute.received(4).a);
});
test('class method returns', t => {
substitute.c("hi", "there").returns("blah", "haha");
t.deepEqual(substitute.c("hi", "there"), 'blah');
t.deepEqual(substitute.c("hi", "the1re"), void 0);
t.deepEqual(substitute.c("hi", "there"), 'haha');
t.deepEqual(substitute.c("hi", "there"), void 0);
t.deepEqual(substitute.c("hi", "there"), void 0);
});
test('class method received', t => {

@@ -95,0 +128,0 @@ void substitute.c("hi", "there");

@@ -0,2 +1,32 @@

export class Argument<T> {
constructor(
private description: string,
private matchingFunction: (arg: T) => boolean
) {
}
matches(arg: T) {
return this.matchingFunction(arg);
}
toString() {
return this.description;
}
inspect() {
return this.description;
}
}
export class AllArguments extends Argument<any> {
constructor() {
super('{all arguments}', () => true);
}
}
export class Arg {
static all() {
return new AllArguments();
}
static any()

@@ -12,6 +42,6 @@ static any<T extends 'string'>(type: T): Argument<string> & string

return new Argument<any>(description, x => {
if(typeof type === 'string')
if(!type)
return true;
if(typeof type === 'undefined')
if(typeof x === 'undefined')
return true;

@@ -39,22 +69,2 @@

}
}
export class Argument<T> {
constructor(
private description: string,
private matchingFunction: (arg: T) => boolean
) {
}
matches(arg: T) {
return this.matchingFunction(arg);
}
toString() {
return this.description;
}
inspect() {
return this.description;
}
}
import { areArgumentsEqual } from "./Utilities";
import { ENGINE_METHOD_DIGESTS } from "constants";
import { AllArguments } from "./Arguments";

@@ -17,2 +17,4 @@ export abstract class ProxyPropertyContextBase {

type: 'object';
mimicks: Function;
returnValues: any[];

@@ -48,2 +50,3 @@

returnValues: any[];
mimicks: Function;

@@ -112,2 +115,7 @@ constructor() {

const firstArg1 = args1[0];
const firstArg2 = args2[0];
if(firstArg1 instanceof AllArguments || firstArg2 instanceof AllArguments)
return true;
if(args1.length !== args2.length)

@@ -120,3 +128,3 @@ return false;

if(!areArgumentsEqual(arg1, arg2))
if(!areArgumentsEqual(arg1, arg2))
return false;

@@ -150,11 +158,8 @@ }

if(existingCall) {
existingCall.callCount++;
return;
if(!existingCall) {
existingCall = new ProxyCallRecord(this.property);
this.calls.actual.push(existingCall);
}
const newCall = new ProxyCallRecord(this.property);
this.calls.actual.push(newCall);
return newCall;
existingCall.callCount++;
}

@@ -161,0 +166,0 @@ }

@@ -6,2 +6,3 @@ import { ObjectSubstitute } from "./Transformations";

export class Substitute {
static for<T>(): ObjectSubstitute<T> {

@@ -14,7 +15,7 @@ const objectContext = new ProxyObjectContext();

const propertyContext = objectContext.property;
const existingCalls = objectContext.findActualMethodCalls(propertyContext.name, argumentsList);
const existingCall = existingCalls[0];
if (propertyContext.type === 'function') {
let existingCalls = objectContext.findActualMethodCalls(propertyContext.name, argumentsList);
if (existingCalls.length === 0)
return void 0;
const expected = objectContext.calls.expected;

@@ -26,11 +27,18 @@ if(expected && expected.callCount !== void 0) {

this.assertCallMatchCount('method', expected, existingCalls);
return thisProxy;
return void 0;
}
const existingCall = existingCalls[0];
if(existingCall) {
existingCall.callCount++;
if(existingCall.property.type === 'function') {
const mimicks = existingCall.property.method.mimicks;
if(mimicks)
return mimicks.call(_target, ...argumentsList);
}
}
if(!existingCall)
return propertyContext.method.returnValues[0];
return void 0;
existingCall.callCount++;
if(propertyContext.method.returnValues)

@@ -77,4 +85,3 @@ return propertyContext.method.returnValues[existingCall.callCount - 1];

const call = objectContext.addActualPropertyCall();
call.callCount = 1;
objectContext.addActualPropertyCall();

@@ -105,14 +112,33 @@ return true;

if (property === 'returns') {
if (currentPropertyContext.type === 'object') {
const createReturnsFunction = (context: {returnValues, mimicks}) => {
return (...args: any[]) => {
currentPropertyContext.returnValues = args;
context.returnValues = args;
context.mimicks = void 0;
objectContext.getLastCall().callCount--;
};
}
};
if (currentPropertyContext.type === 'function') {
return (...args: any[]) => {
currentPropertyContext.method.returnValues = args;
if (currentPropertyContext.type === 'object')
return createReturnsFunction(currentPropertyContext);
if (currentPropertyContext.type === 'function')
return createReturnsFunction(currentPropertyContext.method);
}
if(property === 'mimicks') {
const createMimicksFunction = (context: {returnValues, mimicks}) => {
return (value: Function) => {
context.returnValues = void 0;
context.mimicks = value;
objectContext.getLastCall().callCount--;
};
};
if(currentPropertyContext.type === 'object')
return createMimicksFunction(currentPropertyContext);
if(currentPropertyContext.type === 'function') {
return createMimicksFunction(currentPropertyContext.method);
}

@@ -147,6 +173,10 @@ }

if (!existingCallProperty.returnValues)
return void 0;
if (existingCallProperty.returnValues)
return existingCallProperty.returnValues[existingCall.callCount - 1];
const mimicks = existingCallProperty.mimicks;
if(mimicks)
return mimicks();
return existingCallProperty.returnValues[existingCall.callCount - 1];
return void 0;
}

@@ -161,4 +191,3 @@

const call = objectContext.addActualPropertyCall();
call.callCount++;
objectContext.addActualPropertyCall();

@@ -165,0 +194,0 @@ return thisProxy;

@@ -1,11 +0,27 @@

export type FunctionSubstitute<F extends any[], T> = (...args: F) => (T & MockObjectMixin<T>)
import { AllArguments } from "./Arguments";
export type PropertySubstitute<T> = T & Partial<MockObjectMixin<T>>
export type NoArgumentFunctionSubstitute<TReturnType> =
(() => (TReturnType & NoArgumentMockObjectMixin<TReturnType>))
type MockObjectMixin<T> = {
returns: (...args: T[]) => void;
export type FunctionSubstitute<TArguments extends any[], TReturnType> =
((...args: TArguments) => (TReturnType & MockObjectMixin<TArguments, TReturnType>)) &
((allArguments: AllArguments) => (TReturnType & MockObjectMixin<TArguments, TReturnType>))
export type PropertySubstitute<TReturnType> = TReturnType & Partial<NoArgumentMockObjectMixin<TReturnType>>
type BaseMockObjectMixin<TReturnType> = {
returns: (...args: TReturnType[]) => void;
}
type NoArgumentMockObjectMixin<TReturnType> = BaseMockObjectMixin<TReturnType> & {
mimicks: (func: () => TReturnType) => void;
}
type MockObjectMixin<TArguments extends any[], TReturnType> = BaseMockObjectMixin<TReturnType> & {
mimicks: (func: (...args: TArguments) => TReturnType) => void;
}
export type ObjectSubstitute<T extends Object> = ObjectSubstituteTransformation<T> & {
received(amount?: number): T;
mimick(instance: T): void;
}

@@ -15,4 +31,5 @@

[P in keyof T]:
T[P] extends () => infer R ? NoArgumentFunctionSubstitute<R> :
T[P] extends (...args: infer F) => infer R ? FunctionSubstitute<F, R> :
PropertySubstitute<T[P]>;
}
import { ProxyCallRecord } from "./Context";
import { Argument } from "./Arguments";
import { Argument, AllArguments } from "./Arguments";

@@ -27,2 +27,5 @@ export function stringifyArguments(args: any[]) {

export function areArgumentsEqual(a: any, b: any) {
if(a instanceof AllArguments || b instanceof AllArguments)
return true;
if(a instanceof Argument && b instanceof Argument)

@@ -40,9 +43,3 @@ return a.matches(b) && b.matches(a);

if ((!a || !b) && a !== b)
return false;
if (Array.isArray(a) !== Array.isArray(b))
return false;
return a === b;
};

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc