This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2015-10-07
Channels
- # admin-announcements (19)
- # announcements (1)
- # beginners (14)
- # boot (244)
- # cider (2)
- # clojure (23)
- # clojure-dev (23)
- # clojure-poland (55)
- # clojure-russia (118)
- # clojure-uk (4)
- # clojurescript (143)
- # core-async (31)
- # core-logic (1)
- # cursive (30)
- # datascript (2)
- # datomic (3)
- # emacs (7)
- # hoplon (40)
- # ldnclj (8)
- # off-topic (2)
- # om (64)
- # reagent (10)
- # ring (1)
- # yada (71)
Próbuję napisać test dla componenta w Reagencie, ktoś wie jak sprawdzić funkcję :on-click
? Testy odpalamy z phantomjs, tam nie ma click()
więc próbuję użyć jQuery, ale ten nie odpala :on-click
'a w ogóle
Jasne, robię to w mniej wiecej w sposób pożyczony z samego reagenta: https://github.com/reagent-project/reagent/blob/master/test/reagenttest/testreagent.cljs
Po wywołaniu with-mounted-component
mam dostęp do obiektu DOM js i na tym wołam jQuery.trigger('click')
. Ta sama funkcja jQuery działa oczywiście poprawnie w przeglądarce, a w phantomjs z jakiegoś powodu nic się nie dzieje
Tak zeby było jasniej, jeden prosty test (klik on <tr>
zaznacza checkbox'a gdzies w tym rzędzie:
(deftest service-component-test
(when browser?
(let [acme-service (->> acme-tenant :services rand-nth)
get-first-row (fn [div] (.querySelector div "tr:nth-child(2)"))
checkbox-checked? (fn [row] (.-checked (.querySelector row "td input")))
service-component (p/service-component acme-service p/toggle-row)]
(with-mounted-component service-component
(fn [c div]
(let [first-row (get-first-row div)]
(testing "Unchecked checkbox"
(is (not (checkbox-checked? first-row))))
(.trigger (js/jQuery first-row) "click")
(testing "Checked checkbox"
(is (checkbox-checked? first-row)))))))))
Nie mówię, że moje podejście do sprawy jest dobre oczyiście, ale już brakowalo mi pomysłów
bo tam nie prawdziwego event listenera. Jest jeden event listener który zbiera wszystkie zdarzenia od "korzenia" i na podstawie przekazanego identyfikatora komponentu podejmuje akcję
heh, no to widocznie moja wiedza zardzewiała sorry, może ktoś bardziej obeznany się wypowie w tej kwestii. może spróbuj na #C0620C0C8, kanał jest dosyć aktywny
dobra, już chyba wiem dlaczego to działa , zdarzenia wywołane jQuery.trigger bąbelkują od 1.3 http://api.jquery.com/trigger/
Tak, przeczytałem ten fragment, bardziej chodziło mi o to, że po prostu nie pamiętałem żeby tak nie było i mnie to trochę zdziwiło ; d
Wydaje mi sie ze zwraca wszystko dobrze... Tutaj prosty przyklad:
(deftest click-test
(when browser?
(let [component (fn [] [:div {:class "someclass"
:on-click #(println "something")}])]
(with-mounted-component (component)
(fn [c div]
(let [d (.querySelector div ".someclass")]
;; :on-click println never fires
(.trigger (js/jQuery d) "click")))))))
Natomiast to działa:
(deftest click-checkbox-test
(when browser?
(let [component (fn [] [:input {:type :checkbox
:class "someclass"
:on-click #(println "something")}])]
(with-mounted-component (component)
(fn [c div]
(let [d (.querySelector div "input")]
;; :on-click is fired
(.trigger (js/jQuery d) "click")))))))
osobiście postawiłbym na maksymalnie prosty handler który wywołuje jakąś zewnętrzną funkcję, którą można z ręki wyzwolić. wtedy w teście po odpaleniu funkcji, która modyfikuje stan renderujesz komponent i sprawdzasz
wtedy masz z bani zabawę z asynchronicznymi zdarzeniami. oczywiście nie zawsze się tak da
no ta funkcja jest sprawdzana swoją drogą, ale tutaj potrzebuje potwierdzić, że DOM reaguje tak jak trzeba na click'a
no i ogólnie ta wiedza wydaje mi się przydatna, więc chętnie się pomęczę z tym problemem jeszcze chwile
chociaż jednak może nie; bo chciałem powiedzieć, że println
zwraca nil
a to oznacza zatrzymanie propagacji, ale to i tak się powinno wypisać
A co do testowania rzeczy asynchronicznych to jest to - https://github.com/clojure/clojurescript/wiki/Testing#async-testing (bazowane na tym - https://github.com/cemerick/clojurescript.test#asynchronous-testing)