Fork me on GitHub
#cursive
<
2021-12-16
>
cfleming00:12:42

Something I’ve been meaning to add for ages: the ability to diff data structures from the REPL.

🎉 12
🙌 4
😍 3
kenny00:12:22

This will be a huge win!!

cfleming00:12:19

I hope so! I’m not sure yet how it will perform for really big structures (the return value has to contain both sides of the diff, and the UI might be interesting too).

kenny00:12:48

It'd perform equivalently to how it performs in the clojure.test integration, I'd assume?

cfleming00:12:08

Right, but I suspect people will use this with larger results.

kenny00:12:34

Ah. Probably right. Maybe generate some large data with test.check and see what happens 😅

cfleming00:12:39

Yep. I can probably create an option to elide identical values in maps and replace them with ... or something too.

kenny00:12:26

Ooo. That'd be awesome and useful even for the test integration!

kenny00:12:22

One thing that's always been really tough to parse out is when a set of maps differs from the left and right sides. The diff UI seems really tricky and perhaps some assumptions had to be made. I could find an example if interested.

cfleming00:12:38

Yes, I’d definitely be interested in an example.

cfleming00:12:14

It’s definitely hard to know how to present arbitrary diffs, since it’s impossible to know how arbitrary data structures should be formatted.

kenny00:12:35

Yeah. I have no idea how you'd even present the diff for a set of maps in the correct manner, now that I think about it. You don't know the semantics of the things I want compared since they're in a set.

cfleming00:12:26

Right, and it’s often obvious to the user how you would want that data formatted, but that can’t be determined automatically. If you have suggestions about how it might work I’m all ears.

✔️ 1
cfleming00:12:51

I’ve thought about showing the diffs as a collapsible tree, but haven’t got around to a proof of concept for that.

kenny00:12:05

Sent a follow up with a difficult map+set diff via DM. I don't have any ideas on that one since it seems very hard to do for arbitrary data.

kenny00:12:20

Here's one I've gotten used to at this point: list vs vector show up in the diff even though they will be treated as =.

cfleming00:12:23

(= '(1 2 3) [1 2 3])
=> true
WAT

cfleming00:12:31

I’m truly shocked by that.

cfleming00:12:02

Those things are not equal by anyone’s definition.

kenny00:12:00

Haha. It has some weird consequences too. It does happen to be useful in tests a lot since the vector literal is nicer to type than (list ...). Fun thread on the topic: https://clojurians.slack.com/archives/C03S1KBA2/p1621184012406400

kenny00:12:15

Maybe you've seen this already, but here's another interesting approach: http://fazzone.github.io/autochrome.html

cfleming01:12:54

Yep, there are a bunch of them - deep-diff2, editscript and a couple more.

kenny01:12:24

One other thing I was curious about. If a test reports :expected and :actual keys and is not an is form, could the diff still be shown?

cfleming02:12:58

Umm… maybe? I’d have to go back and refresh my memory of how clojure.test works. What’s your use case?

kenny02:12:31

From a naive perspective, it seems reasonable that any test report that contains an expected and actual could render the diff viewer.

cfleming02:12:10

Seems reasonable, I’ll take a look.

kenny02:12:16

Anyway, thanks for working on the diff api function. That will be really helpful.

imre14:12:41

This is a really promising feature, thanks Colin!

agigao06:12:46

Hey there, I wonder how Cursive "decides" which profile to use and load? For example I have dev,test under profiles in repl configuration. Both configurations have corresponding config dirs: config/test/ and config/dev/ populated with config.edn . Repl starts by having both dirs in a classpath. And when I run test in the repl, which loads fixture from the same dir, where we load config file using https://github.com/yogthos/config, :java-class-path has config/test. By contrast, when dealing with Emacs, I have to manually specify the test profile. And I wonder how does Cursive choose a proper profile and/or config dir for :java-class-path? Not completely sure if it's the right place and the sound question, though 👻

cfleming08:12:57

So there are two places where you can configure profiles, and they do different things. There’s this: https://cursive-ide.com/userguide/leiningen.html#working-with-profiles, which is used when syncing the project to the IDE. And then you can also select the profiles to be used when constructing the classpath in your REPL run configuration, and that will be used to start the REPL (or other task). Does that make sense?

cfleming08:12:38

It sounds like you’re talking about running a REPL, so it’s probably the second of those. You can find the selected profiles in the run config.

Daniel Stephens10:12:18

Hi all, wonder if anyone could help me sort this issue with test output when an exception is thrown or confirm if it's a cursive bug? Basically if somethig inside of (is) throws an exception, then I only get the top level Exception when running with cursive's 'run test' fns. If it's not in an (is) it works fine so my guess was that cursive overrides the report :error multimethod and drops the cause, but I'm not sure. Attached shows: • what I get running with other test runners, showing both the top level and causing parts of the exception. • what I get running with cursive REPL -> run test fns which only shows top level • and the test that I used for recreation purposes