From 6bcb7adeb400a32915b1a7bddde8fdf5e7dfd101 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Valim?= Date: Sun, 19 Jan 2014 15:25:26 +0100 Subject: [PATCH] Clean up DictTest implementation Before this commit, DictTest used too many helper functions and used assertions in the opposite order. --- lib/elixir/test/elixir/dict_test.exs | 395 +++++++++++----------- lib/elixir/test/elixir/hash_dict_test.exs | 20 -- 2 files changed, 201 insertions(+), 214 deletions(-) diff --git a/lib/elixir/test/elixir/dict_test.exs b/lib/elixir/test/elixir/dict_test.exs index 6cfad63825..89b67f9eea 100644 --- a/lib/elixir/test/elixir/dict_test.exs +++ b/lib/elixir/test/elixir/dict_test.exs @@ -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 } 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 } 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 diff --git a/lib/elixir/test/elixir/hash_dict_test.exs b/lib/elixir/test/elixir/hash_dict_test.exs index 156f679c3e..ca43820a1a 100644 --- a/lib/elixir/test/elixir/hash_dict_test.exs +++ b/lib/elixir/test/elixir/hash_dict_test.exs @@ -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)