Give the interpreter real Celtic Cross meanings and --format/--lang support
- guidance.c now prints last, after the full spread; both it and main.c's new Celtic Cross readout pull real Waite card meanings via tarot_data.c instead of just naming cards. - interpreter-cli gains --format text|html|json and --lang en|de, matching deck-engine - required linking engine/src/tarot_data.c and i18n.c into the interpreter binary (a narrow, documented exception to its earlier "no engine .c files" policy) and writing German translations for narrative.c's/guidance.c's own text.
This commit is contained in:
@@ -41,11 +41,11 @@ static void test_json_parse_rejects_malformed(void) {
|
||||
}
|
||||
|
||||
/* A trimmed-but-structurally-faithful fixture matching deck-engine's real
|
||||
* --format json shape: "spread" is present with decoy content the loader
|
||||
* must skip over without understanding its schema, to prove it navigates
|
||||
* by key path rather than assuming any position. "natal"/"transits"
|
||||
* bodies are real (if partial) - reading_load_json now parses sign/house
|
||||
* from them for display, alongside the aspects used for scoring. */
|
||||
* --format json shape. "natal"/"transits" bodies are real (if partial) -
|
||||
* reading_load_json parses sign/house from them for display, alongside
|
||||
* the aspects used for scoring. "spread" only fills in the Attitude and
|
||||
* Outcome positions (the two guidance.c reads); the other eight are
|
||||
* absent entirely, to prove partial spread data doesn't fail the load. */
|
||||
static const char *k_fixture =
|
||||
"{"
|
||||
" \"natal\": {\"bodies\": [{\"body\": \"sun\", \"sign\": \"taurus\", \"house\": 3}], \"houses\": []},"
|
||||
@@ -57,7 +57,10 @@ static const char *k_fixture =
|
||||
" {\"transiting_planet\": \"saturn\", \"natal_planet\": \"sun\", \"type\": \"square\", \"orb\": 0.5}"
|
||||
" ]"
|
||||
" },"
|
||||
" \"spread\": {\"positions\": [{\"position\": \"present\", \"card\": \"devil\", \"reversed\": false}]}"
|
||||
" \"spread\": {\"positions\": ["
|
||||
" {\"position\": \"attitude\", \"card\": \"devil\", \"reversed\": true},"
|
||||
" {\"position\": \"outcome\", \"card\": \"world\", \"reversed\": false}"
|
||||
" ]}"
|
||||
"}";
|
||||
|
||||
static void test_reading_load_json_extracts_aspects(void) {
|
||||
@@ -95,6 +98,35 @@ static void test_reading_load_json_extracts_body_sign_and_house(void) {
|
||||
printf("PASS test_reading_load_json_extracts_body_sign_and_house\n");
|
||||
}
|
||||
|
||||
static void test_reading_load_json_extracts_spread_positions(void) {
|
||||
DailyReading reading;
|
||||
bool ok = reading_load_json(k_fixture, strlen(k_fixture), &reading);
|
||||
|
||||
assert(ok);
|
||||
assert(reading.spread.positions[POSITION_ATTITUDE].card == CARD_DEVIL);
|
||||
assert(reading.spread.positions[POSITION_ATTITUDE].reversed == true);
|
||||
assert(reading.spread.positions[POSITION_OUTCOME].card == CARD_WORLD);
|
||||
assert(reading.spread.positions[POSITION_OUTCOME].reversed == false);
|
||||
|
||||
/* Positions absent from the fixture (e.g. Present) get the zeroed
|
||||
* default (CARD_FOOL, upright) rather than garbage. */
|
||||
assert(reading.spread.positions[POSITION_PRESENT].card == CARD_FOOL);
|
||||
assert(reading.spread.positions[POSITION_PRESENT].reversed == false);
|
||||
|
||||
printf("PASS test_reading_load_json_extracts_spread_positions\n");
|
||||
}
|
||||
|
||||
static void test_reading_load_json_missing_spread_is_not_fatal(void) {
|
||||
const char *text = "{\"transits\": {\"aspects\": []}}";
|
||||
DailyReading reading;
|
||||
bool ok = reading_load_json(text, strlen(text), &reading);
|
||||
|
||||
assert(ok);
|
||||
assert(reading.spread.positions[POSITION_OUTCOME].card == CARD_FOOL);
|
||||
|
||||
printf("PASS test_reading_load_json_missing_spread_is_not_fatal\n");
|
||||
}
|
||||
|
||||
static void test_reading_load_json_unknown_body_slug_is_skipped_not_fatal(void) {
|
||||
const char *text =
|
||||
"{\"natal\": {\"bodies\": [{\"body\": \"xenu\", \"sign\": \"taurus\", \"house\": 3}]},"
|
||||
@@ -147,6 +179,8 @@ int main(void) {
|
||||
test_json_parse_rejects_malformed();
|
||||
test_reading_load_json_extracts_aspects();
|
||||
test_reading_load_json_extracts_body_sign_and_house();
|
||||
test_reading_load_json_extracts_spread_positions();
|
||||
test_reading_load_json_missing_spread_is_not_fatal();
|
||||
test_reading_load_json_unknown_body_slug_is_skipped_not_fatal();
|
||||
test_reading_load_json_empty_aspects_is_valid();
|
||||
test_reading_load_json_rejects_missing_transits();
|
||||
|
||||
Reference in New Issue
Block a user