static void test_Keys_Values_Iter(TestBatch *batch) { Hash *hash = Hash_new(0); // trigger multiple rebuilds. VArray *expected = VA_new(100); VArray *keys; VArray *values; for (uint32_t i = 0; i < 500; i++) { CharBuf *cb = CB_newf("%u32", i); Hash_Store(hash, (Obj*)cb, (Obj*)cb); VA_Push(expected, INCREF(cb)); } VA_Sort(expected, NULL, NULL); keys = Hash_Keys(hash); values = Hash_Values(hash); VA_Sort(keys, NULL, NULL); VA_Sort(values, NULL, NULL); TEST_TRUE(batch, VA_Equals(keys, (Obj*)expected), "Keys"); TEST_TRUE(batch, VA_Equals(values, (Obj*)expected), "Values"); VA_Clear(keys); VA_Clear(values); { Obj *key; Obj *value; Hash_Iterate(hash); while (Hash_Next(hash, &key, &value)) { VA_Push(keys, INCREF(key)); VA_Push(values, INCREF(value)); } } VA_Sort(keys, NULL, NULL); VA_Sort(values, NULL, NULL); TEST_TRUE(batch, VA_Equals(keys, (Obj*)expected), "Keys from Iter"); TEST_TRUE(batch, VA_Equals(values, (Obj*)expected), "Values from Iter"); { ZombieCharBuf *forty = ZCB_WRAP_STR("40", 2); ZombieCharBuf *nope = ZCB_WRAP_STR("nope", 4); Obj *key = Hash_Find_Key(hash, (Obj*)forty, ZCB_Hash_Sum(forty)); TEST_TRUE(batch, Obj_Equals(key, (Obj*)forty), "Find_Key"); key = Hash_Find_Key(hash, (Obj*)nope, ZCB_Hash_Sum(nope)), TEST_TRUE(batch, key == NULL, "Find_Key returns NULL for non-existent key"); } DECREF(hash); DECREF(expected); DECREF(keys); DECREF(values); }
static void test_Read_File_and_Write_File(TestBatchRunner *runner) { Snapshot *snapshot = Snapshot_new(); Folder *folder = (Folder*)RAMFolder_new(NULL); String *snap = (String*)SSTR_WRAP_UTF8("snap", 4); String *foo = (String*)SSTR_WRAP_UTF8("foo", 3); Snapshot_Add_Entry(snapshot, foo); Snapshot_Write_File(snapshot, folder, snap); Snapshot *dupe = Snapshot_new(); Snapshot *read_retval = Snapshot_Read_File(dupe, folder, snap); TEST_TRUE(runner, dupe == read_retval, "Read_File() returns the object"); VArray *orig_list = Snapshot_List(snapshot); VArray *dupe_list = Snapshot_List(dupe); TEST_TRUE(runner, VA_Equals(orig_list, (Obj*)dupe_list), "Round trip through Write_File() and Read_File()"); DECREF(orig_list); DECREF(dupe_list); DECREF(dupe); DECREF(snapshot); DECREF(folder); }
bool_t PolyAnalyzer_equals(PolyAnalyzer *self, Obj *other) { PolyAnalyzer *const twin = (PolyAnalyzer*)other; if (twin == self) { return true; } if (!Obj_Is_A(other, POLYANALYZER)) { return false; } if (!VA_Equals(twin->analyzers, (Obj*)self->analyzers)) { return false; } return true; }
bool PolyAnalyzer_Equals_IMP(PolyAnalyzer *self, Obj *other) { if ((PolyAnalyzer*)other == self) { return true; } if (!Obj_Is_A(other, POLYANALYZER)) { return false; } PolyAnalyzerIVARS *const ivars = PolyAnalyzer_IVARS(self); PolyAnalyzerIVARS *const ovars = PolyAnalyzer_IVARS((PolyAnalyzer*)other); if (!VA_Equals(ovars->analyzers, (Obj*)ivars->analyzers)) { return false; } return true; }
static void S_round_trip_integer(TestBatch *batch, int64_t value) { Integer64 *num = Int64_new(value); VArray *array = VA_new(1); VA_Store(array, 0, (Obj*)num); CharBuf *json = Json_to_json((Obj*)array); Obj *dump = Json_from_json(json); TEST_TRUE(batch, VA_Equals(array, dump), "Round trip integer %ld", (long)value); DECREF(dump); DECREF(json); DECREF(array); }
bool_t PhraseQuery_equals(PhraseQuery *self, Obj *other) { PhraseQuery *evil_twin = (PhraseQuery*)other; if (evil_twin == self) return true; if (!Obj_Is_A(other, PHRASEQUERY)) return false; if (self->boost != evil_twin->boost) return false; if (self->field && !evil_twin->field) return false; if (!self->field && evil_twin->field) return false; if (self->field && !CB_Equals(self->field, (Obj*)evil_twin->field)) return false; if (!VA_Equals(evil_twin->terms, (Obj*)self->terms)) return false; return true; }
static void test_stress(TestBatch *batch) { Hash *hash = Hash_new(0); // trigger multiple rebuilds. VArray *expected = VA_new(1000); VArray *keys; VArray *values; for (uint32_t i = 0; i < 1000; i++) { CharBuf *cb = TestUtils_random_string(rand() % 1200); while (Hash_Fetch(hash, (Obj*)cb)) { DECREF(cb); cb = TestUtils_random_string(rand() % 1200); } Hash_Store(hash, (Obj*)cb, (Obj*)cb); VA_Push(expected, INCREF(cb)); } VA_Sort(expected, NULL, NULL); // Overwrite for good measure. for (uint32_t i = 0; i < 1000; i++) { CharBuf *cb = (CharBuf*)VA_Fetch(expected, i); Hash_Store(hash, (Obj*)cb, INCREF(cb)); } keys = Hash_Keys(hash); values = Hash_Values(hash); VA_Sort(keys, NULL, NULL); VA_Sort(values, NULL, NULL); TEST_TRUE(batch, VA_Equals(keys, (Obj*)expected), "stress Keys"); TEST_TRUE(batch, VA_Equals(values, (Obj*)expected), "stress Values"); DECREF(keys); DECREF(values); DECREF(expected); DECREF(hash); }
bool ProximityQuery_Equals_IMP(ProximityQuery *self, Obj *other) { if ((ProximityQuery*)other == self) { return true; } if (!Obj_Is_A(other, PROXIMITYQUERY)) { return false; } ProximityQueryIVARS *const ivars = ProximityQuery_IVARS(self); ProximityQueryIVARS *const ovars = ProximityQuery_IVARS((ProximityQuery*)other); if (ivars->boost != ovars->boost) { return false; } if (ivars->field && !ovars->field) { return false; } if (!ivars->field && ovars->field) { return false; } if (ivars->field && !Str_Equals(ivars->field, (Obj*)ovars->field)) { return false; } if (!VA_Equals(ovars->terms, (Obj*)ivars->terms)) { return false; } if (ivars->within != ovars->within) { return false; } return true; }
static void test_Store_and_Fetch(TestBatch *batch) { Hash *hash = Hash_new(100); Hash *dupe = Hash_new(100); const uint32_t starting_cap = Hash_Get_Capacity(hash); VArray *expected = VA_new(100); VArray *got = VA_new(100); ZombieCharBuf *twenty = ZCB_WRAP_STR("20", 2); ZombieCharBuf *forty = ZCB_WRAP_STR("40", 2); ZombieCharBuf *foo = ZCB_WRAP_STR("foo", 3); for (int32_t i = 0; i < 100; i++) { CharBuf *cb = CB_newf("%i32", i); Hash_Store(hash, (Obj*)cb, (Obj*)cb); Hash_Store(dupe, (Obj*)cb, INCREF(cb)); VA_Push(expected, INCREF(cb)); } TEST_TRUE(batch, Hash_Equals(hash, (Obj*)dupe), "Equals"); TEST_INT_EQ(batch, Hash_Get_Capacity(hash), starting_cap, "Initial capacity sufficient (no rebuilds)"); for (int32_t i = 0; i < 100; i++) { Obj *key = VA_Fetch(expected, i); Obj *elem = Hash_Fetch(hash, key); VA_Push(got, (Obj*)INCREF(elem)); } TEST_TRUE(batch, VA_Equals(got, (Obj*)expected), "basic Store and Fetch"); TEST_INT_EQ(batch, Hash_Get_Size(hash), 100, "size incremented properly by Hash_Store"); TEST_TRUE(batch, Hash_Fetch(hash, (Obj*)foo) == NULL, "Fetch against non-existent key returns NULL"); Hash_Store(hash, (Obj*)forty, INCREF(foo)); TEST_TRUE(batch, ZCB_Equals(foo, Hash_Fetch(hash, (Obj*)forty)), "Hash_Store replaces existing value"); TEST_FALSE(batch, Hash_Equals(hash, (Obj*)dupe), "replacement value spoils equals"); TEST_INT_EQ(batch, Hash_Get_Size(hash), 100, "size unaffected after value replaced"); TEST_TRUE(batch, Hash_Delete(hash, (Obj*)forty) == (Obj*)foo, "Delete returns value"); DECREF(foo); TEST_INT_EQ(batch, Hash_Get_Size(hash), 99, "size decremented by successful Delete"); TEST_TRUE(batch, Hash_Delete(hash, (Obj*)forty) == NULL, "Delete returns NULL when key not found"); TEST_INT_EQ(batch, Hash_Get_Size(hash), 99, "size not decremented by unsuccessful Delete"); DECREF(Hash_Delete(dupe, (Obj*)forty)); TEST_TRUE(batch, VA_Equals(got, (Obj*)expected), "Equals after Delete"); Hash_Clear(hash); TEST_TRUE(batch, Hash_Fetch(hash, (Obj*)twenty) == NULL, "Clear"); TEST_TRUE(batch, Hash_Get_Size(hash) == 0, "size is 0 after Clear"); DECREF(hash); DECREF(dupe); DECREF(got); DECREF(expected); }
static void test_flatten_spans(TestBatchRunner *runner) { VArray *spans = VA_new(8); VArray *wanted = VA_new(8); HeatMap *heat_map = HeatMap_new(spans, 133); VArray *flattened, *boosts; VA_Push(spans, (Obj*)Span_new(10, 10, 1.0f)); VA_Push(spans, (Obj*)Span_new(16, 14, 2.0f)); flattened = HeatMap_Flatten_Spans(heat_map, spans); VA_Push(wanted, (Obj*)Span_new(10, 6, 1.0f)); VA_Push(wanted, (Obj*)Span_new(16, 4, 3.0f)); VA_Push(wanted, (Obj*)Span_new(20, 10, 2.0f)); TEST_TRUE(runner, VA_Equals(flattened, (Obj*)wanted), "flatten two overlapping spans"); VA_Clear(wanted); boosts = HeatMap_Generate_Proximity_Boosts(heat_map, spans); VA_Push(wanted, (Obj*)Span_new(10, 20, 3.0f)); TEST_TRUE(runner, VA_Equals(boosts, (Obj*)wanted), "prox boosts for overlap"); VA_Clear(wanted); VA_Clear(spans); DECREF(boosts); DECREF(flattened); VA_Push(spans, (Obj*)Span_new(10, 10, 1.0f)); VA_Push(spans, (Obj*)Span_new(16, 14, 2.0f)); VA_Push(spans, (Obj*)Span_new(50, 1, 1.0f)); flattened = HeatMap_Flatten_Spans(heat_map, spans); VA_Push(wanted, (Obj*)Span_new(10, 6, 1.0f)); VA_Push(wanted, (Obj*)Span_new(16, 4, 3.0f)); VA_Push(wanted, (Obj*)Span_new(20, 10, 2.0f)); VA_Push(wanted, (Obj*)Span_new(50, 1, 1.0f)); TEST_TRUE(runner, VA_Equals(flattened, (Obj*)wanted), "flatten two overlapping spans, leave hole, then third span"); VA_Clear(wanted); boosts = HeatMap_Generate_Proximity_Boosts(heat_map, spans); TEST_TRUE(runner, VA_Get_Size(boosts) == 2 + 1, "boosts generated for each unique pair, since all were in range"); VA_Clear(spans); DECREF(boosts); DECREF(flattened); VA_Push(spans, (Obj*)Span_new(10, 10, 1.0f)); VA_Push(spans, (Obj*)Span_new(14, 4, 4.0f)); VA_Push(spans, (Obj*)Span_new(16, 14, 2.0f)); flattened = HeatMap_Flatten_Spans(heat_map, spans); VA_Push(wanted, (Obj*)Span_new(10, 4, 1.0f)); VA_Push(wanted, (Obj*)Span_new(14, 2, 5.0f)); VA_Push(wanted, (Obj*)Span_new(16, 2, 7.0f)); VA_Push(wanted, (Obj*)Span_new(18, 2, 3.0f)); VA_Push(wanted, (Obj*)Span_new(20, 10, 2.0f)); TEST_TRUE(runner, VA_Equals(flattened, (Obj*)wanted), "flatten three overlapping spans"); VA_Clear(wanted); boosts = HeatMap_Generate_Proximity_Boosts(heat_map, spans); TEST_TRUE(runner, VA_Get_Size(boosts) == 2 + 1, "boosts generated for each unique pair, since all were in range"); VA_Clear(spans); DECREF(boosts); DECREF(flattened); VA_Push(spans, (Obj*)Span_new(10, 10, 1.0f)); VA_Push(spans, (Obj*)Span_new(16, 14, 4.0f)); VA_Push(spans, (Obj*)Span_new(16, 14, 2.0f)); VA_Push(spans, (Obj*)Span_new(30, 10, 10.0f)); flattened = HeatMap_Flatten_Spans(heat_map, spans); VA_Push(wanted, (Obj*)Span_new(10, 6, 1.0f)); VA_Push(wanted, (Obj*)Span_new(16, 4, 7.0f)); VA_Push(wanted, (Obj*)Span_new(20, 10, 6.0f)); VA_Push(wanted, (Obj*)Span_new(30, 10, 10.0f)); TEST_TRUE(runner, VA_Equals(flattened, (Obj*)wanted), "flatten 4 spans, middle two have identical range"); VA_Clear(wanted); boosts = HeatMap_Generate_Proximity_Boosts(heat_map, spans); TEST_TRUE(runner, VA_Get_Size(boosts) == 3 + 2 + 1, "boosts generated for each unique pair, since all were in range"); VA_Clear(spans); DECREF(boosts); DECREF(flattened); VA_Push(spans, (Obj*)Span_new( 10, 10, 1.0f)); VA_Push(spans, (Obj*)Span_new( 16, 4, 4.0f)); VA_Push(spans, (Obj*)Span_new( 16, 14, 2.0f)); VA_Push(spans, (Obj*)Span_new(230, 10, 10.0f)); flattened = HeatMap_Flatten_Spans(heat_map, spans); VA_Push(wanted, (Obj*)Span_new( 10, 6, 1.0f)); VA_Push(wanted, (Obj*)Span_new( 16, 4, 7.0f)); VA_Push(wanted, (Obj*)Span_new( 20, 10, 2.0f)); VA_Push(wanted, (Obj*)Span_new(230, 10, 10.0f)); TEST_TRUE(runner, VA_Equals(flattened, (Obj*)wanted), "flatten 4 spans, middle two have identical starts but different ends"); VA_Clear(wanted); boosts = HeatMap_Generate_Proximity_Boosts(heat_map, spans); TEST_TRUE(runner, VA_Get_Size(boosts) == 2 + 1, "boosts not generated for out of range span"); VA_Clear(spans); DECREF(boosts); DECREF(flattened); DECREF(heat_map); DECREF(wanted); DECREF(spans); }