Skip to content

Liturgical event tests

John R. D'Orazio edited this page Apr 24, 2026 · 3 revisions

Liturgical event tests

Liturgical event tests verify the liturgical correctness of the calendar output: that events fall on the right dates, respect precedence rules, appear only in the years they should, and are correctly moved when they coincide with higher-ranking celebrations. These are distinct from the code-quality unit tests that exercise the API's PHP classes and HTTP routes.

Overview

Test definitions live as JSON files in jsondata/tests/ within the LiturgicalCalendarAPI repository. Each file defines assertions about a single liturgical event across one or more calendar years. These definitions can be created and managed through the Unit Test interface frontend. See Unit Test server and interface for details on that frontend and its WebSocket backend.

The API exposes a /tests/ discovery endpoint that lists all available test definitions, making them consumable by the frontend interface.

File location and naming

Test files are stored in:

jsondata/tests/
├── MaryMotherChurchTest.json
├── NativityJohnBaptistTest.json
├── PrayerUnbornTest.json
├── StJaneFrancesDeChantalTest.json
└── rotter_nl_HLaurentiusdiakenenmartelaarpatroonvanhetbisdomTest.json

File names must end in *Test.json. The name typically matches the event_key of the event being tested. For diocesan or national events, the name is prefixed with the calendar identifier (e.g., rotter_nl_ for the Diocese of Rotterdam in the Netherlands).

JSON structure

Every test definition is a JSON object with these top-level properties:

Property Type Required Description
name string yes Identifier for the test (matches the filename)
event_key string yes The liturgical event key as used in the API response
description string yes Human-readable explanation of what the test verifies
test_type string yes One of the three test types (see below)
year_since number no Starting year (required for exactCorrespondenceSince)
applies_to object no Restricts the test to a specific calendar (see below)
assertions array yes Array of assertion objects (see below)

Test types

exactCorrespondence

The event is tested only against the years listed in the assertions array. Every assertion must have an explicit expected_value. This type is appropriate when the event exists in every calendar year but may fall on different dates in specific years due to precedence rules.

Example use case: The Nativity of John the Baptist normally falls on June 24, but when it coincides with the Solemnity of the Sacred Heart, it is moved to June 23. The test lists only the years where this coincidence occurs:

{
    "name": "NativityJohnBaptistTest",
    "event_key": "NativityJohnBaptist",
    "description": "When the Nativity of John the Baptist coincides with the Sacred Heart, is it moved to June 23?",
    "test_type": "exactCorrespondence",
    "assertions": [
        {
            "year": 2022,
            "expected_value": "2022-06-23T00:00:00+00:00",
            "assert": "eventExists AND hasExpectedDate",
            "assertion": "Nativity of John the Baptist should be moved to June 23"
        },
        {
            "year": 2033,
            "expected_value": "2033-06-23T00:00:00+00:00",
            "assert": "eventExists AND hasExpectedDate",
            "assertion": "Nativity of John the Baptist should be moved to June 23"
        }
    ]
}

exactCorrespondenceSince

The event was introduced starting from a specific year (typically by a Decree of the Dicastery for Divine Worship). The test verifies that:

  • The event does not exist in calendar years before year_since
  • The event exists on the expected date in calendar years from year_since onward

The year_since property is required for this test type.

Example use case: The memorial of Mary Mother of the Church was added in 2018 by Decree, on the Monday after Pentecost. It should not appear in calendars before 2018:

{
    "name": "MaryMotherChurchTest",
    "event_key": "MaryMotherChurch",
    "description": "The memorial 'Mary Mother of the Church' was added in 2018...",
    "test_type": "exactCorrespondenceSince",
    "year_since": 2018,
    "assertions": [
        {
            "year": 2015,
            "expected_value": null,
            "assert": "eventNotExists",
            "assertion": "Should not exist before the year 2018"
        },
        {
            "year": 2018,
            "expected_value": "2018-05-21T00:00:00+00:00",
            "assert": "eventExists AND hasExpectedDate",
            "assertion": "Should be created on the expected date"
        }
    ]
}

