Skip to content

Commit e64a1af

Browse files
committed
Merge branch 'dev' into sierra
2 parents 3888bdd + 5619590 commit e64a1af

File tree

7 files changed

+106
-120
lines changed

7 files changed

+106
-120
lines changed

package/__mocks__/timeJump.js

Lines changed: 0 additions & 1 deletion
This file was deleted.

package/__tests__/index.test.js

Lines changed: 15 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -1,69 +1,28 @@
1-
const index = require('../index');
1+
const timeJumpRequire = require('../timeJump');
22

33
jest.mock('../timeJump');
4+
const timeJump = jest.fn();
5+
timeJumpRequire.mockReturnValue(timeJump);
6+
7+
const index = require('../index');
48

59
describe('unit testing for index.js', () => {
6-
test('index.js should be exporting the linkFiber, timeJump, getTree methods', () => {
7-
expect(typeof index.linkFiber).toBe('function');
8-
expect(typeof index.timeJump).toBe('function');
9-
expect(typeof index.getTree).toBe('function');
10+
test('index.js should be exporting a function', () => {
11+
expect(typeof index).toBe('function');
1012
});
1113

12-
test('index.js should be listening to the window for the jumpToSnap message', (done) => {
14+
test('index.js should be calling timeJump for every jumpToSnap message', (done) => {
1315
const calls = 10;
1416
let count = 0;
1517
global.addEventListener('message', ({ data: { action } }) => {
16-
switch (action) {
17-
case 'jumpToSnap':
18-
count += 1;
19-
expect(index.timeJump.mock.calls.length).toBe(count);
20-
if (count === calls) done();
21-
break;
22-
default:
23-
break;
24-
}
25-
});
26-
[...Array(calls).keys()].forEach(() => global.postMessage({ action: 'jumpToSnap', payload: ['test'] }, '*'));
27-
});
28-
test('setLock message should change the mode object to the given payload', (done) => {
29-
const mode = { paused: false };
30-
const action = 'setLock';
31-
const payloads = [true, false, true, false, true, false, false];
32-
let count = 0;
33-
const calls = payloads.length;
34-
global.addEventListener('message', ({ data: { action: actionReceived, payload } }) => {
35-
switch (actionReceived) {
36-
case 'setLock':
37-
mode.locked = payload;
38-
expect(mode.locked).toBe(payloads[count]);
39-
count += 1;
40-
if (calls === count) done();
41-
break;
42-
default:
43-
break;
44-
}
45-
});
46-
payloads.forEach(payload => global.postMessage({ action, payload }, '*'));
47-
});
48-
49-
test('setPause message should change the mode object to the given payload', (done) => {
50-
const mode = { paused: false };
51-
const action = 'setPause';
52-
const payloads = [true, false, true, false, true, false, false];
53-
let count = 0;
54-
const calls = payloads.length;
55-
global.addEventListener('message', ({ data: { action: actionReceived, payload } }) => {
56-
switch (actionReceived) {
57-
case 'setPause':
58-
mode.locked = payload;
59-
expect(mode.locked).toBe(payloads[count]);
60-
count += 1;
61-
if (calls === count) done();
62-
break;
63-
default:
64-
break;
18+
if (action === 'jumpToSnap') {
19+
count += 1;
20+
expect(timeJump.mock.calls.length).toBe(count);
21+
if (count === calls) done();
6522
}
6623
});
67-
payloads.forEach(payload => global.postMessage({ action, payload }, '*'));
24+
for (let i = 0; i < calls; i += 1) {
25+
global.postMessage({ action: 'jumpToSnap', payload: ['test'] }, '*');
26+
}
6827
});
6928
});

package/__tests__/linkFiber.test.js

Lines changed: 18 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,14 @@
1+
/* eslint-disable import/no-extraneous-dependencies */
12
// const Tree = require('./tree');
3+
import React from 'react';
4+
import { render } from 'react-dom';
5+
6+
const linkFiberRequire = require('../linkFiber');
7+
28
let linkFiber;
3-
let ReactDOM;
4-
let React;
59
let mode;
610
let snapShot;
11+
let component;
712

813
describe('unit test for linkFiber', () => {
914
beforeEach(() => {
@@ -13,9 +18,7 @@ describe('unit test for linkFiber', () => {
1318
paused: false,
1419
locked: false,
1520
};
16-
React = require('react');
17-
ReactDOM = require('react-dom');
18-
linkFiber = require('../linkFiber')(snapShot, mode);
21+
linkFiber = linkFiberRequire(snapShot, mode);
1922

2023
class App extends React.Component {
2124
constructor(props) {
@@ -29,8 +32,10 @@ describe('unit test for linkFiber', () => {
2932
}
3033

3134
const container = document.createElement('div');
32-
ReactDOM.render(<App />, container);
35+
render(<App />, container);
3336
linkFiber(container);
37+
// eslint-disable-next-line prefer-destructuring
38+
component = snapShot.tree.children[0].component;
3439
});
3540

3641
test('linkFiber should mutate the snapshot tree property', () => {
@@ -42,9 +47,12 @@ describe('unit test for linkFiber', () => {
4247
});
4348

4449
test('linkFiber should modify the setState of the stateful component', () => {
45-
console.log(snapShot.tree.children[0].component.setState);
46-
// snapShot.tree.children[0].component.setState({ foo: 'josh' });
47-
// expect(snapShot.tree.children[0].component.setState).toBeInstanceOf(newSetState);
48-
// expect(snapShot.tree.children[0].component.state.foo).toBe('josh');
50+
expect(snapShot.tree.children[0].component.setState.linkFiberChanged).toBe(true);
4951
});
52+
53+
// test('newSetState should still setState correctly', () => {
54+
// component.setState({ foo: 'barf' });
55+
// expect(component.state).not.toEqual({ foo: 'bar' });
56+
// expect(component.state).toEqual({ foo: 'barf' });
57+
// });
5058
});

package/__tests__/timeJump.test.js

Lines changed: 62 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1,53 +1,78 @@
1-
const timeJumpExport = require('../timeJump');
1+
const timeJumpRequire = require('../timeJump');
2+
3+
class Component {
4+
constructor(mockfn) {
5+
this.mockfn = mockfn;
6+
}
7+
8+
setState(state, func = () => { }) {
9+
this.mockfn(state);
10+
func();
11+
}
12+
}
13+
14+
class FiberNode {
15+
constructor(mockfn, state) {
16+
this.state = state;
17+
this.children = [];
18+
this.component = new Component(mockfn);
19+
}
20+
}
221

322
describe('unit testing for timeJump.js', () => {
423
let timeJump;
524
let snapShot;
625
let mode;
726
let mockFuncs;
8-
const count = 3;
927

1028
beforeEach(() => {
11-
snapShot = [];
1229
mode = { jumping: false };
1330
mockFuncs = [];
14-
timeJump = timeJumpExport(snapShot, mode);
31+
for (let i = 0; i < 4; i += 1) mockFuncs.push(jest.fn());
32+
33+
const tree = new FiberNode(mockFuncs[0]);
34+
tree.children = [
35+
new FiberNode(mockFuncs[1]),
36+
new FiberNode(mockFuncs[2]),
37+
new FiberNode(mockFuncs[3]),
38+
];
1539

16-
const createSetStateAsync = i => state => new Promise((resolve) => {
17-
mockFuncs[i](state);
18-
resolve();
40+
snapShot = { tree };
41+
timeJump = timeJumpRequire(snapShot, mode);
42+
});
43+
44+
test('calling the initial require should return a function', () => {
45+
expect(typeof timeJumpRequire).toBe('function');
46+
});
47+
48+
describe('testing iteration through snapshot tree', () => {
49+
const states = ['root', 'firstChild', 'secondChild', 'thirdChild'];
50+
const target = new FiberNode(null, states[0]);
51+
target.children = [
52+
new FiberNode(null, states[1]),
53+
new FiberNode(null, states[2]),
54+
new FiberNode(null, states[3]),
55+
];
56+
57+
beforeEach(() => {
58+
timeJump(target);
59+
});
60+
test('timeJump should call setState on each state in origin', () => {
61+
mockFuncs.forEach(mockFunc => expect(mockFunc.mock.calls.length).toBe(1));
1962
});
2063

21-
for (let i = 0; i < count; i += 1) {
22-
mockFuncs.push(jest.fn());
23-
snapShot.push({ setStateAsync: createSetStateAsync(i) });
24-
}
64+
test('timeJump should pass target state to origin setState', () => {
65+
mockFuncs.forEach((mockFunc, i) => expect(mockFunc.mock.calls[0][0]).toBe(states[i]));
66+
});
2567
});
2668

27-
// test('calling the initial require should return a function', () => {
28-
// expect(typeof timeJump).toBe('function');
29-
// });
30-
31-
// test('timeJump should iterate through snapshot and call setStateAsync on each state', () => {
32-
// const calls = 10;
33-
// for (let i = 1; i <= calls; i += 1) {
34-
// timeJump(Array(count).fill('test'));
35-
// mockFuncs.forEach(mockFunc => expect(mockFunc.mock.calls.length).toBe(i));
36-
// }
37-
// });
38-
39-
// test('timeJump should pass the state from new snapshot to setStateAsync', () => {
40-
// const newSnapShot = [];
41-
// for (let i = 0; i < count; i += 1) {
42-
// newSnapShot.push(`testState${i}`);
43-
// }
44-
// timeJump(newSnapShot);
45-
// mockFuncs.forEach((mockFunc, i) => expect(mockFunc.mock.calls[0][0]).toBe(`testState${i}`));
46-
47-
// for (let i = 0; i < count; i += 1) {
48-
// newSnapShot[i] = { testkey: `testval${i}` };
49-
// }
50-
// timeJump(newSnapShot);
51-
// mockFuncs.forEach((mockFunc, i) => expect(mockFunc.mock.calls[1][0]).toEqual({ testkey: `testval${i}` }));
52-
// });
69+
test('jumping mode should be set while timeJumping', () => {
70+
const logMode = jest.fn();
71+
logMode.mockImplementation(() => expect(mode.jumping).toBe(true));
72+
73+
snapShot.tree = new FiberNode(logMode);
74+
const target = new FiberNode(null, 'test');
75+
timeJump(target);
76+
expect(logMode).toHaveBeenCalled();
77+
});
5378
});

package/index.js

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,6 @@ const mode = {
99
const linkFiber = require('./linkFiber')(snapShot, mode);
1010
const timeJump = require('./timeJump')(snapShot, mode);
1111

12-
const getTree = () => snapShot.tree.getCopy();
13-
1412
window.addEventListener('message', ({ data: { action, payload } }) => {
1513
switch (action) {
1614
case 'jumpToSnap':
@@ -27,9 +25,4 @@ window.addEventListener('message', ({ data: { action, payload } }) => {
2725
}
2826
});
2927

30-
// window.postMessage({ data: { action: 'foo', payload: 'bar' } });
31-
module.exports = {
32-
timeJump,
33-
linkFiber,
34-
getTree,
35-
};
28+
module.exports = linkFiber;

package/linkFiber.js

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,14 @@ module.exports = (snap, mode) => {
1717

1818
function changeSetState(component) {
1919
// check that setState hasn't been changed yet
20-
if (component.setState.name === 'newSetState') return;
20+
if (component.setState.linkFiberChanged) return;
2121

2222
// make a copy of setState
2323
const oldSetState = component.setState.bind(component);
2424

25-
function newSetState(state, callback = () => {}) {
25+
// replace component's setState so developer doesn't change syntax
26+
// component.setState = newSetState.bind(component);
27+
component.setState = (state, callback = () => {}) => {
2628
// dont do anything if state is locked
2729
// UNLESS we are currently jumping through time
2830
if (mode.locked && !mode.jumping) return;
@@ -32,10 +34,8 @@ module.exports = (snap, mode) => {
3234
sendSnapshot();
3335
callback();
3436
});
35-
}
36-
37-
// replace component's setState so developer doesn't change syntax
38-
component.setState = newSetState;
37+
};
38+
component.setState.linkFiberChanged = true;
3939
}
4040

4141
function createTree(currentFiber, tree = new Tree('root')) {
@@ -68,8 +68,10 @@ module.exports = (snap, mode) => {
6868
return (container) => {
6969
const {
7070
_reactRootContainer: { _internalRoot },
71+
_reactRootContainer,
7172
} = container;
72-
fiberRoot = _internalRoot;
73+
// only assign internal root if it actually exists
74+
fiberRoot = (_internalRoot) ? _internalRoot : _reactRootContainer;
7375
updateSnapShotTree();
7476

7577
// send the initial snapshot once the content script has started up

package/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "react-time-travel",
3-
"version": "1.0.4",
3+
"version": "1.1.0",
44
"description": "A library that helps debug React by memorizing the state of components with every render.",
55
"main": "index.js",
66
"repository": {

0 commit comments

Comments
 (0)