diff --git a/test/pbt_rb_tree_monoid_test.exs b/test/pbt_rb_tree_monoid_test.exs index 07d1f53..19789d9 100644 --- a/test/pbt_rb_tree_monoid_test.exs +++ b/test/pbt_rb_tree_monoid_test.exs @@ -5,7 +5,7 @@ defmodule RedBlackTreeMonoidPropertyTest do property "merging with nil (neutral element) does not change the tree" do check all( - keys <- uniq_list_of(integer()), + keys <- uniq_list_of(integer(), min_length: 1, max_tries: 1000), values <- list_of(term()), max_runs: 50 ) do @@ -24,11 +24,11 @@ defmodule RedBlackTreeMonoidPropertyTest do property "associative property of merging two trees" do check all( - keys1 <- uniq_list_of(integer(), min_length: 1, max_length: 20), + keys1 <- uniq_list_of(integer(), min_length: 1, max_tries: 1000), values1 <- list_of(term(), length: length(keys1)), - keys2 <- uniq_list_of(integer(), min_length: 1, max_length: 20), + keys2 <- uniq_list_of(integer(), min_length: 1, max_tries: 1000), values2 <- list_of(term(), length: length(keys2)), - keys3 <- uniq_list_of(integer(), min_length: 1, max_length: 20), + keys3 <- uniq_list_of(integer(), min_length: 1, max_tries: 1000), values3 <- list_of(term(), length: length(keys3)), max_runs: 100 ) do diff --git a/test/pbt_tree_dict_test.exs b/test/pbt_tree_dict_test.exs new file mode 100644 index 0000000..789db7c --- /dev/null +++ b/test/pbt_tree_dict_test.exs @@ -0,0 +1,47 @@ +defmodule TreeDictTreePropertyBasedTest do + use ExUnit.Case + use ExUnitProperties + + alias RedBlackTree + + property "insert and get values correctly" do + check all(key <- term(), value <- term()) do + dict = TreeDict.new() |> TreeDict.insert(key, value) + assert TreeDict.get(dict, key) == value + end + end + + property "deleting a key removes it from the dictionary" do + check all(key <- term(), value <- term()) do + dict = TreeDict.new() |> TreeDict.insert(key, value) |> TreeDict.delete(key) + assert TreeDict.get(dict, key) == nil + end + end + + property "merging two dictionaries maintains values" do + check all( + keys1 <- uniq_list_of(integer(), min_length: 1), + keys2 <- uniq_list_of(integer(), min_length: 1), + values1 <- list_of(term(), length: length(keys1)), + values2 <- list_of(term(), length: length(keys2)) + ) do + dict1 = + Enum.zip(keys1, values1) + |> Enum.reduce(TreeDict.new(), fn {k, v}, acc -> TreeDict.insert(acc, k, v) end) + + dict2 = + Enum.zip(keys2, values2) + |> Enum.reduce(TreeDict.new(), fn {k, v}, acc -> TreeDict.insert(acc, k, v) end) + + merged_dict = TreeDict.merge(dict1, dict2) + + Enum.each(keys1, fn k -> + if k in keys2 do + assert TreeDict.get(merged_dict, k) != nil + else + assert TreeDict.get(merged_dict, k) == TreeDict.get(dict1, k) + end + end) + end + end +end diff --git a/test/unit_tree_dict_test.exs b/test/unit_tree_dict_test.exs index d8f96b5..4252154 100644 --- a/test/unit_tree_dict_test.exs +++ b/test/unit_tree_dict_test.exs @@ -127,4 +127,75 @@ defmodule TreeDictTest do assert TreeDict.get(dict, :b) == nil assert TreeDict.get(dict, :c) == nil end + + test "filtering keys based on value" do + dict = TreeDict.new() + dict = TreeDict.insert(dict, :key1, 10) + dict = TreeDict.insert(dict, :key2, 20) + dict = TreeDict.insert(dict, :key3, 30) + + filtered_dict = TreeDict.filter(dict, fn _key, value -> value > 15 end) + + assert TreeDict.get(filtered_dict, :key1) == nil + assert TreeDict.get(filtered_dict, :key2) == 20 + assert TreeDict.get(filtered_dict, :key3) == 30 + end + + # Тесты на отображение (map) + test "applying map function to all values" do + dict = TreeDict.new() + dict = TreeDict.insert(dict, :key1, 10) + dict = TreeDict.insert(dict, :key2, 20) + dict = TreeDict.insert(dict, :key3, 30) + + mapped_dict = TreeDict.map(dict, fn _key, value -> value * 2 end) + + assert TreeDict.get(mapped_dict, :key1) == 20 + assert TreeDict.get(mapped_dict, :key2) == 40 + assert TreeDict.get(mapped_dict, :key3) == 60 + end + + # Тесты на свёртки (левая и правая) + test "left fold applies function from left to right" do + dict = TreeDict.new() + dict = TreeDict.insert(dict, 1, 2) + dict = TreeDict.insert(dict, 3, 4) + dict = TreeDict.insert(dict, 5, 6) + + result = TreeDict.foldl(dict, 0, fn _key, value, acc -> acc + value end) + assert result == 12 + end + + test "right fold applies function from right to left" do + dict = TreeDict.new() + dict = TreeDict.insert(dict, 1, 2) + dict = TreeDict.insert(dict, 3, 4) + dict = TreeDict.insert(dict, 5, 6) + + result = TreeDict.foldr(dict, 0, fn _key, value, acc -> acc + value end) + assert result == 12 + end + + # Check monoid properties + test "monoid property: merging with empty TreeDict" do + dict1 = TreeDict.new() + dict2 = TreeDict.insert(TreeDict.new(), :key, "value") + + merged_left = TreeDict.merge(dict1, dict2) + merged_right = TreeDict.merge(dict2, dict1) + + assert merged_left == dict2 + assert merged_right == dict2 + end + + test "monoid property: associative merging" do + dict1 = TreeDict.insert(TreeDict.new(), :key1, "value1") + dict2 = TreeDict.insert(TreeDict.new(), :key2, "value2") + dict3 = TreeDict.insert(TreeDict.new(), :key3, "value3") + + merged_left = TreeDict.merge(TreeDict.merge(dict1, dict2), dict3) + merged_right = TreeDict.merge(dict1, TreeDict.merge(dict2, dict3)) + + assert merged_left == merged_right + end end