Fork me on GitHub
#clojure-russia
<
2017-07-12
>
y.khmelevskii08:07:53

Народ, как вы тестируете ваше API? Что используете? У меня pedestal, схемой валидирую запросы и ответы. Мне нужно мокать обращения к БД и другим сервисам, генерировать или подготовить данные для тестов и собственно запускать тесты. Что почитать что бы лучше в вопросе разобраться?

artemyarulin08:07:22

дак тестирование или валидация?

artemyarulin08:07:00

если генерить данные для тестов то конечно спека. Ну или https://github.com/clojure/test.check если спеку не охота тащить, но я б все равно лучше спеку взял

y.khmelevskii08:07:15

а мокать запросы чем?

artemyarulin08:07:08

эм, т.е. ты хочешь интеграционный тест прям, от ХТТП запроса до мок БД и до респонса? Есть кието либы, компонент вроде чота умеет типа этого, на а если просто нужно для юнит тестов то я обычно пишу свои функции как

(defn get-customer-fn [customer-finder]
  (fn [id]
    (do-other-pure-logic (customer-finder id))))

(def get-customer (get-customer-fn (my-actual-db-connection/find-customer-by-id)))
Т.е. по сути весь IO идет как параметром, поэтому тестить все очень просто

misha10:07:33

господа, а что такоего почитать по организации стейта в коде? проблема: дофига атомов и полей в них, между которыми связи со всякими нюансами (вочеры, которые сравнивает/не сравнивает значения на входе/выходе) хочется это всё нагляднее как-то засетапить, чтобы в глаза умещалось

misha10:07:47

можно конечно стейт машину в столбик написать, и из нее картинку генерить на каждое изменение, но хочется это как-нибудь по-кошернее распедалить

artemyarulin10:07:48

дофега mutable атомов это прям жава какая-то troll

artemyarulin10:07:56

а чо не один где весь стейт?

misha10:07:16

потому что тогда сильно много локальных проверок не поменялось ли чо

misha10:07:07

например сейчас "пишу" видео плеер, в котором звук отдельно, это уже сами по себе 2 мьютабл жс хреновины со своими ивентами

misha10:07:32

их нужно синхронизировать, давать возможность сдвигать звук левее/правее, потому что жизнь

misha10:07:40

+ нужен кастомный прогресс бар

misha10:07:01

и чтобы юай не захлебывался, много где нужно хирургичненько из одного здорового атома получать значение конкретного поля и игнорировать остальные изменения

misha10:07:15

очень не хочется это делать "на клиенте"

misha10:07:28

хочется чистую тупую функцию "перемотать", которая не знает, что есть атом, а получает просто время куда мотать.

misha10:07:38

но если так сделать со здоровым атомом, нужно везде будет оборачивать вызов "перемотать" проверками "стаорое ≠ новое", инача на например изменение громкости оно будет на последнее место перемотки перематывать

misha10:07:28

и хочется эти ≠ вынести куда-то нагляднее ближе к значениям что ли

misha10:07:55

считай, что это продвинутый случай rum/derived-atom'a

artemyarulin10:07:14

ха, я делал видеоплеер тоже в свое время 🙂 у меня все эвенты от UI были в виде данных [:action/forward 10] [:action/pause true] и дальше один диспатчер который уже все менял/мониторил

misha10:07:15

только их дохера и хочется незапутаться

misha10:07:26

ну я так и сделал

misha10:07:29

но если диспатчер не напрямую модифицирует audio/video объекты, а атом обновляет – то начинается всё, что я выше описал

artemyarulin10:07:32

>и чтобы юай не захлебывался, много где нужно хирургичненько из одного здорового атома получать значение конкретного поля и игнорировать остальные изменения т.е. у тебя UI подписывается на эвенты по сути всякие aka pull. У меня просто было push - диспатчер получал евенты и уже думал дергать какой UI или нет

misha10:07:45

ну и даже не про аудио/видео: просто когда появляется хоть пара значений, на которые нужно подписаться только если ≠ – то собирать эту инфу по всем неймспейсам в add-watch - такое себе удовольствие

artemyarulin10:07:57

