1<?php 2 3namespace dokuwiki\test\Treebuilder; 4 5use dokuwiki\TreeBuilder\PageTreeBuilder; 6use DokuWikiTest; 7 8class PageTreeBuilderTest extends DokuWikiTest 9{ 10 protected $originalDataDir; 11 12 public static function setUpBeforeClass(): void 13 { 14 parent::setUpBeforeClass(); 15 16 // Create a test page hierarchy 17 saveWikiText('namespace:start', 'This is the start page', 'test'); 18 saveWikiText('namespace:page1', 'This is page 1', 'test'); 19 saveWikiText('namespace:page2', 'This is page 2', 'test'); 20 saveWikiText('namespace:subns:start', 'This is the subns start page', 'test'); 21 saveWikiText('namespace:subns:page3', 'This is page 3 in subns', 'test'); 22 saveWikiText('namespace:subns:deeper:start', 'This is the deeper start page', 'test'); 23 saveWikiText('namespace:subns:deeper:page4', 'This is page 4 in deeper', 'test'); 24 } 25 26 public function setUp(): void 27 { 28 parent::setUp(); 29 global $conf; 30 $this->originalDataDir = $conf['datadir']; 31 } 32 33 public function tearDown(): void 34 { 35 global $conf; 36 $conf['datadir'] = $this->originalDataDir; 37 parent::tearDown(); 38 } 39 40 public function treeConfigProvider() 41 { 42 return [ 43 'Default configuration' => [ 44 'namespace' => 'namespace', 45 'depth' => -1, 46 'flags' => 0, 47 'expected' => [ 48 '+namespace:start', 49 '+namespace:page1', 50 '+namespace:page2', 51 '+namespace:subns', 52 '++namespace:subns:start', 53 '++namespace:subns:page3', 54 '++namespace:subns:deeper', 55 '+++namespace:subns:deeper:start', 56 '+++namespace:subns:deeper:page4' 57 ] 58 ], 59 'Depth limit 1' => [ 60 'namespace' => 'namespace', 61 'depth' => 1, 62 'flags' => 0, 63 'expected' => [ 64 '+namespace:start', 65 '+namespace:page1', 66 '+namespace:page2', 67 '+namespace:subns', 68 '++namespace:subns:start', 69 '++namespace:subns:page3', 70 '++namespace:subns:deeper' 71 ] 72 ], 73 'Depth limit 1 with NS_AS_STARTPAGE' => [ 74 'namespace' => 'namespace', 75 'depth' => 1, 76 'flags' => PageTreeBuilder::FLAG_NS_AS_STARTPAGE, 77 'expected' => [ 78 '+namespace:page1', 79 '+namespace:page2', 80 '+namespace:subns:start', 81 '++namespace:subns:page3', 82 '++namespace:subns:deeper:start' 83 ] 84 ], 85 'FLAG_NO_NS' => [ 86 'namespace' => 'namespace', 87 'depth' => -1, 88 'flags' => PageTreeBuilder::FLAG_NO_NS, 89 'expected' => [ 90 '+namespace:start', 91 '+namespace:page1', 92 '+namespace:page2' 93 ] 94 ], 95 'FLAG_NO_PAGES' => [ 96 'namespace' => 'namespace', 97 'depth' => -1, 98 'flags' => PageTreeBuilder::FLAG_NO_PAGES, 99 'expected' => [ 100 '+namespace:subns', 101 '++namespace:subns:deeper' 102 ] 103 ], 104 'FLAG_NS_AS_STARTPAGE' => [ 105 'namespace' => 'namespace', 106 'depth' => -1, 107 'flags' => PageTreeBuilder::FLAG_NS_AS_STARTPAGE, 108 'expected' => [ 109 '+namespace:page1', 110 '+namespace:page2', 111 '+namespace:subns:start', 112 '++namespace:subns:page3', 113 '++namespace:subns:deeper:start', 114 '+++namespace:subns:deeper:page4' 115 ] 116 ], 117 'Combined FLAG_NO_NS and FLAG_NS_AS_STARTPAGE' => [ 118 'namespace' => 'namespace', 119 'depth' => -1, 120 'flags' => PageTreeBuilder::FLAG_NO_NS | PageTreeBuilder::FLAG_NS_AS_STARTPAGE, 121 'expected' => [ 122 '+namespace:page1', 123 '+namespace:page2' 124 ] 125 ], 126 'FLAG_SELF_TOP' => [ 127 'namespace' => 'namespace', 128 'depth' => -1, 129 'flags' => PageTreeBuilder::FLAG_SELF_TOP, 130 'expected' => [ 131 '+namespace', 132 '++namespace:start', 133 '++namespace:page1', 134 '++namespace:page2', 135 '++namespace:subns', 136 '+++namespace:subns:start', 137 '+++namespace:subns:page3', 138 '+++namespace:subns:deeper', 139 '++++namespace:subns:deeper:start', 140 '++++namespace:subns:deeper:page4' 141 ] 142 ], 143 ]; 144 } 145 146 147 /** 148 * @dataProvider treeConfigProvider 149 */ 150 public function testPageTreeConfigurations(string $namespace, int $depth, int $flags, array $expected) 151 { 152 $tree = new PageTreeBuilder($namespace, $depth); 153 if ($flags) { 154 $tree->addFlag($flags); 155 } 156 $tree->generate(); 157 158 $result = explode("\n", (string)$tree); 159 sort($expected); 160 sort($result); 161 162 $this->assertEquals($expected, $result); 163 } 164 165 /** 166 * This is the same test as above, but pretending that our data directory is in our test namespace. 167 * 168 * @dataProvider treeConfigProvider 169 */ 170 public function testTopLevelTree(string $namespace, int $depth, int $flags, array $expected) 171 { 172 global $conf; 173 $conf['datadir'] .= '/namespace'; 174 175 $expected = array_map(function ($item) use ($namespace) { 176 return preg_replace('/namespace:?/', '', $item); 177 }, $expected); 178 179 $namespace = ''; 180 $this->testPageTreeConfigurations($namespace, $depth, $flags, $expected); 181 } 182 183 184 public function testPageTreeLeaves() 185 { 186 $tree = new PageTreeBuilder('namespace'); 187 $tree->generate(); 188 189 $leaves = $tree->getLeaves(); 190 $branches = $tree->getBranches(); 191 192 // Test that we have both leaves and branches 193 $this->assertGreaterThan(0, count($leaves), 'Should have leaf pages'); 194 $this->assertGreaterThan(0, count($branches), 'Should have branch pages'); 195 196 // The total should equal all pages 197 $this->assertEquals(count($tree->getAll()), count($leaves) + count($branches), 198 'Leaves + branches should equal total pages'); 199 } 200} 201