Skip to content

Unpinned the enum tests and repaired lsp/language; 878 is the first defensible assertion count #2715

Description

@gHashTag

Follow-through on #2712: the emitter now lowers a sole enum field to a real enum, so the tests that pinned the accidental struct shape had to move with it. Plus the first repair of a file whose tests had never run.

Measured, with the corpus clean and the cache isolated (#2714)

ast-check valid 293 / 520
valid, pure t27 288 / 455 — 63%
ast-check errors 591
compiled and ran 206
of those, running zero tests 31
assertions actually executed 878
ASSERTION FAILED 8, down from 10
parse gate 105 events / 0 lost, holds

878 is the first assertion count I can defend. The 888 published earlier was not necessarily wrong, but the instrument that produced it could serve a result compiled from different code, so it was never verifiable. Treat the two as incomparable rather than as a regression of ten.

One spec now times out at 120s. That is the isolated cache paying for a cold std build, not a new defect.

The unpinning

specs/tri/sort/sort.t27 is the model. The old test carried its own instruction to delete it:

test sort_order_still_emits_as_a_struct_rather_than_an_enum
    // ... Delete this test once the emitter is fixed.
    then ascending_type == void

Its replacement is stronger, not merely adapted:

test sort_order_is_an_enum_whose_two_directions_are_alternatives
    given ascending = @intFromEnum(SortOrder.Ascending)
    and descending = @intFromEnum(SortOrder.Descending)
    then ascending == 0 and descending == 1

Tag ordering is something the void-field struct could not express at all. Same for color.t27 (which gained tag_type == u2 and two ordering pins, 15 expect sites → 18) and bson.t27 (first and last tag values, so eleven members cannot be silently renumbered).

msgpack.t27 is the one that gained nothing — a single .@"struct".@"enum" and no ordering pin. Its nine MessagePack families are inherently ordered and nothing checks that.

lsp/language.t27 — 14 tests that had never run

68 lines. The file compiles for the first time; 13 of 14 pass.

All 16 LANG_*/EXT_* constants go from [N]u8 to []const u8 — a Zig string literal is *const [N:0]u8, and every one of these is compared, returned, and stored in a LanguageInfo, which is slice usage and never a fixed buffer. Slice equality replaces ext == EXT_T27, which is a pointer comparison on arrays and an outright error on slices; std.mem.eql is the corpus idiom, 65 uses across 20 specs. Invariants using @as(u8, Enum.x) become @intFromEnum.

One test is left failing on purpose. LANG_ZIG : [4]u8 = "zig" — a four-slot array declared to hold three characters — and the test inherited that 4:

try std.testing.expectEqual(@as(usize, info.id.len), @as(usize, 4));

The string is right and the test is wrong. Because the file never compiled, nothing ever forced the declaration and the assertion to agree, so the wrong number propagated from one into the other. Its two siblings of identical shape both pass.

A caveat the audit raised and I am carrying forward: moving to []const u8 drops 16 declared-length claims, and 12 are now checked by nothing. They were never checked before either — the file did not compile — but the type used to state them. Worth a follow-up that asserts the lengths in tests rather than in types.

Not touched: specs/lsp/protocol.t27 has the identical [N]u8 = "literal" pattern across 15 constants with several visibly wrong lengths — METHOD_HOVER : [17]u8 = "textDocument/hover" is 18 characters. Same defect, tests presumably never run either.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions