Commit 9e872a96 authored by James Laver's avatar James Laver

v0.1.0

parent 953a4679
...@@ -20,13 +20,12 @@ ...@@ -20,13 +20,12 @@
"pulp": "^12.4.0", "pulp": "^12.4.0",
"purescript": "^0.12.5", "purescript": "^0.12.5",
"purs-loader": "^3.2.0", "purs-loader": "^3.2.0",
"react-testing-library": "^5.9.0", "react-testing-library": "^6.1.2",
"spago": "^0.7.5" "spago": "^0.7.5"
}, },
"dependencies": { "dependencies": {
"react": "^16.8.6", "react": "^16.8.6",
"react-dom": "^16.8.6", "react-dom": "^16.8.6"
"react-testing-library": "^6.1.2"
}, },
"eslintConfig": { "eslintConfig": {
"extends": "react-app" "extends": "react-app"
......
...@@ -123,6 +123,11 @@ let additions = ...@@ -123,6 +123,11 @@ let additions =
, "spec", "spec-mocha", "unsafe-coerce" ] , "spec", "spec-mocha", "unsafe-coerce" ]
"https://github.com/irresponsible/purescript-dom-simple" "https://github.com/irresponsible/purescript-dom-simple"
"master" "master"
, ffi-simple =
mkPackage
[ "functions", "nullable", "prelude" ]
"https://github.com/irresponsible/purescript-ffi-simple"
"v0.1.2"
, spec-mocha = , spec-mocha =
mkPackage mkPackage
[ "console", "foldable-traversable", "exceptions", "spec" ] [ "console", "foldable-traversable", "exceptions", "spec" ]
......
...@@ -6,10 +6,12 @@ ...@@ -6,10 +6,12 @@
[ "console" [ "console"
, "dom-simple" , "dom-simple"
, "effect" , "effect"
, "ffi-simple"
, "functions" , "functions"
, "newtype" , "newtype"
, "nullable" , "nullable"
, "prelude" , "prelude"
, "refs"
, "spec" , "spec"
, "spec-mocha" , "spec-mocha"
, "unsafe-coerce" ] , "unsafe-coerce" ]
......
module Reactix.DOM.Raw module Reactix.DOM.Raw
(LeafFactory, TreeFactory (LeafFactory, ElementFactory
, button, div, div', i, i', p, p', span, span' , button, div, div', hr
, i, i', p, p', span, span'
, text) where , text) where
import Reactix.React (Element, createDOMElement) import Reactix.React (Element, createElement)
import Unsafe.Coerce (unsafeCoerce) import Unsafe.Coerce (unsafeCoerce)
createLeafDOMElement :: forall props. String -> Record props -> Element createLeafElement :: forall props. String -> Record props -> Element
createLeafDOMElement e p = createDOMElement e p [] createLeafElement e p = createElement e p []
-- A factory function for a DOM element with no children -- A factory function for a DOM element with no children
type LeafFactory = forall props. Record props -> Element type LeafFactory = forall props. Record props -> Element
-- A factory function for a DOM element with children -- A factory function for a DOM element with children
type TreeFactory = forall props. Record props -> Array Element -> Element type ElementFactory = forall props. Record props -> Array Element -> Element
text :: String -> Element text :: String -> Element
text = unsafeCoerce text = unsafeCoerce
button :: TreeFactory button :: ElementFactory
button = createDOMElement "button" button = createElement "button"
div :: TreeFactory div :: ElementFactory
div = createDOMElement "div" div = createElement "div"
div' :: LeafFactory div' :: LeafFactory
div' = createLeafDOMElement "div" div' = createLeafElement "div"
i :: TreeFactory hr :: LeafFactory
i = createDOMElement "i" hr = createLeafElement "hr"
i :: ElementFactory
i = createElement "i"
i' :: LeafFactory i' :: LeafFactory
i' = createLeafDOMElement "i" i' = createLeafElement "i"
p :: TreeFactory p :: ElementFactory
p = createDOMElement "p" p = createElement "p"
p' :: LeafFactory p' :: LeafFactory
p' = createLeafDOMElement "p" p' = createLeafElement "p"
span :: TreeFactory span :: ElementFactory
span = createDOMElement "span" span = createElement "span"
span' :: LeafFactory span' :: LeafFactory
span' = createLeafDOMElement "span" span' = createLeafElement "span"
...@@ -4,12 +4,6 @@ var React = require("react"); ...@@ -4,12 +4,6 @@ var React = require("react");
function _simple(prop) { function _simple(prop) {
return function() { return React[prop].apply(React, arguments); }; return function() { return React[prop].apply(React, arguments); };
} }
function _tuple(prop) {
return function(ctor) {
const r = React[prop].apply(React, Array.prototype.slice.call(arguments, 1));
return ctor(r[0])(r[1]);
}
}
function _memo(prop) { function _memo(prop) {
return function() { return function() {
var args = Array.prototype.slice.call(arguments); var args = Array.prototype.slice.call(arguments);
...@@ -17,16 +11,13 @@ function _memo(prop) { ...@@ -17,16 +11,13 @@ function _memo(prop) {
return React[prop].apply(React, args); return React[prop].apply(React, args);
} }
} }
exports._tuple = function tuple(ctor, v) { return ctor(v[0])(v[1]); };
exports._useContext = _simple('useContext'); exports._useContext = _simple('useContext');
exports._useDebugValue = _simple('useDebugValue'); exports._useDebugValue = _simple('useDebugValue');
exports._useDebugValuePrime = _simple('useDebugValue'); exports._useDebugValuePrime = _simple('useDebugValue');
// exports._useImperativeHandle = _simple('useImperativeHandle'); // exports._useImperativeHandle = _simple('useImperativeHandle');
exports._useState = _tuple('useState');
exports._useReducer = _tuple('useReducer');
exports._useRef = function(ctor, value) { exports._useRef = function(ctor, value) {
const r = React.useRef(value); const r = React.useRef(value);
const set = function(v) { r.current = v; }; const set = function(v) { r.current = v; };
...@@ -40,16 +31,3 @@ exports._useMemo3 = _memo('useMemo'); ...@@ -40,16 +31,3 @@ exports._useMemo3 = _memo('useMemo');
exports._useMemo4 = _memo('useMemo'); exports._useMemo4 = _memo('useMemo');
exports._useMemo5 = _memo('useMemo'); exports._useMemo5 = _memo('useMemo');
exports._useEffect = _simple('useEffect');
exports._useEffect1 = _memo('useEffect');
exports._useEffect2 = _memo('useEffect');
exports._useEffect3 = _memo('useEffect');
exports._useEffect4 = _memo('useEffect');
exports._useEffect5 = _memo('useEffect');
exports._useLayoutEffect = _simple('useLayoutEffect');
exports._useLayoutEffect1 = _memo('useLayoutEffect');
exports._useLayoutEffect2 = _memo('useLayoutEffect');
exports._useLayoutEffect3 = _memo('useLayoutEffect');
exports._useLayoutEffect4 = _memo('useLayoutEffect');
exports._useLayoutEffect5 = _memo('useLayoutEffect');
This diff is collapsed.
'use strict'; 'use strict';
exports.react = require("react");
exports.reactDOM = require('react-dom');
var React = require("react");
var react_dom = require('react-dom');
function _simple(prop) {
return function() { return React[prop].apply(React, arguments); };
}
exports._isValid = _simple('isValidElement');
exports._children = function(c) { return React.Children.toArray(c); };
exports._memo = _simple('memo');
exports._memoPrime = _simple('memo');
exports._createRef = function() { return React.createRef(); };
exports._deref = function(r) { return r.current; };
// https://reactjs.org/docs/react-api.html#reactforwardref
// exports._forwardRef = _simple('forwardRef');
// creating and cloning elements
exports._cloneElement = _simple('cloneElement');
function _createElement(elem, props, children) {
var c = children.slice();
c.unshift(props);
c.unshift(elem);
return React.createElement.apply(React, c);
}
exports._createElement = _createElement;
exports._createFragment = function(children) {
return _createElement(React.Fragment, {}, children);
};
exports._contextProvider = function(c) { return c.Provider; };
exports._contextConsumer = function(c) { return c.Consumer; };
exports._createContext = function(ctor, val) {
var c = React.createContext(val);
return {provider: c.Provider, consumer: c.Consumer, context: c};
};
exports._render = function(a,b) { return react_dom.render(a,b); };
exports._named = function(name, f) { Object.defineProperty(f, 'name', {value: name, writable: false}); return f; };
This diff is collapsed.
-- | https://reactjs.org/docs/events.html
module Reactix.SyntheticEvent where
import Prelude
import DOM.Simple as DOM
import Effect ( Effect )
import Effect.Uncurried ( EffectFn1, runEffectFn1 )
import FFI.Simple ( (..), (...) )
class IsSyntheticEvent e
foreign import data NativeEvent :: Type
foreign import data MouseEvent :: Type
foreign import data KeyboardEvent :: Type
instance keyboardEventIsSyntheticEvent :: IsSyntheticEvent KeyboardEvent
instance mouseEventIsSyntheticEvent :: IsSyntheticEvent MouseEvent
bubbles :: forall e. IsSyntheticEvent e => e -> Boolean
bubbles e = e .. "bubbles"
cancelable :: forall e. IsSyntheticEvent e => e -> Boolean
cancelable e = e .. "cancelable"
isTrusted :: forall e. IsSyntheticEvent e => e -> Boolean
isTrusted e = e .. "isTrusted"
defaultPrevented :: forall e. IsSyntheticEvent e => e -> Boolean
defaultPrevented e = e .. "defaultPrevented"
eventPhase :: forall e. IsSyntheticEvent e => e -> Number
eventPhase e = e .. "eventPhase"
timestamp :: forall e. IsSyntheticEvent e => e -> Number
timestamp e = e .. "timeStamp"
type' :: forall e. IsSyntheticEvent e => e -> String
type' e = e .. "type"
-- target :: forall e. IsSyntheticEvent e => e -> NativeEventTarget
-- target e = e .. "target"
-- currentTarget :: forall e. IsSyntheticEvent e => e -> NativeEventTarget
-- currentTarget e = e .. "currentTarget"
-- nativeEvent :: forall e. IsSyntheticEvent e => e -> NativeEvent
-- nativeEvent e = e .. "nativeEvent"
stopPropagation :: forall e. IsSyntheticEvent e => e -> Effect Unit
stopPropagation e = e ... "stopPropagation" $ []
preventDefault :: forall e. IsSyntheticEvent e => e -> Effect Unit
preventDefault e = e ... "preventDefault" $ []
isPropagationStopped :: forall e. IsSyntheticEvent e => e -> Effect Unit
isPropagationStopped e = e ... "isPropagationStopped" $ []
isDefaultPrevented :: forall e. IsSyntheticEvent e => e -> Effect Unit
isDefaultPrevented e = e ... "isDefaultPrevented" $ []
-- Events with Modifier keys
-- | This class is used to access information about modifier keys for
-- | supported events
class HasModifierKeys e
instance mouseEventHasModifierKeys :: HasModifierKeys MouseEvent
instance keyboardEventHasModifierKeys :: HasModifierKeys KeyboardEvent
-- instance touchEventHasModifierKeys :: HasModifierKeys TouchEvent
altKey :: forall e. HasModifierKeys e => e -> Boolean
altKey e = e .. "altKey"
ctrlKey :: forall e. HasModifierKeys e => e -> Boolean
ctrlKey e = e .. "ctrlKey"
shiftKey :: forall e. HasModifierKeys e => e -> Boolean
shiftKey e = e .. "shiftKey"
metaKey :: forall e. HasModifierKeys e => e -> Boolean
metaKey e = e .. "metaKey"
getModifierState :: forall e. HasModifierKeys e => e -> String -> Boolean
getModifierState e s = e ... "getModifierState" $ [ s ]
-- Keyboard Events
key :: KeyboardEvent -> String
key e = e .. "key"
which :: KeyboardEvent -> Number
which e = e .. "which"
charCode :: KeyboardEvent -> Int
charCode e = e .. "charCode"
keyCode :: KeyboardEvent -> Number
keyCode e = e .. "keyCode"
locale :: KeyboardEvent -> String
locale e = e .. "locale"
location :: KeyboardEvent -> Number
location e = e .. "location"
repeat :: KeyboardEvent -> Boolean
repeat e = e .. "repeat"
button :: MouseEvent -> Number
button e = e .. "button"
buttons :: MouseEvent -> Number
buttons e = e .. "buttons"
-- relatedTarget :: MouseEvent -> NativeEventTarget
-- relatedTarget e = e .. "relatedTarget"
clientX :: MouseEvent -> Number
clientX e = e .. "clientX"
clientY :: MouseEvent -> Number
clientY e = e .. "clientY"
pageX :: MouseEvent -> Number
pageX e = e .. "pageX"
pageY :: MouseEvent -> Number
pageY e = e .. "pageY"
screenX :: MouseEvent -> Number
screenX e = e .. "screenX"
screenY :: MouseEvent -> Number
screenY e = e .. "screenY"
-- foreign import data TouchEvent :: Type
-- changedTouches :: TouchEvent -> NativeTouchList
-- targetTouches :: TouchEvent -> NativeTouchList
-- touches :: TouchEvent -> NativeTouchList
-- foreign import data NativeDataTransfer :: Type
-- foreign import data NativeAbstractView :: Type
-- foreign import data NativeTouchList :: Type
-- foreign import data AnimationEvent :: Type
-- animationName :: AnimationEvent -> String
-- pseudoElement :: AnimationEvent -> String
-- elapsedTime :: AnimationEvent -> Number
-- foreign import data ClipboardEvent :: Type
-- clipboardData :: ClipboardEvent -> NativeDataTransfer
-- foreign import data CompositionEvent :: Type
-- data' :: SyntheticCompositionEvent -> String
-- foreign import data FocusEvent :: Type
-- relatedTarget :: FocusEvent -> NativeEventTarget
-- foreign import data TransitionEvent :: Type
-- propertyName :: TransitionEvent -> String
-- pseudoElement :: TransitionEvent -> String
-- elapsedTime :: TransitionEvent -> Number
-- foreign import data UIEvent :: Type
-- detail :: UIEvent -> Number
-- view :: UIEvent -> NativeAbstractView
-- foreign import data WheelEvent :: Type
-- deltaMode :: WheelEvent -> Number
-- deltaX :: WheelEvent -> Number
-- deltaY :: WheelEvent -> Number
-- deltaZ :: WheelEvent -> Number
'use strict'; 'use strict';
const utils = require('react-dom/test-utils'); 'use strict';
const test = require('react-testing-library'); exports.testUtils = require('react-dom/test-utils');
exports.testingLibrary = require('react-testing-library');
function spread(obj,prop) {
return function() {
return obj[prop].apply(obj, Array.from(arguments));
};
}
exports._act = function(e) {
var ret;
utils.act(function() { ret = e(); });
return ret;
};
exports._render = spread(test,'render');
exports._fireEvent = function(name, obj) {
test.fireEvent[name].call(test.fireEvent, obj);
};
...@@ -3,36 +3,48 @@ module Reactix.Test ...@@ -3,36 +3,48 @@ module Reactix.Test
, render , render
, Rendered , Rendered
, fireEvent, fireClick , fireEvent, fireClick
, cleanup
) where ) where
import Prelude ( Unit ) import Prelude
import Effect ( Effect ) import Effect ( Effect )
import Effect.Uncurried ( EffectFn1, runEffectFn1, EffectFn2, runEffectFn2 ) import Effect.Uncurried ( EffectFn1, runEffectFn1, EffectFn2, runEffectFn2 )
import Data.Function.Uncurried ( Fn2, runFn2 ) import Data.Function.Uncurried ( Fn2, runFn2 )
import DOM.Simple as DOM import DOM.Simple as DOM
import Reactix.React ( Element ) import Reactix.React ( react, Element )
import FFI.Simple ( (..), (...), delay )
import DOM.Simple.Console
foreign import data TestUtils :: Type
foreign import testUtils :: TestUtils
foreign import data Testing :: Type
foreign import testingLibrary :: Testing
type Rendered = type Rendered =
{ getByText :: EffectFn1 String Element { getByText :: String -> Effect Element
, getByTestId :: EffectFn1 String Element , getByTestId :: String -> Effect Element
, container :: DOM.Element , container :: DOM.Element
, asFragment :: Effect DOM.Fragment } , asFragment :: Effect DOM.Fragment }
render :: Element -> Effect Rendered render :: Element -> Effect Rendered
render = runEffectFn1 _render render e = pure $ raw { getByText=getByText, getByTestId=getByTestId }
where getByText = runEffectFn1 raw.getByText
foreign import _render :: EffectFn1 Element Rendered getByTestId = runEffectFn1 raw.getByTestId
raw = testingLibrary ... "render" $ [e]
-- | Make react behave more predictably in tests -- | Make react behave more predictably in tests
act :: forall t. Effect t -> Effect t act :: forall t. (Unit -> Effect t) -> Effect t
act = runEffectFn1 _act act f = testUtils ... "act" $ [ delay f ]
foreign import _act :: forall t. EffectFn1 (Effect t) t
fireClick :: DOM.Element -> Effect Unit fireClick :: DOM.Element -> Effect Unit
fireClick = fireEvent "click" fireClick = fireEvent "click"
fireEvent :: String -> DOM.Element -> Effect Unit fireEvent :: String -> DOM.Element -> Effect Unit
fireEvent = runEffectFn2 _fireEvent fireEvent ev el = pure $ (testingLibrary .. "fireEvent") ... ev $ [el]
cleanup :: Effect Unit
cleanup = delay $ \_ -> pure $ testingLibrary ... "cleanup" $ []
foreign import _fireEvent :: EffectFn2 String DOM.Element Unit
...@@ -8,35 +8,35 @@ import Data.Traversable ( traverse, traverse_, sequence_ ) ...@@ -8,35 +8,35 @@ import Data.Traversable ( traverse, traverse_, sequence_ )
import Data.Tuple ( Tuple(..) ) import Data.Tuple ( Tuple(..) )
import Data.Tuple.Nested ( (/\) ) import Data.Tuple.Nested ( (/\) )
import Effect ( Effect ) import Effect ( Effect )
import Effect.Aff ( Aff )
import Effect.Class ( liftEffect ) import Effect.Class ( liftEffect )
import Effect.Ref as Ref
import Effect.Uncurried ( EffectFn1, mkEffectFn1, runEffectFn1 ) import Effect.Uncurried ( EffectFn1, mkEffectFn1, runEffectFn1 )
-- import Effect.Aff (launchAff_) -- import Effect.Aff (launchAff_)
import Test.Spec ( Spec, describe, it ) import Test.Spec ( Spec, describe, it )
import Test.Spec.Assertions ( shouldEqual ) import Test.Spec.Assertions ( shouldEqual )
-- import Test.Spec.QuickCheck (quickCheck') -- import Test.Spec.QuickCheck (quickCheck')
import DOM.Simple.Console ( log2 )
import DOM.Simple as DOM import DOM.Simple as DOM
import DOM.Simple.Document as Document import DOM.Simple.Document as Document
import DOM.Simple.Element as Element import DOM.Simple.Element as Element
import DOM.Simple.Event as Event import DOM.Simple.Event as Event
import Reactix as R import Reactix as R
import Reactix.Test as RT import Reactix.Test as RT
import Reactix.DOM.Raw ( button, div, i, text ) import Reactix.DOM.Raw ( button, div, i, text )
import Reactix.Hooks ( useState ) import Reactix.Hooks ( useState, useEffect, useLayoutEffect )
staticTest :: Spec Unit staticTest :: Spec Unit
staticTest = staticTest =
describe "Basic DOM rendering" do describe "Basic DOM rendering" $ do
it "Simple elements" do it "Simple elements" $ do
root <- liftEffect $ RT.render elem root <- liftEffect $ RT.render elem
(Element.name <$> Element.children root.container) `shouldEqual` ["I"] let children = Element.children root.container
it "Fragments" do (Element.name <$> children) `shouldEqual` ["I"]
children /\ count <- liftEffect $ (Element.innerHTML <$> children) `shouldEqual` ["hello world"]
do let root = Document.createElement "div" it "Fragments" $ do
RT.act $ R.render frag root root <- liftEffect $ RT.render $ frag
pure $ Tuple (Element.children root) (Element.childCount root) Element.childCount root.container `shouldEqual` 2
count `shouldEqual` 2 let children = Element.children root.container
A.length children `shouldEqual` 2 A.length children `shouldEqual` 2
(Element.name <$> children) `shouldEqual` ["I", "I"] (Element.name <$> children) `shouldEqual` ["I", "I"]
(Element.innerHTML <$> children) `shouldEqual` ["hello","world"] (Element.innerHTML <$> children) `shouldEqual` ["hello","world"]
...@@ -46,28 +46,26 @@ staticTest = ...@@ -46,28 +46,26 @@ staticTest =
type CounterProps = ( count :: Int ) type CounterProps = ( count :: Int )
counterCpt :: R.Component CounterProps counterCpt :: R.Component CounterProps
counterCpt = R.hooksLeaf "Counter" cpt counterCpt = R.hooksComponent "Counter" cpt
where where
cpt :: forall m. R.MonadHooks m => Record CounterProps -> m R.Element cpt {count} _ = do
cpt {count} = do y /\ setY <- useState $ \_ -> pure count
y /\ setY <- useState $ pure count
pure $ div { className: "counter" } pure $ div { className: "counter" }
[ button { type: "button", onClick: onclick setY (y + 1) } [ text "++" ] [ button { type: "button", onClick: onclick setY (y + 1) } [ text "++" ]
, div {} [ text (show y) ] ] , div {} [ text (show y) ] ]
onclick set to = mkEffectFn1 $ \e -> do onclick set to = mkEffectFn1 $ \e -> runEffectFn1 set to
runEffectFn1 set to
counterTest :: Spec Unit counterTest :: Spec Unit
counterTest = counterTest =
describe "Counter" do describe "Counter" do
it "Works for plain components" $ do it "Works for plain components" $ do
let counter = R.createLeaf counterCpt {count: 0} let counter = R.createElement counterCpt {count: 0} []
liftEffect (RT.render counter) >>= test liftEffect (RT.render counter) >>= test
it "Works for memoised components" $ do it "Works for memoised components" $ do
let counter = R.createLeaf (R.memo counterCpt (==)) {count: 0} let counter = R.createElement (R.memo counterCpt (==)) {count: 0} []
liftEffect (RT.render counter) >>= test liftEffect (RT.render counter) >>= test
it "works for memo'ised components" $ do it "works for memo'ised components" $ do
let counter = R.createLeaf (R.memo' counterCpt) {count: 0} let counter = R.createElement (R.memo' counterCpt) {count: 0} []
liftEffect (RT.render counter) >>= test liftEffect (RT.render counter) >>= test
where where
test root = do test root = do
...@@ -86,12 +84,105 @@ counterTest = ...@@ -86,12 +84,105 @@ counterTest =
A.length children4 `shouldEqual` 2 A.length children4 `shouldEqual` 2
(Element.innerHTML <$> children4) `shouldEqual` ["++", "2"] (Element.innerHTML <$> children4) `shouldEqual` ["++", "2"]
listTest :: Spec Unit data EffectorState = Fresh | Initialised | Done
listTest = pure unit
derive instance eqEffectorState :: Eq EffectorState
instance showEffectorState :: Show EffectorState where
show Fresh = "fresh"
show Initialised = "initialised"
show Done = "done"
type EffectorProps = ( stateRef :: Ref.Ref EffectorState )
effectorCpt :: R.Component EffectorProps
effectorCpt = R.hooksComponent "Effector" cpt
where cpt {stateRef} _ = do
useEffect $ \_ -> do
Ref.write Initialised stateRef
pure $ \_ -> Ref.write Done stateRef
pure $ div {} []
-- TODO: test it's firing at the right time
effectorTest :: Spec Unit
effectorTest =
describe "Effector" do
it "Works for plain components" $
test $ effectorCpt
it "works for memo'ised components" $
test $ R.memo' effectorCpt
where
test :: forall cpt. R.IsComponent cpt EffectorProps (Array R.Element) => cpt -> Aff Unit
test cpt = do
ref <- liftEffect $ Ref.new Fresh
let effector = R.createElement cpt {stateRef: ref} []
root <- liftEffect (RT.render effector)
state <- liftEffect $ Ref.read ref
state `shouldEqual` Initialised
liftEffect $ RT.cleanup
state' <- liftEffect $ Ref.read ref
state' `shouldEqual` Done
layoutEffectorCpt :: R.Component EffectorProps
layoutEffectorCpt = R.hooksComponent "LayoutEffector" cpt
where cpt {stateRef} _ = do
useLayoutEffect $ \_ -> do
Ref.write Initialised stateRef
pure $ \_ -> Ref.write Done stateRef
pure $ div {} []
-- TODO: test it's firing at the right time
layoutEffectorTest :: Spec Unit
layoutEffectorTest =
describe "LayoutEffector" do
it "Works for plain components" $
test $ layoutEffectorCpt
it "works for memo'ised components" $
test $ R.memo' layoutEffectorCpt
where
test :: forall cpt. R.IsComponent cpt EffectorProps (Array R.Element) => cpt -> Aff Unit
test cpt = do
ref <- liftEffect $ Ref.new Fresh
let effector = R.createElement cpt {stateRef: ref} []
root <- liftEffect (RT.render effector)
state <- liftEffect $ Ref.read ref
state `shouldEqual` Initialised
liftEffect $ RT.cleanup
state' <- liftEffect $ Ref.read ref
state' `shouldEqual` Done
type ContextProps = ()
-- contextualCpt :: R.Component ContextProps
-- contextualCpt = R.hooksComponent "Contextual" cpt
-- where cpt {stateRef} _ = do
-- useEffect $ \_ -> do
-- Ref.write Initialised stateRef
-- pure $ \_ -> Ref.write Done stateRef
-- pure $ div {} []
-- contextTest :: Spec Unit
-- contextTest =
-- describe "Context" do
-- it "Works for plain components" $
-- test $ contextualCpt
-- where test cpt = pure unit
-- reducerTest :: Spec Unit
-- memoTest :: Spec Unit
-- refTest :: Spec Unit
-- imperativeHandleTest :: Spec Unit
-- debugValueTest :: Spec Unit
-- listTest :: Spec Unit
-- listTest = pure unit
spec :: Spec Unit spec :: Spec Unit
spec = sequence_ spec = sequence_
[ staticTest [ staticTest
, counterTest , counterTest
, listTest , effectorTest
, layoutEffectorTest
] ]
-- , listTest
-- ]
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment