module encoding::base32 @test; import std::encoding::base32; // https://www.rfc-editor.org/rfc/rfc4648#section-10 struct TestCase { char[] dec; char[] enc; } TestCase[*] std_tests = { { "", "" }, { "f", "MY======" }, { "fo", "MZXQ====" }, { "foo", "MZXW6===" }, { "foob", "MZXW6YQ=" }, { "fooba", "MZXW6YTB" }, { "foobar", "MZXW6YTBOI======" }, }; TestCase[*] hex_tests = { { "", "" }, { "f", "CO======" }, { "fo", "CPNG====" }, { "foo", "CPNMU===" }, { "foob", "CPNMUOG=" }, { "fooba", "CPNMUOJ1" }, { "foobar", "CPNMUOJ1E8======" }, }; macro encode_tests(tests, alphabet, padding) { foreach (t : tests) { char[64] buf; usz n = base32::encode_len(t.dec.len, padding); base32::encode_buffer(t.dec, buf[:n], padding, alphabet); char[] want = t.enc; usz? pad_idx = array::index_of(want, '='); if (try pad_idx && !padding) { want = want[:pad_idx]; } assert(buf[:n] == want, "got: %s, want: %s", (String)buf[:n], (String)want); } } fn void encode() { encode_tests(std_tests, &base32::STANDARD, '='); encode_tests(hex_tests, &base32::HEX, '='); } fn void encode_nopadding() { encode_tests(std_tests, &base32::STANDARD, base32::NO_PAD); encode_tests(hex_tests, &base32::HEX, base32::NO_PAD); } macro decode_tests(tests, alphabet, padding) { foreach (t : tests) { char[] input = t.enc[..]; usz? pad_idx = array::index_of(input, '='); if (try pad_idx && !padding) { input = input[:pad_idx]; } char[64] buf; usz n = base32::decode_len(input.len, padding); char[] buf2 = base32::decode_buffer(input, buf[:n], padding, alphabet)!!; assert(buf2 == t.dec, "got: %s, want: %s", buf2, (String)t.dec); } } fn void decode() { decode_tests(std_tests, &base32::STANDARD, '='); decode_tests(hex_tests, &base32::HEX, '='); } fn void decode_nopadding() { decode_tests(std_tests, &base32::STANDARD, base32::NO_PAD); decode_tests(hex_tests, &base32::HEX, base32::NO_PAD); } fn void base32_api() { @pool() { foreach (t : std_tests) { String got = base32::tencode(t.dec)!!; assert(got == t.enc, "got: %s, want: %s", got, t.enc); char[] got_chars = base32::tdecode(t.enc)!!; assert(got_chars == t.dec, "got: %s, want: %s", got_chars, t.dec); } }; }