| #include "../../unity/unity.h" |
| #include <stdio.h> |
| #include <stdlib.h> |
| #include <string.h> |
|
|
| |
| void setUp(void) { |
| |
| |
| check_input_order = CHECK_ORDER_DISABLED; |
| |
| seen_unpairable = false; |
| } |
|
|
| void tearDown(void) { |
| |
| free_spareline(); |
| } |
|
|
| |
| static FILE* make_tempfile_with(const char* content) { |
| FILE *fp = tmpfile(); |
| TEST_ASSERT_NOT_NULL_MESSAGE(fp, "tmpfile() failed"); |
| if (content && *content) { |
| size_t len = strlen(content); |
| TEST_ASSERT_EQUAL_MESSAGE(len, fwrite(content, 1, len, fp), |
| "Failed to write content to tmp file"); |
| } |
| fflush(fp); |
| rewind(fp); |
| return fp; |
| } |
|
|
| |
| static void assert_field_equals(const struct field *f, const char *s) { |
| size_t slen = strlen(s); |
| TEST_ASSERT_EQUAL_size_t(slen, (size_t)f->len); |
| if (slen > 0) { |
| TEST_ASSERT_NOT_NULL(f->beg); |
| TEST_ASSERT_EQUAL_INT(0, memcmp(f->beg, s, slen)); |
| } |
| } |
|
|
| |
| void test_getseq_reads_single_line_and_fields(void) { |
| FILE *fp = make_tempfile_with("a b c\n"); |
|
|
| struct seq s; |
| initseq(&s); |
|
|
| bool ok = getseq(fp, &s, 1); |
| TEST_ASSERT_TRUE(ok); |
| TEST_ASSERT_TRUE(s.count == 1); |
| TEST_ASSERT_NOT_NULL(s.lines); |
| TEST_ASSERT_TRUE(s.alloc >= 1); |
| TEST_ASSERT_NOT_NULL(s.lines[0]); |
|
|
| struct line *l = s.lines[0]; |
| TEST_ASSERT_NOT_NULL(l); |
| TEST_ASSERT_TRUE(l->nfields == 3); |
|
|
| TEST_ASSERT_NOT_NULL(l->fields); |
| assert_field_equals(&l->fields[0], "a"); |
| assert_field_equals(&l->fields[1], "b"); |
| assert_field_equals(&l->fields[2], "c"); |
|
|
| delseq(&s); |
| fclose(fp); |
| } |
|
|
| |
| void test_getseq_returns_false_on_empty_file(void) { |
| FILE *fp = make_tempfile_with(""); |
|
|
| struct seq s; |
| initseq(&s); |
|
|
| bool ok = getseq(fp, &s, 1); |
| TEST_ASSERT_FALSE(ok); |
| TEST_ASSERT_TRUE(s.count == 0); |
| |
| TEST_ASSERT_NOT_NULL(s.lines); |
| TEST_ASSERT_TRUE(s.alloc >= 1); |
| TEST_ASSERT_NULL(s.lines[0]); |
|
|
| delseq(&s); |
| fclose(fp); |
| } |
|
|
| |
| void test_getseq_reads_multiple_lines(void) { |
| FILE *fp = make_tempfile_with("x\ny\nz\n"); |
|
|
| struct seq s; |
| initseq(&s); |
|
|
| bool ok1 = getseq(fp, &s, 1); |
| TEST_ASSERT_TRUE(ok1); |
| TEST_ASSERT_TRUE(s.count == 1); |
| TEST_ASSERT_NOT_NULL(s.lines[0]); |
| TEST_ASSERT_TRUE(s.lines[0]->nfields == 1); |
| assert_field_equals(&s.lines[0]->fields[0], "x"); |
|
|
| bool ok2 = getseq(fp, &s, 1); |
| TEST_ASSERT_TRUE(ok2); |
| TEST_ASSERT_TRUE(s.count == 2); |
| TEST_ASSERT_NOT_NULL(s.lines[1]); |
| TEST_ASSERT_TRUE(s.lines[1]->nfields == 1); |
| assert_field_equals(&s.lines[1]->fields[0], "y"); |
|
|
| bool ok3 = getseq(fp, &s, 1); |
| TEST_ASSERT_TRUE(ok3); |
| TEST_ASSERT_TRUE(s.count == 3); |
| TEST_ASSERT_NOT_NULL(s.lines[2]); |
| TEST_ASSERT_TRUE(s.lines[2]->nfields == 1); |
| assert_field_equals(&s.lines[2]->fields[0], "z"); |
|
|
| |
| bool ok4 = getseq(fp, &s, 1); |
| TEST_ASSERT_FALSE(ok4); |
| TEST_ASSERT_TRUE(s.count == 3); |
|
|
| delseq(&s); |
| fclose(fp); |
| } |
|
|
| |
| void test_getseq_works_for_both_files(void) { |
| FILE *fp1 = make_tempfile_with("a\nb\n"); |
| FILE *fp2 = make_tempfile_with("c\nd\n"); |
|
|
| struct seq s1, s2; |
| initseq(&s1); |
| initseq(&s2); |
|
|
| |
| TEST_ASSERT_TRUE(getseq(fp1, &s1, 1)); |
| TEST_ASSERT_TRUE(s1.count == 1); |
| TEST_ASSERT_TRUE(s1.lines[0]->nfields == 1); |
| assert_field_equals(&s1.lines[0]->fields[0], "a"); |
|
|
| |
| TEST_ASSERT_TRUE(getseq(fp2, &s2, 2)); |
| TEST_ASSERT_TRUE(s2.count == 1); |
| TEST_ASSERT_TRUE(s2.lines[0]->nfields == 1); |
| assert_field_equals(&s2.lines[0]->fields[0], "c"); |
|
|
| |
| TEST_ASSERT_TRUE(getseq(fp1, &s1, 1)); |
| TEST_ASSERT_TRUE(s1.count == 2); |
| assert_field_equals(&s1.lines[1]->fields[0], "b"); |
|
|
| TEST_ASSERT_TRUE(getseq(fp2, &s2, 2)); |
| TEST_ASSERT_TRUE(s2.count == 2); |
| assert_field_equals(&s2.lines[1]->fields[0], "d"); |
|
|
| |
| TEST_ASSERT_FALSE(getseq(fp1, &s1, 1)); |
| TEST_ASSERT_FALSE(getseq(fp2, &s2, 2)); |
|
|
| delseq(&s1); |
| delseq(&s2); |
| fclose(fp1); |
| fclose(fp2); |
| } |
|
|
| |
| void test_getseq_handles_line_without_trailing_newline(void) { |
| FILE *fp = make_tempfile_with("no-trailing-newline"); |
|
|
| struct seq s; |
| initseq(&s); |
|
|
| TEST_ASSERT_TRUE(getseq(fp, &s, 1)); |
| TEST_ASSERT_TRUE(s.count == 1); |
| TEST_ASSERT_NOT_NULL(s.lines[0]); |
| TEST_ASSERT_TRUE(s.lines[0]->nfields == 1); |
| assert_field_equals(&s.lines[0]->fields[0], "no-trailing-newline"); |
|
|
| |
| TEST_ASSERT_FALSE(getseq(fp, &s, 1)); |
|
|
| delseq(&s); |
| fclose(fp); |
| } |
|
|
| int main(void) { |
| UNITY_BEGIN(); |
| RUN_TEST(test_getseq_reads_single_line_and_fields); |
| RUN_TEST(test_getseq_returns_false_on_empty_file); |
| RUN_TEST(test_getseq_reads_multiple_lines); |
| RUN_TEST(test_getseq_works_for_both_files); |
| RUN_TEST(test_getseq_handles_line_without_trailing_newline); |
| return UNITY_END(); |
| } |