diff --git a/package-lock.json b/package-lock.json index 0560643..0f69ff4 100644 --- a/package-lock.json +++ b/package-lock.json @@ -5884,6 +5884,16 @@ "pretty-format": "^24.9.0" } }, + "jest-marbles": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/jest-marbles/-/jest-marbles-2.5.1.tgz", + "integrity": "sha512-BsHEqrHLMTsfqagWeWJ+vJrSPNcn7vIFpx+e4G/sKGnx8JLDniRBbiwtHfUP5yoQtXDi+56I6atr5WdgJUknmw==", + "dev": true, + "requires": { + "jest-diff": "24.9.0", + "jest-matcher-utils": "24.9.0" + } + }, "jest-matcher-utils": { "version": "24.9.0", "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-24.9.0.tgz", diff --git a/package.json b/package.json index 17a52f5..8a0a21b 100644 --- a/package.json +++ b/package.json @@ -42,6 +42,7 @@ "@types/react": "^16.9.35", "@types/react-dom": "^16.9.8", "husky": "^4.2.5", + "jest-marbles": "^2.5.1", "react": "^16.13.1", "react-dom": "^16.13.1", "react-test-renderer": "^16.13.1", diff --git a/test/connectInstanceObservable.test.ts b/test/connectInstanceObservable.test.ts index d61e042..8c50b57 100644 --- a/test/connectInstanceObservable.test.ts +++ b/test/connectInstanceObservable.test.ts @@ -54,7 +54,7 @@ const usePriceData = connectInstanceObservable( return combineLatest(data$, merge(periods$, plug$)).pipe( map(([data, period]) => data.slice(-period)), - ) + ) as Observable }, [], ) diff --git a/test/operators/distinct-share-replay.test.ts b/test/operators/distinct-share-replay.test.ts new file mode 100644 index 0000000..64920ec --- /dev/null +++ b/test/operators/distinct-share-replay.test.ts @@ -0,0 +1,77 @@ +import { distinctShareReplay } from "../../src" +import { cold } from "jest-marbles" +import { TestScheduler } from "rxjs/testing" +import { shareReplay } from "rxjs/operators" + +const scheduler = () => + new TestScheduler((actual, expected) => { + expect(actual).toEqual(expected) + }) + +describe("operators/distinctShareReplay", () => { + it("only emits distinct values", () => { + const values = { + a: { val: 1 }, + b: { val: 2 }, + c: { val: 3 }, + d: { val: 4 }, + } + + let source = " a-b-b-b-c-c-d|" + let expected = "a-b-----c---d|" + + expect(cold(source, values).pipe(distinctShareReplay())).toBeObservable( + cold(expected, values), + ) + + const customCompare = (a: { val: number }, b: { val: number }) => + a.val === b.val + values.c.val = 2 + + source = " a-b-b-b-c-c-d|" + expected = "a-b---------d|" + expect( + cold(source, values).pipe(distinctShareReplay(customCompare)), + ).toBeObservable(cold(expected, values)) + }) + + // prettier-ignore + it("should restart due to unsubscriptions", () => { + scheduler().run(({ expectObservable, expectSubscriptions, cold }) => { + const sourceSubs = [] + const source = cold("a-b-c-d-e-f-g-h-i-j") + sourceSubs.push(" ^------!----------------------") + sourceSubs.push(" -----------^------------------") + const sub1 = " ^------!" + const expected1 = " a-b-c-d-" + const sub2 = " -----------^------------------" + const expected2 = " -----------a-b-c-d-e-f-g-h-i-j" + + const shared = source.pipe(shareReplay({refCount: true, bufferSize: 1})) + + expectObservable(shared, sub1).toBe(expected1) + expectObservable(shared, sub2).toBe(expected2) + expectSubscriptions(source.subscriptions).toBe(sourceSubs) + }) + }) + + // prettier-ignore + it("should restart due to unsubscriptions when the source has completed", () => { + scheduler().run(({ expectObservable, expectSubscriptions, cold }) => { + const sourceSubs = [] + const source = cold('a-(b|) '); + sourceSubs.push( '-^-! '); + sourceSubs.push( '-----------^-!'); + const sub1 = '-^--! '; + const expected1 = '-a-(b|) '; + const sub2 = '-----------^--!'; + const expected2 = '-----------a-(b|)'; + + const shared = source.pipe(distinctShareReplay()); + + expectObservable(shared, sub1).toBe(expected1); + expectObservable(shared, sub2).toBe(expected2); + expectSubscriptions(source.subscriptions).toBe(sourceSubs); + }) + }) +})