Moodle  2.2.1
http://www.collinsharper.com
C:/xampp/htdocs/moodle/backup/util/xml/simpletest/testwriter.php
Go to the documentation of this file.
00001 <?php
00002 
00003 // This file is part of Moodle - http://moodle.org/
00004 //
00005 // Moodle is free software: you can redistribute it and/or modify
00006 // it under the terms of the GNU General Public License as published by
00007 // the Free Software Foundation, either version 3 of the License, or
00008 // (at your option) any later version.
00009 //
00010 // Moodle is distributed in the hope that it will be useful,
00011 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00012 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013 // GNU General Public License for more details.
00014 //
00015 // You should have received a copy of the GNU General Public License
00016 // along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
00017 
00025 // Prevent direct access to this file
00026 if (!defined('MOODLE_INTERNAL')) {
00027     die('Direct access to this script is forbidden.');
00028 }
00029 
00030 // Include all the needed stuff
00031 require_once($CFG->dirroot . '/backup/util/xml/xml_writer.class.php');
00032 require_once($CFG->dirroot . '/backup/util/xml/output/xml_output.class.php');
00033 require_once($CFG->dirroot . '/backup/util/xml/output/memory_xml_output.class.php');
00034 require_once($CFG->dirroot . '/backup/util/xml/contenttransformer/xml_contenttransformer.class.php');
00035 
00036 /*
00037  * xml_writer tests
00038  */
00039 class xml_writer_test extends UnitTestCase {
00040 
00041     public static $includecoverage = array('backup/util/xml/xml_writer.class.php');
00042     public static $excludecoverage = array('backup/util/xml/simpletest');
00043 
00044     /*
00045      * test xml_writer public methods
00046      */
00047     function test_xml_writer_public_api() {
00048         global $CFG;
00049         // Instantiate xml_output
00050         $xo = new memory_xml_output();
00051         $this->assertTrue($xo instanceof xml_output);
00052 
00053         // Instantiate xml_writer with null xml_output
00054         try {
00055             $xw = new mock_xml_writer(null);
00056             $this->assertTrue(false, 'xml_writer_exception expected');
00057         } catch (exception $e) {
00058             $this->assertTrue($e instanceof xml_writer_exception);
00059             $this->assertEqual($e->errorcode, 'invalid_xml_output');
00060         }
00061 
00062         // Instantiate xml_writer with wrong xml_output object
00063         try {
00064             $xw = new mock_xml_writer(new stdclass());
00065             $this->assertTrue(false, 'xml_writer_exception expected');
00066         } catch (exception $e) {
00067             $this->assertTrue($e instanceof xml_writer_exception);
00068             $this->assertEqual($e->errorcode, 'invalid_xml_output');
00069         }
00070 
00071         // Instantiate xml_writer with wrong xml_contenttransformer object
00072         try {
00073             $xw = new mock_xml_writer($xo, new stdclass());
00074             $this->assertTrue(false, 'xml_writer_exception expected');
00075         } catch (exception $e) {
00076             $this->assertTrue($e instanceof xml_writer_exception);
00077             $this->assertEqual($e->errorcode, 'invalid_xml_contenttransformer');
00078         }
00079 
00080         // Instantiate xml_writer and start it twice
00081         $xw = new mock_xml_writer($xo);
00082         $xw->start();
00083         try {
00084             $xw->start();
00085             $this->assertTrue(false, 'xml_writer_exception expected');
00086         } catch (exception $e) {
00087             $this->assertTrue($e instanceof xml_writer_exception);
00088             $this->assertEqual($e->errorcode, 'xml_writer_already_started');
00089         }
00090 
00091         // Instantiate xml_writer and stop it twice
00092         $xo = new memory_xml_output();
00093         $xw = new mock_xml_writer($xo);
00094         $xw->start();
00095         $xw->stop();
00096         try {
00097             $xw->stop();
00098             $this->assertTrue(false, 'xml_writer_exception expected');
00099         } catch (exception $e) {
00100             $this->assertTrue($e instanceof xml_writer_exception);
00101             $this->assertEqual($e->errorcode, 'xml_writer_already_stopped');
00102         }
00103 
00104         // Stop writer without starting it
00105         $xo = new memory_xml_output();
00106         $xw = new mock_xml_writer($xo);
00107         try {
00108             $xw->stop();
00109             $this->assertTrue(false, 'xml_writer_exception expected');
00110         } catch (exception $e) {
00111             $this->assertTrue($e instanceof xml_writer_exception);
00112             $this->assertEqual($e->errorcode, 'xml_writer_not_started');
00113         }
00114 
00115         // Start writer after stopping it
00116         $xo = new memory_xml_output();
00117         $xw = new mock_xml_writer($xo);
00118         $xw->start();
00119         $xw->stop();
00120         try {
00121             $xw->start();
00122             $this->assertTrue(false, 'xml_writer_exception expected');
00123         } catch (exception $e) {
00124             $this->assertTrue($e instanceof xml_writer_exception);
00125             $this->assertEqual($e->errorcode, 'xml_writer_already_stopped');
00126         }
00127 
00128         // Try to set prologue/schema after start
00129         $xo = new memory_xml_output();
00130         $xw = new mock_xml_writer($xo);
00131         $xw->start();
00132         try {
00133             $xw->set_nonamespace_schema('http://moodle.org');
00134             $this->assertTrue(false, 'xml_writer_exception expected');
00135         } catch (exception $e) {
00136             $this->assertTrue($e instanceof xml_writer_exception);
00137             $this->assertEqual($e->errorcode, 'xml_writer_already_started');
00138         }
00139         try {
00140             $xw->set_prologue('sweet prologue');
00141             $this->assertTrue(false, 'xml_writer_exception expected');
00142         } catch (exception $e) {
00143             $this->assertTrue($e instanceof xml_writer_exception);
00144             $this->assertEqual($e->errorcode, 'xml_writer_already_started');
00145         }
00146 
00147         // Instantiate properly with memory_xml_output, start and stop.
00148         // Must get default UTF-8 prologue
00149         $xo = new memory_xml_output();
00150         $xw = new mock_xml_writer($xo);
00151         $xw->start();
00152         $xw->stop();
00153         $this->assertEqual($xo->get_allcontents(), $xw->get_default_prologue());
00154 
00155         // Instantiate, set prologue and schema, put 1 full tag and get results
00156         $xo = new memory_xml_output();
00157         $xw = new mock_xml_writer($xo);
00158         $xw->set_prologue('CLEARLY WRONG PROLOGUE');
00159         $xw->set_nonamespace_schema('http://moodle.org/littleschema');
00160         $xw->start();
00161         $xw->full_tag('TEST', 'Hello World!', array('id' => 1));
00162         $xw->stop();
00163         $result = $xo->get_allcontents();
00164         // Perform various checks
00165         $this->assertEqual(strpos($result, 'WRONG'), 8);
00166         $this->assertEqual(strpos($result, '<TEST id="1"'), 22);
00167         $this->assertEqual(strpos($result, 'xmlns:xsi='), 39);
00168         $this->assertEqual(strpos($result, 'http://moodle.org/littleschema'), 128);
00169         $this->assertEqual(strpos($result, 'Hello World'), 160);
00170         $this->assertFalse(strpos($result, $xw->get_default_prologue()));
00171 
00172         // Try to close one tag in wrong order
00173         $xo = new memory_xml_output();
00174         $xw = new mock_xml_writer($xo);
00175         $xw->start();
00176         $xw->begin_tag('first');
00177         $xw->begin_tag('second');
00178         try {
00179             $xw->end_tag('first');
00180             $this->assertTrue(false, 'xml_writer_exception expected');
00181         } catch (exception $e) {
00182             $this->assertTrue($e instanceof xml_writer_exception);
00183             $this->assertEqual($e->errorcode, 'xml_writer_end_tag_no_match');
00184         }
00185 
00186         // Try to close one tag before starting any tag
00187         $xo = new memory_xml_output();
00188         $xw = new mock_xml_writer($xo);
00189         $xw->start();
00190         try {
00191             $xw->end_tag('first');
00192             $this->assertTrue(false, 'xml_writer_exception expected');
00193         } catch (exception $e) {
00194             $this->assertTrue($e instanceof xml_writer_exception);
00195             $this->assertEqual($e->errorcode, 'xml_writer_end_tag_no_match');
00196         }
00197 
00198         // Full tag without contents (null and empty string)
00199         $xo = new memory_xml_output();
00200         $xw = new mock_xml_writer($xo);
00201         $xw->set_prologue(''); // empty prologue for easier matching
00202         $xw->start();
00203         $xw->full_tag('tagname', null, array('attrname' => 'attrvalue'));
00204         $xw->full_tag('tagname2', '', array('attrname' => 'attrvalue'));
00205         $xw->stop();
00206         $result = $xo->get_allcontents();
00207         $this->assertEqual($result, '<tagname attrname="attrvalue" /><tagname2 attrname="attrvalue"></tagname2>');
00208 
00209 
00210         // Test case-folding is working
00211         $xo = new memory_xml_output();
00212         $xw = new mock_xml_writer($xo, null, true);
00213         $xw->set_prologue(''); // empty prologue for easier matching
00214         $xw->start();
00215         $xw->full_tag('tagname', 'textcontent', array('attrname' => 'attrvalue'));
00216         $xw->stop();
00217         $result = $xo->get_allcontents();
00218         $this->assertEqual($result, '<TAGNAME ATTRNAME="attrvalue">textcontent</TAGNAME>');
00219 
00220         // Test UTF-8 chars in tag and attribute names, attr values and contents
00221         $xo = new memory_xml_output();
00222         $xw = new mock_xml_writer($xo);
00223         $xw->set_prologue(''); // empty prologue for easier matching
00224         $xw->start();
00225         $xw->full_tag('áéíóú', 'ÁÉÍÓÚ', array('àèìòù' => 'ÀÈÌÒÙ'));
00226         $xw->stop();
00227         $result = $xo->get_allcontents();
00228         $this->assertEqual($result, '<áéíóú àèìòù="ÀÈÌÒÙ">ÁÉÍÓÚ</áéíóú>');
00229 
00230         // Try non-safe content in attributes
00231         $xo = new memory_xml_output();
00232         $xw = new mock_xml_writer($xo);
00233         $xw->set_prologue(''); // empty prologue for easier matching
00234         $xw->start();
00235         $xw->full_tag('tagname', 'textcontent', array('attrname' => 'attr' . chr(27) . '\'"value'));
00236         $xw->stop();
00237         $result = $xo->get_allcontents();
00238         $this->assertEqual($result, '<tagname attrname="attr\'&quot;value">textcontent</tagname>');
00239 
00240         // Try non-safe content in text
00241         $xo = new memory_xml_output();
00242         $xw = new mock_xml_writer($xo);
00243         $xw->set_prologue(''); // empty prologue for easier matching
00244         $xw->start();
00245         $xw->full_tag('tagname', "text\r\ncontent\rwith" . chr(27), array('attrname' => 'attrvalue'));
00246         $xw->stop();
00247         $result = $xo->get_allcontents();
00248         $this->assertEqual($result, '<tagname attrname="attrvalue">text' . "\ncontent\n" . 'with</tagname>');
00249 
00250         // Try to stop the writer without clossing all the open tags
00251         $xo = new memory_xml_output();
00252         $xw = new mock_xml_writer($xo);
00253         $xw->start();
00254         $xw->begin_tag('first');
00255         try {
00256             $xw->stop();
00257             $this->assertTrue(false, 'xml_writer_exception expected');
00258         } catch (exception $e) {
00259             $this->assertTrue($e instanceof xml_writer_exception);
00260             $this->assertEqual($e->errorcode, 'xml_writer_open_tags_remaining');
00261         }
00262 
00263         // Test simple transformer
00264         $xo = new memory_xml_output();
00265         $xt = new mock_xml_contenttransformer();
00266         $xw = new mock_xml_writer($xo, $xt);
00267         $xw->set_prologue(''); // empty prologue for easier matching
00268         $xw->start();
00269         $xw->full_tag('tagname', null, array('attrname' => 'attrvalue'));
00270         $xw->full_tag('tagname2', 'somecontent', array('attrname' => 'attrvalue'));
00271         $xw->stop();
00272         $result = $xo->get_allcontents();
00273         $this->assertEqual($result, '<tagname attrname="attrvalue" /><tagname2 attrname="attrvalue">testsomecontent</tagname2>');
00274 
00275         // Build a complex XML file and test results against stored file in fixtures
00276         $xo = new memory_xml_output();
00277         $xw = new mock_xml_writer($xo);
00278         $xw->start();
00279         $xw->begin_tag('toptag', array('name' => 'toptag', 'level' => 1, 'path' => '/toptag'));
00280         $xw->full_tag('secondtag', 'secondvalue', array('name' => 'secondtag', 'level' => 2, 'path' => '/toptag/secondtag', 'value' => 'secondvalue'));
00281         $xw->begin_tag('thirdtag', array('name' => 'thirdtag', 'level' => 2, 'path' => '/toptag/thirdtag'));
00282         $xw->full_tag('onevalue', 'onevalue', array('name' => 'onevalue', 'level' => 3, 'path' => '/toptag/thirdtag/onevalue'));
00283         $xw->full_tag('onevalue', 'anothervalue', array('name' => 'onevalue', 'level' => 3, 'value' => 'anothervalue'));
00284         $xw->full_tag('onevalue', 'yetanothervalue', array('name' => 'onevalue', 'level' => 3, 'value' => 'yetanothervalue'));
00285         $xw->full_tag('twovalue', 'twovalue', array('name' => 'twovalue', 'level' => 3, 'path' => '/toptag/thirdtag/twovalue'));
00286         $xw->begin_tag('forthtag', array('name' => 'forthtag', 'level' => 3, 'path' => '/toptag/thirdtag/forthtag'));
00287         $xw->full_tag('innervalue', 'innervalue');
00288         $xw->begin_tag('innertag');
00289         $xw->begin_tag('superinnertag', array('name' => 'superinnertag', 'level' => 5));
00290         $xw->full_tag('superinnervalue', 'superinnervalue', array('name' => 'superinnervalue', 'level' => 6));
00291         $xw->end_tag('superinnertag');
00292         $xw->end_tag('innertag');
00293         $xw->end_tag('forthtag');
00294         $xw->begin_tag('fifthtag', array('level' => 3));
00295         $xw->begin_tag('sixthtag', array('level' => 4));
00296         $xw->full_tag('seventh', 'seventh', array('level' => 5));
00297         $xw->end_tag('sixthtag');
00298         $xw->end_tag('fifthtag');
00299         $xw->full_tag('finalvalue', 'finalvalue', array('name' => 'finalvalue', 'level' => 3, 'path' => '/toptag/thirdtag/finalvalue'));
00300         $xw->full_tag('finalvalue');
00301         $xw->end_tag('thirdtag');
00302         $xw->end_tag('toptag');
00303         $xw->stop();
00304         $result = $xo->get_allcontents();
00305         $fcontents = file_get_contents($CFG->dirroot . '/backup/util/xml/simpletest/fixtures/test1.xml');
00306 
00307         // Normalise carriage return characters.
00308         $fcontents = str_replace("\r\n", "\n", $fcontents);
00309         $this->assertEqual(trim($result), trim($fcontents));
00310     }
00311 }
00312 
00313 /*
00314  * helper extended xml_writer class that makes some methods public for testing
00315  */
00316 class mock_xml_writer extends xml_writer {
00317     public function get_default_prologue() {
00318         return parent::get_default_prologue();
00319     }
00320 }
00321 
00322 /*
00323  * helper extended xml_contenttransformer prepending "test" to all the notnull contents
00324  */
00325 class mock_xml_contenttransformer extends xml_contenttransformer {
00326     public function process($content) {
00327         return is_null($content) ? null : 'test' . $content;
00328     }
00329 }
 All Data Structures Namespaces Files Functions Variables Enumerations