metosin / compojure-api

Sweet web apis with Compojure & Swagger
http://metosin.github.io/compojure-api/doc/
Eclipse Public License 1.0
1.12k stars 149 forks source link

Coercion into Set doesn't apply when spec is using s/and #407

Closed rlovtangen closed 4 years ago

rlovtangen commented 5 years ago

Library Version(s)

2.0.0-alpha27

Problem

Given a route like

(api/GET "/foo" []
  {:responses {status/ok {:schema ::foobar}}}
  (response/ok {:foo (list "bar")} ))

with a spec like

(s/def ::foo
  (su/spec
    (s/coll-of string? :distinct true :into #{})
    {}))

(s/def ::foobar
  (st/spec
    (s/and
      (s/keys :req-un [::foo]))
    {}))

With 2.0.0-alpha26 the list is being coerced into a Set due to :into #{}:

$ curl -X GET --header 'Accept: application/edn' 'http://localhost:8003/foo'
{:foo #{"bar"}}

With 2.0.0-alpha27 it is not:

$ curl -X GET --header 'Accept: application/edn' 'http://localhost:8003/foo'
{:foo ("bar")}

This seems to be caused by s/and. If I remove s/and (which is not necessary in this example because I have only one predicate):

(s/def ::foobar
  (st/spec
    (s/keys :req-un [::foo])
    {}))

then :foo is a Set like with 2.0.0-alpha26:

$ curl -X GET --header 'Accept: application/edn' 'http://localhost:8003/foo'
{:foo #{"bar"}}
miikka commented 4 years ago

Works with 2.0.0-alpha30.