#include "../../unity/unity.h" #include #include #include #include /* Unity setup/teardown */ void setUp(void) { /* Reset key globals to a known state before each test */ in_column = 0; tabs = false; } void tearDown(void) { /* Nothing to cleanup */ } /* Helper to create a tmp file with content s, rewound for reading */ static FILE* make_tmp_with(const char* s) { FILE* f = tmpfile(); TEST_ASSERT_NOT_NULL(f); if (s && *s) { size_t len = strlen(s); TEST_ASSERT_EQUAL_size_t(len, fwrite(s, 1, len, f)); } rewind(f); return f; } /* 1) Non-blank initial character: should return c, not change in_column or tabs, and not consume further. */ static void test_get_space_nonblank_initial(void) { FILE* f = make_tmp_with("A"); int first = getc(f); TEST_ASSERT_EQUAL_INT('A', first); in_column = 5; tabs = false; int r = get_space(f, first); TEST_ASSERT_EQUAL_INT('A', r); TEST_ASSERT_EQUAL_INT(5, in_column); TEST_ASSERT_FALSE(tabs); /* Next char should be EOF because only 'A' was present and already consumed before call */ int next = getc(f); TEST_ASSERT_EQUAL_INT(EOF, next); fclose(f); } /* 2) Spaces then non-blank: should consume spaces, update in_column, return first non-blank, and consume it. */ static void test_get_space_spaces_then_nonblank(void) { FILE* f = make_tmp_with(" XZ"); /* 4 spaces, 'X', 'Z' */ int first = getc(f); TEST_ASSERT_EQUAL_INT(' ', first); in_column = 0; tabs = false; int r = get_space(f, first); TEST_ASSERT_EQUAL_INT('X', r); TEST_ASSERT_EQUAL_INT(4, in_column); TEST_ASSERT_FALSE(tabs); /* X has been consumed by get_space; next should be 'Z' */ int next = getc(f); TEST_ASSERT_EQUAL_INT('Z', next); fclose(f); } /* 3) Tabs and spaces mixed with non-zero initial in_column: verify tab stops and tabs flag. */ static void test_get_space_tabs_and_spaces_mixed_initial_incol(void) { FILE* f = make_tmp_with("\t\t XZ"); /* tab, tab, space, space, 'X', 'Z' */ int first = getc(f); TEST_ASSERT_EQUAL_INT('\t', first); in_column = 3; /* Start not on tab stop */ tabs = false; int r = get_space(f, first); TEST_ASSERT_EQUAL_INT('X', r); /* Computation: start 3 '\t' -> 8 '\t' -> 16 ' ' -> 17 ' ' -> 18 */ TEST_ASSERT_EQUAL_INT(18, in_column); TEST_ASSERT_TRUE(tabs); /* 'X' consumed; next should be 'Z' */ int next = getc(f); TEST_ASSERT_EQUAL_INT('Z', next); fclose(f); } /* 4) Only spaces to EOF: should return EOF and update in_column accordingly, tabs remains false. */ static void test_get_space_only_spaces_to_eof(void) { FILE* f = make_tmp_with(" "); /* three spaces, then EOF */ int first = getc(f); TEST_ASSERT_EQUAL_INT(' ', first); in_column = 10; tabs = false; int r = get_space(f, first); TEST_ASSERT_EQUAL_INT(EOF, r); TEST_ASSERT_EQUAL_INT(13, in_column); TEST_ASSERT_FALSE(tabs); /* Stream should now be at EOF */ int next = getc(f); TEST_ASSERT_EQUAL_INT(EOF, next); fclose(f); } /* 5) Initial EOF: should return EOF without changing state or reading. */ static void test_get_space_initial_eof(void) { FILE* f = make_tmp_with(""); /* empty file */ in_column = 7; tabs = false; int r = get_space(f, EOF); TEST_ASSERT_EQUAL_INT(EOF, r); TEST_ASSERT_EQUAL_INT(7, in_column); TEST_ASSERT_FALSE(tabs); int next = getc(f); TEST_ASSERT_EQUAL_INT(EOF, next); fclose(f); } /* 6) Newline treated as non-blank: should return '\n' immediately, no changes to in_column or tabs. */ static void test_get_space_newline_nonblank(void) { FILE* f = make_tmp_with("\nA"); int first = getc(f); TEST_ASSERT_EQUAL_INT('\n', first); in_column = 2; tabs = false; int r = get_space(f, first); TEST_ASSERT_EQUAL_INT('\n', r); TEST_ASSERT_EQUAL_INT(2, in_column); TEST_ASSERT_FALSE(tabs); int next = getc(f); TEST_ASSERT_EQUAL_INT('A', next); fclose(f); } /* 7) Tab when at a tab stop boundary: should advance to next tab stop correctly. */ static void test_get_space_tab_at_tabstop(void) { FILE* f = make_tmp_with("\tY"); int first = getc(f); TEST_ASSERT_EQUAL_INT('\t', first); in_column = 8; /* at a tab stop already */ tabs = false; int r = get_space(f, first); TEST_ASSERT_EQUAL_INT('Y', r); TEST_ASSERT_EQUAL_INT(16, in_column); TEST_ASSERT_TRUE(tabs); int next = getc(f); TEST_ASSERT_EQUAL_INT(EOF, next); /* after 'Y', file ends */ fclose(f); } int main(void) { UNITY_BEGIN(); RUN_TEST(test_get_space_nonblank_initial); RUN_TEST(test_get_space_spaces_then_nonblank); RUN_TEST(test_get_space_tabs_and_spaces_mixed_initial_incol); RUN_TEST(test_get_space_only_spaces_to_eof); RUN_TEST(test_get_space_initial_eof); RUN_TEST(test_get_space_newline_nonblank); RUN_TEST(test_get_space_tab_at_tabstop); return UNITY_END(); }