Search code examples
testingclojurespecificationsleiningenclojure.spec

Clojure spec for vector of map with indeterminate number of keys


I am trying to write a clojure spec for a function that takes the following two maps as parameters.

{1 BL0-MD0-SU, 0 BL0-SM0-SU}
{0 [https://gateway.pinata.cloud/ipfs/QmcLjsUDHVuy8GPUPmj4ZdGa3FWTfGnsKhWZ4dxqUaGGXk/doge.jpg ], 1 [https://gateway.pinata.cloud/ipfs/QmcLjsUDHVuy8GPUPmj4ZdGa3FWTfGnsKhWZ4dxqUaGGXk/doge.jpg ]}

Each map can have a varying length, dependent on how many tshirts a user wishes to purchase. I am unsure how to write a spec for this, that allows for the number of keys and values in each map to vary. Also it would be useful if I could assert that each of the maps contain the same number of keys.

EDIT:

The spec should also passed when the following is passed:

{1 BL0-MD0-SU, 0 BL0-SM0-SU, 2 BL0-LG0-SU}
{0 [https://gateway.pinata.cloud/ipfs/QmcLjsUDHVuy8GPUPmj4ZdGa3FWTfGnsKhWZ4dxqUaGGXk/doge.jpg ], 1 [https://gateway.pinata.cloud/ipfs/QmcLjsUDHVuy8GPUPmj4ZdGa3FWTfGnsKhWZ4dxqUaGGXk/doge.jpg ], 2 [ ]}

Solution

  • (s/def ::arg1 (s/map-of long? string?))
    (s/def ::arg2 (s/map-of long? vector?))
    (s/def ::args (s/and (s/cat :arg1 ::arg1 :arg2 ::arg2)
                         (fn [{:keys [arg1 arg2]}]
                           (= (count arg1) (count arg2)))))
    

    If you need to attach this spec to a function, you can learn how to do it here: https://clojure.org/guides/spec#_specing_functions