>подписаться two way binding по сути же получается не? UI дергает изменения и подписывается на нове одноврменно

misha10:07:27

или у тебя есть сеть core.async каналов со всякими мультами и тд - хочется это в виде диаграмы видеть, а не глазами из кода выпаршивать

misha10:07:17

смотри, проблемы нахачить - нет, есть проблема наглядности. оно слишком многословно и размазано получается

artemyarulin10:07:29

ну вот значит да - слишком много всего и во все стороны что даж диаграму хочешь. Может как в redux/react - one way data binding?

artemyarulin10:07:51

подписки и add-watch уже попахивает

misha10:07:27

ну так 5 вочеров в 3 неймспейсах могут быть ван вэй, но их всёравно надо ходить собирать по проекту, и, в первую очередь, знать, что они вообще есть

misha10:07:26

а хочется как-то или табличку размером со страницу написать, или диаграмму надраг-дропать, и чтобы всё это говно сгенерилось за меня

artemyarulin10:07:43

сори, можешь еще раз развернуть почему один атом не канает у тебя?

misha10:07:00

а мне чтоб осталось медитировать в 1 страницу

misha10:07:54

в 1 атоме много полей. много полей = много подписок много полей = много ивентов "атом поменялся" не все подписки дешево звать каждый "атом поменялся" раз

misha10:07:28

начинаются гранулярные оборачивания во всякие ≠

misha10:07:47

эти ≠ и сами подписки размазаны по всему проекту

artemyarulin10:07:58

хм, оно реально так медленно? в видео плеере у меня был 1 евент в секунду (таймер тикал) + иногда от юзера с десяток

misha10:07:59

а хочется это всё на 1 странице

misha10:07:20

медленный не плеер, а кастомный прогресс бар

misha10:07:37

точнее не медленный, а вскипает процессор

misha10:07:14

но это фигня на фоне того, что этот граф зависимостей размазан по проекту всему, хотя там тупо 10-20 полей в атоме(атомах)

artemyarulin10:07:09

ээ, 10 полей и уже прям тяжело процу??

misha10:07:57

да не в процессоре дело йоптить, а в том, что я сижу и собираю эти несчастные 10 полей по 3 файлам

artemyarulin10:07:36

дак положи в один атом то епт 😄

misha10:07:00

чувак

artemyarulin10:07:38

нуууу, ну объясни для тупых почему не канает 🙂 Реально я не верю что перформанс просядет если в одном атоме все будет

misha10:07:54

да в жопу перформанс компьютера

misha10:07:36

мне важно, что я сижу и граф зависимостей собираю 40 минут, чтобы понять/вспомнить че ж там было то, когда мне нужно ветку к графу присобачить новую

misha10:07:17

многа кода, хочется мало кода

artemyarulin10:07:20

дак это и решается как раз если одни атом будет нет? Все в одном файле, все видно

misha10:07:32

не решается лол

misha10:07:16

если у тебя в третьем поле результат f от первых двух

misha10:07:53

и в четвертом f от трех - этот атом будет "бесконечно" пересчитываться/обновляться

misha10:07:11

пока ты не пооборачиваешь в ≠ это всё

misha10:07:26

но даже не всё можно в ≠ обернуть

misha10:07:24

этот граф зависимостей с нюансами очень быстро разрастается, и перестает помещаться на страницу уже после 5 неудобных полей

misha10:07:58

+ если ты результаты вычислений складываешь в тот же атом - тебе на "клиенте" значения нужно дополнительно ≠ вызывать (чтобы то же видео бесконечно не перематывать например)

misha10:07:47

и вот твой атом протёк в компонент, который теперь должен не про значение знать, а про атом, чтобы смочь сравнить старое/новое значения

misha10:07:19

даже не знаю что добавить harold

artemyarulin10:07:19

ну единсвенное что приходит в голову это сделать однопроходный апдейт, т.е. обновлять атом один раз и пересчитывать новый стейт один раз 1. Посчитать новое поле 1 2. Посчитать новое поле 2 3. Посчитать новое поле 3 на основе 1 и 2 4. Посчитать новое поле 4 на осное 3 Положить новый стейт в атом

