Skip to content

Commit

Permalink
Modify default print behavior (#59)
Browse files Browse the repository at this point in the history
Modify default print behavior
  • Loading branch information
ptitFicus authored Apr 4, 2017
1 parent 9ef784f commit 66bc956
Show file tree
Hide file tree
Showing 7 changed files with 111 additions and 56 deletions.
8 changes: 4 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ import loader from 'hoc-react-loader'

const Component = ({ data }) => <div>Component {JSON.stringify(data)}</div>

export default loader(Component, { print: true })
export default loader(Component)
```
In this example, the loader component doesn't wait for props. `this.props.load` is called once, but the `LoadingIndicator` component isn't displayed.

Expand All @@ -56,7 +56,7 @@ export default loader(Component, { load: () => console.log('here') })
```
In this case, the loader calls `this.props.load` if it exists *AND* the `load` parameter, resulting in `here` to be printed.

The default `print` parameter value is `false`. It means that in this example the `LoadingIndicator` isn't displayed.
The default `print` parameter value is `true`. It means that in this example the `LoadingIndicator` isn't displayed.

### Load as a string parameter
```es6
Expand All @@ -68,7 +68,7 @@ export default loader(Component, { load: 'myLoader' })
```
In this case, the loader calls `this.props.myLoader` if it exists.

The default `print` parameter value is `false`. It means that in this example the `LoadingIndicator` isn't displayed.
The default `print` parameter value is `true`. It means that in this example the `LoadingIndicator` isn't displayed.

### Wait as a function
### Print as a function
The `print` parameter can also be a function. Then the `props` and `context` are given to it (in this order), and it should return a boolean indicating wether or not the actual component should be displayed.
18 changes: 13 additions & 5 deletions build/core.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,8 @@ function _classCallCheck(instance, Constructor) { if (!(instance instanceof Cons

function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }

function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /* eslint react/prop-types: 0 */


var getTypeOf = function getTypeOf(something) {
var getType = {};
Expand All @@ -47,10 +48,8 @@ exports.default = function (ComposedComponent) {

var _ref = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {},
LoadingIndicator = _ref.LoadingIndicator,
_ref$print = _ref.print,
print = _ref$print === undefined ? ['loaded'] : _ref$print,
_ref$load = _ref.load,
load = _ref$load === undefined ? undefined : _ref$load;
print = _ref.print,
load = _ref.load;

var loadFunctionName = isString(load) ? load : 'load';

Expand All @@ -71,6 +70,15 @@ exports.default = function (ComposedComponent) {
return _ret = (_temp = (_this = _possibleConstructorReturn(this, (_ref2 = _class.__proto__ || Object.getPrototypeOf(_class)).call.apply(_ref2, [this].concat(args))), _this), _this.state = {
props: {}
}, _this.isLoaded = function () {
// Print is undefined,
// we rely on 'props.loaded' if present
// if not, we directly print the component
if (print === undefined) {
var loaded = _this.props.loaded;

return loaded === undefined ? true : !!loaded;
}

// Print is an array
// Implicitly meaning that this is an array of props
if (Array.isArray(print)) {
Expand Down
2 changes: 1 addition & 1 deletion examples/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@
"webpack-dev-server": "~1.12.1"
},
"dependencies": {
"hoc-react-loader": "../",
"hoc-react-loader": "file:../",
"lodash": "^4.15.0",
"normalize.css": "~4.2.0",
"react": "15.3.0",
Expand Down
5 changes: 3 additions & 2 deletions examples/src/components/Examples/Examples.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,10 @@ const Examples = ({ style, className }) => (
example={<Base />}
>
<div className={styles.doc}>
<h3>Base: defaults parameters</h3>
<h3>Base: `this.props.loaded` is defined</h3>
<p className={styles.description}>
In this example, the loader wraps a Component with its default parameters.
In this example, the loader wraps a Component with
&nbsp;<pre>this.props.loaded</pre>&nbsp;defined.
It means that the loader calls <pre>this.props.load</pre>
&nbsp;if presents, then waits for <pre>this.props.loaded</pre>
&nbsp;to be truthy, and finally displays the wrapped components.
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "hoc-react-loader",
"version": "4.0.0",
"version": "5.0.0",
"description": "Higher order component to call a load function from props at mount.",
"main": "build/index.js",
"peerDependencies": {
Expand Down
13 changes: 11 additions & 2 deletions src/core.jsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
/* eslint react/prop-types: 0 */
import React, { Component } from 'react'

const getTypeOf = (something) => {
Expand All @@ -22,8 +23,8 @@ export default (
ComposedComponent,
{
LoadingIndicator,
print = ['loaded'],
load = undefined,
print,
load,
} = {},
) => {
const loadFunctionName = isString(load) ? load : 'load'
Expand All @@ -36,6 +37,14 @@ export default (
}

isLoaded = () => {
// Print is undefined,
// we rely on 'props.loaded' if present
// if not, we directly print the component
if (print === undefined) {
const { loaded } = this.props
return loaded === undefined ? true : !!loaded
}

// Print is an array
// Implicitly meaning that this is an array of props
if (Array.isArray(print)) {
Expand Down
119 changes: 78 additions & 41 deletions src/index.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -63,95 +63,132 @@ const isLoadedTwice = (load, loaded) => {
}

describe('react-loader', () => {
it('should wait for a `data` props [readme]', () => {
/*
* The `loaded` default props is not set.
* There is not `print` option.
*/
it('should print the wrapped component by default', () => {
const load = spy(() => {})
const wrappedComponent = getWrapped(undefined, { load })

isLoaded(load, wrappedComponent)
})

/*
* `print` option is set as an array of one element.
*/
it('should wait for `data` in props to be truthy', () => {
// Mount
const load = spy(() => {})
const loaded = getWrapped({ print: ['data'] }, { load })
const wrappedComponent = getWrapped({ print: ['data'] }, { load })

isLoading(load, loaded)
isLoading(load, wrappedComponent)

// Change `data` value
loaded.setProps({ data: true })
wrappedComponent.setProps({ data: true })

isLoaded(load, loaded)
isLoaded(load, wrappedComponent)
})

it('should wait for a `loaded` props [default]', () => {
/*
* `print` option is not set, but the `loaded` parameter is.
*/
it('should wait for the default props (`loaded`) to be truthy', () => {
// Mount
const load = spy(() => {})
const loaded = getWrapped(undefined, { load })
const wrappedComponent = getWrapped(undefined, { loaded: false, load })

isLoading(load, loaded)
isLoading(load, wrappedComponent)

// Change `loaded` value
loaded.setProps({ loaded: true })
wrappedComponent.setProps({ loaded: true })

isLoaded(load, loaded)
isLoaded(load, wrappedComponent)
})

it('should wait for an array of props', () => {
/*
* `print` option is set to an array of two elements.
*/
it('should wait for all props defined in an array of props', () => {
// Mount
const load = spy(() => {})
const loaded = getWrapped({ print: ['prop1', 'prop2'] }, { load })
const wrappedComponent = getWrapped({ print: ['prop1', 'prop2'] }, { load })

isLoading(load, loaded)
isLoading(load, wrappedComponent)

// Change `prop1` value
loaded.setProps({ prop1: true })
wrappedComponent.setProps({ prop1: true })

isLoading(load, loaded)
isLoading(load, wrappedComponent)

// Change `prop3` value
loaded.setProps({ prop3: true })
wrappedComponent.setProps({ prop3: true })

isLoading(load, loaded)
isLoading(load, wrappedComponent)

// Change `prop2` value
loaded.setProps({ prop2: true })
wrappedComponent.setProps({ prop2: true })

isLoaded(load, loaded)
isLoaded(load, wrappedComponent)
})

it('should handle `print` parameter to be a function', () => {
/*
* `print` option is a function.
*/
it('should wait `print` to return a truthy value', () => {
// Mount (false case)
const load = spy(() => {})
let loaded = getWrapped({ print: () => false }, { load })
let wrappedComponent = getWrapped({ print: () => false }, { load })

isLoading(load, loaded)
isLoading(load, wrappedComponent)

// Mount (true case)
loaded = getWrapped({ print: () => true }, { load })
wrappedComponent = getWrapped({ print: () => true }, { load })

isLoadedTwice(load, loaded)
isLoadedTwice(load, wrappedComponent)
})

it('should handle `print` parameter to be a boolean', () => {
// Mount (false case)
/*
* `print` value is harcoded (to true).
*/
it('should handle a hardcoded `print` value (truthy)', () => {
// Mount
const load = spy(() => {})
const wrappedComponent = getWrapped({ print: true }, { load })

isLoaded(load, wrappedComponent)
})

/*
* `print` value is harcoded (to false).
*/
it('should handle a hardcoded `print` value (falsey)', () => {
// Mount
const load = spy(() => {})
const loaded = getWrapped({ print: true }, { load })
const wrappedComponent = getWrapped({ print: false }, { load })

isLoaded(load, loaded)
isLoading(load, wrappedComponent)
})

it('should print a different LoadingIndicator component', () => {
// Mount
const load = spy(() => {})
const loaded = getWrapped({ LoadingIndicator, print: ['data'] }, { load })
const wrappedComponent = getWrapped({ LoadingIndicator, print: ['data'] }, { load })

isLoadingCustomLoader(load, loaded)
isLoadingCustomLoader(load, wrappedComponent)

// Change `data` value
loaded.setProps({ data: true })
wrappedComponent.setProps({ data: true })

isLoadedCustomLoader(load, loaded)
isLoadedCustomLoader(load, wrappedComponent)
})

it('should call the `load` function parameter if present', () => {
// Mount
const loadProp = spy(() => {})
const loadParam = spy(() => {})
const props = { prop1: 'prop1', load: loadProp }
const loaded = getWrapped({ load: loadParam }, props)
const wrappedComponent = getWrapped({ load: loadParam }, props)

// Load function is called
// Graphic component isn't called
Expand All @@ -160,34 +197,34 @@ describe('react-loader', () => {
loadProp.should.have.been.called.with(props)
loadParam.should.have.been.called.once
loadParam.should.have.been.called.with(props)
expect(loaded.find(Component).node).to.be.undefined
loaded.find(TailSpin).node.should.exists
expect(wrappedComponent.find(TailSpin).node).to.be.undefined
wrappedComponent.find(Component).node.should.exists
})

it('should call matching props if the load parameter is a string', () => {
// Mount
const loadProp = spy(() => {})
const loadPropName = 'customLoadFunction'
const props = { prop1: 'prop1', [loadPropName]: loadProp }
const loaded = getWrapped({ load: loadPropName }, props)
const wrappedComponent = getWrapped({ load: loadPropName }, props)

// Load function is called
// Graphic component isn't called
// Loader should be Dots
loadProp.should.have.been.called.once
loadProp.should.have.been.called.with(props)
expect(loaded.find(Component).node).to.be.undefined
loaded.find(TailSpin).node.should.exists
expect(wrappedComponent.find(TailSpin).node).to.be.undefined
wrappedComponent.find(Component).node.should.exists
})

it('should handle a `null` `load` props/parameter', () => {
// Mount
const loaded = getWrapped()
const wrappedComponent = getWrapped()

// Graphic component isn't called
// Dots should be printed
expect(loaded.find(Component).node).to.be.undefined
loaded.find(TailSpin).node.should.exists
expect(wrappedComponent.find(TailSpin).node).to.be.undefined
wrappedComponent.find(Component).node.should.exists
})
})

Expand Down

0 comments on commit 66bc956

Please sign in to comment.