diff options
| author | Murilo Ijanc <[email protected]> | 2026-07-27 20:39:06 -0300 |
|---|---|---|
| committer | Murilo Ijanc <[email protected]> | 2026-07-27 20:39:06 -0300 |
| commit | 497b1c1b01f6c9a584e5b40e02aff4763447529c (patch) | |
| tree | b50feb4252ba93cf045be3aaac14a96eeb04dff5 /test | |
| parent | 87166a5299aa551517a86379a0c05eb2110b52b0 (diff) | |
| download | zig-497b1c1b01f6c9a584e5b40e02aff4763447529c.tar.gz | |
A CEP that fails to resolve is rarely a random number. It is almost always
someone who knows the city and guessed the digits, and the classic guess is
the -000 that 957 municipalities never received. The API now says so: a 404
carries an optional faixa block naming the municipality the number would have
belonged to, and answering "no such CEP in Areal/RJ, which has 118 of them" is
a great deal more useful than "not found".
It arrives through Diagnostics, which is where every other detail a Zig error
tag cannot carry already travels, and it is read with diag.faixa(). Like
message(), it lives in a fixed buffer inside the value and allocates nothing,
so no caller has to learn a new deinit for it.
The lookup still fails. faixa is context for the error, never an address, and
cep_ini/cep_fim are the smallest and largest CEP that actually exist there
rather than the bounds the Correios publish — for Areal the DNE's own start is
25845000, which is exactly the CEP that failed. The range is also sparse, 118
CEPs over ~4,900 numbers, so ceps is the count and the pair must never be
presented as a list. The doc comments and the README say all three, because
this field is easy to misread as a success.
Parsing is deliberately inert: a faixa that is missing, null, not an object,
nameless or oversized yields null, and an unreadable body is skipped. Nothing
about this field may promote a clean not-found into a parse failure.
Diffstat (limited to 'test')
| -rw-r--r-- | test/api.zig | 135 |
1 files changed, 134 insertions, 1 deletions
diff --git a/test/api.zig b/test/api.zig index fcdb956..b860e41 100644 --- a/test/api.zig +++ b/test/api.zig @@ -379,6 +379,139 @@ test "a missing CEP is not found" { try testing.expect(std.mem.indexOf(u8, diag.message(), "99999999") != null); } +test "a missing CEP names the municipality it would have been in" { + var fixture: Fixture = undefined; + try fixture.init(); + defer fixture.deinit(); + + // 25845000 is Areal's own start in the DNE — and it is not a CEP that + // exists. That is exactly the guess this field is there to answer. + try fixture.server.respond("/25845000", &.{.{ + .status = 404, + .body = + \\{"erro":"cep_nao_encontrado","mensagem":"CEP não existe na base do DNE", + \\"faixa":{"localidade":"Areal","uf":"RJ","estado":"Rio de Janeiro", + \\"regiao":"Sudeste","ibge":"3300225","cep_ini":"25845001", + \\"cep_fim":"25849899","ceps":118}} + , + }}); + + var client = try fixture.server.client(.{}); + defer client.deinit(); + + var diag: cepis.Diagnostics = .{}; + // Still an error. The range explains the failure; it does not undo it. + try testing.expectError(error.NotFound, client.lookup("25845-000", .{ .diagnostics = &diag })); + try testing.expectEqual(@as(?u16, 404), diag.status); + + const faixa = diag.faixa().?; + try testing.expectEqualStrings("Areal", faixa.localidade); + try testing.expectEqualStrings("RJ", faixa.uf); + try testing.expectEqualStrings("Rio de Janeiro", faixa.estado); + try testing.expectEqualStrings("Sudeste", faixa.regiao); + try testing.expectEqualStrings("3300225", faixa.ibge); + // Not the Correios' bounds: cep_ini is the smallest CEP that exists, and + // the CEP that just failed is one below it. + try testing.expectEqualStrings("25845001", faixa.cep_ini); + try testing.expectEqualStrings("25849899", faixa.cep_fim); + // Sparse: 118 CEPs scattered over the ~4,900 numbers the pair spans. + try testing.expectEqual(@as(u64, 118), faixa.ceps); +} + +test "a CEP in a band no municipality owns reports no faixa" { + var fixture: Fixture = undefined; + try fixture.init(); + defer fixture.deinit(); + + // The API omits `faixa` here; it never sends null. + try fixture.server.respond("/99999999", &.{.{ + .status = 404, + .body = + \\{"erro":"cep_nao_encontrado","mensagem":"CEP não existe na base do DNE"} + , + }}); + + var client = try fixture.server.client(.{}); + defer client.deinit(); + + var diag: cepis.Diagnostics = .{}; + try testing.expectError(error.NotFound, client.lookup("99999999", .{ .diagnostics = &diag })); + try testing.expect(diag.faixa() == null); + try testing.expect(std.mem.indexOf(u8, diag.message(), "99999999") != null); +} + +test "a malformed faixa is still a clean not found" { + var fixture: Fixture = undefined; + try fixture.init(); + defer fixture.deinit(); + + try fixture.server.respond("/99999999", &.{ + .{ .status = 404, .body = "{\"erro\":\"cep_nao_encontrado\",\"faixa\":\"Areal\"}" }, + .{ .status = 404, .body = "{\"faixa\":{\"uf\":\"RJ\",\"ceps\":118}}" }, + .{ .status = 404, .body = "not json at all" }, + .{ .status = 404, .body = "" }, + }); + + var client = try fixture.server.client(.{}); + defer client.deinit(); + + for (0..4) |_| { + var diag: cepis.Diagnostics = .{}; + try testing.expectError( + error.NotFound, + client.lookup("99999999", .{ .diagnostics = &diag }), + ); + try testing.expect(diag.faixa() == null); + } +} + +test "one Diagnostics reused across lookups does not keep a stale faixa" { + var fixture: Fixture = undefined; + try fixture.init(); + defer fixture.deinit(); + + try fixture.server.respond("/25845000", &.{.{ + .status = 404, + .body = + \\{"erro":"cep_nao_encontrado","faixa":{"localidade":"Areal","uf":"RJ", + \\"ibge":"3300225","cep_ini":"25845001","cep_fim":"25849899","ceps":118}} + , + }}); + try fixture.server.respond("/99999999", &.{.{ + .status = 404, + .body = + \\{"erro":"cep_nao_encontrado","mensagem":"CEP não existe na base do DNE"} + , + }}); + + var client = try fixture.server.client(.{}); + defer client.deinit(); + + var diag: cepis.Diagnostics = .{}; + try testing.expectError(error.NotFound, client.lookup("25845000", .{ .diagnostics = &diag })); + try testing.expectEqualStrings("Areal", diag.faixa().?.localidade); + + try testing.expectError(error.NotFound, client.lookup("99999999", .{ .diagnostics = &diag })); + try testing.expect(diag.faixa() == null); +} + +test "a successful lookup carries no faixa" { + var fixture: Fixture = undefined; + try fixture.init(); + defer fixture.deinit(); + + try fixture.server.respond("/01001000", &.{.{ .body = se_address }}); + + var client = try fixture.server.client(.{}); + defer client.deinit(); + + var diag: cepis.Diagnostics = .{}; + var address = try client.lookup("01001000", .{ .diagnostics = &diag }); + defer address.deinit(testing.allocator); + + try testing.expect(diag.faixa() == null); +} + test "a 404 is not retried" { var fixture: Fixture = undefined; try fixture.init(); @@ -862,7 +995,7 @@ test "the User-Agent identifies the library and can be overridden" { try fixture.init(); defer fixture.deinit(); - try testing.expect(std.mem.startsWith(u8, cepis.default_user_agent, "cepis-zig/0.1.0")); + try testing.expect(std.mem.startsWith(u8, cepis.default_user_agent, "cepis-zig/0.2.0")); try fixture.server.respond("/01001000", &.{.{ .body = se_address }}); |