-
Notifications
You must be signed in to change notification settings - Fork 11
/
Copy pathmarbleAssert.ts
121 lines (104 loc) · 3.99 KB
/
marbleAssert.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
import { TestMessage } from '../message/TestMessage';
import { SubscriptionLog } from '../utils/coreInternalImport';
import { constructObservableMarble } from './constructObservableMarble';
import { constructSubscriptionMarble } from './constructSubscriptionMarble';
//tslint:disable:no-require-imports no-var-requires
const { matcherHint, printExpected, printReceived } = require('jest-matcher-utils');
const { default: matchers } = require('expect/build/matchers');
//tslint:enbale:no-require-imports no-var-requires
const toEqualAssert = matchers.toEqual.bind({ expand: false });
const subscriptionMarbleAssert = (source: Array<SubscriptionLog>) => (expected: Array<SubscriptionLog>) => {
const asserted = toEqualAssert(source, expected);
if (!asserted.pass) {
const length = source.length > expected.length ? source.length : expected.length;
let description = `
${matcherHint(' to equal ')}
`;
for (let idx = 0; idx < length; idx++) {
const sourceMarble = !!source[idx]
? constructSubscriptionMarble(source[idx])
: { marbleString: '', frameString: '' };
const expectedMarble = !!expected[idx]
? constructSubscriptionMarble(expected[idx])
: { marbleString: '', frameString: '' };
if (toEqualAssert(sourceMarble, expectedMarble).pass) {
continue;
}
description += `
${printReceived(`Source: ${sourceMarble.marbleString}`)}
${printReceived(` ${sourceMarble.frameString}`)}
${printExpected(`Expected: ${expectedMarble.marbleString}`)}
${printExpected(` ${expectedMarble.frameString}`)}
`;
}
description += `
${asserted.message()}
`;
throw new Error(description);
}
};
const observableMarbleAssert =
<T extends Object = string>(source: Array<TestMessage<T>> | Readonly<Array<TestMessage<T>>>) =>
(expected: Array<TestMessage<T>> | Readonly<Array<TestMessage<T>>>) => {
if (!Array.isArray(expected)) {
throw new Error('Expected value is not array');
}
//polymorphic picks up observablemarbleassert first when empty array, manually falls back
//if expected is subscriptionlog
if ((expected as any).every((x: any) => x instanceof SubscriptionLog)) {
subscriptionMarbleAssert(source as any)(expected as any);
return;
}
const sourceMarble = constructObservableMarble(source);
const expectedMarble = constructObservableMarble(expected);
const asserted = toEqualAssert(source, expected);
if (!asserted.pass) {
const description = `
${printReceived(`Source: ${sourceMarble}`)}
${printExpected(`Expected: ${expectedMarble}`)}
${asserted.message()}
`;
throw new Error(description);
}
};
function marbleAssert<T = string>(
source: Array<TestMessage<T | Array<TestMessage<T>>>> | Readonly<Array<TestMessage<T | Array<TestMessage<T>>>>>
): {
to: {
equal(
expected: TestMessage<T | Array<TestMessage<T>>> | Readonly<Array<TestMessage<T | Array<TestMessage<T>>>>>
): void;
};
toEqual(
expected: TestMessage<T | Array<TestMessage<T>>> | Readonly<Array<TestMessage<T | Array<TestMessage<T>>>>>
): void;
};
function marbleAssert<T = void>(
source: Array<SubscriptionLog>
): {
to: { equal(expected: Array<SubscriptionLog>): void };
toEqual(expected: Array<SubscriptionLog>): void;
};
function marbleAssert<T = string>(
source:
| Array<SubscriptionLog>
| Array<TestMessage<T | Array<TestMessage<T>>>>
| Readonly<Array<TestMessage<T | Array<TestMessage<T>>>>>
): {
to: { equal(expected: object): void };
toEqual(expected: object): void;
} {
const isSourceArray = Array.isArray(source);
if (!isSourceArray) {
throw new Error('Cannot assert non array');
}
const isSourceSubscription = source.length > 0 && (source as Array<any>).every((v) => v instanceof SubscriptionLog);
const equal = isSourceSubscription ? subscriptionMarbleAssert(source as any) : observableMarbleAssert(source as any);
return {
to: {
equal,
},
toEqual: equal,
};
}
export { marbleAssert, constructSubscriptionMarble };