-
-
Notifications
You must be signed in to change notification settings - Fork 33
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.
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.
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).
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) |
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"
}
]
}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_sinceonward
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"
}
]
}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"
}
]
}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 |
-
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 theexpected_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.
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.
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.
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
-
Create a new JSON file in
jsondata/tests/following the naming convention{EventKey}Test.json(or{calendar_id}_{EventKey}Test.jsonfor calendar-specific tests) -
Define the test structure with the appropriate
test_type -
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
- For
-
The test will be automatically picked up by the
/tests/discovery endpoint and appear in the Unit Test interface
For Users
For Webmasters
For Liturgists
For Developers
For Contributors
Testing
Authentication & RBAC