22233a8745
This makes it easier to keep track of which pieces the client will have already dispatched or been executed, reducing the amount of class members needed. Critically, this makes it so the 'stop' button (which is currently a send button) actually works even after the automatic stop has happened. UI is still pending for stopping recording early. This is not covered by this change.
115 lines
4 KiB
TypeScript
115 lines
4 KiB
TypeScript
/*
|
|
Copyright 2021 The Matrix.org Foundation C.I.C.
|
|
|
|
Licensed under the Apache License, Version 2.0 (the "License");
|
|
you may not use this file except in compliance with the License.
|
|
You may obtain a copy of the License at
|
|
|
|
http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
Unless required by applicable law or agreed to in writing, software
|
|
distributed under the License is distributed on an "AS IS" BASIS,
|
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
See the License for the specific language governing permissions and
|
|
limitations under the License.
|
|
*/
|
|
|
|
import {Singleflight} from "../src/utils/Singleflight";
|
|
|
|
describe('Singleflight', () => {
|
|
afterEach(() => {
|
|
Singleflight.forgetAll();
|
|
});
|
|
|
|
it('should throw for bad context variables', () => {
|
|
const permutations: [Object, string][] = [
|
|
[null, null],
|
|
[{}, null],
|
|
[null, "test"],
|
|
];
|
|
for (const p of permutations) {
|
|
try {
|
|
Singleflight.for(p[0], p[1]);
|
|
// noinspection ExceptionCaughtLocallyJS
|
|
throw new Error("failed to fail: " + JSON.stringify(p));
|
|
} catch (e) {
|
|
expect(e.message).toBe("An instance and key must be supplied");
|
|
}
|
|
}
|
|
});
|
|
|
|
it('should execute the function once', () => {
|
|
const instance = {};
|
|
const key = "test";
|
|
const val = {}; // unique object for reference check
|
|
const fn = jest.fn().mockReturnValue(val);
|
|
const sf = Singleflight.for(instance, key);
|
|
const r1 = sf.do(fn);
|
|
expect(r1).toBe(val);
|
|
expect(fn.mock.calls.length).toBe(1);
|
|
const r2 = sf.do(fn);
|
|
expect(r2).toBe(val);
|
|
expect(fn.mock.calls.length).toBe(1);
|
|
});
|
|
|
|
it('should execute the function once, even with new contexts', () => {
|
|
const instance = {};
|
|
const key = "test";
|
|
const val = {}; // unique object for reference check
|
|
const fn = jest.fn().mockReturnValue(val);
|
|
let sf = Singleflight.for(instance, key);
|
|
const r1 = sf.do(fn);
|
|
expect(r1).toBe(val);
|
|
expect(fn.mock.calls.length).toBe(1);
|
|
sf = Singleflight.for(instance, key); // RESET FOR TEST
|
|
const r2 = sf.do(fn);
|
|
expect(r2).toBe(val);
|
|
expect(fn.mock.calls.length).toBe(1);
|
|
});
|
|
|
|
it('should execute the function twice if the result was forgotten', () => {
|
|
const instance = {};
|
|
const key = "test";
|
|
const val = {}; // unique object for reference check
|
|
const fn = jest.fn().mockReturnValue(val);
|
|
const sf = Singleflight.for(instance, key);
|
|
const r1 = sf.do(fn);
|
|
expect(r1).toBe(val);
|
|
expect(fn.mock.calls.length).toBe(1);
|
|
sf.forget();
|
|
const r2 = sf.do(fn);
|
|
expect(r2).toBe(val);
|
|
expect(fn.mock.calls.length).toBe(2);
|
|
});
|
|
|
|
it('should execute the function twice if the instance was forgotten', () => {
|
|
const instance = {};
|
|
const key = "test";
|
|
const val = {}; // unique object for reference check
|
|
const fn = jest.fn().mockReturnValue(val);
|
|
const sf = Singleflight.for(instance, key);
|
|
const r1 = sf.do(fn);
|
|
expect(r1).toBe(val);
|
|
expect(fn.mock.calls.length).toBe(1);
|
|
Singleflight.forgetAllFor(instance);
|
|
const r2 = sf.do(fn);
|
|
expect(r2).toBe(val);
|
|
expect(fn.mock.calls.length).toBe(2);
|
|
});
|
|
|
|
it('should execute the function twice if everything was forgotten', () => {
|
|
const instance = {};
|
|
const key = "test";
|
|
const val = {}; // unique object for reference check
|
|
const fn = jest.fn().mockReturnValue(val);
|
|
const sf = Singleflight.for(instance, key);
|
|
const r1 = sf.do(fn);
|
|
expect(r1).toBe(val);
|
|
expect(fn.mock.calls.length).toBe(1);
|
|
Singleflight.forgetAll();
|
|
const r2 = sf.do(fn);
|
|
expect(r2).toBe(val);
|
|
expect(fn.mock.calls.length).toBe(2);
|
|
});
|
|
});
|
|
|