Skip to content

Commit

Permalink
test(super): improves test coverage
Browse files Browse the repository at this point in the history
  • Loading branch information
rafamel committed Apr 6, 2020
1 parent 60ed82a commit ed3fc1c
Show file tree
Hide file tree
Showing 5 changed files with 611 additions and 256 deletions.
199 changes: 199 additions & 0 deletions test/super/Machine.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,199 @@
import { subscribe } from 'promist';
import {
SuperMachine,
MachineSubject,
ReporterMachineSubject,
ResourceSubject,
MachineSourceSubject
} from '~/super';

const mocks = {
enable: jest.spyOn(SuperMachine.prototype as any, 'enable'),
disable: jest.spyOn(SuperMachine.prototype as any, 'disable')
};

test(`methods call super`, () => {
const subjects = [
new MachineSubject(),
new ReporterMachineSubject(),
new MachineSourceSubject(null),
new ResourceSubject(null)
];

for (const subject of subjects) {
Object.values(mocks).map((mock) => mock.mockClear());

expect(mocks.enable).not.toHaveBeenCalled();
expect(mocks.disable).not.toHaveBeenCalled();

subject.enable();
expect(mocks.enable).toHaveBeenLastCalledWith();

subject.disable();
expect(mocks.disable).toHaveBeenLastCalledWith();
}
});

test(`enable and disable call constructor parameters once`, () => {
const [a, b] = [jest.fn(), jest.fn()];
const subjects = [
new MachineSubject(a, b),
new ReporterMachineSubject(a, b),
new MachineSourceSubject(null, null, a, b),
new ResourceSubject(null, null, a, b)
];

for (const subject of subjects) {
[a, b].map((mock) => mock.mockClear());

expect(a).not.toHaveBeenCalled();
expect(b).not.toHaveBeenCalled();

subject.enable();
expect(a).toHaveBeenCalledTimes(1);
subject.enable();
expect(a).toHaveBeenCalledTimes(1);

subject.disable();
expect(b).toHaveBeenCalledTimes(1);
subject.disable();
expect(b).toHaveBeenCalledTimes(1);
}
});

test(`a subscription returned by enable is unsubscribed on disable`, () => {
const subscription: any = { unsubscribe: jest.fn() };
const subjects = [
new MachineSubject(() => subscription),
new ReporterMachineSubject(() => subscription),
new MachineSourceSubject(null, null, () => subscription),
new ResourceSubject(null, null, () => subscription)
];

for (const subject of subjects) {
subscription.unsubscribe.mockClear();

subject.enable();
expect(subscription.unsubscribe).not.toHaveBeenCalled();
subject.disable();
expect(subscription.unsubscribe).toHaveBeenCalledTimes(1);
subject.disable();
expect(subscription.unsubscribe).toHaveBeenCalledTimes(1);

subject.enable();
subject.disable();
expect(subscription.unsubscribe).toHaveBeenCalledTimes(2);
}
});

test(`a subscription array returned by enable is unsubscribed on disable`, () => {
const subscriptions: any[] = [
{ unsubscribe: jest.fn() },
{ unsubscribe: jest.fn() },
{ unsubscribe: jest.fn() }
];
const subjects = [
new MachineSubject(() => subscriptions),
new ReporterMachineSubject(() => subscriptions),
new MachineSourceSubject(null, null, () => subscriptions),
new ResourceSubject(null, null, () => subscriptions)
];

for (const subject of subjects) {
subscriptions.map(({ unsubscribe }) => unsubscribe.mockClear());

subject.enable();
expect(subscriptions[0].unsubscribe).not.toHaveBeenCalled();
expect(subscriptions[1].unsubscribe).not.toHaveBeenCalled();
expect(subscriptions[2].unsubscribe).not.toHaveBeenCalled();

subject.disable();
expect(subscriptions[0].unsubscribe).toHaveBeenCalledTimes(1);
expect(subscriptions[1].unsubscribe).toHaveBeenCalledTimes(1);
expect(subscriptions[2].unsubscribe).toHaveBeenCalledTimes(1);

subject.disable();
expect(subscriptions[0].unsubscribe).toHaveBeenCalledTimes(1);
expect(subscriptions[1].unsubscribe).toHaveBeenCalledTimes(1);
expect(subscriptions[2].unsubscribe).toHaveBeenCalledTimes(1);

subject.enable();
subject.disable();
expect(subscriptions[0].unsubscribe).toHaveBeenCalledTimes(2);
expect(subscriptions[1].unsubscribe).toHaveBeenCalledTimes(2);
expect(subscriptions[2].unsubscribe).toHaveBeenCalledTimes(2);
}
});

