Skip to content

Commit 0b96348

Browse files
committed
Revert changes to unit tests
1 parent 4eb3b6b commit 0b96348

2 files changed

Lines changed: 895 additions & 0 deletions

File tree

src/harness/assert.ts

Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
/// <reference path="./harness.ts" />
2+
declare namespace Chai {
3+
interface ChaiStatic {
4+
util: UtilStatic;
5+
}
6+
7+
interface UtilStatic {
8+
objDisplay(obj: any): string;
9+
}
10+
11+
interface AssertStatic {
12+
sameMembers<T>(actual: Iterable<T>, expected: Iterable<T>, message?: string): void;
13+
notSameMembers<T>(actual: Iterable<T>, expected: Iterable<T>, message?: string): void;
14+
includeMembersOnce<T>(actual: Iterable<T>, expected: Iterable<T>, message?: string): void;
15+
includeMembers<T>(actual: Iterable<T>, expected: Iterable<T>, message?: string): void;
16+
notIncludeMembers<T>(actual: Iterable<T>, expected: Iterable<T>, message?: string): void;
17+
}
18+
}
19+
20+
// patch assert.sameMembers to support other iterables
21+
_chai.use((chai: Chai.ChaiStatic, util: Chai.UtilStatic) => {
22+
function isIdenticalTo<T>(left: Iterable<T>, right: Iterable<T>) {
23+
if (!(left instanceof core.SortedSet) && right instanceof core.SortedSet) {
24+
[left, right] = [right, left];
25+
}
26+
27+
const set = asReadonlySet(left);
28+
const seen = set instanceof core.SortedSet ? new core.SortedSet<T>(set.comparer) : new Set<T>();
29+
const iterator = Array.isArray(right) ? ts.arrayIterator(right) : right[Symbol.iterator]();
30+
for (let { value, done } = iterator.next(); !done; { value, done } = iterator.next()) {
31+
if (!set.has(value)) return false;
32+
seen.add(value);
33+
}
34+
return set.size === seen.size;
35+
}
36+
37+
function isSubsetOf<T>(subset: Iterable<T>, superset: Iterable<T>, unique?: boolean) {
38+
const set = asReadonlySet(superset);
39+
const seen = unique ? set instanceof core.SortedSet ? new core.SortedSet<T>(set.comparer) : new Set<T>() : undefined;
40+
const iterator = Array.isArray(subset) ? ts.arrayIterator(subset) : subset[Symbol.iterator]();
41+
for (let { value, done } = iterator.next(); !done; { value, done } = iterator.next()) {
42+
if (!set.has(value)) return false;
43+
if (seen) {
44+
if (seen.has(value)) return false;
45+
seen.add(value);
46+
}
47+
}
48+
return true;
49+
}
50+
51+
function overlaps<T>(left: Iterable<T>, right: Iterable<T>) {
52+
if (!(left instanceof core.SortedSet) && right instanceof core.SortedSet) {
53+
[left, right] = [right, left];
54+
}
55+
56+
const set = asReadonlySet(left);
57+
const iterator = Array.isArray(right) ? ts.arrayIterator(right) : right[Symbol.iterator]();
58+
for (let { value, done } = iterator.next(); !done; { value, done } = iterator.next()) {
59+
if (set.has(value)) return true;
60+
}
61+
return false;
62+
}
63+
64+
function asReadonlySet<T>(iterable: Iterable<T>): ReadonlySet<T> {
65+
return iterable instanceof Set ? iterable :
66+
iterable instanceof core.SortedSet ? iterable :
67+
new Set(iterable);
68+
}
69+
70+
function asReadonlyArray<T>(iterable: Iterable<T>): ReadonlyArray<T> {
71+
return Array.isArray(iterable) ? iterable : Array.from(iterable);
72+
}
73+
74+
// patch `assert.sameMembers` to support any iterable
75+
chai.assert.sameMembers = <T>(actual: Iterable<T>, expected: Iterable<T>, message?: string) => {
76+
if (!isIdenticalTo(actual, expected)) {
77+
actual = asReadonlyArray(actual);
78+
expected = asReadonlyArray(expected);
79+
assert.fail(actual, expected, message || `expected ${util.objDisplay(actual)} to have the same members as ${util.objDisplay(expected)}`);
80+
}
81+
};
82+
83+
// patch `assert.notSameMembers` to support any iterable
84+
chai.assert.notSameMembers = <T>(actual: Iterable<T>, expected: Iterable<T>, message?: string) => {
85+
if (isIdenticalTo(actual, expected)) {
86+
actual = asReadonlyArray(actual);
87+
expected = asReadonlyArray(expected);
88+
assert.fail(actual, expected, message || `expected ${util.objDisplay(actual)} to not have the same members as ${util.objDisplay(expected)}`);
89+
}
90+
};
91+
92+
chai.assert.includeMembersOnce = <T>(actual: Iterable<T>, expected: Iterable<T>, message?: string) => {
93+
if (!isSubsetOf(expected, actual, /*unique*/ true)) {
94+
actual = asReadonlyArray(actual);
95+
expected = asReadonlyArray(expected);
96+
assert.fail(actual, expected, message || `expected ${util.objDisplay(actual)} to include the members of ${util.objDisplay(expected)} only once`);
97+
}
98+
};
99+
100+
// patch `assert.includeMembers` to support any iterable
101+
chai.assert.includeMembers = <T>(actual: Iterable<T>, expected: Iterable<T>, message?: string) => {
102+
if (!isSubsetOf(expected, actual)) {
103+
actual = asReadonlyArray(actual);
104+
expected = asReadonlyArray(expected);
105+
assert.fail(actual, expected, message || `expected ${util.objDisplay(actual)} to include the members of ${util.objDisplay(expected)}`);
106+
}
107+
};
108+
109+
// patch `assert.notIncludeMembers` to support any iterable
110+
chai.assert.notIncludeMembers = <T>(actual: Iterable<T>, expected: Iterable<T>, message?: string) => {
111+
if (overlaps(expected, actual)) {
112+
actual = asReadonlyArray(actual);
113+
expected = asReadonlyArray(expected);
114+
assert.fail(actual, expected, message || `expected ${util.objDisplay(actual)} to not include the members of ${util.objDisplay(expected)}`);
115+
}
116+
};
117+
});

0 commit comments

Comments
 (0)