Current section
Files
Jump to
Current section
Files
test/bech32_test.exs
defmodule Bitcoinex.Bech32Test do
use ExUnit.Case
doctest Bitcoinex.Bech32
alias Bitcoinex.Bech32
# Bech32
@valid_bech32 [
"A12UEL5L",
"an83characterlonghumanreadablepartthatcontainsthenumber1andtheexcludedcharactersbio1tt5tgs",
"abcdef1qpzry9x8gf2tvdw0s3jn54khce6mua7lmqqqxw",
"11qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqc8247j",
"split1checkupstagehandshakeupstreamerranterredcaperred2y9e3w"
]
@invalid_bech32_hrp_char_out_of_range [
<<0x20, "1nwldj5">>,
<<0x7F, "1axkwrx">>,
<<0x90::utf8, "1eym55h">>
]
@invalid_bech32_max_length_exceeded [
"an84characterslonghumanreadablepartthatcontainsthenumber1andtheexcludedcharactersbio1569pvx"
]
@invalid_bech32_no_separator_character [
"pzry9x0s0muk"
]
@invalid_bech32_empty_hrp [
"1pzry9x0s0muk",
"10a06t8",
"1qzzfhee"
]
@invalid_bech32_checksum [
"A12UEL5A"
]
@invalid_bech32_invalid_data_character [
"x1b4n0q5v"
]
@invalid_bech32_too_short_checksum [
"li1dgmt3"
]
@invalid_bech32_invalid_character_in_checksum [
<<"de1lg7wt", 0xFF::utf8>>
]
# Bech32m
@valid_bech32m [
"A1LQFN3A",
"a1lqfn3a",
"an83characterlonghumanreadablepartthatcontainsthetheexcludedcharactersbioandnumber11sg7hg6",
"abcdef1l7aum6echk45nj3s0wdvt2fg8x9yrzpqzd3ryx",
"11llllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllludsr8",
"split1checkupstagehandshakeupstreamerranterredcaperredlc445v",
"?1v759aa"
]
@invalid_bech32m_hrp_char_out_of_range [
<<0x20, "1xj0phk">>,
<<0x7F, "1g6xzxy">>,
<<0x90::utf8, "1vctc34">>
]
@invalid_bech32m_max_length_exceeded [
"an84characterslonghumanreadablepartthatcontainsthetheexcludedcharactersbioandnumber11d6pts4"
]
@invalid_bech32m_no_separator_character [
"qyrz8wqd2c9m"
]
@invalid_bech32m_empty_hrp [
"1qyrz8wqd2c9m",
"16plkw9",
"1p2gdwpf"
]
@invalid_bech32m_checksum [
"M1VUXWEZ"
]
@invalid_bech32m_invalid_data_character [
"y1b0jsk6g",
"lt1igcx5c0"
]
@invalid_bech32m_too_short_checksum [
"in1muywd"
]
@invalid_bech32m_invalid_character_in_checksum [
"mm1crxm3i",
"au1s5cgom"
]
describe "decode/1 for bech32" do
test "successfully decode with valid bech32" do
for bech <- @valid_bech32 do
assert {:ok, {:bech32, hrp, data}} = Bech32.decode(bech)
assert hrp != nil
# encode after decode should be the same(after downcase) as before
{:ok, new_bech} = Bech32.encode(hrp, data, :bech32)
assert new_bech == String.downcase(bech)
end
end
test "fail to decode with invalid bech32 out of ranges" do
for bech <- @invalid_bech32_hrp_char_out_of_range do
assert {:error, msg} = Bech32.decode(bech)
assert msg == :hrp_char_out_opf_range
end
end
test "fail to decode with invalid bech32 overall max length exceeded" do
for bech <- @invalid_bech32_max_length_exceeded do
assert {:error, msg} = Bech32.decode(bech)
assert msg == :overall_max_length_exceeded
end
end
test "fail to decode with invalid bech32 no separator character" do
for bech <- @invalid_bech32_no_separator_character do
assert {:error, msg} = Bech32.decode(bech)
assert msg == :no_separator_character
end
end
test "fail to decode with invalid bech32 empty hrp" do
for bech <- @invalid_bech32_empty_hrp do
assert {:error, msg} = Bech32.decode(bech)
assert msg == :empty_hrp
end
end
test "fail to decode with invalid data character" do
for bech <- @invalid_bech32_invalid_data_character do
assert {:error, msg} = Bech32.decode(bech)
assert msg == :contain_invalid_data_char
end
end
test "fail to decode with too short checksum" do
for bech <- @invalid_bech32_too_short_checksum do
assert {:error, msg} = Bech32.decode(bech)
assert msg == :too_short_checksum
end
end
test "fail to decode with invalid character in checksum" do
for bech <- @invalid_bech32_invalid_character_in_checksum do
assert {:error, msg} = Bech32.decode(bech)
assert msg == :contain_invalid_data_char
end
end
test "fail to decode with invalid checksum" do
for bech <- @invalid_bech32_checksum do
assert {:error, msg} = Bech32.decode(bech)
assert msg == :invalid_checksum
end
end
end
describe "decode/1 for bech32m" do
test "successfully decode with valid bech32" do
for bech <- @valid_bech32m do
assert {:ok, {:bech32m, hrp, data}} = Bech32.decode(bech)
assert hrp != nil
# encode after decode should be the same(after downcase) as before
{:ok, new_bech} = Bech32.encode(hrp, data, :bech32m)
assert new_bech == String.downcase(bech)
end
end
test "fail to decode with invalid bech32m out of ranges" do
for bech <- @invalid_bech32m_hrp_char_out_of_range do
assert {:error, msg} = Bech32.decode(bech)
assert msg == :hrp_char_out_opf_range
end
end
test "fail to decode with invalid bech32m overall max length exceeded" do
for bech <- @invalid_bech32m_max_length_exceeded do
assert {:error, msg} = Bech32.decode(bech)
assert msg == :overall_max_length_exceeded
end
end
test "fail to decode with invalid bech32m no separator character" do
for bech <- @invalid_bech32m_no_separator_character do
assert {:error, msg} = Bech32.decode(bech)
assert msg == :no_separator_character
end
end
test "fail to decode with invalid bech32m empty hrp" do
for bech <- @invalid_bech32m_empty_hrp do
assert {:error, msg} = Bech32.decode(bech)
assert msg == :empty_hrp
end
end
test "fail to decode with invalid data character" do
for bech <- @invalid_bech32m_invalid_data_character do
assert {:error, msg} = Bech32.decode(bech)
assert msg == :contain_invalid_data_char
end
end
test "fail to decode with too short checksum" do
for bech <- @invalid_bech32m_too_short_checksum do
assert {:error, msg} = Bech32.decode(bech)
assert msg == :too_short_checksum
end
end
test "fail to decode with invalid character in checksum" do
for bech <- @invalid_bech32m_invalid_character_in_checksum do
assert {:error, msg} = Bech32.decode(bech)
assert msg == :contain_invalid_data_char
end
end
test "fail to decode with invalid checksum" do
for bech <- @invalid_bech32m_checksum do
assert {:error, msg} = Bech32.decode(bech)
assert msg == :invalid_checksum
end
end
end
describe "encode/2 for bech32" do
test "successfully encode with valid hrp and empty data" do
assert {:ok, _bech} = Bech32.encode("bc", [], :bech32)
end
test "successfully encode with valid hrp and non empty valid data" do
assert {:ok, _bech} = Bech32.encode("bc", [1, 2], :bech32)
end
test "successfully encode with invalid string data" do
assert {:ok, _bech} = Bech32.encode("bc", "qpzry9x8gf2tvdw0s3jn54khce6mua7l", :bech32)
end
test "fail to encode with valid hrp and non empty valid string data" do
assert {:error, _bech} = Bech32.encode("bc", "qpzry9x8gf2tvdw0s3jn54khce6mua7lo", :bech32)
end
test "fail to encode with overall encoded length is over 90" do
data = for _ <- 1..82, do: 1
assert {:error, :overall_max_length_exceeded} = Bech32.encode("bc", data, :bech32)
end
test "fail to encode with hrp contain invalid char(out of 1 to 83 US-ASCII)" do
data = [1]
assert {:error, :hrp_char_out_opf_range} = Bech32.encode(" ", data, :bech32)
assert {:error, :hrp_char_out_opf_range} = Bech32.encode("\ł", data, :bech32)
assert {:error, :hrp_char_out_opf_range} = Bech32.encode("中文", data, :bech32)
end
end
describe "encode/2 for bech32m" do
test "successfully encode with valid hrp and empty data" do
assert {:ok, _bech} = Bech32.encode("bc", [], :bech32m)
end
test "successfully encode with valid hrp and non empty valid data" do
assert {:ok, _bech} = Bech32.encode("bc", [1, 2], :bech32m)
end
test "successfully encode with invalid string data" do
assert {:ok, _bech} = Bech32.encode("bc", "qpzry9x8gf2tvdw0s3jn54khce6mua7l", :bech32m)
end
test "fail to encode with valid hrp and non empty valid string data" do
assert {:error, _bech} = Bech32.encode("bc", "qpzry9x8gf2tvdw0s3jn54khce6mua7lo", :bech32m)
end
test "fail to encode with overall encoded length is over 90" do
data = for _ <- 1..82, do: 1
assert {:error, :overall_max_length_exceeded} = Bech32.encode("bc", data, :bech32m)
end
test "fail to encode with hrp contain invalid char(out of 1 to 83 US-ASCII)" do
data = [1]
assert {:error, :hrp_char_out_opf_range} = Bech32.encode(" ", data, :bech32m)
assert {:error, :hrp_char_out_opf_range} = Bech32.encode("\ł", data, :bech32m)
assert {:error, :hrp_char_out_opf_range} = Bech32.encode("中文", data, :bech32m)
end
end
end