|
| 1 | +/****************************************************************************** |
| 2 | + * MODULE : tree_observer_test.cpp |
| 3 | + * DESCRIPTION: Tests for raw tree modifications and refcount integrity |
| 4 | + * COPYRIGHT : (C) 2026 Mogan developers |
| 5 | + ******************************************************************************* |
| 6 | + * This software falls under the GNU general public license version 3 or later. |
| 7 | + * It comes WITHOUT ANY WARRANTY WHATSOEVER. For details, see the file LICENSE |
| 8 | + * in the root directory or <http://www.gnu.org/licenses/gpl-3.0.html>. |
| 9 | + ******************************************************************************/ |
| 10 | + |
| 11 | +#include <QtTest/QtTest> |
| 12 | + |
| 13 | +#include "base.hpp" |
| 14 | +#include "tree_helper.hpp" |
| 15 | +#include "tree_observer.hpp" |
| 16 | + |
| 17 | +using namespace moebius; |
| 18 | + |
| 19 | +class TestTreeObserver : public QObject { |
| 20 | + Q_OBJECT |
| 21 | + |
| 22 | +private slots: |
| 23 | + void init () { init_lolly (); } |
| 24 | + |
| 25 | + void test_raw_insert (); |
| 26 | + void test_raw_remove (); |
| 27 | + void test_insert_remove_refcount (); |
| 28 | +}; |
| 29 | + |
| 30 | +void |
| 31 | +TestTreeObserver::test_raw_insert () { |
| 32 | + tree doc (DOCUMENT, tree ("a"), tree ("b"), tree ("d")); |
| 33 | + // 在头部插入 |
| 34 | + raw_insert (doc, 0, tree (DOCUMENT, tree ("x"))); |
| 35 | + QVERIFY (N (doc) == 4); |
| 36 | + QVERIFY (doc[0] == tree ("x")); |
| 37 | + QVERIFY (doc[1] == tree ("a")); |
| 38 | + // 在中部插入多个 |
| 39 | + raw_insert (doc, 2, tree (DOCUMENT, tree ("m"), tree ("n"))); |
| 40 | + QVERIFY (N (doc) == 6); |
| 41 | + QVERIFY (doc[1] == tree ("a")); |
| 42 | + QVERIFY (doc[2] == tree ("m")); |
| 43 | + QVERIFY (doc[3] == tree ("n")); |
| 44 | + QVERIFY (doc[4] == tree ("b")); |
| 45 | + QVERIFY (doc[5] == tree ("d")); |
| 46 | + // 在尾部插入 |
| 47 | + raw_insert (doc, 6, tree (DOCUMENT, tree ("z"))); |
| 48 | + QVERIFY (N (doc) == 7); |
| 49 | + QVERIFY (doc[6] == tree ("z")); |
| 50 | +} |
| 51 | + |
| 52 | +void |
| 53 | +TestTreeObserver::test_raw_remove () { |
| 54 | + tree doc (DOCUMENT, tree ("a"), tree ("b"), tree ("c"), tree ("d"), |
| 55 | + tree ("e")); |
| 56 | + // 头部删除 |
| 57 | + raw_remove (doc, 0, 1); |
| 58 | + QVERIFY (N (doc) == 4); |
| 59 | + QVERIFY (doc[0] == tree ("b")); |
| 60 | + // 中部删除多个 |
| 61 | + raw_remove (doc, 1, 2); |
| 62 | + QVERIFY (N (doc) == 2); |
| 63 | + QVERIFY (doc[0] == tree ("b")); |
| 64 | + QVERIFY (doc[1] == tree ("e")); |
| 65 | + // 尾部删除 |
| 66 | + raw_remove (doc, 1, 1); |
| 67 | + QVERIFY (N (doc) == 1); |
| 68 | + QVERIFY (doc[0] == tree ("b")); |
| 69 | +} |
| 70 | + |
| 71 | +void |
| 72 | +TestTreeObserver::test_insert_remove_refcount () { |
| 73 | + // 交叉插入/删除并共享子树:若数组块移动的引用计数记账有误, |
| 74 | + // 后续拷贝比较或进程退出时会崩溃或得到错误内容 |
| 75 | + tree shared (CONCAT, tree ("s1"), tree ("s2")); |
| 76 | + tree doc (DOCUMENT); |
| 77 | + for (int round= 0; round < 50; round++) { |
| 78 | + tree ins (DOCUMENT); |
| 79 | + ins << shared << tree ("t") << shared; |
| 80 | + raw_insert (doc, 0, ins); |
| 81 | + QVERIFY (doc[0] == shared); |
| 82 | + QVERIFY (doc[2] == shared); |
| 83 | + if (round % 2 == 0) raw_remove (doc, 0, 1); |
| 84 | + } |
| 85 | + QVERIFY (N (doc) == 125); |
| 86 | + // 大数组跨容量桶的插入/删除 |
| 87 | + tree big (DOCUMENT); |
| 88 | + for (int i= 0; i < 1000; i++) |
| 89 | + big << tree ("p" * as_string (i)); |
| 90 | + for (int i= 0; i < 40; i++) |
| 91 | + raw_insert (big, 500, tree (DOCUMENT, tree ("q"))); |
| 92 | + QVERIFY (N (big) == 1040); |
| 93 | + QVERIFY (big[500] == tree ("q")); |
| 94 | + QVERIFY (big[499] == tree ("p499")); |
| 95 | + QVERIFY (big[539] == tree ("q")); |
| 96 | + QVERIFY (big[540] == tree ("p500")); |
| 97 | + raw_remove (big, 500, 40); |
| 98 | + QVERIFY (N (big) == 1000); |
| 99 | + QVERIFY (big[500] == tree ("p500")); |
| 100 | +} |
| 101 | + |
| 102 | +#ifdef QTTEXMACS |
| 103 | +QTEST_MAIN (TestTreeObserver) |
| 104 | +#else |
| 105 | +int |
| 106 | +main () { |
| 107 | + return 0; |
| 108 | +} |
| 109 | +#endif |
| 110 | +#include "tree_observer_test.moc" |
0 commit comments