I'm having trouble understanding why the assertThrown in unit test 5 is not behaving in the code below:
ubyte[] decodeBase32(string encoded) {
import std.string: indexOf, stripRight;
// Remove padding if present
encoded = encoded.stripRight("=");
ubyte[] result;
size_t bitBuffer = 0;
int bitBufferLen = 0;
foreach (char c; encoded) {
auto index = base32Alphabet.indexOf(c);
if (index == -1)
throw new Exception("Invalid character in base32 string");
bitBuffer = (bitBuffer << 5) | index;
bitBufferLen += 5;
while (bitBufferLen >= 8) {
bitBufferLen -= 8;
result ~= cast(ubyte)((bitBuffer >> bitBufferLen) & 0xFF);
}
}
return result;
}
unittest {
import std.algorithm.comparison: equal;
import std.string: representation;
import std.stdio: writeln;
writeln("Testing new implementation:");
// Test case 1: Basic "Hello world" example
string encoded = "JBSWY3DPEB3W64TMMQ======";
auto expected = "Hello world".representation;
ubyte[] result = decodeBase32(encoded);
assert(result.equal(expected), "Test case 1 failed: 'Hello World' decoding");
// Test case 2: Empty string should return an empty array
writeln("Test case 2: Empty string should return an empty array");
encoded = "";
expected = [];
result = decodeBase32(encoded);
assert(result == expected, "Test case 2 failed: Empty string decoding");
// Test case 3: "foobar" in Base32
writeln("Test case 3: 'foobar' in Base32");
encoded = "MZXW6YTBOI======";
expected = [102, 111, 111, 98, 97, 114]; // "foobar"
result = decodeBase32(encoded);
assert(result == expected, "Test case 3 failed: 'foobar' decoding");
import std.exception: assertThrown;
// Test case 4: Test with padding in the middle (invalid)
writeln("Test case 4: Test with padding in the middle (invalid)");
assertThrown(decodeBase32("JBSWY=3DPEB======"),
"Test case 4 failed: Invalid input with padding in the middle should throw");
// Test case 5: Invalid character in input string
writeln("Test case 5: Invalid character in input string");
// '@' is not a valid Base32 character
try {
result = decodeBase32("JBSWY3DP@B3W64TMMQ");
} catch (Exception e) {
writeln("case 5 passed really..., exception msg was: ", e.msg);
}
// for some reason the below fails, giving an assert error (ie, no exception thrown)
assertThrown(decodeBase32("JBSWY3DP@B3W64TMMQ"),
"Test case 5 failed: Invalid character should throw an exception");
}
When I compile with unit tests on, I get this output:
Testing new implementation:
Test case 2: Empty string should return an empty array
Test case 3: 'foobar' in Base32
Test case 4: Test with padding in the middle (invalid)
Test case 5: Invalid character in input string
case 5 passed really..., exception msg was: Invalid character in base32 string
core.exception.AssertError@src/encoding.d(283): Assertion failure
It seems like assertThrown works as expected for case 4, but mysteriously not working for case 5 - despite the code under test raising the same exception. Am I missing something stupid here?