misha10:07:59

т.е. монстрить суперфункцию, которая всю начинку атома пересчитывает? ты шутишь?

artemyarulin10:07:10

т.е. может и будут хаки вида 5. Пересчитать поле 1 если поле 4 обновилось он оно будет в одном месте

artemyarulin10:07:54

ну а как ты хочешь? Если я тебя логика уже такая, либо явно монста этого описать (счас у тебя это не явно и в мозг не влезает) либо менять логику

misha10:07:57

или не шутишь. ща подумаю

misha10:07:38

вообще, это не годится тоже

misha10:07:57

потому что тебе вне атома на клиентах нужно кастомно в ≠ оборачивать всё равно

artemyarulin10:07:17

можешь пример я плохо понимаю

misha10:07:05

меняешь ты звук, атом меняется, всем подписчикам надо решить делать что-то по этому поводу или нет

misha10:07:17

чем больше полей, тем больше подписчиков

misha10:07:43

в итоге твои 1 2 3 4 количество ивентов "атом обновился" не уменьшают (ну может уменьшают, но гранулярности не добавляют всё равно)

artemyarulin10:07:26

ну вот, у тебя подписчики просто подписываются. А что если сделать что диспатчке обновляет стейт и потом уже сам дергает нужные контролы сам? Соответсвенно логика = будет в одном месте

misha10:07:38

и даже "чистые" подписки будут шум генерить, типа заставлять реакт пересчитывать равенства и тд, не говоря уже о сайд эффектах

artemyarulin10:07:59

a != b очень быстро работает так то 🙂

misha10:07:05

не везде дело только ≠ обходится же, и не везде нужно ниче не делать, если значение не обновилось, хотя то наверное уже про сайд эффекты, как ни крути

artemyarulin10:07:21

т.е. ака redux - контролы умеют слать евенты (юзер погроме захотел!) затем все уходит в диспатчер, тот обновляет стейт в один проход, пересчитыват новые поля (звук уже 100 и дальше can-increase-volume = false), обновляет стейт в атоме и затем решает (опционально ибо я думаю и так быстро будет) какие данные новые появились и дергает уже контролы с новыми данными (volume-control can-increas-volume=false)

misha10:07:24

вообще, я не сильно представляю, как написать убер функцию, которая весь атом пересчитывает, но при этом состоит из независимых обработчиков

artemyarulin10:07:42

ну котролы не должны делать сайд эффекты

artemyarulin10:07:20

по крайней мере напрямую, все диспатчер должен делать. Даже тотже HTMLVideoPlayer это mutable state и его должен менять только диспатчер

misha10:07:23

да? а как тогда перемотать видос на 10 сек вперед? )

misha10:07:37

а, ну конечно, через диспатчер

misha10:07:22

почитал про рефрейм, чот мне кажется дикой свалкой, его обработчики ивентов

misha10:07:50

не нравится мне идея, что кто-то кроме девелопера должен знать обо всём стейте сразу

misha10:07:38

и явно везде расставлять "не хочу знать" на подписках - тоже не нравится

misha11:07:47

в подходе с 1 атомом получается, с т.з. подписчика на атом, бывает 3 причины получения ивента "атом обновился": 1. поменялось интересующее значение 2. кто-то тронул интересующее значение (для сайд эффектов полезно, типа "пойди базу синкни". (defn touch [a] (reset! a @a))) 3. поменялось неинтересующее значение а должно, как мне кажется, быть только 2 причины: 1 и 2

misha11:07:17

и то 2 - какой-то хак возможно, но без каналов хз как это сделать иначе

artemyarulin11:07:20

ага 2 это хак, по мне дак скрытое IO по сути, но ты и сам пишешь для сайд эффектов

misha11:07:24

при чем принимать решение "интересен ивент 1 или ивент 2" я хочу не на клиенте атома, а при создании графа, чтобы можно было втупую подписаться компонентом на атом, и смотреть только на значение, а не сравнивать старое и новое

misha11:07:48

@artemyarulin ну а как еще отделить чувака, который просит сайдэффект, и чувака, который его выполняет? не тянуть же корасинк ради единственного случая?

