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?

Reply via email to