diff --git a/solutions/testing-react-component/Button/Exercise1.test.js b/solutions/testing-react-component/Button/Exercise1.test.js new file mode 100644 index 0000000..5b4308b --- /dev/null +++ b/solutions/testing-react-component/Button/Exercise1.test.js @@ -0,0 +1,57 @@ +import React from "react"; +import { shallow } from "enzyme"; +import renderer from "react-test-renderer"; +import Button from "."; + +// Exasice #1 +describe("Rendering", () => { + // A sample test. + it("Should render a button", () => { + const wrapper = shallow( + ); +} + +Button.propTypes = { + disabled: PropTypes.bool, + children: PropTypes.string, + size: PropTypes.oneOf(["small", "medium", "large"]), + onClick: PropTypes.func +}; + +Button.defaultProps = { + disabled: false, + children: "Button", + size: "medium", + onClick: () => {} +}; + +export default Button; \ No newline at end of file diff --git a/solutions/testing-react-component/Counter/Exercise3.test.js b/solutions/testing-react-component/Counter/Exercise3.test.js new file mode 100644 index 0000000..5af25b4 --- /dev/null +++ b/solutions/testing-react-component/Counter/Exercise3.test.js @@ -0,0 +1,18 @@ +import React from "react"; +import { shallow } from "enzyme"; +import Counter from "."; + +// Exasice #3 +describe("Initial state of the counter", () => { + + // A Sample bad test + it("initial state in bad way", () => { + const wrapper = shallow(); + expect(wrapper.state().count).toEqual(0); + }); + + it("initial state should be 0", () => { + const wrapper = shallow(); + expect(wrapper.find(".count").text()).toEqual("0"); + }); +}); diff --git a/solutions/testing-react-component/Counter/Exercise4.test.js b/solutions/testing-react-component/Counter/Exercise4.test.js new file mode 100644 index 0000000..f0e48a1 --- /dev/null +++ b/solutions/testing-react-component/Counter/Exercise4.test.js @@ -0,0 +1,19 @@ +import React from "react"; +import { shallow } from "enzyme"; +import Counter from "."; + +// Exasice #4 +describe("User interactions on counter", () => { + + it("increment the count when the increment button is clicked", () => { + const wrapper = shallow(); + wrapper.find('Button.increment').simulate('click'); + expect(wrapper.find(".count").text()).toEqual("1"); + }); + + it("decrement the count when the decrement button is clicked", () => { + const wrapper = shallow(); + wrapper.find('Button.decrement').simulate('click'); + expect(wrapper.find(".count").text()).toEqual("-1"); + }); +}); diff --git a/solutions/testing-react-component/Counter/index.js b/solutions/testing-react-component/Counter/index.js new file mode 100644 index 0000000..822ece4 --- /dev/null +++ b/solutions/testing-react-component/Counter/index.js @@ -0,0 +1,43 @@ +import React, { Component } from "react"; + +import Button from "../Button"; + +class Counter extends Component { + constructor(props) { + super(props); + this.state = { + count: 0 + } + + this.increment = this.increment.bind(this); + this.decrement = this.decrement.bind(this); + } + + increment() { + this.setState(prevState => ({ count: prevState.count + 1 })); + }; + + decrement() { + this.setState(prevState => ({ count: prevState.count - 1 })); + }; + + render() { + return ( +
+

{this.state.count}

+ + +
+ ); + } +} + +export default Counter; \ No newline at end of file diff --git a/solutions/testing-react-component/CounterStore/Exercise5.test.js b/solutions/testing-react-component/CounterStore/Exercise5.test.js new file mode 100644 index 0000000..fe1590d --- /dev/null +++ b/solutions/testing-react-component/CounterStore/Exercise5.test.js @@ -0,0 +1,43 @@ +import React from 'react' +import { shallow } from 'enzyme' +import { counterIncrement, counterDecrement } from './actions' + +import { Counter } from './index' + +describe('Counter component connected with redux store', () => { + + // A sample test + it('should renders the count', () => { + const props = { + dispatch: jest.fn(), + count: 1 + } + + const wrapper = shallow() + expect(wrapper.find('.count').text()).toEqual('1') + }) + + it('dispatches the right action for incrementing', () => { + const props = { + dispatch: jest.fn(), + count: 3 + } + + const wrapper = shallow(); + wrapper.find('Button.increment').simulate('click') + + expect(props.dispatch).toHaveBeenCalledWith(counterIncrement()) + }) + + it('dispatches the right action for decrementing', () => { + const props = { + dispatch: jest.fn(), + count: 3 + } + + const wrapper = shallow() + wrapper.find('Button.decrement').simulate('click') + + expect(props.dispatch).toHaveBeenCalledWith(counterDecrement()) + }) +}) diff --git a/solutions/testing-react-component/CounterStore/actions.js b/solutions/testing-react-component/CounterStore/actions.js new file mode 100644 index 0000000..478df96 --- /dev/null +++ b/solutions/testing-react-component/CounterStore/actions.js @@ -0,0 +1,10 @@ +export const COUNTER_INCREMENT = '@@Counter/COUNTER_INCREMENT'; +export const COUNTER_DECREMENT = '@@Counter/COUNTER_DECREMENT'; + +export const counterIncrement = () => ({ + type: COUNTER_INCREMENT +}); + +export const counterDecrement = () => ({ + type: COUNTER_DECREMENT +}); \ No newline at end of file diff --git a/solutions/testing-react-component/CounterStore/index.js b/solutions/testing-react-component/CounterStore/index.js new file mode 100644 index 0000000..070e269 --- /dev/null +++ b/solutions/testing-react-component/CounterStore/index.js @@ -0,0 +1,49 @@ +import React, { Component } from "react"; +import { connect } from "react-redux"; +import { counterIncrement, counterDecrement } from "./actions"; +import Button from "../Button"; + +export class Counter extends Component { + constructor(props) { + super(props); + this.increment = this.increment.bind(this); + this.decrement = this.decrement.bind(this); + } + + increment() { + this.props.dispatch(counterIncrement()); + }; + + decrement() { + this.props.dispatch(counterDecrement()); + }; + + render() { + return ( +
+

{this.props.count}

+ + +
+ ); + } +} + +const mapStateToProps = (state) => ({ + count: state.count, +}) + +export default connect(mapStateToProps, { + counterIncrement, + counterDecrement +})(Counter) \ No newline at end of file diff --git a/solutions/testing-react-component/CounterStore/reducer.js b/solutions/testing-react-component/CounterStore/reducer.js new file mode 100644 index 0000000..2ac0fa1 --- /dev/null +++ b/solutions/testing-react-component/CounterStore/reducer.js @@ -0,0 +1,23 @@ +import { + COUNTER_INCREMENT, + COUNTER_DECREMENT +} from "./actions"; + +const INITIAL_STATE = { count: 0 }; + +export default (state = INITIAL_STATE, action) => { + switch (action.type) { + case COUNTER_INCREMENT: + return { + ...state, + count : state.count + 1, + } + case COUNTER_DECREMENT: + return { + ...state, + count : state.count - 1, + } + default: + return state; + } +}