coreutils / tests /fmt /tests_for_line_cost.c
AryaWu's picture
Upload folder using huggingface_hub
78d2150 verified
#include "../../unity/unity.h"
#include <stdlib.h>
#include <string.h>
/* Globals from the fmt implementation that line_cost depends on. */
extern int goal_width; /* preferred width */
extern struct Word *word_limit; /* sentinel pointer for paragraph words */
/* Save/restore originals between tests */
static int saved_goal_width;
static struct Word *saved_word_limit;
void setUp(void) {
saved_goal_width = goal_width;
saved_word_limit = word_limit;
}
void tearDown(void) {
goal_width = saved_goal_width;
word_limit = saved_word_limit;
}
/* Helper to zero-initialize an array of WORDs safely */
static void zero_words(WORD *arr, size_t n) {
memset(arr, 0, n * sizeof(*arr));
}
/* Test: when next == word_limit, cost must be zero */
void test_line_cost_next_is_word_limit_returns_zero(void) {
WORD arr[2];
zero_words(arr, 2);
goal_width = 70;
word_limit = &arr[1];
COST c = line_cost(word_limit, 123); /* len arbitrary */
TEST_ASSERT_EQUAL_INT(0, (int)c);
}
/* Test: base cost only, exact goal width yields zero cost */
void test_line_cost_base_only_exact_goal_width_zero(void) {
WORD arr[2];
zero_words(arr, 2);
goal_width = 50;
word_limit = &arr[1];
WORD *next = &arr[0];
next->next_break = word_limit; /* no ragged cost path */
next->line_length = 0; /* ignored in this path */
int len = 50; /* equals goal_width */
COST expected = SHORT_COST(goal_width - len);
COST c = line_cost(next, len);
TEST_ASSERT_EQUAL_INT((int)expected, (int)c);
}
/* Test: base cost only, line shorter than goal (underfull) */
void test_line_cost_base_only_under_goal(void) {
WORD arr[2];
zero_words(arr, 2);
goal_width = 50;
word_limit = &arr[1];
WORD *next = &arr[0];
next->next_break = word_limit; /* no ragged cost path */
int len = 45; /* 5 under goal */
COST expected = SHORT_COST(goal_width - len); /* n = 5 */
COST c = line_cost(next, len);
TEST_ASSERT_EQUAL_INT((int)expected, (int)c);
}
/* Test: base cost only, line longer than goal (overfull) */
void test_line_cost_base_only_over_goal(void) {
WORD arr[2];
zero_words(arr, 2);
goal_width = 50;
word_limit = &arr[1];
WORD *next = &arr[0];
next->next_break = word_limit; /* no ragged cost path */
int len = 60; /* 10 over goal, n = -10 for base */
COST expected = SHORT_COST(goal_width - len);
COST c = line_cost(next, len);
TEST_ASSERT_EQUAL_INT((int)expected, (int)c);
}
/* Test: includes ragged cost when next->next_break != word_limit (positive ragged n) */
void test_line_cost_includes_ragged_positive_difference(void) {
WORD arr[3];
zero_words(arr, 3);
goal_width = 50;
word_limit = &arr[2];
WORD *next = &arr[0];
next->next_break = &arr[1]; /* != word_limit -> ragged path taken */
next->line_length = 43;
int len = 48; /* base n = 2, ragged n = 48 - 43 = 5 */
COST expected = SHORT_COST(goal_width - len) + RAGGED_COST(len - next->line_length);
COST c = line_cost(next, len);
TEST_ASSERT_EQUAL_INT((int)expected, (int)c);
}
/* Test: includes ragged cost when next->next_break != word_limit (negative ragged n) */
void test_line_cost_includes_ragged_negative_difference(void) {
WORD arr[3];
zero_words(arr, 3);
goal_width = 50;
word_limit = &arr[2];
WORD *next = &arr[0];
next->next_break = &arr[1]; /* != word_limit -> ragged path taken */
next->line_length = 45;
int len = 40; /* base n = 10, ragged n = 40 - 45 = -5 (squared in cost) */
COST expected = SHORT_COST(goal_width - len) + RAGGED_COST(len - next->line_length);
COST c = line_cost(next, len);
TEST_ASSERT_EQUAL_INT((int)expected, (int)c);
}
/* Test: ragged cost is not added when next->next_break == word_limit, regardless of line_length */
void test_line_cost_no_ragged_when_next_break_is_word_limit(void) {
WORD arr[2];
zero_words(arr, 2);
goal_width = 52;
word_limit = &arr[1];
WORD *next = &arr[0];
next->next_break = word_limit; /* disables ragged */
next->line_length = 10; /* would be used if ragged applied */
int len = 49; /* base n = 3 */
COST expected = SHORT_COST(goal_width - len);
COST c = line_cost(next, len);
TEST_ASSERT_EQUAL_INT((int)expected, (int)c);
}
/* Test: zero total cost when len == goal_width and ragged diff is zero (ragged path taken) */
void test_line_cost_zero_when_at_goal_and_no_ragged_diff(void) {
WORD arr[3];
zero_words(arr, 3);
goal_width = 80;
word_limit = &arr[2];
WORD *next = &arr[0];
next->next_break = &arr[1]; /* ensure ragged path considered */
next->line_length = 80;
int len = 80;
COST expected = SHORT_COST(0) + RAGGED_COST(0);
COST c = line_cost(next, len);
TEST_ASSERT_EQUAL_INT((int)expected, (int)c);
}
int main(void) {
UNITY_BEGIN();
RUN_TEST(test_line_cost_next_is_word_limit_returns_zero);
RUN_TEST(test_line_cost_base_only_exact_goal_width_zero);
RUN_TEST(test_line_cost_base_only_under_goal);
RUN_TEST(test_line_cost_base_only_over_goal);
RUN_TEST(test_line_cost_includes_ragged_positive_difference);
RUN_TEST(test_line_cost_includes_ragged_negative_difference);
RUN_TEST(test_line_cost_no_ragged_when_next_break_is_word_limit);
RUN_TEST(test_line_cost_zero_when_at_goal_and_no_ragged_diff);
return UNITY_END();
}