test(`active is false`, () => {
const subjects = [
new MachineSubject(),
new ReporterMachineSubject(),
new MachineSourceSubject(null),
new ResourceSubject(null)
];

for (const subject of subjects) {
expect(subject.active).toBe(false);
}
});

test(`active$ emits first value (false) synchronously`, () => {
const subjects = [
new MachineSubject(),
new ReporterMachineSubject(),
new MachineSourceSubject(null),
new ResourceSubject(null)
];

for (const subject of subjects) {
let value: boolean | null = null;
const subscription = subject.active$.subscribe((val) => (value = val));
subscription.unsubscribe();
expect(value).toBe(false);
}
});

test(`enable/disable set active/active$`, async () => {
const subjects = [
new MachineSubject(),
new ReporterMachineSubject(),
new MachineSourceSubject(null),
new ResourceSubject(null)
];

for (const subject of subjects) {
subject.enable();
expect(subject.active).toBe(true);
await expect(subscribe(subject.active$)).resolves.toBe(true);

subject.disable();
expect(subject.active).toBe(false);
await expect(subscribe(subject.active$)).resolves.toBe(false);
}
});

test(`active$ is a stream with unique sequential values`, () => {
const subjects = [
new MachineSubject(),
new ReporterMachineSubject(),
new MachineSourceSubject(null),
new ResourceSubject(null)
];

for (const subject of subjects) {
const values: boolean[] = [];
const subscription = subject.active$.subscribe((value) =>
values.push(value)
);
subject.enable();
subject.disable();
subject.disable();
subject.enable();
subject.enable();
subject.disable();
subscription.unsubscribe();

expect(values).toEqual([false, true, false, true, false]);
}
});
66 changes: 0 additions & 66 deletions test/super/MachineSource.test.ts

This file was deleted.

55 changes: 55 additions & 0 deletions test/super/Reporter.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
import { subscribe } from 'promist';
import {
SuperReporter,
ReporterSubject,
ReporterMachineSubject,
ReporterSourceSubject,
ResourceSubject
} from '~/super';

const mocks = {
report: jest.spyOn(SuperReporter.prototype as any, 'report')
};

test(`methods call super`, () => {
const subjects = [
new ReporterSubject(),
new ReporterMachineSubject(),
new ReporterSourceSubject(null),
new ResourceSubject(null)
];

for (const subject of subjects) {
Object.values(mocks).map((mock) => mock.mockClear());

expect(mocks.report).not.toHaveBeenCalled();

const err = Error('foo');
subject.report(err);
expect(mocks.report).toHaveBeenLastCalledWith(err);
}
});

test(`error$ emits on report`, async () => {
const subjects = [
new ReporterSubject(),
new ReporterMachineSubject(),
new ReporterSourceSubject(null),
new ResourceSubject(null)
];

for (const subject of subjects) {
const err = Error(`foo`);
const errors: Error[] = [];
const promise = subscribe(subject.error$);
const subscription = subject.error$.subscribe((err) => errors.push(err));

subject.report(err);
await expect(promise).resolves.toBe(err);

subject.report(Error());
subject.report(Error());
subscription.unsubscribe();
expect(errors).toHaveLength(3);
}
});
37 changes: 0 additions & 37 deletions test/super/ReporterSource.test.ts

This file was deleted.

Loading

0 comments on commit ed3fc1c

Please sign in to comment.