artemyarulin11:07:21

ну я уже писал - у меня весь IO в диспатчере просиходит, компоненты тупые и тока получают уже готовые нужные данные и иногда шлют экшены обратно в диспатчер когда юзер чо нажал

misha11:07:33

но это немного оффтопик, основная идея - я не хочу обрабатывать возможность 3 на клиентах

misha11:07:02

потому что разростается кодэ

misha11:07:24

протекает

artemyarulin11:07:57

есть же отличный shouldComponentUpdate(a,b) { return a != b } который отлично обрабывате ситуацию когда теже данные пришли

misha11:07:07

I feel dirty kappa

misha11:07:51

хз, надо подумать еще раз

misha11:07:42

возможно у меня где-то намешано чистого с и/о, и потому у меня ласты склеиваются, хз

misha11:07:34

а теперь сижу и собираю по всему проекту кто на что подписан, и кто что когда меняет, с чего и начинал kappa

misha11:07:05

@artemyarulin а как и куда в диспетчере полжить вот такое?

(add-watch !STATE ::audio-delay
  (fn [k r o n]
    (let [id (::episode-id n)]
      (when (not= id (::episode-id o))
        (reset! !AUDIO-DELAY-MS (audio-delay-by-episode-id! id))))))

misha11:07:24

это заменяется на ивент, но кто этот ивент вызовет? куда положить знание о том, что когда айди эпизода меняется - нужно передернуть подсчёт/фетч дилея?

misha12:07:30

типа наделать кучу ивентов для изменения конкретных атрибутов кнопками, и 1 ивент "пересчитать всё!" с огромным обработчиком, в котором каскадно весь стейт пересчитать?

artemyarulin13:07:21

ну ты уже почти сделал redux, actions у тебя уже есть (суть именованные евенты с доп данными), осталось изобрести reducers чтоб был не один большой хендлер а несколько малельнких troll

artemyarulin13:07:37

В данном конкретном случае я б сделал что контрол шлет :video-ends -> video-control-reducer создает [:episode-ends :reset-audio-delay] ну а playback-reducer уже обрабатывает :reset-audio-delay и делает нужный IO

artemyarulin13:07:39

ну т.е. изолировать всю бизнесс логику которую тебе надо выполнять когда видео заканчивается в одном месте. В терминах redux это reducer, в ом-некст это вроде мутации, хотя я уже забыл. В других фреймворках по другому называется

misha13:07:00

кто говорил, что видео заканчивается? troll

misha13:07:53

кароче у меня пока что сложности с тем, куда запихнуть вызов ивентов "второго порядка", типа кто, когда и как будет следить за тем, что нужно вызвать каскадные изменения. типа внешний ивент запустил изменения внутри, которые хз как порождают дальнейшие изменения внутри

artemyarulin13:07:39

>куда положить знание о том, что когда айди эпизода меняется я думал это оно. Ну в общем ты позырь на редукс - он мелкий сам по себе, можно за часик на коленке такой-же делать. У меня старый проект был на ObjectiveC, тоже мешанина хер разберешся, сделал redux на коленке и все через него провел - полет отличный

misha13:07:56

слушай, редюсеры - это мои чистые ивент хендлеры.

misha13:07:17

а теперь как бы так сделать, чтобы после применения чистого ивент хендлера стало понятно, что нужно следом что-то еще поменять, и всё это перед тем, как закоммитить в атом?

misha13:07:34

читаю редукс

misha13:07:44

жс - кровь из глаз harold

povloid14:07:34

Всем доброго времени суток, кто нибудь тут re-natal юзает?

misha14:07:59

тебе в общем случае сюда #cljsrn

misha14:07:07

но вообще да

povloid14:07:40

Да немогу react-native run-android запустить на реальном андройд девайсе. вроде все проходит и adb не падает, и на мобиле даже окно появляется но оно чего там долго ждет фигвил

povloid14:07:59

*Waiting for figwheel to load files*

povloid14:07:27

причем очень долго. уже незнаю как победить

misha14:07:43

@artemyarulin ну вот смотри: http://redux.js.org/docs/basics/UsageWithReact.html они фильтр визибл тудушек суют в компонент

