Fork me on GitHub
#clojure-spec
<
2017-07-27
>
misha13:07:43

@alexmiller @gfredericks I'd listen about "highjacking" specs with generators, and generators strategies in general, e.g. for cases, where you need to define some root rules, and all downstream generators need to inherit it. Which is, probably, the same issue/situation, as "I wrote a lib, and need to either hardcode some resource to use it implicitly (bad, but easy), or need every function to accept it as an argument (good, but messy verbose)". Think taxi-driver's browser arg, component vs. mount, etc. One use case would be testing datomic/datascript, where on the one hand you have all the specs about db/`tx-report` structure, but on the other, when you test actual transaction, – an extra layer of testing the data flow is required, like "my temp ids appear in tx-report, and transacted data appears in db". Such "flow" specs can be described, and tested generatively, but it is somewhat messy, and is hard to keep de-complected from "structure" specs.

gfredericks13:07:39

@misha is this a situation where you're doing a higher level test and want to model some external system?

misha13:07:30

the closest to real life I got – is datascript testing, which I described. It probably is "higher level testing" from some pov, but feels like essential for any lib a larger than few util functions

misha13:07:23

You might perceive datascript as being external to the app code, yes. Not sure if I answered your question

gfredericks13:07:44

Is "flow" vs "structure" partially about one call vs multiple calls?

misha13:07:00

yes, though, those multiple calls could be a single fn.

gfredericks13:07:22

Right; okay cool that makes sense

misha13:07:44

ok, how'd you go about testing datscript/datomic's transact!? I'd have specs for db, tx-report. I'd see, if structure conforms the specs. But then I'd need to test that, all temp-ids are permanent, that mapped temp-ids - are the same and for same entities, as in submitted data. That extra data in new db - is in fact submitted data. I feel, like it can be done on "generators" level, and not in just custom test code, which does not leverage, say, spec. Because after I'm done testing datascript, I want to model it (lol now I understand your question opieop) to enable testing app code build on top of it, and I would not be able to do this with custom test code, which does not leverage generators

gfredericks13:07:31

@misha so when you say "custom test code" you're thinking of example-based tests, not something like vanilla test.check properties?

misha13:07:48

yeah, I think so.

misha13:07:41

I think the question can be narrowed down to "how to use system-wide seed data, and set of rules, which affect all(most) of the generators"

misha13:07:52

I don't have an intuition developed in this area much, so I might be talking gibberish here and there. That's why I'd listen to something structured on the topic opieop

gfredericks13:07:27

yeah, it sounds like you need a higher level overview; which is somewhat at odds with alex's more focused talk idea, but it might be that going over certain generator patterns would illuminate other aspects as a side effect

misha13:07:18

anything helps, and generative testing is so huge, but "under-appreciated" from talks perspective. Everyone's just "here, you can generate strings, ints, and booleans. Boom! Off you go."

misha21:07:47

@gfredericks check this out, interesting approach to closures, to solve what I was trying to describe earlier today: https://clojurians.slack.com/archives/C03S1KBA2/p1501187926443798

misha21:07:32

~alternative to closures and dynamic vars

gfredericks22:07:07

@misha this is related to test.check generators somehow?

misha22:07:59

@gfredericks no, but this might be useful in a highjacking generators with seed data. Seemed relevant to what I wrote earlier today...

gfredericks22:07:44

@misha I'm having trouble figuring out what you mean by hijacking a generator

misha22:07:49

I am having trouble describing it opieop

misha22:07:22

I had a problem with my spec usage, where I wanted to have a spec for, say datascript entity. This spec contains datascript id spec, which can specify either id-before-transaction (actual id or temp id), or id-after-transaction (actual id only). So I have this nested spec, at the bottom of which there is an id-spec. For some tests I wanted that id-spec to be id-before-transaction, and for the others – id-after-transaction.

bfabry22:07:08

ok I can't find a gif to demonstrate it. but imo that sounds like a sign that you have two different things that should have different names

misha22:07:12

@bfabry that's sort of true, but I doubt, that redefining entire entity spec with only id spec change – is THE solution.

seancorfield22:07:26

What about s/merge?

seancorfield22:07:23

Define a datascript-core spec and then have datascript, datascript-before-transaction, and datascript-after-transaction for the three cases where you 1) don't care, 2 & 3) do care.

seancorfield22:07:03

(or possibly you only need datascript and transacted-datascript since the ID in the first one is either anyway)

seancorfield22:07:30

Given that you have two ID specs, presumably there are situations where you care which type of ID you have?

seancorfield22:07:59

(if you don't care, you don't need two specs -- you're over-specifying!)

misha22:07:17

@seancorfield in this example, you are might be 100% right. But I just want to illustrate a situation, where you might have a composed spec more than 2 levels deep, and you want to replace a leaf sub-spec or a generator for it.

misha22:07:26

in that case I cared about pre/post transact ids, hence the "story"

misha22:07:47

all of it is to describe "what I'd like to hear about in test.check conj talk" opieop