Welcome! Please see the About page for a little more info on how this works.

+8 votes
in Collections by
retagged by

(submap? m1 m2) recursively checks if m1 is contained in m2


(deftest submap
  (is (submap? {} {}))
  (is (not (submap? {:k 1} {})))
  (is (submap? {:k 1} {:k 1 :j 2}))
  (is (submap? {:k {:kk 1}} {:k {:kk 1 :j 2}}))
  (is (not (submap? {:k {:kk 1}} {:j 2}))))

This need often arises in tests, where you want to check if the map returned by function-under-test has a certain shape and while assuming an open world - i.e. you want to ignore any additional keys so that changing function-under-test doesn't break the tests:

;; BAD: doesn't assume open world
(is (= {:k :v} (function-under-test)))

;; BAD: not expressive
(is (= :v (:k (function-under-test))))

;; BAD: not expressive, need to write :k twice
(is (= {:k :v} (select-keys (function-under-test) [:k])))

;; GOOD: expressive
(is (submap? {:k :v} (function-under-test)))

Implementations already exist in many codebases (400+ hits on Github code search). Examples:



1 Answer

0 votes