jasmine-marbles
Advanced tools
Comparing version 0.9.0 to 0.10.0-beta.0
(function (global, factory) { | ||
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('rxjs'), require('rxjs/testing'), require('lodash')) : | ||
typeof define === 'function' && define.amd ? define(['exports', 'rxjs', 'rxjs/testing', 'lodash'], factory) : | ||
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global['jasmine-marbles'] = {}, global.Rx, global.Rx, global._)); | ||
}(this, (function (exports, rxjs, testing, lodash) { 'use strict'; | ||
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('rxjs/testing'), require('lodash'), require('rxjs')) : | ||
typeof define === 'function' && define.amd ? define(['exports', 'rxjs/testing', 'lodash', 'rxjs'], factory) : | ||
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global['jasmine-marbles'] = {}, global.Rx, global._, global.Rx)); | ||
}(this, (function (exports, testing, lodash, rxjs) { 'use strict'; | ||
@@ -106,2 +106,36 @@ /* istanbul ignore file */ | ||
function mapSymbolsToNotifications(marbles, messagesArg) { | ||
const messages = messagesArg.slice(); | ||
const result = {}; | ||
for (let i = 0; i < marbles.length; i++) { | ||
const symbol = marbles[i]; | ||
switch (symbol) { | ||
case ' ': | ||
case '-': | ||
case '^': | ||
case '(': | ||
case ')': | ||
break; | ||
case '#': | ||
case '|': { | ||
messages.shift(); | ||
break; | ||
} | ||
default: { | ||
if ((symbol.match(/^[0-9]$/) && i === 0) || marbles[i - 1] === ' ') { | ||
const buffer = marbles.slice(i); | ||
const match = buffer.match(/^([0-9]+(?:\.[0-9]+)?)(ms|s|m) /); | ||
if (match) { | ||
i += match[0].length - 1; | ||
} | ||
break; | ||
} | ||
const message = messages.shift(); | ||
result[symbol] = message.notification; | ||
} | ||
} | ||
} | ||
return result; | ||
} | ||
function unparseMarble(result, assignSymbolFn) { | ||
@@ -156,45 +190,2 @@ const FRAME_TIME_FACTOR = 10; // need to be up to date with `TestScheduler.frameTimeFactor` | ||
function mapSymbolsToNotifications(marbles, messagesArg) { | ||
const messages = messagesArg.slice(); | ||
const result = {}; | ||
for (let i = 0; i < marbles.length; i++) { | ||
const symbol = marbles[i]; | ||
switch (symbol) { | ||
case ' ': | ||
case '-': | ||
case '^': | ||
case '(': | ||
case ')': | ||
break; | ||
case '#': | ||
case '|': { | ||
messages.shift(); | ||
break; | ||
} | ||
default: { | ||
if ((symbol.match(/^[0-9]$/) && i === 0) || marbles[i - 1] === ' ') { | ||
const buffer = marbles.slice(i); | ||
const match = buffer.match(/^([0-9]+(?:\.[0-9]+)?)(ms|s|m) /); | ||
if (match) { | ||
i += match[0].length - 1; | ||
} | ||
break; | ||
} | ||
const message = messages.shift(); | ||
result[symbol] = message.notification; | ||
} | ||
} | ||
} | ||
return result; | ||
} | ||
function hot(marbles, values, error) { | ||
return new TestHotObservable(marbles.trim(), values, error); | ||
} | ||
function cold(marbles, values, error) { | ||
return new TestColdObservable(marbles.trim(), values, error); | ||
} | ||
function time(marbles) { | ||
return getTestScheduler().createTime(marbles.trim()); | ||
} | ||
/* | ||
@@ -242,67 +233,59 @@ * Based on source code found in rxjs library | ||
} | ||
function addMatchers() { | ||
jasmine.addMatchers({ | ||
toHaveSubscriptions: () => ({ | ||
compare: function (actual, marbles) { | ||
const marblesArray = typeof marbles === 'string' ? [marbles] : marbles; | ||
const results = marblesArray.map((marbles) => testing.TestScheduler.parseMarblesAsSubscriptions(marbles)); | ||
expect(results).toEqual(actual.getSubscriptions()); | ||
return { pass: true }; | ||
function toHaveSubscriptionsComparer(actual, marbles) { | ||
const marblesArray = typeof marbles === 'string' ? [marbles] : marbles; | ||
const results = marblesArray.map((marbles) => testing.TestScheduler.parseMarblesAsSubscriptions(marbles)); | ||
expect(results).toEqual(actual.getSubscriptions()); | ||
return { pass: true, message: () => '' }; | ||
} | ||
function toBeObservableComparer(actual, fixture) { | ||
const results = []; | ||
const scheduler = getTestScheduler(); | ||
scheduler.schedule(() => { | ||
actual.subscribe({ | ||
next: (x) => { | ||
let value = x; | ||
// Support Observable-of-Observables | ||
if (x instanceof rxjs.Observable) { | ||
value = materializeInnerObservable(value, scheduler.frame); | ||
} | ||
results.push({ | ||
frame: scheduler.frame, | ||
notification: { | ||
kind: 'N', | ||
value, | ||
error: undefined, | ||
}, | ||
}); | ||
}, | ||
}), | ||
toBeObservable: (_utils, _equalityTester) => ({ | ||
compare: function (actual, fixture) { | ||
const results = []; | ||
const scheduler = getTestScheduler(); | ||
scheduler.schedule(() => { | ||
actual.subscribe({ | ||
next: (x) => { | ||
let value = x; | ||
// Support Observable-of-Observables | ||
if (x instanceof rxjs.Observable) { | ||
value = materializeInnerObservable(value, scheduler.frame); | ||
} | ||
results.push({ | ||
frame: scheduler.frame, | ||
notification: { | ||
kind: 'N', | ||
value, | ||
error: undefined, | ||
}, | ||
}); | ||
}, | ||
error: (error) => { | ||
results.push({ | ||
frame: scheduler.frame, | ||
notification: { | ||
kind: 'E', | ||
value: undefined, | ||
error, | ||
}, | ||
}); | ||
}, | ||
complete: () => { | ||
results.push({ | ||
frame: scheduler.frame, | ||
notification: { | ||
kind: 'C', | ||
value: undefined, | ||
error: undefined, | ||
}, | ||
}); | ||
}, | ||
}); | ||
error: (error) => { | ||
results.push({ | ||
frame: scheduler.frame, | ||
notification: { | ||
kind: 'E', | ||
value: undefined, | ||
error, | ||
}, | ||
}); | ||
scheduler.flush(); | ||
const expected = testing.TestScheduler.parseMarbles(fixture.marbles, fixture.values, fixture.error, true, true); | ||
if (lodash.isEqual(results, expected)) { | ||
return { pass: true }; | ||
} | ||
const mapNotificationToSymbol = buildNotificationToSymbolMapper(fixture.marbles, expected, lodash.isEqual); | ||
const receivedMarble = unparseMarble(results, mapNotificationToSymbol); | ||
const message = formatMessage(fixture.marbles, expected, receivedMarble, results); | ||
return { pass: false, message }; | ||
}, | ||
}), | ||
complete: () => { | ||
results.push({ | ||
frame: scheduler.frame, | ||
notification: { | ||
kind: 'C', | ||
value: undefined, | ||
error: undefined, | ||
}, | ||
}); | ||
}, | ||
}); | ||
}); | ||
scheduler.flush(); | ||
const expected = testing.TestScheduler.parseMarbles(fixture.marbles, fixture.values, fixture.error, true, true); | ||
if (lodash.isEqual(results, expected)) { | ||
return { pass: true, message: () => '' }; | ||
} | ||
const mapNotificationToSymbol = buildNotificationToSymbolMapper(fixture.marbles, expected, lodash.isEqual); | ||
const receivedMarble = unparseMarble(results, mapNotificationToSymbol); | ||
const message = formatMessage(fixture.marbles, expected, receivedMarble, results); | ||
return { pass: false, message: () => message }; | ||
} | ||
@@ -328,2 +311,36 @@ function buildNotificationToSymbolMapper(expectedMarbles, expectedMessages, equalityFn) { | ||
} | ||
function hot(marbles, values, error) { | ||
return new TestHotObservable(marbles.trim(), values, error); | ||
} | ||
function cold(marbles, values, error) { | ||
return new TestColdObservable(marbles.trim(), values, error); | ||
} | ||
function time(marbles) { | ||
return getTestScheduler().createTime(marbles.trim()); | ||
} | ||
function addMatchers() { | ||
/** | ||
* expect.extend is an API exposed by jest-circus, | ||
* the default runner as of Jest v27. If that method | ||
* is not available, assume we're in a Jasmine test | ||
* environment. | ||
*/ | ||
if (!expect.extend) { | ||
jasmine.addMatchers({ | ||
toHaveSubscriptions: () => ({ | ||
compare: toHaveSubscriptionsComparer, | ||
}), | ||
toBeObservable: (_utils, _equalityTester) => ({ | ||
compare: toBeObservableComparer, | ||
}), | ||
}); | ||
} | ||
else { | ||
expect.extend({ | ||
toHaveSubscriptions: toHaveSubscriptionsComparer, | ||
toBeObservable: toBeObservableComparer, | ||
}); | ||
} | ||
} | ||
function setupEnvironment() { | ||
@@ -330,0 +347,0 @@ beforeAll(() => addMatchers()); |
154
es6/index.js
@@ -1,8 +0,4 @@ | ||
import { Observable, } from 'rxjs'; | ||
import { TestScheduler } from 'rxjs/testing'; | ||
import { isEqual } from 'lodash'; | ||
import { getTestScheduler, initTestScheduler, resetTestScheduler, } from './src/scheduler'; | ||
import { TestColdObservable, TestHotObservable, } from './src/test-observables'; | ||
import { unparseMarble } from './src/marble-unparser'; | ||
import { mapSymbolsToNotifications } from './src/map-symbols-to-notifications'; | ||
import { toHaveSubscriptionsComparer, toBeObservableComparer, } from './src/utils'; | ||
export { getTestScheduler, initTestScheduler, resetTestScheduler, } from './src/scheduler'; | ||
@@ -18,130 +14,26 @@ export function hot(marbles, values, error) { | ||
} | ||
/* | ||
* Based on source code found in rxjs library | ||
* https://github.com/ReactiveX/rxjs/blob/master/src/testing/TestScheduler.ts | ||
* | ||
*/ | ||
function materializeInnerObservable(observable, outerFrame) { | ||
const messages = []; | ||
const scheduler = getTestScheduler(); | ||
observable.subscribe({ | ||
next: (value) => { | ||
messages.push({ | ||
frame: scheduler.frame - outerFrame, | ||
notification: { | ||
kind: 'N', | ||
value, | ||
error: undefined, | ||
}, | ||
}); | ||
}, | ||
error: (error) => { | ||
messages.push({ | ||
frame: scheduler.frame - outerFrame, | ||
notification: { | ||
kind: 'E', | ||
value: undefined, | ||
error, | ||
}, | ||
}); | ||
}, | ||
complete: () => { | ||
messages.push({ | ||
frame: scheduler.frame - outerFrame, | ||
notification: { | ||
kind: 'C', | ||
value: undefined, | ||
error: undefined, | ||
}, | ||
}); | ||
}, | ||
}); | ||
return messages; | ||
} | ||
export function addMatchers() { | ||
jasmine.addMatchers({ | ||
toHaveSubscriptions: () => ({ | ||
compare: function (actual, marbles) { | ||
const marblesArray = typeof marbles === 'string' ? [marbles] : marbles; | ||
const results = marblesArray.map((marbles) => TestScheduler.parseMarblesAsSubscriptions(marbles)); | ||
expect(results).toEqual(actual.getSubscriptions()); | ||
return { pass: true }; | ||
}, | ||
}), | ||
toBeObservable: (_utils, _equalityTester) => ({ | ||
compare: function (actual, fixture) { | ||
const results = []; | ||
let subscription; | ||
const scheduler = getTestScheduler(); | ||
scheduler.schedule(() => { | ||
subscription = actual.subscribe({ | ||
next: (x) => { | ||
let value = x; | ||
// Support Observable-of-Observables | ||
if (x instanceof Observable) { | ||
value = materializeInnerObservable(value, scheduler.frame); | ||
} | ||
results.push({ | ||
frame: scheduler.frame, | ||
notification: { | ||
kind: 'N', | ||
value, | ||
error: undefined, | ||
}, | ||
}); | ||
}, | ||
error: (error) => { | ||
results.push({ | ||
frame: scheduler.frame, | ||
notification: { | ||
kind: 'E', | ||
value: undefined, | ||
error, | ||
}, | ||
}); | ||
}, | ||
complete: () => { | ||
results.push({ | ||
frame: scheduler.frame, | ||
notification: { | ||
kind: 'C', | ||
value: undefined, | ||
error: undefined, | ||
}, | ||
}); | ||
}, | ||
}); | ||
}); | ||
scheduler.flush(); | ||
const expected = TestScheduler.parseMarbles(fixture.marbles, fixture.values, fixture.error, true, true); | ||
if (isEqual(results, expected)) { | ||
return { pass: true }; | ||
} | ||
const mapNotificationToSymbol = buildNotificationToSymbolMapper(fixture.marbles, expected, isEqual); | ||
const receivedMarble = unparseMarble(results, mapNotificationToSymbol); | ||
const message = formatMessage(fixture.marbles, expected, receivedMarble, results); | ||
return { pass: false, message }; | ||
}, | ||
}), | ||
}); | ||
/** | ||
* expect.extend is an API exposed by jest-circus, | ||
* the default runner as of Jest v27. If that method | ||
* is not available, assume we're in a Jasmine test | ||
* environment. | ||
*/ | ||
if (!expect.extend) { | ||
jasmine.addMatchers({ | ||
toHaveSubscriptions: () => ({ | ||
compare: toHaveSubscriptionsComparer, | ||
}), | ||
toBeObservable: (_utils, _equalityTester) => ({ | ||
compare: toBeObservableComparer, | ||
}), | ||
}); | ||
} | ||
else { | ||
expect.extend({ | ||
toHaveSubscriptions: toHaveSubscriptionsComparer, | ||
toBeObservable: toBeObservableComparer, | ||
}); | ||
} | ||
} | ||
function buildNotificationToSymbolMapper(expectedMarbles, expectedMessages, equalityFn) { | ||
const symbolsToNotificationsMap = mapSymbolsToNotifications(expectedMarbles, expectedMessages); | ||
return (notification) => { | ||
const mapped = Object.keys(symbolsToNotificationsMap).find((key) => equalityFn(symbolsToNotificationsMap[key], notification)); | ||
return mapped || '?'; | ||
}; | ||
} | ||
function formatMessage(expectedMarbles, expectedMessages, receivedMarbles, receivedMessages) { | ||
return ` | ||
Expected: ${expectedMarbles}, | ||
Received: ${receivedMarbles}, | ||
Expected: | ||
${JSON.stringify(expectedMessages)} | ||
Received: | ||
${JSON.stringify(receivedMessages)}, | ||
`; | ||
} | ||
export function setupEnvironment() { | ||
@@ -148,0 +40,0 @@ beforeAll(() => addMatchers()); |
149
index.js
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.setupEnvironment = exports.addMatchers = exports.time = exports.cold = exports.hot = exports.resetTestScheduler = exports.initTestScheduler = exports.getTestScheduler = void 0; | ||
var rxjs_1 = require("rxjs"); | ||
var testing_1 = require("rxjs/testing"); | ||
var lodash_1 = require("lodash"); | ||
var scheduler_1 = require("./src/scheduler"); | ||
var test_observables_1 = require("./src/test-observables"); | ||
var marble_unparser_1 = require("./src/marble-unparser"); | ||
var map_symbols_to_notifications_1 = require("./src/map-symbols-to-notifications"); | ||
var utils_1 = require("./src/utils"); | ||
var scheduler_2 = require("./src/scheduler"); | ||
@@ -27,126 +23,27 @@ Object.defineProperty(exports, "getTestScheduler", { enumerable: true, get: function () { return scheduler_2.getTestScheduler; } }); | ||
exports.time = time; | ||
/* | ||
* Based on source code found in rxjs library | ||
* https://github.com/ReactiveX/rxjs/blob/master/src/testing/TestScheduler.ts | ||
* | ||
*/ | ||
function materializeInnerObservable(observable, outerFrame) { | ||
var messages = []; | ||
var scheduler = scheduler_1.getTestScheduler(); | ||
observable.subscribe({ | ||
next: function (value) { | ||
messages.push({ | ||
frame: scheduler.frame - outerFrame, | ||
notification: { | ||
kind: 'N', | ||
value: value, | ||
error: undefined, | ||
}, | ||
}); | ||
}, | ||
error: function (error) { | ||
messages.push({ | ||
frame: scheduler.frame - outerFrame, | ||
notification: { | ||
kind: 'E', | ||
value: undefined, | ||
error: error, | ||
}, | ||
}); | ||
}, | ||
complete: function () { | ||
messages.push({ | ||
frame: scheduler.frame - outerFrame, | ||
notification: { | ||
kind: 'C', | ||
value: undefined, | ||
error: undefined, | ||
}, | ||
}); | ||
}, | ||
}); | ||
return messages; | ||
} | ||
function addMatchers() { | ||
jasmine.addMatchers({ | ||
toHaveSubscriptions: function () { return ({ | ||
compare: function (actual, marbles) { | ||
var marblesArray = typeof marbles === 'string' ? [marbles] : marbles; | ||
var results = marblesArray.map(function (marbles) { | ||
return testing_1.TestScheduler.parseMarblesAsSubscriptions(marbles); | ||
}); | ||
expect(results).toEqual(actual.getSubscriptions()); | ||
return { pass: true }; | ||
}, | ||
}); }, | ||
toBeObservable: function (_utils, _equalityTester) { return ({ | ||
compare: function (actual, fixture) { | ||
var results = []; | ||
var subscription; | ||
var scheduler = scheduler_1.getTestScheduler(); | ||
scheduler.schedule(function () { | ||
subscription = actual.subscribe({ | ||
next: function (x) { | ||
var value = x; | ||
// Support Observable-of-Observables | ||
if (x instanceof rxjs_1.Observable) { | ||
value = materializeInnerObservable(value, scheduler.frame); | ||
} | ||
results.push({ | ||
frame: scheduler.frame, | ||
notification: { | ||
kind: 'N', | ||
value: value, | ||
error: undefined, | ||
}, | ||
}); | ||
}, | ||
error: function (error) { | ||
results.push({ | ||
frame: scheduler.frame, | ||
notification: { | ||
kind: 'E', | ||
value: undefined, | ||
error: error, | ||
}, | ||
}); | ||
}, | ||
complete: function () { | ||
results.push({ | ||
frame: scheduler.frame, | ||
notification: { | ||
kind: 'C', | ||
value: undefined, | ||
error: undefined, | ||
}, | ||
}); | ||
}, | ||
}); | ||
}); | ||
scheduler.flush(); | ||
var expected = testing_1.TestScheduler.parseMarbles(fixture.marbles, fixture.values, fixture.error, true, true); | ||
if (lodash_1.isEqual(results, expected)) { | ||
return { pass: true }; | ||
} | ||
var mapNotificationToSymbol = buildNotificationToSymbolMapper(fixture.marbles, expected, lodash_1.isEqual); | ||
var receivedMarble = marble_unparser_1.unparseMarble(results, mapNotificationToSymbol); | ||
var message = formatMessage(fixture.marbles, expected, receivedMarble, results); | ||
return { pass: false, message: message }; | ||
}, | ||
}); }, | ||
}); | ||
/** | ||
* expect.extend is an API exposed by jest-circus, | ||
* the default runner as of Jest v27. If that method | ||
* is not available, assume we're in a Jasmine test | ||
* environment. | ||
*/ | ||
if (!expect.extend) { | ||
jasmine.addMatchers({ | ||
toHaveSubscriptions: function () { return ({ | ||
compare: utils_1.toHaveSubscriptionsComparer, | ||
}); }, | ||
toBeObservable: function (_utils, _equalityTester) { return ({ | ||
compare: utils_1.toBeObservableComparer, | ||
}); }, | ||
}); | ||
} | ||
else { | ||
expect.extend({ | ||
toHaveSubscriptions: utils_1.toHaveSubscriptionsComparer, | ||
toBeObservable: utils_1.toBeObservableComparer, | ||
}); | ||
} | ||
} | ||
exports.addMatchers = addMatchers; | ||
function buildNotificationToSymbolMapper(expectedMarbles, expectedMessages, equalityFn) { | ||
var symbolsToNotificationsMap = map_symbols_to_notifications_1.mapSymbolsToNotifications(expectedMarbles, expectedMessages); | ||
return function (notification) { | ||
var mapped = Object.keys(symbolsToNotificationsMap).find(function (key) { | ||
return equalityFn(symbolsToNotificationsMap[key], notification); | ||
}); | ||
return mapped || '?'; | ||
}; | ||
} | ||
function formatMessage(expectedMarbles, expectedMessages, receivedMarbles, receivedMessages) { | ||
return "\n Expected: " + expectedMarbles + ",\n Received: " + receivedMarbles + ",\n \n Expected:\n " + JSON.stringify(expectedMessages) + "\n \n Received:\n " + JSON.stringify(receivedMessages) + ",\n "; | ||
} | ||
function setupEnvironment() { | ||
@@ -153,0 +50,0 @@ beforeAll(function () { return addMatchers(); }); |
@@ -10,3 +10,3 @@ { | ||
], | ||
"version": "0.9.0", | ||
"version": "0.10.0-beta.0", | ||
"module": "index.js", | ||
@@ -31,4 +31,3 @@ "es2015": "es6/index.js", | ||
"build:umd": "npm run build:es6 && rollup -c rollup.config.js", | ||
"test:unit": "node ./tests.js", | ||
"test": "nyc yarn run test:unit", | ||
"test": "jest", | ||
"precommit": "yarn run prettier", | ||
@@ -55,5 +54,9 @@ "prettier": "prettier --parser typescript --single-quote --trailing-comma all --write \"./**/*.ts\"", | ||
"devDependencies": { | ||
"@types/jasmine": "^3.7.4", | ||
"@babel/core": "^7.14.6", | ||
"@babel/preset-env": "^7.14.7", | ||
"@babel/preset-typescript": "^7.14.5", | ||
"@types/jest": "^26.0.23", | ||
"@types/lodash": "^4.14.106", | ||
"@types/node": "^14.17.0", | ||
"babel-jest": "^27.0.6", | ||
"conventional-changelog": "^3.1.12", | ||
@@ -64,2 +67,4 @@ "conventional-changelog-cli": "^2.0.25", | ||
"jasmine": "^3.7.0", | ||
"jest": "^27.0.6", | ||
"jest-jasmine2": "^27.0.6", | ||
"nyc": "^15.1.0", | ||
@@ -66,0 +71,0 @@ "prettier": "^2.3.0", |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
146707
52
1624
21