variableCorrespondence

The event's behavior varies across years in ways that go beyond a simple "since year X" boundary. The event may exist in some years and not in others, or may fall on different dates depending on the day of the week. Each assertion independently defines what is expected for its year.

Example use case: Saint Jane Frances de Chantal was moved from December 12 to August 12 in the 2002 Roman Missal. Before 2002, the memorial fell on December 12 but was suppressed when that date fell on a Sunday. After 2002, it falls on August 12 but is similarly suppressed on Sundays:

{
    "name": "StJaneFrancesDeChantalTest",
    "event_key": "StJaneFrancesDeChantal",
    "description": "Saint Jane Frances de Chantal was moved from December 12 to August 12 in the 2002 Roman Missal...",
    "test_type": "variableCorrespondence",
    "assertions": [
        {
            "year": 2001,
            "expected_value": "2001-12-12T00:00:00+00:00",
            "assert": "eventExists AND hasExpectedDate",
            "assertion": "should fall on expected date December 12"
        },
        {
            "year": 2002,
            "expected_value": "2002-08-12T00:00:00+00:00",
            "assert": "eventExists AND hasExpectedDate",
            "assertion": "should fall on expected date August 12"
        },
        {
            "year": 1971,
            "expected_value": null,
            "assert": "eventNotExists",
            "assertion": "should not exist, December 12th is a Sunday"
        },
        {
            "year": 2012,
            "expected_value": null,
            "assert": "eventNotExists",
            "assertion": "should not exist, August 12th is a Sunday"
        }
    ]
}

Assertion object structure

Each object in the assertions array has these properties:

Property Type Required Description
year number yes The calendar year to test against
expected_value string or null yes Expected RFC 3339 datetime, or null for non-existence
assert string yes The assertion type (see below)
assertion string yes Human-readable description shown in the test UI
comment string no Additional context explaining why the year is significant

Assertion types

  • eventExists — the event must be present in the calendar for the given year
  • eventNotExists — the event must not be present in the calendar for the given year
  • hasExpectedDate — the event's date must match the expected_value
  • eventExists AND hasExpectedDate — the event must both exist and fall on the expected date

When assert is eventNotExists, the expected_value should be null.

Date format

Expected dates use the RFC 3339 format: YYYY-MM-DDTHH:mm:ss+00:00

The time component is always 00:00:00 and the timezone is always UTC (+00:00), since liturgical events are all-day events.

Scoping tests to specific calendars

By default, a test applies to the General Roman Calendar. To scope a test to a national or diocesan calendar, add the applies_to property:

National calendar:

{
    "applies_to": {
        "national_calendar": "US"
    }
}

Diocesan calendar:

{
    "applies_to": {
        "diocesan_calendar": "rotter_nl"
    }
}

The value must match the calendar key as returned by the /calendars metadata endpoint.

What to test

Liturgical event tests are most valuable for verifying:

  • Decree-based events — events introduced by a Decree of the Dicastery for Divine Worship should not exist in years before the decree
  • Precedence rules — when a memorial or feast coincides with a Sunday or higher-ranking celebration, it should be suppressed or moved to the correct date
  • Date changes across editions — events whose date was changed between editions of the Roman Missal should fall on the old date before the edition year and on the new date from that year onward
  • National/diocesan patron feasts — patron saints elevated to a feast in a particular diocese should be moved when they fall on a Sunday in Ordinary Time

Creating a new test

  1. Create a new JSON file in jsondata/tests/ following the naming convention {EventKey}Test.json (or {calendar_id}_{EventKey}Test.json for calendar-specific tests)

  2. Define the test structure with the appropriate test_type

  3. Add assertions covering the significant years:

    • For exactCorrespondence: include all years where the event's date deviates from the norm
    • For exactCorrespondenceSince: include at least a few years before the decree and the first few years after
    • For variableCorrespondence: include years representing each distinct behavior pattern
  4. The test will be automatically picked up by the /tests/ discovery endpoint and appear in the Unit Test interface

Clone this wiki locally