1#include <muleunit/test.h> 2#include <algorithm> 3#include "Types.h" 4#include "RangeMap.h" 5 6 7using namespace muleunit; 8 9typedef CRangeMap<int> TestRangeMap; 10 11 12/** 13 * Returns the contents of a TestRangeMap iterator as a string-presentation. 14 */ 15wxString StringFrom(const TestRangeMap::const_iterator& it) 16{ 17 return wxString::Format(wxT("(%") wxLongLongFmtSpec wxT("u, %") wxLongLongFmtSpec wxT("u, %i)"), it.keyStart(), it.keyEnd(), *it); 18} 19 20/** 21 * Returns the contents of a TestRangeMap iterator as a string-presentation. 22 */ 23wxString StringFrom(TestRangeMap::iterator it) 24{ 25 return wxString::Format(wxT("(%") wxLongLongFmtSpec wxT("u, %") wxLongLongFmtSpec wxT("u, %i)"), it.keyStart(), it.keyEnd(), *it); 26} 27 28 29/** 30 * Returns the contents of a CRangeSet iterator as a string-presentation. 31 */ 32wxString StringFrom(const CRangeMap<void>::const_iterator& it) 33{ 34 return wxString::Format(wxT("(%") wxLongLongFmtSpec wxT("u, %") wxLongLongFmtSpec wxT("u)"), it.keyStart(), it.keyEnd()); 35} 36 37/** 38 * Returns the contents of a CRangeSet iterator as a string-presentation. 39 */ 40wxString StringFrom(CRangeMap<void>::iterator it) 41{ 42 return wxString::Format(wxT("(%") wxLongLongFmtSpec wxT("u, %") wxLongLongFmtSpec wxT("u)"), it.keyStart(), it.keyEnd()); 43} 44 45 46 47/** 48 * Returns the contents of a TestRangeMap as a string-representation. 49 * 50 * Using this function allows for easy comparison against the expected 51 * result of a particular test. 52 */ 53template <typename VALUE> 54wxString StringFrom(const CRangeMap<VALUE>& map) 55{ 56 wxString stream; 57 58 typename CRangeMap<VALUE>::const_iterator it = map.begin(); 59 for (; it != map.end(); ++it) { 60 if (it != map.begin()) { 61 stream << wxT(", "); 62 } 63 64 stream += StringFrom(it); 65 } 66 67 return wxT("[") + stream + wxT("]"); 68} 69 70 71 72DECLARE(RangeMap); 73 TestRangeMap m_map; 74 TestRangeMap m_mmaps[3]; 75 76 // Identifers for the multirange maps 77 enum Maps { 78 CONT = 0, // Continues ranges, IE no gap 79 SSAME = 1, // Seperated but equal 80 SDIFF = 2 // Seperated and not equal 81 }; 82 83 // Sets up a few maps with predefined ranges. 84 void setUp() { 85 m_map.insert(100, 150, 0); 86 87 m_mmaps[CONT].insert(100, 150, 0); 88 m_mmaps[CONT].insert(151, 200, 1); 89 90 m_mmaps[SDIFF].insert(100, 150, 0); 91 m_mmaps[SDIFF].insert(160, 200, 1); 92 93 m_mmaps[SSAME].insert(100, 150, 1); 94 m_mmaps[SSAME].insert(160, 200, 1); 95 96 ASSERT_EQUALS(wxT("[(100, 150, 0)]"), StringFrom(m_map)); 97 ASSERT_EQUALS(wxT("[(100, 150, 0), (151, 200, 1)]"), StringFrom(m_mmaps[CONT])); 98 ASSERT_EQUALS(wxT("[(100, 150, 0), (160, 200, 1)]"), StringFrom(m_mmaps[SDIFF])); 99 ASSERT_EQUALS(wxT("[(100, 150, 1), (160, 200, 1)]"), StringFrom(m_mmaps[SSAME])); 100 } 101 102 void tearDown() { 103 m_map.clear(); 104 m_mmaps[0].clear(); 105 m_mmaps[1].clear(); 106 m_mmaps[2].clear(); 107 } 108 109 110 /** 111 * Tests insertion into a map with a single range, checking against an 112 * expected result. 113 */ 114 void singleInsert(uint32 start, uint32 end, int value, const wxString& result) 115 { 116 TestRangeMap::iterator it = m_map.insert(start, end, value); 117 118 // Test that the correct iterator was returned 119 ASSERT_TRUE(it.keyStart() <= start); 120 ASSERT_TRUE(it.keyEnd() >= end); 121 ASSERT_EQUALS(*it, value); 122 123 // Check the resulting map 124 ASSERT_EQUALS(result, StringFrom(m_map)); 125 ASSERT_EQUALS((uint32)std::count(result.begin(), result.end(), '('), m_map.size()); 126 127 // Reset the rangemap 128 tearDown(); 129 setUp(); 130 } 131 132 void doErase(uint32 start, uint32 end, const wxString& result) 133 { 134 m_map.erase_range(start, end); 135 136 // Check the resulting map 137 ASSERT_EQUALS(result, StringFrom(m_map)); 138 ASSERT_EQUALS((uint32)std::count(result.begin(), result.end(), '('), m_map.size()); 139 140 // Reset the rangemap 141 tearDown(); 142 setUp(); 143 } 144 145 /** 146 * Tests insertion into a map with multiple ranges, checking against an 147 * expected result. 148 */ 149 void multiInsert(int type, uint32 start, uint32 end, int value, const wxString& result) 150 { 151 TestRangeMap::iterator it = m_mmaps[type].insert(start, end, value); 152 153 // Test that the correct iterator was returned 154 ASSERT_TRUE(it.keyStart() <= start); 155 ASSERT_TRUE(it.keyEnd() >= end); 156 ASSERT_EQUALS(*it, value); 157 158 // Check the resulting map 159 ASSERT_EQUALS(result, StringFrom(m_mmaps[type])); 160 ASSERT_EQUALS((uint32)std::count(result.begin(), result.end(), '('), m_mmaps[type].size()); 161 162 tearDown(); 163 setUp(); 164 } 165END_DECLARE; 166 167 168 169TEST(RangeMap, DefaultConstructor) 170{ 171 TestRangeMap map; 172 173 ASSERT_EQUALS(0u, map.size()); 174 ASSERT_TRUE(map.empty()); 175} 176 177 178TEST(RangeMap, CopyConstructor) 179{ 180 // Check basic copying 181 TestRangeMap mapA(m_map); 182 TestRangeMap mapB(m_mmaps[CONT]); 183 TestRangeMap mapC(m_mmaps[SSAME]); 184 TestRangeMap mapD(m_mmaps[SDIFF]); 185 186 ASSERT_EQUALS(m_map, mapA); 187 ASSERT_EQUALS(m_mmaps[CONT], mapB); 188 ASSERT_EQUALS(m_mmaps[SSAME], mapC); 189 ASSERT_EQUALS(m_mmaps[SDIFF], mapD); 190 191 192 // The copies must not affect the originals 193 mapA.insert(125, 175, 2); 194 mapB.insert(125, 175, 2); 195 mapC.insert(125, 175, 2); 196 mapD.insert(125, 175, 2); 197 198 ASSERT_FALSE(m_map == mapA); 199 ASSERT_FALSE(m_mmaps[CONT] == mapB); 200 ASSERT_FALSE(m_mmaps[SSAME] == mapC); 201 ASSERT_FALSE(m_mmaps[SDIFF] == mapD); 202} 203 204 205TEST(RangeMap, AssignmentOperator) 206{ 207 // Check basic assignment 208 TestRangeMap mapA, mapB; 209 mapA = mapB = m_map; 210 211 ASSERT_EQUALS(m_map, mapA); 212 ASSERT_EQUALS(m_map, mapB); 213 214 215 // The copies must not affect the originals 216 mapA.insert(125, 175, 2); 217 mapB.insert(125, 175, 2); 218 219 ASSERT_TRUE(mapA == mapB); 220 ASSERT_FALSE(m_map == mapA); 221 ASSERT_FALSE(m_map == mapB); 222} 223 224 225TEST(RangeMap, Equality) 226{ 227 TestRangeMap mapA(m_mmaps[SSAME]), mapB(m_mmaps[SDIFF]); 228 229 ASSERT_FALSE(mapA == mapB); 230 231 mapA = mapB; 232 233 ASSERT_EQUALS(mapA, mapB); 234 235 mapA.insert(10, 20, 3); 236 237 ASSERT_FALSE(mapA == mapB); 238} 239 240 241TEST(RangeMap, Iterators) 242{ 243 // Adding a third range 244 m_mmaps[CONT].insert(125, 175, 2); 245 TestRangeMap map(m_mmaps[CONT]); 246 247 TestRangeMap::iterator it = map.begin(); 248 TestRangeMap::iterator it_orig = map.begin(); 249 TestRangeMap::iterator it_other = map.end(); 250 251 ASSERT_EQUALS(wxT("(100, 124, 0)"), StringFrom(it)); 252 253 it_other = ++it; 254 255 ASSERT_EQUALS(wxT("(125, 175, 2)"), StringFrom(it)); 256 ASSERT_EQUALS(it_other, it++); 257 ASSERT_EQUALS(wxT("(176, 200, 1)"), StringFrom(it)); 258 259 it_other = --it; 260 261 ASSERT_EQUALS(wxT("(125, 175, 2)"), StringFrom(it)); 262 ASSERT_EQUALS(it_other, it--); 263 ASSERT_EQUALS(wxT("(100, 124, 0)"), StringFrom(it)); 264} 265 266 267TEST(RangeMap, Erase) 268{ 269 // Adding a third range 270 m_mmaps[CONT].insert(125, 175, 2); 271 272 // The expected results from forwards deletion 273 TestRangeMap map(m_mmaps[CONT]); 274 wxString expectedFW[4]; 275 expectedFW[0] = wxT("[(100, 124, 0), (125, 175, 2), (176, 200, 1)]"); 276 expectedFW[1] = wxT("[(125, 175, 2), (176, 200, 1)]"); 277 expectedFW[2] = wxT("[(176, 200, 1)]"); 278 expectedFW[3] = wxT("[]"); 279 280 for (int i = 0; i < 4; ++i) { 281 ASSERT_EQUALS(expectedFW[i], StringFrom(map)); 282 283 if (map.begin() != map.end()) { 284 map.erase(map.begin()); 285 } 286 } 287 288 // Test the expected result from backwards deletion 289 map = m_mmaps[CONT]; 290 wxString expectedBW[4]; 291 expectedBW[0] = wxT("[(100, 124, 0), (125, 175, 2), (176, 200, 1)]"); 292 expectedBW[1] = wxT("[(100, 124, 0), (125, 175, 2)]"); 293 expectedBW[2] = wxT("[(100, 124, 0)]"); 294 expectedBW[3] = wxT("[]"); 295 296 for (int i = 0; i < 4; ++i) { 297 ASSERT_EQUALS(expectedBW[i], StringFrom(map)); 298 299 if (map.begin() != map.end()) { 300 map.erase(--map.end()); 301 } 302 } 303} 304 305 306TEST(RangeMap, Clear) 307{ 308 m_map.clear(); 309 ASSERT_TRUE(m_map.empty()); 310 ASSERT_EQUALS(0u, m_map.size()); 311 ASSERT_EQUALS(wxT("[]"), StringFrom(m_map)); 312 313 for (int i = 0; i < 3; ++i) { 314 m_mmaps[i].clear(); 315 ASSERT_TRUE(m_mmaps[i].empty()); 316 ASSERT_EQUALS(0u, m_mmaps[i].size()); 317 ASSERT_EQUALS(wxT("[]"), StringFrom(m_mmaps[i])); 318 } 319} 320 321 322TEST(RangeMap, FindRange) 323{ 324 // Adding a third range 325 m_mmaps[CONT].insert(125, 175, 2); 326 TestRangeMap map(m_mmaps[CONT]); 327 328 ASSERT_EQUALS(map.end(), map.find_range(0)); 329 ASSERT_EQUALS(map.end(), map.find_range(98)); 330 ASSERT_EQUALS(map.end(), map.find_range(99)); 331 332 ASSERT_EQUALS(wxT("(100, 124, 0)"), StringFrom(map.find_range(100))); 333 ASSERT_EQUALS(wxT("(100, 124, 0)"), StringFrom(map.find_range(112))); 334 ASSERT_EQUALS(wxT("(100, 124, 0)"), StringFrom(map.find_range(124))); 335 336 ASSERT_EQUALS(wxT("(125, 175, 2)"), StringFrom(map.find_range(125))); 337 ASSERT_EQUALS(wxT("(125, 175, 2)"), StringFrom(map.find_range(150))); 338 ASSERT_EQUALS(wxT("(125, 175, 2)"), StringFrom(map.find_range(175))); 339 340 ASSERT_EQUALS(wxT("(176, 200, 1)"), StringFrom(map.find_range(176))); 341 ASSERT_EQUALS(wxT("(176, 200, 1)"), StringFrom(map.find_range(186))); 342 ASSERT_EQUALS(wxT("(176, 200, 1)"), StringFrom(map.find_range(200))); 343 344 ASSERT_EQUALS(map.end(), map.find_range(201)); 345 ASSERT_EQUALS(map.end(), map.find_range(202)); 346 ASSERT_EQUALS(map.end(), map.find_range(250)); 347} 348 349 350TEST(RangeMap, InvalidErase) 351{ 352 ASSERT_RAISES(CInvalidParamsEx, m_map.erase(m_map.end())); 353} 354 355 356TEST(RangeMap, InvalidInsert) 357{ 358 ASSERT_RAISES(CInvalidParamsEx, m_map.insert(10, 9, 8)); 359} 360 361 362///////////////////////////////////////////////// 363// The following tests exercize the merging algorithm. 364// The comment before each comment descrices the RangeMaps used to test, 365// and which types of ranges are tested. For example, the description 366// "a / b <-> c / d" is to be read as: 367// Insert range starting at a or b, ending at c or d. 368 369 370// Single insert before start <-> before start. 371TEST(RangeMap, SingleInsert_BeforeStart_BeforeStart) 372{ 373 // Test with same and different type 374 singleInsert(0, 90, 0, wxT("[(0, 90, 0), (100, 150, 0)]")); 375 singleInsert(0, 90, 1, wxT("[(0, 90, 1), (100, 150, 0)]")); 376} 377 378 379// Single insert before start <-> touching start. 380TEST(RangeMap, SingleInsert_BeforeStart_TouchingStart) 381{ 382 singleInsert(0, 99, 0, wxT("[(0, 150, 0)]")); // Same type 383 singleInsert(0, 99, 1, wxT("[(0, 99, 1), (100, 150, 0)]")); // Different type 384} 385 386 387// Single insert before start <-> at start / inside. 388TEST(RangeMap, SingleInsert_BeforeStart_AtStart_InSide) 389{ 390 for (int offset = 0; offset < 3; ++offset) { // at start, inside, inside 391 singleInsert(0, 100 + offset, 0, wxT("[(0, 150, 0)]")); // Same type 392 393 wxString expected = wxString::Format(wxT("[(0, %u, 1), (%u, 150, 0)]"), 100 + offset, 101 + offset); 394 singleInsert(0, 100 + offset, 1, expected); // Different type 395 } 396} 397 398 399// Single insert before start / touching start <-> at end / touching end / after end. 400TEST(RangeMap, SingleInsert_BeforeStart_TouchingStart_AtEnd_TouchingEnd_AfterEnd) 401{ 402 // Test with same and different type 403 for (int type = 0; type < 2; ++type) { 404 // (at end, touching end, after end) 405 for (int end_offset = 0; end_offset < 3; ++end_offset) { 406 // (before start, touching start) 407 for (int start_offset = 0; start_offset < 2; ++start_offset) { 408 wxString expected = wxString::Format(wxT("[(%u, %u, %i)]"), 98 + start_offset, 150 + end_offset, type); 409 singleInsert(98 + start_offset, 150 + end_offset, type, expected); 410 } 411 } 412 } 413} 414 415 416// Single insert touching start <-> touching start. 417TEST(RangeMap, SingleInsert_TouchingStart_TouchingStart) 418{ 419 singleInsert(99, 99, 0, wxT("[(99, 150, 0)]")); // Same 420 singleInsert(99, 99, 1, wxT("[(99, 99, 1), (100, 150, 0)]")); // Different 421} 422 423 424// Single insert touching start / at start <-> at start / inside. 425TEST(RangeMap, SingleInsert_TouchingStart_AtStart_AtStart_Inside) 426{ 427 for (int offset_a = 0; offset_a < 2; ++offset_a) { // (touching start, at start) 428 for (int offset_b = 0; offset_b < 2; ++offset_b) { // (at start, inside) 429 int start = 99 + offset_a; 430 int end = 100 + offset_b; 431 432 // Same 433 singleInsert(start, end, 0, wxString::Format(wxT("[(%u, 150, 0)]"), 99 + offset_a)); 434 435 // Different 436 wxString exp = wxString::Format(wxT("[(%u, %u, 1), (%u, 150, 0)]"), start, end, 101 + offset_b); 437 singleInsert(start, end, 1, exp); 438 } 439 } 440} 441 442 443// Single insert at start <-> at end / touching end / after end. 444TEST(RangeMap, SingleInsert_AtStart_AtEnd_TouchingEnd_AfterEnd) 445{ 446 // (at end, touching end, after end) 447 for (int offset = 0; offset < 3; ++offset) { 448 // Same 449 singleInsert(100, 150 + offset, 0, wxString::Format(wxT("[(100, %u, 0)]"), 150 + offset)); 450 // Different 451 singleInsert(100, 150 + offset, 1, wxString::Format(wxT("[(100, %u, 1)]"), 150 + offset)); 452 } 453} 454 455 456// Single insert inside / at end <-> at end / touching end / after end. 457TEST(RangeMap, SingleInsert_Inside_AtEnd_AtEnd_TouchingEnd_AfterEnd) 458{ 459 // (inside, at end) 460 for (int offset_a = 0; offset_a < 2; ++offset_a) { 461 // (at end, touching end, after end) 462 for (int offset_b = 0; offset_b < 3; ++offset_b) { 463 int start = 149 + offset_a; 464 int end = 150 + offset_b; 465 466 // Same 467 singleInsert(start, end, 0, wxString::Format(wxT("[(100, %u, 0)]"), end)); 468 469 // Different 470 singleInsert(start, end, 1, wxString::Format(wxT("[(100, %u, 0), (%u, %u, 1)]"), 148 + offset_a, start, end)); 471 } 472 } 473} 474 475 476// Single insert touching end <-> touching end / after end. 477TEST(RangeMap, SingleInsert_TouchingEnd_TouchingEnd_AfterEnd) 478{ 479 // (touching end, after end) 480 for (int offset = 0; offset < 2; ++offset) { 481 int end = 151 + offset; 482 483 // Same 484 singleInsert(151, end, 0, wxString::Format(wxT("[(100, %u, 0)]"), end)); 485 486 // Different 487 singleInsert(151, end, 1, wxString::Format(wxT("[(100, 150, 0), (151, %u, 1)]"), end)); 488 } 489} 490 491 492// Single insert after end <-> after end. 493TEST(RangeMap, SingleInsert_AfterEnd_AfterEnd) 494{ 495 singleInsert(152, 170, 0, wxT("[(100, 150, 0), (152, 170, 0)]")); // Same 496 singleInsert(152, 170, 1, wxT("[(100, 150, 0), (152, 170, 1)]")); // Different 497} 498 499 500// Multi insert before start <-> before start. 501TEST(RangeMap, MultiInsert_BeforeStart_BeforeStart) 502{ 503 for (int type = 0; type < 2; ++type) { // Test with same and different type 504 multiInsert(CONT, 0, 90, type, wxString(wxT("[(0, 90, ")) << type << wxT("), (100, 150, 0), (151, 200, 1)]")); 505 multiInsert(SDIFF, 0, 90, type, wxString(wxT("[(0, 90, ")) << type << wxT("), (100, 150, 0), (160, 200, 1)]")); 506 multiInsert(SSAME, 0, 90, type, wxString(wxT("[(0, 90, ")) << type << wxT("), (100, 150, 1), (160, 200, 1)]")); 507 } 508} 509 510 511// Multi insert before start <-> touching start. 512TEST(RangeMap, MultiInsert_BeforeStart_TouchingStart) 513{ 514 multiInsert(CONT, 0, 99, 0, wxT("[(0, 150, 0), (151, 200, 1)]")); 515 multiInsert(SDIFF, 0, 99, 0, wxT("[(0, 150, 0), (160, 200, 1)]")); 516 multiInsert(SSAME, 0, 99, 0, wxT("[(0, 99, 0), (100, 150, 1), (160, 200, 1)]")); 517 518 multiInsert(CONT, 0, 99, 1, wxT("[(0, 99, 1), (100, 150, 0), (151, 200, 1)]")); 519 multiInsert(SDIFF, 0, 99, 1, wxT("[(0, 99, 1), (100, 150, 0), (160, 200, 1)]")); 520 multiInsert(SSAME, 0, 99, 1, wxT("[(0, 150, 1), (160, 200, 1)]")); 521} 522 523 524// Multi insert before start <-> at start / inside. 525TEST(RangeMap, MultiInsert_BeforeStart_AtStart_InSide) 526{ 527 for (int offset = 0; offset < 3; ++offset) { // (at start, inside, inside) 528 int end = 100 + offset; 529 530 multiInsert(CONT, 0, end, 0, wxT("[(0, 150, 0), (151, 200, 1)]")); 531 multiInsert(SDIFF, 0, end, 0, wxT("[(0, 150, 0), (160, 200, 1)]")); 532 multiInsert(SSAME, 0, end, 0, wxString::Format(wxT("[(0, %u, 0), (%u, 150, 1), (160, 200, 1)]"), end, 101 + offset)); 533 534 multiInsert(CONT, 0, end, 1, wxString::Format(wxT("[(0, %u, 1), (%u, 150, 0), (151, 200, 1)]"), end, 101 + offset)); 535 multiInsert(SDIFF, 0, end, 1, wxString::Format(wxT("[(0, %u, 1), (%u, 150, 0), (160, 200, 1)]"), end, 101 + offset)); 536 multiInsert(SSAME, 0, end, 1, wxT("[(0, 150, 1), (160, 200, 1)]")); 537 } 538} 539 540 541// Multi insert before start / touching start <-> at end / touching end / after end. 542TEST(RangeMap, MultiInsert_BeforeStart_TouchingStart_AtEnd_TouchingEnd_AfterEnd) 543{ 544 for (int end_offset = 0; end_offset < 3; ++end_offset) { // (at end, touching end, after end) 545 for (int start_offset = 0; start_offset < 2; ++start_offset) { // (before start, touching start) 546 int start = 98 + start_offset; 547 int end = 150 + end_offset; 548 549 multiInsert(CONT, start, end, 0, wxString::Format(wxT("[(%u, %u, 0), (%u, 200, 1)]"), start, end, end + 1)); 550 multiInsert(SDIFF, start, end, 0, wxString::Format(wxT("[(%u, %u, 0), (160, 200, 1)]"), start, end)); 551 multiInsert(SSAME, start, end, 0, wxString::Format(wxT("[(%u, %u, 0), (160, 200, 1)]"), start, end)); 552 553 multiInsert(CONT, start, end, 1, wxString::Format(wxT("[(%u, 200, 1)]"), start)); 554 multiInsert(SDIFF, start, end, 1, wxString::Format(wxT("[(%u, %u, 1), (160, 200, 1)]"), start, end)); 555 multiInsert(SSAME, start, end, 1, wxString::Format(wxT("[(%u, %u, 1), (160, 200, 1)]"), start, end)); 556 } 557 } 558} 559 560 561// Multi insert touching start <-> touching start. 562TEST(RangeMap, MultiInsert_TouchingStart_TouchingStart) 563{ 564 multiInsert(CONT, 99, 99, 0, wxT("[(99, 150, 0), (151, 200, 1)]")); 565 multiInsert(SDIFF, 99, 99, 0, wxT("[(99, 150, 0), (160, 200, 1)]")); 566 multiInsert(SSAME, 99, 99, 0, wxT("[(99, 99, 0), (100, 150, 1), (160, 200, 1)]")); 567 568 multiInsert(CONT, 99, 99, 1, wxT("[(99, 99, 1), (100, 150, 0), (151, 200, 1)]")); 569 multiInsert(SDIFF, 99, 99, 1, wxT("[(99, 99, 1), (100, 150, 0), (160, 200, 1)]")); 570 multiInsert(SSAME, 99, 99, 1, wxT("[(99, 150, 1), (160, 200, 1)]")); 571} 572 573 574// Multi insert touching start / at start <-> at start / inside. 575TEST(RangeMap, MultiInsert_TouchingStart_AtStart_AtStart_Inside) 576{ 577 for (int offset_a = 0; offset_a < 2; ++offset_a) { // (touching start, at start) 578 for (int offset_b = 0; offset_b < 2; ++offset_b) { // (at start, inside) 579 int start = 99 + offset_a; 580 int end = 100 + offset_b; 581 582 multiInsert(CONT, start, end, 0, wxString::Format(wxT("[(%u, 150, 0), (151, 200, 1)]"), start)); 583 multiInsert(SDIFF, start, end, 0, wxString::Format(wxT("[(%u, 150, 0), (160, 200, 1)]"), start)); 584 multiInsert(SSAME, start, end, 0, wxString::Format(wxT("[(%u, %u, 0), (%u, 150, 1), (160, 200, 1)]"), start, end, end + 1)); 585 586 multiInsert(CONT, start, end, 1, wxString::Format(wxT("[(%u, %u, 1), (%u, 150, 0), (151, 200, 1)]"), start, end, end + 1)); 587 multiInsert(SDIFF, start, end, 1, wxString::Format(wxT("[(%u, %u, 1), (%u, 150, 0), (160, 200, 1)]"), start, end, end + 1)); 588 multiInsert(SSAME, start, end, 1, wxString::Format(wxT("[(%u, 150, 1), (160, 200, 1)]"), start)); 589 } 590 } 591} 592 593 594// rangeMap: Multi insert at start <-> at end / touching end / after end. 595TEST(RangeMap, MultiInsert_AtStart_AtEnd_TouchingEnd_AfterEnd) 596{ 597 for (int offset = 0; offset < 3; ++offset) { // (at end, touching end, after end) 598 int start = 100; 599 int end = 150 + offset; 600 601 multiInsert(CONT, start, end, 0, wxString::Format(wxT("[(%u, %u, 0), (%u, 200, 1)]"), start, end, end + 1)); 602 multiInsert(SDIFF, start, end, 0, wxString::Format(wxT("[(%u, %u, 0), (160, 200, 1)]"), start, end)); 603 multiInsert(SSAME, start, end, 0, wxString::Format(wxT("[(%u, %u, 0), (160, 200, 1)]"), start, end)); 604 605 multiInsert(CONT, start, end, 1, wxString::Format(wxT("[(%u, 200, 1)]"), start)); 606 multiInsert(SDIFF, start, end, 1, wxString::Format(wxT("[(%u, %u, 1), (160, 200, 1)]"), start, end)); 607 multiInsert(SSAME, start, end, 1, wxString::Format(wxT("[(%u, %u, 1), (160, 200, 1)]"), start, end)); 608 } 609} 610 611 612// Multi insert inside <-> inside. 613TEST(RangeMap, MultiInsert_Inside_Inside) 614{ 615 multiInsert(CONT, 110, 140, 0, wxT("[(100, 150, 0), (151, 200, 1)]")); 616 multiInsert(SDIFF, 110, 140, 0, wxT("[(100, 150, 0), (160, 200, 1)]")); 617 multiInsert(SSAME, 110, 140, 0, wxT("[(100, 109, 1), (110, 140, 0), (141, 150, 1), (160, 200, 1)]")); 618 619 multiInsert(CONT, 110, 140, 1, wxT("[(100, 109, 0), (110, 140, 1), (141, 150, 0), (151, 200, 1)]")); 620 multiInsert(SDIFF, 110, 140, 1, wxT("[(100, 109, 0), (110, 140, 1), (141, 150, 0), (160, 200, 1)]")); 621 multiInsert(SSAME, 110, 140, 1, wxT("[(100, 150, 1), (160, 200, 1)]")); 622} 623 624 625// Multi insert inside / at end <-> at end / touching end / after end. 626TEST(RangeMap, MultiInsert_Inside_AtEnd_AtEnd_TouchingEnd_AfterEnd) 627{ 628 for (int offset_a = 0; offset_a < 2; ++offset_a) { // (inside, at end) 629 for (int offset_b = 0; offset_b < 3; ++offset_b) { // (at end, touching end, after end) 630 int start = 149 + offset_a; 631 int end = 150 + offset_b; 632 633 multiInsert(CONT, start, end, 0, wxString::Format(wxT("[(100, %u, 0), (%u, 200, 1)]"), end, end + 1)); 634 multiInsert(SDIFF, start, end, 0, wxString::Format(wxT("[(100, %u, 0), (160, 200, 1)]"), end)); 635 multiInsert(SSAME, start, end, 0, wxString::Format(wxT("[(100, %u, 1), (%u, %u, 0), (160, 200, 1)]"), start - 1, start, end)); 636 637 multiInsert(CONT, start, end, 1, wxString::Format(wxT("[(100, %u, 0), (%u, 200, 1)]"), start - 1, start)); 638 multiInsert(SDIFF, start, end, 1, wxString::Format(wxT("[(100, %u, 0), (%u, %u, 1), (160, 200, 1)]"), start - 1, start, end)); 639 multiInsert(SSAME, start, end, 1, wxString::Format(wxT("[(100, %u, 1), (160, 200, 1)]"), end)); 640 } 641 } 642} 643 644 645// Multi insert touching end <-> touching end / after end. 646TEST(RangeMap, MultiInsert_TouchingEnd_TouchingEnd_AfterEnd) 647{ 648 for (int offset = 0; offset < 2; ++offset) { // (touching end, after end) 649 int start = 151; 650 int end = 151 + offset; 651 652 multiInsert(CONT, start, end, 0, wxString::Format(wxT("[(100, %u, 0), (%u, 200, 1)]"), end, end + 1)); 653 multiInsert(SDIFF, start, end, 0, wxString::Format(wxT("[(100, %u, 0), (160, 200, 1)]"), end)); 654 multiInsert(SSAME, start, end, 0, wxString::Format(wxT("[(100, 150, 1), (%u, %u, 0), (160, 200, 1)]"), start, end)); 655 656 multiInsert(CONT, start, end, 1, wxString::Format(wxT("[(100, 150, 0), (%u, 200, 1)]"), start)); 657 multiInsert(SDIFF, start, end, 1, wxString::Format(wxT("[(100, 150, 0), (%u, %u, 1), (160, 200, 1)]"), start, end)); 658 multiInsert(SSAME, start, end, 1, wxString::Format(wxT("[(100, %u, 1), (160, 200, 1)]"), end)); 659 } 660} 661 662 663// Multi insert after end <-> after end. 664TEST(RangeMap, MultiInsert_AfterEnd_AfterEnd) 665{ 666 multiInsert(CONT, 152, 170, 0, wxT("[(100, 150, 0), (151, 151, 1), (152, 170, 0), (171, 200, 1)]")); 667 multiInsert(SDIFF, 152, 170, 0, wxT("[(100, 150, 0), (152, 170, 0), (171, 200, 1)]")); 668 multiInsert(SSAME, 152, 170, 0, wxT("[(100, 150, 1), (152, 170, 0), (171, 200, 1)]")); 669 670 multiInsert(CONT, 152, 170, 1, wxT("[(100, 150, 0), (151, 200, 1)]")); 671 multiInsert(SDIFF, 152, 170, 1, wxT("[(100, 150, 0), (152, 200, 1)]")); 672 multiInsert(SSAME, 152, 170, 1, wxT("[(100, 150, 1), (152, 200, 1)]")); 673} 674 675 676///////////////////////////////////////////////// 677// The following tests exercize the erase function. 678// Since the erase function use the insert function, all 679// that is needed is to test that no merging is done. 680 681// Single erase before start <-> before start. 682TEST(RangeMap, Erase_BeforeStart_BeforeStart) 683{ 684 // Test with same and different type 685 doErase(0, 90, wxT("[(100, 150, 0)]")); 686} 687 688 689// Single erase before start <-> touching start. 690TEST(RangeMap, Erase_BeforeStart_TouchingStart) 691{ 692 doErase(0, 99, wxT("[(100, 150, 0)]")); 693} 694 695 696// Single erase before start <-> at start / inside. 697TEST(RangeMap, Erase_BeforeStart_AtStart_InSide) 698{ 699 for (int offset = 0; offset < 3; ++offset) { // at start, inside, inside 700 doErase(0, 100 + offset, wxString::Format(wxT("[(%u, 150, 0)]"), 100 + offset + 1)); 701 } 702} 703 704 705// Single erase before start / touching start <-> at end / touching end / after end. 706TEST(RangeMap, Erase_BeforeStart_TouchingStart_AtEnd_TouchingEnd_AfterEnd) 707{ 708 // (at end, touching end, after end) 709 for (int end_offset = 0; end_offset < 3; ++end_offset) { 710 // (before start, touching start) 711 for (int start_offset = 0; start_offset < 2; ++start_offset) { 712 doErase(98 + start_offset, 150 + end_offset, wxT("[]")); 713 } 714 } 715} 716 717 718// Single erase touching start <-> touching start. 719TEST(RangeMap, Erase_TouchingStart_TouchingStart) 720{ 721 doErase(99, 99, wxT("[(100, 150, 0)]")); 722} 723 724 725// Single erase touching start / at start <-> at start / inside. 726TEST(RangeMap, Erase_TouchingStart_AtStart_AtStart_Inside) 727{ 728 for (int offset_a = 0; offset_a < 2; ++offset_a) { // (touching start, at start) 729 for (int offset_b = 0; offset_b < 2; ++offset_b) { // (at start, inside) 730 int start = 99 + offset_a; 731 int end = 100 + offset_b; 732 733 doErase(start, end, wxString::Format(wxT("[(%u, 150, 0)]"), 100 + offset_b + 1)); 734 } 735 } 736} 737 738 739// Single erase at start <-> at end / touching end / after end. 740TEST(RangeMap, Erase_AtStart_AtEnd_TouchingEnd_AfterEnd) 741{ 742 // (at end, touching end, after end) 743 for (int offset = 0; offset < 3; ++offset) { 744 doErase(100, 150 + offset, wxT("[]")); 745 } 746} 747 748 749// Single erase inside / at end <-> at end / touching end / after end. 750TEST(RangeMap, Erase_Inside_AtEnd_AtEnd_TouchingEnd_AfterEnd) 751{ 752 // (inside, at end) 753 for (int offset_a = 0; offset_a < 2; ++offset_a) { 754 // (at end, touching end, after end) 755 for (int offset_b = 0; offset_b < 3; ++offset_b) { 756 int start = 149 + offset_a; 757 int end = 150 + offset_b; 758 759 doErase(start, end, wxString::Format(wxT("[(100, %u, 0)]"), start - 1)); 760 } 761 } 762} 763 764 765// Single erase touching end <-> touching end / after end. 766TEST(RangeMap, Erase_TouchingEnd_TouchingEnd_AfterEnd) 767{ 768 // (touching end, after end) 769 for (int offset = 0; offset < 2; ++offset) { 770 int end = 151 + offset; 771 772 doErase(151, end, wxT("[(100, 150, 0)]")); 773 } 774} 775 776 777// Single erase after end <-> after end. 778TEST(RangeMap, Erase_AfterEnd_AfterEnd) 779{ 780 doErase(152, 170, wxT("[(100, 150, 0)]")); 781} 782 783 784TEST(RangeMap, Swap) 785{ 786 { 787 TestRangeMap mapA = m_mmaps[CONT]; 788 TestRangeMap mapB = m_mmaps[SSAME]; 789 790 ASSERT_EQUALS(mapA, m_mmaps[CONT]); 791 ASSERT_EQUALS(mapB, m_mmaps[SSAME]); 792 793 std::swap(mapA, mapB); 794 795 ASSERT_EQUALS(mapB, m_mmaps[CONT]); 796 ASSERT_EQUALS(mapA, m_mmaps[SSAME]); 797 } 798 799 { 800 TestRangeMap mapA = m_mmaps[CONT]; 801 TestRangeMap mapB = m_mmaps[SSAME]; 802 803 ASSERT_EQUALS(mapA, m_mmaps[CONT]); 804 ASSERT_EQUALS(mapB, m_mmaps[SSAME]); 805 806 mapA.swap(mapB); 807 808 ASSERT_EQUALS(mapB, m_mmaps[CONT]); 809 ASSERT_EQUALS(mapA, m_mmaps[SSAME]); 810 } 811} 812 813 814///////////////////////////////////////////////// 815// The following test exercize the CRangeSet specialization. 816// 817 818TEST(RangeMap, RangeSet) 819{ 820 CRangeSet set; 821 822 set.insert(0, 10); 823 set.insert(20, 30); 824 set.insert(40, 50); 825 826 ASSERT_EQUALS(wxT("[(0, 10), (20, 30), (40, 50)]"), StringFrom(set)); 827 ASSERT_EQUALS(3u, set.size()); 828 829 { 830 CRangeSet::iterator it = set.begin(); 831 unsigned value = 0; 832 for (; it != set.end(); ++it, value += 20) { 833 ASSERT_EQUALS(value, it.keyStart()); 834 ASSERT_EQUALS(value + 10, it.keyEnd()); 835 } 836 837 ASSERT_EQUALS(60u, value); 838 } 839 840 set.erase_range(5, 45); 841 842 ASSERT_EQUALS(wxT("[(0, 4), (46, 50)]"), StringFrom(set)); 843 ASSERT_EQUALS(2u, set.size()); 844} 845 846