unit tests for exercised egcpool #59

pull/63/head
nick black 5 years ago committed by Nick Black
parent ba648dbd74
commit 2080e0bff3

@ -394,6 +394,11 @@ cell_double_wide_p(const cell* c){
return (c->channels & CELL_WIDEASIAN_MASK);
}
static inline uint32_t
cell_egc_idx(const cell* c){
return c->gcluster - 0x80;
}
// load up six cells with the EGCs necessary to draw a light, rounded box.
// returns 0 on success, -1 on error. on error, any cells this function might
// have loaded before the error are cell_release()d.

@ -45,6 +45,7 @@ int widecolor_demo(struct notcurses* nc){
"Μπορῶ νὰ φάω σπασμένα γυαλιὰ χωρὶς νὰ πάθω τίποτα",
"Vitrum edere possum; mihi non nocet",
"🚬🌿💉💊☢☣🔫💣⚔🤜🤛🧠🦹🤺🏋️,🦔🐧🐣🦆🦢🦜🦉🐊🐸🦕 🦖🐬🐙🦂🦠🦀",
*/
"Je puis mangier del voirre. Ne me nuit",
"Je peux manger du verre, ça ne me fait pas mal",
"Pòdi manjar de veire, me nafrariá pas",
@ -76,7 +77,7 @@ int widecolor_demo(struct notcurses* nc){
"Foddym gee glonney agh cha jean eh gortaghey mee",
"᚛᚛ᚉᚑᚅᚔᚉᚉᚔᚋ ᚔᚈᚔ ᚍᚂᚐᚅᚑ ᚅᚔᚋᚌᚓᚅᚐ",
"Con·iccim ithi nglano. Ním·géna",
"🗽🏴☭࿗☮࿘☭🏴🗽",
"☭࿗☮࿘☭",
"Is féidir liom gloinne a ithe. Ní dhéanann sí dochar ar bith dom",
"Ithim-sa gloine agus ní miste damh é",
"S urrainn dhomh gloinne ithe; cha ghoirtich i mi",
@ -98,6 +99,7 @@ int widecolor_demo(struct notcurses* nc){
"Jag kan äta glas utan att skada mig",
"Jeg kan spise glas, det gør ikke ondt på mig",
"Æ ka æe glass uhen at det go mæ naue",
/*
"က္ယ္ဝန္တော္၊က္ယ္ဝန္မ မ္ယက္စားနုိင္သည္။ ၎က္ရောင္ ထိခုိက္မ္ဟု မရ္ဟိပာ။",
"ကျွန်တော် ကျွန်မ မှန်စားနိုင်တယ်။ ၎င်းကြောင့် ထိခိုက်မှုမရှိပါ။ ",
"Tôi có thể ăn thủy tinh mà không hại gì",
@ -118,6 +120,7 @@ int widecolor_demo(struct notcurses* nc){
"Hiki iaʻu ke ʻai i ke aniani; ʻaʻole nō lā au e ʻeha",
"E koʻana e kai i te karahi, mea ʻā, ʻaʻe hauhau",
"ᐊᓕᒍᖅ ᓂᕆᔭᕌᖓᒃᑯ ᓱᕋᙱᑦᑐᓐᓇᖅᑐ",
*/
"Naika məkmək kakshət labutay, pi weyk ukuk munk-sik nay",
"Tsésǫʼ yishą́ągo bííníshghah dóó doo shił neezgai da",
"mi kakne le nu citka le blaci .iku'i le se go'i na xrani m",
@ -132,6 +135,7 @@ int widecolor_demo(struct notcurses* nc){
"Isch kann Jlaas kimmeln, uuhne datt mich datt weh dääd",
"Ich koann Gloos assn und doas dudd merr ni wii",
"Мен шиша ейишим мумкин, аммо у менга зарар келтирмайди",
/*
"আমি কাঁচ খেতে পারি, তাতে আমার কোনো ক্ষতি হয় না",
"मी काच खाऊ शकतो, मला ते दुखत नाही",
"ನನಗೆ ಹಾನಿ ಆಗದೆ, ನಾನು ಗಜನ್ನು ತಿನಬಹು",

@ -616,14 +616,9 @@ simple_cell_p(const cell* c){
return c->gcluster < 0x80;
}
static inline uint32_t
extended_gcluster_idx(const cell* c){
return c->gcluster - 0x80;
}
static inline const char*
extended_gcluster(const ncplane* n, const cell* c){
uint32_t idx = extended_gcluster_idx(c);
uint32_t idx = cell_egc_idx(c);
return n->pool.pool + idx;
}
@ -796,7 +791,7 @@ int ncplane_getc(const ncplane* n, cell* c, char** gclust){
void cell_release(ncplane* n, cell* c){
if(!simple_cell_p(c)){
egcpool_release(&n->pool, extended_gcluster_idx(c));
egcpool_release(&n->pool, cell_egc_idx(c));
c->gcluster = 0; // don't subject ourselves to double-release problems
}
}

@ -113,3 +113,92 @@ TEST_F(EGCPoolTest, AddTwiceRemoveSecond) {
EXPECT_EQ(u2 + 1, pool_.poolused);
EXPECT_LT(0, pool_.poolwrite);
}
// POOL_MINIMUM_ALLOC is the minimum size of an egcpool once it goes active.
// add EGCs to it past this boundary, and verify that they're all still
// accurate.
TEST_F(EGCPoolTest, ForceReallocation) {
std::array<int, POOL_MINIMUM_ALLOC * 8> candidates; // offsets
char* firstalloc = nullptr;
for(auto i = 0u ; i < candidates.max_size() ; ++i){
char mb[MB_CUR_MAX + 1];
wchar_t wcs = i + 0x80;
auto r = wctomb(mb, wcs);
if(r < 0){
candidates[i] = -1;
continue;
}
ASSERT_GE(sizeof(mb), r);
mb[r] = '\0';
candidates[i] = egcpool_stash(&pool_, mb, r);
ASSERT_GT(1u << 24u, candidates[i]);
if(!firstalloc){
firstalloc = pool_.pool;
}
}
// verify that we moved the pool at least once
ASSERT_NE(pool_.pool, firstalloc);
for(auto i = 0u ; i < candidates.max_size() ; ++i){
auto stored = pool_.pool + candidates[i];
char mb[MB_CUR_MAX + 1];
wchar_t wcs = i + 0x80;
auto r = wctomb(mb, wcs);
if(r < 0){
ASSERT_EQ(-1, candidates[i]);
continue;
}
ASSERT_LT(0, r);
mb[r] = '\0';
EXPECT_STREQ(mb, stored);
}
}
// POOL_MINIMUM_ALLOC is the minimum size of an egcpool once it goes active.
// add EGCs to it past this boundary, and verify that they're all still
// accurate.
TEST_F(EGCPoolTest, ForceReallocationWithRemovals) {
std::array<int, POOL_MINIMUM_ALLOC * 8> candidates; // offsets
char* curpool = nullptr;
for(auto i = 0u ; i < candidates.max_size() ; ++i){
char mb[MB_CUR_MAX + 1];
wchar_t wcs = i + 0x80;
auto r = wctomb(mb, wcs);
if(r < 0){
candidates[i] = -1;
continue;
}
ASSERT_GE(sizeof(mb), r);
mb[r] = '\0';
candidates[i] = egcpool_stash(&pool_, mb, r);
ASSERT_GT(1u << 24u, candidates[i]);
if(pool_.pool != curpool){
// cut through and release a bunch of them
if(curpool){
for(auto j = 0u ; j < i ; j += 3){
if(candidates[j] >= 0){
egcpool_release(&pool_, candidates[j]);
candidates[j] = -1;
}
}
}
curpool = pool_.pool;
}
}
for(auto i = 0u ; i < candidates.max_size() ; ++i){
auto stored = pool_.pool + candidates[i];
char mb[MB_CUR_MAX + 1];
wchar_t wcs = i + 0x80;
auto r = wctomb(mb, wcs);
if(r < 0){
ASSERT_EQ(-1, candidates[i]);
continue;
}
ASSERT_LT(0, r);
mb[r] = '\0';
if(i % 3 == 0){
EXPECT_STREQ(mb, "");
}else{
EXPECT_STREQ(mb, stored);
}
}
}

Loading…
Cancel
Save