Clean up DictTest implementation

Before this commit, DictTest used too many helper functions
and  used assertions in the opposite order.
This commit is contained in:
José Valim
2014-01-19 15:25:35 +01:00
parent d311e10bea
commit 6bcb7adeb4
2 changed files with 201 additions and 214 deletions
+201 -194
View File
@@ -3,16 +3,7 @@ Code.require_file "test_helper.exs", __DIR__
defmodule DictTest.Common do
defmacro __using__(_) do
quote location: :keep do
# Most underlying Dict implementations have no key
# order guarantees, sort them before we compare:
defmacrop dicts_equal(actual, expected) do
quote do
cmp = fn { k1, _ }, { k2, _ } -> k1 < k2 end
Enum.sort(unquote(expected), cmp) == Enum.sort(unquote(actual), cmp)
end
end
defp empty_dict, do: dict_impl.new
import Enum, only: [sort: 1]
defp new_dict(list // [{"first_key", 1}, {"second_key", 2}]) do
dict_impl.new list
@@ -26,284 +17,287 @@ defmodule DictTest.Common do
dict_impl.new [{1,1}]
end
test :access do
dict = new_dict [{"first_key", 1}, {"second_key", 2}]
test "access" do
dict = new_dict()
assert dict["first_key"] == 1
assert dict["third_key"] == nil
assert dict["other_key"] == nil
end
test :access_with_match do
assert int_dict[1] == 1
assert int_dict[1.0] == nil
test "access uses match operation" do
dict = int_dict()
assert dict[1] == 1
assert dict[1.0] == nil
end
test :new_pairs do
dict = new_dict [{"first_key", 1}, {"second_key", 2}]
assert 2 == Dict.size dict
assert ["first_key", "second_key"] == Enum.sort Dict.keys dict
assert [1, 2] == Enum.sort Dict.values dict
test "new/1" do
dict = new_dict()
assert Dict.size(dict) == 2
assert Enum.sort(dict) == [{"first_key", 1}, {"second_key", 2}]
end
test :new_pairs_with_transform do
dict = new_dict [{1}, {2}, {3}], fn {x} -> { <<x + 64>>, x } end
assert 3 == Dict.size dict
assert ["A", "B", "C"] == Enum.sort Dict.keys dict
assert [1, 2, 3] == Enum.sort Dict.values dict
test "new/2" do
dict = new_dict([{1}, {2}, {3}], fn {x} -> { <<x + 64>>, x } end)
assert Dict.size(dict) == 3
assert Enum.sort(dict) == [{"A", 1}, {"B", 2}, {"C", 3}]
end
test :get do
assert 1 == Dict.get(new_dict, "first_key")
assert 2 == Dict.get(new_dict, "second_key")
assert nil == Dict.get(new_dict, "other_key")
assert "default" == Dict.get(empty_dict, "first_key", "default")
test "get/2 and get/3" do
dict = new_dict()
assert Dict.get(dict, "first_key") == 1
assert Dict.get(dict, "second_key") == 2
assert Dict.get(dict, "other_key") == nil
assert Dict.get(dict, "other_key", 3) == 3
end
test :get_with_match do
test "get/2 with match" do
assert Dict.get(int_dict, 1) == 1
assert Dict.get(int_dict, 1.0) == nil
end
test :fetch do
assert { :ok, 1 } == Dict.fetch(new_dict, "first_key")
assert { :ok, 2 } == Dict.fetch(new_dict, "second_key")
assert :error == Dict.fetch(new_dict, "other_key")
test "fetch/2" do
dict = new_dict()
assert Dict.fetch(dict, "first_key") == {:ok, 1}
assert Dict.fetch(dict, "second_key") == {:ok, 2}
assert Dict.fetch(dict, "other_key") == :error
end
test :fetch_with_match do
assert Dict.fetch(int_dict, 1) == { :ok, 1 }
test "fetch/2 with match" do
assert Dict.fetch(int_dict, 1) == {:ok, 1}
assert Dict.fetch(int_dict, 1.0) == :error
end
test :fetch! do
assert 1 == Dict.fetch!(new_dict, "first_key")
assert 2 == Dict.fetch!(new_dict, "second_key")
test "fetch!/2" do
dict = new_dict()
assert Dict.fetch!(dict, "first_key") == 1
assert Dict.fetch!(dict, "second_key") == 2
assert_raise KeyError, fn ->
Dict.fetch!(new_dict, "other_key")
Dict.fetch!(dict, "other_key")
end
end
test :fetch_with_match! do
assert Dict.fetch!(int_dict, 1) == 1
assert_raise KeyError, fn ->
assert Dict.fetch!(int_dict, 1.0)
end
test "put/3" do
dict = new_dict() |> Dict.put("first_key", {1})
assert Dict.get(dict, "first_key") == {1}
assert Dict.get(dict, "second_key") == 2
end
test :put do
dict = Dict.put(new_dict, "first_key", {1})
assert {1} == Dict.get dict, "first_key"
assert 2 == Dict.get dict, "second_key"
test "put/3 with_match" do
dict = int_dict()
assert Dict.get(Dict.put(dict, 1, :other), 1) == :other
assert Dict.get(Dict.put(dict, 1.0, :other), 1) == 1
assert Dict.get(Dict.put(dict, 1, :other), 1.0) == nil
assert Dict.get(Dict.put(dict, 1.0, :other), 1.0) == :other
end
test :put_with_match do
assert Dict.get(Dict.put(int_dict, 1, :other), 1) == :other
assert Dict.get(Dict.put(int_dict, 1.0, :other), 1) == 1
assert Dict.get(Dict.put(int_dict, 1, :other), 1.0) == nil
assert Dict.get(Dict.put(int_dict, 1.0, :other), 1.0) == :other
test "put_new/3" do
dict = Dict.put_new(new_dict(), "first_key", {1})
assert Dict.get(dict, "first_key") == 1
end
test :put_new do
dict = Dict.put_new(new_dict, "first_key", {1})
assert 1 == Dict.get dict, "first_key"
end
test :put_new_with_match do
test "put_new/3 with_match" do
assert Dict.get(Dict.put_new(int_dict, 1, :other), 1) == 1
assert Dict.get(Dict.put_new(int_dict, 1.0, :other), 1) == 1
assert Dict.get(Dict.put_new(int_dict, 1, :other), 1.0) == nil
assert Dict.get(Dict.put_new(int_dict, 1.0, :other), 1.0) == :other
end
test :keys do
assert Enum.sort(Dict.keys new_dict) == ["first_key", "second_key"]
assert Dict.keys(empty_dict) == []
test "keys/1" do
assert Enum.sort(Dict.keys(new_dict())) == ["first_key", "second_key"]
assert Dict.keys(new_dict([])) == []
end
test :values do
assert Enum.sort(Dict.values(new_dict)) == [1, 2]
assert Dict.values(empty_dict) == []
test "values/1" do
assert Enum.sort(Dict.values(new_dict())) == [1, 2]
assert Dict.values(new_dict([])) == []
end
test :delete do
mdict = Dict.delete new_dict, "second_key"
assert Dict.size(mdict) == 1
assert Dict.has_key? mdict, "first_key"
refute Dict.has_key? mdict, "second_key"
test "delete/2" do
dict = Dict.delete(new_dict(), "second_key")
assert Dict.size(dict) == 1
assert Dict.has_key?(dict, "first_key")
refute Dict.has_key?(dict, "second_key")
mdict = Dict.delete(new_dict, "other_key")
assert mdict == new_dict
assert Dict.size(Dict.delete(empty_dict, "other_key")) == 0
dict = Dict.delete(new_dict(), "other_key")
assert dict == new_dict()
assert Dict.size(dict) == 2
end
test :delete_with_match do
test "delete/2 with match" do
assert Dict.get(Dict.delete(int_dict, 1), 1) == nil
assert Dict.get(Dict.delete(int_dict, 1.0), 1) == 1
end
test :merge do
dict = new_dict
assert dict == Dict.merge empty_dict, dict
assert dict == Dict.merge dict, empty_dict
assert dict == Dict.merge dict, dict
assert empty_dict == Dict.merge empty_dict, empty_dict
test "merge/2" do
dict = new_dict()
assert Dict.merge(new_dict([]), dict) == dict
assert Dict.merge(dict, new_dict([])) == dict
assert Dict.merge(dict, dict) == dict
assert Dict.merge(new_dict([]), new_dict([])) == new_dict([])
dict1 = new_dict Enum.zip ["a", "b", "c"], [1, 2, 3]
dict2 = new_dict Enum.zip ["a", "c", "d"], [3, :a, 0]
actual = Dict.merge(dict1, dict2)
expected = new_dict Enum.zip ["a", "b", "c", "d"], [3, 2, :a, 0]
assert dicts_equal actual, expected
dict1 = new_dict [{"a", 1}, {"b", 2}, {"c", 3}]
dict2 = new_dict [{"a", 3}, {"c", :a}, {"d", 0}]
assert Dict.merge(dict1, dict2) |> Enum.sort ==
[{"a", 3}, {"b", 2}, {"c", :a}, {"d", 0}]
end
test :merge_with_enum do
dict1 = new_dict Enum.zip ["a", "b", "c"], [1, 2, 3]
test "merge/2 with enum" do
dict1 = new_dict [{"a", 1}, {"b", 2}, {"c", 3}]
dict2 = Enum.zip ["a", "c", "d"], [3, :a, 0]
actual = Dict.merge(dict1, dict2)
expected = new_dict(Enum.zip ["a", "b", "c", "d"], [3, 2, :a, 0])
assert dicts_equal actual, expected
assert Dict.merge(dict1, dict2) |> Enum.sort ==
[{"a", 3}, {"b", 2}, {"c", :a}, {"d", 0}]
end
test :merge_with_function do
dict1 = new_dict Enum.zip ["a", "b"], [1, 2]
dict2 = new_dict Enum.zip ["a", "d"], [3, 4]
test "merge/3" do
dict1 = new_dict [{"a", 1}, {"b", 2}]
dict2 = new_dict [{"a", 3}, {"d", 4}]
actual = Dict.merge dict1, dict2, fn _k, v1, v2 -> v1 + v2 end
expected = new_dict(Enum.zip ["a", "b", "d"], [4, 2, 4])
assert dicts_equal actual, expected
assert Enum.sort(actual) == [{"a", 4}, {"b", 2}, {"d", 4}]
end
test :has_key do
dict = new_dict [{"a", 1}]
assert Dict.has_key?(dict, "a")
refute Dict.has_key?(dict, "b")
test "has_key?/2" do
dict = new_dict()
assert Dict.has_key?(dict, "first_key")
refute Dict.has_key?(dict, "other_key")
end
test :has_key_with_match do
test "has_key?/2 with match" do
assert Dict.has_key?(int_dict, 1)
refute Dict.has_key?(int_dict, 1.0)
end
test :size do
assert 2 == Dict.size new_dict
assert 0 == Dict.size empty_dict
test "size/1" do
assert Dict.size(new_dict()) == 2
assert Dict.size(new_dict([])) == 0
end
test :update do
dict = Dict.update!(new_dict, "first_key", fn val -> -val end)
test "update!/3" do
dict = Dict.update!(new_dict(), "first_key", fn val -> -val end)
assert Dict.get(dict, "first_key") == -1
dict = Dict.update(dict, "non-existent", "...", fn val -> -val end)
assert_raise KeyError, fn ->
Dict.update!(new_dict(), "non-existent", fn val -> -val end)
end
end
test "update!/3 with match" do
assert Dict.get(Dict.update!(int_dict(), 1, &(&1 + 1)), 1) == 2
end
test "update/4" do
dict = Dict.update(new_dict(), "first_key", 0, fn val -> -val end)
assert Dict.get(dict, "first_key") == -1
dict = Dict.update(new_dict(), "non-existent", "...", fn val -> -val end)
assert Dict.get(dict, "non-existent") == "..."
end
test :update_with_match do
assert Dict.get(Dict.update!(int_dict, 1, &(&1 + 1)), 1) == 2
assert Dict.get(Dict.update(int_dict, 1.0, 2, &(&1 + 1)), 1) == 1
assert Dict.get(Dict.update(int_dict, 1.0, 2, &(&1 + 1)), 1.0) == 2
test "update/4 with match" do
dict = int_dict()
assert Dict.get(Dict.update(dict, 1.0, 2, &(&1 + 1)), 1) == 1
assert Dict.get(Dict.update(dict, 1.0, 2, &(&1 + 1)), 1.0) == 2
end
test :pop do
{v, actual} = Dict.pop(new_dict, "first_key")
assert 1 == v
assert dicts_equal actual, Dict.delete(new_dict, "first_key")
test "pop/2 and pop/3" do
dict = new_dict()
{v, actual} = Dict.pop(new_dict, "second_key")
assert 2 == v
assert dicts_equal actual, Dict.delete(new_dict, "second_key")
{v, actual} = Dict.pop(new_dict, "other_key")
assert nil == v
assert dicts_equal actual, new_dict
{v, actual} = Dict.pop(empty_dict, "first_key", "default")
assert "default" == v
assert dicts_equal actual, empty_dict
{v, actual} = Dict.pop(new_dict, "other_key", "default")
assert "default" == v
assert dicts_equal actual, new_dict
end
test :pop_with_match do
{v, actual} = Dict.pop(int_dict, 1)
{v, actual} = Dict.pop(dict, "first_key")
assert v == 1
assert dicts_equal actual, []
assert actual == new_dict([{"second_key", 2}])
{v, actual} = Dict.pop(int_dict, 1.0)
{v, actual} = Dict.pop(dict, "other_key")
assert v == nil
assert dicts_equal actual, int_dict
assert dict == actual
{v, actual} = Dict.pop(dict, "other_key", "default")
assert v == "default"
assert dict == actual
end
test :split do
split_keys = []
{take, drop} = Dict.split(new_dict, split_keys)
assert dicts_equal take, Dict.empty(new_dict)
assert dicts_equal drop, new_dict
test "pop/2 and pop/3 with match" do
dict = int_dict()
split_keys = ["unknown_key"]
{take, drop} = Dict.split(new_dict, split_keys)
assert dicts_equal take, Dict.empty(new_dict)
assert dicts_equal drop, new_dict
{v, actual} = Dict.pop(dict, 1)
assert v == 1
assert Enum.sort(actual) == []
{v, actual} = Dict.pop(dict, 1.0)
assert v == nil
assert actual == dict
end
test "split/2" do
dict = new_dict()
{take, drop} = Dict.split(dict, [])
assert take == new_dict([])
assert drop == dict
{take, drop} = Dict.split(dict, ["unknown_key"])
assert take == new_dict([])
assert drop == dict
split_keys = ["first_key", "second_key", "unknown_key"]
{take, drop} = Dict.split(new_dict, split_keys)
{take, drop} = Dict.split(dict, split_keys)
first_val = Dict.get(new_dict, "first_key")
second_val = Dict.get(new_dict, "second_key")
take_expected = Dict.empty(new_dict)
take_expected = Dict.put(take_expected, "first_key", first_val)
take_expected = Dict.put(take_expected, "second_key", second_val)
drop_expected = new_dict
drop_expected = Dict.delete(drop_expected, "first_key")
drop_expected = Dict.delete(drop_expected, "second_key")
take_expected = new_dict([])
|> Dict.put("first_key", 1)
|> Dict.put("second_key", 2)
assert dicts_equal take, take_expected
assert dicts_equal drop, drop_expected
drop_expected = new_dict([])
|> Dict.delete("first_key")
|> Dict.delete("second_key")
assert Enum.sort(take) == Enum.sort(take_expected)
assert Enum.sort(drop) == Enum.sort(drop_expected)
end
test :split_with_match do
{ take, drop } = Dict.split(int_dict, [1])
assert dicts_equal take, int_dict
assert dicts_equal drop, []
test "split/2 with match" do
dict = int_dict()
{ take, drop } = Dict.split(dict, [1])
assert take == dict
assert drop == new_dict([])
{ take, drop } = Dict.split(int_dict, [1.0])
assert dicts_equal take, []
assert dicts_equal drop, int_dict
{ take, drop } = Dict.split(dict, [1.0])
assert take == new_dict([])
assert drop == dict
end
test :take do
result = Dict.take(new_dict, ["unknown_key"])
assert dicts_equal result, Dict.empty(new_dict)
test "take/2" do
dict = new_dict()
take = Dict.take(dict, ["unknown_key"])
assert take == new_dict([])
result = Dict.take(new_dict, ["first_key"])
first_val = Dict.get(new_dict, "first_key")
expected = Dict.put(Dict.empty(new_dict), "first_key", first_val)
assert dicts_equal result, expected
take = Dict.take(dict, ["first_key"])
assert take == new_dict([{"first_key", 1}])
end
test :take_with_match do
assert dicts_equal Dict.take(int_dict, [1]), int_dict
assert dicts_equal Dict.take(int_dict, [1.0]), []
test "take/2 with match" do
dict = int_dict()
assert Dict.take(dict, [1]) == dict
assert Dict.take(dict, [1.0]) == new_dict([])
end
test :drop do
result = Dict.drop(new_dict, ["unknown_key"])
assert dicts_equal result, new_dict
test "drop/2" do
dict = new_dict()
drop = Dict.drop(dict, ["unknown_key"])
assert drop == dict
result = Dict.drop(new_dict, ["first_key"])
assert dicts_equal result, Dict.delete(new_dict, "first_key")
drop = Dict.drop(dict, ["first_key"])
assert drop == new_dict([{"second_key", 2}])
end
test :drop_with_match do
assert dicts_equal Dict.drop(int_dict, [1]), []
assert dicts_equal Dict.drop(int_dict, [1.0]), int_dict
test "drop/2 with match" do
dict = int_dict()
assert Dict.drop(dict, [1]) == new_dict([])
assert Dict.drop(dict, [1.0]) == dict
end
test :empty do
assert empty_dict == Dict.empty new_dict
test "empty" do
assert Dict.empty(new_dict) == new_dict([])
end
test :equal? do
test "equal?/2" do
dict1 = new_dict(a: 2, b: 3, f: 5, c: 123)
dict2 = new_dict(a: 2, b: 3, f: 5, c: 123)
assert dict_impl.equal?(dict1, dict2)
@@ -318,7 +312,7 @@ defmodule DictTest.Common do
refute Dict.equal?(dict3, dict1)
end
test :equal_with_match? do
test "equal?/2 with_match" do
dict1 = new_dict([{1,1}])
dict2 = new_dict([{1.0,1}])
assert dict_impl.equal?(dict1, dict1)
@@ -327,11 +321,24 @@ defmodule DictTest.Common do
refute Dict.equal?(dict1, dict2)
end
test :enum_member do
assert Enum.member?(new_dict([{1,1}]), { 1, 1 })
refute Enum.member?(new_dict([{1,1}]), { 1.0, 1 })
refute Enum.member?(new_dict([{1,1}]), { 1, 1.0 })
refute Enum.member?(new_dict([{1,1}]), { 1.0, 1.0 })
test "implements Enumerable" do
dict = new_dict()
assert Enum.empty?(new_dict([]))
refute Enum.empty?(dict)
assert Enum.member?(dict, { "first_key", 1 })
refute Enum.member?(dict, { "first_key", 2 })
assert Enum.count(dict) == 2
assert Enum.reduce(dict, 0, fn({ k, v }, acc) -> v + acc end) == 3
end
test "is zippable" do
dict = new_dict()
list = Dict.to_list(dict)
assert Enum.zip(list, list) == Enum.zip(dict, dict)
dict = new_dict(1..120, fn i -> { i, i } end)
list = Dict.to_list(dict)
assert Enum.zip(list, list) == Enum.zip(dict, dict)
end
end
end
-20
View File
@@ -52,26 +52,6 @@ defmodule HashDictTest do
assert inspect(filled_dict(8)) =~ "#HashDict<"
end
test "implements Enumerable" do
dict = filled_dict(10)
assert Enum.empty?(HashDict.new)
refute Enum.empty?(dict)
assert Enum.member?(dict, { 5, 5 })
refute Enum.member?(dict, { 5, 8 })
assert Enum.count(dict) == 10
assert Enum.reduce(filled_dict(3), 0, fn({ k, v }, acc) -> k + v + acc end) == 12
end
test "is zippable" do
dict = filled_dict(8)
list = Dict.to_list(dict)
assert Enum.zip(list, list) == Enum.zip(dict, dict)
dict = filled_dict(120)
list = Dict.to_list(dict)
assert Enum.zip(list, list) == Enum.zip(dict, dict)
end
defp smoke_test(range) do
{ dict, _ } = Enum.reduce range, { HashDict.new, 1 }, fn(x, { acc, i }) ->
acc = HashDict.put(acc, x, x)