misha14:07:47

я этого как раз хочу избежать и вынести в стейт, или в другой атом, который подписывается на стейт

misha14:07:59

а компонент сделать совсем тупым

misha14:07:50

и вот где мне в этом редуксе сказать, что после изменения вот этого поля стейта стрельни вот эти 3 ивента на пересчет остального?

misha14:07:14

@povloid не трогал даже андроид, не помогу, сорян

misha14:07:32

в редюсере после изменения стейта позвать диспатч? так это ж уже и/о, а не чистота

misha14:07:01

надо из обработчика/редюсера везвдращать [events, new-state]!

misha14:07:43

а диспатчером редюсить ивенты, пока кто-то не вернет [nil, new-state]

misha14:07:03

или нет harold

misha14:07:24

не, в таком случае обработчик ивента должен будет знать, на кого он повлияет, а нужно чтоб не знал.

dottedmag15:07:24

@misha В ре-фрейме есть такая штука, как подписки, которые тебе из события "что-то сменилось" делают события "поменялось a". Сложи их все в одно место, и навесь на их результат хэндлеры.

dottedmag15:07:30

Или я что-то упускаю?

dottedmag15:07:26

Кому тут хотелось Clojure в браузере? troll http://plasma-umass.github.io/doppio-demo/

y.khmelevskii15:07:22

@artemyarulin спасибо. вот только мне нужен swagger, а я пока подружить спеку, педестал и сваггер не смог

y.khmelevskii15:07:49

вот смотрю на https://github.com/metosin/spec-tools. Может эта штука поможет

artemyarulin15:07:43

сваггер тема да, но я начал юзать его уже после кложы, не могу сказать

artemyarulin15:07:04

>в редюсере после изменения стейта позвать диспатч? так это ж уже и/о, а не чистота вся цепочка выглядит вот так control -> action -> [action-can-produce-new-actions] -> data -> reducer -> new state. При таком подходе action это где все IO происходят, редьюсеры все чистые. На самом деле это все фигня - главное найди одно место где весь IO у тебя будет происходить и все будет ок. Тока помни что мутирование переменной (атом) это тоже IO (хаскель FTW!). Как тока весь IO будет изолирован - дальше можно чо угодно делать ибо все остальное то чистое

misha15:07:51

@dottedmag сижу монстрю что-то подобное: мапа {[state-keys] callback}, которую засуну в 1 вочер, который будет по всем ключам проходиться, и если значение хоть одного из state-keys изменились - дергать колбэк, в котором просто (диспач ивент) лежит

misha15:07:35

вот-вот :D

misha15:07:03

мне не нравится action -> [action-can-produce-new-actions]

misha15:07:25

потому что экшн - это тупо киворд, откуда ему знать, какие в итоге ключи в стейте поменяются?

misha15:07:16

а new-actions появляются, если что-то внутри стейта поменялось конкретное

artemyarulin15:07:10

action не меняет же стейт напрямую

artemyarulin15:07:24

он не знает про ключи в атоме

misha15:07:28

получается типа такого: button -> action -> handler -> new state -> [maybe-new-actions] -> handlers -> new state -> [maybe-new-actions] -> handlers -> new state -> ...

misha15:07:39

я так и написал )

artemyarulin15:07:21

у тебя ре-фрейм или руками все? Ре-фрейм же должен решить проблему стейта

misha15:07:19

да какой рефрейм, рум, но я хочу всё забацать так, чтобы весь стейт можно было в кложа-репле проверять, а компоненты все статическими сделать

misha15:07:56

рефрейм сложный какой-то, каких-то пустых аргументов везде дофига

artemyarulin15:07:24

аааа, рум как скала - умеет стейт хендлить как хочешь поэтому не умеет вовсе ::troll:

misha15:07:22

ну вот текущая имплементация - там размазано: половина в 1 атоме, половина в остальных, и еще немного в локальном, и песец

misha15:07:20

но рум же - просто вью либа, ты ж сам диктуешь как и чо. вот хочу перехачить так, чтоб можно было весь апп симулировать без компонент совершенно, а потом хоп и дописал компоненты

