|
# Load RFlatten directly as we are not using Mix to manage dependencies. |
|
Code.load_file("r_flatten.exs") |
|
|
|
# Setup ExUnit to manage our unit tests for RFlatten. |
|
ExUnit.start() |
|
|
|
# Developer Note: |
|
# For the purpose of these tests, we use the word "nested" to refer to a list |
|
# contained within another list (e.g., [n, [m]]). For multiple levels of nesting |
|
# we will sometimes refer to a "depth" of the nested list/elements: |
|
# * A list of depth 1 signifies it has a list within a list. |
|
# * A list of depth 2 signifies it has a list within a list within a list. |
|
# * A list of depth n signifies it has a list containing an n-1 depth list. |
|
defmodule RFlattenTest do |
|
@moduledoc """ |
|
Unit tests for RFlatten covering our "gold standard" (example in the README), |
|
a strong set of edge cases (various depth, length), and some unsupported use |
|
cases which will help other developers understand the limitations of RFlatten. |
|
""" |
|
use ExUnit.Case |
|
|
|
# Our first test ensures that RFlatten works as we describe in the README. |
|
test "when flattening the documented example list" do |
|
assert RFlatten.call([1, [2], [3, 4, [5]], 6, []]) == [1, 2, 3, 4, 5, 6] |
|
end |
|
|
|
# Now, we move onto more base case examples (e.g., empty list, [1], []): |
|
test "with empty list (no Integers, no nested lists)" do |
|
assert RFlatten.call([]) == [] |
|
end |
|
|
|
test "with list containing one Integer" do |
|
assert RFlatten.call([1]) == [1] |
|
end |
|
|
|
test "with list containing three Integers" do |
|
assert RFlatten.call([1, 2, 3]) == [1, 2, 3] |
|
end |
|
|
|
test "with list containing two Integers and a nested list (with Integer)" do |
|
assert RFlatten.call([1, 2, [3]]) == [1, 2, 3] |
|
end |
|
|
|
test "with list with four elements and a single- and double-nested lists" do |
|
assert RFlatten.call([1, [2], [[3]]]) == [1, 2, 3] |
|
end |
|
|
|
# Some more complex examples: |
|
test "when given the input: [1, [2, [3, [4]]]]" do |
|
ex_list = [1, [2, [3, [4]]]] |
|
assert RFlatten.call(ex_list) == [1, 2, 3, 4] |
|
end |
|
|
|
test "when given the input: [[[[1], 2], 3, 4], 5]" do |
|
ex_list = [[[[1], 2], 3, 4], 5] |
|
assert RFlatten.call(ex_list) == [1, 2, 3, 4, 5] |
|
end |
|
|
|
test "when given the input: [[[[[[[]]]]]]]" do |
|
ex_list = [[[[[[[]]]]]]] |
|
assert RFlatten.call(ex_list) == [] |
|
end |
|
|
|
# Finally, document some of the limitations of this system. |
|
# The current specification is only focused on Integers; and therefore we |
|
# show how RFlatten will handle strings, symbols, and other types. |
|
# Note: Could also be written as RFlatten.call("string") to hit base case. |
|
# |
|
# See: https://elixir-lang.org/getting-started/basic-types.html |
|
test "when containing a String, should raise a FunctionClauseError" do |
|
assert_raise FunctionClauseError, fn -> |
|
RFlatten.call(["Hello, world!"]) |
|
end |
|
end |
|
|
|
test "when containing an Atom (Symbol), should raise a FunctionClauseError" do |
|
assert_raise FunctionClauseError, fn -> |
|
assert RFlatten.call([:x]) |
|
end |
|
end |
|
|
|
test "when containing an Boolean, should raise a FunctionClauseError" do |
|
assert_raise FunctionClauseError, fn -> |
|
assert RFlatten.call([true]) |
|
end |
|
end |
|
|
|
test "when containing a Tuple, should raise a FunctionClauseError" do |
|
assert_raise FunctionClauseError, fn -> |
|
assert RFlatten.call([{1}]) |
|
end |
|
end |
|
|
|
test "when containing nil, should raise a FunctionClauseError" do |
|
assert_raise FunctionClauseError, fn -> |
|
assert RFlatten.call([nil]) |
|
end |
|
end |
|
|
|
# However, it should handle Integers in hexadecimal correctly. |
|
test "when containing an Integer represented in hexadecimal notation" do |
|
# 31 represented in hexadecimal notation is 0x1F. |
|
assert RFlatten.call([0x1F]) == [0x1F] |
|
assert RFlatten.call([0x1F]) == [31] |
|
end |
|
|
|
# Many types |
|
test "when given a List containing an Integer, String, and Symbol." do |
|
assert_raise FunctionClauseError, fn -> |
|
assert RFlatten.call([1, "2", :three]) |
|
end |
|
end |
|
end |