Fork of bibtexbrowser for static publications lists on the website of the ZRD Saar
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1683 lines
69 KiB

7 years ago
7 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
7 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
7 years ago
7 years ago
7 years ago
11 years ago
9 years ago
11 years ago
9 years ago
11 years ago
9 years ago
11 years ago
11 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
9 years ago
9 years ago
9 years ago
7 years ago
4 years ago
9 months ago
  1. #!/usr/bin/env phpunit
  2. <?php
  3. /** PhPUnit tests for bibtexbrowser
  4. To run them:
  5. $ phpunit BibtexbrowserTest.php
  6. With coverage:
  7. $ phpunit --coverage-html ./coverage BibtexbrowserTest.php
  8. $ XDEBUG_MODE=coverage phpunit --coverage-filter bibtexbrowser.php --coverage-html=foo.html BibtexbrowserTest.php
  9. (be sure that xdebug is enabled: /etc/php5/cli/conf.d# ln -s ../../mods-available/xdebug.ini)
  10. */
  11. // backward compatibility
  12. if (!class_exists('PHPUnit_Framework_TestCase')) {
  13. class_alias('\PHPUnit\Framework\TestCase', 'PHPUnit_Framework_TestCase');
  14. }
  15. function exception_error_handler($severity, $message, $file, $line) {
  16. if ($severity != E_ERROR) {
  17. //trigger_error($message);
  18. return;
  19. }
  20. throw new ErrorException($message, 0, $severity, $file, $line);
  21. }
  22. error_reporting(E_ALL);
  23. // setup
  24. @copy('bibtexbrowser.local.php','bibtexbrowser.local.php.bak');
  25. @unlink('bibtexbrowser.local.php');
  26. class Nothing {
  27. function main() {}
  28. }
  29. define('BIBTEXBROWSER_MAIN','Nothing');
  30. //require_once('bibtexbrowser.php');
  31. set_error_handler("exception_error_handler");
  32. if (!is_file('reflectivedoc.php')) {
  33. die("to run the bibtexbrowser tests, download this file first:\ncurl -L -o reflectivedoc.php https://www.monperrus.net/martin/reflectivedoc.php.txt\n");
  34. }
  35. require('reflectivedoc.php');
  36. $nsnippet=0;
  37. foreach(getAllSnippetsInFile('bibtexbrowser.php') as $snippet) {
  38. ob_start();
  39. eval($snippet);
  40. ob_get_clean();
  41. unset($_GET['bib']);
  42. $nsnippet++;
  43. }
  44. if ($nsnippet!=19) {
  45. die('oops '.$nsnippet);
  46. }
  47. restore_error_handler();
  48. class SimpleDisplayExt extends SimpleDisplay {
  49. function setIndices() {
  50. $this->setIndicesInIncreasingOrderChangingEveryYear();
  51. }
  52. }
  53. class BibtexbrowserTest extends PHPUnit_Framework_TestCase {
  54. public function setUp():void {
  55. // resetting the default link style
  56. bibtexbrowser_configure('BIBTEXBROWSER_LINK_STYLE','bib2links_default');
  57. bibtexbrowser_configure('ABBRV_TYPE','index');
  58. bibtexbrowser_configure('BIBTEXBROWSER_USE_PROGRESSIVE_ENHANCEMENT', false);
  59. }
  60. function createDB() {
  61. return $this->_createDB("@book{aKey,title={A Book},author={Martin Monperrus},publisher={Springer},year=2009}\n"
  62. ."@book{aKey/withSlash,title={Slash Dangerous for web servers},author={Ap Ache},editor={Martin Monperrus},publisher={Springer},year=2010}\n"
  63. ."@article{aKeyA,title={An Article},author={Foo Bar and Jane Doe},volume=5,journal=\"New Results\",year=2009,pages={1-2}}\n");
  64. }
  65. function _createDB($content, $fakefilename="inline") {
  66. $test_data = fopen('php://memory','x+');
  67. fwrite($test_data, $content);
  68. fseek($test_data,0);
  69. $btb = new BibDataBase();
  70. $btb->update_internal($fakefilename, $test_data);
  71. return $btb;
  72. }
  73. function test_bibentry_to_html_book() {
  74. $btb = $this->createDB();
  75. $first_entry=$btb->getEntryByKey('aKey');
  76. // default style
  77. $this->assertEquals("A Book (Martin Monperrus), Springer, 2009. [bibtex]",strip_tags($first_entry->toHTML()));
  78. $this->assertEquals('<span itemscope="" itemtype="http://schema.org/ScholarlyArticle"><span class="bibtitle" itemprop="name">A Book</span> (<span class="bibauthor"><span itemprop="author" itemtype="http://schema.org/Person">Martin Monperrus</span></span>), <span class="bibpublisher">Springer</span>, <span itemprop="datePublished">2009</span>.<span class="Z3988" title="ctx_ver=Z39.88-2004&amp;rft_val_fmt=info%3Aofi%2Ffmt%3Akev%3Amtx%3Abook&amp;rft.btitle=A+Book&amp;rft.genre=book&amp;rft.pub=Springer&amp;rft.date=2009&amp;rft.au=Martin+Monperrus"></span></span> <span class="bibmenu"><a class="biburl" title="aKey" href="bibtexbrowser.php?key=aKey&amp;bib=inline">[bibtex]</a></span>',$first_entry->toHTML());
  79. // IEEE style
  80. bibtexbrowser_configure('BIBLIOGRAPHYSTYLE','JanosBibliographyStyle');
  81. $this->assertEquals("Martin Monperrus, \"A Book\", Springer, 2009.\n [bibtex]",strip_tags($first_entry->toHTML()));
  82. // Vancouver style
  83. bibtexbrowser_configure('BIBLIOGRAPHYSTYLE','VancouverBibliographyStyle');
  84. $this->assertEquals("Martin Monperrus. A Book. Springer; 2009.\n [bibtex]",strip_tags($first_entry->toHTML()));
  85. // other methods
  86. $this->assertEquals('<span class="bibmenu"><a class="biburl" title="aKey" href="bibtexbrowser.php?key=aKey&amp;bib=inline">[bibtex]</a></span>',$first_entry->bib2links());
  87. $this->assertEquals('<a class="bibanchor" name=""></a>',$first_entry->anchor());
  88. }
  89. function extract_css_classes($str) {
  90. $xml = new SimpleXMLElement($str);
  91. $css_classes = array();
  92. foreach($xml->xpath('//node()/@class') as $v) {
  93. $css_classes[] = $v->__toString();
  94. };
  95. sort($css_classes);
  96. return $css_classes;
  97. }
  98. function test_bibentry_to_html_article() {
  99. $btb = $this->createDB();
  100. $first_entry=$btb->getEntryByKey('aKeyA');
  101. $this->assertEquals("1-2",$first_entry->getField("pages"));
  102. $this->assertEquals("1",$first_entry->getPages()[0]);
  103. $this->assertEquals("2",$first_entry->getPages()[1]);
  104. // default style
  105. bibtexbrowser_configure('BIBLIOGRAPHYSTYLE','DefaultBibliographyStyle');
  106. bibtexbrowser_configure('BIBTEXBROWSER_LINK_STYLE','nothing');
  107. $this->assertEquals("An Article (Foo Bar and Jane Doe), In New Results, volume 5, 2009. ",strip_tags($first_entry->toHTML()));
  108. $this->assertEquals('<span itemscope="" itemtype="http://schema.org/ScholarlyArticle"><span class="bibtitle" itemprop="name">An Article</span> (<span class="bibauthor"><span itemprop="author" itemtype="http://schema.org/Person">Foo Bar</span> and <span itemprop="author" itemtype="http://schema.org/Person">Jane Doe</span></span>), <span class="bibbooktitle">In <span itemprop="isPartOf">New Results</span></span>, volume 5, <span itemprop="datePublished">2009</span>.<span class="Z3988" title="ctx_ver=Z39.88-2004&amp;rft_val_fmt=info%3Aofi%2Ffmt%3Akev%3Amtx%3Ajournal&amp;rft.atitle=An+Article&amp;rft.jtitle=New+Results&amp;rft.volume=5&amp;rft.issue=&amp;rft.pub=&amp;rft.date=2009&amp;rft.au=Foo+Bar&amp;rft.au=Jane+Doe"></span></span> ',$first_entry->toHTML());
  109. // listing the CSS classes
  110. $css_classes_before = $this->extract_css_classes($first_entry->toHTML());
  111. // IEEE style
  112. bibtexbrowser_configure('BIBLIOGRAPHYSTYLE','JanosBibliographyStyle');
  113. $this->assertEquals("Foo Bar and Jane Doe, \"An Article\", New Results, vol. 5, pp. 1-2, 2009.\n ",strip_tags($first_entry->toHTML()));
  114. $css_classes_after = $this->extract_css_classes($first_entry->toHTML());
  115. // contract: make sure the Janos style and default style use the same CSS classes
  116. $this->assertEquals($css_classes_before, $css_classes_after);
  117. // Vancouver style
  118. bibtexbrowser_configure('BIBLIOGRAPHYSTYLE','VancouverBibliographyStyle');
  119. $this->assertEquals("Foo Bar and Jane Doe. An Article. New Results. 2009;5:1-2.\n ",strip_tags($first_entry->toHTML()));
  120. // changing the target
  121. bibtexbrowser_configure('BIBLIOGRAPHYSTYLE','DefaultBibliographyStyle');
  122. bibtexbrowser_configure('BIBTEXBROWSER_LINKS_TARGET','_top');
  123. $this->assertEquals('<span itemscope="" itemtype="http://schema.org/ScholarlyArticle"><span class="bibtitle" itemprop="name">An Article</span> (<span class="bibauthor"><span itemprop="author" itemtype="http://schema.org/Person">Foo Bar</span> and <span itemprop="author" itemtype="http://schema.org/Person">Jane Doe</span></span>), <span class="bibbooktitle">In <span itemprop="isPartOf">New Results</span></span>, volume 5, <span itemprop="datePublished">2009</span>.<span class="Z3988" title="ctx_ver=Z39.88-2004&amp;rft_val_fmt=info%3Aofi%2Ffmt%3Akev%3Amtx%3Ajournal&amp;rft.atitle=An+Article&amp;rft.jtitle=New+Results&amp;rft.volume=5&amp;rft.issue=&amp;rft.pub=&amp;rft.date=2009&amp;rft.au=Foo+Bar&amp;rft.au=Jane+Doe"></span></span> ',$first_entry->toHTML());
  124. // testing ABBRV_TYPE
  125. bibtexbrowser_configure('ABBRV_TYPE','year');
  126. $this->assertEquals("[2009]",$first_entry->getAbbrv());
  127. bibtexbrowser_configure('ABBRV_TYPE','key');
  128. $this->assertEquals("[aKeyA]",$first_entry->getAbbrv());
  129. bibtexbrowser_configure('ABBRV_TYPE','index');
  130. $this->assertEquals("[]",$first_entry->getAbbrv());
  131. $first_entry->setIndex('foo');
  132. $this->assertEquals("[foo]",$first_entry->getAbbrv());
  133. bibtexbrowser_configure('ABBRV_TYPE','none');
  134. $this->assertEquals("",$first_entry->getAbbrv());
  135. }
  136. function testMultiSearch() {
  137. $btb = $this->createDB();
  138. $q=array(Q_AUTHOR=>'monperrus');
  139. $results=$btb->multisearch($q);
  140. $entry = $results[0];
  141. $this->assertTrue(count($results) == 1);
  142. $this->assertTrue($entry->getTitle() == 'A Book');
  143. }
  144. function testMultiSearch2() {
  145. $btb = $this->createDB();
  146. $q=array(Q_AUTHOR=>'monperrus|ducasse');
  147. $results=$btb->multisearch($q);
  148. $entry = $results[0];
  149. $this->assertTrue(count($results) == 1);
  150. $this->assertTrue($entry->getTitle() == 'A Book');
  151. }
  152. function testMultiSearch_name_match() {
  153. $btb = $this->createDB();
  154. $q=array(Q_NAME=>'Martin Monperrus');
  155. $results=$btb->multisearch($q);
  156. $this->assertTrue(count($results) == 2);
  157. }
  158. function testMultiSearch_author_name_match() {
  159. $btb = $this->createDB();
  160. $q=array(Q_AUTHOR_NAME=>'Martin Monperrus');
  161. $results=$btb->multisearch($q);
  162. $entry = $results[0];
  163. $this->assertTrue(count($results) == 1);
  164. $this->assertTrue($entry->getTitle() == 'A Book');
  165. }
  166. function testMultiSearch_editor_name_match() {
  167. $btb = $this->createDB();
  168. $q=array(Q_EDITOR_NAME=>'Martin Monperrus');
  169. $results=$btb->multisearch($q);
  170. $entry = $results[0];
  171. $this->assertTrue(count($results) == 1);
  172. $this->assertTrue($entry->getTitle() == 'Slash Dangerous for web servers');
  173. }
  174. function test_config_value() {
  175. // default value
  176. $this->assertFalse(config_value('BIBTEXBROWSER_NO_DEFAULT'));
  177. // setting to true
  178. bibtexbrowser_configure('BIBTEXBROWSER_NO_DEFAULT', true);
  179. $this->assertTrue(config_value('BIBTEXBROWSER_NO_DEFAULT'));
  180. ob_start();
  181. default_message();
  182. $this->assertEquals('', ob_get_clean());
  183. // setting to false
  184. bibtexbrowser_configure('BIBTEXBROWSER_NO_DEFAULT', false);
  185. $this->assertFalse(config_value('BIBTEXBROWSER_NO_DEFAULT'));
  186. ob_start();
  187. default_message();
  188. $this->assertStringContainsString('Congratulations', ob_get_clean());
  189. }
  190. function testInternationalization() {
  191. $btb = $this->createDB();
  192. global $BIBTEXBROWSER_LANG;
  193. $BIBTEXBROWSER_LANG=array();
  194. $BIBTEXBROWSER_LANG['Refereed Conference Papers']="foo";
  195. $this->assertEquals("foo",__("Refereed Conference Papers"));
  196. $BIBTEXBROWSER_LANG['Books']="Livres";
  197. $d = new AcademicDisplay();
  198. $d->setDB($btb);
  199. ob_start();
  200. $d->display();
  201. $data = ob_get_clean();
  202. $this->assertStringContainsString('Livres', $data);
  203. }
  204. function testNoSlashInKey() {
  205. $btb = $this->createDB();
  206. $q=array(Q_SEARCH=>'Slash');
  207. $results=$btb->multisearch($q);
  208. $this->assertTrue(count($results) == 1);
  209. $entry = $results[0];
  210. $this->assertStringContainsString("aKey-withSlash",$entry->toHTML());
  211. $q=array(Q_KEY=>'aKey-withSlash');
  212. $results=$btb->multisearch($q);
  213. $entry2 = $results[0];
  214. $this->assertSame($entry2,$entry);
  215. }
  216. function test_string_should_be_deleted_after_update() {
  217. $test_data = fopen('php://memory','x+');
  218. fwrite($test_data, "@book{aKey,title={A Book},author={Martin Monperrus},publisher={Springer},year=2009}\n".
  219. "@String{x=2008}\n"
  220. );
  221. fseek($test_data,0);
  222. $btb = new BibDataBase();
  223. $btb->update_internal("inline", $test_data);
  224. // print_r($btb->stringdb);
  225. $this->assertEquals(1,count($btb->stringdb));
  226. // replacing the existing one
  227. $test_data = fopen('php://memory','x+');
  228. fwrite($test_data, "@book{aKey2,title={A Book},author={Martin Monperrus},publisher={Springer},year=2009}\n".
  229. "@String{x=2009}\n"
  230. );
  231. fseek($test_data,0);
  232. $btb = new BibDataBase();
  233. $btb->update_internal("inline2", $test_data);
  234. // print_r($btb->stringdb);
  235. $this->assertEquals(1,count($btb->stringdb));
  236. $this->assertEquals("2009",$btb->stringdb['x']->value);//
  237. // now adding another one and removing the string
  238. $test_data2 = fopen('php://memory','x+');
  239. fwrite($test_data2, "@book{aKey,title={A Book},author={Martin Monperrus},publisher={Springer},year=2009}\n".
  240. "@String{y=2010}\n"
  241. );
  242. fseek($test_data2,0);
  243. $btb->update_internal("inline2", $test_data2);
  244. $this->assertEquals(1,count($btb->stringdb));//
  245. $this->assertEquals("2010",$btb->stringdb['y']->value);//
  246. }
  247. function test_mastersthesis() {
  248. $test_data = fopen('php://memory','x+');
  249. fwrite($test_data, "@mastersthesis{aKey,title={A Thing},author={Martin Monperrus},year=2009,school={School of Nowhere}}\n".
  250. "@String{x=2008}\n"
  251. );
  252. fseek($test_data,0);
  253. $db = new BibDataBase();
  254. $db->update_internal("inline", $test_data);
  255. $this->assertEquals("A Thing (Martin Monperrus), Master's thesis, School of Nowhere, 2009. [bibtex]",strip_tags($db->getEntryByKey('aKey')->toHTML()));
  256. }
  257. function test_google_scholar_metadata() {
  258. bibtexbrowser_configure('METADATA_GS', true);
  259. $test_data = fopen('php://memory','x+');
  260. fwrite($test_data, "@article{aKey,title={A Book},author={Martin Monperrus},publisher={Springer},year=2009,pages={42--4242},number=1}\n".
  261. "@String{x=2008}\n"
  262. );
  263. fseek($test_data,0);
  264. $db = new BibDataBase();
  265. $db->update_internal("inline", $test_data);
  266. $dis = new BibEntryDisplay($db->getEntryByKey('aKey'));
  267. $metadata = $dis->metadata_dict();
  268. //print_r($metadata);
  269. $this->assertEquals("A Book",$metadata['citation_title']);
  270. $this->assertEquals("2009",$metadata['citation_date']);
  271. $this->assertEquals("2009",$metadata['citation_year']);
  272. $this->assertEquals("42",$metadata['citation_firstpage']);
  273. $this->assertEquals("4242",$metadata['citation_lastpage']);
  274. $this->assertEquals("1",$metadata['citation_issue']);
  275. }
  276. function test_metadata_opengraph() {
  277. $test_data = fopen('php://memory','x+');
  278. fwrite($test_data, "@article{aKey,title={A Book},author={Martin Monperrus},url={http://foo.com/},publisher={Springer},year=2009,pages={42--4242},number=1}\n".
  279. "@String{x=2008}\n"
  280. );
  281. fseek($test_data,0);
  282. $db = new BibDataBase();
  283. $db->update_internal("inline", $test_data);
  284. $dis = new BibEntryDisplay($db->getEntryByKey('aKey'));
  285. $metadata = $dis->metadata_dict();
  286. //print_r($metadata);
  287. $this->assertEquals("A Book",$metadata['og:title']);
  288. $this->assertEquals("article",$metadata['og:type']);
  289. $this->assertTrue(1 == preg_match("/http:.*author=Martin\+Monperrus/",$metadata['og:author']));
  290. $this->assertEquals("2009",$metadata['og:published_time']);
  291. }
  292. function test_math_cal() {
  293. $test_data = fopen('php://memory','x+');
  294. fwrite($test_data, "@book{aKey,title={{A {Book} $\mbox{foo}$ tt $\boo{t}$}} ,author={Martin Monperrus},publisher={Springer},year=2009}\n".
  295. "@String{x=2008}\n"
  296. );
  297. fseek($test_data,0);
  298. $btb = new BibDataBase();
  299. $btb->update_internal("inline", $test_data);
  300. $first_entry=$btb->bibdb[array_keys($btb->bibdb)[0]];
  301. // $this->assertTrue(strpos('A Book{} $\mbox{foo}$',$first_entry->toHTML());
  302. $this->assertEquals('A Book $\mbox{foo}$ tt $\boo{t}$',$first_entry->getTitle());
  303. }
  304. function test_link_configuration() {
  305. bibtexbrowser_configure('BIBTEXBROWSER_LINKS_TARGET','_self');
  306. $test_data = fopen('php://memory','x+');
  307. fwrite($test_data, "@book{aKey,pdf={myarticle.pdf}}\n@book{bKey,url={myarticle.pdf}}\n@book{cKey,url={myarticle.xyz}}\n"
  308. );
  309. fseek($test_data,0);
  310. $btb = new BibDataBase();
  311. $btb->update_internal("inline", $test_data);
  312. $first_entry=$btb->bibdb[array_keys($btb->bibdb)[0]];
  313. $this->assertEquals('<a href="myarticle.pdf">[pdf]</a>',$first_entry->getLink('pdf'));
  314. $this->assertEquals('<a href="myarticle.pdf">[pdf]</a>',$first_entry->getPdfLink());
  315. $this->assertEquals('<a href="myarticle.pdf"><img class="icon" src="pdficon.png" alt="[pdf]" title="pdf"/></a>',$first_entry->getLink('pdf','pdficon.png'));
  316. $this->assertEquals('<a href="myarticle.pdf">[see]</a>',$first_entry->getLink('pdf',NULL,'see'));
  317. $second_entry=$btb->bibdb[array_keys($btb->bibdb)[1]];
  318. $this->assertEquals('<a href="myarticle.pdf">[pdf]</a>',$second_entry->getPdfLink());
  319. $third_entry=$btb->bibdb[array_keys($btb->bibdb)[2]];
  320. $this->assertEquals('<a href="myarticle.xyz">[url]</a>',$third_entry->getPdfLink());
  321. }
  322. // see https://github.com/monperrus/bibtexbrowser/pull/14
  323. function test_zotero() {
  324. bibtexbrowser_configure('BIBTEXBROWSER_LINKS_TARGET','_self');
  325. $test_data = fopen('php://memory','x+');
  326. fwrite($test_data, "@book{aKey,file={myarticle.pdf}}\n"
  327. );
  328. fseek($test_data,0);
  329. $btb = new BibDataBase();
  330. $btb->update_internal("inline", $test_data);
  331. $first_entry=$btb->bibdb[array_keys($btb->bibdb)[0]];
  332. $this->assertEquals('<a href="myarticle.pdf">[pdf]</a>',$first_entry->getPdfLink());
  333. }
  334. // https://github.com/monperrus/bibtexbrowser/issues/40
  335. function test_doi_url() {
  336. bibtexbrowser_configure('BIBTEXBROWSER_LINKS_TARGET','_self');
  337. $test_data = fopen('php://memory','x+');
  338. fwrite($test_data, "@Article{Baldwin2014Quantum,Doi={10.1103/PhysRevA.90.012110},Url={http://link.aps.org/doi/10.1103/PhysRevA.90.012110}}"
  339. );
  340. fseek($test_data,0);
  341. $btb = new BibDataBase();
  342. $btb->update_internal("inline", $test_data);
  343. $first_entry=$btb->bibdb[array_keys($btb->bibdb)[0]];
  344. $this->assertEquals('<pre class="purebibtex">@Article{Baldwin2014Quantum,Doi={<a href="https://doi.org/10.1103/PhysRevA.90.012110">10.1103/PhysRevA.90.012110</a>},Url={<a href="http://link.aps.org/doi/10.1103/PhysRevA.90.012110">http://link.aps.org/doi/10.1103/PhysRevA.90.012110</a>}}</pre>',$first_entry->toEntryUnformatted());
  345. }
  346. function test_filter_view() {
  347. $test_data = fopen('php://memory','x+');
  348. fwrite($test_data, "@article{aKey,title={A Book},author={Martin M\'e},publisher={Springer},year=2009,pages={42--4242},number=1}\n");
  349. fseek($test_data,0);
  350. $db = new BibDataBase();
  351. $db->update_internal("inline", $test_data);
  352. $dis = $db->getEntryByKey('aKey');
  353. $this->assertEquals("@article{aKey,title={A Book},author={Martin M\'e},publisher={Springer},year=2009,pages={42--4242},number=1}",$dis->getText());
  354. // now ith option
  355. bibtexbrowser_configure('BIBTEXBROWSER_BIBTEX_VIEW', 'reconstructed');
  356. bibtexbrowser_configure('BIBTEXBROWSER_BIBTEX_VIEW_FILTEREDOUT', 'pages|number');
  357. $this->assertEquals("@article{aKey,\n title = {A Book},\n author = {Martin M\'e},\n publisher = {Springer},\n year = {2009},\n}\n", $dis->getText());
  358. }
  359. function test_BIBTEXBROWSER_USE_LATEX2HTML() {
  360. $bibtex = "@article{aKey,title={\`a Book},author={J\'e Lo},publisher={Springer},year=2009,pages={42--4242},number=1}\n";
  361. bibtexbrowser_configure('BIBTEXBROWSER_USE_LATEX2HTML', true);
  362. $test_data = fopen('php://memory','x+');
  363. fwrite($test_data, $bibtex);
  364. fseek($test_data,0);
  365. $db = new BibDataBase();
  366. $db->update_internal("inline", $test_data);
  367. $dis = $db->getEntryByKey('aKey');
  368. $this->assertEquals("à Book",$dis->getTitle());
  369. $this->assertEquals("Jé Lo",$dis->getFormattedAuthorsString());
  370. // ensure that it is comma separated, used for metadata
  371. $this->assertEquals("Lo, Jé",$dis->getArrayOfCommaSeparatedAuthors()[0]);
  372. bibtexbrowser_configure('BIBTEXBROWSER_USE_LATEX2HTML', false);
  373. $test_data = fopen('php://memory','x+');
  374. fwrite($test_data, $bibtex);
  375. fseek($test_data,0);
  376. $db = new BibDataBase();
  377. $db->update_internal("inline", $test_data);
  378. $dis = $db->getEntryByKey('aKey');
  379. $this->assertEquals("\`a Book",$dis->getTitle());
  380. $this->assertEquals("J\'e Lo",$dis->getFormattedAuthorsString());
  381. }
  382. function test_PagedDisplay() {
  383. $PAGE_SIZE = 4;
  384. bibtexbrowser_configure('BIBTEXBROWSER_DEFAULT_DISPLAY', 'PagedDisplay');
  385. bibtexbrowser_configure('PAGE_SIZE', $PAGE_SIZE);
  386. $db = new BibDataBase();
  387. $db->load('bibacid-utf8.bib');
  388. $d = new PagedDisplay();
  389. $d->setEntries($db->bibdb);
  390. ob_start();
  391. $d->display();
  392. $content = "<div>".ob_get_clean()."</div>";
  393. $xml = new SimpleXMLElement($content);
  394. $result = $xml->xpath('//td[@class=\'bibref\']');
  395. $this->assertEquals($PAGE_SIZE,count($result));
  396. }
  397. function test_getKeywords() {
  398. $bibtex = "@article{aKey,title={\`a Book},keywords={foo,bar},author={Martin Monperrus},publisher={Springer},year=2009,pages={42--4242},number=1}\n";
  399. bibtexbrowser_configure('BIBTEXBROWSER_USE_LATEX2HTML', true);
  400. $test_data = fopen('php://memory','x+');
  401. fwrite($test_data, $bibtex);
  402. fseek($test_data,0);
  403. $db = new BibDataBase();
  404. $db->update_internal("inline", $test_data);
  405. $dis = $db->getEntryByKey('aKey');
  406. $this->assertEquals(2,count($dis->getKeywords()));
  407. }
  408. # https://github.com/monperrus/bibtexbrowser/pull/51
  409. function test_emptyGetPdfLink() {
  410. bibtexbrowser_configure('BIBTEXBROWSER_LINKS_TARGET','_self');
  411. $bibtex = "
  412. @article{aKey,
  413. title={\`a Book},
  414. author={Martin Monperrus},
  415. publisher={Springer},
  416. year=2009,
  417. pages={42--4242},
  418. number=1
  419. }
  420. @article{bKey,
  421. url={magic.pdf},
  422. }
  423. @article{cKey,
  424. pdf={magic2.pdf},
  425. url={magic3}
  426. }";
  427. $test_data = fopen('php://memory','x+');
  428. fwrite($test_data, $bibtex);
  429. fseek($test_data,0);
  430. $db = new BibDataBase();
  431. $db->update_internal("inline", $test_data);
  432. $dis = $db->getEntryByKey('aKey');
  433. $this->assertEquals("",$dis->getPdfLink());
  434. $dis = $db->getEntryByKey('bKey');
  435. $this->assertEquals('<a href="magic.pdf">[pdf]</a>',$dis->getPdfLink());
  436. $dis = $db->getEntryByKey('cKey');
  437. $this->assertEquals('<a href="magic2.pdf">[pdf]</a>',$dis->getPdfLink());
  438. }
  439. function test_formatting() {
  440. $bibtex = "@article{aKey61,title={An article Book},author = {Meyer, Heribert and {Advanced Air and Ground Research Team} and Foo Bar}}\n@article{bKey61,title={An article Book},author = {Meyer, Heribert and Foo Bar}}\n";
  441. $test_data = fopen('php://memory','x+');
  442. fwrite($test_data, $bibtex);
  443. fseek($test_data,0);
  444. $db = new BibDataBase();
  445. $db->update_internal("inline", $test_data);
  446. $entry = $db->getEntryByKey('aKey61');
  447. // test with formatting with default options same as getRawAuthors()
  448. $authors = $entry->getFormattedAuthorsArray();
  449. $this->assertEquals(3, count($authors));
  450. $this->assertEquals("Meyer, Heribert", $authors[0]);
  451. $this->assertEquals("Advanced Air and Ground Research Team", $authors[1]);
  452. $this->assertEquals("Foo Bar", $authors[2]);
  453. $this->assertEquals("Meyer, Heribert, Advanced Air and Ground Research Team and Foo Bar", $entry->getFormattedAuthorsString());
  454. // test with formatting (first name before)
  455. bibtexbrowser_configure('USE_COMMA_AS_NAME_SEPARATOR_IN_OUTPUT', true);
  456. $authors = $entry->getFormattedAuthorsArray();
  457. $this->assertEquals(3, count($authors));
  458. $this->assertEquals("Meyer, Heribert", $authors[0]);
  459. $this->assertEquals("Team, Advanced Air and Ground Research", $authors[1]);
  460. $this->assertEquals("Bar, Foo", $authors[2]);
  461. $this->assertEquals("Meyer, Heribert; Team, Advanced Air and Ground Research and Bar, Foo", $entry->getFormattedAuthorsString());
  462. // test with formatting (with initials) formatAuthorInitials
  463. bibtexbrowser_configure('USE_COMMA_AS_NAME_SEPARATOR_IN_OUTPUT', false);
  464. bibtexbrowser_configure('USE_INITIALS_FOR_NAMES', true);
  465. $authors = $entry->getFormattedAuthorsArray();
  466. $this->assertEquals(3, count($authors));
  467. $this->assertEquals("Meyer H", $authors[0]);
  468. $this->assertEquals("Team AAand GR", $authors[1]);
  469. $this->assertEquals("Bar F", $authors[2]);
  470. $this->assertEquals("Meyer H, Team AAand GR and Bar F", $entry->getFormattedAuthorsString());
  471. // test with first_name last_name formatAuthorCanonical
  472. bibtexbrowser_configure('USE_COMMA_AS_NAME_SEPARATOR_IN_OUTPUT', false);
  473. bibtexbrowser_configure('USE_INITIALS_FOR_NAMES', false);
  474. bibtexbrowser_configure('USE_FIRST_THEN_LAST', true);
  475. $authors = $entry->getFormattedAuthorsArray();
  476. $this->assertEquals(3, count($authors));
  477. $this->assertEquals("Heribert Meyer", $authors[0]);
  478. $this->assertEquals("Advanced Air and Ground Research Team", $authors[1]);
  479. $this->assertEquals("Foo Bar", $authors[2]);
  480. $this->assertEquals("Heribert Meyer, Advanced Air and Ground Research Team and Foo Bar", $entry->getFormattedAuthorsString());
  481. // test Oxford comma with default options
  482. bibtexbrowser_configure('USE_COMMA_AS_NAME_SEPARATOR_IN_OUTPUT', false);
  483. bibtexbrowser_configure('USE_INITIALS_FOR_NAMES', false);
  484. bibtexbrowser_configure('USE_FIRST_THEN_LAST', false);
  485. bibtexbrowser_configure('USE_OXFORD_COMMA', true);
  486. $this->assertEquals("Meyer, Heribert, Advanced Air and Ground Research Team, and Foo Bar", $entry->getFormattedAuthorsString());
  487. $entry = $db->getEntryByKey('bKey61');
  488. $this->assertEquals("Meyer, Heribert and Foo Bar", $entry->getFormattedAuthorsString());
  489. bibtexbrowser_configure('USE_OXFORD_COMMA', false);
  490. }
  491. function test_parsing_author_list() {
  492. // specify parsing of author list
  493. bibtexbrowser_configure('USE_COMMA_AS_NAME_SEPARATOR_IN_OUTPUT', false);
  494. bibtexbrowser_configure('USE_FIRST_THEN_LAST', false);
  495. // default case: one authors
  496. $bibtex = "@article{aKey61,title={An article Book},author = {Meyer, Heribert}}\n";
  497. $test_data = fopen('php://memory','x+');
  498. fwrite($test_data, $bibtex);
  499. fseek($test_data,0);
  500. $db = new BibDataBase();
  501. $db->update_internal("inline", $test_data);
  502. $entry = $db->getEntryByKey('aKey61');
  503. $authors = $entry->getRawAuthors();
  504. $this->assertEquals(1,count($authors));
  505. $this->assertEquals("Meyer, Heribert", $authors[0]);
  506. // default case: no sub list
  507. $bibtex = "@article{aKey61,title={An article Book},author = {Meyer, Heribert and Foo Bar}}\n";
  508. $test_data = fopen('php://memory','x+');
  509. fwrite($test_data, $bibtex);
  510. fseek($test_data,0);
  511. $db = new BibDataBase();
  512. $db->update_internal("inline", $test_data);
  513. $entry = $db->getEntryByKey('aKey61');
  514. $authors = $entry->getRawAuthors();
  515. $this->assertEquals(2,count($authors));
  516. $this->assertEquals("Meyer, Heribert", $authors[0]);
  517. $this->assertEquals("Meyer, Heribert and Foo Bar", $entry->getFormattedAuthorsString());
  518. // Github issue 61
  519. $bibtex = "@article{aKey61,title={An article Book},author = {Meyer, Heribert and {Advanced Air and Ground Research Team} and Foo Bar and J{\'e} Ko and J{\'e} Le and Fd L{\'e}}}\n";
  520. // wrong parsing of author names
  521. $test_data = fopen('php://memory','x+');
  522. fwrite($test_data, $bibtex);
  523. fseek($test_data,0);
  524. $db = new BibDataBase();
  525. $db->update_internal("inline", $test_data);
  526. $entry = $db->getEntryByKey('aKey61');
  527. $authors = $entry->getRawAuthors();
  528. $this->assertEquals(6, count($authors));
  529. $this->assertEquals("Meyer, Heribert", $authors[0]);
  530. $this->assertEquals("Advanced Air and Ground Research Team", $authors[1]);
  531. $this->assertEquals("Foo Bar", $authors[2]);
  532. $this->assertEquals("J{\'e} Ko", $authors[3]);
  533. $this->assertEquals("J{\'e} Le", $authors[4]);
  534. $this->assertEquals("Fd L{\'e}", $authors[5]);
  535. }
  536. function test_latex2html() {
  537. $this->assertEquals('"', latex2html("``"));
  538. $this->assertEquals('"', latex2html("''"));
  539. $this->assertEquals('&eacute;', latex2html("\'e"));
  540. $this->assertEquals('&eacute;', latex2html("{\'e}"));
  541. }
  542. function test_homepage_link() {
  543. bibtexbrowser_configure('USE_COMMA_AS_NAME_SEPARATOR_IN_OUTPUT', false);
  544. bibtexbrowser_configure('USE_FIRST_THEN_LAST', false);
  545. $bibtex = "@string{hp_MartinMonperrus={http://www.monperrus.net/~martin},hp_FooAcé={http://example.net/}},@article{aKey61,title={An article Book},author = {Martin Monperrus and Foo Acé and Monperrus, Martin}}\n";
  546. $test_data = fopen('php://memory','x+');
  547. fwrite($test_data, $bibtex);
  548. fseek($test_data,0);
  549. $db = new BibDataBase();
  550. $db->update_internal("inline", $test_data);
  551. $entry = $db->getEntryByKey('aKey61');
  552. $authors = $entry->getFormattedAuthorsArray();
  553. $this->assertEquals('<a href="http://www.monperrus.net/~martin">Martin Monperrus</a>', $authors[0]);
  554. $this->assertEquals('<a href="http://example.net/">Foo Acé</a>', $authors[1]);
  555. $this->assertEquals('<a href="http://www.monperrus.net/~martin">Monperrus, Martin</a>', $authors[2]);
  556. }
  557. function test_author_index() {
  558. bibtexbrowser_configure('USE_FIRST_THEN_LAST', true);
  559. $bibtex = "@string{hp_MartinMonperrus={http://www.monperrus.net/martin},hp_FooAcé={http://example.net/}},@article{aKey61,title={An article Book},author = {Martin Monperrus and Foo Ac\'e and Monperrus, Martin}}\n";
  560. $test_data = fopen('php://memory','x+');
  561. fwrite($test_data, $bibtex);
  562. fseek($test_data,0);
  563. $db = new BibDataBase();
  564. $db->update_internal("inline", $test_data);
  565. $index = var_export($db->authorIndex(), true);
  566. $this->assertEquals("array (\n 'Foo Acé' => 'Foo Acé',\n 'Martin Monperrus' => 'Martin Monperrus',\n)", $index);
  567. }
  568. function test_string_entries() {
  569. $btb = new BibDataBase();
  570. $btb->load('bibacid-utf8.bib');
  571. $this->assertEquals(5, count($btb->stringdb));
  572. $this->assertEquals("@string{foo={Foo}}",$btb->stringdb['foo']->toString());
  573. }
  574. function test_indices() {
  575. $btb = $this->createDB();
  576. $this->assertEquals("[]", $btb->getEntryByKey('aKey')->getAbbrv());
  577. $d = new SimpleDisplay();
  578. $d->setDB($btb);
  579. ob_start();
  580. $d->display();
  581. ob_get_clean();
  582. // the indices have been set by SimpleDisplay
  583. $this->assertEquals("[3]", $btb->getEntryByKey('aKey')->getAbbrv());
  584. $this->assertEquals("[1]", $btb->getEntryByKey('aKey-withSlash')->getAbbrv());
  585. // SimpleDisplayExt sets the indices differently, using setIndicesInIncreasingOrderChangingEveryYear
  586. $d = new SimpleDisplayExt();
  587. $d->setDB($btb);
  588. ob_start();
  589. $d->display();
  590. ob_get_clean();
  591. $this->assertEquals("[1]", $btb->getEntryByKey('aKey')->getAbbrv());
  592. $this->assertEquals("[1]", $btb->getEntryByKey('aKey-withSlash')->getAbbrv());
  593. }
  594. function test_identity() {
  595. $btb = new BibDataBase();
  596. $btb->load('bibacid-utf8.bib');
  597. bibtexbrowser_configure('BIBTEXBROWSER_BIBTEX_VIEW_FILTEREDOUT', '');
  598. // computing the representation
  599. $d = new SimpleDisplay();
  600. $d->setDB($btb);
  601. ob_start();
  602. $d->display();
  603. $rep = ob_get_clean();
  604. $nref = count($btb->bibdb);
  605. $bibtex = $btb->toBibtex();
  606. // reparsing the new content
  607. $btb2 = $this->_createDB($bibtex, 'bibacid-utf8.bib');
  608. $d->setDB($btb2);
  609. ob_start();
  610. $d->display();
  611. $rep2 = ob_get_clean();
  612. // there is the same number of entries
  613. $this->assertEquals($nref, count($btb2->bibdb));
  614. $this->assertEquals($bibtex, $btb2->toBibtex());
  615. $this->assertEquals($rep, $rep2);
  616. }
  617. function test_cli() {
  618. $test_file="test_cli.bib";
  619. copy('bibacid-utf8.bib', $test_file);
  620. system('php bibtexbrowser-cli.php '.$test_file." --id classical --set-title \"a new title\"");
  621. $db = new BibDataBase();
  622. $db->load($test_file);
  623. $this->assertEquals("a new title", $db->getEntryByKey('classical')->getField('title'));
  624. // multiple changes
  625. system('php bibtexbrowser-cli.php '.$test_file." --id classical --set-title \"a new title\" --id with_abstract --set-title \"a new title\" --set-year 1990");
  626. $db = new BibDataBase();
  627. $db->load($test_file);
  628. $this->assertEquals("a new title", $db->getEntryByKey('classical')->getField('title'));
  629. $this->assertEquals("a new title", $db->getEntryByKey('with_abstract')->getField('title'));
  630. $this->assertEquals("1990", $db->getEntryByKey('with_abstract')->getField('year'));
  631. unlink($test_file);
  632. }
  633. function test_removeField() {
  634. $btb = $this->createDB();
  635. $first_entry=$btb->getEntryByKey('aKey');
  636. $this->assertTrue($first_entry->hasField('author'));
  637. $first_entry->removeField('author');
  638. $this->assertFalse($first_entry->hasField('author'));
  639. }
  640. function testdefaultkey() {
  641. bibtexbrowser_configure('BIBTEXBROWSER_BIBTEX_VIEW', 'original');
  642. $bibtex = "@article{title={An article Book},author = {Martin Monperrus and Foo Ac\'e and Monperrus, Martin}}";
  643. $key = md5($bibtex);
  644. $test_data = fopen('php://memory','x+');
  645. fwrite($test_data, $bibtex);
  646. fseek($test_data,0);
  647. $db = new BibDataBase();
  648. $db->update_internal("inline", $test_data);
  649. $entry=$db->getEntryByKey($key);
  650. $this->assertEquals($bibtex, $entry->getText());
  651. }
  652. function testscholarlink() {
  653. bibtexbrowser_configure('BIBTEXBROWSER_LINKS_TARGET','_self');
  654. bibtexbrowser_configure('BIBTEXBROWSER_BIBTEX_VIEW', 'original');
  655. $bibtex = "@article{key,title={An article Book},gsid={1234},author = {Martin Monperrus and Foo Ac\'e and Monperrus, Martin}}";
  656. $test_data = fopen('php://memory','x+');
  657. fwrite($test_data, $bibtex);
  658. fseek($test_data,0);
  659. $db = new BibDataBase();
  660. $db->update_internal("inline", $test_data);
  661. $entry=$db->getEntryByKey("key");
  662. $this->assertStringContainsString('<a href="https://scholar.google.com/scholar?cites=1234">[citations]</a>', $entry->toHTML());
  663. }
  664. function test_before() {
  665. // contract: the ordering is chronological
  666. $bibtex = "@article{doe2000,title={An article},author={Jane Doe},journal={The Wordpress Journal},year=2000}@book{doo2001,title={A book},author={Jane Doe},year=2001}";
  667. $test_data = fopen('php://memory','x+');
  668. fwrite($test_data, $bibtex);
  669. fseek($test_data,0);
  670. $db = new BibDataBase();
  671. $_GET[Q_FILE] = 'sample.bib';
  672. $db->update_internal("inline", $test_data);
  673. $d = new SimpleDisplay();
  674. $d->setDB($db);
  675. ob_start();
  676. NoWrapper($d);
  677. $output = ob_get_clean();
  678. $res = eval("return ".file_get_contents('reference-output-wp-publications.txt').";");
  679. $this->assertEquals(strip_tags($res['rendered']), "&#091;wp-publications bib=sample.bib all=1&#093; gives:\n".strip_tags($output)."\n");
  680. }
  681. function test80() {
  682. // contract: entries without year are at the top
  683. $bibtex = "@article{keyWithoutYear,title={First article},author = {Martin}},@article{key2,title={Second article},author = {Martin}, year=2007}";
  684. $test_data = fopen('php://memory','x+');
  685. fwrite($test_data, $bibtex);
  686. fseek($test_data,0);
  687. $db = new BibDataBase();
  688. $db->update_internal("inline", $test_data);
  689. $d = new SimpleDisplay();
  690. $d->setDB($db);
  691. ob_start();
  692. $d->display();
  693. $output = ob_get_clean();
  694. // print($output);
  695. $this->assertEquals("keyWithoutYear", $d->entries[0]->getKey());
  696. $this->assertEquals("key2", $d->entries[1]->getKey());
  697. // the indices have been set by SimpleDisplay, by default the one at the top is the one withuut year (the first in $d->entries)
  698. $this->assertEquals("[2]", $db->getEntryByKey('keyWithoutYear')->getAbbrv());
  699. $this->assertEquals("[1]", $db->getEntryByKey('key2')->getAbbrv());
  700. }
  701. function test_bug_201808() {
  702. $btb = new BibDataBase();
  703. $btb->load('bibacid-utf8.bib');
  704. $this->assertEquals(4,count($btb->bibdb['arXiv-1807.05030']->getRawAuthors()));
  705. $this->assertEquals(4,count($btb->bibdb['arXiv-1807.05030']->getFormattedAuthorsArray()));
  706. $this->assertEquals("Oscar Luis Vera-Pérez, Benjamin Danglot, Martin Monperrus and Benoit Baudry",$btb->bibdb['arXiv-1807.05030']->getAuthor());
  707. bibtexbrowser_configure('BIBTEXBROWSER_LINK_STYLE','nothing');
  708. bibtexbrowser_configure('BIBLIOGRAPHYSTYLE','JanosBibliographyStyle');
  709. $this->assertEquals("Oscar Luis Vera-Pérez, Benjamin Danglot, Martin Monperrus and Benoit Baudry, \"A Comprehensive Study of Pseudo-tested Methods\", Technical report, arXiv 1807.05030, 2018.\n ",strip_tags($btb->bibdb['arXiv-1807.05030']->toHTML()));
  710. }
  711. function test_multiple_table() {
  712. ob_start();
  713. $btb = new BibDataBase();
  714. $btb->load('bibacid-utf8.bib');
  715. $display = new SimpleDisplay($btb, array(Q_YEAR => '1997'));
  716. $display->display();
  717. $display = new SimpleDisplay($btb, array(Q_YEAR => '2010'));
  718. $display->display();
  719. $output = ob_get_clean();
  720. // assertion: we have two tables in the output
  721. $xml = new SimpleXMLElement("<doc>".$output."</doc>");
  722. $result = $xml->xpath('//table');
  723. $this->assertEquals(2,count($result));
  724. }
  725. function test_cff() {
  726. $btb = new BibDataBase();
  727. $btb->load('bibacid-utf8.bib');
  728. $entry = $btb->bibdb['arXiv-1807.05030'];
  729. $expected = "cff-version: 1.2.0\n".
  730. "# CITATION.cff created with https://github.com/monperrus/bibtexbrowser/\n".
  731. "preferred-citation:\n".
  732. " title: \"A Comprehensive Study of Pseudo-tested Methods\"\n".
  733. " year: \"2018\"\n".
  734. " authors:\n".
  735. " - family-names: Vera-Pérez\n".
  736. " given-names: Oscar Luis\n".
  737. " - family-names: Danglot\n".
  738. " given-names: Benjamin\n".
  739. " - family-names: Monperrus\n".
  740. " given-names: Martin\n".
  741. " - family-names: Baudry\n".
  742. " given-names: Benoit\n";
  743. $this->assertEquals($expected,$entry->toCFF());
  744. }
  745. function test_uppercase() {
  746. print(preg_replace_callback('/\\\\uppercase\{(.*)\}/',"strtolowercallback", "$\uppercase{B}"));
  747. $bibtex = "@article{doe2000,title={Preferential polarization and its reversal in polycrystalline $\uppercase{B}i\uppercase{F}e\uppercase{O}_{3}$/$\uppercase{L}a_{0. 5}\uppercase{S}r_{0.5} \uppercase{C}o\uppercase{O}_{3}$ heterostructures},author={Jane Doe},journal={The Wordpress Journal},year=2000}";
  748. $test_data = fopen('php://memory','x+');
  749. fwrite($test_data, $bibtex);
  750. fseek($test_data,0);
  751. $db = new BibDataBase();
  752. $_GET[Q_FILE] = 'sample.bib';
  753. $db->update_internal("inline", $test_data);
  754. $this->assertEquals('Preferential polarization and its reversal in polycrystalline $BiFeO_{3}$/$La_{0. 5}Sr_{0.5} CoO_{3}$ heterostructures', $db->bibdb['doe2000']->getTitle());
  755. }
  756. function test_sorting_year() {
  757. $bibtex = "@article{doe2004,year=2004},@article{doe1999,year=1999},@article{doe2000,year=2000}";
  758. $test_data = fopen('php://memory','x+');
  759. fwrite($test_data, $bibtex);
  760. fseek($test_data,0);
  761. $db = new BibDataBase();
  762. $db->update_internal("inline", $test_data);
  763. // print_r($db);
  764. $data = array_values($db->bibdb);
  765. $this->assertEquals("2004", $data[0]->getYear());
  766. $this->assertEquals("1999", $data[1]->getYear());
  767. $this->assertEquals("2000", $data[2]->getYear());
  768. usort($data, 'compare_bib_entry_by_year');
  769. $this->assertEquals("1999", $data[0]->getYear());
  770. $this->assertEquals("2000", $data[1]->getYear());
  771. $this->assertEquals("2004", $data[2]->getYear());
  772. $bibtex = "@article{doe2004,year=2004},@article{doe1999,year=1999},@article{doe2000,year=2000}";
  773. }
  774. function test_sorting_month() {
  775. $bibtex = "@article{doe2004,year=2004, month={may}},@article{doe1999,year=2004,month={jan}},@article{doe2000,year=2000, month={dec}}";
  776. $test_data = fopen('php://memory','x+');
  777. fwrite($test_data, $bibtex);
  778. fseek($test_data,0);
  779. $db = new BibDataBase();
  780. $db->update_internal("inline", $test_data);
  781. // print_r($db);
  782. $data = array_values($db->bibdb);
  783. $this->assertEquals("may", $data[0]->getField("month"));
  784. usort($data, 'compare_bib_entry_by_month');
  785. $this->assertEquals("jan", $data[0]->getField("month"));
  786. $this->assertEquals("may", $data[1]->getField("month"));
  787. $this->assertEquals("dec", $data[2]->getField("month"));
  788. }
  789. function test_misc() {
  790. bibtexbrowser_configure('BIBLIOGRAPHYSTYLE','DefaultBibliographyStyle');
  791. $bibtex = "@misc{doe2004,title={foo bar title}, publisher={publisher}, howpublished={howpublished}}";
  792. $test_data = fopen('php://memory','x+');
  793. fwrite($test_data, $bibtex);
  794. fseek($test_data,0);
  795. $db = new BibDataBase();
  796. $db->update_internal("inline", $test_data);
  797. // print_r($db);
  798. $data = array_values($db->bibdb);
  799. $this->assertEquals('foo bar title, howpublished. [bibtex]', strip_tags($data[0]->toHTML()));
  800. }
  801. function test_note() {
  802. // fix https://github.com/monperrus/bibtexbrowser/issues/131
  803. bibtexbrowser_configure('BIBLIOGRAPHYSTYLE','DefaultBibliographyStyle');
  804. bibtexbrowser_configure('BIBTEXBROWSER_BIBTEX_LINKS',false);
  805. bibtexbrowser_configure('BIBTEXBROWSER_PDF_LINKS',false);
  806. $bibtex = "
  807. @inproceedings{exampleEntry,
  808. author = {Aurora Macías and Elena Navarro and Carlos E. Cuesta and Uwe Zdun},
  809. title = {Architecting Digital Twins Using a Domain-Driven Design-Based Approach},
  810. booktitle = {XXVII Jornadas de Ingenier'{\i}a del Software y Bases de Datos (JISBD 2023)},
  811. month = {September},
  812. note = {handle: 11705/JISBD/2023/7321},
  813. year = {2023},
  814. url = {https://hdl.handle.net/11705/JISBD/2023/7321},
  815. month = {September},
  816. pages = {1--1},
  817. publisher = {SISTEDES},
  818. editor = {Amador Dur'{a}n Toro},
  819. }";
  820. $test_data = fopen('php://memory','x+');
  821. fwrite($test_data, $bibtex);
  822. fseek($test_data,0);
  823. $db = new BibDataBase();
  824. $db->update_internal("inline", $test_data);
  825. // print_r($db);
  826. $data = array_values($db->bibdb);
  827. $this->assertEquals(' Architecting Digital Twins Using a Domain-Driven Design-Based Approach (Aurora Macías, Elena Navarro, Carlos E. Cuesta and Uwe Zdun), In XXVII Jornadas de Ingenier\'ia del Software y Bases de Datos (JISBD 2023) (Amador Dur\'an Toro, ed.), SISTEDES, 2023, handle: 11705/JISBD/2023/7321. ', strip_tags($data[0]->toHTML()));
  828. }
  829. function test_keyword() {
  830. bibtexbrowser_configure('BIBLIOGRAPHYSTYLE','DefaultBibliographyStyle');
  831. $bibtex = "@misc{doe2004,title={foo bar title}, publisher={publisher}, howpublished={howpublished}} @misc{doe2,title={baz}, keywords={bar}, howpublished={howpublished}}";
  832. $test_data = fopen('php://memory','x+');
  833. fwrite($test_data, $bibtex);
  834. fseek($test_data,0);
  835. $db = new BibDataBase();
  836. $db->update_internal("inline", $test_data);
  837. // print_r($db);
  838. // no keyword
  839. $entry = array_values($db->bibdb)[0];
  840. $entry->addKeyword("foo");
  841. $this->assertEquals('foo', $entry->getField("keywords"));
  842. // already one keyword
  843. $entry = array_values($db->bibdb)[1];
  844. $entry->addKeyword("foo");
  845. $this->assertEquals('bar;foo', $entry->getField("keywords"));
  846. }
  847. public function testYearDisplay() {
  848. // Create test entries
  849. $entry2020 = new RawBibEntry();
  850. $entry2020->setField('year', '2020');
  851. $entry2020->setField('title', 'Paper 2020');
  852. $entry2020->setField('author', 'Author A');
  853. // assert getKey
  854. $this->assertEquals('97c46f8bdf428ce28cfa05cdedba2ec1', $entry2020->getKey());
  855. $entry2019a = new RawBibEntry();
  856. $entry2019a->setField('year', '2019');
  857. $entry2019a->setField('title', 'Paper 2019 A');
  858. $entry2019a->setField('author', 'Author B');
  859. $entry2019b = new RawBibEntry();
  860. $entry2019b->setField('year', '2019');
  861. $entry2019b->setField('title', 'Paper 2019 B');
  862. $entry2019b->setField('author', 'Author C');
  863. // Create YearDisplay
  864. $display = new YearDisplay();
  865. // Set test entries
  866. $entries = array(
  867. 'key2020' => $entry2020,
  868. 'key2019a' => $entry2019a,
  869. 'key2019b' => $entry2019b
  870. );
  871. $display->setEntries($entries);
  872. // Get year index and verify
  873. $yearIndex = $display->yearIndex;
  874. $this->assertEquals("2020", $yearIndex[2020]);
  875. // Capture output
  876. ob_start();
  877. $display->display();
  878. $output = ob_get_clean();
  879. // Verify output contains years and titles
  880. // split output by line
  881. $lines = explode("\n", $output);
  882. $this->assertEquals('<div class="theader">2020</div><table class="result">', $lines[0]);
  883. }
  884. public function testXMLPrettyPrinter() {
  885. // Create sample BibTeX entry with various fields to test
  886. $bibtex = "@article{test2023,
  887. author = {Test Author},
  888. title = {A Test Title with Special Characters: & < >},
  889. journal = {Test Journal},
  890. year = {2023},
  891. volume = {1},
  892. number = {2},
  893. pages = {100--200}
  894. }";
  895. // Set up input stream with BibTeX content
  896. $stream = fopen('php://memory', 'r+');
  897. fwrite($stream, $bibtex);
  898. rewind($stream);
  899. // Create XMLPrettyPrinter and parse
  900. $printer = new XMLPrettyPrinter();
  901. $printer->header = false;
  902. $parser = new StateBasedBibtexParser($printer);
  903. // Capture output
  904. ob_start();
  905. $parser->parse($stream);
  906. $output = ob_get_clean();
  907. // Verify XML structure and content
  908. $this->assertStringContainsString('<?xml version="1.0"', $output);
  909. $this->assertStringContainsString('<bibfile>', $output);
  910. $this->assertStringContainsString('</bibfile>', $output);
  911. // Verify entry type
  912. $this->assertStringContainsString('<type>article</type>', $output);
  913. // Verify fields are present
  914. $this->assertStringContainsString('<key>author</key>', $output);
  915. $this->assertStringContainsString('<value>Test Author</value>', $output);
  916. // Verify special characters are escaped
  917. $this->assertStringContainsString('&amp;', $output);
  918. $this->assertStringContainsString('&lt;', $output);
  919. $this->assertStringContainsString('&gt;', $output);
  920. fclose($stream);
  921. }
  922. public function testBibtexDisplay() {
  923. // Create test entries
  924. $entry1 = new RawBibEntry();
  925. $entry1->setType('article');
  926. $entry1->setField('title', 'Test Title');
  927. $entry1->setField('author', 'Test Author');
  928. $entry1->setField('year', '2023');
  929. $entry1->setField('journal', 'Test Journal');
  930. $entry2 = new RawBibEntry();
  931. $entry2->setType('inproceedings');
  932. $entry2->setField('title', 'Another Title with Special Chars: é');
  933. $entry2->setField('author', 'Another Author');
  934. $entry2->setField('year', '2022');
  935. $entry2->setField('booktitle', 'Test Conference');
  936. // Create BibtexDisplay instance
  937. $display = new BibtexDisplay();
  938. $display->header = false;
  939. $display->setTitle('Test Export');
  940. $display->setEntries(array($entry1, $entry2));
  941. // assert entries in $display
  942. $this->assertEquals(2, count($display->entries));
  943. // set BIBTEXBROWSER_BIBTEX_VIEW to reconstructed
  944. bibtexbrowser_configure('BIBTEXBROWSER_BIBTEX_VIEW', 'reconstructed');
  945. // Capture output
  946. ob_start();
  947. $display->display();
  948. $output = ob_get_clean();
  949. // Verify output contains expected elements
  950. // Header comments
  951. $this->assertStringContainsString('% generated by bibtexbrowser', $output);
  952. $this->assertStringContainsString('% Test Export', $output);
  953. $this->assertStringContainsString('% Encoding: UTF-8', $output);
  954. // Entry 1 content
  955. $this->assertStringContainsString('@article{', $output);
  956. $this->assertStringContainsString('title = {Test Title}', $output);
  957. $this->assertStringContainsString('author = {Test Author}', $output);
  958. $this->assertStringContainsString('year = {2023}', $output);
  959. $this->assertStringContainsString('journal = {Test Journal}', $output);
  960. // Entry 2 content
  961. $this->assertStringContainsString('@inproceedings{', $output);
  962. $this->assertStringContainsString('title = {Another Title with Special Chars: é}', $output);
  963. $this->assertStringContainsString('author = {Another Author}', $output);
  964. $this->assertStringContainsString('year = {2022}', $output);
  965. $this->assertStringContainsString('booktitle = {Test Conference}', $output);
  966. }
  967. public function testCreateBibEntryDisplay() {
  968. // Test instance creation
  969. $display = createBibEntryDisplay();
  970. $this->assertInstanceOf('BibEntryDisplay', $display);
  971. // Create test entry
  972. $entry = new RawBibEntry();
  973. $entry->setType('article');
  974. $entry->setField('title', 'Test Title');
  975. $entry->setField('author', 'Test Author');
  976. $entry->setField('year', '2023');
  977. $entry->setField('journal', 'Test Journal');
  978. $entry->setField('abstract', 'Test Abstract');
  979. $entry->setField('url', 'http://example.com');
  980. // assertion on toString
  981. $this->assertEquals('article 4a9ba73904f4f22a7b37e18750ee5454', $entry->__toString());
  982. // Test display with entry
  983. $display->setEntries(array($entry));
  984. // Capture output
  985. ob_start();
  986. $display->display();
  987. $output = ob_get_clean();
  988. // Verify display output contains expected elements
  989. $this->assertStringContainsString('Test Title', $output);
  990. $this->assertStringContainsString('Test Author', $output);
  991. $this->assertStringContainsString('Test Journal', $output);
  992. $this->assertStringContainsString('Test Abstract', $output);
  993. // Test metadata generation
  994. $metadata = $display->metadata();
  995. $this->assertIsArray($metadata);
  996. // Verify metadata contains essential fields
  997. $foundTitle = false;
  998. $foundAuthor = false;
  999. foreach($metadata as $meta) {
  1000. if($meta[0] == 'citation_title' && $meta[1] == 'Test Title') {
  1001. $foundTitle = true;
  1002. }
  1003. if($meta[0] == 'citation_author' && $meta[1] == 'Author, Test') {
  1004. $foundAuthor = true;
  1005. }
  1006. }
  1007. $this->assertTrue($foundTitle);
  1008. $this->assertTrue($foundAuthor);
  1009. // Test title generation
  1010. $this->assertEquals('Test Title (bibtex)', $display->getTitle());
  1011. }
  1012. public function testParserDelegate() {
  1013. // Create test delegate
  1014. $delegate = new TestParserDelegate();
  1015. // Create parser with delegate
  1016. $parser = new StateBasedBibtexParser($delegate);
  1017. // Create test bibtex content
  1018. $bibtex = "@article{test2023,
  1019. author = {Test Author},
  1020. title = {Test Title},
  1021. journal = {Test Journal},
  1022. year = {2023},
  1023. abstract = {Test Abstract}
  1024. }";
  1025. // Create memory stream with test content
  1026. $stream = fopen('php://memory', 'r+');
  1027. fwrite($stream, $bibtex);
  1028. rewind($stream);
  1029. // Parse the content
  1030. $parser->parse($stream);
  1031. // Verify event sequence
  1032. $expected = array(
  1033. 'beginFile',
  1034. 'beginEntry',
  1035. 'setEntryType:article',
  1036. 'setEntryKey:test2023',
  1037. 'setEntryField:author:Test Author',
  1038. 'setEntryField:title:Test Title',
  1039. 'setEntryField:journal:Test Journal',
  1040. 'setEntryField:year:2023',
  1041. 'setEntryField:abstract:Test Abstract',
  1042. 'endEntry',
  1043. 'endFile'
  1044. );
  1045. $this->assertEquals($expected, $delegate->events);
  1046. fclose($stream);
  1047. }
  1048. public function testRSSDisplay() {
  1049. // Create test entries with various data to test RSS generation
  1050. $entry1 = new RawBibEntry();
  1051. $entry1->setType('article');
  1052. $entry1->setField('title', 'Test Title with Special Chars: & < >');
  1053. $entry1->setField('author', 'Test Author');
  1054. $entry1->setField('year', '2023');
  1055. $entry1->setField('journal', 'Test Journal');
  1056. $entry1->setField('abstract', 'Test Abstract with HTML <b>tags</b>');
  1057. $entry1->setField('url', 'http://example.com');
  1058. $entry2 = new RawBibEntry();
  1059. $entry2->setType('inproceedings');
  1060. $entry2->setField('title', 'Another Test Title');
  1061. $entry2->setField('author', 'Another Author');
  1062. $entry2->setField('year', '2022');
  1063. $entry2->setField('booktitle', 'Test Conference');
  1064. // Create RSSDisplay instance
  1065. $display = new RSSDisplay();
  1066. $display->header = false;
  1067. $display->setTitle('Test RSS Feed');
  1068. $display->setEntries(array($entry1, $entry2));
  1069. // Capture output
  1070. ob_start();
  1071. $display->display();
  1072. $output = ob_get_clean();
  1073. // Verify XML declaration
  1074. $this->assertStringContainsString('<?xml version="1.0" encoding="UTF-8"?>', $output);
  1075. // Verify RSS structure
  1076. $this->assertStringContainsString('<rss version="2.0"', $output);
  1077. $this->assertStringContainsString('<channel>', $output);
  1078. $this->assertStringContainsString('<title>Test RSS Feed</title>', $output);
  1079. // Verify entries
  1080. $this->assertStringContainsString('<item>', $output);
  1081. $this->assertStringContainsString('Test Title with Special Chars: &#38; &#60; &#62;', $output);
  1082. $this->assertStringContainsString('Another Test Title', $output);
  1083. // Verify text encoding
  1084. $rss = $display->text2rss('Test & Text <b>bold</b> with HTML &eacute;');
  1085. $this->assertEquals('Test &#38; Text bold with HTML ', $rss);
  1086. // Verify metadata handling
  1087. $this->assertStringContainsString('<description>', $output);
  1088. $this->assertStringContainsString('<link>', $output);
  1089. $this->assertStringContainsString('<guid', $output);
  1090. // Verify valid XML
  1091. $xml = new SimpleXMLElement($output);
  1092. $this->assertInstanceOf('SimpleXMLElement', $xml);
  1093. }
  1094. public function testHTMLTemplate() {
  1095. // Create mock content object that implements required methods
  1096. $mockContent = new class {
  1097. public function display() {
  1098. echo '<div class="test-content">Test Content</div>';
  1099. }
  1100. public function getTitle() {
  1101. return 'Test Title';
  1102. }
  1103. public function metadata() {
  1104. return array(
  1105. array('description', 'Test Description'),
  1106. array('keywords', 'test, bibtex')
  1107. );
  1108. }
  1109. };
  1110. // Capture output
  1111. bibtexbrowser_configure('BIBTEXBROWSER_USE_PROGRESSIVE_ENHANCEMENT', true);
  1112. ob_start();
  1113. HTMLTemplate($mockContent, false);
  1114. $output = ob_get_clean();
  1115. // Verify basic HTML structure
  1116. $this->assertStringContainsString('<!DOCTYPE html PUBLIC', $output);
  1117. $this->assertStringContainsString('<html xmlns="http://www.w3.org/1999/xhtml">', $output);
  1118. $this->assertStringContainsString('</html>', $output);
  1119. // Verify HEAD section
  1120. $this->assertStringContainsString('<meta http-equiv="Content-Type" content="text/html; charset=', $output);
  1121. $this->assertStringContainsString('<meta name="generator" content="bibtexbrowser', $output);
  1122. // Verify meta tags
  1123. $this->assertStringContainsString('<meta name="description" property="description" content="Test Description"', $output);
  1124. $this->assertStringContainsString('<meta name="keywords" property="keywords" content="test, bibtex"', $output);
  1125. // Verify title
  1126. $this->assertStringContainsString('<title>Test Title</title>', $output);
  1127. // Verify CSS inclusion
  1128. $this->assertStringContainsString('<style type="text/css">', $output);
  1129. // Verify content display
  1130. $this->assertStringContainsString('<div class="test-content">Test Content</div>', $output);
  1131. // Verify JavaScript includes when progressive enhancement enabled
  1132. $this->assertStringContainsString(JQUERY_URI, $output);
  1133. }
  1134. function test_hasPhrase() {
  1135. // Create test entries with various content to test phrase matching
  1136. $bibtex = "@article{entry1,title={Security Analysis of Web Applications},author={John Smith},year=2023,abstract={This paper discusses security vulnerabilities in modern web applications including XSS and CSRF attacks.}}
  1137. @inproceedings{entry2,title={Machine Learning for Cybersecurity},author={Jane Doe},year=2022,keywords={AI, security, neural networks},booktitle={International Conference on Security}}";
  1138. $test_data = fopen('php://memory','x+');
  1139. fwrite($test_data, $bibtex);
  1140. fseek($test_data,0);
  1141. $db = new BibDataBase();
  1142. $db->update_internal("inline", $test_data);
  1143. $entries = array_values($db->bibdb);
  1144. $entry1 = $entries[0]; // Security Analysis paper
  1145. $entry2 = $entries[1]; // Machine Learning paper
  1146. // Test basic phrase matching
  1147. $this->assertTrue($entry1->hasPhrase('security'));
  1148. $this->assertTrue($entry1->hasPhrase('web applications'));
  1149. $this->assertTrue($entry2->hasPhrase('machine learning'));
  1150. // Test case insensitivity
  1151. $this->assertTrue($entry1->hasPhrase('SECURITY'));
  1152. $this->assertTrue($entry2->hasPhrase('Machine LEARNING'));
  1153. // Test specific field searching
  1154. $this->assertTrue($entry1->hasPhrase('security', 'title'));
  1155. $this->assertTrue($entry2->hasPhrase('cybersecurity', 'title'));
  1156. $this->assertFalse($entry1->hasPhrase('cybersecurity', 'title')); // Should not match
  1157. // Test matching in different fields
  1158. $this->assertTrue($entry1->hasPhrase('smith', 'author'));
  1159. $this->assertTrue($entry2->hasPhrase('neural', 'keywords'));
  1160. $this->assertFalse($entry1->hasPhrase('neural', 'keywords')); // No keywords field in entry1
  1161. // Test advanced patterns with regex
  1162. $this->assertTrue($entry1->hasPhrase('XSS.*CSRF')); // Testing regex across words
  1163. $this->assertTrue($entry2->hasPhrase('AI.*security')); // Testing regex with multiple terms
  1164. $this->assertTrue($entry1->hasPhrase('vulnerab')); // Partial word matching
  1165. // Test non-matching phrases
  1166. $this->assertFalse($entry1->hasPhrase('blockchain')); // Not in any field
  1167. $this->assertFalse($entry2->hasPhrase('database', 'title')); // Not in title
  1168. // Test special characters
  1169. $bibtex_special = "@article{special,title={Testing special chars: a/b (c) [d] {e}}}";
  1170. $test_data_special = fopen('php://memory','x+');
  1171. fwrite($test_data_special, $bibtex_special);
  1172. fseek($test_data_special, 0);
  1173. $db_special = new BibDataBase();
  1174. $db_special->update_internal("inline", $test_data_special);
  1175. $entry_special = array_values($db_special->bibdb)[0];
  1176. // Test that special chars are properly handled in the search phrase
  1177. $this->assertTrue($entry_special->hasPhrase('a/b'));
  1178. $this->assertTrue($entry_special->hasPhrase('(c)'));
  1179. $this->assertTrue($entry_special->hasPhrase('[d]'));
  1180. $this->assertTrue($entry_special->hasPhrase('e')); // Curly braces get stripped in the stored fields
  1181. // Test edge cases
  1182. $this->assertFalse($entry1->hasPhrase('')); // Empty phrase should not match
  1183. }
  1184. function testMultiSearchWithSpecialChars() {
  1185. // Create test entries with C/C++ related content
  1186. $bibtex = "@article{cpp2023,
  1187. title={Advances in C/C++ Programming Language},
  1188. author={Jane Programmer},
  1189. journal={Journal of Programming Languages},
  1190. year=2023,
  1191. keywords={C/C++, programming languages, compilers}
  1192. }
  1193. @inproceedings{java2023,
  1194. title={Java vs Python: Performance Comparison},
  1195. author={John Coder},
  1196. booktitle={International Conference on Software Engineering},
  1197. year=2023,
  1198. keywords={Java, Python, performance}
  1199. }";
  1200. $test_data = fopen('php://memory','x+');
  1201. fwrite($test_data, $bibtex);
  1202. fseek($test_data, 0);
  1203. $db = new BibDataBase();
  1204. $db->update_internal("inline", $test_data);
  1205. // Test searching for C/C++ (which contains special characters / and +)
  1206. $q = array(Q_SEARCH => 'C/C++');
  1207. $results = $db->multisearch($q);
  1208. // Should match only the first entry
  1209. $this->assertEquals(1, count($results));
  1210. $this->assertEquals('Advances in C/C++ Programming Language', $results[0]->getTitle());
  1211. // Test searching with escaped slashes
  1212. $q = array(Q_SEARCH => 'C/C\+\+');
  1213. $results = $db->multisearch($q);
  1214. $this->assertEquals(1, count($results));
  1215. // Test with partial match
  1216. $q = array(Q_SEARCH => 'C/C');
  1217. $results = $db->multisearch($q);
  1218. $this->assertEquals(1, count($results));
  1219. // Test with keywords field specifically
  1220. $q = array(Q_TAG => 'C/C++');
  1221. $results = $db->multisearch($q);
  1222. $this->assertEquals(1, count($results));
  1223. // Test searching for something that doesn't exist
  1224. $q = array(Q_SEARCH => 'Rust');
  1225. $results = $db->multisearch($q);
  1226. $this->assertEquals(0, count($results));
  1227. }
  1228. function test_tags_pagination() {
  1229. // Define the page size for pagination
  1230. bibtexbrowser_configure('TAGS_SIZE', 2);
  1231. // Create a test BibTeX database with multiple entries and keywords
  1232. $bibtex = "@article{paper1,title={Paper One},keywords={tagA, tagB},year=2020}
  1233. @article{paper2,title={Paper Two},keywords={tagC},year=2020}
  1234. @article{paper3,title={Paper Three},keywords={tagD},year=2020}
  1235. @article{paper4,title={Paper Four},keywords={tagE},year=2020}";
  1236. $test_data = fopen('php://memory','r+');
  1237. fwrite($test_data, $bibtex);
  1238. fseek($test_data, 0);
  1239. $db = new BibDataBase();
  1240. $db->update_internal("inline", $test_data);
  1241. // Create MenuManager display
  1242. $display = new MenuManager();
  1243. $display->setDB($db);
  1244. // Test the first page
  1245. $_GET["tags_page"] = '1';
  1246. ob_start();
  1247. $display->display();
  1248. $output1 = ob_get_clean();
  1249. // Tags are sorted alphabetically.
  1250. $this->assertStringContainsString('tagA', $output1);
  1251. $this->assertStringContainsString('tagB', $output1);
  1252. $this->assertStringNotContainsString('tagC', $output1);
  1253. // Verify pagination link to the next page
  1254. $this->assertStringContainsString('keywords_page=2', $output1);
  1255. // Test the second page
  1256. $_GET["keywords_page"] = '2';
  1257. ob_start();
  1258. $display->display();
  1259. $output2 = ob_get_clean();
  1260. $this->assertStringContainsString('tagC', $output2);
  1261. $this->assertStringContainsString('tagD', $output2);
  1262. $this->assertStringNotContainsString('tagA', $output2);
  1263. $this->assertStringNotContainsString('tagE', $output2);
  1264. // Verify navigation links to previous and next pages
  1265. $this->assertStringContainsString('keywords_page=1', $output2);
  1266. $this->assertStringContainsString('keywords_page=3', $output2);
  1267. // Test the third page
  1268. $_GET["keywords_page"] = '3';
  1269. ob_start();
  1270. $display->display();
  1271. $output3 = ob_get_clean();
  1272. $this->assertStringContainsString('tagE', $output3);
  1273. $this->assertStringNotContainsString('tagD', $output3);
  1274. // Verify navigation link to the previous page
  1275. $this->assertStringContainsString('keywords_page=2', $output3);
  1276. $this->assertStringNotContainsString('keywords_page=4', $output3); // No next page
  1277. // Clean up
  1278. unset($_GET["keywords_page"]);
  1279. }
  1280. function test_venuevc_pagination() {
  1281. // Define the page size for pagination
  1282. bibtexbrowser_configure('VENUE_SIZE', 2);
  1283. // Create a test BibTeX database with multiple entries
  1284. $bibtex = "@article{paper1,title={Paper One},journal={Journal A},year=2020}
  1285. @article{paper2,title={Paper Two},journal={Journal A},year=2020}
  1286. @article{paper3,title={Paper Three},journal={Journal B},year=2020}
  1287. @article{paper4,title={Paper Four},journal={Journal B},year=2020}
  1288. @article{paper5,title={Paper Five},journal={Journal C},year=2020}
  1289. @article{paper6,title={Paper Six},journal={Journal C},year=2020}";
  1290. $test_data = fopen('php://memory','r+');
  1291. fwrite($test_data, $bibtex);
  1292. fseek($test_data, 0);
  1293. $db = new BibDataBase();
  1294. $db->update_internal("inline", $test_data);
  1295. // Create VenueVC display
  1296. $display = new MenuManager();
  1297. $display->setDB($db);
  1298. // First, test without pagination parameter
  1299. $_GET["venue_page"] = '1';
  1300. ob_start();
  1301. $display->display();
  1302. $output = ob_get_clean();
  1303. // Verify all entries are shown when no pagination is specified
  1304. $this->assertStringContainsString('Journal A', $output);
  1305. $this->assertStringContainsString('Journal B', $output);
  1306. // Test with pagination parameter
  1307. $_GET["venue_page"] = '1';
  1308. ob_start();
  1309. $display->display();
  1310. $output1 = ob_get_clean();
  1311. // Create XML parser to properly analyze the HTML structure
  1312. $xml = new SimpleXMLElement("<doc>".$output1."</doc>");
  1313. // Count number of entries displayed on first page
  1314. //$result = $xml->xpath('//tr[contains(@class, "btb-menu-items")]');
  1315. //$this->assertEquals($PAGE_SIZE, count($result));
  1316. // Verify pagination links existence
  1317. $this->assertStringContainsString('venue_page=2', $output1);
  1318. // Test second page
  1319. $_GET["venue_page"] = '2';
  1320. ob_start();
  1321. $display->display();
  1322. $output2 = ob_get_clean();
  1323. // Verify navigation links
  1324. $this->assertStringContainsString('venue_page=1', $output2); // Link to previous page
  1325. // Verify different entries on second page
  1326. $this->assertStringContainsString('Journal C', $output2);
  1327. // Clean up
  1328. unset($_GET["venue_page"]);
  1329. }
  1330. function test_AcademicDisplay() {
  1331. // Create test BibTeX database with entries from different categories
  1332. $bibtex = "@article{journal1,title={Journal Article},author={John Doe},journal={Nature},year=2023,type={Journal Articles}}
  1333. @inproceedings{conf1,title={Conference Paper},author={Jane Smith},booktitle={ICSE},year=2023,type={Refereed Conference Papers}}
  1334. @book{book1,title={A Book},author={Bob Johnson},publisher={Springer},year=2022,type={Books}}
  1335. @techreport{tech1,title={Technical Report},author={Alice Brown},institution={MIT},year=2023,type={Technical Reports}}";
  1336. $test_data = fopen('php://memory','x+');
  1337. fwrite($test_data, $bibtex);
  1338. fseek($test_data,0);
  1339. $db = new BibDataBase();
  1340. $db->update_internal("inline", $test_data);
  1341. // Test with BIBTEXBROWSER_ACADEMIC_TOC = true
  1342. bibtexbrowser_configure('BIBTEXBROWSER_ACADEMIC_TOC', true);
  1343. $display = new AcademicDisplay();
  1344. $display->setDB($db);
  1345. ob_start();
  1346. $display->display();
  1347. $output_with_toc = ob_get_clean();
  1348. // Verify TOC is present
  1349. // $this->assertStringContainsString('class="btb-menu-toc"', $output_with_toc);
  1350. $this->assertStringContainsString('Refereed Articles', $output_with_toc);
  1351. // Verify HTML structure for both cases
  1352. $xml1 = new SimpleXMLElement("<doc>".$output_with_toc."</doc>");
  1353. $headers1 = $xml1->xpath('//div[@class="sheader"]');
  1354. $this->assertEquals(0, count($headers1));
  1355. $anchors = $xml1->xpath('//h2');
  1356. $this->assertGreaterThan(3, count($anchors));
  1357. // Test with BIBTEXBROWSER_ACADEMIC_TOC = false
  1358. bibtexbrowser_configure('BIBTEXBROWSER_ACADEMIC_TOC', false);
  1359. $display2 = new AcademicDisplay();
  1360. $display2->setDB($db);
  1361. ob_start();
  1362. $display2->display();
  1363. $output_without_toc = ob_get_clean();
  1364. // Verify TOC is not present
  1365. $this->assertStringNotContainsString('class="btb-menu-toc"', $output_without_toc);
  1366. // But category headers should still be present
  1367. $this->assertStringContainsString('Refereed Articles', $output_without_toc);
  1368. $xml2 = new SimpleXMLElement("<doc>".$output_without_toc."</doc>");
  1369. $headers2 = $xml2->xpath('//div[@class="sheader"]');
  1370. $this->assertGreaterThan(0, count($headers2));
  1371. }
  1372. } // end class
  1373. // Test implementation that records events
  1374. class TestParserDelegate extends ParserDelegate {
  1375. public $events = array();
  1376. function beginFile() {
  1377. $this->events[] = 'beginFile';
  1378. }
  1379. function endFile() {
  1380. $this->events[] = 'endFile';
  1381. }
  1382. function setEntryField($key, $value) {
  1383. $this->events[] = "setEntryField:".trim($key).":".trim($value);
  1384. }
  1385. function setEntryType($type) {
  1386. $this->events[] = "setEntryType:$type";
  1387. }
  1388. function setEntryKey($key) {
  1389. $this->events[] = "setEntryKey:$key";
  1390. }
  1391. function beginEntry() {
  1392. $this->events[] = 'beginEntry';
  1393. }
  1394. function endEntry($source) {
  1395. $this->events[] = 'endEntry';
  1396. }
  1397. }
  1398. @copy('bibtexbrowser.local.php.bak','bibtexbrowser.local.php');
  1399. ?>