Moodle  2.2.1
http://www.collinsharper.com
C:/xampp/htdocs/moodle/backup/util/xml/parser/simpletest/testparser.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/parser/progressive_parser.class.php');
00032 require_once($CFG->dirroot . '/backup/util/xml/parser/processors/progressive_parser_processor.class.php');
00033 require_once($CFG->dirroot . '/backup/util/xml/parser/processors/simplified_parser_processor.class.php');
00034 require_once($CFG->dirroot . '/backup/util/xml/parser/processors/grouped_parser_processor.class.php');
00035 
00036 /*
00037  * progressive_parser and progressive_parser_processor tests
00038  */
00039 class progressive_parser_test extends UnitTestCase {
00040 
00041     public static $includecoverage = array('backup/util/xml/parser');
00042     public static $excludecoverage = array('backup/util/xml/parser/simpletest');
00043 
00044     /*
00045      * test progressive_parser public methods
00046      */
00047     function test_parser_public_api() {
00048         global $CFG;
00049         // Instantiate progressive_parser
00050         $pp = new progressive_parser();
00051         $this->assertTrue($pp instanceof progressive_parser);
00052         $pr = new mock_parser_processor();
00053         $this->assertTrue($pr instanceof progressive_parser_processor);
00054 
00055         // Try to process without processor
00056         try {
00057             $pp->process();
00058             $this->assertTrue(false);
00059         } catch (exception $e) {
00060             $this->assertTrue($e instanceof progressive_parser_exception);
00061             $this->assertEqual($e->errorcode, 'undefined_parser_processor');
00062         }
00063 
00064         // Assign processor to parser
00065         $pp->set_processor($pr);
00066 
00067         // Try to process without file and contents
00068         try {
00069             $pp->process();
00070             $this->assertTrue(false);
00071         } catch (exception $e) {
00072             $this->assertTrue($e instanceof progressive_parser_exception);
00073             $this->assertEqual($e->errorcode, 'undefined_xml_to_parse');
00074         }
00075 
00076         // Assign *invalid* processor to parser
00077         try {
00078             $pp->set_processor(new stdClass());
00079             $this->assertTrue(false);
00080         } catch (exception $e) {
00081             $this->assertTrue($e instanceof progressive_parser_exception);
00082             $this->assertEqual($e->errorcode, 'invalid_parser_processor');
00083         }
00084 
00085         // Set file from fixtures (test1.xml) and process it
00086         $pp = new progressive_parser();
00087         $pr = new mock_parser_processor();
00088         $pp->set_processor($pr);
00089         $pp->set_file($CFG->dirroot . '/backup/util/xml/parser/simpletest/fixtures/test1.xml');
00090         $pp->process();
00091         $serfromfile = serialize($pr->get_chunks()); // Get serialized results (to compare later)
00092         // Set *unexisting* file from fixtures
00093         try {
00094             $pp->set_file($CFG->dirroot . '/backup/util/xml/parser/simpletest/fixtures/test0.xml');
00095             $this->assertTrue(false);
00096         } catch (exception $e) {
00097             $this->assertTrue($e instanceof progressive_parser_exception);
00098             $this->assertEqual($e->errorcode, 'invalid_file_to_parse');
00099         }
00100 
00101         // Set contents from fixtures (test1.xml) and process it
00102         $pp = new progressive_parser();
00103         $pr = new mock_parser_processor();
00104         $pp->set_processor($pr);
00105         $pp->set_contents(file_get_contents($CFG->dirroot . '/backup/util/xml/parser/simpletest/fixtures/test1.xml'));
00106         $pp->process();
00107         $serfrommemory = serialize($pr->get_chunks()); // Get serialized results (to compare later)
00108         // Set *empty* contents
00109         try {
00110             $pp->set_contents('');
00111             $this->assertTrue(false);
00112         } catch (exception $e) {
00113             $this->assertTrue($e instanceof progressive_parser_exception);
00114             $this->assertEqual($e->errorcode, 'invalid_contents_to_parse');
00115         }
00116 
00117         // Check that both results from file processing and content processing are equal
00118         $this->assertEqual($serfromfile, $serfrommemory);
00119 
00120         // Check case_folding is working ok
00121         $pp = new progressive_parser(true);
00122         $pr = new mock_parser_processor();
00123         $pp->set_processor($pr);
00124         $pp->set_file($CFG->dirroot . '/backup/util/xml/parser/simpletest/fixtures/test1.xml');
00125         $pp->process();
00126         $chunks = $pr->get_chunks();
00127         $this->assertTrue($chunks[0]['path'] === '/FIRSTTAG');
00128         $this->assertTrue($chunks[0]['tags']['SECONDTAG']['name'] === 'SECONDTAG');
00129         $this->assertTrue($chunks[0]['tags']['SECONDTAG']['attrs']['NAME'] === 'secondtag');
00130 
00131         // Check invalid XML exception is working ok
00132         $pp = new progressive_parser(true);
00133         $pr = new mock_parser_processor();
00134         $pp->set_processor($pr);
00135         $pp->set_file($CFG->dirroot . '/backup/util/xml/parser/simpletest/fixtures/test2.xml');
00136         try {
00137             $pp->process();
00138         } catch (exception $e) {
00139             $this->assertTrue($e instanceof progressive_parser_exception);
00140             $this->assertEqual($e->errorcode, 'xml_parsing_error');
00141         }
00142 
00143         // Check double process throws exception
00144         $pp = new progressive_parser(true);
00145         $pr = new mock_parser_processor();
00146         $pp->set_processor($pr);
00147         $pp->set_file($CFG->dirroot . '/backup/util/xml/parser/simpletest/fixtures/test1.xml');
00148         $pp->process();
00149         try { // Second process, will throw exception
00150             $pp->process();
00151             $this->assertTrue(false);
00152         } catch (exception $e) {
00153             $this->assertTrue($e instanceof progressive_parser_exception);
00154             $this->assertEqual($e->errorcode, 'progressive_parser_already_used');
00155         }
00156     }
00157 
00158     /*
00159      * test progressive_parser parsing results using testing_parser_processor and test1.xml
00160      * auto-described file from fixtures
00161      */
00162     function test_parser_results() {
00163         global $CFG;
00164         // Instantiate progressive_parser
00165         $pp = new progressive_parser();
00166         // Instantiate processor, passing the unit test as param
00167         $pr = new mock_auto_parser_processor($this);
00168         $this->assertTrue($pr instanceof progressive_parser_processor);
00169         // Assign processor to parser
00170         $pp->set_processor($pr);
00171         // Set file from fixtures
00172         $pp->set_file($CFG->dirroot . '/backup/util/xml/parser/simpletest/fixtures/test3.xml');
00173         // Process the file, the autotest processor will perform a bunch of automatic tests
00174         $pp->process();
00175         // Get processor debug info
00176         $debug = $pr->debug_info();
00177         $this->assertTrue(is_array($debug));
00178         $this->assertTrue(array_key_exists('chunks', $debug));
00179         // Check the number of chunks is correct for the file
00180         $this->assertEqual($debug['chunks'], 10);
00181     }
00182 
00183     /*
00184      * test progressive_parser parsing results using simplified_parser_processor and test4.xml
00185      * (one simple glossary backup file example)
00186      */
00187     function test_simplified_parser_results() {
00188         global $CFG;
00189         // Instantiate progressive_parser
00190         $pp =  new progressive_parser();
00191         // Instantiate simplified_parser_processor declaring the interesting paths
00192         $pr = new mock_simplified_parser_processor(array(
00193             '/activity',
00194             '/activity/glossary',
00195             '/activity/glossary/entries/entry',
00196             '/activity/glossary/entries/entry/aliases/alias',
00197             '/activity/glossary/entries/entry/ratings/rating',
00198             '/activity/glossary/categories/category',
00199             '/activity/glossary/onetest',
00200             '/activity/glossary/othertest'));
00201         $this->assertTrue($pr instanceof progressive_parser_processor);
00202         // Assign processor to parser
00203         $pp->set_processor($pr);
00204         // Set file from fixtures
00205         $pp->set_file($CFG->dirroot . '/backup/util/xml/parser/simpletest/fixtures/test4.xml');
00206         // Process the file
00207         $pp->process();
00208         // Get processor debug info
00209         $debug = $pr->debug_info();
00210         $this->assertTrue(is_array($debug));
00211         $this->assertTrue(array_key_exists('chunks', $debug));
00212 
00213         // Check the number of chunks is correct for the file
00214         $this->assertEqual($debug['chunks'], 12);
00215         // Get all the simplified chunks and perform various validations
00216         $chunks = $pr->get_chunks();
00217         // Check we have received the correct number of chunks
00218         $this->assertEqual(count($chunks), 12);
00219 
00220         // chunk[0] (/activity) tests
00221         $this->assertEqual(count($chunks[0]), 3);
00222         $this->assertEqual($chunks[0]['path'], '/activity');
00223         $this->assertEqual($chunks[0]['level'],'2');
00224         $tags = $chunks[0]['tags'];
00225         $this->assertEqual(count($tags), 4);
00226         $this->assertEqual($tags['id'], 1);
00227         $this->assertEqual($tags['moduleid'], 5);
00228         $this->assertEqual($tags['modulename'], 'glossary');
00229         $this->assertEqual($tags['contextid'], 26);
00230         $this->assertEqual($chunks[0]['level'],'2');
00231 
00232         // chunk[1] (/activity/glossary) tests
00233         $this->assertEqual(count($chunks[1]), 3);
00234         $this->assertEqual($chunks[1]['path'], '/activity/glossary');
00235         $this->assertEqual($chunks[1]['level'],'3');
00236         $tags = $chunks[1]['tags'];
00237         $this->assertEqual(count($tags), 24);
00238         $this->assertEqual($tags['id'], 1);
00239         $this->assertEqual($tags['intro'], '<p>One simple glossary to test backup &amp; restore. Here it\'s the standard image:</p>'.
00240                                            "\n".
00241                                            '<p><img src="@@PLUGINFILE@@/88_31.png" alt="pwd by moodle" width="88" height="31" /></p>');
00242         $this->assertEqual($tags['timemodified'], 1275639747);
00243         $this->assertTrue(!isset($tags['categories']));
00244 
00245         // chunk[5] (second /activity/glossary/entries/entry) tests
00246         $this->assertEqual(count($chunks[5]), 3);
00247         $this->assertEqual($chunks[5]['path'], '/activity/glossary/entries/entry');
00248         $this->assertEqual($chunks[5]['level'],'5');
00249         $tags = $chunks[5]['tags'];
00250         $this->assertEqual(count($tags), 15);
00251         $this->assertEqual($tags['id'], 2);
00252         $this->assertEqual($tags['concept'], 'cat');
00253         $this->assertTrue(!isset($tags['aliases']));
00254         $this->assertTrue(!isset($tags['entries']));
00255 
00256         // chunk[6] (second /activity/glossary/entries/entry/aliases/alias) tests
00257         $this->assertEqual(count($chunks[6]), 3);
00258         $this->assertEqual($chunks[6]['path'], '/activity/glossary/entries/entry/aliases/alias');
00259         $this->assertEqual($chunks[6]['level'],'7');
00260         $tags = $chunks[6]['tags'];
00261         $this->assertEqual(count($tags), 2);
00262         $this->assertEqual($tags['id'], 2);
00263         $this->assertEqual($tags['alias_text'], 'cats');
00264 
00265         // chunk[7] (second /activity/glossary/entries/entry/aliases/alias) tests
00266         $this->assertEqual(count($chunks[7]), 3);
00267         $this->assertEqual($chunks[7]['path'], '/activity/glossary/entries/entry/aliases/alias');
00268         $this->assertEqual($chunks[7]['level'],'7');
00269         $tags = $chunks[7]['tags'];
00270         $this->assertEqual(count($tags), 2);
00271         $this->assertEqual($tags['id'], 3);
00272         $this->assertEqual($tags['alias_text'], 'felines');
00273 
00274         // chunk[8] (second /activity/glossary/entries/entry/ratings/rating) tests
00275         $this->assertEqual(count($chunks[8]), 3);
00276         $this->assertEqual($chunks[8]['path'], '/activity/glossary/entries/entry/ratings/rating');
00277         $this->assertEqual($chunks[8]['level'],'7');
00278         $tags = $chunks[8]['tags'];
00279         $this->assertEqual(count($tags), 6);
00280         $this->assertEqual($tags['id'], 1);
00281         $this->assertEqual($tags['timemodified'], '1275639779');
00282 
00283         // chunk[9] (first /activity/glossary/onetest) tests
00284         $this->assertEqual(count($chunks[9]), 3);
00285         $this->assertEqual($chunks[9]['path'], '/activity/glossary/onetest');
00286         $this->assertEqual($chunks[9]['level'],'4');
00287         $tags = $chunks[9]['tags'];
00288         $this->assertEqual(count($tags), 2);
00289         $this->assertEqual($tags['name'], 1);
00290         $this->assertEqual($tags['value'], 1);
00291 
00292         // chunk[10] (second /activity/glossary/onetest) tests
00293         $this->assertEqual(count($chunks[10]), 3);
00294         $this->assertEqual($chunks[10]['path'], '/activity/glossary/onetest');
00295         $this->assertEqual($chunks[10]['level'],'4');
00296         $tags = $chunks[10]['tags'];
00297         $this->assertEqual(count($tags), 2);
00298         $this->assertEqual($tags['name'], 2);
00299         $this->assertEqual($tags['value'], 2);
00300 
00301         // chunk[11] (first /activity/glossary/othertest) tests
00302         // note we don't allow repeated "final" element, so we only return the last one
00303         $this->assertEqual(count($chunks[11]), 3);
00304         $this->assertEqual($chunks[11]['path'], '/activity/glossary/othertest');
00305         $this->assertEqual($chunks[11]['level'],'4');
00306         $tags = $chunks[11]['tags'];
00307         $this->assertEqual(count($tags), 2);
00308         $this->assertEqual($tags['name'], 4);
00309         $this->assertEqual($tags['value'], 5);
00310 
00311         // Now check start notifications
00312         $snotifs = $pr->get_start_notifications();
00313         // Check we have received the correct number of notifications
00314         $this->assertEqual(count($snotifs), 12);
00315         // Check first, sixth and last notifications
00316         $this->assertEqual($snotifs[0], '/activity');
00317         $this->assertEqual($snotifs[5], '/activity/glossary/entries/entry');
00318         $this->assertEqual($snotifs[11], '/activity/glossary/othertest');
00319 
00320         // Now check end notifications
00321         $enotifs = $pr->get_end_notifications();
00322         // Check we have received the correct number of notifications
00323         $this->assertEqual(count($snotifs), 12);
00324         // Check first, sixth and last notifications
00325         $this->assertEqual($enotifs[0], '/activity/glossary/entries/entry/aliases/alias');
00326         $this->assertEqual($enotifs[5], '/activity/glossary/entries/entry/ratings/rating');
00327         $this->assertEqual($enotifs[11], '/activity');
00328 
00329         // Check start and end notifications are balanced
00330         sort($snotifs);
00331         sort($enotifs);
00332         $this->assertEqual($snotifs, $enotifs);
00333 
00334         // Now verify that the start/process/end order is correct
00335         $allnotifs = $pr->get_all_notifications();
00336         $this->assertEqual(count($allnotifs), count($snotifs) + count($enotifs) + count($chunks)); // The count
00337         // Check integrity of the notifications
00338         $errcount = $this->helper_check_notifications_order_integrity($allnotifs);
00339         $this->assertEqual($errcount, 0); // No errors found, plz
00340     }
00341 
00347     function test_simplified_david_backup19_file_fragment() {
00348         global $CFG;
00349         // Instantiate progressive_parser
00350         $pp =  new progressive_parser();
00351         // Instantiate grouped_parser_processor
00352         $pr = new mock_simplified_parser_processor();
00353         // Add interesting paths
00354         $pr->add_path('/MOODLE_BACKUP/COURSE');
00355         $pr->add_path('/MOODLE_BACKUP/COURSE/SECTIONS/SECTION');
00356         $pr->add_path('/MOODLE_BACKUP/COURSE/SECTIONS/SECTION/MODS/MOD');
00357         $pr->add_path('/MOODLE_BACKUP/COURSE/SECTIONS/SECTION/MODS/MOD/ROLES_OVERRIDES');
00358         $this->assertTrue($pr instanceof progressive_parser_processor);
00359         // Assign processor to parser
00360         $pp->set_processor($pr);
00361         // Set file from fixtures
00362         $pp->set_file($CFG->dirroot . '/backup/util/xml/parser/simpletest/fixtures/test5.xml');
00363         // Process the file
00364         $pp->process();
00365 
00366         // Get all the simplified chunks and perform various validations
00367         $chunks = $pr->get_chunks();
00368         $this->assertEqual(count($chunks), 3); // Only 3, because 7 (COURSE, ROLES_OVERRIDES and 5 MOD) are empty, aka no chunk
00369 
00370         // Now check start notifications
00371         $snotifs = $pr->get_start_notifications();
00372         // Check we have received the correct number of notifications
00373         $this->assertEqual(count($snotifs), 10); // Start tags are dispatched for empties (ROLES_OVERRIDES)
00374         // Check first and last notifications
00375         $this->assertEqual($snotifs[0], '/MOODLE_BACKUP/COURSE');
00376         $this->assertEqual($snotifs[1], '/MOODLE_BACKUP/COURSE/SECTIONS/SECTION');
00377         $this->assertEqual($snotifs[2], '/MOODLE_BACKUP/COURSE/SECTIONS/SECTION/MODS/MOD');
00378         $this->assertEqual($snotifs[3], '/MOODLE_BACKUP/COURSE/SECTIONS/SECTION/MODS/MOD/ROLES_OVERRIDES');
00379         $this->assertEqual($snotifs[7], '/MOODLE_BACKUP/COURSE/SECTIONS/SECTION/MODS/MOD');
00380         $this->assertEqual($snotifs[8], '/MOODLE_BACKUP/COURSE/SECTIONS/SECTION/MODS/MOD');
00381         $this->assertEqual($snotifs[9], '/MOODLE_BACKUP/COURSE/SECTIONS/SECTION/MODS/MOD');
00382 
00383         // Now check end notifications
00384         $enotifs = $pr->get_end_notifications();
00385         // Check we have received the correct number of notifications
00386         $this->assertEqual(count($snotifs), 10); // End tags are dispatched for empties (ROLES_OVERRIDES)
00387         // Check first, and last notifications
00388         $this->assertEqual($enotifs[0], '/MOODLE_BACKUP/COURSE/SECTIONS/SECTION/MODS/MOD/ROLES_OVERRIDES');
00389         $this->assertEqual($enotifs[1], '/MOODLE_BACKUP/COURSE/SECTIONS/SECTION/MODS/MOD');
00390         $this->assertEqual($enotifs[2], '/MOODLE_BACKUP/COURSE/SECTIONS/SECTION/MODS/MOD');
00391         $this->assertEqual($enotifs[3], '/MOODLE_BACKUP/COURSE/SECTIONS/SECTION/MODS/MOD');
00392         $this->assertEqual($enotifs[7], '/MOODLE_BACKUP/COURSE/SECTIONS/SECTION/MODS/MOD');
00393         $this->assertEqual($enotifs[8], '/MOODLE_BACKUP/COURSE/SECTIONS/SECTION');
00394         $this->assertEqual($enotifs[9], '/MOODLE_BACKUP/COURSE');
00395 
00396         // Check start and end notifications are balanced
00397         sort($snotifs);
00398         sort($enotifs);
00399         $this->assertEqual($snotifs, $enotifs);
00400 
00401         // Now verify that the start/process/end order is correct
00402         $allnotifs = $pr->get_all_notifications();
00403         $this->assertEqual(count($allnotifs), count($snotifs) + count($enotifs) + count($chunks)); // The count
00404         // Check integrity of the notifications
00405         $errcount = $this->helper_check_notifications_order_integrity($allnotifs);
00406         $this->assertEqual($errcount, 0); // No errors found, plz
00407     }
00408 
00409     /*
00410      * test progressive_parser parsing results using grouped_parser_processor and test4.xml
00411      * (one simple glossary backup file example)
00412      */
00413     function test_grouped_parser_results() {
00414         global $CFG;
00415         // Instantiate progressive_parser
00416         $pp =  new progressive_parser();
00417         // Instantiate grouped_parser_processor
00418         $pr = new mock_grouped_parser_processor();
00419         // Add interesting paths
00420         $pr->add_path('/activity');
00421         $pr->add_path('/activity/glossary', true);
00422         $pr->add_path('/activity/glossary/entries/entry');
00423         $pr->add_path('/activity/glossary/entries/entry/aliases/alias');
00424         $pr->add_path('/activity/glossary/entries/entry/ratings/rating');
00425         $pr->add_path('/activity/glossary/categories/category');
00426         $pr->add_path('/activity/glossary/onetest');
00427         $pr->add_path('/activity/glossary/othertest');
00428         $this->assertTrue($pr instanceof progressive_parser_processor);
00429         // Assign processor to parser
00430         $pp->set_processor($pr);
00431         // Set file from fixtures
00432         $pp->set_file($CFG->dirroot . '/backup/util/xml/parser/simpletest/fixtures/test4.xml');
00433         // Process the file
00434         $pp->process();
00435         // Get processor debug info
00436         $debug = $pr->debug_info();
00437         $this->assertTrue(is_array($debug));
00438         $this->assertTrue(array_key_exists('chunks', $debug));
00439 
00440         // Check the number of chunks is correct for the file
00441         $this->assertEqual($debug['chunks'], 2);
00442         // Get all the simplified chunks and perform various validations
00443         $chunks = $pr->get_chunks();
00444         // Check we have received the correct number of chunks
00445         $this->assertEqual(count($chunks), 2);
00446 
00447         // chunk[0] (/activity) tests
00448         $this->assertEqual(count($chunks[0]), 3);
00449         $this->assertEqual($chunks[0]['path'], '/activity');
00450         $this->assertEqual($chunks[0]['level'],'2');
00451         $tags = $chunks[0]['tags'];
00452         $this->assertEqual(count($tags), 4);
00453         $this->assertEqual($tags['id'], 1);
00454         $this->assertEqual($tags['moduleid'], 5);
00455         $this->assertEqual($tags['modulename'], 'glossary');
00456         $this->assertEqual($tags['contextid'], 26);
00457         $this->assertEqual($chunks[0]['level'],'2');
00458 
00459         // chunk[1] (grouped /activity/glossary tests)
00460         $this->assertEqual(count($chunks[1]), 3);
00461         $this->assertEqual($chunks[1]['path'], '/activity/glossary');
00462         $this->assertEqual($chunks[1]['level'],'3');
00463         $tags = $chunks[1]['tags'];
00464         $this->assertEqual(count($tags), 27);
00465         $this->assertEqual($tags['id'], 1);
00466         $this->assertEqual($tags['intro'], '<p>One simple glossary to test backup &amp; restore. Here it\'s the standard image:</p>'.
00467                                            "\n".
00468                                            '<p><img src="@@PLUGINFILE@@/88_31.png" alt="pwd by moodle" width="88" height="31" /></p>');
00469         $this->assertEqual($tags['timemodified'], 1275639747);
00470         $this->assertTrue(!isset($tags['categories']));
00471         $this->assertTrue(isset($tags['entries']));
00472         $this->assertTrue(isset($tags['onetest']));
00473         $this->assertTrue(isset($tags['othertest']));
00474 
00475         // Various tests under the entries
00476         $entries = $chunks[1]['tags']['entries']['entry'];
00477         $this->assertEqual(count($entries), 2);
00478 
00479         // First entry
00480         $entry1 = $entries[0];
00481         $this->assertEqual(count($entry1), 17);
00482         $this->assertEqual($entry1['id'], 1);
00483         $this->assertEqual($entry1['userid'], 2);
00484         $this->assertEqual($entry1['concept'], 'dog');
00485         $this->assertEqual($entry1['definition'], '<p>Traditional enemies of cats</p>');
00486         $this->assertTrue(isset($entry1['aliases']));
00487         $this->assertTrue(isset($entry1['ratings']));
00488         // aliases of first entry
00489         $aliases = $entry1['aliases']['alias'];
00490         $this->assertEqual(count($aliases), 1);
00491         // first alias
00492         $alias1 = $aliases[0];
00493         $this->assertEqual(count($alias1), 2);
00494         $this->assertEqual($alias1['id'], 1);
00495         $this->assertEqual($alias1['alias_text'], 'dogs');
00496         // ratings of first entry
00497         $ratings = $entry1['ratings']['rating'];
00498         $this->assertEqual(count($ratings), 1);
00499         // first rating
00500         $rating1 = $ratings[0];
00501         $this->assertEqual(count($rating1), 6);
00502         $this->assertEqual($rating1['id'], 2);
00503         $this->assertEqual($rating1['value'], 6);
00504         $this->assertEqual($rating1['timemodified'], '1275639797');
00505 
00506         // Second entry
00507         $entry2 = $entries[1];
00508         $this->assertEqual(count($entry2), 17);
00509         $this->assertEqual($entry2['id'], 2);
00510         $this->assertEqual($entry2['userid'], 2);
00511         $this->assertEqual($entry2['concept'], 'cat');
00512         $this->assertEqual($entry2['definition'], '<p>traditional enemies of dogs</p>');
00513         $this->assertTrue(isset($entry2['aliases']));
00514         $this->assertTrue(isset($entry2['ratings']));
00515         // aliases of first entry
00516         $aliases = $entry2['aliases']['alias'];
00517         $this->assertEqual(count($aliases), 2);
00518         // first alias
00519         $alias1 = $aliases[0];
00520         $this->assertEqual(count($alias1), 2);
00521         $this->assertEqual($alias1['id'], 2);
00522         $this->assertEqual($alias1['alias_text'], 'cats');
00523         // second alias
00524         $alias2 = $aliases[1];
00525         $this->assertEqual(count($alias2), 2);
00526         $this->assertEqual($alias2['id'], 3);
00527         $this->assertEqual($alias2['alias_text'], 'felines');
00528         // ratings of first entry
00529         $ratings = $entry2['ratings']['rating'];
00530         $this->assertEqual(count($ratings), 1);
00531         // first rating
00532         $rating1 = $ratings[0];
00533         $this->assertEqual(count($rating1), 6);
00534         $this->assertEqual($rating1['id'], 1);
00535         $this->assertEqual($rating1['value'], 5);
00536         $this->assertEqual($rating1['scaleid'], 10);
00537 
00538         // Onetest test (only 1 level nested)
00539         $onetest = $tags['onetest'];
00540         $this->assertEqual(count($onetest), 2);
00541         $this->assertEqual(count($onetest[0]), 2);
00542         $this->assertEqual($onetest[0]['name'], 1);
00543         $this->assertEqual($onetest[0]['value'], 1);
00544         $this->assertEqual(count($onetest[1]), 2);
00545         $this->assertEqual($onetest[1]['name'], 2);
00546         $this->assertEqual($onetest[1]['value'], 2);
00547 
00548         // Other test (0 level nested, only last one is retrieved)
00549         $othertest = $tags['othertest'];
00550         $this->assertEqual(count($othertest), 1);
00551         $this->assertEqual(count($othertest[0]), 2);
00552         $this->assertEqual($othertest[0]['name'], 4);
00553         $this->assertEqual($othertest[0]['value'], 5);
00554 
00555         // Now check start notifications
00556         $snotifs = $pr->get_start_notifications();
00557         // Check we have received the correct number of notifications
00558         $this->assertEqual(count($snotifs), 2);
00559         // Check first and last notifications
00560         $this->assertEqual($snotifs[0], '/activity');
00561         $this->assertEqual($snotifs[1], '/activity/glossary');
00562 
00563         // Now check end notifications
00564         $enotifs = $pr->get_end_notifications();
00565         // Check we have received the correct number of notifications
00566         $this->assertEqual(count($snotifs), 2);
00567         // Check first, and last notifications
00568         $this->assertEqual($enotifs[0], '/activity/glossary');
00569         $this->assertEqual($enotifs[1], '/activity');
00570 
00571         // Check start and end notifications are balanced
00572         sort($snotifs);
00573         sort($enotifs);
00574         $this->assertEqual($snotifs, $enotifs);
00575 
00576         // Now verify that the start/process/end order is correct
00577         $allnotifs = $pr->get_all_notifications();
00578         $this->assertEqual(count($allnotifs), count($snotifs) + count($enotifs) + count($chunks)); // The count
00579         // Check integrity of the notifications
00580         $errcount = $this->helper_check_notifications_order_integrity($allnotifs);
00581         $this->assertEqual($errcount, 0); // No errors found, plz
00582     }
00583 
00589     function test_grouped_david_backup19_file_fragment() {
00590         global $CFG;
00591         // Instantiate progressive_parser
00592         $pp =  new progressive_parser();
00593         // Instantiate grouped_parser_processor
00594         $pr = new mock_grouped_parser_processor();
00595         // Add interesting paths
00596         $pr->add_path('/MOODLE_BACKUP/COURSE');
00597         $pr->add_path('/MOODLE_BACKUP/COURSE/SECTIONS/SECTION', true);
00598         $pr->add_path('/MOODLE_BACKUP/COURSE/SECTIONS/SECTION/MODS/MOD');
00599         $pr->add_path('/MOODLE_BACKUP/COURSE/SECTIONS/SECTION/MODS/MOD/ROLES_OVERRIDES');
00600         $this->assertTrue($pr instanceof progressive_parser_processor);
00601         // Assign processor to parser
00602         $pp->set_processor($pr);
00603         // Set file from fixtures
00604         $pp->set_file($CFG->dirroot . '/backup/util/xml/parser/simpletest/fixtures/test5.xml');
00605         // Process the file
00606         $pp->process();
00607 
00608         // Get all the simplified chunks and perform various validations
00609         $chunks = $pr->get_chunks();
00610         $this->assertEqual(count($chunks), 1); // Only 1, the SECTION one
00611 
00612         // Now check start notifications
00613         $snotifs = $pr->get_start_notifications();
00614         // Check we have received the correct number of notifications
00615         $this->assertEqual(count($snotifs), 2);
00616         // Check first and last notifications
00617         $this->assertEqual($snotifs[0], '/MOODLE_BACKUP/COURSE');
00618         $this->assertEqual($snotifs[1], '/MOODLE_BACKUP/COURSE/SECTIONS/SECTION');
00619 
00620         // Now check end notifications
00621         $enotifs = $pr->get_end_notifications();
00622         // Check we have received the correct number of notifications
00623         $this->assertEqual(count($snotifs), 2); // End tags are dispatched for empties (ROLES_OVERRIDES)
00624         // Check first, and last notifications
00625         $this->assertEqual($enotifs[0], '/MOODLE_BACKUP/COURSE/SECTIONS/SECTION');
00626         $this->assertEqual($enotifs[1], '/MOODLE_BACKUP/COURSE');
00627 
00628         // Check start and end notifications are balanced
00629         sort($snotifs);
00630         sort($enotifs);
00631         $this->assertEqual($snotifs, $enotifs);
00632 
00633         // Now verify that the start/process/end order is correct
00634         $allnotifs = $pr->get_all_notifications();
00635         $this->assertEqual(count($allnotifs), count($snotifs) + count($enotifs) + count($chunks)); // The count
00636         // Check integrity of the notifications
00637         $errcount = $this->helper_check_notifications_order_integrity($allnotifs);
00638         $this->assertEqual($errcount, 0); // No errors found, plz
00639     }
00640 
00641 
00652     function helper_check_notifications_order_integrity($notifications) {
00653         $numerrors = 0;
00654         $notifpile = array('pilebase' => 'start');
00655         $lastnotif = 'start:pilebase';
00656         foreach ($notifications as $notif) {
00657 
00658             $lastpiletype = end($notifpile);
00659             $lastpilepath = key($notifpile);
00660             $lastpilelevel = strlen(preg_replace('/[^\/]/', '', $lastpilepath));
00661 
00662             $lastnotiftype  = preg_replace('/:.*/', '', $lastnotif);
00663             $lastnotifpath  = preg_replace('/.*:/', '', $lastnotif);
00664             $lastnotiflevel = strlen(preg_replace('/[^\/]/', '', $lastnotifpath));
00665 
00666             $notiftype  = preg_replace('/:.*/', '', $notif);
00667             $notifpath  = preg_replace('/.*:/', '', $notif);
00668             $notiflevel = strlen(preg_replace('/[^\/]/', '', $notifpath));
00669 
00670             switch ($notiftype) {
00671                 case 'process':
00672                     if ($lastnotifpath != $notifpath or $lastnotiftype != 'start') {
00673                         $numerrors++; // Only start for same path from last notification is allowed before process
00674                     }
00675                     $notifpile[$notifpath] = 'process'; // Update the status in the pile
00676                     break;
00677                 case 'end':
00678                     if ($lastpilepath != $notifpath or ($lastpiletype != 'process' and $lastpiletype != 'start')) {
00679                         $numerrors++; // Only process and start for same path from last pile is allowed before end
00680                     }
00681                     unset($notifpile[$notifpath]); // Delete from the pile
00682                     break;
00683                 case 'start':
00684                     if (array_key_exists($notifpath, $notifpile) or $notiflevel <= $lastpilelevel) {
00685                         $numerrors++; // Only non existing in pile and with level > last pile is allowed on start
00686                     }
00687                     $notifpile[$notifpath] = 'start'; // Add to the pile
00688                     break;
00689                 default:
00690                     $numerrors++; // Incorrect type of notification => error
00691             }
00692             // Update lastnotif
00693             $lastnotif = $notif;
00694         }
00695         return $numerrors;
00696     }
00697 }
00698 
00699 /*
00700  * helper processor able to perform various auto-cheks based on attributes while processing
00701  * the test1.xml file available in the fixtures dir. It performs these checks:
00702  *    - name equal to "name" attribute of the tag (if present)
00703  *    - level equal to "level" attribute of the tag (if present)
00704  *    - path + tagname equal to "path" attribute of the tag (if present)
00705  *    - cdata, if not empty is:
00706  *        - equal to "value" attribute of the tag (if present)
00707  *        - else, equal to tag name
00708  *
00709  * We pass the whole UnitTestCase object to the processor in order to be
00710  * able to perform the tests in the straight in the process
00711  */
00712 class mock_auto_parser_processor extends progressive_parser_processor {
00713 
00714     private $utc = null; // To store the unit test case
00715 
00716     public function __construct($unit_test_case) {
00717         parent::__construct();
00718         $this->utc = $unit_test_case;
00719     }
00720 
00721     public function process_chunk($data) {
00722         // Perform auto-checks based in the rules above
00723         if (isset($data['tags'])) {
00724             foreach ($data['tags'] as $tag) {
00725                 if (isset($tag['attrs']['name'])) { // name tests
00726                     $this->utc->assertEqual($tag['name'], $tag['attrs']['name']);
00727                 }
00728                 if (isset($tag['attrs']['level'])) { // level tests
00729                     $this->utc->assertEqual($data['level'], $tag['attrs']['level']);
00730                 }
00731                 if (isset($tag['attrs']['path'])) { // path tests
00732                     $this->utc->assertEqual(rtrim($data['path'], '/') . '/' . $tag['name'], $tag['attrs']['path']);
00733                 }
00734                 if (!empty($tag['cdata'])) { // cdata tests
00735                     if (isset($tag['attrs']['value'])) {
00736                         $this->utc->assertEqual($tag['cdata'], $tag['attrs']['value']);
00737                     } else {
00738                         $this->utc->assertEqual($tag['cdata'], $tag['name']);
00739                     }
00740                 }
00741             }
00742         }
00743     }
00744 }
00745 
00746 /*
00747  * helper processor that accumulates all the chunks, resturning them with the get_chunks() method
00748  */
00749 class mock_parser_processor extends progressive_parser_processor {
00750 
00751     private $chunksarr = array(); // To accumulate the found chunks
00752 
00753     public function process_chunk($data) {
00754         $this->chunksarr[] = $data;
00755     }
00756 
00757     public function get_chunks() {
00758         return $this->chunksarr;
00759     }
00760 }
00761 
00762 /*
00763  * helper processor that accumulates simplified chunks, returning them with the get_chunks() method
00764  */
00765 class mock_simplified_parser_processor extends simplified_parser_processor {
00766 
00767     private $chunksarr = array(); // To accumulate the found chunks
00768     private $startarr  = array(); // To accumulate all the notified path starts
00769     private $endarr    = array(); // To accumulate all the notified path ends
00770     private $allnotif  = array(); // To accumulate all the notified and dispatched events in an ordered way
00771 
00772     public function dispatch_chunk($data) {
00773         $this->chunksarr[] = $data;
00774         $this->allnotif[] = 'process:' . $data['path'];
00775     }
00776 
00777     public function notify_path_start($path) {
00778         $this->startarr[] = $path;
00779         $this->allnotif[] = 'start:' . $path;
00780     }
00781 
00782     public function notify_path_end($path) {
00783         $this->endarr[] = $path;
00784         $this->allnotif[] = 'end:' . $path;
00785     }
00786 
00787     public function get_chunks() {
00788         return $this->chunksarr;
00789     }
00790 
00791     public function get_start_notifications() {
00792         return $this->startarr;
00793     }
00794 
00795     public function get_end_notifications() {
00796         return $this->endarr;
00797     }
00798 
00799     public function get_all_notifications() {
00800         return $this->allnotif;
00801     }
00802 }
00803 
00804 /*
00805  * helper processor that accumulates grouped chunks, returning them with the get_chunks() method
00806  */
00807 class mock_grouped_parser_processor extends grouped_parser_processor {
00808 
00809     private $chunksarr = array(); // To accumulate the found chunks
00810     private $startarr  = array(); // To accumulate all the notified path starts
00811     private $endarr    = array(); // To accumulate all the notified path ends
00812     private $allnotif  = array(); // To accumulate all the notified and dispatched events in an ordered way
00813 
00814     public function dispatch_chunk($data) {
00815         $this->chunksarr[] = $data;
00816         $this->allnotif[] = 'process:' . $data['path'];
00817     }
00818 
00819     public function notify_path_start($path) {
00820         $this->startarr[] = $path;
00821         $this->allnotif[] = 'start:' . $path;
00822     }
00823 
00824     public function notify_path_end($path) {
00825         $this->endarr[] = $path;
00826         $this->allnotif[] = 'end:' . $path;
00827     }
00828 
00829     public function get_chunks() {
00830         return $this->chunksarr;
00831     }
00832 
00833     public function get_start_notifications() {
00834         return $this->startarr;
00835     }
00836 
00837     public function get_end_notifications() {
00838         return $this->endarr;
00839     }
00840 
00841     public function get_all_notifications() {
00842         return $this->allnotif;
00843     }
00844 }
 All Data Structures Namespaces Files Functions Variables Enumerations