static void test_bigend_u64(TestBatch *batch) { size_t count = 32; uint64_t *ints = TestUtils_random_u64s(NULL, count, 0, U64_MAX); size_t amount = (count + 1) * sizeof(uint64_t); char *allocated = (char*)CALLOCATE(amount, sizeof(char)); char *encoded = allocated + 1; // Intentionally misaligned. char *target = encoded; for (size_t i = 0; i < count; i++) { NumUtil_encode_bigend_u64(ints[i], &target); target += sizeof(uint64_t); } target = encoded; for (size_t i = 0; i < count; i++) { uint64_t got = NumUtil_decode_bigend_u64(target); TEST_TRUE(batch, got == ints[i], "bigend u64"); target += sizeof(uint64_t); } target = encoded; NumUtil_encode_bigend_u64(1, &target); TEST_INT_EQ(batch, encoded[0], 0, "Truly big-endian"); TEST_INT_EQ(batch, encoded[7], 1, "Truly big-endian"); FREEMEM(allocated); FREEMEM(ints); }
static void test_Contains_and_Find(TestBatchRunner *runner) { String *string; String *substring = S_get_str("foo"); string = S_get_str(""); TEST_FALSE(runner, Str_Contains(string, substring), "Not contained in empty string"); TEST_INT_EQ(runner, S_find(string, substring), -1, "Not found in empty string"); DECREF(string); string = S_get_str("foo"); TEST_TRUE(runner, Str_Contains(string, substring), "Contained in complete string"); TEST_INT_EQ(runner, S_find(string, substring), 0, "Find complete string"); DECREF(string); string = S_get_str("afoo"); TEST_TRUE(runner, Str_Contains(string, substring), "Contained after first"); TEST_INT_EQ(runner, S_find(string, substring), 1, "Find after first"); String *prefix = Str_SubString(string, 0, 3); TEST_FALSE(runner, Str_Contains(prefix, substring), "Don't overrun"); DECREF(prefix); DECREF(string); string = S_get_str("afood"); TEST_TRUE(runner, Str_Contains(string, substring), "Contained in middle"); TEST_INT_EQ(runner, S_find(string, substring), 1, "Find in middle"); DECREF(string); DECREF(substring); }
static void test_Equals(TestBatchRunner *runner) { ByteBuf *wanted = BB_new_bytes("foo", 4); // Include terminating NULL. ByteBuf *got = BB_new_bytes("foo", 4); TEST_TRUE(runner, BB_Equals(wanted, (Obj*)got), "Equals"); TEST_INT_EQ(runner, BB_Hash_Sum(got), BB_Hash_Sum(wanted), "Hash_Sum"); TEST_TRUE(runner, BB_Equals_Bytes(got, "foo", 4), "Equals_Bytes"); TEST_FALSE(runner, BB_Equals_Bytes(got, "foo", 3), "Equals_Bytes spoiled by different size"); TEST_FALSE(runner, BB_Equals_Bytes(got, "bar", 4), "Equals_Bytes spoiled by different content"); BB_Set_Size(got, 3); TEST_FALSE(runner, BB_Equals(wanted, (Obj*)got), "Different size spoils Equals"); TEST_FALSE(runner, BB_Hash_Sum(got) == BB_Hash_Sum(wanted), "Different size spoils Hash_Sum (probably -- at least this one)"); BB_Mimic_Bytes(got, "bar", 4); TEST_INT_EQ(runner, BB_Get_Size(wanted), BB_Get_Size(got), "same length"); TEST_FALSE(runner, BB_Equals(wanted, (Obj*)got), "Different content spoils Equals"); DECREF(got); DECREF(wanted); }
static void test_iterator_whitespace(TestBatchRunner *runner) { int num_spaces; String *ws_smiley = S_smiley_with_whitespace(&num_spaces); { StringIterator *iter = Str_Top(ws_smiley); TEST_INT_EQ(runner, StrIter_Skip_Whitespace(iter), num_spaces, "Skip_Whitespace"); TEST_INT_EQ(runner, StrIter_Skip_Whitespace(iter), 0, "Skip_Whitespace without whitespace"); DECREF(iter); } { StringIterator *iter = Str_Tail(ws_smiley); TEST_INT_EQ(runner, StrIter_Skip_Whitespace_Back(iter), num_spaces, "Skip_Whitespace_Back"); TEST_INT_EQ(runner, StrIter_Skip_Whitespace_Back(iter), 0, "Skip_Whitespace_Back without whitespace"); DECREF(iter); } DECREF(ws_smiley); }
static void test_bigend_f32(TestBatchRunner *runner) { float source[] = { -1.3f, 0.0f, 100.2f }; size_t count = 3; size_t amount = (count + 1) * sizeof(float); uint8_t *allocated = (uint8_t*)CALLOCATE(amount, sizeof(uint8_t)); uint8_t *encoded = allocated + 1; // Intentionally misaligned. uint8_t *target = encoded; for (size_t i = 0; i < count; i++) { NumUtil_encode_bigend_f32(source[i], &target); target += sizeof(float); } target = encoded; for (size_t i = 0; i < count; i++) { float got = NumUtil_decode_bigend_f32(target); TEST_TRUE(runner, got == source[i], "bigend f32"); target += sizeof(float); } target = encoded; NumUtil_encode_bigend_f32(-2.0f, &target); TEST_INT_EQ(runner, (encoded[0] & 0x80), 0x80, "Truly big-endian (IEEE 754 sign bit set for negative number)"); TEST_INT_EQ(runner, encoded[0], 0xC0, "IEEE 754 representation of -2.0f, byte 0"); for (size_t i = 1; i < sizeof(float); i++) { TEST_INT_EQ(runner, encoded[i], 0, "IEEE 754 representation of -2.0f, byte %d", (int)i); } FREEMEM(allocated); }
static void test_bigend_u32(TestBatchRunner *runner) { size_t count = 32; uint64_t *ints = TestUtils_random_u64s(NULL, count, 0, UINT64_C(1) + UINT32_MAX); size_t amount = (count + 1) * sizeof(uint32_t); char *allocated = (char*)CALLOCATE(amount, sizeof(char)); char *encoded = allocated + 1; // Intentionally misaligned. char *target = encoded; for (size_t i = 0; i < count; i++) { NumUtil_encode_bigend_u32((uint32_t)ints[i], &target); target += sizeof(uint32_t); } target = encoded; for (size_t i = 0; i < count; i++) { uint32_t got = NumUtil_decode_bigend_u32(target); TEST_INT_EQ(runner, got, (long)ints[i], "bigend u32"); target += sizeof(uint32_t); } target = encoded; NumUtil_encode_bigend_u32(1, &target); TEST_INT_EQ(runner, encoded[0], 0, "Truly big-endian u32"); TEST_INT_EQ(runner, encoded[3], 1, "Truly big-endian u32"); FREEMEM(allocated); FREEMEM(ints); }
void test_freqfilepos(TestBatch *batch) { TermInfo* tinfo = TInfo_new(10); TInfo_Set_Post_FilePos(tinfo, 20); TInfo_Set_Skip_FilePos(tinfo, 40); TInfo_Set_Lex_FilePos(tinfo, 50); TermInfo* cloned_tinfo = TInfo_Clone(tinfo); TEST_FALSE(batch, Lucy_TInfo_Equals(tinfo, (lucy_Obj*)cloned_tinfo),"the clone should be a separate C struct"); TEST_INT_EQ(batch, TInfo_Get_Doc_Freq(tinfo), 10, "new sets doc_freq correctly" ); TEST_INT_EQ(batch, TInfo_Get_Doc_Freq(tinfo), 10, "... doc_freq cloned" ); TEST_INT_EQ(batch, TInfo_Get_Post_FilePos(tinfo), 20, "... post_filepos cloned" ); TEST_INT_EQ(batch, TInfo_Get_Skip_FilePos(tinfo), 40, "... skip_filepos cloned" ); TEST_INT_EQ(batch, TInfo_Get_Lex_FilePos(tinfo), 50, "... lex_filepos cloned" ); TInfo_Set_Doc_Freq(tinfo, 5); TEST_INT_EQ(batch, TInfo_Get_Doc_Freq(tinfo), 5, "set/get doc_freq" ); TEST_INT_EQ(batch, TInfo_Get_Doc_Freq(cloned_tinfo), 10, "setting orig doesn't affect clone" ); TInfo_Set_Post_FilePos(tinfo, 15); TEST_INT_EQ(batch, TInfo_Get_Post_FilePos(tinfo), 15, "set/get post_filepos" ); TInfo_Set_Skip_FilePos(tinfo, 35); TEST_INT_EQ(batch, TInfo_Get_Skip_FilePos(tinfo), 35, "set/get skip_filepos" ); TInfo_Set_Lex_FilePos(tinfo, 45); TEST_INT_EQ(batch, TInfo_Get_Lex_FilePos(tinfo), 45, "set/get lex_filepos" ); DECREF(tinfo); DECREF(cloned_tinfo); }
static void test_bigend_f64(TestBatch *batch) { double source[] = { -1.3, 0.0, 100.2 }; size_t count = 3; size_t amount = (count + 1) * sizeof(double); uint8_t *allocated = (uint8_t*)CALLOCATE(amount, sizeof(uint8_t)); uint8_t *encoded = allocated + 1; // Intentionally misaligned. uint8_t *target = encoded; for (size_t i = 0; i < count; i++) { NumUtil_encode_bigend_f64(source[i], &target); target += sizeof(double); } target = encoded; for (size_t i = 0; i < count; i++) { double got = NumUtil_decode_bigend_f64(target); TEST_TRUE(batch, got == source[i], "bigend f64"); target += sizeof(double); } target = encoded; NumUtil_encode_bigend_f64(-2.0, &target); TEST_INT_EQ(batch, (encoded[0] & 0x80), 0x80, "Truly big-endian (IEEE 754 sign bit set for negative number)"); TEST_INT_EQ(batch, encoded[0], 0xC0, "IEEE 754 representation of -2.0, byte 0"); for (size_t i = 1; i < sizeof(double); i++) { TEST_INT_EQ(batch, encoded[i], 0, "IEEE 754 representation of -2.0, byte %d", (int)i); } FREEMEM(allocated); }
static void test_Code_Point_At_and_From(TestBatchRunner *runner) { int32_t code_points[] = { 'a', smiley_cp, smiley_cp, 'b', smiley_cp, 'c' }; uint32_t num_code_points = sizeof(code_points) / sizeof(int32_t); String *string = Str_newf("a%s%sb%sc", smiley, smiley, smiley); uint32_t i; for (i = 0; i < num_code_points; i++) { uint32_t from = num_code_points - i; TEST_INT_EQ(runner, Str_Code_Point_At(string, i), code_points[i], "Code_Point_At %ld", (long)i); TEST_INT_EQ(runner, Str_Code_Point_From(string, from), code_points[i], "Code_Point_From %ld", (long)from); } TEST_INT_EQ(runner, Str_Code_Point_At(string, num_code_points), STR_OOB, "Code_Point_At %ld", (long)num_code_points); TEST_INT_EQ(runner, Str_Code_Point_From(string, 0), STR_OOB, "Code_Point_From 0"); TEST_INT_EQ(runner, Str_Code_Point_From(string, num_code_points + 1), STR_OOB, "Code_Point_From %ld", (long)(num_code_points + 1)); DECREF(string); }
static void test_u1(TestBatch *batch) { size_t count = 64; uint64_t *ints = TestUtils_random_u64s(NULL, count, 0, 2); size_t amount = count / 8; uint8_t *bits = (uint8_t*)CALLOCATE(amount, sizeof(uint8_t)); for (size_t i = 0; i < count; i++) { if (ints[i]) { NumUtil_u1set(bits, i); } } for (size_t i = 0; i < count; i++) { TEST_INT_EQ(batch, NumUtil_u1get(bits, i), (long)ints[i], "u1 set/get"); } for (size_t i = 0; i < count; i++) { NumUtil_u1flip(bits, i); } for (size_t i = 0; i < count; i++) { TEST_INT_EQ(batch, NumUtil_u1get(bits, i), !ints[i], "u1 flip"); } FREEMEM(bits); FREEMEM(ints); }
static void test_c32(TestBatch *batch) { uint64_t mins[] = { 0, 0x4000 - 100, (uint32_t)I32_MAX - 100, U32_MAX - 10 }; uint64_t limits[] = { 500, 0x4000 + 100, (uint32_t)I32_MAX + 100, U32_MAX }; uint32_t set_num; uint32_t num_sets = sizeof(mins) / sizeof(uint64_t); size_t count = 64; uint64_t *ints = NULL; size_t amount = count * C32_MAX_BYTES; char *encoded = (char*)CALLOCATE(amount, sizeof(char)); char *target = encoded; char *limit = target + amount; for (set_num = 0; set_num < num_sets; set_num++) { char *skip; ints = TestUtils_random_u64s(ints, count, mins[set_num], limits[set_num]); target = encoded; for (size_t i = 0; i < count; i++) { NumUtil_encode_c32((uint32_t)ints[i], &target); } target = encoded; skip = encoded; for (size_t i = 0; i < count; i++) { TEST_INT_EQ(batch, NumUtil_decode_c32(&target), (long)ints[i], "c32 %lu", (long)ints[i]); NumUtil_skip_cint(&skip); if (target > limit) { THROW(ERR, "overrun"); } } TEST_TRUE(batch, skip == target, "skip %lu == %lu", (unsigned long)skip, (unsigned long)target); target = encoded; for (size_t i = 0; i < count; i++) { NumUtil_encode_padded_c32((uint32_t)ints[i], &target); } TEST_TRUE(batch, target == limit, "padded c32 uses 5 bytes (%lu == %lu)", (unsigned long)target, (unsigned long)limit); target = encoded; skip = encoded; for (size_t i = 0; i < count; i++) { TEST_INT_EQ(batch, NumUtil_decode_c32(&target), (long)ints[i], "padded c32 %lu", (long)ints[i]); NumUtil_skip_cint(&skip); if (target > limit) { THROW(ERR, "overrun"); } } TEST_TRUE(batch, skip == target, "skip padded %lu == %lu", (unsigned long)skip, (unsigned long)target); } target = encoded; NumUtil_encode_c32(U32_MAX, &target); target = encoded; TEST_INT_EQ(batch, NumUtil_decode_c32(&target), U32_MAX, "c32 U32_MAX"); FREEMEM(encoded); FREEMEM(ints); }
static void test_refill(TestBatchRunner *runner) { RAMFile *file = RAMFile_new(NULL, false); OutStream *outstream = OutStream_open((Obj*)file); InStream *instream; char scratch[5]; InStreamIVARS *ivars; for (int32_t i = 0; i < 1023; i++) { OutStream_Write_U8(outstream, 'x'); } OutStream_Write_U8(outstream, 'y'); OutStream_Write_U8(outstream, 'z'); OutStream_Close(outstream); instream = InStream_open((Obj*)file); ivars = InStream_IVARS(instream); InStream_Refill(instream); TEST_INT_EQ(runner, ivars->limit - ivars->buf, IO_STREAM_BUF_SIZE, "Refill"); TEST_INT_EQ(runner, (long)InStream_Tell(instream), 0, "Correct file pos after standing-start Refill()"); DECREF(instream); instream = InStream_open((Obj*)file); ivars = InStream_IVARS(instream); InStream_Fill(instream, 30); TEST_INT_EQ(runner, ivars->limit - ivars->buf, 30, "Fill()"); TEST_INT_EQ(runner, (long)InStream_Tell(instream), 0, "Correct file pos after standing-start Fill()"); DECREF(instream); instream = InStream_open((Obj*)file); ivars = InStream_IVARS(instream); InStream_Read_Bytes(instream, scratch, 5); TEST_INT_EQ(runner, ivars->limit - ivars->buf, IO_STREAM_BUF_SIZE - 5, "small read triggers refill"); DECREF(instream); instream = InStream_open((Obj*)file); ivars = InStream_IVARS(instream); TEST_INT_EQ(runner, InStream_Read_U8(instream), 'x', "Read_U8"); InStream_Seek(instream, 1023); TEST_INT_EQ(runner, (long)FileWindow_IVARS(ivars->window)->offset, 0, "no unnecessary refill on Seek"); TEST_INT_EQ(runner, (long)InStream_Tell(instream), 1023, "Seek/Tell"); TEST_INT_EQ(runner, InStream_Read_U8(instream), 'y', "correct data after in-buffer Seek()"); TEST_INT_EQ(runner, InStream_Read_U8(instream), 'z', "automatic Refill"); TEST_TRUE(runner, (FileWindow_IVARS(ivars->window)->offset != 0), "refilled"); DECREF(instream); DECREF(outstream); DECREF(file); }
static void test_Grow(TestBatchRunner *runner) { ByteBuf *bb = BB_new(1); TEST_INT_EQ(runner, BB_Get_Capacity(bb), 8, "Allocate in 8-byte increments"); BB_Grow(bb, 9); TEST_INT_EQ(runner, BB_Get_Capacity(bb), 16, "Grow in 8-byte increments"); DECREF(bb); }
void TestQPSyntax_run_tests(Folder *index) { uint32_t i; TestBatch *batch = TestBatch_new(58); IndexSearcher *searcher = IxSearcher_new((Obj*)index); QueryParser *qparser = QParser_new(IxSearcher_Get_Schema(searcher), NULL, NULL, NULL); QParser_Set_Heed_Colons(qparser, true); TestBatch_Plan(batch); for (i = 0; leaf_test_funcs[i] != NULL; i++) { kino_TestQPSyntax_test_t test_func = leaf_test_funcs[i]; TestQueryParser *test_case = test_func(); Query *tree = QParser_Tree(qparser, test_case->query_string); Query *expanded = QParser_Expand_Leaf(qparser, test_case->tree); Query *parsed = QParser_Parse(qparser, test_case->query_string); Hits *hits = IxSearcher_Hits(searcher, (Obj*)parsed, 0, 10, NULL); TEST_TRUE(batch, Query_Equals(tree, (Obj*)test_case->tree), "tree() %s", (char*)CB_Get_Ptr8(test_case->query_string)); TEST_TRUE(batch, Query_Equals(expanded, (Obj*)test_case->expanded), "expand_leaf() %s", (char*)CB_Get_Ptr8(test_case->query_string)); TEST_INT_EQ(batch, Hits_Total_Hits(hits), test_case->num_hits, "hits: %s", (char*)CB_Get_Ptr8(test_case->query_string)); DECREF(hits); DECREF(parsed); DECREF(expanded); DECREF(tree); DECREF(test_case); } for (i = 0; syntax_test_funcs[i] != NULL; i++) { kino_TestQPSyntax_test_t test_func = syntax_test_funcs[i]; TestQueryParser *test_case = test_func(); Query *tree = QParser_Tree(qparser, test_case->query_string); Query *parsed = QParser_Parse(qparser, test_case->query_string); Hits *hits = IxSearcher_Hits(searcher, (Obj*)parsed, 0, 10, NULL); TEST_TRUE(batch, Query_Equals(tree, (Obj*)test_case->tree), "tree() %s", (char*)CB_Get_Ptr8(test_case->query_string)); TEST_INT_EQ(batch, Hits_Total_Hits(hits), test_case->num_hits, "hits: %s", (char*)CB_Get_Ptr8(test_case->query_string)); DECREF(hits); DECREF(parsed); DECREF(tree); DECREF(test_case); } DECREF(batch); DECREF(searcher); DECREF(qparser); }
static void test_Window(TestBatchRunner *runner) { String *test_filename = SSTR_WRAP_C("_fstest"); FSFileHandle *fh; FileWindow *window = FileWindow_new(); uint32_t i; S_remove(test_filename); fh = FSFH_open(test_filename, FH_CREATE | FH_WRITE_ONLY | FH_EXCLUSIVE); for (i = 0; i < 1024; i++) { FSFH_Write(fh, "foo ", 4); } if (!FSFH_Close(fh)) { RETHROW(INCREF(Err_get_error())); } // Reopen for reading. DECREF(fh); fh = FSFH_open(test_filename, FH_READ_ONLY); if (!fh) { RETHROW(INCREF(Err_get_error())); } Err_set_error(NULL); TEST_FALSE(runner, FSFH_Window(fh, window, -1, 4), "Window() with a negative offset returns false"); TEST_TRUE(runner, Err_get_error() != NULL, "Window() with a negative offset sets error"); Err_set_error(NULL); TEST_FALSE(runner, FSFH_Window(fh, window, 4000, 1000), "Window() past EOF returns false"); TEST_TRUE(runner, Err_get_error() != NULL, "Window() past EOF sets error"); TEST_TRUE(runner, FSFH_Window(fh, window, 1021, 2), "Window() returns true"); const char *buf = FileWindow_Get_Buf(window); int64_t offset = FileWindow_Get_Offset(window); TEST_TRUE(runner, strncmp(buf - offset + 1021, "oo", 2) == 0, "Window()"); TEST_TRUE(runner, FSFH_Release_Window(fh, window), "Release_Window() returns true"); TEST_TRUE(runner, FileWindow_Get_Buf(window) == NULL, "Release_Window() resets buf"); TEST_INT_EQ(runner, FileWindow_Get_Offset(window), 0, "Release_Window() resets offset"); TEST_INT_EQ(runner, FileWindow_Get_Len(window), 0, "Release_Window() resets len"); DECREF(window); DECREF(fh); S_remove(test_filename); }
static void test_all(TestBatchRunner *runner) { RAMFolder *folder = RAMFolder_new(NULL); String *foo = SSTR_WRAP_C("foo"); String *boffo = SSTR_WRAP_C("boffo"); String *foo_boffo = SSTR_WRAP_C("foo/boffo"); bool saw_foo = false; bool saw_boffo = false; bool foo_was_dir = false; bool boffo_was_dir = false; int count = 0; // Set up folder contents. RAMFolder_MkDir(folder, foo); FileHandle *fh = RAMFolder_Open_FileHandle(folder, boffo, FH_CREATE | FH_WRITE_ONLY); DECREF(fh); fh = RAMFolder_Open_FileHandle(folder, foo_boffo, FH_CREATE | FH_WRITE_ONLY); DECREF(fh); RAMDirHandle *dh = RAMDH_new(folder); while (RAMDH_Next(dh)) { count++; String *entry = RAMDH_Get_Entry(dh); if (Str_Equals(entry, (Obj*)foo)) { saw_foo = true; foo_was_dir = RAMDH_Entry_Is_Dir(dh); } else if (Str_Equals(entry, (Obj*)boffo)) { saw_boffo = true; boffo_was_dir = RAMDH_Entry_Is_Dir(dh); } DECREF(entry); } TEST_INT_EQ(runner, 2, count, "correct number of entries"); TEST_TRUE(runner, saw_foo, "Directory was iterated over"); TEST_TRUE(runner, foo_was_dir, "Dir correctly identified by Entry_Is_Dir"); TEST_TRUE(runner, saw_boffo, "File was iterated over"); TEST_FALSE(runner, boffo_was_dir, "File correctly identified by Entry_Is_Dir"); uint32_t refcount = REFCOUNT_NN(folder); RAMDH_Close(dh); TEST_INT_EQ(runner, REFCOUNT_NN(folder), refcount - 1, "Folder reference released by Close()"); DECREF(dh); DECREF(folder); }
static void test_refcounts(TestBatch *batch) { Obj *obj = S_new_testobj(); TEST_INT_EQ(batch, Obj_Get_RefCount(obj), 1, "Correct starting refcount"); Obj_Inc_RefCount(obj); TEST_INT_EQ(batch, Obj_Get_RefCount(obj), 2, "Inc_RefCount"); Obj_Dec_RefCount(obj); TEST_INT_EQ(batch, Obj_Get_RefCount(obj), 1, "Dec_RefCount"); DECREF(obj); }
static void test_refcounts(TestBatchRunner *runner) { Obj *obj = S_new_testobj(); TEST_INT_EQ(runner, CFISH_REFCOUNT_NN(obj), 1, "Correct starting refcount"); obj = CFISH_INCREF_NN(obj); TEST_INT_EQ(runner, CFISH_REFCOUNT_NN(obj), 2, "INCREF_NN"); CFISH_DECREF_NN(obj); TEST_INT_EQ(runner, CFISH_REFCOUNT_NN(obj), 1, "DECREF_NN"); DECREF(obj); }
static void test_threads(TestBatchRunner *runner) { Err_set_error(Err_new(Str_newf("main"))); int err; pthread_t thread; err = pthread_create(&thread, NULL, S_err_thread, runner); TEST_INT_EQ(runner, err, 0, "pthread_create succeeds"); err = pthread_join(thread, NULL); TEST_INT_EQ(runner, err, 0, "pthread_join succeeds"); String *mess = Err_Get_Mess(Err_get_error()); TEST_TRUE(runner, Str_Equals_Utf8(mess, "main", 4), "thread doesn't clobber global error"); }
static void test_Flip_Block_bulk(TestBatch *batch) { int32_t offset; for (offset = 0; offset <= 17; offset++) { int32_t len; for (len = 0; len <= 17; len++) { int i; int upper = offset + len - 1; BitVector *bit_vec = BitVec_new(0); BitVec_Flip_Block(bit_vec, offset, len); for (i = 0; i <= 17; i++) { if (i >= offset && i <= upper) { if (!BitVec_Get(bit_vec, i)) { break; } } else { if (BitVec_Get(bit_vec, i)) { break; } } } TEST_INT_EQ(batch, i, 18, "Flip_Block(%d, %d)", offset, len); DECREF(bit_vec); } } }
static void test_Mimic(TestBatch *batch) { int foo; for (foo = 0; foo <= 17; foo++) { int bar; for (bar = 0; bar <= 17; bar++) { int i; BitVector *foo_vec = BitVec_new(0); BitVector *bar_vec = BitVec_new(0); BitVec_Set(foo_vec, foo); BitVec_Set(bar_vec, bar); BitVec_Mimic(foo_vec, (Obj*)bar_vec); for (i = 0; i <= 17; i++) { if (BitVec_Get(foo_vec, i) && i != bar) { break; } } TEST_INT_EQ(batch, i, 18, "Mimic(%d, %d)", foo, bar); DECREF(foo_vec); DECREF(bar_vec); } } }
static void test_To_Array(TestBatch *batch) { uint64_t *source_ints = TestUtils_random_u64s(NULL, 20, 0, 200); BitVector *bit_vec = BitVec_new(0); I32Array *array; long num_unique = 0; long i; // Unique the random ints. Sort_quicksort(source_ints, 20, sizeof(uint64_t), S_compare_u64s, NULL); for (i = 0; i < 19; i++) { if (source_ints[i] != source_ints[i + 1]) { source_ints[num_unique] = source_ints[i]; num_unique++; } } // Set bits. for (i = 0; i < num_unique; i++) { BitVec_Set(bit_vec, (uint32_t)source_ints[i]); } // Create the array and compare it to the source. array = BitVec_To_Array(bit_vec); for (i = 0; i < num_unique; i++) { if (I32Arr_Get(array, i) != (int32_t)source_ints[i]) { break; } } TEST_INT_EQ(batch, i, num_unique, "To_Array (%ld == %ld)", i, num_unique); DECREF(array); DECREF(bit_vec); FREEMEM(source_ints); }
static void test_Code_Point_At_and_From(TestBatch *batch) { uint32_t code_points[] = { 'a', 0x263A, 0x263A, 'b', 0x263A, 'c' }; uint32_t num_code_points = sizeof(code_points) / sizeof(uint32_t); CharBuf *string = CB_newf("a%s%sb%sc", smiley, smiley, smiley); uint32_t i; for (i = 0; i < num_code_points; i++) { uint32_t from = num_code_points - i - 1; TEST_INT_EQ(batch, CB_Code_Point_At(string, i), code_points[i], "Code_Point_At %ld", (long)i); TEST_INT_EQ(batch, CB_Code_Point_At(string, from), code_points[from], "Code_Point_From %ld", (long)from); } DECREF(string); }
static void test_Clear_All(TestBatch *batch) { BitVector *bit_vec = BitVec_new(64); BitVec_Flip_Block(bit_vec, 0, 63); BitVec_Clear_All(bit_vec); TEST_INT_EQ(batch, BitVec_Next_Hit(bit_vec, 0), -1, "Clear_All"); DECREF(bit_vec); }
static void test_to_base36(TestBatchRunner *runner) { char buffer[StrHelp_MAX_BASE36_BYTES]; StrHelp_to_base36(UINT64_MAX, buffer); TEST_STR_EQ(runner, "3w5e11264sgsf", buffer, "base36 UINT64_MAX"); StrHelp_to_base36(1, buffer); TEST_STR_EQ(runner, "1", buffer, "base36 1"); TEST_INT_EQ(runner, buffer[1], 0, "base36 NULL termination"); }
static void test_discard(TestBatchRunner *runner) { int32_t i; NumPriorityQueue *pq = NumPriQ_new(5); for (i = 1; i <= 10; i++) { S_insert_num(pq, i); } S_insert_num(pq, -3); for (i = 1590; i <= 1600; i++) { S_insert_num(pq, i); } S_insert_num(pq, 5); TEST_INT_EQ(runner, S_pop_num(pq), 1596, "discard waste"); TEST_INT_EQ(runner, S_pop_num(pq), 1597, "discard waste"); TEST_INT_EQ(runner, S_pop_num(pq), 1598, "discard waste"); TEST_INT_EQ(runner, S_pop_num(pq), 1599, "discard waste"); TEST_INT_EQ(runner, S_pop_num(pq), 1600, "discard waste"); DECREF(pq); }
static void test_Xor(TestBatchRunner *runner) { BitVector *smaller = S_create_set(1); BitVector *larger = S_create_set(2); BitVector *set_1 = S_create_set(1); BitVector *set_2 = S_create_set(2); BitVec_Xor(smaller, set_2); TEST_INT_EQ(runner, S_verify_logical_op(smaller, set_1, set_2, OP_XOR), 50, "XOR with self smaller than other"); BitVec_Xor(larger, set_1); TEST_INT_EQ(runner, S_verify_logical_op(larger, set_1, set_2, OP_XOR), 50, "XOR with other smaller than self"); DECREF(smaller); DECREF(larger); DECREF(set_1); DECREF(set_2); }
static void test_And(TestBatch *batch) { BitVector *smaller = S_create_set(1); BitVector *larger = S_create_set(2); BitVector *set_1 = S_create_set(1); BitVector *set_2 = S_create_set(2); BitVec_And(smaller, set_2); TEST_INT_EQ(batch, S_verify_logical_op(smaller, set_1, set_2, OP_AND), 50, "AND with self smaller than other"); BitVec_And(larger, set_1); TEST_INT_EQ(batch, S_verify_logical_op(larger, set_1, set_2, OP_AND), 50, "AND with other smaller than self"); DECREF(smaller); DECREF(larger); DECREF(set_1); DECREF(set_2); }
static void test_all(TestBatch *batch) { CharBuf *foo = (CharBuf*)ZCB_WRAP_STR("foo", 3); CharBuf *boffo = (CharBuf*)ZCB_WRAP_STR("boffo", 5); CharBuf *foo_boffo = (CharBuf*)ZCB_WRAP_STR("foo/boffo", 9); CharBuf *test_dir = (CharBuf*)ZCB_WRAP_STR("_fsdir_test", 11); FSFolder *folder = FSFolder_new(test_dir); bool_t saw_foo = false; bool_t saw_boffo = false; bool_t foo_was_dir = false; bool_t boffo_was_dir = false; int count = 0; // Clean up after previous failed runs. FSFolder_Delete(folder, foo_boffo); FSFolder_Delete(folder, foo); FSFolder_Delete(folder, boffo); rmdir("_fsdir_test"); FSFolder_Initialize(folder); FSFolder_MkDir(folder, foo); OutStream *outstream = FSFolder_Open_Out(folder, boffo); DECREF(outstream); outstream = FSFolder_Open_Out(folder, foo_boffo); DECREF(outstream); FSDirHandle *dh = FSDH_open(test_dir); CharBuf *entry = FSDH_Get_Entry(dh); while (FSDH_Next(dh)) { count++; if (CB_Equals(entry, (Obj*)foo)) { saw_foo = true; foo_was_dir = FSDH_Entry_Is_Dir(dh); } else if (CB_Equals(entry, (Obj*)boffo)) { saw_boffo = true; boffo_was_dir = FSDH_Entry_Is_Dir(dh); } } TEST_INT_EQ(batch, 2, count, "correct number of entries"); TEST_TRUE(batch, saw_foo, "Directory was iterated over"); TEST_TRUE(batch, foo_was_dir, "Dir correctly identified by Entry_Is_Dir"); TEST_TRUE(batch, saw_boffo, "File was iterated over"); TEST_FALSE(batch, boffo_was_dir, "File correctly identified by Entry_Is_Dir"); DECREF(dh); FSFolder_Delete(folder, foo_boffo); FSFolder_Delete(folder, foo); FSFolder_Delete(folder, boffo); DECREF(folder); rmdir("_fsdir_test"); }
static void test_Next_Hit(TestBatchRunner *runner) { for (int i = 24; i <= 33; i++) { BitVector *bit_vec = BitVec_new(64); BitVec_Set(bit_vec, (size_t)i); TEST_INT_EQ(runner, BitVec_Next_Hit(bit_vec, 0), i, "Next_Hit for 0 is %d", i); TEST_INT_EQ(runner, BitVec_Next_Hit(bit_vec, 0), i, "Next_Hit for 1 is %d", i); for (int probe = 15; probe <= i; probe++) { TEST_INT_EQ(runner, BitVec_Next_Hit(bit_vec, (size_t)probe), i, "Next_Hit for %d is %d", probe, i); } for (int probe = i + 1; probe <= i + 9; probe++) { TEST_INT_EQ(runner, BitVec_Next_Hit(bit_vec, (size_t)probe), -1, "no Next_Hit for %d when max is %d", probe, i); } DECREF(bit_vec); } }