You're Invited:Meet the Socket Team at BlackHat and DEF CON in Las Vegas, Aug 4-6.RSVP
Socket
Book a DemoInstallSign in
Socket

jasmine-auto-spies

Package Overview
Dependencies
Maintainers
1
Versions
60
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

jasmine-auto-spies - npm Package Compare versions

Comparing version

to
4.0.0

src/create-spy-from-class.types.d.ts

12

package.json
{
"name": "jasmine-auto-spies",
"version": "3.2.1",
"version": "4.0.0",
"repository": {

@@ -12,3 +12,3 @@ "type": "git",

"scripts": {
"clean": "rimraf src/*.js* src/*.d.ts *.d.ts",
"clean": "rimraf src/**/*.js* src/**/*.d.ts *.d.ts",
"commit": "git-cz",

@@ -59,3 +59,2 @@ "build": "tsc",

"@types/webpack": "4.4.11",
"@types/window-or-global": "1.0.0",
"awesome-typescript-loader": "^3.1.3",

@@ -88,11 +87,8 @@ "commitizen": "2.10.1",

"typescript": "^2.9.2",
"webpack": "2.7.0",
"window-or-global": "1.0.1"
"webpack": "2.7.0"
},
"dependencies": {
"deep-equal": "1.0.1",
"window-or-global": "1.0.1"
"deep-equal": "1.0.1"
},
"peerDependencies": {
"core-js": "^2.4.1",
"jasmine": "^2.6.0",

@@ -99,0 +95,0 @@ "rxjs": "^6.0.0",

@@ -9,10 +9,7 @@ # jasmine-auto-spies

## IMPORTANT: compatibility
* Version `2.x` and above requires **RxJS 6.0** and above.
* Version `3.x` and above requires **TypeScript 2.8** and above.
- Version `2.x` and above requires **RxJS 6.0** and above.
- Version `3.x` and above requires **TypeScript 2.8** and above.
## What is it?

@@ -22,3 +19,3 @@

If you need to create a spy from any class, just do:
If you need to create a spy from any class, just do:

@@ -39,3 +36,2 @@ ```js

## What is it good for?

@@ -53,9 +49,7 @@

## Usage (JavaScript)
```js
// my-spec.js
// my-spec.js
import { createSpyFromClass } from 'jasmine-auto-spies';

@@ -110,12 +104,10 @@ import { MyService } from './my-service';

}
```
## Usage (TypeScript)
### TypeScript Setup
Set these 2 properties in your `tsconfig.json` -
Set these 2 properties in your `tsconfig.json` -
```json

@@ -125,3 +117,3 @@ {

"experimentalDecorators": true,
"emitDecoratorMetadata": true,
"emitDecoratorMetadata": true
}

@@ -131,7 +123,5 @@ }

### 1. Spying on regular sync methods
```ts
// my-spec.ts

@@ -150,3 +140,3 @@

myServiceSpy.getName.and.returnValue('Fake Name');
... (the rest of the test) ...

@@ -163,3 +153,2 @@ });

}
```

@@ -169,17 +158,4 @@

First, annotate the method with `@AsyncSpyable` -
```ts
import { AsyncSpyable } from 'jasmine-auto-spies';
Use the `resolveWith` or `rejectWith` methods -
export class MyService{
@AsyncSpyable() // <-- MUST ADD THIS
getItems(): Promise<any> {
return Promise.resolve( itemsList );
}
}
```
Now you can use the `resolveWith` or `rejectWith` methods -
```ts

@@ -190,32 +166,17 @@ import { Spy, createSpyFromClass } from 'jasmine-auto-spies';

beforeEach( ()=> {
myServiceSpy = createSpyFromClass( MyService )
beforeEach(() => {
myServiceSpy = createSpyFromClass(MyService);
});
it( ()=>{
myServiceSpy.getItems.and.resolveWith( fakeItemsList );
it(() => {
myServiceSpy.getItems.and.resolveWith(fakeItemsList);
// OR
myServiceSpy.getItems.and.rejectWith( fakeError );
myServiceSpy.getItems.and.rejectWith(fakeError);
});
```
### 3. Spy on a `Observable` returning method
First, annotate your Observable returning method with `@AsyncSpyable` -
```ts
import { AsyncSpyable } from 'jasmine-auto-spies';
Use the `nextWith` or `throwWith` and other methods -
export class MyService{
@AsyncSpyable() // <-- MUST ADD THIS
getProducts(): Observable<any> {
return Observable.of( productsList );
}
}
```
Now you can use the `nextWith` or `throwWith` and other methods -
```ts

@@ -226,19 +187,18 @@ import { Spy, createSpyFromClass } from 'jasmine-auto-spies';

beforeEach( ()=> {
myServiceSpy = createSpyFromClass( MyService )
beforeEach(() => {
myServiceSpy = createSpyFromClass(MyService);
});
it( ()=>{
myServiceSpy.getProducts.and.nextWith( fakeProductsList );
it(() => {
myServiceSpy.getProducts.and.nextWith(fakeProductsList);
// OR
myServiceSpy.getProducts.and.nextOneTimeWith( fakeProductsList ); // emits one value and completes
myServiceSpy.getProducts.and.nextOneTimeWith(fakeProductsList); // emits one value and completes
// OR
myServiceSpy.getProducts.and.throwWith( fakeError );
myServiceSpy.getProducts.and.throwWith(fakeError);
// OR
myServiceSpy.getProducts.and.complete();
});
```
### Use `calledWith()` to configure mocks easily
### Use `calledWith()` to configure conditional return values

@@ -249,38 +209,56 @@ You can setup the expected arguments ahead of time

```ts
myServiceSpy.getProducts.calledWith(1).returnValue(true)
myServiceSpy.getProducts.calledWith(1).returnValue(true);
```
is equal to:
and it will only return this value if your subject was called with `getProducts(1)`.
#### Oh, and it also works with Promises / Observables:
```ts
myServiceSpy.getProducts.and.returnValue(true)
myServiceSpy.getProductsPromise.calledWith(1).resolveWith(true);
expect(myServiceSpy.getProducts).toHaveBeenCalledWith(1);
// OR
myServiceSpy.getProducts$.calledWith(1).nextWith(true);
// OR ANY OTHER ASYNC CONFIGURATION METHOD...
```
You can also use it with async method:
### Use `throwOnMismatch()` to turn a conditional stub into a mock
```ts
myServiceSpy.getProducts.calledWith(1).resolveWith(true)
myServiceSpy.getProducts
.calledWith(1)
.returnValue(true)
.throwOnMismatch();
```
// OR
is equal to:
myServiceSpy.getProducts.calledWith(1).nextWith(true)
```ts
myServiceSpy.getProducts.and.returnValue(true);
// OR ANY OTHER ASYNC CONFIGURATION METHOD...
expect(myServiceSpy.getProducts).toHaveBeenCalledWith(1);
```
But the difference is that the error is being thrown during `getProducts()` call and not in the `expect(...)` call.
### Manual Setup
If you need to manually configure async methods by names you could pass them as arrays of strings -
If you need to manually add methods that you want to be spies by passing an array of names as the second param of the `createSpyFromClass` function:
```ts
let spy = createSpyFromClass(MyClass, ['customMethod1', 'customMethod2']);
```
let spy = createSpyFromClass(
MyClass,
['promiseMethod1', 'promiseMethod2'],
['observableMethod1', 'observableMethod2']
);
This is good for times where a method is not part of the `prototype` of the Class but instead being defined in its constructor.
```ts
class MyClass {
constructor() {
this.customMethod1 = function() {
// This definition is not part of MyClass' prototype
};
}
}
```
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
function AsyncSpyable() {
return function (target, propertyKey, descriptor) {
};
// tslint:disable-next-line:no-console
console.warn("The \"AsyncSpyable\" is depcracated,\n You don't need to use it anymore.\n\n IT WILL GET REMOVED IN THE NEXT MAJOR VERSION\n So please remove it from your code.");
return function (target, propertyKey, descriptor) { };
}
exports.AsyncSpyable = AsyncSpyable;
//# sourceMappingURL=async-spyable-decorator.js.map

@@ -1,5 +0,5 @@

import { Spy } from './spy-types';
import { Spy } from './spy.types';
export declare function createSpyFromClass<T>(ObjectClass: {
new (...args: any[]): T;
[key: string]: any;
}, providedPromiseMethodNames?: string[], providedObservableMethodNames?: string[]): Spy<T>;
}, providedMethodNames?: string[]): Spy<T>;
"use strict";
var __read = (this && this.__read) || function (o, n) {
var m = typeof Symbol === "function" && o[Symbol.iterator];
if (!m) return o;
var i = m.call(o), r, ar = [], e;
try {
while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);
}
catch (error) { e = { error: error }; }
finally {
try {
if (r && !r.done && (m = i["return"])) m.call(i);
}
finally { if (e) throw e.error; }
}
return ar;
};
var __spread = (this && this.__spread) || function () {
for (var ar = [], i = 0; i < arguments.length; i++) ar = ar.concat(__read(arguments[i]));
return ar;
};
var __values = (this && this.__values) || function (o) {
var m = typeof Symbol === "function" && o[Symbol.iterator], i = 0;
if (m) return m.call(o);
return {
next: function () {
if (o && i >= o.length) o = void 0;
return { value: o && o[i++], done: !o };
}
};
};
var __importDefault = (this && this.__importDefault) || function (mod) {

@@ -7,22 +37,14 @@ return (mod && mod.__esModule) ? mod : { "default": mod };

var deep_equal_1 = __importDefault(require("deep-equal"));
var error_handling_1 = require("./error-handling");
var rxjs_1 = require("rxjs");
var window_or_global_1 = __importDefault(require("window-or-global"));
var Reflect = window_or_global_1.default.Reflect;
function createSpyFromClass(ObjectClass, providedPromiseMethodNames, providedObservableMethodNames) {
var error_handling_1 = require("./errors/error-handling");
var observable_spy_utils_1 = require("./observables/observable-spy-utils");
var promises_spy_utils_1 = require("./promises/promises-spy-utils");
function createSpyFromClass(ObjectClass, providedMethodNames) {
var proto = ObjectClass.prototype;
var methodNames = getAllMethodNames(proto);
if (providedMethodNames && providedMethodNames.length > 0) {
methodNames.push.apply(methodNames, __spread(providedMethodNames));
}
var autoSpy = {};
methodNames.forEach(function (methodName) {
var returnTypeClass = Reflect.getMetadata('design:returntype', proto, methodName);
var spyMethod = createSpyFunction(methodName);
if (doesMethodReturnPromise(providedPromiseMethodNames, methodName, returnTypeClass)) {
autoSpy[methodName] = createPromiseSpyFunction(spyMethod);
}
else if (doesMethodReturnObservable(providedObservableMethodNames, methodName, returnTypeClass)) {
autoSpy[methodName] = createObservableSpyFunction(spyMethod);
}
else {
autoSpy[methodName] = spyMethod;
}
autoSpy[methodName] = createSpyFunction(methodName);
});

@@ -32,18 +54,21 @@ return autoSpy;

exports.createSpyFromClass = createSpyFromClass;
function createObservableSpyFunction(spyFunction) {
var subject = new rxjs_1.ReplaySubject(1);
spyFunction.and.returnValue(subject);
spyFunction.and.nextWith = function nextWith(value) {
subject.next(value);
function createSpyFunction(name) {
var spyFunction = jasmine.createSpy(name);
var calledWithObject = {
calledWithMethodWasCalled: false,
shouldThrow: false,
calledWithMap: new Map()
};
spyFunction.and.nextOneTimeWith = function nextOneTimeWith(value) {
subject.next(value);
subject.complete();
var valueContainer = {
value: undefined
};
spyFunction.and.throwWith = function throwWith(value) {
subject.error(value);
};
spyFunction.and.complete = function complete() {
subject.complete();
};
promises_spy_utils_1.promisifySpyFunction(spyFunction, valueContainer);
observable_spy_utils_1.observablifySpyFunction(spyFunction, valueContainer);
spyFunction.and.callFake(function () {
var actualArgs = [];
for (var _i = 0; _i < arguments.length; _i++) {
actualArgs[_i] = arguments[_i];
}
return spyFunctionCallFakeImplementation(calledWithObject, valueContainer, actualArgs);
});
spyFunction.calledWith = function () {

@@ -54,132 +79,45 @@ var calledWithArgs = [];

}
return {
nextWith: function (value) {
spyFunction.and.callFake(function () {
var actualArgs = [];
for (var _i = 0; _i < arguments.length; _i++) {
actualArgs[_i] = arguments[_i];
}
if (!deep_equal_1.default(calledWithArgs, actualArgs)) {
error_handling_1.throwArgumentsError(calledWithArgs, actualArgs);
}
subject.next(value);
return subject;
});
},
nextOneTimeWith: function (value) {
spyFunction.and.callFake(function () {
var actualArgs = [];
for (var _i = 0; _i < arguments.length; _i++) {
actualArgs[_i] = arguments[_i];
}
if (!deep_equal_1.default(calledWithArgs, actualArgs)) {
error_handling_1.throwArgumentsError(calledWithArgs, actualArgs);
}
subject.next(value);
subject.complete();
return subject;
});
},
throwWith: function (value) {
spyFunction.and.callFake(function () {
var actualArgs = [];
for (var _i = 0; _i < arguments.length; _i++) {
actualArgs[_i] = arguments[_i];
}
if (!deep_equal_1.default(calledWithArgs, actualArgs)) {
error_handling_1.throwArgumentsError(calledWithArgs, actualArgs);
}
subject.error(value);
return subject;
});
},
complete: function () {
spyFunction.and.callFake(function () {
var actualArgs = [];
for (var _i = 0; _i < arguments.length; _i++) {
actualArgs[_i] = arguments[_i];
}
if (!deep_equal_1.default(calledWithArgs, actualArgs)) {
error_handling_1.throwArgumentsError(calledWithArgs, actualArgs);
}
subject.complete();
return subject;
});
}
};
calledWithObject.calledWithMethodWasCalled = true;
calledWithObject = addSyncHandlingToCalledWith(calledWithObject, calledWithArgs);
calledWithObject = promises_spy_utils_1.addPromiseHandlingToCalledWith(calledWithObject, calledWithArgs);
calledWithObject = observable_spy_utils_1.addObservableHandlingToCalledWith(calledWithObject, calledWithArgs);
return calledWithObject;
};
return spyFunction;
}
function createPromiseSpyFunction(spyFunction) {
spyFunction.and.returnValue(new Promise(function (resolveWith, rejectWith) {
spyFunction.and.resolveWith = resolveWith;
spyFunction.and.rejectWith = rejectWith;
}));
spyFunction.calledWith = function () {
var calledWithArgs = [];
for (var _i = 0; _i < arguments.length; _i++) {
calledWithArgs[_i] = arguments[_i];
function spyFunctionCallFakeImplementation(calledWithObject, valueContainer, actualArgs) {
var e_1, _a;
if (calledWithObject.calledWithMethodWasCalled) {
try {
for (var _b = __values(calledWithObject.calledWithMap.keys()), _c = _b.next(); !_c.done; _c = _b.next()) {
var storedCalledWithArgs = _c.value;
if (deep_equal_1.default(storedCalledWithArgs, actualArgs)) {
return calledWithObject.calledWithMap.get(storedCalledWithArgs);
}
}
}
return {
resolveWith: function (value) {
spyFunction.and.callFake(function () {
var actualArgs = [];
for (var _i = 0; _i < arguments.length; _i++) {
actualArgs[_i] = arguments[_i];
}
if (!deep_equal_1.default(calledWithArgs, actualArgs)) {
error_handling_1.throwArgumentsError(calledWithArgs, actualArgs);
}
return Promise.resolve(value);
});
},
rejectWith: function (value) {
spyFunction.and.callFake(function () {
var actualArgs = [];
for (var _i = 0; _i < arguments.length; _i++) {
actualArgs[_i] = arguments[_i];
}
if (!deep_equal_1.default(calledWithArgs, actualArgs)) {
error_handling_1.throwArgumentsError(calledWithArgs, actualArgs);
}
return Promise.reject(value);
});
catch (e_1_1) { e_1 = { error: e_1_1 }; }
finally {
try {
if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
}
};
};
return spyFunction;
finally { if (e_1) throw e_1.error; }
}
if (calledWithObject.shouldThrow) {
error_handling_1.throwArgumentsError(actualArgs);
}
}
return valueContainer.value;
}
function createSpyFunction(name) {
var spyFunction = jasmine.createSpy(name);
spyFunction.calledWith = function () {
var calledWithArgs = [];
for (var _i = 0; _i < arguments.length; _i++) {
calledWithArgs[_i] = arguments[_i];
}
function addSyncHandlingToCalledWith(calledWithObject, calledWithArgs) {
calledWithObject.returnValue = function (value) {
calledWithObject.calledWithMap.set(calledWithArgs, value);
return {
returnValue: function (value) {
spyFunction.and.callFake(function () {
var actualArgs = [];
for (var _i = 0; _i < arguments.length; _i++) {
actualArgs[_i] = arguments[_i];
}
if (!deep_equal_1.default(calledWithArgs, actualArgs)) {
error_handling_1.throwArgumentsError(calledWithArgs, actualArgs);
}
return value;
});
throwOnMismatch: function () {
calledWithObject.shouldThrow = true;
}
};
};
return spyFunction;
return calledWithObject;
}
function doesMethodReturnPromise(promiseMethodsList, methodName, returnTypeClass) {
return ((promiseMethodsList && promiseMethodsList.indexOf(methodName) !== -1) ||
returnTypeClass === Promise);
}
function doesMethodReturnObservable(observableMethodsList, methodName, returnTypeClass) {
return ((observableMethodsList && observableMethodsList.indexOf(methodName) !== -1) ||
returnTypeClass === rxjs_1.Observable ||
(returnTypeClass && returnTypeClass.prototype instanceof rxjs_1.Observable));
}
function getAllMethodNames(obj) {

@@ -195,5 +133,4 @@ var methods = [];

}
// .filter(methodName => typeof proto[methodName] == 'function')
return methods;
}
//# sourceMappingURL=create-spy-from-class.js.map

@@ -1,3 +0,3 @@

export * from './spy-types';
export * from './spy.types';
export { AsyncSpyable } from './async-spyable-decorator';
export { createSpyFromClass } from './create-spy-from-class';

@@ -11,2 +11,3 @@ {

"sourceMap": true,
"downlevelIteration": true,
"lib": ["es2015", "es2016"],

@@ -13,0 +14,0 @@ "pretty": true,

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