Rev 1 | Ir a la última revisión | Autoría | Comparar con el anterior | Ultima modificación | Ver Log |
<?php// This file is part of Moodle - http://moodle.org///// Moodle is free software: you can redistribute it and/or modify// it under the terms of the GNU General Public License as published by// the Free Software Foundation, either version 3 of the License, or// (at your option) any later version.//// Moodle is distributed in the hope that it will be useful,// but WITHOUT ANY WARRANTY; without even the implied warranty of// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the// GNU General Public License for more details.//// You should have received a copy of the GNU General Public License// along with Moodle. If not, see <http://www.gnu.org/licenses/>./*** Test xml_writer tests.** @package core_backup* @category test* @copyright 2010 onwards Eloy Lafuente (stronk7) {@link http://stronk7.com}* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later*/namespace core_backup;use memory_xml_output;use phpunit_util;use xml_contenttransformer;use xml_output;use xml_writer;use xml_writer_exception;defined('MOODLE_INTERNAL') || die();// Include all the needed stuffglobal $CFG;require_once($CFG->dirroot . '/backup/util/xml/xml_writer.class.php');require_once($CFG->dirroot . '/backup/util/xml/output/xml_output.class.php');require_once($CFG->dirroot . '/backup/util/xml/output/memory_xml_output.class.php');require_once($CFG->dirroot . '/backup/util/xml/contenttransformer/xml_contenttransformer.class.php');/*** Test xml_writer tests.** @package core_backup* @category test* @copyright 2010 onwards Eloy Lafuente (stronk7) {@link http://stronk7.com}* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later*/class writer_test extends \basic_testcase {/*** test xml_writer public methods*/function test_xml_writer_public_api(): void {global $CFG;// Instantiate xml_output$xo = new memory_xml_output();$this->assertTrue($xo instanceof xml_output);// Instantiate xml_writer with null xml_outputtry {$xw = new mock_xml_writer(null);$this->assertTrue(false, 'xml_writer_exception expected');} catch (\Exception $e) {$this->assertTrue($e instanceof xml_writer_exception);$this->assertEquals($e->errorcode, 'invalid_xml_output');}// Instantiate xml_writer with wrong xml_output objecttry {$xw = new mock_xml_writer(new \stdClass());$this->assertTrue(false, 'xml_writer_exception expected');} catch (\Exception $e) {$this->assertTrue($e instanceof xml_writer_exception);$this->assertEquals($e->errorcode, 'invalid_xml_output');}// Instantiate xml_writer with wrong xml_contenttransformer objecttry {$xw = new mock_xml_writer($xo, new \stdClass());$this->assertTrue(false, 'xml_writer_exception expected');} catch (\Exception $e) {$this->assertTrue($e instanceof xml_writer_exception);$this->assertEquals($e->errorcode, 'invalid_xml_contenttransformer');}// Instantiate xml_writer and start it twice$xw = new mock_xml_writer($xo);$xw->start();try {$xw->start();$this->assertTrue(false, 'xml_writer_exception expected');} catch (\Exception $e) {$this->assertTrue($e instanceof xml_writer_exception);$this->assertEquals($e->errorcode, 'xml_writer_already_started');}// Instantiate xml_writer and stop it twice$xo = new memory_xml_output();$xw = new mock_xml_writer($xo);$xw->start();$xw->stop();try {$xw->stop();$this->assertTrue(false, 'xml_writer_exception expected');} catch (\Exception $e) {$this->assertTrue($e instanceof xml_writer_exception);$this->assertEquals($e->errorcode, 'xml_writer_already_stopped');}// Stop writer without starting it$xo = new memory_xml_output();$xw = new mock_xml_writer($xo);try {$xw->stop();$this->assertTrue(false, 'xml_writer_exception expected');} catch (\Exception $e) {$this->assertTrue($e instanceof xml_writer_exception);$this->assertEquals($e->errorcode, 'xml_writer_not_started');}// Start writer after stopping it$xo = new memory_xml_output();$xw = new mock_xml_writer($xo);$xw->start();$xw->stop();try {$xw->start();$this->assertTrue(false, 'xml_writer_exception expected');} catch (\Exception $e) {$this->assertTrue($e instanceof xml_writer_exception);$this->assertEquals($e->errorcode, 'xml_writer_already_stopped');}// Try to set prologue/schema after start$xo = new memory_xml_output();$xw = new mock_xml_writer($xo);$xw->start();try {$xw->set_nonamespace_schema('http://moodle.org');$this->assertTrue(false, 'xml_writer_exception expected');} catch (\Exception $e) {$this->assertTrue($e instanceof xml_writer_exception);$this->assertEquals($e->errorcode, 'xml_writer_already_started');}try {$xw->set_prologue('sweet prologue');$this->assertTrue(false, 'xml_writer_exception expected');} catch (\Exception $e) {$this->assertTrue($e instanceof xml_writer_exception);$this->assertEquals($e->errorcode, 'xml_writer_already_started');}// Instantiate properly with memory_xml_output, start and stop.// Must get default UTF-8 prologue$xo = new memory_xml_output();$xw = new mock_xml_writer($xo);$xw->start();$xw->stop();$this->assertEquals($xo->get_allcontents(), $xw->get_default_prologue());// Instantiate, set prologue and schema, put 1 full tag and get results$xo = new memory_xml_output();$xw = new mock_xml_writer($xo);$xw->set_prologue('CLEARLY WRONG PROLOGUE');$xw->set_nonamespace_schema('http://moodle.org/littleschema');$xw->start();$xw->full_tag('TEST', 'Hello World!', array('id' => 1));$xw->stop();$result = $xo->get_allcontents();// Perform various checks$this->assertEquals(strpos($result, 'WRONG'), 8);$this->assertEquals(strpos($result, '<TEST id="1"'), 22);$this->assertEquals(strpos($result, 'xmlns:xsi='), 39);$this->assertEquals(strpos($result, 'http://moodle.org/littleschema'), 128);$this->assertEquals(strpos($result, 'Hello World'), 160);$this->assertFalse(strpos($result, $xw->get_default_prologue()));// Try to close one tag in wrong order$xo = new memory_xml_output();$xw = new mock_xml_writer($xo);$xw->start();$xw->begin_tag('first');$xw->begin_tag('second');try {$xw->end_tag('first');$this->assertTrue(false, 'xml_writer_exception expected');} catch (\Exception $e) {$this->assertTrue($e instanceof xml_writer_exception);$this->assertEquals($e->errorcode, 'xml_writer_end_tag_no_match');}// Try to close one tag before starting any tag$xo = new memory_xml_output();$xw = new mock_xml_writer($xo);$xw->start();try {$xw->end_tag('first');$this->assertTrue(false, 'xml_writer_exception expected');} catch (\Exception $e) {$this->assertTrue($e instanceof xml_writer_exception);$this->assertEquals($e->errorcode, 'xml_writer_end_tag_no_match');}// Full tag without contents (null and empty string)$xo = new memory_xml_output();$xw = new mock_xml_writer($xo);$xw->set_prologue(''); // empty prologue for easier matching$xw->start();$xw->full_tag('tagname', null, array('attrname' => 'attrvalue'));$xw->full_tag('tagname2', '', array('attrname' => 'attrvalue'));$xw->stop();$result = $xo->get_allcontents();$this->assertEquals($result, '<tagname attrname="attrvalue" /><tagname2 attrname="attrvalue"></tagname2>');// Test case-folding is working$xo = new memory_xml_output();$xw = new mock_xml_writer($xo, null, true);$xw->set_prologue(''); // empty prologue for easier matching$xw->start();$xw->full_tag('tagname', 'textcontent', array('attrname' => 'attrvalue'));$xw->stop();$result = $xo->get_allcontents();$this->assertEquals($result, '<TAGNAME ATTRNAME="attrvalue">textcontent</TAGNAME>');// Test UTF-8 chars in tag and attribute names, attr values and contents$xo = new memory_xml_output();$xw = new mock_xml_writer($xo);$xw->set_prologue(''); // empty prologue for easier matching$xw->start();$xw->full_tag('áéíóú', 'ÁÉÍÓÚ', array('àèìòù' => 'ÀÈÌÒÙ'));$xw->stop();$result = $xo->get_allcontents();$this->assertEquals($result, '<áéíóú àèìòù="ÀÈÌÒÙ">ÁÉÍÓÚ</áéíóú>');// Try non-safe content in attributes$xo = new memory_xml_output();$xw = new mock_xml_writer($xo);$xw->set_prologue(''); // empty prologue for easier matching$xw->start();$xw->full_tag('tagname', 'textcontent', array('attrname' => 'attr' . chr(27) . '\'"value'));$xw->stop();$result = $xo->get_allcontents();$this->assertEquals($result, '<tagname attrname="attr\'"value">textcontent</tagname>');// Try non-safe content in text$xo = new memory_xml_output();$xw = new mock_xml_writer($xo);$xw->set_prologue(''); // empty prologue for easier matching$xw->start();$xw->full_tag('tagname', "text\r\ncontent\rwith" . chr(27), array('attrname' => 'attrvalue'));$xw->stop();$result = $xo->get_allcontents();$this->assertEquals($result, '<tagname attrname="attrvalue">text' . "\ncontent\n" . 'with</tagname>');// Try to stop the writer without clossing all the open tags$xo = new memory_xml_output();$xw = new mock_xml_writer($xo);$xw->start();$xw->begin_tag('first');try {$xw->stop();$this->assertTrue(false, 'xml_writer_exception expected');} catch (\Exception $e) {$this->assertTrue($e instanceof xml_writer_exception);$this->assertEquals($e->errorcode, 'xml_writer_open_tags_remaining');}// Test simple transformer$xo = new memory_xml_output();$xt = new mock_xml_contenttransformer();$xw = new mock_xml_writer($xo, $xt);$xw->set_prologue(''); // empty prologue for easier matching$xw->start();$xw->full_tag('tagname', null, array('attrname' => 'attrvalue'));$xw->full_tag('tagname2', 'somecontent', array('attrname' => 'attrvalue'));$xw->stop();$result = $xo->get_allcontents();$this->assertEquals($result, '<tagname attrname="attrvalue" /><tagname2 attrname="attrvalue">testsomecontent</tagname2>');// Build a complex XML file and test results against stored file in fixtures$xo = new memory_xml_output();$xw = new mock_xml_writer($xo);$xw->start();$xw->begin_tag('toptag', array('name' => 'toptag', 'level' => 1, 'path' => '/toptag'));$xw->full_tag('secondtag', 'secondvalue', array('name' => 'secondtag', 'level' => 2, 'path' => '/toptag/secondtag', 'value' => 'secondvalue'));$xw->begin_tag('thirdtag', array('name' => 'thirdtag', 'level' => 2, 'path' => '/toptag/thirdtag'));$xw->full_tag('onevalue', 'onevalue', array('name' => 'onevalue', 'level' => 3, 'path' => '/toptag/thirdtag/onevalue'));$xw->full_tag('onevalue', 'anothervalue', array('name' => 'onevalue', 'level' => 3, 'value' => 'anothervalue'));$xw->full_tag('onevalue', 'yetanothervalue', array('name' => 'onevalue', 'level' => 3, 'value' => 'yetanothervalue'));$xw->full_tag('twovalue', 'twovalue', array('name' => 'twovalue', 'level' => 3, 'path' => '/toptag/thirdtag/twovalue'));$xw->begin_tag('forthtag', array('name' => 'forthtag', 'level' => 3, 'path' => '/toptag/thirdtag/forthtag'));$xw->full_tag('innervalue', 'innervalue');$xw->begin_tag('innertag');$xw->begin_tag('superinnertag', array('name' => 'superinnertag', 'level' => 5));$xw->full_tag('superinnervalue', 'superinnervalue', array('name' => 'superinnervalue', 'level' => 6));$xw->end_tag('superinnertag');$xw->end_tag('innertag');$xw->end_tag('forthtag');$xw->begin_tag('fifthtag', array('level' => 3));$xw->begin_tag('sixthtag', array('level' => 4));$xw->full_tag('seventh', 'seventh', array('level' => 5));$xw->end_tag('sixthtag');$xw->end_tag('fifthtag');$xw->full_tag('finalvalue', 'finalvalue', array('name' => 'finalvalue', 'level' => 3, 'path' => '/toptag/thirdtag/finalvalue'));$xw->full_tag('finalvalue');$xw->end_tag('thirdtag');$xw->end_tag('toptag');$xw->stop();$result = $xo->get_allcontents();$fcontents = file_get_contents($CFG->dirroot . '/backup/util/xml/tests/fixtures/test1.xml');// Normalise carriage return characters.$fcontents = phpunit_util::normalise_line_endings($fcontents);$this->assertEquals(trim($result), trim($fcontents));}}/** helper extended xml_writer class that makes some methods public for testing*/class mock_xml_writer extends xml_writer {public function get_default_prologue() {return parent::get_default_prologue();}}/** helper extended xml_contenttransformer prepending "test" to all the notnull contents*/class mock_xml_contenttransformer extends xml_contenttransformer {public function process($content) {return is_null($content) ? null : 'test' . $content;}}