#include "../../unity/unity.h" #include #include /* Access to: - static WORD word[MAXWORDS]; - static COST base_cost (WORD *this); - Macros: LINE_COST, SENTENCE_BONUS, NOBREAK_COST, PUNCT_BONUS, PAREN_BONUS, ORPHAN_COST, WIDOW_COST are available because this test file is included into the same TU. */ static void reset_words(void) { memset(word, 0, sizeof(word)); } void setUp(void) { reset_words(); } void tearDown(void) { /* nothing */ } /* Helper to initialize a specific word entry. */ static void init_word(int idx, int length, bool paren, bool period, bool punct, bool final_flag) { word[idx].length = length; word[idx].paren = paren ? 1u : 0u; word[idx].period = period ? 1u : 0u; word[idx].punct = punct ? 1u : 0u; word[idx].final = final_flag ? 1u : 0u; } /* 1) First word, neither paren nor final: cost should be just LINE_COST. */ void test_base_cost_first_word_plain(void) { init_word(0, 5, false, false, false, false); COST actual = base_cost(&word[0]); COST expected = LINE_COST; TEST_ASSERT_EQUAL_INT((int)expected, (int)actual); } /* 2) First word, paren true: subtract PAREN_BONUS. (Paren takes precedence over orphan.) */ void test_base_cost_first_word_paren_bonus(void) { init_word(0, 6, true, false, false, false); COST actual = base_cost(&word[0]); COST expected = LINE_COST - PAREN_BONUS; TEST_ASSERT_EQUAL_INT((int)expected, (int)actual); } /* 3) First word, not paren, final true: add ORPHAN_COST(length). */ void test_base_cost_first_word_orphan_cost(void) { int len = 7; init_word(0, len, false, false, false, true); COST actual = base_cost(&word[0]); COST expected = LINE_COST + ORPHAN_COST(len); TEST_ASSERT_EQUAL_INT((int)expected, (int)actual); } /* 4) Second word: previous has period and is final => subtract SENTENCE_BONUS. */ void test_base_cost_prev_period_and_final_sentence_bonus(void) { init_word(0, 3, false, true, false, true); /* previous: ends a sentence */ init_word(1, 4, false, false, false, false); /* this */ COST actual = base_cost(&word[1]); COST expected = LINE_COST - SENTENCE_BONUS; TEST_ASSERT_EQUAL_INT((int)expected, (int)actual); } /* 5) Second word: previous has period but not final => add NOBREAK_COST. */ void test_base_cost_prev_period_not_final_nobreak_penalty(void) { init_word(0, 3, false, true, false, false); /* period but not sentence end */ init_word(1, 4, false, false, false, false); /* this */ COST actual = base_cost(&word[1]); COST expected = LINE_COST + NOBREAK_COST; TEST_ASSERT_EQUAL_INT((int)expected, (int)actual); } /* 6) Second word: previous punctuation (but not period) => subtract PUNCT_BONUS. */ void test_base_cost_prev_punct_bonus(void) { init_word(0, 3, false, false, true, false); /* punct but not period */ init_word(1, 5, false, false, false, false); /* this */ COST actual = base_cost(&word[1]); COST expected = LINE_COST - PUNCT_BONUS; TEST_ASSERT_EQUAL_INT((int)expected, (int)actual); } /* 7) Third word: widow scenario => (this > word+1) and (this-2)->final true; add WIDOW_COST(length of previous). */ void test_base_cost_widow_cost_third_word_after_sentence_start(void) { int prev_len = 8; init_word(0, 2, false, false, false, true); /* word[0] ends a sentence */ init_word(1, prev_len, false, false, false, false); /* first word of new sentence, no punct/period */ init_word(2, 4, false, false, false, false); /* this */ COST actual = base_cost(&word[2]); COST expected = LINE_COST + WIDOW_COST(prev_len); TEST_ASSERT_EQUAL_INT((int)expected, (int)actual); } /* 8) Combination: previous period+final and this has paren => subtract both SENTENCE_BONUS and PAREN_BONUS. */ void test_base_cost_sentence_bonus_plus_paren_bonus_combined(void) { init_word(0, 3, false, true, false, true); /* previous ends a sentence */ init_word(1, 5, true, false, false, false); /* this has paren */ COST actual = base_cost(&word[1]); COST expected = LINE_COST - SENTENCE_BONUS - PAREN_BONUS; TEST_ASSERT_EQUAL_INT((int)expected, (int)actual); } /* 9) Paren overrides orphan: if this has paren and final, only PAREN_BONUS applies, no ORPHAN_COST. */ void test_base_cost_paren_overrides_orphan(void) { int len = 10; init_word(0, 1, false, false, false, false); /* irrelevant */ init_word(1, len, true, false, false, true); /* paren and final */ COST actual = base_cost(&word[1]); COST expected = LINE_COST - PAREN_BONUS; /* no +ORPHAN since paren takes precedence */ TEST_ASSERT_EQUAL_INT((int)expected, (int)actual); } /* 10) Combination: previous punctuation (not period) and this is final => subtract PUNCT_BONUS and add ORPHAN_COST. */ void test_base_cost_prev_punct_and_this_final_combined(void) { int len = 4; init_word(0, 3, false, false, true, false); /* prev punct (not period) */ init_word(1, len, false, false, false, true); /* this is final (not paren) */ COST actual = base_cost(&word[1]); COST expected = LINE_COST - PUNCT_BONUS + ORPHAN_COST(len); TEST_ASSERT_EQUAL_INT((int)expected, (int)actual); } int main(void) { UNITY_BEGIN(); RUN_TEST(test_base_cost_first_word_plain); RUN_TEST(test_base_cost_first_word_paren_bonus); RUN_TEST(test_base_cost_first_word_orphan_cost); RUN_TEST(test_base_cost_prev_period_and_final_sentence_bonus); RUN_TEST(test_base_cost_prev_period_not_final_nobreak_penalty); RUN_TEST(test_base_cost_prev_punct_bonus); RUN_TEST(test_base_cost_widow_cost_third_word_after_sentence_start); RUN_TEST(test_base_cost_sentence_bonus_plus_paren_bonus_combined); RUN_TEST(test_base_cost_paren_overrides_orphan); RUN_TEST(test_base_cost_prev_punct_and_this_final_combined); return UNITY_END(); }