artemyarulin15:07:15

ну чисто redux 😄

artemyarulin15:07:42

ну еще ом-некст так умеет тоже, его возьми! troll

artemyarulin15:07:22

тут ксто юзает om-next? как оно вам?

misha15:07:44

:перекати-поле:

misha15:07:41

да какой редукс?

misha15:07:01

не умеет редукс стейт сам на себя подписывать

misha15:07:28

потому там стейт "плоский", а все подсчеты - в компонентах

misha15:07:56

так я тоже умею

artemyarulin15:07:55

Не понимаю я тебя, у нас в компонентах логики нет вообще, тупо f(data)->HTML

artemyarulin15:07:32

ну и в этом же фишка его, что не подсчеты в компонентах а в reducers. Тож самое с омом - контролы умееют тока наверх кидать эвенты, диспатчер их обрабатывает в одном месте и посылает если надо новые данные в контролы обрытно. One way data binding все дела

misha15:07:51

Reselect is a simple library for creating memoized, composable selector functions. Reselect selectors can be used to efficiently compute derived data from the Redux store.

misha15:07:15

вот так они решают дерайвед дату: зависимостью еще одной на проект, йопта

artemyarulin15:07:10

оспади, 107 строк, я думаю ты осилишь troll

misha15:07:16

ну лол

misha15:07:29

фишка же не в 100 строках зависимости

misha15:07:17

а в том, что у тебя редакс стор и редюсеры на одной странице, а вся эта дерайвед-дата-подсчет кухня - размазана по остальному проекту и компонентам

misha15:07:03

а я как раз всё о "что из чего вытекает, перетекает, зависит" хочу на 1 страницу как-то вывалить, чтобы в глаза поместилось

artemyarulin15:07:23

https://github.com/konukhov/redux-cljs Redux for ClojureScript based on core.async and transducers. во как, самый смак!)

misha15:07:30

похер на редакс, представь себе кор-асинк проект с 2 десятками каналов с мультами и тд

misha16:07:09

хочу 1 структурой данных всю канализацию эту описать наглядно, и потом кода из неё сгенерить

artemyarulin16:07:43

ну ты писал чуть выше что гиганский диспатчер ты тоже не хочешь. Оно не будет размазано прям по всему проекту, это вполне себе конкретный слой, все рядом будет лежать

misha16:07:47

какие каналы в какой сливаются, где мультиплексор стоит, где входы, где стоки, какие трансдюсери промеж них

artemyarulin16:07:15

>и потом кода из неё сгенерить ловите кложуриста! troll

misha16:07:20

про гиганский диспатчер не помню: может не так выразился, или ты не так понял

artemyarulin16:07:40

тут любят просто генерить 🙂

artemyarulin16:07:05

ну в общем я хз уже, ты как найдешь решение - скажи, мне уж самому интересно стало 🙂

misha16:07:17

ну лисп жеж йоптить, нечего его пальчиками набирать

misha16:07:18

надо в оникс посмотреть, там примерно такое же вроде: всё данными описано, но там слишком детально, а нужно на уровень-два выше

misha16:07:24

минимап

misha16:07:05

как Кишанов жаловался, что разрастается проект на рефрейме - вроде всё структурировано, а вроде уже и хрен пойми как оно выглядит "свысока"

misha16:07:49

вот такую беду для подписок пока налепил, нужно чуть поитерировать:

(def SUBSCRIPTIONS
  "{[state-keys-to-watch] callback]}"
  {[::paused?]
   (fn [old-state new-state]
     (if (-> new-state ::paused? (true?))
       (dispatch ::pause!)
       (dispatch ::play!)))

   [::playback-rate]
   (fn [old-state new-state]
     (dispatch ::change-playback-rate!))})


(add-watch !STATE ::derivatives
  (fn [k r o n]
    (doseq [[ks f!] SUBSCRIPTIONS]
      (let [ov (select-keys o ks)
            nv (select-keys n ks)]
        (when (not= ov nv)
          (f! o n))))))

artemyarulin16:07:12

капс убери, не по джентельменски

misha16:07:42

