defmoduleRepeaterTestdouseExUnit.Case describe "duplicate/2"do test "creates a new string, with the first argument duplicated a specified number of times"do assert "aaaa"==Repeater.duplicate("a",4)endendend
defmoduleRepeaterTestdouseExUnit.CaseuseExUnitProperties describe "duplicate/2"do property "creates a new string, with the first argument duplicated a specified number of times"do check all str <-string(:printable), times <-integer(), times >=0do assert ??? ==Repeater.duplicate(str, times)endendendend
list = str|>Repeater.duplicate(times)|>String.split(str)assert Enum.all?(list, &(&1 ==""))
让我们把这两个断言结合起来看看:
defmoduleRepeaterTestdouseExUnit.CaseuseExUnitProperties describe "duplicate/2"do property "creates a new string, with the first argument duplicated a specified number of times"do check all str <-string(:printable), times <-integer(), times >=0do new_string =Repeater.duplicate(str, times) assert String.length(new_string) ==String.length(str) * times assert Enum.all?(String.split(new_string, str), &(&1 ==""))endendendend
defmoduleRepeaterTestdouseExUnit.Case describe "duplicating a string"do test "duplicates the first argument a number of times equal to the second argument"do assert "aaaa"==Repeater.duplicate("a",4)end test "returns an empty string if the first argument is an empty string"do assert ""==Repeater.duplicate("",4)end test "returns an empty string if the second argument is zero"do assert ""==Repeater.duplicate("a",0)end test "works with longer strings"do alphabet ="abcdefghijklmnopqrstuvwxyz" assert "#{alphabet}#{alphabet}"==Repeater.duplicate(alphabet,2)endendend
defmoduleRepeaterdodefduplicate(list,0) whenis_list(list) do []enddefduplicate(list, times) whenis_list(list) do list ++duplicate(list, times -1)endend
StreamData 的测试看起来可能是这样的:
defmoduleRepeaterTestdouseExUnit.CaseuseExUnitProperties describe "duplicate/2"do property "creates a new list, with the elements of the original list repeated a specified number or times"do check all list <-list_of(term()), times <-integer(), times >=0do new_list =Repeater.duplicate(list, times) assert length(new_list) ==length(list) * timesiflength(list) >0do assert Enum.all?(Enum.chunk_every(new_list,length(list)), &(&1 == list))endendendendend
这就是 Scott Wlaschin 提到的一种应用模式 "不同的路径,相同的终点"。这两种不同的处理顺序,最后生成的结果应该是一样的。让我们用这种方式来测试。
defmoduleRepeaterTestdouseExUnit.CaseuseExUnitProperties describe "duplicate/2"do property "creates a new tuple, with the elements of the original tuple repeated a specified number of times"do check all t <-tuple({term()}), times <-integer(), times >=0do result_1 = t|>Repeater.duplicate(times)|>Tuple.to_list() result_2 = t|>Tuple.to_list()|>Repeater.duplicate(times) assert result_1 == result_2endendendend
defmoduleRepeaterdodefduplicate(string, times) whenis_binary(string) doString.duplicate(string, times)enddefduplicate(list,0) whenis_list(list) do []enddefduplicate(list, times) whenis_list(list) do list ++duplicate(list, times -1)enddefduplicate(tuple, times) whenis_tuple(tuple) do tuple|>Tuple.to_list()|>Repeater.duplicate(times)|>List.to_tuple()endend
下面是基于特性的测试:
defmoduleRepeaterTestdouseExUnit.CaseuseExUnitProperties describe "duplicate/2"do property "creates a new string, with the first argument duplicated a specified number of times"do check all str <-string(:printable), times <-integer(), times >=0do new_string =Repeater.duplicate(str, times) assert String.length(new_string) ==String.length(str) * times assert Enum.all?(String.split(new_string, str), &(&1 ==""))endend property "creates a new list, with the elements of the original list repeated a specified number or times"do check all list <-list_of(term()), times <-integer(), times >=0do new_list =Repeater.duplicate(list, times) assert length(new_list) ==length(list) * timesiflength(list) >0do assert Enum.all?(Enum.chunk_every(new_list,length(list)), &(&1 == list))endendend property "creates a new tuple, with the elements of the original tuple repeated a specified number of times"do check all t <-tuple({term()}), times <-integer(), times >=0do result_1 = t|>Repeater.duplicate(times)|>Tuple.to_list() result_2 = t|>Tuple.to_list()|>Repeater.duplicate(times) assert result_1 == result_2endendendend