Skip to content

Conversation

@shakrav2
Copy link
Contributor

Summary

Implements linting rules for AEP-126 (Enumerations) to validate enum field usage in OpenAPI specifications.

Closes #58

Rules Added

This PR adds 6 new linting rules:

  1. aep-126-enum-type-string (error) - Enums must use type: string, not integer or number
  2. aep-126-enum-case-consistent (warn) - All enum values must use consistent case formatting
  3. aep-126-enum-null-first (warn) - Nullable enums must have null as the first value
  4. aep-126-enum-nullable-declaration (error) - Enums containing null must declare nullable: true
  5. aep-126-no-standard-value-enums (warn) - Warns against enumerating standard codes (ISO 639, ISO 3166, ISO 4217, IANA)
  6. aep-126-enum-has-description (info) - Enum fields should include a description

Implementation Details

  • Custom Functions: 4 new Spectral functions in functions/aep-126-*.js
  • Tests: 38 test cases across 6 test files in test/0126/
  • Documentation: Complete rule documentation in docs/0126.md
  • JSONPath Pattern: Uses parent selector $..[?(@property === 'enum')]^ to safely handle enums containing null values

Test Results

38/38 tests passing (100%)
Code coverage: 80-85% for all custom functions
Linter: All checks passing

Testing

```bash
npm test -- --testPathPattern=0126
```

Checklist

  • All 6 rules implemented in `aep/0126.yaml`
  • Custom functions created with proper error handling
  • Comprehensive tests written (38 tests)
  • Documentation added in `docs/0126.md`
  • `spectral.yaml` and `docs/rules.md` updated
  • All tests passing
  • Code coverage >80%
  • Linter passing

- Replace pattern match with schema function to handle both scalar and array types
- Add support for OAS 3.1 type: ['string', 'null'] syntax
- Add test cases for OAS 3.1 nullable enums
- Fixes critical bug where OAS 3.1 specs would fail with runtime error
Copy link
Contributor

@mkistler mkistler left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks good but there are a few problems to fix and some improvements I'd like you to make.

message: Enum field "{{property}}" should have type "string", not "{{error}}".
severity: error
formats: ['oas2', 'oas3']
given: $..[?(@property === 'enum')]^
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since this is used in multiple givens, it seems like a good candidate for an alias.

- type: array
contains:
const: string
maxItems: 2
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess maxItems is here to allow "null" but it also allows other things that we'd want to flag. E.g. 'type: ["string", "number"]` should fail but I think would not currently.

description: If enum is nullable, null should be the first value in the enum array.
message: '{{error}}'
severity: warn
formats: ['oas2', 'oas3']
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is no good way to represent "nullable" fields in oas2, so I think any rule that involves nullable types should not declare that it works on oas2.

Suggested change
formats: ['oas2', 'oas3']
formats: ['oas3']

description: If enum contains null, field must declare nullable true.
message: '{{error}}'
severity: error
formats: ['oas2', 'oas3']
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
formats: ['oas2', 'oas3']
formats: ['oas3']

Comment on lines +20 to +23
// Only check string enums
if (field.type !== 'string') {
return [];
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This will might properties that are declared type: [null, string], which is the way nullable properties are defined in OpenAPI 3.1 and later. Please add some tests for v3.1 with nullable fields and then make sure all the rules work correctly.

return linter;
});

test('aep-126-enum-case-consistent should find warnings for mixed case', () => {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please add tests for parameters with enum values -- here and in all the other rule test files.

Comment on lines +54 to +61
aep-126-no-standard-value-enums:
description: Fields should not enumerate standard codes (language, country, currency, media types).
message: '{{error}}'
severity: warn
formats: ['oas2', 'oas3']
given: $..[?(@property === 'enum')]^
then:
function: aep-126-no-standard-value-enums
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think we need a custom function here. I think we can write the rule this way and avoid custom js code.

Suggested change
aep-126-no-standard-value-enums:
description: Fields should not enumerate standard codes (language, country, currency, media types).
message: '{{error}}'
severity: warn
formats: ['oas2', 'oas3']
given: $..[?(@property === 'enum')]^
then:
function: aep-126-no-standard-value-enums
aep-126-no-standard-value-enums:
description: Fields should not enumerate standard codes (language, country, currency, media types).
severity: warn
formats: ['oas2', 'oas3']
given:
- $..properties[[?(@property == 'language' || @property == 'language_code')]]
- $..properties[[?(@property == 'country' || @property == 'country_code' || @property == 'region_code')]]
- $..properties[[?(@property == 'currency' || @property == 'currency_code')]]
- $..properties[[?(@property == 'media_type' || @property == 'content_type')]]
then:
function: schema
functionOptions:
schema:
type: object
not:
required: ['enum']

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Implement rules for AEP-126: Enumerations

2 participants