digitalmars.D.learn - Problem with assertThrown
- kookman (88/88) Sep 09 I'm having trouble understanding why the assertThrown in unit
- Jonathan M Davis (7/10) Sep 09 At a glance, it looks like the part of case 5 which explicitly catches t...
- kookman (7/19) Sep 09 Thanks Jonathan. Sorry I missed the excerpt for base32Alphabet -
- Jonathan M Davis (19/41) Sep 09 When I run it locally, assertThrown passes as expected for test case 5, ...
- kookman (8/32) Sep 09 Ah! *(forehead slap)* Thank you! It was actually an assert in the
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?
Sep 09
On Monday, September 9, 2024 5:46:18 PM MDT kookman via Digitalmars-d-learn wrote: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?At a glance, it looks like the part of case 5 which explicitly catches the Exception and the part that uses assertThrown should behave the same, but your example doesn't actually compile (you didn't include a definition for base32Alphabet), so it's not actually possible to reproduce your problem. - Jonathan M Davis
Sep 09
On Tuesday, 10 September 2024 at 00:27:43 UTC, Jonathan M Davis wrote:On Monday, September 9, 2024 5:46:18 PM MDT kookman via Digitalmars-d-learn wrote:Thanks Jonathan. Sorry I missed the excerpt for base32Alphabet - included below: ``` enum base32Alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567"; ```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?At a glance, it looks like the part of case 5 which explicitly catches the Exception and the part that uses assertThrown should behave the same, but your example doesn't actually compile (you didn't include a definition for base32Alphabet), so it's not actually possible to reproduce your problem. - Jonathan M Davis
Sep 09
On Monday, September 9, 2024 6:40:07 PM MDT kookman via Digitalmars-d-learn wrote:On Tuesday, 10 September 2024 at 00:27:43 UTC, Jonathan M Davis wrote:When I run it locally, assertThrown passes as expected for test case 5, and the same happens on run.dlang.io, so nothing in my specific setup is making it pass when it normally wouldn't. So, unless you verified that your example failed (and since you forgot to include that enum, I suspect you didn't), I would guess that whatever your problem is went away when you reduced the code to provide the example for your question. I would note however, that the message for the AssertError that you provided did not come from assertThrown, since while assertThrown does take the file and line number from the caller, its message starts with "assertThrown failed:", whereas your error message was the generic message that you get from an assertion failure. So, whatever is going wrong in your code, assertThrown is not determining that your code didn't throw and then code you actually ran (which is clearly longer than the example you provided, since it's not that long) is failing. - Jonathan M DavisOn Monday, September 9, 2024 5:46:18 PM MDT kookman via Digitalmars-d-learn wrote:Thanks Jonathan. Sorry I missed the excerpt for base32Alphabet - included below: ``` enum base32Alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567"; ```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?At a glance, it looks like the part of case 5 which explicitly catches the Exception and the part that uses assertThrown should behave the same, but your example doesn't actually compile (you didn't include a definition for base32Alphabet), so it's not actually possible to reproduce your problem. - Jonathan M Davis
Sep 09
On Tuesday, 10 September 2024 at 01:04:15 UTC, Jonathan M Davis wrote:When I run it locally, assertThrown passes as expected for test case 5, and the same happens on run.dlang.io, so nothing in my specific setup is making it pass when it normally wouldn't. So, unless you verified that your example failed (and since you forgot to include that enum, I suspect you didn't), I would guess that whatever your problem is went away when you reduced the code to provide the example for your question. I would note however, that the message for the AssertError that you provided did not come from assertThrown, since while assertThrown does take the file and line number from the caller, its message starts with "assertThrown failed:", whereas your error message was the generic message that you get from an assertion failure. So, whatever is going wrong in your code, assertThrown is not determining that your code didn't throw and then throwing an AssertError. It looks like an assertion on line code you actually ran (which is clearly longer than the example you provided, since it's not that long) is failing. - Jonathan M DavisAh! *(forehead slap)* Thank you! It was actually an assert in the immediately following unittest block failing (which I hadn't added a message to). I should have tried my reduced version before posting. Thanks, Kookman
Sep 09