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