Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions .vscode/launch.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,21 @@
],
"console": "integratedTerminal",
"internalConsoleOptions": "neverOpen"
},
{
"type": "node",
"request": "launch",
"name": "Jest current file",
"program": "${workspaceRoot}/node_modules/jest/bin/jest.js",
"args": [
"${fileBasename}",
"--verbose",
"-i",
"--no-cache",
"--watchAll"
],
"console": "integratedTerminal",
"internalConsoleOptions": "neverOpen"
}
]
}
2 changes: 1 addition & 1 deletion src/__snapshots__/trackerHoc.test.js.snap
Original file line number Diff line number Diff line change
Expand Up @@ -331,7 +331,7 @@ exports[`trackerHoc Initial Status should render component with trackedPromiseIn
"delay": 300,
}
}
promiseInProgress={false}
promiseInProgress={true}
>
<span>
test
Expand Down
29 changes: 17 additions & 12 deletions src/trackerHoc.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import React, { Component } from "react";
import React, { Component } from 'react';
import {
emitter,
getCounter,
promiseCounterUpdateEventId
} from "./trackPromise";
} from './trackPromise';
import { setupConfig } from './setupConfig';

// Props:
Expand All @@ -20,26 +20,31 @@ export const promiseTrackerHoc = ComponentToWrap => {
this.state = {
promiseInProgress: false,
internalPromiseInProgress: false,
config: setupConfig(props.config),
config: setupConfig(props.config)
};

this.notifyPromiseInProgress = this.notifyPromiseInProgress.bind(this);
this.updateProgress = this.updateProgress.bind(this);
this.subscribeToCounterUpdate = this.subscribeToCounterUpdate.bind(this);
}

updateProgressWithDelay() {
setTimeout(() => {
this.setState({
promiseInProgress: this.state.internalPromiseInProgress
});
}, this.state.config.delay);
notifyPromiseInProgress() {
this.state.config.delay === 0
? this.setState({ promiseInProgress: true })
: setTimeout(() => {
this.setState({ promiseInProgress: true });
}, this.state.config.delay);
}

updateProgress(progress, afterUpdateCallback) {
this.setState(
{ internalPromiseInProgress: progress },
afterUpdateCallback
);
this.state.config.delay === 0
? this.setState({ promiseInProgress: progress })
: this.updateProgressWithDelay();

!progress
? this.setState({ promiseInProgress: false })
: this.notifyPromiseInProgress();
}

subscribeToCounterUpdate() {
Expand Down
88 changes: 31 additions & 57 deletions src/trackerHoc.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import React from "react";
import { promiseTrackerHoc } from "./trackerHoc";
import * as trackPromiseAPI from "./trackPromise";
import { defaultArea } from "./constants";
import { act } from "react-dom/test-utils"; // ES6

describe("trackerHoc", () => {
describe("Initial Status", () => {
Expand Down Expand Up @@ -471,90 +470,65 @@ describe("trackerHoc", () => {
jest.useRealTimers();
});

it("should render <h1>NO SPINNER</h2> when counter is 1 but delay is set to 200 (before timing out)", () => {
it("should render <h1>NO SPINNER</h2> when counter is 1 but delay is set to 300 (before timing out)", done => {
// Arrange
let TestSpinnerComponent = null;
act(() => {
TestSpinnerComponent = props => {
return (
<div>
{props.promiseInProgress ? <h1>SPINNER</h1> : <h2>NO SPINNER</h2>}
</div>
);
};

trackPromiseAPI.getCounter = jest.fn().mockImplementation(() => 0);
});
const TestSpinnerComponent = props => {
return (
<div>
{props.promiseInProgress ? <h1>SPINNER</h1> : <h2>NO SPINNER</h2>}
</div>
);
};

const getCounterStub = jest
.spyOn(trackPromiseAPI, "getCounter")
.mockReturnValue(0);

// Act
let component = null;
act(() => {
const TrackedComponent = promiseTrackerHoc(TestSpinnerComponent);
component = mount(<TrackedComponent config={{ delay: 300 }} />);
});
const TrackedComponent = promiseTrackerHoc(TestSpinnerComponent);
const component = mount(<TrackedComponent config={{ delay: 300 }} />);

// Check very beginning (no promises going on) NO SPINNER is shown
// TODO: this assert could be skipped (move to another test)
expect(component.text()).toMatch("NO SPINNER");
expect(trackPromiseAPI.getCounter).toHaveBeenCalled();
expect(component.text()).toEqual("NO SPINNER");
expect(getCounterStub).toHaveBeenCalled();

// Assert
// This promise will resolved after 1 seconds, by doing this
// we will be able to test 2 scenarios:
// [0] first 200ms spinner won't be shown (text NOSPINNER)
// [1] after 200ms spinner will be shown (text SPINNER)
// [2] after 1000ms spinner will be hidded again (text NOSPINNER)
let myFakePromise = null;

act(() => {
myFakePromise = new Promise(resolve => {
setTimeout(() => {
resolve(true);
}, 1000);
});
});

act(() => {
trackPromiseAPI.trackPromise(myFakePromise);

// Runs all pending timers. whether it's a second from now or a year.
// https://jestjs.io/docs/en/timer-mocks.html
//jest.advanceTimersByTime(300);
const myFakePromise = new Promise(resolve => {
setTimeout(() => {
resolve(true);
}, 1000);
});

act(() => {
// Runs all pending timers. whether it's a second from now or a year.
// https://jestjs.io/docs/en/timer-mocks.html
jest.advanceTimersByTime(100);
});
trackPromiseAPI.trackPromise(myFakePromise);

jest.advanceTimersByTime(100);

// [0] first 200ms spinner won't be shown (text NOSPINNER)
expect(component.text()).toMatch("NO SPINNER");
expect(component.text()).toEqual("NO SPINNER");

act(() => {
// Runs all pending timers. whether it's a second from now or a year.
// https://jestjs.io/docs/en/timer-mocks.html
jest.advanceTimersByTime(300);
});
jest.advanceTimersByTime(300);

// Before the promise get's resolved
// [1] after 200ms spinner will be shown (text SPINNER)
expect(component.text()).toMatch("SPINNER");
expect(component.text()).toEqual("SPINNER");

// After the promise get's resolved

act(() => {
jest.advanceTimersByTime(1500);
//jest.runAllTimers();
});
jest.runAllTimers();

// [2] after 1000ms spinner will be hidded again (text NOSPINNER)
// Wait for fakePromise (simulated ajax call) to be completed
// no spinner should be shown
act(() => {
myFakePromise.then(() => {
expect(component.text()).toMatch("NO SPINNER");
});

myFakePromise.then(() => {
expect(component.text()).toEqual("NO SPINNER");
done();
});
});
});
Expand Down
1 change: 0 additions & 1 deletion src/trackerHook.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import React from "react";
import { emitter, promiseCounterUpdateEventId, getCounter} from "./trackPromise";
import { defaultArea } from "./constants";
import { defaultConfig, setupConfig } from './setupConfig';


Expand Down
13 changes: 6 additions & 7 deletions src/trackerHook.test.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
import React from "react";
import { usePromiseTracker } from "./trackerHook";
import * as trackPromiseAPI from "./trackPromise";
import { defaultArea } from "./constants";
import { trackPromise, emitter } from "./trackPromise";
import { act } from "react-dom/test-utils"; // ES6

describe("trackerHook", () => {
Expand Down Expand Up @@ -164,7 +162,7 @@ describe("trackerHook", () => {
jest.useRealTimers();
});

it("should render <h1>NO SPINNER</h2> when counter is 1 but delay is set to 200 (before timing out)", () => {
it("should render <h1>NO SPINNER</h2> when counter is 1 but delay is set to 200 (before timing out)", done => {
// Arrange
let TestSpinnerComponent = null;
act(() => {
Expand All @@ -191,7 +189,7 @@ describe("trackerHook", () => {

// Check very beginning (no promises going on) NO SPINNER is shown
// TODO: this assert could be skipped (move to another test)
expect(component.text()).toMatch("NO SPINNER");
expect(component.text()).toEqual("NO SPINNER");
expect(trackPromiseAPI.getCounter).toHaveBeenCalled();

// Assert
Expand Down Expand Up @@ -225,7 +223,7 @@ describe("trackerHook", () => {
});

// [0] first 200ms spinner won't be shown (text NOSPINNER)
expect(component.text()).toMatch("NO SPINNER");
expect(component.text()).toEqual("NO SPINNER");

act(() => {
// Runs all pending timers. whether it's a second from now or a year.
Expand All @@ -235,7 +233,7 @@ describe("trackerHook", () => {

// Before the promise get's resolved
// [1] after 200ms spinner will be shown (text SPINNER)
expect(component.text()).toMatch("SPINNER");
expect(component.text()).toEqual("SPINNER");

// After the promise get's resolved

Expand All @@ -248,7 +246,8 @@ describe("trackerHook", () => {
// no spinner should be shown
act(() => {
myFakePromise.then(() => {
expect(component.text()).toMatch("NO SPINNER");
expect(component.text()).toEqual("NO SPINNER");
done();
});
});
});
Expand Down