Skip to content

Commit 40d1d83

Browse files
akoclaude
andcommitted
fix: CREATE ENUMERATION rejects duplicate value names (#390)
ValidateEnumeration only checked for reserved words; it never detected duplicate value names within the same CREATE ENUMERATION statement. Running CREATE ENUMERATION M.E (A 'First', A 'Second') succeeded silently, producing an invalid model that Studio Pro flags as an error. Added a seen-name set (case-insensitive) to ValidateEnumeration. A second occurrence of a name emits a MDL011 violation, which the executor turns into a validation error before any write reaches the backend. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
1 parent 1e33c8b commit 40d1d83

2 files changed

Lines changed: 37 additions & 1 deletion

File tree

mdl/executor/cmd_enumerations.go

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -289,8 +289,24 @@ var mendixReservedWords = map[string]bool{
289289
// This function does not require a project connection.
290290
func ValidateEnumeration(stmt *ast.CreateEnumerationStmt) []linter.Violation {
291291
var violations []linter.Violation
292+
seen := make(map[string]bool)
292293
for _, v := range stmt.Values {
293-
if mendixReservedWords[strings.ToLower(v.Name)] {
294+
lower := strings.ToLower(v.Name)
295+
if seen[lower] {
296+
violations = append(violations, linter.Violation{
297+
RuleID: "MDL011",
298+
Severity: linter.SeverityError,
299+
Message: fmt.Sprintf(
300+
"duplicate enumeration value name '%s'", v.Name),
301+
Location: linter.Location{
302+
DocumentType: "enumeration",
303+
DocumentName: stmt.Name.String(),
304+
},
305+
Suggestion: "Each enumeration value must have a unique name",
306+
})
307+
}
308+
seen[lower] = true
309+
if mendixReservedWords[lower] {
294310
violations = append(violations, linter.Violation{
295311
RuleID: "MDL010",
296312
Severity: linter.SeverityError,

mdl/executor/cmd_enumerations_mock_test.go

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -155,5 +155,25 @@ func TestDropEnumeration_Qualified_Success(t *testing.T) {
155155
}
156156
}
157157

158+
// Issue #390 — CREATE ENUMERATION must reject duplicate value names.
159+
func TestCreateEnumeration_DuplicateValueName_Issue390(t *testing.T) {
160+
mod := mkModule("M")
161+
mb := &mock.MockBackend{
162+
IsConnectedFunc: func() bool { return true },
163+
ListModulesFunc: func() ([]*model.Module, error) { return []*model.Module{mod}, nil },
164+
ListEnumerationsFunc: func() ([]*model.Enumeration, error) { return nil, nil },
165+
}
166+
ctx, _ := newMockCtx(t, withBackend(mb))
167+
err := execCreateEnumeration(ctx, &ast.CreateEnumerationStmt{
168+
Name: ast.QualifiedName{Module: "M", Name: "E"},
169+
Values: []ast.EnumValue{
170+
{Name: "A", Caption: "First"},
171+
{Name: "A", Caption: "Second"},
172+
},
173+
})
174+
assertError(t, err)
175+
assertContainsStr(t, err.Error(), "duplicate")
176+
}
177+
158178
// Backend error: cmd_error_mock_test.go (TestShowEnumerations_Mock_BackendError)
159179
// JSON: cmd_json_mock_test.go (TestShowEnumerations_Mock_JSON)

0 commit comments

Comments
 (0)