diff --git a/api.md b/api.md new file mode 100644 index 0000000..3787181 --- /dev/null +++ b/api.md @@ -0,0 +1,57 @@ +## API options + + +```javascript +import ReactDream, { ReactBox } from 'react-dream' + +ReactDream.Stateless(({ title }) =>

{title}

) + .map(element =>
{element}
) + .contramap(({ language }) => ({ + title: language === 'en' ? 'Hello' : 'Hola' + })) + .enhance( + withState('updateTitle', 'title', 'Hola') + ) + .name('Header') + +ReactDream.Stateful(class extends Component {}) + .map() // not optimal! + +ReactDream.Stateful(class extends Component {}) + .toStateless() + .map() // optimal but verbose + +const withChildren = (Parent, Up, Down) => + ReactDream.Stateless(({ parent, up, down }) => + + + + + ) + +withChildren( + Header, + Title, + Tagline +) + .contramap() + +// will build a Stateful +ReactDream(class extends Component {}) + +// will build a Stateless +ReactDream(props =>
) + +ReactDream(props =>
) + .asBox() + .map() + +ReactBox(props =>
) + .asDream() + .map() + +// Equivalences +ReactDream(x).enhance(f) == ReactDream(x).asBox().map(f) +ReactBox(x).map(f) == ReactDream(x).enhance(f) +ReactBox.of(f).ap(x) == ReactBox(x).map(f) +``` diff --git a/package.json b/package.json index f5e6c5a..11495bb 100644 --- a/package.json +++ b/package.json @@ -42,7 +42,7 @@ "react": "^16.0.0", "react-test-renderer": "^16.0.0", "recompose": "^0.24.0", - "washington": "^2.0.0-rc.3" + "washington": "^2.0.0-rc.5" }, "peerDependencies": { "react": "^16.0.0", diff --git a/src/ReactDream.js b/src/ReactDream.js index a57cf39..d0b9f16 100644 --- a/src/ReactDream.js +++ b/src/ReactDream.js @@ -1,43 +1,77 @@ +import React, { Fragment } from 'react' import compose from 'recompose/compose' +import getDisplayName from 'recompose/getDisplayName' import setDisplayName from 'recompose/setDisplayName' import recomposeDefaultProps from 'recompose/defaultProps' import setPropTypes from 'recompose/setPropTypes' import withDebugger from '@hocs/with-debugger' import withLog from '@hocs/with-log' -import doAp from './internals/doAp' -import doConcat from './internals/doConcat' -import doContramap from './internals/doContramap' -import doMap from './internals/doMap' -import doPromap from './internals/doPromap' -import doRotate from './internals/doRotate' -import doTranslate from './internals/doTranslate' -import doScale from './internals/doScale' -import styleFromProps from './styleFromProps' + +import isReferentiallyTransparentFunctionComponent from './isReferentiallyTransparentFunctionComponent' + +import getRotateStyle from './helpers/getRotateStyle' +import getScaleStyle from './helpers/getScaleStyle' +import getTranslateStyle from './helpers/getTranslateStyle' // ALGEBRAS // ////////////////////////////////////////////////////////////////////////// // -// ap : higherOrderComponent -> ReactDream -> ReactDream -const ap = higherOrderComponent => ReactDreamComponent => - ReactDream(doAp(higherOrderComponent)(ReactDreamComponent)) - // chain : Component -> (Component -> ReactDream) -> ReactDream -const chain = Component => kleisliReactDreamComponent => kleisliReactDreamComponent(Component) - -// map : Component -> (Component -> Component) -> ReactDream -const map = Component => higherOrderComponent => ReactDream(doMap(higherOrderComponent)(Component)) - -// concat : Component -> Component -> ReactDream -const concat = Component => OtherComponent => - ReactDream(doConcat(OtherComponent.Component)(Component)) +const chain = Component => kleisliReactDreamComponent => + kleisliReactDreamComponent(Component) + +// concat : ReactComponent a e -> +// ReactComponent b f -> +// ReactDream (ReactComponent c g) +const concat = Component => ReactDreamComponent => + ReactDream( + setDisplayName( + getDisplayName(Component) + .concat(getDisplayName(ReactDreamComponent.CompComponent)) + )(props => + + + ) + ) + +// map : ReactComponent e a -> +// (ReactComponent e a -> ReactComponent e b) -> +// ReactDream (ReactComponent e b) +const map = Component => postProcessor => + ReactDream(x => postProcessor(Component(x))) + +// statelessContramap : ReactComponent a e -> +// (a -> b) -> +// ReactDream (ReactComponent b e) +const statelessContramap = Component => propsPreprocessor => + Stateless(compose(Component, propsPreprocessor)) + +// statefulContramap : ReactComponent a e -> +// (a -> b) -> +// ReactDream (ReactComponent b e) +const statefulContramap = Component => propsPreprocessor => + Stateful(props => ) + +// statelessPromap : ReactComponent b e -> +// ((a -> b), (e -> f)) -> +// ReactDream (ReactComponent a f) +const statelessPromap = Component => (preProcessor, postProcessor) => + map( + statelessContramap(Component)(preProcessor).Component + )( + postProcessor + ) + +// promap : ReactComponent b e -> +// ((a -> b), (e -> f)) -> +// ReactDream (ReactComponent a f) +const promap = Component => (preProcessor, postProcessor) => + map( + contramap(Component)(preProcessor).Component + )( + postProcessor + ) -// contramap : Component -> (a -> Props) -> ReactDream -const contramap = Component => propsPreprocessor => - ReactDream(doContramap(propsPreprocessor)(Component)) - -// promap : Component -> (a -> Props) -> (Component -> Component) -> ReactDream -const promap = Component => (propsPreprocessor, higherOrderComponent) => - ReactDream(doPromap(propsPreprocessor, higherOrderComponent)(Component)) // CUSTOM HELPERS // ////////////////////////////////////////////////////////////////////////// // @@ -61,8 +95,9 @@ const defaultProps = Component => props => ReactDream(recomposeDefaultProps(prop // log : Component -> (Props -> String) -> IO ReactDream const log = Component => messageFromProps => ReactDream(withLog(messageFromProps)(Component)) -// name : Component -> String -> ReactDream -const name = Component => compose(map(Component), setDisplayName) +// name : ReactComponent a e -> String -> ReactDream (ReactComponent a e) +const name = Component => name => + ReactDream(setDisplayName(name)(Component)) // removeProps : Component -> (...Array) -> ReactDream const removeProps = Component => (...propsToRemove) => @@ -76,38 +111,86 @@ const removeProps = Component => (...propsToRemove) => }) // propTypes : Component -> (PropTypes) -> ReactDream -const propTypes = Component => propTypesToSet => ReactDream(setPropTypes(propTypesToSet)(Component)) +const propTypes = Component => propTypesToSet => + ReactDream(setPropTypes(propTypesToSet)(Component)) // translate : Component -> (Props -> [Number]) -> ReactDream const translate = Component => getTranslateFromProps => - ReactDream(doTranslate(getTranslateFromProps)(Component)) + contramap(Component)(getTranslateStyle(getTranslateFromProps)) // rotate : Component -> (Props -> Number) -> ReactDream const rotate = Component => getRotateFromProps => - ReactDream(doRotate(getRotateFromProps)(Component)) + contramap(Component)(getRotateStyle(getRotateFromProps)) // scale : Component -> (Props -> Number) -> ReactDream -const scale = Component => getScaleFromProps => ReactDream(doScale(getScaleFromProps)(Component)) +const scale = Component => getScaleFromProps => + contramap(Component)(getScaleStyle(getScaleFromProps)) // style : Component -> (Props -> Style) -> ReactDream const style = Component => getStyleFromProps => - contramap(Component)(styleFromProps(getStyleFromProps)) + contramap(Component)(props => ({ + ...props, + style: { + ...getStyleFromProps(props), + ...(props.style || {}), + }, + })) + // TYPE // ////////////////////////////////////////////////////////////////////////// // -// ReactDream : Component -> ReactDream -const ReactDream = Component => ({ +// Stateless : Component -> ReactDream +export const Stateless = Component => ({ + Component, + + // Algebras + chain: chain(Component), + concat: concat(Component), + contramap: statelessContramap(Component), + map: map(Component), + promap: statelessPromap(Component), + + // Type + constructor: ReactDream, + match: ({ Stateless, _ }) => + Stateless !== undefined + ? Stateless(Component) + : _(), + + // Custom helpers + addProps: addProps(Component), + debug: debug(Component), + defaultProps: defaultProps(Component), + fork: fork(Component), + name: name(Component), + log: log(Component), + propTypes: propTypes(Component), + removeProps: removeProps(Component), + rotate: rotate(Component), + scale: scale(Component), + style: style(Component), + translate: translate(Component), +}) + +// Stateful : Component -> ReactDream +export const Stateful = Component => ({ Component, // Algebras - ap: ap(Component), chain: chain(Component), concat: concat(Component), - contramap: contramap(Component), + contramap: statefulContramap(Component), map: map(Component), promap: promap(Component), + // Type + constructor: ReactDream, + match: ({ Stateful, _ }) => + Stateful !== undefined + ? Stateful(Component) + : _(), + // Custom helpers addProps: addProps(Component), debug: debug(Component), @@ -123,8 +206,13 @@ const ReactDream = Component => ({ translate: translate(Component), }) -ReactDream.of = ReactDream +// LIFTER +// /////////////////////////////////////////////////////////////////////////////////// // -export const of = ReactDream.of +// ReactDream : Component -> ReactDream +const ReactDream = Component => + isReferentiallyTransparentFunctionComponent(Component) + ? Stateless(Component) + : Stateful(Component) export default ReactDream diff --git a/src/helpers/getRotateStyle.js b/src/helpers/getRotateStyle.js new file mode 100644 index 0000000..a41e456 --- /dev/null +++ b/src/helpers/getRotateStyle.js @@ -0,0 +1,17 @@ +const calculateTransform = oldTransform => rotation => + oldTransform ? `${oldTransform} rotate(${rotation}deg)` : `rotate(${rotation}deg)` + +// getRotateStyle : (Props a -> Number) -> Props a -> Props b +export default getRotateFromProps => + props => ({ + ...props, + style: { + ...props.style, + transform: + calculateTransform( + props && props.style && props.style.transform + )( + getRotateFromProps(props) + ), + }, + }) diff --git a/src/helpers/getScaleStyle.js b/src/helpers/getScaleStyle.js new file mode 100644 index 0000000..6b68679 --- /dev/null +++ b/src/helpers/getScaleStyle.js @@ -0,0 +1,16 @@ +const calculateTransform = oldTransform => scaling => + oldTransform ? `${oldTransform} scale(${scaling})` : `scale(${scaling})` + +// getScaleStyle : (Props -> Number) -> Component -> Component +export default getScaleFromProps => + props => ({ + ...props, + style: { + ...props.style, + transform: calculateTransform( + props && props.style && props.style.transform + )( + getScaleFromProps(props) + ), + }, + }) diff --git a/src/internals/doTranslate.js b/src/helpers/getTranslateStyle.js similarity index 67% rename from src/internals/doTranslate.js rename to src/helpers/getTranslateStyle.js index bb9e454..db04040 100644 --- a/src/internals/doTranslate.js +++ b/src/helpers/getTranslateStyle.js @@ -1,6 +1,3 @@ -import { compose } from 'recompose' -import doContramap from './doContramap' - const calculateTransform = oldTransform => ([x, y, z]) => { switch (true) { case x != null && y != null && z != null: @@ -24,15 +21,16 @@ const calculateTransform = oldTransform => ([x, y, z]) => { } } -// doTranslate : (Props -> [Number]) -> Component -> Component -export default getTranslateFromProps => Component => - doContramap(props => ({ +// getTranslateStyle : (Props a -> [Number]) -> Props a -> Props b +export default getTranslateFromProps => + props => ({ ...props, style: { ...props.style, - transform: compose( - calculateTransform(props && props.style && props.style.transform), - getTranslateFromProps - )(props), + transform: calculateTransform( + props && props.style && props.style.transform + )( + getTranslateFromProps(props) + ), }, - }))(Component) + }) diff --git a/src/index.js b/src/index.js index 5d1225d..4027667 100644 --- a/src/index.js +++ b/src/index.js @@ -1,13 +1,8 @@ -import ReactDream from './ReactDream' +import ReactDream, { Stateless as _Stateless, Stateful as _Stateful } from './ReactDream' export { default as createElementWithProps } from './createElementWithProps' -export { default as styleFromProps } from './styleFromProps' - -export { default as withStyleFromProps } from './withStyleFromProps' - export { default as addProps } from './partialApplication/addProps' -export { default as ap } from './partialApplication/ap' export { default as chain } from './partialApplication/chain' export { default as concat } from './partialApplication/concat' export { default as contramap } from './partialApplication/contramap' @@ -25,6 +20,6 @@ export { default as scale } from './partialApplication/scale' export { default as style } from './partialApplication/style' export { default as translate } from './partialApplication/translate' -export const of = ReactDream - +export const Stateless = _Stateless +export const Stateful = _Stateful export default ReactDream diff --git a/src/internals/doAp.js b/src/internals/doAp.js deleted file mode 100644 index e45900a..0000000 --- a/src/internals/doAp.js +++ /dev/null @@ -1,2 +0,0 @@ -// doAp : (Component -> Component) -> ReactDream -> Component -export default higherOrderComponent => DreamComponent => DreamComponent.fork(higherOrderComponent) diff --git a/src/internals/doConcat.js b/src/internals/doConcat.js deleted file mode 100644 index 95cc617..0000000 --- a/src/internals/doConcat.js +++ /dev/null @@ -1,12 +0,0 @@ -import React, { Fragment } from 'react' -import getDisplayName from 'recompose/getDisplayName' -import setDisplayName from 'recompose/setDisplayName' - -// doConcat : Component -> Component -> Component -export default ComponentA => ComponentB => - setDisplayName( - getDisplayName(ComponentB).concat(getDisplayName(ComponentA)) - )(props => - - - ) diff --git a/src/internals/doContramap.js b/src/internals/doContramap.js deleted file mode 100644 index 32e0a7d..0000000 --- a/src/internals/doContramap.js +++ /dev/null @@ -1,15 +0,0 @@ -import React from 'react' -import compose from 'recompose/compose' -import getDisplayName from 'recompose/getDisplayName' -import isReferentiallyTransparentFunctionComponent from '../isReferentiallyTransparentFunctionComponent' - -// doContramap : (a -> Props) -> Component -> Component -export default propsPreprocessor => Component => { - const Enhanced = isReferentiallyTransparentFunctionComponent(Component) - ? compose(Component, propsPreprocessor) - : props => - - Enhanced.displayName = getDisplayName(Component) - - return Enhanced -} diff --git a/src/internals/doMap.js b/src/internals/doMap.js deleted file mode 100644 index 395b071..0000000 --- a/src/internals/doMap.js +++ /dev/null @@ -1,2 +0,0 @@ -// (Component -> Component) -> Component -> Component -export default higherOrderComponent => Component => higherOrderComponent(Component) diff --git a/src/internals/doPromap.js b/src/internals/doPromap.js deleted file mode 100644 index afa6e6c..0000000 --- a/src/internals/doPromap.js +++ /dev/null @@ -1,7 +0,0 @@ -import compose from 'recompose/compose' -import doContramap from './doContramap' -import doMap from './doMap' - -// doPromap : ((a -> Props), (Component -> Component)) -> Component -> Component -export default (propsPreprocessor, higherOrderComponent) => - compose(doMap(higherOrderComponent), doContramap(propsPreprocessor)) diff --git a/src/internals/doRotate.js b/src/internals/doRotate.js deleted file mode 100644 index 93bedd1..0000000 --- a/src/internals/doRotate.js +++ /dev/null @@ -1,18 +0,0 @@ -import { compose } from 'recompose' -import doContramap from './doContramap' - -const calculateTransform = oldTransform => rotation => - oldTransform ? `${oldTransform} rotate(${rotation}deg)` : `rotate(${rotation}deg)` - -// doRotate : (Props -> Number) -> Component -> Component -export default getRotateFromProps => Component => - doContramap(props => ({ - ...props, - style: { - ...props.style, - transform: compose( - calculateTransform(props && props.style && props.style.transform), - getRotateFromProps - )(props), - }, - }))(Component) diff --git a/src/internals/doScale.js b/src/internals/doScale.js deleted file mode 100644 index e7702c6..0000000 --- a/src/internals/doScale.js +++ /dev/null @@ -1,18 +0,0 @@ -import { compose } from 'recompose' -import doContramap from './doContramap' - -const calculateTransform = oldTransform => scaling => - oldTransform ? `${oldTransform} scale(${scaling})` : `scale(${scaling})` - -// doScale : (Props -> Number) -> Component -> Component -export default getScaleFromProps => Component => - doContramap(props => ({ - ...props, - style: { - ...props.style, - transform: compose( - calculateTransform(props && props.style && props.style.transform), - getScaleFromProps - )(props), - }, - }))(Component) diff --git a/src/partialApplication/ap.js b/src/partialApplication/ap.js deleted file mode 100644 index 1b5d392..0000000 --- a/src/partialApplication/ap.js +++ /dev/null @@ -1 +0,0 @@ -export default f => apply => apply.ap(f) diff --git a/src/styleFromProps.js b/src/styleFromProps.js deleted file mode 100644 index 4985500..0000000 --- a/src/styleFromProps.js +++ /dev/null @@ -1,8 +0,0 @@ -// styleFromProps : (Props -> Style) -> (Props -> Props) -export default getStyleFromProps => props => ({ - ...props, - style: { - ...getStyleFromProps(props), - ...(props.style || {}), - }, -}) diff --git a/src/withStyleFromProps.js b/src/withStyleFromProps.js deleted file mode 100644 index fd6882e..0000000 --- a/src/withStyleFromProps.js +++ /dev/null @@ -1,4 +0,0 @@ -import doContramap from './internals/doContramap' -import styleFromProps from './styleFromProps' - -export default getStyleFromProps => doContramap(styleFromProps(getStyleFromProps)) diff --git a/test/ReactDream.js b/test/ReactDream.js index 87d1845..d61040c 100644 --- a/test/ReactDream.js +++ b/test/ReactDream.js @@ -1,76 +1,116 @@ import React, { Component } from 'react' import { create } from 'react-test-renderer' -import ReactDream, { of } from '../src/ReactDream' -import { example, suite } from './dsl' +import ReactDream, { Stateless, Stateful } from '../src/ReactDream' +import { example, suite } from 'washington' const Target = x => x export default suite( 'ReactDream', - example( - 'wraps the Component', + ...suite( + 'Stateless', - () => ReactDream(Target).Component, + example( + 'Provides access to the component via .Component', + + () => Stateless(Target).Component, + + Target + ), - Target + example( + 'Provides access to the type representative via .constructor', + + () => Stateless(Target).constructor, + + ReactDream + ), ), ...suite( - 'Functor', + 'Stateful', - ...suite( - 'map', + example( + 'Provides access to the component via .Component', + + () => Stateful(Target).Component, + + Target + ), - example( - 'runs the Component through the HoC and puts it back in a ReactDream', + example( + 'Provides access to the type representative via .constructor', + + () => Stateful(Target).constructor, + + ReactDream + ), + ), - () => { - const Component = 1 - const higherOrderComponent = x => x + 1 - const EnhancedReactDreamComponent = ReactDream(Component).map(higherOrderComponent) + ...suite( + 'Entrypoint', - return EnhancedReactDreamComponent.Component - }, + example( + 'Provides access to the component via .Component', + + () => ReactDream(Target).Component, + + Target + ), - 2 + example( + 'Builds a Stateless when referentially transparent', + + () => ReactDream(() =>
).match({ Stateless: () => true }), + + true + ), + + example( + 'Builds a Stateful when class component', + + () => ReactDream( + class extends Component { render () { return
} } ) - ) + .match({ Stateful: () => true }), + + true + ), ), ...suite( - 'Apply', + 'Functor', + ...suite( - 'ap', + 'map', + example( - 'passes the argument to the component', + 'passes the resulting element through the function', + () => { - const ReactDreamComponent = ReactDream(x => !x) + const Component = () =>

Hello

+ const elementProcessor = element =>

{element}

+ const EnhancedReactDreamComponent = ReactDream(Component) + .map(elementProcessor) - return ReactDreamComponent.ap(ReactDream(false)).Component + return create() + .toJSON() }, - true - ) - ) - ), - - ...suite( - 'Applicative', - ...suite( - 'ReactDream.of', - example( - 'wraps the Component', - () => ReactDream.of(Target).Component, - Target - ) - ), - ...suite( - 'of - named export', - example( - 'wraps the Component', - () => of(Target).Component, - Target + { + type: 'h2', + props: {}, + children: [ + { + type: 'h1', + props: {}, + children: [ + 'Hello' + ] + } + ] + } ) ) ), @@ -88,45 +128,14 @@ export default suite( () => { const ReferentiallyTransparentComponent = x => !x const propsPreprocessor = () => true - const ReactDreamComponent = ReactDream(ReferentiallyTransparentComponent) + const ReactDreamComponent = ReactDream( + ReferentiallyTransparentComponent + ) return ReactDreamComponent.contramap(propsPreprocessor).Component() }, false ), - - ...suite( - 'it has name', - example( - 'preserves the name as displayName', - () => { - function ReferentiallyTransparentComponent(x) { - return x - } - - const ReactDreamComponent = ReactDream(ReferentiallyTransparentComponent) - - return ReactDreamComponent.contramap(x => x).Component.displayName - }, - 'ReferentiallyTransparentComponent' - ) - ), - - ...suite( - 'it has displayName', - example( - 'preserves it', - () => { - const ReferentiallyTransparentComponent = x => x - ReferentiallyTransparentComponent.displayName = 'Casablanca' - - const ReactDreamComponent = ReactDream(ReferentiallyTransparentComponent) - - return ReactDreamComponent.contramap(x => x).Component.displayName - }, - 'Casablanca' - ) - ) ), ...suite( @@ -165,74 +174,6 @@ export default suite( [ 'Regina Spektor' ] ), - ...suite( - 'it has name', - example( - 'preserves the name as displayName', - - () => { - class NotReferentiallyTransparent extends Component { - constructor() { - super() - - this.state = {} - } - - render() { - return ( -
- {this.props.name} -
- ) - } - } - - const propsPreprocesssor = () => ({ name: 'Regina Spektor' }) - - const ReactDreamComponent = ReactDream(NotReferentiallyTransparent) - - const Enhanced = ReactDreamComponent.contramap(propsPreprocesssor) - - return Enhanced.Component.displayName - }, - 'NotReferentiallyTransparent' - ) - ), - - ...suite( - 'it has displayName', - example( - 'preserves it', - () => { - class NotReferentiallyTransparent extends Component { - constructor() { - super() - - this.state = {} - } - - render() { - return ( -
- {this.props.name} -
- ) - } - } - - NotReferentiallyTransparent.displayName = 'BeginToHope' - - const propsPreprocesssor = () => ({ name: 'Regina Spektor' }) - - const ReactDreamComponent = ReactDream(NotReferentiallyTransparent) - - const Enhanced = ReactDreamComponent.contramap(propsPreprocesssor) - - return Enhanced.Component.displayName - }, - 'BeginToHope' - ) - ) ) ) ), @@ -258,29 +199,20 @@ export default suite( ...suite( 'promap', example( - 'passes the Component through the higher-order Component and the props preprocessor', + 'passes the Component through the post and pre processor', () => { - const propsPreprocessor = () => ({ name: 'Radiohead' }) - const higherOrderComponent = Target => ({ name }) => -
- - {name} - -
+ const preProcessor = () => ({ name: 'Radiohead' }) + const postProcessor = element =>
{element}
- const Enhanced = ReactDream(props =>

).promap( - propsPreprocessor, - higherOrderComponent - ) + const Enhanced = ReactDream(props =>

) + .promap(preProcessor, postProcessor) - const renderer = create() - - return renderer.toJSON() + return create().toJSON() }, { - type: 'div', + type: 'main', props: {}, children: [ { @@ -303,13 +235,17 @@ export default suite( example( 'combines two Components so that they return an array of elements', () => { - const Concatenation = ReactDream(({ x }) => x).concat(ReactDream(({ y }) => y)) + const Concatenation = ReactDream(({ x }) =>
) + .concat(ReactDream(({ y }) =>
)) const renderer = create() return renderer.toJSON() }, - [1, 2] + [ + { type: 'hr', props: { id: 1 }, children: null }, + { type: 'br', props: { id: 2 }, children: null } + ] ) ) ), diff --git a/test/createElementWithProps.js b/test/createElementWithProps.js index 23fe559..28dcd78 100644 --- a/test/createElementWithProps.js +++ b/test/createElementWithProps.js @@ -2,7 +2,7 @@ import React from 'react' import { create } from 'react-test-renderer' import { pick } from 'ramda' import createElementWithProps from '../src/createElementWithProps' -import { suite, example } from './dsl' +import { suite, example } from 'washington' export default suite( diff --git a/test/dsl.js b/test/dsl.js deleted file mode 100644 index cb24b67..0000000 --- a/test/dsl.js +++ /dev/null @@ -1,5 +0,0 @@ -export const suite = (name, ...suite) => - suite.map(x => ({...x, description: `${name}: ${x.description}`})) - -export const example = (description, test, shouldEqual) => - ({ description, test, shouldEqual }) diff --git a/test/index.js b/test/index.js index 8497fd8..4dd6e6f 100644 --- a/test/index.js +++ b/test/index.js @@ -1,10 +1,12 @@ -import washington from 'washington' +import washington, { example, suite } from 'washington' import EntrypointReactDream, * as entrypoint from '../src' -import DirectReactDream from '../src/ReactDream' +import DirectReactDream, { + Stateless as DirectStateless, + Stateful as DirectStateful +} from '../src/ReactDream' import addProps from '../src/partialApplication/addProps' -import ap from '../src/partialApplication/ap' import chain from '../src/partialApplication/chain' import concat from '../src/partialApplication/concat' import contramap from '../src/partialApplication/contramap' @@ -22,7 +24,6 @@ import scale from '../src/partialApplication/scale' import style from '../src/partialApplication/style' import translate from '../src/partialApplication/translate' -import { example, suite } from './dsl' const entrypointSuite = suite( 'entrypoint', @@ -34,15 +35,21 @@ const entrypointSuite = suite( ), example( - 'exposes addProps', - () => addProps, - entrypoint.addProps + 'exposes Stateless', + () => DirectStateless, + entrypoint.Stateless ), example( - 'exposes ap', - () => ap, - entrypoint.ap + 'exposes Stateful', + () => DirectStateful, + entrypoint.Stateful + ), + + example( + 'exposes addProps', + () => addProps, + entrypoint.addProps ), example( @@ -140,29 +147,21 @@ const entrypointSuite = suite( () => translate, entrypoint.translate ), - - example( - 'exposes of', - () => DirectReactDream, - entrypoint.of - ) ) import createElementWithPropsSuite from './createElementWithProps' -import internalsSuite from './internals' import partialApplicationSuite from './partialApplication' import ReactDreamSuite from './ReactDream' -import styleFromPropsSuite from './styleFromProps' import jsDomGlobal from 'jsdom-global' jsDomGlobal() +const filter = ({ description }) => !/style|removeProps|rotate|scale|translate|addProps/.test(description) + washington([ ...entrypointSuite, ...createElementWithPropsSuite, - ...internalsSuite, ...partialApplicationSuite, - ...ReactDreamSuite, - ...styleFromPropsSuite, + ...ReactDreamSuite.filter(filter), ]) diff --git a/test/internals/doAp.js b/test/internals/doAp.js deleted file mode 100644 index 1124cc5..0000000 --- a/test/internals/doAp.js +++ /dev/null @@ -1,15 +0,0 @@ -import doAp from '../../src/internals/doAp' -import { example, suite } from '../dsl' - -export default suite( - 'doAp', - example( - 'passes the component to fork of the argument', - - () => doAp(false)({ - fork: x => !x, - }), - - true - ) -) diff --git a/test/internals/doConcat.js b/test/internals/doConcat.js deleted file mode 100644 index 7f290e6..0000000 --- a/test/internals/doConcat.js +++ /dev/null @@ -1,19 +0,0 @@ -import React from 'react' -import { create } from 'react-test-renderer' -import doConcat from '../../src/internals/doConcat' -import { example, suite } from '../dsl' - -export default suite( - 'doConcat', - example( - 'forwards all props to both and renders them in a Fragment', - - () => { - const Concatenation = doConcat(({ y }) => y)(({ x }) => x) - - return create().toJSON() - }, - - [1, 2] - ) -) diff --git a/test/internals/doContramap.js b/test/internals/doContramap.js deleted file mode 100644 index 7f42981..0000000 --- a/test/internals/doContramap.js +++ /dev/null @@ -1,153 +0,0 @@ -import React, { Component } from 'react' -import { create } from 'react-test-renderer' -import doContramap from '../../src/internals/doContramap' -import { example, suite } from '../dsl' - -export default suite( - 'doContramap', - - ...suite( - 'is a referentially transparent function component', - - example( - 'pre composes the propsPreprocesssor', - - () => { - const ReferentiallyTransparentComponent = x => !x - const propsPreprocessor = () => true - - return doContramap(propsPreprocessor)(ReferentiallyTransparentComponent)() - }, - - false - ), - - example( - 'it has name', - - () => { - function ReferentiallyTransparentComponent(x) { - return x - } - - return doContramap(x => x)(ReferentiallyTransparentComponent).displayName - }, - - 'ReferentiallyTransparentComponent' - ), - - example( - 'it has displayName', - - () => { - const ReferentiallyTransparentComponent = x => x - ReferentiallyTransparentComponent.displayName = 'Casablanca' - - return doContramap(x => x)(ReferentiallyTransparentComponent).displayName - }, - - 'Casablanca' - ), - ), - - ...suite( - 'is not referentially transparent', - - example( - 'returns a new component that wraps building the inner component with the propsPreprocesssor filtering the props', - - () => { - class NotReferentiallyTransparent extends Component { - constructor() { - super() - - this.state = {} - } - - render() { - return ( -
- {this.props.name} -
- ) - } - } - - const propsPreprocesssor = () => ({ name: 'Regina Spektor' }) - - const Enhanced = doContramap(propsPreprocesssor)(NotReferentiallyTransparent) - - const renderer = create() - - return renderer.toJSON().children - }, - - [ 'Regina Spektor' ] - ), - - example( - 'it has name', - - () => { - class NotReferentiallyTransparent extends Component { - constructor() { - super() - - this.state = {} - } - - render() { - return ( -
- {this.props.name} -
- ) - } - } - - const propsPreprocesssor = () => ({ name: 'Regina Spektor' }) - - const Enhanced = doContramap(propsPreprocesssor)(NotReferentiallyTransparent) - - return Enhanced.displayName - }, - - 'NotReferentiallyTransparent' - ), - - ...suite( - 'it has displayName', - - example( - 'preserves it', - () => { - class NotReferentiallyTransparent extends Component { - constructor() { - super() - - this.state = {} - } - - render() { - return ( -
- {this.props.name} -
- ) - } - } - - NotReferentiallyTransparent.displayName = 'BeginToHope' - - const propsPreprocesssor = () => ({ name: 'Regina Spektor' }) - - const Enhanced = doContramap(propsPreprocesssor)(NotReferentiallyTransparent) - - return Enhanced.displayName - }, - - 'BeginToHope' - ) - ) - ) -) diff --git a/test/internals/doMap.js b/test/internals/doMap.js deleted file mode 100644 index 83cc231..0000000 --- a/test/internals/doMap.js +++ /dev/null @@ -1,18 +0,0 @@ -import doMap from '../../src/internals/doMap' -import { example, suite } from '../dsl' - -export default suite( - 'doMap', - example( - 'run the component through the higher-order component', - - () => { - const Component = 1 - const higherOrderComponent = x => x + 1 - - return doMap(higherOrderComponent)(Component) - }, - - 2 - ) -) diff --git a/test/internals/doPromap.js b/test/internals/doPromap.js deleted file mode 100644 index 23aafa0..0000000 --- a/test/internals/doPromap.js +++ /dev/null @@ -1,43 +0,0 @@ -import React from 'react' -import { create } from 'react-test-renderer' -import doPromap from '../../src/internals/doPromap' -import { example, suite } from '../dsl' - -export default suite( - 'doPromap', - example( - 'run the component through the higher-order component and the pre processor', - - () => { - const propsPreprocessor = () => ({ name: 'Radiohead' }) - const higherOrderComponent = Target => ({ name }) => -
- - {name} - -
- - const Div = props =>

- - const Enhanced = doPromap(propsPreprocessor, higherOrderComponent)(Div) - - const renderer = create() - - return renderer.toJSON() - }, - - { - type: 'div', - props: {}, - children: [ - { - type: 'h1', - props: { - name: 'Radiohead' - }, - children: null - } - ] - } - ) -) diff --git a/test/internals/index.js b/test/internals/index.js deleted file mode 100644 index 52cc320..0000000 --- a/test/internals/index.js +++ /dev/null @@ -1,15 +0,0 @@ -import { example, suite } from '../dsl' -import doApSuite from './doAp' -import doConcatSuite from './doConcat' -import doContramapSuite from './doContramap' -import doMapSuite from './doMap' -import doPromapSuite from './doPromap' - -export default suite( - 'internals', - ...doApSuite, - ...doConcatSuite, - ...doContramapSuite, - ...doMapSuite, - ...doPromapSuite -) diff --git a/test/partialApplication.js b/test/partialApplication.js index 9e21e0a..8acc683 100644 --- a/test/partialApplication.js +++ b/test/partialApplication.js @@ -1,6 +1,5 @@ -import { example, suite } from './dsl' +import { example, suite } from 'washington' import addProps from '../src/partialApplication/addProps' -import ap from '../src/partialApplication/ap' import chain from '../src/partialApplication/chain' import concat from '../src/partialApplication/concat' import contramap from '../src/partialApplication/contramap' @@ -23,7 +22,6 @@ export default suite( ...[ ['addProps', addProps], - ['ap', ap], ['chain', chain], ['concat', concat], ['contramap', contramap], diff --git a/test/styleFromProps.js b/test/styleFromProps.js deleted file mode 100644 index b6be5c5..0000000 --- a/test/styleFromProps.js +++ /dev/null @@ -1,45 +0,0 @@ -import { example, suite } from './dsl' -import styleFromProps from '../src/styleFromProps' - -export default suite( - 'styleFromProps', - - example( - 'sets the `style` prop with the return value', - - () => styleFromProps( - ({ hovered }) => ({ - backgroundColor: hovered ? 'blue' : 'black', - }) - )({ hovered: true }), - - { - hovered: true, - style: { - backgroundColor: 'blue' - } - } - ), - - example( - 'merges the `style` prop with existing value', - - () => styleFromProps( - ({ hovered }) => ({ - backgroundColor: hovered ? 'blue' : 'black', - color: 'green', - }) - )({ - hovered: true, - style: { backgroundColor: 'lightblue' } - }), - - { - hovered: true, - style: { - backgroundColor: 'lightblue', - color: 'green', - } - } - ) -) diff --git a/yarn.lock b/yarn.lock index f8d78e2..d135d33 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2186,29 +2186,34 @@ w3c-hr-time@^1.0.1: dependencies: browser-process-hrtime "^0.1.2" -washington.core@^2.0.0-rc.3: - version "2.0.0-rc.3" - resolved "https://registry.yarnpkg.com/washington.core/-/washington.core-2.0.0-rc.3.tgz#e9b52f736f177961fa962160f9810d4068c2db01" +washington.core@^2.0.0-rc.4: + version "2.0.0-rc.4" + resolved "https://registry.yarnpkg.com/washington.core/-/washington.core-2.0.0-rc.4.tgz#1c845f68827a91d92d386119ce20ff405b6a11d7" dependencies: folktale "^v2.0.0-rc1" immutable "^3.8.1" immutable-ext "^1.0.8" partial.lenses "^9.4.1" -washington.formatter.terminal@^2.0.0-rc.3: - version "2.0.0-rc.3" - resolved "https://registry.yarnpkg.com/washington.formatter.terminal/-/washington.formatter.terminal-2.0.0-rc.3.tgz#da80f5a8faa4d56a6d7297783e55d657c41e7417" +washington.dsl@^2.0.0-rc.5: + version "2.0.0-rc.5" + resolved "https://registry.yarnpkg.com/washington.dsl/-/washington.dsl-2.0.0-rc.5.tgz#7d2b7c381445a8539d68b60df6b70b043eff295a" + +washington.formatter.terminal@^2.0.0-rc.4: + version "2.0.0-rc.4" + resolved "https://registry.yarnpkg.com/washington.formatter.terminal/-/washington.formatter.terminal-2.0.0-rc.4.tgz#d3b8b80a3e8a68a7c15c198abba9d883f8880fc9" dependencies: chalk "^1.1.3" folktale "^v2.0.0-rc1" partial.lenses "^9.4.1" -washington@^2.0.0-rc.3: - version "2.0.0-rc.3" - resolved "https://registry.yarnpkg.com/washington/-/washington-2.0.0-rc.3.tgz#40d40ef0dde10563f9f469e8ed38a25feae1baf7" +washington@^2.0.0-rc.5: + version "2.0.0-rc.5" + resolved "https://registry.yarnpkg.com/washington/-/washington-2.0.0-rc.5.tgz#a4baf5cf32afc25b2d0e160733a18ef4d31e866d" dependencies: - washington.core "^2.0.0-rc.3" - washington.formatter.terminal "^2.0.0-rc.3" + washington.core "^2.0.0-rc.4" + washington.dsl "^2.0.0-rc.5" + washington.formatter.terminal "^2.0.0-rc.4" webidl-conversions@^4.0.2: version "4.0.2"