# Checking maps and records

marick edited this page Mar 19, 2013 · 5 revisions
##### Clone this wiki locally

Executable examples

Using a map on the right-hand side of a prediction means you care about contents, not type:

```(defrecord R [x y])

(fact
;; That the left-hand side below is a record is irrelevant:
(R. 1 2) => {:x 1, :y 2}
;; The contents of the left are compared to the right in exactly
;; the same way as if both sides were maps:
{:x 1, :y 2} => {:x 1, :y 2})```

When testing code that generates records, you may require that the result be one of those records, not, say, some random map:

```(fact "using a record on the right implies that you care about *both* contents and type"
{:x 1, :y 2} =not=> (R. 1 2)
(NotR. 1 2)  =not=> (R. 1 2)
(R. 1 2)     =>     (R. 1 2)))```

## `just` applies extended equality to values

Use `just` if you want a more flexible check of values than equality. For example:

```(fact "`just` provides extended equality"
{:a 1, :b 2, :c "some text"} => (just {:a odd?, :b 2, :c #"text"}))```

## `contains` works with subsets of maps or records

Use `contains` when you don't care about parts of a map or record:

```(fact "contains ignores unmentioned keys"
(R. 1 'IGNORE!) => (contains {:x 1}))```

`contains` also provides extended equality:

```(fact "`contains` provides extended equality"
(R. 1 'IGNORE) => (contains {:x odd?}))```

In both of the previous examples, `contains` will ignore the type of the left-hand size. If you want to say specifically that the left-hand side is an `R` that contains an odd `:x`, use a combining checker:

```(fact
(R. 1 'IGNORE!) => (every-checker #(instance? R %)
(contains {:x 1})))```

## `has` works with quantifiers and values

`has` lets you make quantified ("every" "some") claims about the values of a map or record:

```(fact "`'has` quantifies over values"
{:a 1, :b 3} => (has every? odd?))```

Making claims about keys is more awkward:

```(fact "ways to make claims about keys"
(keys {:x 1, :y 1}) => (just #{:x :y})            ;; Contains every key
{:x 1, :y 1} => (just {:x anything, :y anything}) ;; a variant

(keys {:x 1, :y 1}) => (contains #{:x}) ;; Contains some of the keys
{:x 1, :y 1} => (contains {:x anything}))```

## Map entries

The `just` and `contains` right-hand sides can take arrays of pairs (or Java `MapEntry` objects) instead of a map or record:

```(fact "a sequence of key/value pairs is OK on the right-hand side"
{:a 1, :b 2} => (just [[:a 1] [:b 2]])
(R. 1 nil) => (contains [[:x 1]]))```