Skip to content
This repository has been archived by the owner on Nov 16, 2023. It is now read-only.

Commit

Permalink
Merge pull request #67 from microsoft/state-transition-validation-onc…
Browse files Browse the repository at this point in the history
…omponentend

Handle invalid state transitions - onComponentEnd
  • Loading branch information
kawwong authored Jul 15, 2019
2 parents 7295bee + 641a4c7 commit 80da656
Show file tree
Hide file tree
Showing 2 changed files with 85 additions and 33 deletions.
26 changes: 20 additions & 6 deletions src/listeners/onComponentEnd.js
Original file line number Diff line number Diff line change
@@ -1,14 +1,28 @@
import { componentEnd } from '../actions/components';
import store from '../store';

async function onComponentEnd (event) {
function onComponentEnd (event) {
if (event != null && event.detail != null) {
const endTime = performance.now();
const state = store.getState();

store.dispatch(componentEnd({
endTime,
id: event.detail.id
}));
if (event.detail.id in state) {
// A COMPONENT_START action has been dispatched for this id
if (state[event.detail.id].endTime == null) {
// A COMPONENT_END action has not yet been dispatched
const endTime = performance.now();

store.dispatch(componentEnd({
endTime,
id: event.detail.id
}));
} else {
// A COMPONENT_END action has already been dispatched for this id
console.warn(`COMPONENT_END emitted for component id with end time: ${event.detail.id}`);
}
} else {
// A COMPONENT_START action has not been dispatched yet for this id
console.warn(`COMPONENT_END emitted before COMPONENT_START for component id: ${event.detail.id}`);
}
}
}

Expand Down
92 changes: 65 additions & 27 deletions src/listeners/onComponentEnd.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,52 +2,90 @@ import { componentEnd } from '../actions/components';
import store from '../store';
import onComponentEnd from './onComponentEnd';

let spyWarn = null;

describe('onComponentEnd.js', () => {
beforeEach(() => {
jest.clearAllMocks();
store.dispatch = jest.fn();
store.getState = jest.fn(() => ({}));
spyWarn = jest.spyOn(console, 'warn');
});

it('should not dispatch when the event is null', () => {
onComponentEnd(null);

expect(store.dispatch).not.toHaveBeenCalled();
afterEach(() => {
spyWarn.mockRestore();
});

it('should not dispatch when the event is undefined', () => {
onComponentEnd(undefined);
describe('invalid events', () => {
it('should not dispatch when the event is null', () => {
onComponentEnd(null);

expect(store.dispatch).not.toHaveBeenCalled();
});
expect(store.dispatch).not.toHaveBeenCalled();
});

it('should not dispatch when the event detail is null', () => {
onComponentEnd({
detail: null
it('should not dispatch when the event is undefined', () => {
onComponentEnd(undefined);

expect(store.dispatch).not.toHaveBeenCalled();
});

expect(store.dispatch).not.toHaveBeenCalled();
});
it('should not dispatch when the event detail is null', () => {
onComponentEnd({
detail: null
});

it('should not dispatch when the event detail is undefined', () => {
onComponentEnd({
detail: undefined
expect(store.dispatch).not.toHaveBeenCalled();
});

expect(store.dispatch).not.toHaveBeenCalled();
it('should not dispatch when the event detail is undefined', () => {
onComponentEnd({
detail: undefined
});

expect(store.dispatch).not.toHaveBeenCalled();
});
});

it('should dispatch the component data to the store', async () => {
performance.now = jest.fn(() => 5);
await onComponentEnd({
detail: {
describe('valid events', () => {
it('should not dispatch when the component id does not exist in the store', () => {
onComponentEnd({
detail: {
endTime: 5,
id: 'id'
}
});

expect(store.dispatch).not.toHaveBeenCalled();
expect(spyWarn).toHaveBeenCalled();
});

it('should not dispatch when the component id exists in the store and has an end time', () => {
store.getState = jest.fn(() => ({ 'id': { endTime: new Date(0) } }));
onComponentEnd({
detail: {
endTime: 5,
id: 'id'
}
});

expect(store.dispatch).not.toHaveBeenCalled();
expect(spyWarn).toHaveBeenCalled();
});

it('should dispatch the component data to the store', () => {
store.getState = jest.fn(() => ({ 'id': {} }));
performance.now = jest.fn(() => 5);
onComponentEnd({
detail: {
endTime: 5,
id: 'id'
}
});

expect(store.dispatch).toHaveBeenCalledWith(componentEnd({
endTime: 5,
id: 'id'
}
}));
});

expect(store.dispatch).toHaveBeenCalledWith(componentEnd({
endTime: 5,
id: 'id'
}));
});
});

0 comments on commit 80da656

Please sign in to comment.