Fork me on GitHub
#clojurescript
<
2017-11-19
>
grzm00:11:13

I've got a cljs.test failing. It's a simple (is (= a b)) test, and the Actual output shows no difference. Like I literally copy-paste the Actual into a repl and it returns true.

Fail (thrower) (com/grzm/dev/cljs_stacktrace/util_test.js:1269:51)
	Expected (= first-file-expected first-file-actual)
	Actual: (not (= "resources/public/js/compiled/out/test/com/grzm/dev/cljs_stacktrace/helpers.cljs" "resources/public/js/compiled/out/test/com/grzm/dev/cljs_stacktrace/helpers.cljs"))

grzm00:11:08

Any ideas as to what I should look at?

au-phiware00:11:08

I'm tempted to say types (but I don't think that makes sense)? have you tried == instead of =?

grzm01:11:58

Yup. Same result. (btw, I think == is just for numerical comparisons, as I understand it. http://clojuredocs.org/clojure.core/==)

grzm01:11:03

I've also checked (= (meta a) (meta b)), and that succeeds (just trying to cover all my bases)

au-phiware02:11:07

maybe (= (str first-file-expected) (str first-file-actual))??

au-phiware02:11:27

(clutching at straws...)

grzm02:11:49

I appreciate you're efforts 🙂 Makes me feel less alone. That doesn't work either.

au-phiware02:11:30

yeah, I can get lonely on this channel... I think I must be in the wrong timezone of something...

grzm02:11:08

yeah, it's after 8PM local for me. It looks like it's midday for you?

zakpatterson02:11:32

@noisesmith I appreciated your help earlier with the stateful component question above. I thought through this for a while and came up with another alternative based on your idea I'm going to start using. This lets me create reusable stateful components without always needing to know the state-shape the component expects. here's a gist: https://gist.github.com/zakpatterson/4df511752b4f53d23deef4de309644c3

au-phiware02:11:54

so @grzm, what are you comparing exactly? are they file objects? can you get the absolute paths?

grzm02:11:04

I'm parsing stacktrace frames.

grzm02:11:43

The stacktrace is just a vector of maps.

au-phiware02:11:31

and you're pulling out the first map from the vector... :thinking_face:

grzm02:11:28

Yeah. The higher level (which is also failing, of course), is (vec (take 2 stacktrace)). Trying to dig down to see what's different, I'm comparing the values of the maps. That filename value is what's failing the equality test in each frame.

au-phiware02:11:14

so that file value can't possibly be a simple string, right? otherwise the test would pass? odd... what could it be?

grzm02:11:33

That's a good idea…

Expected (not= (type first-file-expected) (type first-file-actual))
	Actual: (not (not= #object[String] #object[String]))

grzm02:11:00

I tested using not= so we can see the output. So, that's not it, either 😕

au-phiware02:11:22

well, that's frustrating... how about using clojure.string/includes?

au-phiware02:11:24

i.e. (and (includes? first-file-actual first-file-expected) (includes? first-file-expected first-file-actual))

au-phiware02:11:24

maybe there's a \ff or \cr in there...

au-phiware02:11:55

I'm thinking you need to use hexdump

grzm02:11:56

Yeah, that's a good idea. There's definitely some extra characters there. The counts are different.

grzm02:11:18

Now we're getting somewhere. 🙂

au-phiware02:11:29

maybe just use trim and be done with it

grzm02:11:30

Somehow there's a "base/" prefixed to the actual string! Why isn't that showing up?

grzm02:11:21

Is the string some kind of array buffer that has an offset?

au-phiware02:11:39

really, that would seem to be a greater mystery

au-phiware02:11:18

what, like a golang slice? I don't think so!

grzm02:11:50

I was thinking more like a Java bytebuffer, but yeah, neither should be the case in cljs

grzm02:11:02

Cleary I'm missing something.

au-phiware02:11:18

that would seem very un-clojure... but you know: javascript!

au-phiware02:11:42

that's both the problem and one of cljs best selling points: you can't get away from the host system

au-phiware02:11:17

so the diff of the counts is 5?

au-phiware02:11:12

or is there like 5 backspaces so that the string prints that way?

noisesmith02:11:32

how about

(is (= (class a) (class b)))
(is (= (count a) (count b)))
(is (= (str a) (str b)))
?

noisesmith02:11:20

perhaps (seq a) (seq b) would be revealing, even if they print the same as one another

grzm02:11:18

count are different, str is different, type is different. and yeah, I used seq to reveal the "base/" at the beginning of one of actual.

au-phiware02:11:20

hmm, so you can use str in your test?

au-phiware02:11:26

or just put "base/" in your expected string? You have this solved, right?

grzm02:11:39

(Does class exist in cljs?)

au-phiware02:11:06

(I didn't think so)

noisesmith02:11:12

type is better regardless

grzm02:11:52

Here's a summary of what I'm looking at:

Fail (thrower) (com/grzm/dev/cljs_stacktrace/util_test.js:2367:51)
	Expected (= first-file-expected first-file-actual)
	Actual: (not (= "resources/public/js/compiled/out/test/com/grzm/dev/cljs_stacktrace/helpers.cljs" "resources/public/js/compiled/out/test/com/grzm/dev/cljs_stacktrace/helpers.cljs"))
	
	Fail (thrower) (com/grzm/dev/cljs_stacktrace/util_test.js:2367:51)
	Expected (= (count first-file-actual) (count first-file-expected))
	Actual: (not (= 84 79))
	
	Fail (thrower) (com/grzm/dev/cljs_stacktrace/util_test.js:2367:51)
	Expected (= "" first-file-actual)
	Actual: (not (= "" "resources/public/js/compiled/out/test/com/grzm/dev/cljs_stacktrace/helpers.cljs"))
	
	Fail (thrower) (com/grzm/dev/cljs_stacktrace/util_test.js:2367:51)
	Expected (= [] (take 10 (seq first-file-actual)))
	Actual: (not (= [] ("b" "a" "s" "e" "/" "r" "e" "s" "o" "u")))

au-phiware03:11:07

that's so strange, but if you use (= first-file-expected (str first-file-actual)) then it passes?

au-phiware03:11:49

because goog.string.StringBuffer is doing something strange?

grzm03:11:14

Nope. That fails, too.

au-phiware03:11:44

I mean, yes, that's good

grzm03:11:15

Expected (= (str first-file-actual) (str first-file-expected))
	Actual: (not (= "resources/public/js/compiled/out/test/com/grzm/dev/cljs_stacktrace/helpers.cljs" "resources/public/js/compiled/out/test/com/grzm/dev/cljs_stacktrace/helpers.cljs"))

au-phiware03:11:20

try (= (str "base/" first-file-expected) (str first-file-actual))

au-phiware03:11:57

or change your def of first-file-expected

au-phiware03:11:38

or just (= (str "base/" first-file-expected) first-file-actual)

grzm03:11:44

Appending "base/" works. What's so curious is why it prints the way it does.

au-phiware03:11:56

yes, I agree

au-phiware03:11:03

but you might have to take that up with the Google Closure folks 😕

grzm03:11:06

It looks like "base/" means something special

au-phiware03:11:31

you could have a race condition... goog.string.StringBuffer is mutable 😞

grzm03:11:20

My test assertion looks like: (is (not= (str first-file-actual) (str "base/" first-file-expected))) (using not= so I can see the failure results)

grzm03:11:58

The failure results look like:

Expected (not= (str first-file-actual) (str "" first-file-expected))
	Actual: (not (not= "resources/public/js/compiled/out/test/com/grzm/dev/cljs_stacktrace/helpers.cljs" "resources/public/js/compiled/out/test/com/grzm/dev/cljs_stacktrace/helpers.cljs"))

noisesmith03:11:24

wait, why does "base/" just disappear?

grzm03:11:29

I know, right?

au-phiware03:11:21

oh... it's disappearing on the expected value? I thought it was the other way around... 😕

au-phiware03:11:28

wait it even disappears in the first line of output...

grzm03:11:30

No, I'm appending it to the expected like you suggested. But look at how it's printing.

grzm03:11:20

This doesn't happen in my browser repl, so I don't know what's going on 😕

au-phiware03:11:52

it's like the output is piped through sed /base\//s///

grzm03:11:58

I think my brain is full.

au-phiware03:11:21

😆 I don't blame you

au-phiware03:11:09

I'm now thinking there's something else in your toolchain that's wreaking havoc

grzm03:11:37

Yeah. It could be doo or karma or chrome

au-phiware03:11:34

the toolchain is the worst part of web dev 😞

grzm03:11:01

same thing happens with safari as the browser

grzm03:11:43

Yeah. One of the things I'm trying to do here is ensure portability. Toolchain improvement is actually my goal.

grzm03:11:16

I'm working on using source maps to improve stacktrace readability.

au-phiware03:11:41

hey, maybe if you look at something else for while you'll come back to it with a fresh perspective, here is the problem I'm facing 😉

au-phiware03:11:43

I'm attempting to use https://github.com/jasondavies/d3-parsets in a project... but I get this error from boot cljs:

java.lang.IllegalArgumentException: Duplicate module path after resolving: /home/corin/Projects/Demos/boot-parsets/node_modules/d3/d3.js
I've created a minimal project: https://github.com/au-phiware/boot-parsets...

grzm03:11:00

nice segue

au-phiware03:11:47

when I google the error, I get the source code the emits the error... I hate it when that happens

grzm03:11:52

What else do you have on your filesystem besides the repo? From a fresh checkout, when I run boot cljs I get a different error: SyntaxError: Block-scoped declarations (let, const, function, class) not yet supported outside strict mode

au-phiware03:11:41

oh... um, let me try a clean

au-phiware03:11:44

I don't get a SyntaxError from a clean repo... I've built clojurescript from master in the past... maybe it's that...

au-phiware03:11:15

I tried blowing away ~/.m2/repository/org/clojure/clojurescript but still no SyntaxError

au-phiware03:11:44

is it complaining about es6/d3/parsets.js?

grzm03:11:33

It looks like it's higher up than that:

Writing main.cljs.edn...
Compiling ClojureScript...
• main.js
[eval]:1
let fs = require('fs');
^^^

SyntaxError: Block-scoped declarations (let, const, function, class) not yet supported outside strict mode

au-phiware03:11:19

what? eval? I don't know where that comes from

grzm03:11:28

me, neither

au-phiware03:11:36

what's your boot version?

au-phiware03:11:52

 boot -V
#
#Sun Nov 19 14:45:07 AEDT 2017
BOOT_CLOJURE_NAME=org.clojure/clojure
BOOT_CLOJURE_VERSION=1.8.0
BOOT_VERSION=2.7.2

grzm03:11:20

I haven't compiled cljs with boot, though, so there might be something else wrong with my setup.

grzm03:11:30

I can't even find "let fs" in the repo.

grzm03:11:35

λ boot -V
#
#Sat Nov 18 21:51:17 CST 2017
BOOT_CLOJURE_NAME=org.clojure/clojure
BOOT_CLOJURE_VERSION=1.9.0-RC1
BOOT_VERSION=2.7.2

au-phiware03:11:56

it looks like nodejs...

au-phiware03:11:12

do you get

Classpath conflict: org.clojure/clojure version 1.9.0-RC1 already loaded, NOT loading version 1.8.0
when running boot cljs?

grzm03:11:00

I get the same thing when using 1.8.0

au-phiware03:11:14

I tried BOOT_CLOJURE_VERSION=1.9.0-RC1 boot cljs but I don't get SyntaxError...

grzm03:11:33

λ node --version
v4.8.4

grzm03:11:14

that's probably it

grzm03:11:41

updating...

au-phiware03:11:42

ok, so cljs is trying to npm install and can't

au-phiware04:11:30

wow... how do I specify the node version in my project config... it's the toolchain again!

grzm04:11:21

I think that's handled by $PATH

grzm04:11:57

so, if you can update PATH via boot, then you're good

au-phiware04:11:15

so, you get the same error as me now?

grzm04:11:35

I'm still updating, actually. 😕

au-phiware04:11:57

oh, fair enough

grzm04:11:28

yay, toolchains. I'm dealing with dependency hell

grzm04:11:42

well, now I get the same error you do.

grzm04:11:30

one thought I had was that there were multiple inclusions of d3 in node_modeules, but I see only one.

au-phiware04:11:31

yeah, often you get a node_modules dir inside other modules, but that thought didn't get me anywhere

grzm04:11:44

The comment in the closure-compiler near that error is // Having root paths "a" and "b" and source files "a/f.js" and "b/f.js" is ambiguous. https://github.com/google/closure-compiler/blob/master/src/com/google/javascript/jscomp/deps/ModuleLoader.java#L275

grzm04:11:26

Looking at the project:

λ find . -name "d3*"
./es6/d3
./node_modules/d3
./node_modules/d3/d3.js
./node_modules/d3/d3.min.js
./node_modules/d3/src/d3.js

grzm04:11:29

Perhaps the conflict is between the two d3.js files. I'm spitballing here.

grzm04:11:52

I'd think :npm-deps is smart enough to handle that, but I'm out of my depth here.

grzm04:11:27

Looks like the same issue using the cljsjs package.

au-phiware05:11:01

hmm, fair comment, changing the name of the namespace has no effect 😞

rename es6/{d3 => }/parsets.js

au-phiware05:11:00

I feel like I need to throw in a lot of println into ModuleLoader.java....

au-phiware05:11:38

ok, I'm doing it, I'm building com.google.javascript/closure-compiler-unshaded off master

grzm05:11:28

good luck 🙂 An alternative would be to try lein. I think there are examples using d3 out there.

au-phiware05:11:50

I know! I'm converting a project from lein to boot... I had it working with lein but for some reason it broke... I'm deep in the rabbit hole now!

grzm05:11:29

ah. gotcha

Shantanu Kumar08:11:15

Hi. Are there any well-known pointers available on the Internet on how to create a library targeting both Clojure and ClojureScript?

au-phiware08:11:35

I have found that most examples and tutorials about cljs that have a server side component use Clojure (on the server side)

au-phiware08:11:36

chapter 11 discusses the use of Clojure on the server

Shantanu Kumar08:11:49

@au-phiware I guess the Modern-CLJS approach is too web heavy for me, and I am looking for ways to test the library under both CLJ and CLJS.

au-phiware08:11:56

oh, I see, I've been focused on web, so I haven't come across any

au-phiware08:11:08

so, your looking for cljc centric resources?

Shantanu Kumar08:11:57

yes, CLJC with occasional CLJ and CLJS dependency for platform-specific bits

Shantanu Kumar10:11:26

Is there a way to require macros in CLJS so that I can refer them namespaced? E.g. (foo/bar :baz)bar is a macro here.

Shantanu Kumar10:11:35

If I do (:require-macros [myapp.foo :as foo]), then I can no more refer to functions in foo?

juhoteperi10:11:20

On most cases you don't need to use :require-macros, :refer-macros, just just macros like they were functions

Shantanu Kumar11:11:12

Oh, never knew that! Thanks for sharing that tip.

juhoteperi10:11:20

On most cases you don't need to use :require-macros, :refer-macros, just just macros like they were functions

mfikes12:11:44

@kumarshantanu See the Implicit macro loading: section of (doc ns). Also see more exposition at http://blog.fikesfarm.com/posts/2016-03-01-clojurescript-macro-sugar.html

gklijs14:11:38

I have a small spec-serialize library I only use myself, where almost everything is in one core.cljc file, using (ns spec-serialize.core (:require [#?(:clj clojure.spec.alpha :cljs cljs.spec.alpha :default clojure.spec.alpha) :as s])) then a few small .clj and .cljs files witch use specific code, and call a function on the core.cljc.

mfikes15:11:08

@gklijs You can simplify your ns form to

(ns spec-serialize.core
  (:require [clojure.spec.alpha :as s]))
See Auto-aliasing clojure namespaces: in (doc ns) and some exposition at http://blog.fikesfarm.com/posts/2016-07-03-clojurescript-clojure-namespace-aliasing.html

gklijs15:11:14

Thanks, I didn’t know that, but it works

mfikes15:11:39

You just need to ensure that the clients of your library are on ClojureScript 1.9.198 or later.

mfikes15:11:58

Seems like you are your only client 🙂

gklijs17:11:22

Yes for now, At least I want to add some tests for clojurescript, and some clean-up and especially documentation, then maybe put it on githup/clojars.

Shantanu Kumar17:11:38

Inside a defmacro, is the reader conditional supposed to always favor :clj? E.g. (catch #?(:clj Exception :cljs js/Error) e# (println e#))

darwin17:11:34

"always" in your question is pretty tricky, think about self-hosted clojurescript where defmacro is actually cljs code

darwin17:11:08

I don't remember the answer, but you should think about these corner cases if you want your library to be 100% portable including self-hosted

Shantanu Kumar17:11:20

@darwin I’m using ClojureScript, not self-hosted one for now. (Digging into a puzzling error that complains: ReferenceError: java is not defined in CLJS)

darwin17:11:36

I could imagine some clojure macro to be unaware of clojurescript and generating some lower-level java interop code. When you use this macro in clojurescript, it will happily spit such java-interopy code in the middle of your cljs code.

Shantanu Kumar17:11:14

OK, so I was hit by the issue described here: https://groups.google.com/forum/#!topic/clojure/DvIxYnO1QLQ and here: https://dev.clojure.org/jira/browse/CLJ-1750 — fixed it with the (:ns &env) hack, but not sure if that’s supported by self-hosted CLJS. @darwin

vemv17:11:43

Hello there! Question, is with-redefs somehow incompatible with :advanced compilation?

vemv17:11:34

my codebase's tests use with-redefs extensively, suite breaks with :advanced wherever w-r is used

vemv18:11:21

I get errors in the form $my$namespace$blah$$.$cljs$core$IFn$_invoke$arity$1$ is not a function

darwin18:11:47

@kumarshantanu I'm sorry at some point I knew all the details of this, but I unloaded it from my brain... cannot help ATM

Shantanu Kumar18:11:54

No problem! Thanks for the pointers.

mfikes18:11:31

@vemv I'd suggest trying :static-fns false with :advanced to see if it might work for your case

vemv18:11:05

seems a good call! trying, thanks

mfikes18:11:42

@vemv with-redefs is involved in a couple of compiler unit tests that run under :advanced, but none of them attempt to redefine a function (especially a multi-arity or variadic function)

vemv18:11:29

@mfikes :static-fns: seems to have fixed it, thanks! 🍻 (can't be 100% sure, as suite now remains broken for new unrelated reasons)

mfikes18:11:54

Cool. That would make some sense, given the way with-redefs is implemented.

sova-soars-the-sora20:11:41

hi 😄 I am having trouble getting figwheel to work 😞 Figwheel compiles my js and starts but it reports Resource not Found when I try and connect

sova-soars-the-sora20:11:09

Aha, I see, I did not actually start the clojure-backend that generates the HTML page.

zignd22:11:45

om, reagent or re-frame, with which one should i start considering i'm just starting with ClojureScript?

zignd22:11:25

from just taking a look over the README.md in these projects they seem to be the same thing, interfaces to React from ClojureScript

au-phiware22:11:03

from my understanding om and reagent are independent projects that both attempt to provide a idiomatic clojure interface to react, and re-frame builds upon reagent

au-phiware22:11:56

fwiw I chose reagent when faced with the same choice as I felt that api was simpler

mikethompson22:11:55

@zignd I assume you have a javascript background, so will explain in those terms: reagent wraps React rum wraps React re-frame adds a redux-ish capabilities to reagent fulcro is om.next made easier. It wraps React, plus provides a client<->server story.

mikethompson22:11:19

@zignd I would suggest you start with reagent , kick some easy early goals. Feel good about progress, and then consider next steps from that platform.

mikethompson22:11:53

(but I am a bit biased, so listen also to others :-))

au-phiware22:11:53

I was going to mention om.next but I have found it very hard to find resources for it... good to know that fulcro exists 🙂

zignd22:11:14

thanks @au-phiware and @mikethompson, i think i will start with reagent as both of you recommend, and because its API seems more Clojure like and less JavaScript interop than Om, at least from what i could grasp by just checking their docs quickly, and i didn't know fulcro existed

mikethompson22:11:27

If you do choose the reagent path, then look carefully through these "Domino 5" resources: https://github.com/Day8/re-frame/tree/master/docs#domino-5

mikethompson22:11:06

(ignore the rest of that page, it relates to re-frame)

zignd22:11:33

thanks for linking this resource, i'll check it out!

grzm23:11:55

@au-phiware figured out the mystery of the missing "base/": it's stripped from output by the doo reporter: https://github.com/karma-runner/karma/issues/1706

au-phiware23:11:26

unreal... I ended up finding a bug in cljs compiler with my issue, I even filed a patch... it was late at night so I won't be surprised if it gets rejected at triage!