This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2017-11-03
Channels
- # beginners (167)
- # boot (22)
- # chestnut (3)
- # cider (9)
- # clojure (107)
- # clojure-berlin (1)
- # clojure-greece (3)
- # clojure-italy (6)
- # clojure-losangeles (6)
- # clojure-russia (8)
- # clojure-spec (71)
- # clojure-uk (42)
- # clojurescript (186)
- # community-development (1)
- # core-async (12)
- # core-typed (1)
- # css (15)
- # cursive (29)
- # data-science (11)
- # datomic (8)
- # defnpodcast (28)
- # duct (2)
- # fulcro (169)
- # graphql (6)
- # hoplon (3)
- # jobs-discuss (1)
- # kekkonen (5)
- # leiningen (11)
- # lumo (7)
- # off-topic (14)
- # om (1)
- # other-languages (14)
- # portkey (7)
- # re-frame (27)
- # reagent (14)
- # remote-jobs (1)
- # ring-swagger (5)
- # rum (15)
- # shadow-cljs (52)
- # spacemacs (59)
- # specter (78)
- # test-check (3)
- # vim (9)
- # yada (23)
What is the shape of the data that gets passed to the :fn
argument of s/fdef
? Does someone have an example of that (or a way to print it)?
Thanks. Is that in the docs somewhere?
That is all correct - the values of the map are the confirmed values of the args and ret specs
I’m not sure where it would be doc’ed in the docstrings
Thanks
:fn A spec of the relationship between args and ret - the
value passed is {:args conformed-args :ret conformed-ret} and is
expected to contain predicates that relate those values
Ah, thanks.
So, if the function returns a single value (like a number), then (% :ret)
in the :fn
spec should yield the return value?
Depends on the ret spec
If it’s a simple pred then yes
Sweet, thanks.
I was surprised that putting a do
expression with a println
in the :fn
spec didn't print anything when the function was called (instrumentation on)
> Instrumentation validates that the :args spec is being invoked on instrumented functions …
> check
will generate arguments based on the :args
spec for a function, invoke the function, and check that the :ret
and :fn
specs were satisfied.
Cool. I ran a check
and it printed out what was passed to :fn
.
If I have a production spec of say an email address, it will require a custom generator if I want to generate test data. Since a generator typically will not be used in production would it be a good practice to redefine the production spec in i test ns that will include the generator, keeping any generators out of production code? Can this lead to problems if I have nesting and to be able to generate the top level spec I need to redefine lower levels with the generator in my tests?
Another thing to consider is using generator overrides at the point of testing. That way you don’t have to redefine a spec, you just supply a set of alternate generators.
But in the case of a nested spec such as a person having an email, and I am testing the person don't I have to redefine the email spec refered by the person spec?
Is generator overriding done by using with-gen
or are there other ways I have missed?
no, you can supply custom generators in exercise, instrument, check, etc
in stest/check
for example, you can supply a :gen map in the options: “map from spec names to generator overrides”
so that way you can supply overrides just in the context of a test
Good to be reminded of that. So far, we've tended to write wrappers for generators so we can lazy load the testing library (and therefore keep the actual "testing generator" in the production code without needing the testing libraries in production).
hello, has anyone here though about the idea of specing nested structures? currently s/keys
only supports flat structures, if I need a nested I have to define the nested structure ahead of time on that key, this prevents different nesting structures depending on the context
maybe we could support via a syntax like the datomic pull syntax, eg: (s/keys :req [:user/name {:user/address [:address/line1 :address/city]}])
@U066U8JQJ have you checked https://github.com/metosin/spec-tools/blob/master/README.md#data-specs ? nests also vectors and sets. In the end, just generates specs with alternative (macro free) syntax.
that’s not in line with the “set of attribute” thinking and no plans for that
the issue I'm facing is that for the "container" specs I might want different subsets of keys, depending on the context
so by not having a fixed for the children, it gets tricky
you don’t need a fixed spec for the children
an empty (s/keys) is sufficient to cover an open set of attributes
or use s/multi-spec to select the spec based on the contents
or s/or multiple choices, etc
thanks for the tips Alex, I like the open one, but at same time, if I want to require different sets of keys depending on the context, that doesn't work, the multi-spec can work, but its a lot more involved
I love the idea of living by just attributes, but if I need to give a name to a context of sub-attributes, I feel like backing again to the "box" (class, entity, whatever...) constraints again
@U055NJ5CC thanks for pointing that out, I'll look it up
what you’re saying is that they key at the top level does not have a stable semantic meaning so I would think about what that means and whether it’s a good idea
yeah, in general terms, any sub-set might be unstable, if what you care is just about the leaf attributes validation
I've been writing a considerable amount of code regarding to data fetching apis (om.next style), and many times I see that the sub-set of keys of a child element can vary wildly, in my case I'm embracing this and it's working pretty good, but I can't get the specs around to match it in the way it is
(s/keys) ! :)
the problem is the children, for example, working in micro-service architecture
I have many endpoints across services that can return different sub-sets of the data
and altough they share some root keys, what comes in the children is variable, some endpoints give more, some give less information
and in current spec way, I can't define what is required for each return (or input) on a case-to-case bases
in the same way we can't have a good definition of what are the required fields for an user
(a login might be user/password, a signup would require much more)
I feel the same problem when trying to specify requirements for a nested item
I think that’s all ok, and you should not try to define every key set aggregation
lean on the attributes
but that's the problem, if I have one key like :user/address
, I expect this key to be the same always, but what I expected to be inside of it can change from case to case
on the top level, just create a new set and we are all good
for the nested, there is no way to override the requirements
to say that the sub-set is different a separated case, makes sense?
why not just (s/def :user/address (s/keys))
?
then rely on your address attribute specs to do the work
the only issue there is that we can't make some attributes required for a context that way
so the validation gets too loose
if you need that then it sounds like s/multi-spec to me, or state all the possibilities with s/or, or add outer constraints s/and’ed at the top level
humm, the top level constraint sounds like a good path for the cases I'm thinking
thanks, I'll try that and see how it goes
always come back to “state the truth about what it’s in your data” - what can occur in your actual data? say that in the spec.
had anyone felt the desire to specify the kinds on that way?