defmodule StreamSplitTest do
use ExUnit.Case
doctest StreamSplit
setup do
File.mkdir("tmp")
on_exit(fn ->
File.rm_rf("tmp/")
end)
end
test "basic stream" do
:ok = File.write("tmp/data.txt", "AB;CCCCC;D")
{:ok, fd} = File.open("tmp/data.txt", [:read, :binary])
assert fd
|> StreamSplit.split(";")
|> Stream.map(&String.length/1)
|> Stream.filter(fn x -> rem(x, 2) == 1 end)
|> Enum.count() == 2
end
test "stream manipulation" do
:ok = File.write("tmp/data_manip.txt", "AB;CCCCC;D")
{:ok, fd} = File.open("tmp/data_manip.txt", [:read, :binary])
assert fd
|> StreamSplit.split(";")
|> Stream.with_index()
|> Stream.map(fn
{data, 0} -> String.downcase(data)
{data, _} -> data
end)
|> Enum.to_list() == ["ab", "CCCCC", "D"]
end
test "stream manipulation: tagging" do
:ok = File.write("tmp/data_manip2.txt", "AB;CCCCC;D")
{:ok, fd} = File.open("tmp/data_manip2.txt", [:read, :binary])
assert fd
|> StreamSplit.split(";", tagging: true)
|> Stream.map(fn
{:first, data} -> String.downcase(data)
{:last, data} -> String.downcase(data)
data -> data
end)
|> Enum.to_list() == ["ab", "CCCCC", "d"]
end
test "stream manipulation: tagging (with trailing)" do
:ok = File.write("tmp/data_manip3.txt", "AB;CCCCC;D;***")
{:ok, fd} = File.open("tmp/data_manip3.txt", [:read, :binary])
assert fd
|> StreamSplit.split(";", tagging: true, drop_last: true)
|> Stream.map(fn
{:first, data} -> String.downcase(data)
{:last, data} -> String.downcase(data)
data -> data
end)
|> Enum.to_list() == ["ab", "CCCCC", "d"]
end
test "big stream" do
:ok = File.write("tmp/data2.txt", gen_doc(";;;", 130_221))
{:ok, fd} = File.open("tmp/data2.txt", [:read, :binary])
assert fd
|> StreamSplit.split(";;;")
|> Stream.map(&String.length/1)
|> Enum.count() == 130_221
end
test "consistency" do
:ok =
File.write(
"tmp/data3.txt",
[
"",
"",
"aaa",
"bbb",
"ccc",
""
]
|> Enum.join("")
)
{:ok, fd} = File.open("tmp/data3.txt", [:read, :binary])
assert fd
|> StreamSplit.split("", tagging: true, drop_last: true)
|> Stream.map(fn
{:first, data} ->
data =
data
|> String.replace_prefix("", "")
|> String.upcase()
"#{data}"
{:last, data} ->
data =
data
|> String.replace_prefix("", "")
|> String.replace_suffix("", "")
|> String.upcase()
"#{data}"
data ->
"#{data}"
end)
|> Enum.to_list() == ["AAA", "bbb", "CCC"]
end
##### PRIVATE #####
defp gen_doc(sep, n) do
1..n
|> Enum.map(fn _ -> gen_string() end)
|> Enum.join(sep)
end
defp gen_string() do
n = Enum.random(1..31)
n
|> :crypto.strong_rand_bytes()
|> Base.url_encode64()
|> binary_part(0, n)
end
end