From ec0f213448ba4a11b2f35a63ade5df0b55911751 Mon Sep 17 00:00:00 2001 From: Scott Scoble Date: Sun, 28 Jun 2026 21:57:06 -0700 Subject: [PATCH] test(speckl): lock in enum interface classification (cycle 60) Adds a regression test that confirms a bare-identifier interface (no methods with parens, no fields with colons) parses as kind: 'enum' with the variants on its methods[] array. The .proto generator already emits these correctly as 'enum X { X_UNSPECIFIED = 0; FOO = 1; ... }' - confirmed end-to-end by running generateProtobuf against the federated-meetup CustodyTier shape. This was a verification cycle rather than a feature cycle: the compiler already does the right thing for enums, but without a regression test a future refactor of classifyInterfaces or parseInterface could break this silently. The test pins the behavior so a PR that breaks enum emission will fail CI. All 49 tests pass (48 + 1 new). tsc build clean. Reference: federated-meetup.speckdl CustodyTier shape interface CustodyTier { ColdHardware HotSigning ThresholdSplit BackupOnly Compromised } --- compiler/__tests__/parser.test.ts | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/compiler/__tests__/parser.test.ts b/compiler/__tests__/parser.test.ts index 02a7862..4678ab3 100644 --- a/compiler/__tests__/parser.test.ts +++ b/compiler/__tests__/parser.test.ts @@ -742,4 +742,28 @@ speck Second { } }); }); + + // Cycle 60: enum interfaces (e.g. CustodyTier) parse as `kind: 'enum'` + // and the .proto generator emits a real `enum X { ... }` block. + describe('enum interfaces (cycle 60)', () => { + it('should classify bare-identifier interfaces as enums', () => { + const content = `speck FederatedMeetup { + interface CustodyTier { + ColdHardware + HotSigning + ThresholdSplit + BackupOnly + Compromised + } +}`; + const ast = parseSpeckContent(content); + const tier = ast.specks[0].members.find(m => m.name === 'CustodyTier'); + if (tier?.type === 'interface') { + expect(tier.kind).toBe('enum'); + expect(tier.methods.map(m => m.name)).toEqual([ + 'ColdHardware', 'HotSigning', 'ThresholdSplit', 'BackupOnly', 'Compromised' + ]); + } + }); + }); });