Skip to content

Commit 9b82bb9

Browse files
committed
Refactored wizard context
1 parent 8b95449 commit 9b82bb9

File tree

8 files changed

+112
-72
lines changed

8 files changed

+112
-72
lines changed

__tests__/components/Steps.spec.jsx

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -20,12 +20,12 @@ import { Steps } from '../../src';
2020
const FakeStep = () => <div />;
2121

2222
describe('Steps', () => {
23-
it('should call _setSteps', () => {
23+
it('should call _init', () => {
2424
const context = {
2525
wizard: {
26-
_setSteps: jest.fn(),
2726
steps: [],
2827
},
28+
wizardInit: jest.fn(),
2929
};
3030

3131
shallow(
@@ -34,20 +34,19 @@ describe('Steps', () => {
3434
</Steps>,
3535
{ context },
3636
);
37-
// eslint-disable-next-line no-underscore-dangle
38-
expect(context.wizard._setSteps).toHaveBeenCalled();
37+
expect(context.wizardInit).toHaveBeenCalled();
3938
});
4039

41-
it('should not call _setSteps if wizard already has steps', () => {
40+
it('should not call _init if wizard already has steps', () => {
4241
const context = {
4342
wizard: {
44-
_setSteps: jest.fn(),
4543
steps: [
4644
'we',
4745
'have',
4846
'steps',
4947
],
5048
},
49+
wizardInit: jest.fn(),
5150
};
5251

5352
shallow(
@@ -56,8 +55,7 @@ describe('Steps', () => {
5655
</Steps>,
5756
{ context },
5857
);
59-
// eslint-disable-next-line no-underscore-dangle
60-
expect(context.wizard._setSteps).not.toHaveBeenCalled();
58+
expect(context.wizardInit).not.toHaveBeenCalled();
6159
});
6260

6361
it('should render correct child if controlled', () => {

__tests__/components/Wizard.spec.jsx

Lines changed: 49 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -12,33 +12,39 @@
1212
* the License.
1313
*/
1414

15-
import React from 'react';
15+
import React, { PropTypes } from 'react';
1616
import { mount } from 'enzyme';
1717

1818
import { Wizard } from '../../src';
1919

20+
const ExposeWizard = ({ children }, context) => children(context);
21+
ExposeWizard.contextTypes = {
22+
wizard: PropTypes.object,
23+
wizardInit: PropTypes.func,
24+
};
25+
2026
describe('Wizard', () => {
2127
let mounted;
22-
let setSteps;
28+
let init;
2329
let step;
2430
let next;
2531
let previous;
2632
let push;
2733
let go;
2834

29-
describe('without render prop', () => {
35+
describe('with render prop', () => {
3036
beforeEach(() => {
3137
const history = {
3238
replace: () => null,
3339
listen: () => () => null,
3440
};
3541

3642
mounted = mount(
37-
<Wizard history={history} />,
43+
<Wizard history={history} render={() => null} />,
3844
);
3945
});
4046

41-
it('should render without steps', () => {
47+
it('should render', () => {
4248
expect(mounted).toMatchSnapshot();
4349
});
4450

@@ -50,27 +56,31 @@ describe('Wizard', () => {
5056
describe('with no other props', () => {
5157
beforeEach(() => {
5258
mounted = mount(
53-
<Wizard
54-
render={({
55-
_setSteps,
56-
step: wizardStep,
57-
next: wizardNext,
58-
previous: wizardPrevious,
59-
push: wizardPush,
60-
go: wizardGo,
61-
}) => {
62-
setSteps = _setSteps;
63-
step = wizardStep;
64-
next = wizardNext;
65-
previous = wizardPrevious;
66-
push = wizardPush;
67-
go = wizardGo;
68-
return <noscript />;
69-
}}
70-
/>,
59+
<Wizard>
60+
<ExposeWizard>
61+
{({
62+
wizard: {
63+
step: wizardStep,
64+
next: wizardNext,
65+
previous: wizardPrevious,
66+
push: wizardPush,
67+
go: wizardGo,
68+
},
69+
wizardInit,
70+
}) => {
71+
step = wizardStep;
72+
next = wizardNext;
73+
previous = wizardPrevious;
74+
push = wizardPush;
75+
go = wizardGo;
76+
init = wizardInit;
77+
return null;
78+
}}
79+
</ExposeWizard>
80+
</Wizard>,
7181
);
7282

73-
setSteps([
83+
init([
7484
{ path: 'gryffindor' },
7585
{ path: 'slytherin' },
7686
]);
@@ -119,20 +129,23 @@ describe('Wizard', () => {
119129

120130
beforeEach(() => {
121131
mounted = mount(
122-
<Wizard
123-
onNext={onNext}
124-
render={({
125-
_setSteps,
126-
next: wizardNext,
127-
}) => {
128-
setSteps = _setSteps;
129-
next = wizardNext;
130-
return <noscript />;
131-
}}
132-
/>,
132+
<Wizard onNext={onNext}>
133+
<ExposeWizard>
134+
{({
135+
wizard: {
136+
next: wizardNext,
137+
},
138+
wizardInit,
139+
}) => {
140+
next = wizardNext;
141+
init = wizardInit;
142+
return null;
143+
}}
144+
</ExposeWizard>
145+
</Wizard>,
133146
);
134147

135-
setSteps([
148+
init([
136149
{ path: 'gryffindor' },
137150
{ path: 'slytherin' },
138151
]);
Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
// Jest Snapshot v1, https://goo.gl/fbAQLP
22

3-
exports[`Wizard without render prop should render without steps 1`] = `
3+
exports[`Wizard with render prop should render 1`] = `
44
<Wizard
55
basename=""
66
className=""
@@ -11,10 +11,6 @@ exports[`Wizard without render prop should render without steps 1`] = `
1111
}
1212
}
1313
onNext={null}
14-
render={null}
15-
>
16-
<div
17-
className=""
18-
/>
19-
</Wizard>
14+
render={[Function]}
15+
/>
2016
`;

__tests__/utils/index.spec.js

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
/*
2+
* Copyright (c) 2017 American Express Travel Related Services Company, Inc.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
5+
* in compliance with the License. You may obtain a copy of the License at
6+
*
7+
* http://www.apache.org/licenses/LICENSE-2.0
8+
*
9+
* Unless required by applicable law or agreed to in writing, software distributed under the License
10+
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
11+
* or implied. See the License for the specific language governing permissions and limitations under
12+
* the License.
13+
*/
14+
15+
import fixPath from '../../src/utils';
16+
17+
describe('fixPath', () => {
18+
it('should remove duplicate forward slashes', () => {
19+
const path = 'path//to/something';
20+
const fixedPath = fixPath(path);
21+
expect(fixedPath).toBe('path/to/something');
22+
});
23+
});

package.json

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,7 @@
1616
"posttest": "npm run lint",
1717
"prepublish": "npm run build"
1818
},
19-
"repository": {
20-
"type": "git",
21-
"url": "https://github.com/americanexpress/react-albus.git"
22-
},
19+
"repository": "americanexpress/react-albus",
2320
"keywords": [
2421
"react",
2522
"react-component",

src/components/Steps.jsx

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,15 +16,15 @@ import React, { Component, PropTypes } from 'react';
1616

1717
class Steps extends Component {
1818
componentWillMount() {
19-
const { wizard } = this.context;
19+
const { wizard, wizardInit } = this.context;
2020

2121
// Register steps with Wizard if they're not already registered
2222
if (wizard && !wizard.steps.length) {
2323
const steps = React.Children.map(this.props.children, child => ({
2424
path: child.props.path,
2525
name: child.props.name,
2626
}));
27-
wizard._setSteps(steps); // eslint-disable-line no-underscore-dangle
27+
wizardInit(steps);
2828
}
2929
}
3030

@@ -50,6 +50,7 @@ Steps.defaultProps = {
5050

5151
Steps.contextTypes = {
5252
wizard: PropTypes.object,
53+
wizardInit: PropTypes.func,
5354
};
5455

5556
export default Steps;

src/components/Wizard.jsx

Lines changed: 10 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414

1515
import React, { Component, PropTypes } from 'react';
1616
import { createMemoryHistory } from 'history';
17+
import fixPath from '../utils';
1718

1819
class Wizard extends Component {
1920
state = {
@@ -26,15 +27,15 @@ class Wizard extends Component {
2627
getChildContext() {
2728
return {
2829
wizard: {
29-
_setSteps: this.setSteps,
3030
step: this.state.step,
3131
steps: this.steps,
3232
next: this.next,
33-
previous: this.previous,
33+
previous: this.props.history.goBack,
3434
push: this.push,
35-
go: this.go,
35+
go: this.props.history.go,
3636
history: this.props.history,
3737
},
38+
wizardInit: this.init,
3839
};
3940
}
4041

@@ -54,37 +55,30 @@ class Wizard extends Component {
5455
this.unlisten();
5556
}
5657

57-
setInitialStep() {
58+
init = (steps) => {
59+
this.steps = steps;
60+
5861
if (this.props.onNext) {
5962
this.props.onNext({ path: null, name: null }, this.steps, this.replace);
6063
} else {
6164
this.replace();
6265
}
6366
}
6467

65-
setSteps = (steps) => {
66-
this.steps = steps;
67-
this.setInitialStep();
68-
}
69-
7068
steps = [];
71-
previous = this.props.history.goBack;
72-
go = this.props.history.go;
7369

7470
get paths() {
7571
return this.steps.map(s => s.path);
7672
}
7773

78-
fixPath = pathname => pathname.replace(/\/\/+/g, '/');
79-
8074
push = (step) => {
8175
const nextStep = step || this.paths[this.paths.indexOf(this.state.step.path) + 1];
82-
this.props.history.push(this.fixPath(`${this.props.basename}/${nextStep}`));
76+
this.props.history.push(fixPath(`${this.props.basename}/${nextStep}`));
8377
}
8478

8579
replace = (step) => {
8680
const nextStep = step || this.paths[0];
87-
this.props.history.replace(this.fixPath(`${this.props.basename}/${nextStep}`));
81+
this.props.history.replace(fixPath(`${this.props.basename}/${nextStep}`));
8882
}
8983

9084
next = () => {
@@ -131,6 +125,7 @@ Wizard.defaultProps = {
131125

132126
Wizard.childContextTypes = {
133127
wizard: PropTypes.object,
128+
wizardInit: PropTypes.func,
134129
};
135130

136131
export default Wizard;

src/utils/index.js

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
/*
2+
* Copyright (c) 2017 American Express Travel Related Services Company, Inc.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
5+
* in compliance with the License. You may obtain a copy of the License at
6+
*
7+
* http://www.apache.org/licenses/LICENSE-2.0
8+
*
9+
* Unless required by applicable law or agreed to in writing, software distributed under the License
10+
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
11+
* or implied. See the License for the specific language governing permissions and limitations under
12+
* the License.
13+
*/
14+
15+
const fixPath = pathname => pathname.replace(/\/\/+/g, '/');
16+
17+
export default fixPath;

0 commit comments

Comments
 (0)