Skip to content

Conversation

@r-teller
Copy link

Description

Summary

This PR completes the unevaluatedProperties implementation by adding support to
templates that were missing it and significantly improving test coverage with
real-world examples.

The initial unevaluatedProperties support (added in #47a09a4) covered the core
implementation and most templates, but the flat and md_nested templates were
missing support. This PR fills those gaps and enhances the test cases to better
demonstrate the keyword's intended use with schema composition.

Changes

Template Updates

Flat Template:

  • Added unevaluatedProperties badge display in templates/flat/content.html
  • Added italic styling and descriptive text for unevaluated properties in
    templates/flat/section_properties.html
  • Added CSS styling for .badge.no-unevaluated class in
    templates/flat/schema_doc.css

Markdown Nested Template:

  • Added skip logic for unevaluated properties without schema (consistent with
    additionalProperties behavior)
  • Added proper property type display logic for "Unevaluated Properties" label in
    templates/md_nested/section_properties_details.md

Test Coverage Improvements

Updated docs/examples/cases/unevaluated_properties.json:

  • Demonstrates real-world usage with schema composition (allOf, oneOf, if/then)
  • Shows nested objects with unevaluatedProperties as a schema constraint (not just
    boolean)
  • Properly illustrates the difference between additionalProperties and
    unevaluatedProperties

Added docs/examples/cases/unevaluated_with_additional_properties.json:

  • New test case showing interaction between unevaluatedProperties and
    additionalProperties
  • Demonstrates various nested scenarios with both keywords

Generated Documentation

  • Updated all generated example files across all template variants (JS, JS Offline,
    Flat, Markdown variants)

Testing

All 339 tests pass, including:

  • Flat template rendering with unevaluatedProperties
  • Markdown nested template rendering with unevaluatedProperties
  • Schema composition scenarios (allOf, oneOf, if/then)
  • Nested unevaluatedProperties with schema constraints

Background

The unevaluatedProperties keyword (introduced in JSON Schema Draft 2019-09) differs
from additionalProperties:

  • additionalProperties only considers properties in the same schema object's
    properties/patternProperties
  • unevaluatedProperties considers properties evaluated across schema composition
    (allOf, anyOf, oneOf, if/then/else)

This implementation ensures all output formats properly support this powerful schema
composition feature.

…m JSON Schema Draft 2019-09 and later, providing more precise control over properties not covered by `properties`, `patternProperties`, or `additionalProperties`.

**Add UNEVALUATED_PROPERTIES to SchemaKeyword enum**

Adds `UNEVALUATED_PROPERTIES` to the `SchemaKeyword` enum, enabling support for this JSON Schema keyword introduced in draft 2019-09. This keyword is crucial for advanced schema validation, allowing stricter control over properties not covered by other property-related keywords.

**Add unevaluated properties support to SchemaNode class**

- **Lines 116-119**: Adds `unevaluated_properties` and `no_unevaluated_properties` attributes to track both the schema definition and the boolean false case
- **Lines 138-144**: Implements `explicit_no_unevaluated_properties` property to distinguish between "not set" and "explicitly set to false" (mirrors `explicit_no_additional_properties`)
- **Lines 188-194**: Adds `is_unevaluated_properties` and `is_unevaluated_properties_schema` convenience properties
- **Lines 206-207**: Includes unevaluated_properties in the `iterate_properties` iterator for consistent property enumeration
- **Lines 415-416**: Adds `kw_unevaluated_properties` getter method following the established pattern for keyword access
- **Lines 501-502**: Updates `property_display_name` to return "Unevaluated Properties" when appropriate

The implementation mirrors the existing `additionalProperties` pattern, ensuring consistent behavior and a familiar API.

**Build intermediate representation for unevaluatedProperties**

- **Lines 567-585**: Handles the `unevaluatedProperties` keyword during schema node construction:
  - If the value is `false`, sets `no_unevaluated_properties = True`
  - Otherwise, recursively builds a child SchemaNode for the unevaluated properties schema
  - Correctly sets parent context, HTML IDs, and breadcrumb paths for proper navigation

This ensures that:
1. `"unevaluatedProperties": false` prevents any unevaluated properties
2. `"unevaluatedProperties": { "type": "string" }` validates unevaluated properties against the provided schema

**`section_properties.html`**: Display unevaluated properties with visual distinction
- **Lines 9-15**: Italicizes the "Unevaluated Properties" label for visual consistency with additional properties
- **Lines 50-56**: Adds descriptive text explaining the constraint:
  - If a schema is provided: "Each unevaluated property must conform to the following schema"
  - If no specific schema: "Unevaluated Properties of any type are allowed."

**`content.html`**: Add "No Unevaluated Properties" badge
- Displays a badge when `schema.explicit_no_unevaluated_properties` is true
- Uses `.badge.no-unevaluated` CSS class for styling
- Positioned alongside the existing "No Additional Properties" badge
- Provides a clear visual indicator of schema constraints

**`schema_doc.css`** (in both `templates/js/` and `templates/js_offline/css/`):
- Adds styling for `.badge.no-unevaluated` class
- Applies standard badge formatting (font size, margin) for visual consistency
- Ensures the badge aligns with other property badges like "required" and "deprecated"

**`templates/md/section_properties_details.md`**: Support unevaluated properties in markdown output
- **Lines 6-8**: Skips rendering unevaluated properties without a schema (consistent with additional properties behavior)
- **Lines 22-23**: Renders "Unevaluated Properties" as the section heading
- Ensures markdown documentation properly represents the unevaluated properties constraint

Comprehensive test schema demonstrating various scenarios:
- **Root level**: `"unevaluatedProperties": false` prevents any properties not covered by `properties` or `additionalProperties`
- **subType1**: Object with no explicit additional/unevaluated properties constraint (shows default behavior)
- **subType2**: Object with `"additionalProperties": false` (demonstrates the distinction between the two keywords)
- **Root level**: `"additionalProperties": { ... }` with a schema (demonstrates how unevaluated and additional properties interact)
- **anInt property**: Integer type that should not show property constraints (regression test for issue coveooss#132)

This example serves as both validation and user documentation for the feature.

✅ **Standards Compliance**: Full support for JSON Schema Draft 2019-09+
✅ **Consistent Implementation**: Mirrors the established `additionalProperties` pattern
✅ **Visual Clarity**: Badges and italicized labels make constraints immediately visible
✅ **Complete Coverage**: Works across all template types (HTML JS, HTML offline, Markdown)
✅ **Semantic Accuracy**: Distinguishes between "not set", "set to false", and "set to schema"

1. Verify keyword interaction with combinations of `properties`, `additionalProperties`, and `unevaluatedProperties`
2. Ensure `"unevaluatedProperties": false` displays the badge and prevents properties
3. Verify `"unevaluatedProperties": { "type": "..." }` correctly renders the sub-schema
4. Confirm non-object types don't show property constraints (issue coveooss#132)
5. Test with `$ref` and recursive schemas for proper circular reference handling
This commit completes the unevaluatedProperties implementation by adding support for the flat and md_nested templates, and improves test coverage with more comprehensive examples.

Changes:
- Add unevaluatedProperties badge display to flat template (content.html)
- Add italic styling and descriptive text for unevaluatedProperties in flat template (section_properties.html)
- Add CSS styling for no-unevaluated badge in flat template (schema_doc.css)
- Add skip logic and property type display for unevaluatedProperties in md_nested template
- Update unevaluated_properties.json test case to demonstrate real-world usage with schema composition (allOf, oneOf, if/then) and nested unevaluatedProperties with schema constraints
- Add new test case unevaluated_with_additional_properties.json showing interaction between both keywords
- Update generated documentation examples for all templates
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.

1 participant