antonmi / espec

Elixir Behaviour Driven Development
Other
808 stars 62 forks source link

`have` matcher for maps with string keys? #273

Closed janpieper closed 6 years ago

janpieper commented 6 years ago

Problem

Using the have matcher for maps with atom keys is great:

map = %{foo: "bar"}

expect(map).to have(foo: "bar)

But what to do when the map has string keys?

map = %{"foo" => "bar"}

"Solutions"?

match_pattern

expect(map).to match_pattern(%{"foo" => "bar"})

Works great, but match_pattern is not meant to be used for such a case and in case map does not contain this pattern, the error message contains the whole map and gets unreadable.

have_key + have_value

expect(map).to have_key("foo")
expect(map).to have_value("bar")

Nice idea, but can cause false positives when bar is not the value of foo.

have_key + eq

expect(map).to have_key("foo")
expect(map["foo"]).to eq("bar")

Great alternative and works fine, but feels like a bit too much code for such a simple check.

eq

expect(map).to eq(%{"foo" => "bar"})

Yay, works fine, but gets ugly when you have a big map or dynamic values you do not know.

Question

Is there a good way to to check whether a map with string keys has a key-value-pair? Or do we need a new matcher for this case (e.g. have_key_value_pair or have_key_with_value, or ...)?

andrei-mihaila commented 6 years ago

How about this?

expect(Map.take(map, ["foo"])).to eq(%{"foo" => "bar"})
antonmi commented 6 years ago

Hi @janpieper ! You can pass tuple to the 'have' matcher.

expect(map).to have({:foo, "bar"})
expect(map).to have({"foo", "bar"})

I've added these examples to Readme too. Thank you!

janpieper commented 6 years ago

Yeah, that looks great! Thank you!