clojure-poland

2015-10-07T06:35:09.000003Z

Witam

zoldar 2015-10-07T06:59:03.000004Z

cześć

2015-10-07T07:04:03.000005Z

siemka

2015-10-07T07:05:02.000006Z

uh, fajnie chociaż raz znaleźć polską aktywną grupę 😛

2015-10-07T07:07:35.000007Z

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

zoldar 2015-10-07T07:12:55.000008Z

nie jestem na bieżąco, ale powinieneś być w stanie wywołać (.onClick component)

zoldar 2015-10-07T07:13:26.000009Z

zdarzenia w React są syntetyczne, nie są to typowe handlery w DOM

2015-10-07T07:18:04.000010Z

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

2015-10-07T07:23:45.000012Z

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)))))))))

2015-10-07T07:24:25.000013Z

Nie mówię, że moje podejście do sprawy jest dobre oczyiście, ale już brakowalo mi pomysłów

zoldar 2015-10-07T07:24:47.000014Z

bardziej jestem zdziwiony że trigger na click ci zadziałał... może czegoś nie wiem

2015-10-07T07:25:04.000015Z

Czemu miałby nie działać?

zoldar 2015-10-07T07:26:01.000016Z

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ę

2015-10-07T07:26:51.000017Z

no jasne, ale klikniecie jQuery odpala dokładnie to samo chyba co klikniecie myszką

2015-10-07T07:26:58.000018Z

w sensie, wszystkie dane zostają nadal przekazane

2015-10-07T07:27:29.000019Z

no ale sprawdzę dla pewności jeszcze raz, że napewno działa

2015-10-07T07:28:15.000020Z

no działa bez problemu

zoldar 2015-10-07T07:29:17.000021Z

heh, no to widocznie moja wiedza zardzewiała :simple_smile: sorry, może ktoś bardziej obeznany się wypowie w tej kwestii. może spróbuj na #C0620C0C8, kanał jest dosyć aktywny

2015-10-07T07:29:47.000022Z

Będę próbował, dzięki!

zoldar 2015-10-07T07:33:53.000023Z

dobra, już chyba wiem dlaczego to działa :simple_smile: , zdarzenia wywołane jQuery.trigger bąbelkują od 1.3 http://api.jquery.com/trigger/

jaen 2015-10-07T07:35:54.000025Z

Był czas kiedy nie bubble'owały? TIL

zoldar 2015-10-07T07:36:30.000026Z

"As of jQuery 1.3, .trigger()ed events bubble up the DOM tree"

jaen 2015-10-07T07:37:47.000027Z

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

jaen 2015-10-07T07:38:00.000028Z

Może za młody jestem po prostu xD

zoldar 2015-10-07T07:38:13.000029Z

:simple_smile:

zoldar 2015-10-07T08:53:28.000030Z

@smogg: sprawdzałeś czy querySelector zwraca coś w phantomie?

2015-10-07T08:54:20.000031Z

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")))))))

2015-10-07T08:54:38.000032Z

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")))))))

zoldar 2015-10-07T08:54:56.000033Z

jesteś pewien, że w pierwszym przypadku nie dostajesz nulla?

2015-10-07T08:55:40.000034Z

w sensie czy d jest puste?

2015-10-07T08:55:43.000035Z

Nie, napewno nie

2015-10-07T08:56:11.000036Z

wydaje mi sie, ze moze chodzic o niesynchroniczna funkcje

2015-10-07T08:56:33.000037Z

moze po prostu chwila mija od wywolania trigger() do reakcji, a sprawdzam od razu

2015-10-07T08:57:05.000038Z

tylko nie wiem jak poczekac... Nie wiem czy sie da jakos to zrobic moze z core.async?

2015-10-07T08:57:18.000039Z

probowalem js setTimeout ale bez efektów

zoldar 2015-10-07T08:58:58.000040Z

faktycznie, może tak być

zoldar 2015-10-07T09:00:55.000041Z

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

zoldar 2015-10-07T09:02:09.000042Z

wtedy masz z bani zabawę z asynchronicznymi zdarzeniami. oczywiście nie zawsze się tak da

2015-10-07T09:08:40.000043Z

no ta funkcja jest sprawdzana swoją drogą, ale tutaj potrzebuje potwierdzić, że DOM reaguje tak jak trzeba na click'a

2015-10-07T09:09:06.000044Z

no i ogólnie ta wiedza wydaje mi się przydatna, więc chętnie się pomęczę z tym problemem jeszcze chwile

2015-10-07T09:09:15.000045Z

jak się nie uda, to będę kombinował

jaen 2015-10-07T09:09:56.000046Z

hm

jaen 2015-10-07T09:11:26.000047Z

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ć

2015-10-07T09:11:56.000048Z

no na <input> działa bez problemu, więc...

jaen 2015-10-07T09:12:48.000049Z

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)

jaen 2015-10-07T09:13:02.000053Z

Ale nie używałem więc nie wiem na ile pomoże

2015-10-07T09:14:35.000054Z

ok, sprawdzę, dzięki

jaen 2015-10-07T09:16:08.000055Z

Może też Cię zainteresować to

jaen 2015-10-07T09:16:18.000059Z

Oficjalne utilsy do testowania Reacta

jaen 2015-10-07T09:16:22.000060Z

Mają symulację klikania np.

2015-10-07T09:18:03.000061Z

o, to może być to!

2015-10-07T10:11:14.000062Z

Ehh, nadal dupa nawet z TestUtils 😛

zoldar 2015-10-07T10:14:03.000063Z

parafrazując, lepiej mieć stosunek z jeżem, niż zajmować się webdevem 😆

1
2015-10-07T10:14:47.000064Z

😄