Comments (4)
It certainly is surprising behavior. For comparison:
(def spec-a (ds/spec ::spec-a {:x int?}))
(def spec-b (ds/spec ::spec-b {:x nil?}))
(s/valid? spec-a {:x nil}) ;; false
The idea is that if you provide a qualified name for the map key, it is used as-is, and for not-qualified keys the name is generated (example: user$spec-a/x
). This is in line with Rich Hickey's and clojure.spec's idea that the same (qualified) map key should always hold the same kind of data.
So it's not an outright bug, but ds/spec
silently redefining existing specs seems bad. It should probably throw an exception (maybe there should be an option to allow redefinitions – I don't immediately see an use case, but it would at least allow migration in case any users rely on the existing behavior).
from spec-tools.
Oh I have run into this when trying to override a key for an entity before the following:
(def ^:private crux-entity-w-ranges
(assoc crux-entity
:reference-range-set/reference-ranges
(s/coll-of ::mapper.reference-range/crux-entity)))
(def crux-entity-w-ranges-spec (ds/spec {:name ::crux-entity-w-ranges :spec crux-entity-w-ranges}))
I basically wanted to reuse the same structure for both, but it does not seem to be possible if I understand it right?
The :reference-range-set/reference-ranges
always gets overridden if qualified.
What would be a possible workaround (apart from malli
😄) ?
from spec-tools.
I tried the following but for some reason it still does not work (still checking for the :reference-range-set/reference-ranges
key)
(def ^:private crux-entity-w-ranges
(dissoc crux-entity :reference-range-set/reference-ranges))
(def crux-entity-w-ranges-spec (ds/spec {:name ::crux-entity-w-ranges :spec crux-entity-w-ranges}))
It makes sense, being the spec globally defined.
I ended up patching like so:
;; Data Spec follows what spec does here and seems to always
;; override :reference-range-set/reference-ranges.
;;
;; See https://github.com/metosin/spec-tools/issues/252
;;
;; Quite horrible and we should really consider Malli as an alternative.
(s/def ::reference-ranges
(s/or :uuids (s/coll-of ::mapper.reference-range/id)
:entities (s/coll-of ::mapper.reference-range/crux-entity)))
from spec-tools.
Started looking into this a little and unfortunately I don't think it would be possible due to the fact that spec doesn't support having the same namespace qualified keyword spec'd in more than one way.
For example, given the following specs:
(def spec-a (ds/spec ::spec-a {:a/x int?}))
(def spec-b (ds/spec ::spec-b {:a/x nil?}))
we could auto-generate the following two specs for the above namespace qualified keys.
(s/def ::$spec-a$a/x int?)
(s/def ::$spec-b$a/x nil?)
And then in theory we could write the following specs:
(s/def ::$spec-a (s/keys :req [::$spec-a$a/x]))
(s/def ::$spec-b (s/keys :req [::$spec-b$a/x]))
however there's no way for us to write the above spec so that we're checking a map that contains the :a/x
key instead of ::$spec-a$a/x
.
I think throwing an error like you had initially suggested would be the best option so that users don't accidentally redefine specs.
If there are other suggestions for how this could be possible I'd be happy to explore them. Thanks!
from spec-tools.
Related Issues (20)
- ArityException Wrong number of args (2) passed to: clojure.lang.PersistentVector HOT 2
- StackOverflow when creating or utilising spec-tools with self referencing spec HOT 2
- ClassCastException using transformers
- Correctly generate Swagger2 for specs using int-in HOT 4
- multi-spec -> swagger returns empty map
- strip-extra-keys-transformer not working with s/or if ors predicates are non- map validating specs
- s/keys + clojure.core/or -> swagger returns or args as required
- json-transformer not working correctly with set-specs HOT 1
- Coerce JS objects? HOT 2
- `spec-tools.transform/string->date` and `date->string` fail roundtrip for some dates
- `spec-tools.data-spec/spec` has a wrong assert
- s/explain-data throws exception for s/map-of spec with a s/or key HOT 1
- Unable to parse spec with s/nonconforming HOT 1
- `select-spec` removing keys when using `s/or`
- newer version doesn't support list in data spec
- In OpenAPI 3.0.x, Cannot use null type
- Invalid JSON Schema type generated for `s/tuple`
- `st/strip-extra-keys-transformer` not handling merged `s/or`
- Inconsistent results from s/valid? and s/explain when trying to spec list of values
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from spec-tools.