// Test insertWindow() and windowDestroyed() by random stacking operations. void SuperStackerTest::testStateRandom() { MRestacker mrs; WindowVec wins; bool bottomFirst; if (optLearning) QSKIP("nothing to learn", SkipSingle); // Verify that MRestacker is born with an empty state, // and that setting an empty set of windows works. mrs.verifyState(wins); mrs.setState(wins, bottomFirst=false); QVERIFY(mrs.verifyState(wins, bottomFirst)); mrs.setState(wins, bottomFirst=true); QVERIFY(mrs.verifyState(wins, bottomFirst)); // Test until each operations is executed >= @optNRandomTests times. unsigned nadds = 0, nmoves = 0, nremoves = 0, nshuffles = 0; while (nadds < optNRandomTests || nmoves < optNRandomTests || nremoves < optNRandomTests || nshuffles < optNRandomTests) { enum test { ADD, MOVE, REMOVE, SHUFFLE, LAST } what; switch (what = test(random() % int(LAST))) { default: break; case REMOVE: // Exercise windowDestroyed() by removing a random window, // if there's any. Otherwise ADD one. if (!wins.isEmpty()) { unsigned idx = random() % wins.count(); mrs.windowDestroyed(wins[idx]); wins.remove(idx); QVERIFY(mrs.verifyState(wins, bottomFirst)); nremoves++; break; } case MOVE: // Exercise configureWindow() by moving a window around, // or ADD:ing one if there's nothing to move. if (!wins.isEmpty()) { int idx; Window win, below; // What to move and where. idx = random() % wins.count(); win = wins[idx]; wins.remove(idx); idx = random() % (wins.count()+1); // What shall be @below? if (bottomFirst) // BOTTOM, win1, win2, ..., winN, TOP below = idx > 0 ? wins[idx-1] : None; else // TOP, win1, win2, ..., winN, BOTTOM below = idx < wins.count() ? wins[idx] : None; wins.insert(idx, win); mrs.windowConfigured(win, below); QVERIFY(mrs.verifyState(wins, bottomFirst)); nmoves++; break; } case ADD: { // Exercise createWindow() by adding a new window // at a random place. int idx; Window win, above; // What to insert and where. do win = 1+random(); while (wins.contains(win)); idx = random() % (wins.count()+1); // What shall be @above? if (bottomFirst) // BOTTOM, win1, win2, ..., winN, TOP above = idx < wins.count() ? wins[idx] : None; else // TOP, win1, win2, ..., winN, BOTTOM above = idx > 0 ? wins[idx-1] : None; wins.insert(idx, win); mrs.windowCreated(win, above); QVERIFY(mrs.verifyState(wins, bottomFirst)); nadds++; break; } case SHUFFLE: // Exercise setState() by setting a random order. // Also change @bottomFirst randomly. std::random_shuffle(wins.begin(), wins.end(), libcRandom); mrs.setState(wins, bottomFirst = random() % 2); QVERIFY(mrs.verifyState(wins, bottomFirst)); nshuffles++; break; } } qDebug("\n " "tested nadds=%u, nmoves=%u, nremoves=%u, nshuffles=%u", nadds, nmoves, nremoves, nshuffles); }