coreutils / tests /fmt /tests_for_get_paragraph.c
AryaWu's picture
Upload folder using huggingface_hub
78d2150 verified
#include "../../unity/unity.h"
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
/* We rely on being included after the fmt implementation, so we can
access static functions and globals like get_paragraph, set_prefix,
get_prefix, word, word_limit, etc. */
/* Helper: persistent buffer for set_prefix. */
static char prefix_buf[64];
/* Reset core global state to a known baseline before each test. */
static void reset_state(void)
{
/* Options */
crown = false;
tagged = false;
split = false;
uniform = false;
/* Prefix: empty */
strcpy(prefix_buf, "");
set_prefix(prefix_buf);
/* Widths: defaults safe; fmt_paragraph isn't called by get_paragraph,
but keep sane values anyway. */
max_width = 75; /* WIDTH */
goal_width = (max_width * (100 - 7)) / 100; /* LEEWAY = 7 */
/* Dynamic state */
in_column = 0;
out_column = 0;
tabs = false;
prefix_indent = 0;
first_indent = 0;
other_indent = 0;
next_char = 0;
next_prefix_indent = 0;
last_line_length = 0;
/* Paragraph buffers */
wptr = parabuf;
word_limit = word;
}
/* Helper: create a FILE* from a string using tmpfile. */
static FILE *make_file(const char *s)
{
FILE *f = tmpfile();
TEST_ASSERT_NOT_NULL_MESSAGE(f, "tmpfile() failed");
if (fputs(s, f) == EOF)
{
fclose(f);
TEST_FAIL_MESSAGE("fputs() to tmpfile failed");
}
rewind(f);
return f;
}
/* Count words currently parsed for the paragraph. */
static int count_words(void)
{
return (int)(word_limit - word);
}
void setUp(void)
{
/* Setup code here */
reset_state();
}
void tearDown(void)
{
/* Cleanup code here */
}
/* 1) Basic: single-line paragraph, no prefix, default mode */
static void test_get_paragraph_basic_single_line(void)
{
const char *input = "hello world\n\n"; /* paragraph then blank line */
FILE *f = make_file(input);
/* Initialize next_char as fmt() would */
next_char = get_prefix(f);
TEST_ASSERT_TRUE_MESSAGE(get_paragraph(f), "get_paragraph should find a paragraph");
/* Should have parsed two words: hello, world */
TEST_ASSERT_EQUAL_INT(2, count_words());
/* Indentation expectations */
TEST_ASSERT_EQUAL_INT(0, prefix_indent);
TEST_ASSERT_EQUAL_INT(0, first_indent);
TEST_ASSERT_EQUAL_INT(0, other_indent);
/* Words content and flags */
TEST_ASSERT_EQUAL_INT(5, word[0].length);
TEST_ASSERT_TRUE(!word[0].final);
TEST_ASSERT_TRUE(word_limit[-1].final);
TEST_ASSERT_TRUE(word_limit[-1].period); /* get_paragraph forces last word period=true */
/* After paragraph, next_char should be '\n' for the following blank line */
TEST_ASSERT_EQUAL_INT('\n', next_char);
fclose(f);
}
/* 2) Crown mode: second+ lines must have same indent as second line */
static void test_get_paragraph_crown_mode(void)
{
crown = true;
const char *input =
"one\n"
" two words\n"
" three\n"
" four\n"; /* fourth line different indent -> next paragraph */
FILE *f = make_file(input);
next_char = get_prefix(f);
TEST_ASSERT_TRUE_MESSAGE(get_paragraph(f), "crown: should read a paragraph");
/* First three lines included: 1 + 2 + 1 = 4 words */
TEST_ASSERT_EQUAL_INT(4, count_words());
/* First line indent 0, secondary indent equals second line's indent (2). */
TEST_ASSERT_EQUAL_INT(0, first_indent);
TEST_ASSERT_EQUAL_INT(2, other_indent);
/* Next char should be 'f' from " four" */
TEST_ASSERT_EQUAL_INT('f', next_char);
/* Last word of the paragraph is final and period-marked by get_paragraph */
TEST_ASSERT_TRUE(word_limit[-1].final);
TEST_ASSERT_TRUE(word_limit[-1].period);
fclose(f);
}
/* 3) Tagged mode: first and second lines must have different indents.
If equal, paragraph is just the first line, and other_indent updated. */
static void test_get_paragraph_tagged_mode_requires_diff_indent(void)
{
tagged = true;
const char *input =
"first\n"
"second\n"; /* same indent (0), so only first line included */
FILE *f = make_file(input);
next_char = get_prefix(f);
TEST_ASSERT_TRUE_MESSAGE(get_paragraph(f), "tagged: should read a paragraph");
/* Only the first line included: 1 word */
TEST_ASSERT_EQUAL_INT(1, count_words());
/* First indent 0; other_indent should become DEF_INDENT when identical */
TEST_ASSERT_EQUAL_INT(0, first_indent);
TEST_ASSERT_EQUAL_INT(DEF_INDENT, other_indent);
/* Next paragraph starts at 's' from second line */
TEST_ASSERT_EQUAL_INT('s', next_char);
fclose(f);
}
/* 4) Split-only mode: a paragraph is a single non-blank line */
static void test_get_paragraph_split_only_single_line(void)
{
split = true;
const char *input =
"aaa bbb\n"
"ccc ddd\n";
FILE *f = make_file(input);
next_char = get_prefix(f);
TEST_ASSERT_TRUE_MESSAGE(get_paragraph(f), "split: should read a single-line paragraph");
/* Only first line included: 2 words */
TEST_ASSERT_EQUAL_INT(2, count_words());
/* other_indent must equal first_indent in split mode */
TEST_ASSERT_EQUAL_INT(first_indent, other_indent);
/* Next char should be 'c' from second line */
TEST_ASSERT_EQUAL_INT('c', next_char);
fclose(f);
}
/* 5) Prefix handling: lines must begin with the prefix; words exclude the prefix. */
static void test_get_paragraph_with_prefix_included_lines(void)
{
/* Set a non-empty prefix ">>" */
strcpy(prefix_buf, ">>");
set_prefix(prefix_buf);
const char *input =
">> a b\n"
">> c\n";
FILE *f = make_file(input);
next_char = get_prefix(f);
TEST_ASSERT_TRUE_MESSAGE(get_paragraph(f), "prefix: should read a paragraph with prefixed lines");
/* Words from after the prefix should be captured: a, b, c */
TEST_ASSERT_EQUAL_INT(3, count_words());
/* The first word should be 'a' */
TEST_ASSERT_EQUAL_INT(1, word[0].length);
TEST_ASSERT_EQUAL_CHAR('a', word[0].text[0]);
/* prefix_indent should be 0 given no leading spaces before prefix */
TEST_ASSERT_EQUAL_INT(0, prefix_indent);
/* Next char should be EOF (end of file) */
TEST_ASSERT_EQUAL_INT(EOF, next_char);
/* Last word flags */
TEST_ASSERT_TRUE(word_limit[-1].final);
TEST_ASSERT_TRUE(word_limit[-1].period);
fclose(f);
}
/* 6) EOF before any paragraph: should return false and not touch buffers */
static void test_get_paragraph_empty_file_returns_false(void)
{
const char *input = ""; /* empty file */
FILE *f = make_file(input);
next_char = get_prefix(f); /* sets to EOF */
TEST_ASSERT_FALSE_MESSAGE(get_paragraph(f), "Empty file: should return false");
fclose(f);
}
int main(void)
{
UNITY_BEGIN();
RUN_TEST(test_get_paragraph_basic_single_line);
RUN_TEST(test_get_paragraph_crown_mode);
RUN_TEST(test_get_paragraph_tagged_mode_requires_diff_indent);
RUN_TEST(test_get_paragraph_split_only_single_line);
RUN_TEST(test_get_paragraph_with_prefix_included_lines);
RUN_TEST(test_get_paragraph_empty_file_returns_false);
return UNITY_END();
}