буду опенсорсить - уберу, а так нет troll

misha16:07:24

я еще не определился с нейминг конвенциями

artemyarulin16:07:48

>`(fn [k r o n]` да ты все по одной букве называй чо ты troll

misha16:07:12

get- уже не дописываю функциям, но со словарями еще путаю

misha16:07:31

ну крон - отличная мнемоника для watch-функций

misha16:07:27

кароче идея такая, что диспатч свапает стейт по экшн-киворду (надо ему ! дописать), и один вочер обслуживает все каскадные подписки

artemyarulin16:07:40

а !STATE восклицательный знак в начале это чо значит? в конце обычно когда IO

misha16:07:58

получается, что диспатч дергают только ивент-хендлеры, типа он-клик, он-сик, и вот этот вот единственный add-watch

misha16:07:23

вначале - вместо Никитиного *

misha16:07:51

вконце - это для функций, а вначале - для рефов

misha16:07:23

! - симметричненько со свапом, и мне удобнее набирать

misha16:07:13

работает opieop

mike_ananev19:07:26

всем привет. а кто-нибудь уже использовал сие? https://github.com/jeaye/orchestra

mike_ananev19:07:24

фак зе тайп систем короче

misha20:07:24

@mike1452 а какой аргумент не проверять :ret? я чот забыл

misha20:07:46

@artemyarulin https://github.com/konukhov/redux-cljs какой-то многословный слишком, либо я еще не разобрался и не осознал степени гемора проблемы, либо там и правда личнего как-то дофига, например, зачем экшен - мап с одним полем всего, ну и всякого по-мелочи да и она заброшеная™ troll

artemyarulin20:07:49

да ты погугли redux clojurescript выдает тысячи их, ты свой костыль велосипед свою реализацию сделай! 🙂

mike_ananev20:07:19

@misha аргумент у Рича? не знаю. эта либа все проверяет - спеку на:, входные, выходные параметры и fn спеку

misha20:07:43

@mike1452 это я понял, но там был годный аргумент, почему :fn и :ret не проверяются в спеке, только я его забыл kappa

mike_ananev20:07:44

@misha :ret and :fn specs were originally validated by instrument, but this feature was removed because Rich et al thought it redundant, and that there were different (and arguably better) tools for validating :ret specs, e.g. check.

mike_ananev20:07:21

On Monday, July 11, 2016 at 10:01:05 AM UTC-4, Rich Hickey wrote: On Sunday, July 10, 2016 at 6:04:39 AM UTC-4, puzzler wrote: 1. No way to test function output specs. For documentation purposes, I want to have an output spec on my function. However, as far as I know, after instrumentation-triggered checking of output specs was removed a couple of alphas ago, the only way remaining to check against output specs is to use randomly generated tests. So if I can't make good generators, I have no way to confirm that my output spec works the way I think it does. My documentation could be totally out of touch with reality, and that displeases me. Running return-value instrument-style checking on whatever few hand-written tests you might have isn’t going to give you better coverage than a simple (even hardwired) generator that captures similar ranges. And you can directly exercise your :ret spec - it’s just another spec. You can also spec/assert on your return - the tests will disappear in production, although this is similarly as weak as instrument-triggered return checking, so I’m not going to help you do it, but you can do it yourself 🙂

misha20:07:11

ага, Миллер, когда объясня, делал упор не на "хз чо оно там натестит", а на "слишком жирно на каждый вызов функции запускать для неё генеративное тестирование - ласты склеятся"

artemyarulin20:07:39

я почитал объяснения Ричи но все равно так и не понял зафега убрали эти проверки если честно. Перформанс тоже мимо ибо спеки тока в девелпменте работают же

mike_ananev20:07:33

@artemyarulin тогда просто, верь Ричу. Рич сказал, значит так надо. )))))))))

artemyarulin20:07:10

ну дада, иногда Ричи такую фигню задвинет что ужосужос, а через пол года дойдет тока 🙂

artemyarulin20:07:09

все помню как через пару недель с кложай - “в смысле я не могу поменять перменную, чозанах??111” 🙂

misha20:07:16

спеки работают там, где ты ихх включишь и не выключишь