Hello
'; + $this->assertSame($html, markup::finish($html, 'Contents')); + } + + public function test_headings_get_anchors_and_repeats_are_numbered() + { + $html = $this->heading(2, 'Intro') . 'x
' . $this->heading(2, 'Intro') . $this->heading(3, 'A & B'); + $out = markup::finish($html, 'Contents'); + + $this->assertStringContainsString('Intro
' . $this->heading(2, 'One') . $this->heading(3, 'One A') . $this->heading(3, 'One B') . $this->heading(2, 'Two'); + $out = markup::finish($html, 'Contents'); + + $this->assertSame(1, substr_count($out, 'class="wikitoc"')); + $this->assertLessThan(strpos($out, 'Intro
'), strpos($out, 'class="wikitoc"'), 'and after the intro'); + $this->assertStringContainsString('Contents', $out); + $this->assertStringContainsString('1.1 One A', $out); + $this->assertStringContainsString('1.2 One B', $out); + $this->assertStringContainsString('2 Two', $out); + } + + public function test_the_table_of_contents_markup_is_balanced_when_levels_jump() + { + $html = $this->heading(2, 'A') . $this->heading(4, 'B') . $this->heading(3, 'C') . $this->heading(2, 'D'); + $out = markup::finish($html, 'Contents'); + + $dom = new \DOMDocument(); + $this->assertTrue($dom->loadXML('middle
after
' . $this->heading(2, 'B'), 'Contents'); + $this->assertStringContainsString('class="wikitoc"', $placed, '__TOC__ shows the box for two headings'); + $this->assertGreaterThan(strpos($placed, 'middle
'), strpos($placed, 'class="wikitoc"')); + $this->assertLessThan(strpos($placed, 'after
'), strpos($placed, 'class="wikitoc"')); + $this->assertSame(1, substr_count($placed, 'class="wikitoc"')); + } + + public function test_forcetoc_shows_the_box_for_a_single_heading() + { + $out = markup::finish('' . $this->heading(2, 'Only'), 'Contents'); + $this->assertStringContainsString('class="wikitoc"', $out); + } + + public function test_wiki_markup_is_off_unless_switched_on() + { + $this->assertFalse(markup::is_active()); + markup::set_active(true); + $this->assertTrue(markup::is_active()); + markup::set_active(false); + $this->assertFalse(markup::is_active()); + } + + private function parse(string $text, bool $wiki_markup = true): string + { + $listener = new \phpbbmodders\wiki\event\wikilink_listener( + $this->createMock(\phpbb\controller\helper::class), + $this->createMock(\phpbb\language\language::class), + $this->createMock(\phpbbmodders\wiki\wiki\links::class), + $this->createMock(\phpbbmodders\wiki\wiki\files::class) + ); + + $configurator = new \s9e\TextFormatter\Configurator; + $listener->configure_wikilink(array('configurator' => $configurator)); + extract($configurator->finalize()); + + foreach (array('WIKIHEADING', 'WIKIMAGIC') as $tag) + { + $wiki_markup ? $parser->enableTag($tag) : $parser->disableTag($tag); + } + + return $parser->parse($text); + } + + public function test_headings_of_each_level_become_tags_with_their_marks() + { + $xml = $this->parse("== Two ==\n=== Three ===\n====== Six ======"); + + $this->assertSame(3, substr_count($xml, '' . htmlspecialchars($title, ENT_QUOTES, 'UTF-8') . '
'; + $stack = array(); + $counters = array(); + + foreach ($headings as $heading) + { + $level = $heading['level']; + + // Close the lists the previous entry left open, down to this level + while ($stack && end($stack) > $level) + { + $html .= ''; + array_pop($stack); + array_pop($counters); + } + + if ($stack && end($stack) === $level) + { + $html .= ''; + $counters[count($counters) - 1]++; + } + else + { + // A deeper level than the one open (or the first entry) starts a list + $html .= '