Skip to content

Commit

Permalink
Add tests
Browse files Browse the repository at this point in the history
  • Loading branch information
Grazfather committed Sep 26, 2021
1 parent 907fc0c commit 94b4b11
Show file tree
Hide file tree
Showing 2 changed files with 101 additions and 0 deletions.
4 changes: 4 additions & 0 deletions lib/testing/assert.fnl
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@
[actual expected message]
(assert (= actual expected) (.. message " instead got " (hs.inspect actual))))

(fn exports.not-eq?
[first second message]
(assert (not= first second) (.. message " instead both were " (hs.inspect first))))

(fn exports.ok?
[actual message]
(assert (= (not (not actual)) true) (.. message " instead got " (hs.inspect actual))))
Expand Down
97 changes: 97 additions & 0 deletions test/new-statemachine-test.fnl
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
(local is (require :lib.testing.assert))
(local statemachine (require :lib.new-statemachine))
(local atom (require :lib.atom))

(fn make-fsm
[]
(statemachine.new
;; States that the machine can be in mapped to their actions and transitions
{:state {:current-state :closed
:context {:i 0
:event nil}}

:states {:closed {:toggle (fn closed->opened
[state action extra]
{:state {:current-state :opened
:context {:i (+ state.context.i 1)}}
:effect :opening})}
:opened {:toggle (fn opened->closed
[state action extra]
{:state {:current-state :closed
:context {:i (+ state.context.i 1)}}
:effect :closing})}}}))

(describe
"State Machine"
(fn []

(it "Should create a new fsm in the closed state"
(fn []
(let [fsm (make-fsm)]
(is.eq? (. (atom.deref fsm.state) :current-state) :closed "Initial state was not closed"))))

(it "Should include some methods"
(fn []
(let [fsm (make-fsm)]
(is.eq? (type fsm.get-state) :function "No get-state method")
(is.eq? (type fsm.signal) :function "No get-state method")
(is.eq? (type fsm.subscribe) :function "No get-state method"))))

(it "Should transition to opened on toggle action"
(fn []
(let [fsm (make-fsm)]
(is.eq? (fsm.signal :toggle) true "Dispatch did not return true for handled event")
(is.eq? (. (atom.deref fsm.state) :current-state) :opened "State did not transition to opened"))))

(it "Should transition from closed -> opened -> closed"
(fn []
(let [fsm (make-fsm)]
(fsm.signal :toggle)
(fsm.signal :toggle)
(is.eq? (. (atom.deref fsm.state) :current-state) :closed "State did not transition back to closed")
(is.eq? (. (atom.deref fsm.state) :context :i) 2 "context.i should be 2 from 2 transitions"))))

(it "Should not explode when dispatching an unhandled event"
(fn []
(let [fsm (make-fsm)]
(is.eq? (fsm.signal :fail nil) false "The FSM exploded from dispatching a :fail event"))))

(it "Subscribers should be called on events"
(fn []
(let [fsm (make-fsm)]
(let [i (atom.new 0)]
(fsm.subscribe (fn [] (atom.swap! i (fn [v] (+ v 1)))))
(fsm.signal :toggle)
(is.eq? (atom.deref i) 1 "The subscriber was not called")))))

(it "Subscribers should be provided old and new context, action, effect, and extra"
(fn []
(let [fsm (make-fsm)]
(let [_old (atom.new nil)
_new (atom.new nil)
_action (atom.new nil)
_effect (atom.new nil)
_extra (atom.new nil)]
(fsm.subscribe (fn [{: prev-state : next-state : action : effect : extra}]
(atom.swap! _old (fn [_ nv] nv) prev-state)
(atom.swap! _new (fn [_ nv] nv) next-state)
(atom.swap! _action (fn [_ nv] nv) action)
(atom.swap! _effect (fn [_ nv] nv) effect)
(atom.swap! _extra (fn [_ nv] nv) extra)))
(fsm.signal :toggle :extra)
(is.not-eq? (. (atom.deref _old) :context :i)
(. (atom.deref _new) :context :i) "Subscriber did not get old and new state")
(is.eq? (atom.deref _action) :toggle "Subscriber did not get correct action")
(is.eq? (atom.deref _effect) :opening "Subscriber did not get correct effect")
(is.eq? (atom.deref _extra) :extra "Subscriber did not get correct extra")))))

;; (print (hs.inspect fsm)) ;; DELETEME
(it "Subscribers should be able to unsubscribe"
(fn []
(let [fsm (make-fsm)]
(let [i (atom.new 0)
unsub (fsm.subscribe (fn [] (atom.swap! i (fn [v] (+ v 1)))))]
(fsm.signal :toggle)
(unsub)
(fsm.signal :toggle)
(is.eq? (atom.deref i) 1 "The subscriber was called after unsubscribing")))))))

0 comments on commit 94b4b11

Please sign in to comment.