savepoint
This commit is contained in:
parent
64cd3a986c
commit
022ce6da03
51
just/observable-test.fnl
Normal file
51
just/observable-test.fnl
Normal file
@ -0,0 +1,51 @@
|
||||
(local fennel (require :fennel))
|
||||
(local observable (require :observable))
|
||||
|
||||
(macro expect [form]
|
||||
`(do
|
||||
(assert ,form ,(view [:failed form]))
|
||||
(print ,(view [:passed form]))))
|
||||
|
||||
(macro expect-error [form]
|
||||
`(let [(ok?# msg#) (pcall (fn [] ,form))]
|
||||
(assert (not ok?#) msg#)
|
||||
(print ,(view [:passed (list :error form)]))))
|
||||
|
||||
(local app-state
|
||||
(observable.new
|
||||
{
|
||||
:foo 27
|
||||
:bar 54
|
||||
:nest {
|
||||
:name "beatles"
|
||||
:artists [:john :paul: :ringo :george ]
|
||||
}
|
||||
}))
|
||||
|
||||
|
||||
(expect (= (app-state:get [:foo]) 27))
|
||||
(expect (= (app-state:get [:nest :name]) "beatles"))
|
||||
|
||||
(let [s (observable.new {:foo 43})]
|
||||
;; s:get on a non-leaf returns the subtree. use table.concat
|
||||
;; for comparison of values
|
||||
(expect (= (table.concat (s:get [])) (table.concat {:foo 43}))))
|
||||
|
||||
(let [s (observable.new {:foo 43})]
|
||||
;; update existing entry
|
||||
(s:update [:foo] 84)
|
||||
(expect (= (s:get [:foo]) 84))
|
||||
|
||||
;; create new entry
|
||||
(s:update [:baz] 48)
|
||||
(expect (= (s:get [:baz]) 48))
|
||||
|
||||
;; doesn't create new nested keys
|
||||
(expect-error (s:update [:nonexistent :path] 22)))
|
||||
|
||||
(let [s (observable.new {:foo {:bar 43}})]
|
||||
(var win false)
|
||||
;; observers live on subtrees, not individual nodes
|
||||
(s:observe [:foo] #(set win true))
|
||||
(s:update [:foo :bar] 42)
|
||||
(expect (and win)))
|
35
just/observable.fnl
Normal file
35
just/observable.fnl
Normal file
@ -0,0 +1,35 @@
|
||||
(local {: view} (require :fennel))
|
||||
|
||||
(fn concat [dest src]
|
||||
(table.move dest 1 (# dest) (# src) src))
|
||||
|
||||
(fn update [data self path value]
|
||||
(let [[first & rest] path]
|
||||
(if (next rest)
|
||||
(update (. data first) self rest value)
|
||||
(do
|
||||
(if data._subscribers
|
||||
(each [_ f (pairs data._subscribers)] (f)))
|
||||
(tset data first value)))))
|
||||
|
||||
(fn get [data self path]
|
||||
(let [[first & rest] path]
|
||||
(if (not first) data
|
||||
(next rest) (get (. data first) self rest)
|
||||
(. data first))))
|
||||
|
||||
(fn observe [data self path fun]
|
||||
(let [el (get data self path)]
|
||||
(when el
|
||||
(if el._subscribers
|
||||
(el._subscribers:insert fun)
|
||||
(tset el :_subscribers [fun])))))
|
||||
|
||||
(fn new [data]
|
||||
{
|
||||
:observe (partial observe data)
|
||||
:update (partial update data)
|
||||
:get (partial get data)
|
||||
})
|
||||
|
||||
{: new }
|
Loading…
Reference in New Issue
Block a user