Split domain/clip along the data: clip, nest, bring
domain/clip is the document and what only needs the document: its symbol table, placing, the resolver, problems. domain/nest is how nested symbols relate — one walk down a row path gives the frame, the matrix and the time map, which merges inside and time-down — and moving and grouping between them, and nested sound. domain/bring is copying symbols in from another clip, a take from footage, and one placed that merges the store and places the instance, which conversion and import both now call instead of each doing it in their own words. Tests follow the same split. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
parent
7bb80d315d
commit
c17ee138f2
10 changed files with 639 additions and 589 deletions
26
frontend/test/arthur/domain/bring_test.cljs
Normal file
26
frontend/test/arthur/domain/bring_test.cljs
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
(ns arthur.domain.bring-test
|
||||
(:require [cljs.test :refer [deftest is]]
|
||||
[arthur.domain.bring :as bring]
|
||||
[arthur.domain.clip :as clip]))
|
||||
|
||||
(defn- nested
|
||||
"Three symbols: :outer places :inner, and :loose is placed by nothing."
|
||||
[]
|
||||
(-> (clip/blank)
|
||||
(assoc-in [:symbols :outer] {:id :outer :frames 200 :nodes {}})
|
||||
(assoc-in [:symbols :inner] {:id :inner :frames 10 :nodes {}})
|
||||
(assoc-in [:symbols :loose] {:id :loose :frames 30 :nodes {}})
|
||||
(clip/place-symbol nil :outer :inner 5 (random-uuid) nil)))
|
||||
|
||||
(deftest adopting-symbols-renames-what-collides
|
||||
(let [here (nested)
|
||||
there (-> (clip/blank)
|
||||
(assoc-in [:symbols :inner] {:id :inner :frames 4 :nodes {}})
|
||||
(clip/place-symbol nil :main :inner 0 #uuid "00000000-0000-4000-8000-0000000000aa" nil))
|
||||
{:keys [clip ids]} (bring/symbols here there [:main] {:main :take})]
|
||||
(is (= {:main :take :inner :inner-2} ids)
|
||||
"the root gets the name asked for; a taken id gets the next free one")
|
||||
(is (= 10 (clip/frames clip :inner)) "what was already here is untouched")
|
||||
(is (= :inner-2 (:of (first (vals (get-in clip [:symbols :take :nodes])))))
|
||||
"and the copy's instance follows its renamed symbol")
|
||||
(is (empty? (clip/problems clip)))))
|
||||
|
|
@ -265,68 +265,6 @@
|
|||
(is (seq (node/problems (assoc-in n [:time :in] 3)))
|
||||
"a stale :in is reported rather than silently ignored")))
|
||||
|
||||
(deftest a-frame-is-carried-down-through-the-instances-a-row-path-names
|
||||
(let [c (nested)
|
||||
[id] (keys (get-in c [:symbols :outer :nodes]))
|
||||
at #(select-keys (clip/inside c nil :outer %1 %2) [:sid :frame])]
|
||||
(is (= {:sid :outer :frame 12} (at [] 12)))
|
||||
(is (= {:sid :inner :frame 7} (at [id] 12))
|
||||
"the instance starts at 5, so frame 12 outside is frame 7 inside")
|
||||
(is (nil? (clip/inside c nil :outer [id] 2))
|
||||
"and before it starts there is no inside to be in")))
|
||||
|
||||
(deftest a-shape-drawn-into-an-instance-lands-where-it-was-drawn
|
||||
(let [u #uuid "00000000-0000-4000-8000-0000000000dd"
|
||||
c (-> (clip/blank)
|
||||
(assoc-in [:symbols :box] {:id :box :frames 30 :nodes {}})
|
||||
(clip/place-symbol nil :main :box 10 u nil)
|
||||
;; moved, turned and doubled, so nothing lines up by accident
|
||||
(update-in [:symbols :main :nodes u :channels] merge
|
||||
{[:xform :pos] (ch/framed [40 20])
|
||||
[:xform :rot] (ch/framed (/ js/Math.PI 2))
|
||||
[:xform :scale] (ch/framed [2 2])}))
|
||||
drawn [100 50 140 50 120 90]
|
||||
{:keys [sid frame pts]} (clip/drawn-inside c nil :main [u] 16 drawn)
|
||||
c (paint/new-shape c sid :shape frame pts :brow)
|
||||
[op] (filter #(= [u :shape] (:node %))
|
||||
((clip/resolver c nil pal/index-of :main) 16))]
|
||||
(is (= :box sid))
|
||||
(is (= 6 frame) "frame 16 of main is frame 6 of an instance placed at 10")
|
||||
(is (every? #(< (js/Math.abs %) 1e-9)
|
||||
(map - drawn (take 6 (array-seq (:pts op)))))
|
||||
"resolved back out through the instance, it is exactly what was drawn")))
|
||||
|
||||
(deftest adopting-symbols-renames-what-collides
|
||||
(let [here (nested)
|
||||
there (-> (clip/blank)
|
||||
(assoc-in [:symbols :inner] {:id :inner :frames 4 :nodes {}})
|
||||
(clip/place-symbol nil :main :inner 0 #uuid "00000000-0000-4000-8000-0000000000aa" nil))
|
||||
{:keys [clip ids]} (clip/adopt here there [:main] {:main :take})]
|
||||
(is (= {:main :take :inner :inner-2} ids)
|
||||
"the root gets the name asked for; a taken id gets the next free one")
|
||||
(is (= 10 (clip/frames clip :inner)) "what was already here is untouched")
|
||||
(is (= :inner-2 (:of (first (vals (get-in clip [:symbols :take :nodes])))))
|
||||
"and the copy's instance follows its renamed symbol")
|
||||
(is (empty? (clip/problems clip)))))
|
||||
|
||||
(deftest a-placed-symbols-sound-is-heard-where-it-is-placed
|
||||
(let [voice {:id :v :kind :audio :source {:footage "f"} :z "a1"
|
||||
:span [10 40] :time {:mode :map :at -10 :rate 1}
|
||||
:channels {[:audio :gain] (ch/keyed {0 0.0 5 1.0})}}
|
||||
c (-> (clip/blank)
|
||||
(assoc-in [:symbols :talk] {:id :talk :frames 30 :nodes {:v voice}})
|
||||
(clip/place-symbol nil :main :talk 50 #uuid "00000000-0000-4000-8000-0000000000bb" nil))
|
||||
[t] (clip/audio-tracks c :main)]
|
||||
(is (= [10 40] (:span t)) "the same frames of the source")
|
||||
(is (= [50 80] (node/placed-span t)) "starting where the instance starts")
|
||||
(is (= #{50 55} (set (keys (get-in t [:channels [:audio :gain] :keys]))))
|
||||
"with its automation moved along")
|
||||
(testing "and cut off where the instance's own span ends"
|
||||
(let [c (assoc-in c [:symbols :main :nodes #uuid "00000000-0000-4000-8000-0000000000bb" :span] [0 12])
|
||||
[t] (clip/audio-tracks c :main)]
|
||||
(is (= [10 22] (:span t)))
|
||||
(is (= [50 62] (node/placed-span t)))))))
|
||||
|
||||
(deftest an-instance-pivots-about-the-middle-of-what-it-draws
|
||||
(let [square (fn [x y] {:kind :poly :z "a1" :id :sq
|
||||
:channels {[:geom :pts] (ch/framed [x y (+ x 10) y (+ x 10) (+ y 10) x (+ y 10)])
|
||||
|
|
@ -351,95 +289,3 @@
|
|||
(is (= [55 35] (clip/center grown nil :box)) "the symbol's middle moved")
|
||||
(is (= [25 35] (get-in grown [:symbols :main :nodes u :channels [:xform :anchor] :value]))
|
||||
"the instance's did not")))))
|
||||
|
||||
(defn- picture
|
||||
"What `sid` draws at each of `fs`, without the node paths a move changes:
|
||||
per frame, the sorted marks with their points rounded to a thousandth."
|
||||
[c sid fs]
|
||||
(let [resolve (clip/resolver c nil pal/index-of sid)
|
||||
round #(/ (js/Math.round (* 1000 %)) 1000)]
|
||||
(mapv (fn [f]
|
||||
(sort-by str (map (fn [op]
|
||||
[(:color op) (mapv round (take (* 2 (:n op)) (array-seq (:pts op))))])
|
||||
(resolve f))))
|
||||
fs)))
|
||||
|
||||
(def ^:private a-uuid #uuid "00000000-0000-4000-8000-0000000000e1")
|
||||
(def ^:private b-uuid #uuid "00000000-0000-4000-8000-0000000000e2")
|
||||
|
||||
(defn- studio
|
||||
"`main` holds a keyed shape and a moved, turned, doubled instance of `box`,
|
||||
placed at frame 10; `box` holds a shape of its own."
|
||||
[]
|
||||
(let [tri (fn [id x keyed]
|
||||
{:id id :kind :poly :z "a1" :paint? true :span [4 60]
|
||||
:channels {[:geom :pts] (ch/keyed (into {} (map (fn [[f dx]] [f [x 10 (+ x dx) 10 x 40]])) keyed))
|
||||
[:style :color] (ch/framed :brow)}})]
|
||||
(-> (clip/blank)
|
||||
(assoc-in [:symbols :main :nodes :tri] (tri :tri 100 {4 20 30 40}))
|
||||
(assoc-in [:symbols :box] {:id :box :frames 50 :nodes {:inner (tri :inner 5 {0 10})}})
|
||||
(clip/place-symbol nil :main :box 10 a-uuid nil)
|
||||
(update-in [:symbols :main :nodes a-uuid :channels] merge
|
||||
{[:xform :pos] (ch/framed [30 20])
|
||||
[:xform :rot] (ch/framed 0.5)
|
||||
[:xform :scale] (ch/framed [2 2])}))))
|
||||
|
||||
(deftest moving-a-node-into-a-symbol-changes-nothing-on-screen
|
||||
;; From frame 10, where the instance starts: inside a symbol a node exists only
|
||||
;; while that symbol is on screen, so moving the shape in cuts off 4–9.
|
||||
(let [c (studio)
|
||||
fs [10 16 29 30 45 59 60 70]
|
||||
{moved :clip :as r} (clip/move-node c nil :main [:tri] [a-uuid] 16)]
|
||||
(is (nil? (:refused r)) (:refused r))
|
||||
(is (contains? (get-in moved [:symbols :box :nodes]) :tri) "it is in the symbol now")
|
||||
(is (not (contains? (get-in moved [:symbols :main :nodes]) :tri)) "and not beside it")
|
||||
(is (= [4 60] (get-in moved [:symbols :box :nodes :tri :span]))
|
||||
"its span and keys are its own and do not change")
|
||||
(is (= -10 (get-in moved [:symbols :box :nodes :tri :time :at]))
|
||||
"its time map takes up the ten frames the instance starts late")
|
||||
(is (= (picture c :main fs) (picture moved :main fs)) "and the picture is the same, frame for frame")
|
||||
(testing "moving it back out is also invisible"
|
||||
(let [{back :clip} (clip/move-node moved nil :main [a-uuid :tri] [] 16)]
|
||||
(is (= (picture c :main fs) (picture back :main fs)))))))
|
||||
|
||||
(deftest moving-an-instance-moves-only-its-at
|
||||
(let [c (-> (studio)
|
||||
(assoc-in [:symbols :holder] {:id :holder :frames 100 :nodes {}})
|
||||
(clip/place-symbol nil :main :holder 3 b-uuid nil))
|
||||
fs [0 10 16 40 59]
|
||||
{moved :clip :as r} (clip/move-node c nil :main [a-uuid] [b-uuid] 16)
|
||||
n (get-in moved [:symbols :holder :nodes a-uuid])]
|
||||
(is (nil? (:refused r)) (:refused r))
|
||||
(is (= 7 (get-in n [:time :at])) "placed at 10 in main is at 7 inside something placed at 3")
|
||||
(is (= [0 50] (:span n)) "its own frames do not move")
|
||||
(is (= (picture c :main fs) (picture moved :main fs)))))
|
||||
|
||||
(deftest grouping-makes-a-symbol-around-them-and-changes-nothing-on-screen
|
||||
(let [c (studio)
|
||||
fs [0 4 10 16 30 59 60]
|
||||
{grouped :clip :as r} (clip/group c nil :main [[:tri] [a-uuid]] :group-1 b-uuid 16)
|
||||
inst (get-in grouped [:symbols :main :nodes b-uuid])]
|
||||
(is (nil? (:refused r)) (:refused r))
|
||||
(is (= #{:tri a-uuid} (set (keys (get-in grouped [:symbols :group-1 :nodes])))))
|
||||
(is (= [b-uuid] (keys (get-in grouped [:symbols :main :nodes]))) "one instance where they were")
|
||||
(is (= 4 (get-in inst [:time :at])) "starting where the earliest of them starts")
|
||||
(is (= 56 (clip/frames grouped :group-1)) "and lasting until the last one ends")
|
||||
(is (= (picture c :main fs) (picture grouped :main fs)))
|
||||
(is (empty? (clip/problems grouped)))))
|
||||
|
||||
(deftest what-cannot-move-says-why
|
||||
(let [c (studio)]
|
||||
(is (:refused (clip/move-node c nil :main [a-uuid] [a-uuid] 16)) "not into itself")
|
||||
(is (:refused (clip/move-node c nil :main [:tri] [a-uuid] 2)) "not while the target is off screen")
|
||||
(let [roto (assoc-in c [:symbols :main :nodes :tri :channels [:geom :pts] :generated] {:by :roto})]
|
||||
(is (re-find #"generated" (:refused (clip/move-node roto nil :main [:tri] [a-uuid] 16)))))))
|
||||
|
||||
(deftest moving-into-a-retimed-instance-keeps-the-timing
|
||||
(let [c (assoc-in (studio) [:symbols :main :nodes a-uuid :time :rate] 2)
|
||||
fs [10 12 17 20 29 34]
|
||||
{moved :clip :as r} (clip/move-node c nil :main [:tri] [a-uuid] 16)]
|
||||
(is (nil? (:refused r)) (:refused r))
|
||||
(is (= {:at -20 :rate 0.5}
|
||||
(select-keys (get-in moved [:symbols :box :nodes :tri :time]) [:at :rate]))
|
||||
"half speed inside something at double speed, so it runs as it did")
|
||||
(is (= (picture c :main fs) (picture moved :main fs)))))
|
||||
|
|
|
|||
158
frontend/test/arthur/domain/nest_test.cljs
Normal file
158
frontend/test/arthur/domain/nest_test.cljs
Normal file
|
|
@ -0,0 +1,158 @@
|
|||
(ns arthur.domain.nest-test
|
||||
(:require [cljs.test :refer [deftest is testing]]
|
||||
[arthur.domain.channel :as ch]
|
||||
[arthur.domain.clip :as clip]
|
||||
[arthur.domain.nest :as nest]
|
||||
[arthur.domain.node :as node]
|
||||
[arthur.domain.paint :as paint]
|
||||
[arthur.domain.palette :as pal]))
|
||||
|
||||
(defn- nested
|
||||
"Three symbols: :outer places :inner, and :loose is placed by nothing."
|
||||
[]
|
||||
(-> (clip/blank)
|
||||
(assoc-in [:symbols :outer] {:id :outer :frames 200 :nodes {}})
|
||||
(assoc-in [:symbols :inner] {:id :inner :frames 10 :nodes {}})
|
||||
(assoc-in [:symbols :loose] {:id :loose :frames 30 :nodes {}})
|
||||
(clip/place-symbol nil :outer :inner 5 (random-uuid) nil)))
|
||||
|
||||
(deftest a-frame-is-carried-down-through-the-instances-a-row-path-names
|
||||
(let [c (nested)
|
||||
[id] (keys (get-in c [:symbols :outer :nodes]))
|
||||
at #(select-keys (nest/inside c nil :outer %1 %2) [:sid :frame])]
|
||||
(is (= {:sid :outer :frame 12} (at [] 12)))
|
||||
(is (= {:sid :inner :frame 7} (at [id] 12))
|
||||
"the instance starts at 5, so frame 12 outside is frame 7 inside")
|
||||
(is (nil? (nest/inside c nil :outer [id] 2))
|
||||
"and before it starts there is no inside to be in")))
|
||||
|
||||
(deftest a-shape-drawn-into-an-instance-lands-where-it-was-drawn
|
||||
(let [u #uuid "00000000-0000-4000-8000-0000000000dd"
|
||||
c (-> (clip/blank)
|
||||
(assoc-in [:symbols :box] {:id :box :frames 30 :nodes {}})
|
||||
(clip/place-symbol nil :main :box 10 u nil)
|
||||
;; moved, turned and doubled, so nothing lines up by accident
|
||||
(update-in [:symbols :main :nodes u :channels] merge
|
||||
{[:xform :pos] (ch/framed [40 20])
|
||||
[:xform :rot] (ch/framed (/ js/Math.PI 2))
|
||||
[:xform :scale] (ch/framed [2 2])}))
|
||||
drawn [100 50 140 50 120 90]
|
||||
{:keys [sid frame pts]} (nest/drawn-inside c nil :main [u] 16 drawn)
|
||||
c (paint/new-shape c sid :shape frame pts :brow)
|
||||
[op] (filter #(= [u :shape] (:node %))
|
||||
((clip/resolver c nil pal/index-of :main) 16))]
|
||||
(is (= :box sid))
|
||||
(is (= 6 frame) "frame 16 of main is frame 6 of an instance placed at 10")
|
||||
(is (every? #(< (js/Math.abs %) 1e-9)
|
||||
(map - drawn (take 6 (array-seq (:pts op)))))
|
||||
"resolved back out through the instance, it is exactly what was drawn")))
|
||||
|
||||
(deftest a-placed-symbols-sound-is-heard-where-it-is-placed
|
||||
(let [voice {:id :v :kind :audio :source {:footage "f"} :z "a1"
|
||||
:span [10 40] :time {:mode :map :at -10 :rate 1}
|
||||
:channels {[:audio :gain] (ch/keyed {0 0.0 5 1.0})}}
|
||||
c (-> (clip/blank)
|
||||
(assoc-in [:symbols :talk] {:id :talk :frames 30 :nodes {:v voice}})
|
||||
(clip/place-symbol nil :main :talk 50 #uuid "00000000-0000-4000-8000-0000000000bb" nil))
|
||||
[t] (nest/audio-tracks c :main)]
|
||||
(is (= [10 40] (:span t)) "the same frames of the source")
|
||||
(is (= [50 80] (node/placed-span t)) "starting where the instance starts")
|
||||
(is (= #{50 55} (set (keys (get-in t [:channels [:audio :gain] :keys]))))
|
||||
"with its automation moved along")
|
||||
(testing "and cut off where the instance's own span ends"
|
||||
(let [c (assoc-in c [:symbols :main :nodes #uuid "00000000-0000-4000-8000-0000000000bb" :span] [0 12])
|
||||
[t] (nest/audio-tracks c :main)]
|
||||
(is (= [10 22] (:span t)))
|
||||
(is (= [50 62] (node/placed-span t)))))))
|
||||
|
||||
(defn- picture
|
||||
"What `sid` draws at each of `fs`, without the node paths a move changes:
|
||||
per frame, the sorted marks with their points rounded to a thousandth."
|
||||
[c sid fs]
|
||||
(let [resolve (clip/resolver c nil pal/index-of sid)
|
||||
round #(/ (js/Math.round (* 1000 %)) 1000)]
|
||||
(mapv (fn [f]
|
||||
(sort-by str (map (fn [op]
|
||||
[(:color op) (mapv round (take (* 2 (:n op)) (array-seq (:pts op))))])
|
||||
(resolve f))))
|
||||
fs)))
|
||||
|
||||
(def ^:private a-uuid #uuid "00000000-0000-4000-8000-0000000000e1")
|
||||
(def ^:private b-uuid #uuid "00000000-0000-4000-8000-0000000000e2")
|
||||
|
||||
(defn- studio
|
||||
"`main` holds a keyed shape and a moved, turned, doubled instance of `box`,
|
||||
placed at frame 10; `box` holds a shape of its own."
|
||||
[]
|
||||
(let [tri (fn [id x keyed]
|
||||
{:id id :kind :poly :z "a1" :paint? true :span [4 60]
|
||||
:channels {[:geom :pts] (ch/keyed (into {} (map (fn [[f dx]] [f [x 10 (+ x dx) 10 x 40]])) keyed))
|
||||
[:style :color] (ch/framed :brow)}})]
|
||||
(-> (clip/blank)
|
||||
(assoc-in [:symbols :main :nodes :tri] (tri :tri 100 {4 20 30 40}))
|
||||
(assoc-in [:symbols :box] {:id :box :frames 50 :nodes {:inner (tri :inner 5 {0 10})}})
|
||||
(clip/place-symbol nil :main :box 10 a-uuid nil)
|
||||
(update-in [:symbols :main :nodes a-uuid :channels] merge
|
||||
{[:xform :pos] (ch/framed [30 20])
|
||||
[:xform :rot] (ch/framed 0.5)
|
||||
[:xform :scale] (ch/framed [2 2])}))))
|
||||
|
||||
(deftest moving-a-node-into-a-symbol-changes-nothing-on-screen
|
||||
;; From frame 10, where the instance starts: inside a symbol a node exists only
|
||||
;; while that symbol is on screen, so moving the shape in cuts off 4–9.
|
||||
(let [c (studio)
|
||||
fs [10 16 29 30 45 59 60 70]
|
||||
{moved :clip :as r} (nest/move-node c nil :main [:tri] [a-uuid] 16)]
|
||||
(is (nil? (:refused r)) (:refused r))
|
||||
(is (contains? (get-in moved [:symbols :box :nodes]) :tri) "it is in the symbol now")
|
||||
(is (not (contains? (get-in moved [:symbols :main :nodes]) :tri)) "and not beside it")
|
||||
(is (= [4 60] (get-in moved [:symbols :box :nodes :tri :span]))
|
||||
"its span and keys are its own and do not change")
|
||||
(is (= -10 (get-in moved [:symbols :box :nodes :tri :time :at]))
|
||||
"its time map takes up the ten frames the instance starts late")
|
||||
(is (= (picture c :main fs) (picture moved :main fs)) "and the picture is the same, frame for frame")
|
||||
(testing "moving it back out is also invisible"
|
||||
(let [{back :clip} (nest/move-node moved nil :main [a-uuid :tri] [] 16)]
|
||||
(is (= (picture c :main fs) (picture back :main fs)))))))
|
||||
|
||||
(deftest moving-an-instance-moves-only-its-at
|
||||
(let [c (-> (studio)
|
||||
(assoc-in [:symbols :holder] {:id :holder :frames 100 :nodes {}})
|
||||
(clip/place-symbol nil :main :holder 3 b-uuid nil))
|
||||
fs [0 10 16 40 59]
|
||||
{moved :clip :as r} (nest/move-node c nil :main [a-uuid] [b-uuid] 16)
|
||||
n (get-in moved [:symbols :holder :nodes a-uuid])]
|
||||
(is (nil? (:refused r)) (:refused r))
|
||||
(is (= 7 (get-in n [:time :at])) "placed at 10 in main is at 7 inside something placed at 3")
|
||||
(is (= [0 50] (:span n)) "its own frames do not move")
|
||||
(is (= (picture c :main fs) (picture moved :main fs)))))
|
||||
|
||||
(deftest grouping-makes-a-symbol-around-them-and-changes-nothing-on-screen
|
||||
(let [c (studio)
|
||||
fs [0 4 10 16 30 59 60]
|
||||
{grouped :clip :as r} (nest/group c nil :main [[:tri] [a-uuid]] :group-1 b-uuid 16)
|
||||
inst (get-in grouped [:symbols :main :nodes b-uuid])]
|
||||
(is (nil? (:refused r)) (:refused r))
|
||||
(is (= #{:tri a-uuid} (set (keys (get-in grouped [:symbols :group-1 :nodes])))))
|
||||
(is (= [b-uuid] (keys (get-in grouped [:symbols :main :nodes]))) "one instance where they were")
|
||||
(is (= 4 (get-in inst [:time :at])) "starting where the earliest of them starts")
|
||||
(is (= 56 (clip/frames grouped :group-1)) "and lasting until the last one ends")
|
||||
(is (= (picture c :main fs) (picture grouped :main fs)))
|
||||
(is (empty? (clip/problems grouped)))))
|
||||
|
||||
(deftest what-cannot-move-says-why
|
||||
(let [c (studio)]
|
||||
(is (:refused (nest/move-node c nil :main [a-uuid] [a-uuid] 16)) "not into itself")
|
||||
(is (:refused (nest/move-node c nil :main [:tri] [a-uuid] 2)) "not while the target is off screen")
|
||||
(let [roto (assoc-in c [:symbols :main :nodes :tri :channels [:geom :pts] :generated] {:by :roto})]
|
||||
(is (re-find #"generated" (:refused (nest/move-node roto nil :main [:tri] [a-uuid] 16)))))))
|
||||
|
||||
(deftest moving-into-a-retimed-instance-keeps-the-timing
|
||||
(let [c (assoc-in (studio) [:symbols :main :nodes a-uuid :time :rate] 2)
|
||||
fs [10 12 17 20 29 34]
|
||||
{moved :clip :as r} (nest/move-node c nil :main [:tri] [a-uuid] 16)]
|
||||
(is (nil? (:refused r)) (:refused r))
|
||||
(is (= {:at -20 :rate 0.5}
|
||||
(select-keys (get-in moved [:symbols :box :nodes :tri :time]) [:at :rate]))
|
||||
"half speed inside something at double speed, so it runs as it did")
|
||||
(is (= (picture c :main fs) (picture moved :main fs)))))
|
||||
Loading…
Add table
Add a link
Reference in a new issue