Skip to content

Commit d8220f8

Browse files
committed
feat(sandbox): support 7.x
- BREAKING CHANGE: supports rxjs >= 7
1 parent 3fc5a9f commit d8220f8

12 files changed

+134
-63
lines changed

spec/marbles/parseObservableMarble-spec.ts

+11-4
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,16 @@
11
import { expect } from 'chai';
2-
import { ColdObservable } from 'rxjs/internal/testing/ColdObservable';
32
import { parseObservableMarble } from '../../src/marbles/parseObservableMarble';
43
import { complete, error, next } from '../../src/message/TestMessage';
54
import { TestScheduler } from '../../src/scheduler/TestScheduler';
65

6+
//tslint:disable no-var-requires no-require-imports
7+
const {
8+
ColdObservable,
9+
}: {
10+
ColdObservable: typeof import('rxjs/dist/types/internal/testing/ColdObservable').ColdObservable;
11+
} = require('rxjs/dist/cjs/internal/testing/ColdObservable');
12+
//tslint:enable no-var-requires no-require-imports
13+
714
describe('parseObservableMarble', () => {
815
it('should not allow unsubscription token', () => {
916
const marble = '----!';
@@ -52,7 +59,7 @@ describe('parseObservableMarble', () => {
5259

5360
const customValue = {
5461
a: new ColdObservable(aMessages, null as any),
55-
b: new ColdObservable(bMessages, null as any)
62+
b: new ColdObservable(bMessages, null as any),
5663
};
5764

5865
const messages = parseObservableMarble(marble, customValue, null, true);
@@ -68,7 +75,7 @@ describe('parseObservableMarble', () => {
6875

6976
const customValue = {
7077
a: new ColdObservable<string>(aMessages, null as any),
71-
b: new ColdObservable<string>(bMessages, null as any)
78+
b: new ColdObservable<string>(bMessages, null as any),
7279
};
7380

7481
const messages = parseObservableMarble(marble, customValue, null, false);
@@ -107,7 +114,7 @@ describe('parseObservableMarble', () => {
107114
it('should parse value literal with custom value', () => {
108115
const marble = '----a----';
109116
const customValue = {
110-
a: 'qwerty'
117+
a: 'qwerty',
111118
};
112119

113120
const messages = parseObservableMarble(marble, customValue);

spec/scheduler/TestScheduler-spec.ts

+18-3
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,27 @@
11
import { expect } from 'chai';
2-
import { AsyncAction } from 'rxjs/internal/scheduler/AsyncAction';
3-
import { ColdObservable } from 'rxjs/internal/testing/ColdObservable';
4-
import { HotObservable } from 'rxjs/internal/testing/HotObservable';
52
import { mapTo, windowCount } from 'rxjs/operators';
63
import { parseObservableMarble } from '../../src/marbles/parseObservableMarble';
74
import { complete, error, next, subscribe, TestMessage } from '../../src/message/TestMessage';
85
import { TestScheduler } from '../../src/scheduler/TestScheduler';
96

7+
//tslint:disable no-var-requires no-require-imports
8+
const {
9+
AsyncAction,
10+
}: {
11+
AsyncAction: typeof import('rxjs/dist/types/internal/scheduler/AsyncAction').AsyncAction;
12+
} = require('rxjs/dist/cjs/internal/scheduler/AsyncAction');
13+
const {
14+
ColdObservable,
15+
}: {
16+
ColdObservable: typeof import('rxjs/dist/types/internal/testing/ColdObservable').ColdObservable;
17+
} = require('rxjs/dist/cjs/internal/testing/ColdObservable');
18+
const {
19+
HotObservable,
20+
}: {
21+
HotObservable: typeof import('rxjs/dist/types/internal/testing/HotObservable').HotObservable;
22+
} = require('rxjs/dist/cjs/internal/testing/HotObservable');
23+
//tslint:enable no-var-requires no-require-imports
24+
1025
describe('TestScheduler', () => {
1126
describe('hotObservable', () => {
1227
it('should create hot observable via TestMessage', () => {

src/RxSandbox.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { SubscriptionLog } from 'rxjs/internal/testing/SubscriptionLog';
1+
import { SubscriptionLog } from 'rxjs/dist/types/internal/testing/SubscriptionLog';
22
import { TestMessage } from './message/TestMessage';
33
import { RxSandboxInstance } from './RxSandboxInstance';
44

src/RxSandboxInstance.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { SubscriptionLog } from 'rxjs/internal/testing/SubscriptionLog';
1+
import { SubscriptionLog } from 'rxjs/dist/types/internal/testing/SubscriptionLog';
22
import { TestMessage } from './message/TestMessage';
33
import { TestScheduler } from './scheduler/TestScheduler';
44

@@ -59,5 +59,5 @@ export {
5959
getObservableMessage,
6060
expectedObservable,
6161
expectedSubscription,
62-
RxSandboxInstance
62+
RxSandboxInstance,
6363
};

src/assert/constructSubscriptionMarble.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { SubscriptionLog } from 'rxjs/internal/testing/SubscriptionLog';
1+
import { SubscriptionLog } from 'rxjs/dist/types/internal/testing/SubscriptionLog';
22
import { ObservableMarbleToken } from '../marbles/ObservableMarbleToken';
33
import { SubscriptionMarbleToken } from '../marbles/SubscriptionMarbleToken';
44

@@ -9,7 +9,7 @@ const MAX_FRAME_LENGTH = 30;
99
*/
1010
const constructSubscriptionMarble = ({
1111
subscribedFrame,
12-
unsubscribedFrame
12+
unsubscribedFrame,
1313
}: SubscriptionLog): { marbleString: string; frameString: string } => {
1414
const marble: Array<ObservableMarbleToken | SubscriptionMarbleToken> = Array.from(Array(MAX_FRAME_LENGTH + 1)).map(
1515
() => ObservableMarbleToken.TIMEFRAME

src/assert/marbleAssert.ts

+15-9
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,18 @@
11
import { toEqual } from 'jest-matchers/build/matchers';
2-
import { SubscriptionLog } from 'rxjs/internal/testing/SubscriptionLog';
32
import { TestMessage } from '../message/TestMessage';
43
import { constructObservableMarble } from './constructObservableMarble';
54
import { constructSubscriptionMarble } from './constructSubscriptionMarble';
6-
const { matcherHint, printExpected, printReceived } = require('jest-matcher-utils'); //tslint:disable-line:no-require-imports no-var-requires
5+
6+
//tslint:disable:no-require-imports no-var-requires
7+
const { matcherHint, printExpected, printReceived } = require('jest-matcher-utils');
8+
const { SubscriptionLog } = require('rxjs/dist/cjs/internal/testing/SubscriptionLog');
9+
//tslint:enbale:no-require-imports no-var-requires
710

811
const toEqualAssert = toEqual.bind({ expand: false });
912

10-
const subscriptionMarbleAssert = (source: Array<SubscriptionLog>) => (expected: Array<SubscriptionLog>) => {
13+
const subscriptionMarbleAssert = (
14+
source: Array<import('rxjs/dist/types/internal/testing/SubscriptionLog').SubscriptionLog>
15+
) => (expected: Array<import('rxjs/dist/types/internal/testing/SubscriptionLog').SubscriptionLog>) => {
1116
const asserted = toEqualAssert(source, expected);
1217

1318
if (!asserted.pass) {
@@ -52,6 +57,7 @@ const observableMarbleAssert = <T = string>(source: Array<TestMessage<T>> | Read
5257

5358
//polymorphic picks up observablemarbleassert first when empty array, manually falls back
5459
//if expected is subscriptionlog
60+
//tslint:disable-next-line no-var-requires no-require-imports
5561
if ((expected as any).every((x: any) => x instanceof SubscriptionLog)) {
5662
subscriptionMarbleAssert(source as any)(expected as any);
5763
return;
@@ -83,11 +89,11 @@ function marbleAssert<T = string>(
8389
};
8490
};
8591
function marbleAssert<T = void>(
86-
source: Array<SubscriptionLog>
87-
): { to: { equal(expected: Array<SubscriptionLog>): void } };
92+
source: Array<import('rxjs/dist/types/internal/testing/SubscriptionLog').SubscriptionLog>
93+
): { to: { equal(expected: Array<import('rxjs/dist/types/internal/testing/SubscriptionLog').SubscriptionLog>): void } };
8894
function marbleAssert<T = string>(
8995
source:
90-
| Array<SubscriptionLog>
96+
| Array<import('rxjs/dist/types/internal/testing/SubscriptionLog').SubscriptionLog>
9197
| Array<TestMessage<T | Array<TestMessage<T>>>>
9298
| Readonly<Array<TestMessage<T | Array<TestMessage<T>>>>>
9399
): { to: { equal(expected: object): void } } {
@@ -96,12 +102,12 @@ function marbleAssert<T = string>(
96102
throw new Error('Cannot assert non array');
97103
}
98104

99-
const isSourceSubscription = source.length > 0 && (source as Array<any>).every(v => v instanceof SubscriptionLog);
105+
const isSourceSubscription = source.length > 0 && (source as Array<any>).every((v) => v instanceof SubscriptionLog);
100106

101107
return {
102108
to: {
103-
equal: isSourceSubscription ? subscriptionMarbleAssert(source as any) : observableMarbleAssert(source as any)
104-
}
109+
equal: isSourceSubscription ? subscriptionMarbleAssert(source as any) : observableMarbleAssert(source as any),
110+
},
105111
};
106112
}
107113

src/index.ts

+3-11
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,3 @@
1-
import { Observable } from 'rxjs';
2-
import { ColdObservable } from 'rxjs/internal/testing/ColdObservable';
3-
import { HotObservable } from 'rxjs/internal/testing/HotObservable';
41
import { marbleAssert } from './assert/marbleAssert';
52
import { parseObservableMarble } from './marbles/parseObservableMarble';
63
import { parseSubscriptionMarble } from './marbles/parseSubscriptionMarble';
@@ -16,14 +13,9 @@ export {
1613
getObservableMessage,
1714
expectedObservable,
1815
expectedSubscription,
19-
RxSandboxInstance
16+
RxSandboxInstance,
2017
} from './RxSandboxInstance';
2118

22-
//workaround TS4029 by explicitly import types and avoid unused import error
23-
(() => Observable.toString())();
24-
(() => ColdObservable.toString())();
25-
(() => HotObservable.toString())();
26-
2719
type marbleAssertion = typeof marbleAssert;
2820

2921
const rxSandbox: RxSandbox = {
@@ -39,10 +31,10 @@ const rxSandbox: RxSandbox = {
3931
getMessages: scheduler.getMessages.bind(scheduler) as typeof scheduler.getMessages,
4032
e: <T = string>(marble: string, value?: { [key: string]: T } | null, error?: any) =>
4133
parseObservableMarble(marble, value, error, true, frameTimeFactor, frameTimeFactor * maxFrameValue),
42-
s: (marble: string) => parseSubscriptionMarble(marble, frameTimeFactor, frameTimeFactor * maxFrameValue)
34+
s: (marble: string) => parseSubscriptionMarble(marble, frameTimeFactor, frameTimeFactor * maxFrameValue),
4335
};
4436
},
45-
marbleAssert: marbleAssert
37+
marbleAssert: marbleAssert,
4638
};
4739

4840
export { rxSandbox, TestMessage, marbleAssertion, next, error, complete, subscribe };

src/marbles/parseSubscriptionMarble.ts

+10-3
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,27 @@
1-
import { SubscriptionLog } from 'rxjs/internal/testing/SubscriptionLog';
21
import { ObservableMarbleToken } from './ObservableMarbleToken';
32
import { subscriptionTokenParseReducer } from './tokenParseReducer';
43

4+
//tslint:disable no-var-requires no-require-imports
5+
const {
6+
SubscriptionLog,
7+
}: {
8+
SubscriptionLog: typeof import('rxjs/dist/types/internal/testing/SubscriptionLog').SubscriptionLog;
9+
} = require('rxjs/dist/cjs/internal/testing/SubscriptionLog');
10+
//tslint:enable no-var-requires no-require-imports
11+
512
const parseSubscriptionMarble = (marble: string | null, frameTimeFactor: number = 1, maxFrame = 1000) => {
613
if (!marble) {
714
return new SubscriptionLog(Number.POSITIVE_INFINITY);
815
}
916

10-
const marbleTokenArray = Array.from(marble).filter(token => token !== ObservableMarbleToken.NOOP);
17+
const marbleTokenArray = Array.from(marble).filter((token) => token !== ObservableMarbleToken.NOOP);
1118
const value = marbleTokenArray.reduce(subscriptionTokenParseReducer(frameTimeFactor, maxFrame), {
1219
currentTimeFrame: 0,
1320
subscriptionFrame: Number.POSITIVE_INFINITY,
1421
unsubscriptionFrame: Number.POSITIVE_INFINITY,
1522
simultaneousGrouped: false,
1623
expandingTokenCount: 0,
17-
expandingValue: []
24+
expandingValue: [],
1825
});
1926

2027
return value.unsubscriptionFrame === Number.POSITIVE_INFINITY

src/marbles/tokenParseReducer.ts

+9-2
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,15 @@
1-
import { ColdObservable } from 'rxjs/internal/testing/ColdObservable';
21
import { complete, error as e, next, TestMessage } from '../message/TestMessage';
32
import { ObservableMarbleToken } from './ObservableMarbleToken';
43
import { SubscriptionMarbleToken } from './SubscriptionMarbleToken';
54

5+
//tslint:disable no-var-requires no-require-imports
6+
const {
7+
ColdObservable,
8+
}: {
9+
ColdObservable: typeof import('rxjs/dist/types/internal/testing/ColdObservable').ColdObservable;
10+
} = require('rxjs/dist/cjs/internal/testing/ColdObservable');
11+
//tslint:enable no-var-requires no-require-imports
12+
613
/**
714
* @internal
815
* Base accumulator interface for parsing marble diagram.
@@ -219,5 +226,5 @@ export {
219226
ObservableTokenParseAccumulator,
220227
SubscriptionTokenParseAccumulator,
221228
subscriptionTokenParseReducer,
222-
observableTokenParseReducer
229+
observableTokenParseReducer,
223230
};

src/message/TestMessage.ts

+8-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,12 @@
11
import { Notification } from 'rxjs';
2-
import { SubscriptionLog } from 'rxjs/internal/testing/SubscriptionLog';
2+
3+
//tslint:disable no-var-requires no-require-imports
4+
const {
5+
SubscriptionLog,
6+
}: {
7+
SubscriptionLog: typeof import('rxjs/dist/types/internal/testing/SubscriptionLog').SubscriptionLog;
8+
} = require('rxjs/dist/cjs/internal/testing/SubscriptionLog');
9+
//tslint:enable no-var-requires no-require-imports
310

411
/**
512
* Represents interface for single metadata value emitted by HotObservable<T> or ColdObservable<T>

src/scheduler/TestScheduler.ts

+49-22
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,34 @@
11
import { Notification, Observable, Subscription } from 'rxjs';
2-
import { AsyncAction } from 'rxjs/internal/scheduler/AsyncAction';
3-
import {
4-
VirtualAction,
5-
VirtualTimeScheduler
6-
} from 'rxjs/internal/scheduler/VirtualTimeScheduler';
7-
import { ColdObservable } from 'rxjs/internal/testing/ColdObservable';
8-
import { HotObservable } from 'rxjs/internal/testing/HotObservable';
2+
import { AsyncAction } from 'rxjs/dist/types/internal/scheduler/AsyncAction';
93
import { parseObservableMarble } from '../marbles/parseObservableMarble';
104
import { SubscriptionMarbleToken } from '../marbles/SubscriptionMarbleToken';
115
import { TestMessage } from '../message/TestMessage';
126
import { TestMessageValue } from '../message/TestMessage';
137
import { calculateSubscriptionFrame } from './calculateSubscriptionFrame';
148

9+
//tslint:disable no-var-requires no-require-imports
10+
const {
11+
VirtualAction,
12+
VirtualTimeScheduler,
13+
}: {
14+
VirtualAction: typeof import('rxjs/dist/types/internal/scheduler/VirtualTimeScheduler').VirtualAction;
15+
VirtualTimeScheduler: typeof import('rxjs/dist/types/internal/scheduler/VirtualTimeScheduler').VirtualTimeScheduler;
16+
} = require('rxjs/dist/cjs/internal/scheduler/VirtualTimeScheduler');
17+
18+
const hotObservableCtor = require('rxjs/dist/cjs/internal/testing/HotObservable').HotObservable;
19+
const coldObservableCtor = require('rxjs/dist/cjs/internal/testing/ColdObservable').ColdObservable;
20+
//tslint:enable no-var-requires no-require-imports
21+
1522
/**
1623
* @internal
1724
*/
1825
class TestScheduler extends VirtualTimeScheduler {
19-
private readonly coldObservables: Array<ColdObservable<any>> = [];
20-
private readonly hotObservables: Array<HotObservable<any>> = [];
26+
private readonly coldObservables: Array<
27+
import('rxjs/dist/types/internal/testing/ColdObservable').ColdObservable<any>
28+
> = [];
29+
private readonly hotObservables: Array<
30+
import('rxjs/dist/types/internal/testing/HotObservable').HotObservable<any>
31+
> = [];
2132
private flushed: boolean = false;
2233
private flushing: boolean = false;
2334

@@ -75,9 +86,17 @@ class TestScheduler extends VirtualTimeScheduler {
7586
return observableMetadata;
7687
}
7788

78-
public createColdObservable<T = string>(marble: string, value?: { [key: string]: T } | null, error?: any): ColdObservable<T>;
79-
public createColdObservable<T = string>(message: Array<TestMessage<T>>): ColdObservable<T>;
80-
public createColdObservable<T = string>(...args: Array<any>): ColdObservable<T> {
89+
public createColdObservable<T = string>(
90+
marble: string,
91+
value?: { [key: string]: T } | null,
92+
error?: any
93+
): import('rxjs/dist/types/internal/testing/ColdObservable').ColdObservable<T>;
94+
public createColdObservable<T = string>(
95+
message: Array<TestMessage<T>>
96+
): import('rxjs/dist/types/internal/testing/ColdObservable').ColdObservable<T>;
97+
public createColdObservable<T = string>(
98+
...args: Array<any>
99+
): import('rxjs/dist/types/internal/testing/ColdObservable').ColdObservable<T> {
81100
const [marbleValue, value, error] = args;
82101

83102
if (typeof marbleValue === 'string' && marbleValue.indexOf(SubscriptionMarbleToken.SUBSCRIBE) !== -1) {
@@ -86,21 +105,29 @@ class TestScheduler extends VirtualTimeScheduler {
86105

87106
const messages = Array.isArray(marbleValue)
88107
? marbleValue
89-
: parseObservableMarble(marbleValue, value, error, false, this.frameTimeFactor, this._maxFrame) as any;
90-
const observable = new ColdObservable<T>(messages as Array<TestMessage<T | Array<TestMessage<T>>>>, this);
108+
: (parseObservableMarble(marbleValue, value, error, false, this.frameTimeFactor, this._maxFrame) as any);
109+
const observable = new coldObservableCtor(messages as Array<TestMessage<T | Array<TestMessage<T>>>>, this);
91110
this.coldObservables.push(observable);
92111
return observable;
93112
}
94113

95-
public createHotObservable<T = string>(marble: string, value?: { [key: string]: T } | null, error?: any): HotObservable<T>;
96-
public createHotObservable<T = string>(message: Array<TestMessage<T>>): HotObservable<T>;
97-
public createHotObservable<T = string>(...args: Array<any>): HotObservable<T> {
114+
public createHotObservable<T = string>(
115+
marble: string,
116+
value?: { [key: string]: T } | null,
117+
error?: any
118+
): import('rxjs/dist/types/internal/testing/HotObservable').HotObservable<T>;
119+
public createHotObservable<T = string>(
120+
message: Array<TestMessage<T>>
121+
): import('rxjs/dist/types/internal/testing/HotObservable').HotObservable<T>;
122+
public createHotObservable<T = string>(
123+
...args: Array<any>
124+
): import('rxjs/dist/types/internal/testing/HotObservable').HotObservable<T> {
98125
const [marbleValue, value, error] = args;
99126

100127
const messages = Array.isArray(marbleValue)
101128
? marbleValue
102-
: parseObservableMarble(marbleValue, value, error, false, this.frameTimeFactor, this._maxFrame) as any;
103-
const subject = new HotObservable<T>(messages as Array<TestMessage<T | Array<TestMessage<T>>>>, this);
129+
: (parseObservableMarble(marbleValue, value, error, false, this.frameTimeFactor, this._maxFrame) as any);
130+
const subject = new hotObservableCtor(messages as Array<TestMessage<T | Array<TestMessage<T>>>>, this);
104131
this.hotObservables.push(subject);
105132
return subject;
106133
}
@@ -124,8 +151,8 @@ class TestScheduler extends VirtualTimeScheduler {
124151
innerObservableMetadata.push(new TestMessageValue<T>(this.frame - outerFrame, notification));
125152

126153
observable.subscribe(
127-
value => pushMetaData(Notification.createNext(value)),
128-
err => pushMetaData(Notification.createError(err)),
154+
(value) => pushMetaData(Notification.createNext(value)),
155+
(err) => pushMetaData(Notification.createError(err)),
129156
() => pushMetaData(Notification.createComplete())
130157
);
131158

@@ -177,4 +204,4 @@ class TestScheduler extends VirtualTimeScheduler {
177204
}
178205
}
179206

180-
export { TestScheduler };
207+
export { TestScheduler, VirtualTimeScheduler };

0 commit comments

Comments
 (0)