From 3441421e8b8b3a0154c1b4f6446cdedd0deb98ba Mon Sep 17 00:00:00 2001 From: "Edward Z. Yang" Date: Sat, 16 Feb 2008 00:40:30 +0000 Subject: [PATCH] [3.1.0] Land PHPT integration (currently required; we'll relax this later) - Port ConfigSchema and Config tests to new syntax - Deprecate Debugger - Add $schema params to most Config convenience functions - Add --php flag to testing scripts for command line - NOT TESTED WITH MULTITEST.PHP! git-svn-id: http://htmlpurifier.org/svnroot/htmlpurifier/trunk@1551 48356398-32a2-884e-a903-53898d9a118a --- NEWS | 9 + library/HTMLPurifier/Config.php | 28 ++-- tests/HTMLPurifier/ConfigSchemaTest.php | 4 - tests/HTMLPurifier/ConfigTest.php | 186 ++++++++++----------- tests/HTMLPurifier/GeneratorTest.php | 2 - tests/HTMLPurifier/Lexer/DirectLexTest.php | 1 - tests/HTMLPurifier/PHPT/Smoketest.phpt | 6 + tests/PHPT/Controller/SimpleTest.php | 28 ++++ tests/PHPT/Reporter/SimpleTest.php | 72 ++++++++ tests/common.php | 33 +++- tests/index.php | 26 ++- tests/multitest.php | 13 +- tests/test_files.php | 4 + 13 files changed, 275 insertions(+), 137 deletions(-) create mode 100644 tests/HTMLPurifier/PHPT/Smoketest.phpt create mode 100644 tests/PHPT/Controller/SimpleTest.php create mode 100644 tests/PHPT/Reporter/SimpleTest.php diff --git a/NEWS b/NEWS index f2a49abe..4039d3d5 100644 --- a/NEWS +++ b/NEWS @@ -25,8 +25,12 @@ NEWS ( CHANGELOG and HISTORY ) HTMLPurifier be found in extras/. Specifically, these are FSTools and ConfigSchema. You may find a use for these in your own project, but right now they are highly experimental and volatile. +! Integration with PHPT allows for automated smoketests - Autoclose now operates iteratively, i.e.
now has both span tags closed. +- Various HTMLPurifier_Config convenience functions now accept another parameter + $schema which defines what HTMLPurifier_ConfigSchema to use besides the + global default. . Plugins now get their own changelogs according to project conventions. . Convert tokens to use instanceof, reducing memory footprint and improving comparison speed. @@ -41,6 +45,11 @@ NEWS ( CHANGELOG and HISTORY ) HTMLPurifier . HTMLPurifier_Token subclasses split into seperate files . HTMLPURIFIER_PREFIX now is defined in Bootstrap.php, NOT HTMLPurifier.php . HTMLPURIFIER_PREFIX can now be defined outside of HTML Purifier +. New --php=php flag added, allows PHP executable to be specified (command + line only!) +. htmlpurifier_add_test() preferred method to translate test files in to + classes, because it handles PHPT files too. +. Debugger class is deprecated and will be removed soon. 3.0.0, released 2008-01-06 # HTML Purifier is PHP 5 only! The 2.1.x branch will be maintained diff --git a/library/HTMLPurifier/Config.php b/library/HTMLPurifier/Config.php index 0f89de63..1ea7e84c 100644 --- a/library/HTMLPurifier/Config.php +++ b/library/HTMLPurifier/Config.php @@ -78,14 +78,19 @@ class HTMLPurifier_Config * object. Can be: a HTMLPurifier_Config() object, * an array of directives based on loadArray(), * or a string filename of an ini file. + * @param HTMLPurifier_ConfigSchema Schema object * @return Configured HTMLPurifier_Config object */ - public static function create($config) { + public static function create($config, $schema = null) { if ($config instanceof HTMLPurifier_Config) { // pass-through return $config; } - $ret = HTMLPurifier_Config::createDefault(); + if (!$schema) { + $ret = HTMLPurifier_Config::createDefault(); + } else { + $ret = new HTMLPurifier_Config($schema); + } if (is_string($config)) $ret->loadIni($config); elseif (is_array($config)) $ret->loadArray($config); return $ret; @@ -346,8 +351,10 @@ class HTMLPurifier_Config * namespaces/directives list. * @param $allowed List of allowed namespaces/directives */ - public static function getAllowedDirectivesForForm($allowed) { - $schema = HTMLPurifier_ConfigSchema::instance(); + public static function getAllowedDirectivesForForm($allowed, $schema = null) { + if (!$schema) { + $schema = HTMLPurifier_ConfigSchema::instance(); + } if ($allowed !== true) { if (is_string($allowed)) $allowed = array($allowed); $allowed_ns = array(); @@ -389,10 +396,11 @@ class HTMLPurifier_Config * @param $index Index/name that the config variables are in * @param $allowed List of allowed namespaces/directives * @param $mq_fix Boolean whether or not to enable magic quotes fix + * @param $schema Instance of HTMLPurifier_ConfigSchema to use, if not global copy */ - public static function loadArrayFromForm($array, $index, $allowed = true, $mq_fix = true) { - $ret = HTMLPurifier_Config::prepareArrayFromForm($array, $index, $allowed, $mq_fix); - $config = HTMLPurifier_Config::create($ret); + public static function loadArrayFromForm($array, $index, $allowed = true, $mq_fix = true, $schema = null) { + $ret = HTMLPurifier_Config::prepareArrayFromForm($array, $index, $allowed, $mq_fix, $schema); + $config = HTMLPurifier_Config::create($ret, $schema); return $config; } @@ -401,7 +409,7 @@ class HTMLPurifier_Config * @note Same parameters as loadArrayFromForm */ public function mergeArrayFromForm($array, $index, $allowed = true, $mq_fix = true) { - $ret = HTMLPurifier_Config::prepareArrayFromForm($array, $index, $allowed, $mq_fix); + $ret = HTMLPurifier_Config::prepareArrayFromForm($array, $index, $allowed, $mq_fix, $this->def); $this->loadArray($ret); } @@ -409,11 +417,11 @@ class HTMLPurifier_Config * Prepares an array from a form into something usable for the more * strict parts of HTMLPurifier_Config */ - public static function prepareArrayFromForm($array, $index, $allowed = true, $mq_fix = true) { + public static function prepareArrayFromForm($array, $index, $allowed = true, $mq_fix = true, $schema = null) { $array = (isset($array[$index]) && is_array($array[$index])) ? $array[$index] : array(); $mq = get_magic_quotes_gpc() && $mq_fix; - $allowed = HTMLPurifier_Config::getAllowedDirectivesForForm($allowed); + $allowed = HTMLPurifier_Config::getAllowedDirectivesForForm($allowed, $schema); $ret = array(); foreach ($allowed as $key) { list($ns, $directive) = $key; diff --git a/tests/HTMLPurifier/ConfigSchemaTest.php b/tests/HTMLPurifier/ConfigSchemaTest.php index 2bfe3c1e..d785fa60 100644 --- a/tests/HTMLPurifier/ConfigSchemaTest.php +++ b/tests/HTMLPurifier/ConfigSchemaTest.php @@ -2,10 +2,6 @@ require_once 'HTMLPurifier/ConfigSchema.php'; -if (!class_exists('CS')) { - class CS extends HTMLPurifier_ConfigSchema {} -} - class HTMLPurifier_ConfigSchemaTest extends HTMLPurifier_Harness { diff --git a/tests/HTMLPurifier/ConfigTest.php b/tests/HTMLPurifier/ConfigTest.php index 24d3eba9..19f75e32 100644 --- a/tests/HTMLPurifier/ConfigTest.php +++ b/tests/HTMLPurifier/ConfigTest.php @@ -2,46 +2,39 @@ require_once 'HTMLPurifier/Config.php'; -if (!class_exists('CS')) { - class CS extends HTMLPurifier_ConfigSchema {} -} - class HTMLPurifier_ConfigTest extends HTMLPurifier_Harness { - protected $our_copy, $old_copy; + protected $schema; function setUp() { // set up a dummy schema object for testing - $our_copy = new HTMLPurifier_ConfigSchema(); - $this->old_copy = HTMLPurifier_ConfigSchema::instance(); - $this->our_copy =& HTMLPurifier_ConfigSchema::instance($our_copy); + $this->schema = new HTMLPurifier_ConfigSchema(); } function tearDown() { - HTMLPurifier_ConfigSchema::instance($this->old_copy); tally_errors($this); } // test functionality based on ConfigSchema function testNormal() { - CS::defineNamespace('Element', 'Chemical substances that cannot be further decomposed'); + $this->schema->addNamespace('Element', 'Chemical substances that cannot be further decomposed'); - CS::define('Element', 'Abbr', 'H', 'string', 'Abbreviation of element name.'); - CS::define('Element', 'Name', 'hydrogen', 'istring', 'Full name of atoms.'); - CS::define('Element', 'Number', 1, 'int', 'Atomic number, is identity.'); - CS::define('Element', 'Mass', 1.00794, 'float', 'Atomic mass.'); - CS::define('Element', 'Radioactive', false, 'bool', 'Does it have rapid decay?'); - CS::define('Element', 'Isotopes', array(1 => true, 2 => true, 3 => true), 'lookup', + $this->schema->add('Element', 'Abbr', 'H', 'string', 'Abbreviation of element name.'); + $this->schema->add('Element', 'Name', 'hydrogen', 'istring', 'Full name of atoms.'); + $this->schema->add('Element', 'Number', 1, 'int', 'Atomic number, is identity.'); + $this->schema->add('Element', 'Mass', 1.00794, 'float', 'Atomic mass.'); + $this->schema->add('Element', 'Radioactive', false, 'bool', 'Does it have rapid decay?'); + $this->schema->add('Element', 'Isotopes', array(1 => true, 2 => true, 3 => true), 'lookup', 'What numbers of neutrons for this element have been observed?'); - CS::define('Element', 'Traits', array('nonmetallic', 'odorless', 'flammable'), 'list', + $this->schema->add('Element', 'Traits', array('nonmetallic', 'odorless', 'flammable'), 'list', 'What are general properties of the element?'); - CS::define('Element', 'IsotopeNames', array(1 => 'protium', 2 => 'deuterium', 3 => 'tritium'), 'hash', + $this->schema->add('Element', 'IsotopeNames', array(1 => 'protium', 2 => 'deuterium', 3 => 'tritium'), 'hash', 'Lookup hash of neutron counts to formal names.'); - CS::define('Element', 'Object', new stdClass(), 'mixed', 'Model representation.'); + $this->schema->add('Element', 'Object', new stdClass(), 'mixed', 'Model representation.'); - $config = HTMLPurifier_Config::createDefault(); + $config = new HTMLPurifier_Config($this->schema); $config->autoFinalize = false; // test default value retrieval @@ -90,23 +83,23 @@ class HTMLPurifier_ConfigTest extends HTMLPurifier_Harness function testEnumerated() { - CS::defineNamespace('Instrument', 'Of the musical type.'); + $this->schema->addNamespace('Instrument', 'Of the musical type.'); // case sensitive - CS::define('Instrument', 'Manufacturer', 'Yamaha', 'string', 'Who made it?'); - CS::defineAllowedValues('Instrument', 'Manufacturer', array( + $this->schema->add('Instrument', 'Manufacturer', 'Yamaha', 'string', 'Who made it?'); + $this->schema->addAllowedValues('Instrument', 'Manufacturer', array( 'Yamaha', 'Conn-Selmer', 'Vandoren', 'Laubin', 'Buffet', 'other')); - CS::defineValueAliases('Instrument', 'Manufacturer', array( + $this->schema->addValueAliases('Instrument', 'Manufacturer', array( 'Selmer' => 'Conn-Selmer')); // case insensitive - CS::define('Instrument', 'Family', 'woodwind', 'istring', 'What family is it?'); - CS::defineAllowedValues('Instrument', 'Family', array( + $this->schema->add('Instrument', 'Family', 'woodwind', 'istring', 'What family is it?'); + $this->schema->addAllowedValues('Instrument', 'Family', array( 'brass', 'woodwind', 'percussion', 'string', 'keyboard', 'electronic')); - CS::defineValueAliases('Instrument', 'Family', array( + $this->schema->addValueAliases('Instrument', 'Family', array( 'synth' => 'electronic')); - $config = HTMLPurifier_Config::createDefault(); + $config = new HTMLPurifier_Config($this->schema); $config->autoFinalize = false; // case sensitive @@ -138,11 +131,11 @@ class HTMLPurifier_ConfigTest extends HTMLPurifier_Harness function testNull() { - CS::defineNamespace('ReportCard', 'It is for grades.'); - CS::define('ReportCard', 'English', null, 'string/null', 'Grade from English class.'); - CS::define('ReportCard', 'Absences', 0, 'int', 'How many times missing from school?'); + $this->schema->addNamespace('ReportCard', 'It is for grades.'); + $this->schema->add('ReportCard', 'English', null, 'string/null', 'Grade from English class.'); + $this->schema->add('ReportCard', 'Absences', 0, 'int', 'How many times missing from school?'); - $config = HTMLPurifier_Config::createDefault(); + $config = new HTMLPurifier_Config($this->schema); $config->autoFinalize = false; $config->set('ReportCard', 'English', 'B-'); @@ -159,11 +152,11 @@ class HTMLPurifier_ConfigTest extends HTMLPurifier_Harness function testAliases() { - CS::defineNamespace('Home', 'Sweet home.'); - CS::define('Home', 'Rug', 3, 'int', 'ID.'); - CS::defineAlias('Home', 'Carpet', 'Home', 'Rug'); + $this->schema->addNamespace('Home', 'Sweet home.'); + $this->schema->add('Home', 'Rug', 3, 'int', 'ID.'); + $this->schema->addAlias('Home', 'Carpet', 'Home', 'Rug'); - $config = HTMLPurifier_Config::createDefault(); + $config = new HTMLPurifier_Config($this->schema); $config->autoFinalize = false; $this->assertIdentical($config->get('Home', 'Rug'), 3); @@ -180,11 +173,11 @@ class HTMLPurifier_ConfigTest extends HTMLPurifier_Harness function test_getBatch() { - CS::defineNamespace('Variables', 'Changing quantities in equation.'); - CS::define('Variables', 'TangentialAcceleration', 'a_tan', 'string', 'In m/s^2'); - CS::define('Variables', 'AngularAcceleration', 'alpha', 'string', 'In rad/s^2'); + $this->schema->addNamespace('Variables', 'Changing quantities in equation.'); + $this->schema->add('Variables', 'TangentialAcceleration', 'a_tan', 'string', 'In m/s^2'); + $this->schema->add('Variables', 'AngularAcceleration', 'alpha', 'string', 'In rad/s^2'); - $config = HTMLPurifier_Config::createDefault(); + $config = new HTMLPurifier_Config($this->schema); $config->autoFinalize = false; // grab a namespace @@ -204,12 +197,12 @@ class HTMLPurifier_ConfigTest extends HTMLPurifier_Harness function test_loadIni() { - CS::defineNamespace('Shortcut', 'Keyboard shortcuts for commands'); - CS::define('Shortcut', 'Copy', 'c', 'istring', 'Copy text'); - CS::define('Shortcut', 'Paste', 'v', 'istring', 'Paste clipboard'); - CS::define('Shortcut', 'Cut', 'x', 'istring', 'Cut text'); + $this->schema->addNamespace('Shortcut', 'Keyboard shortcuts for commands'); + $this->schema->add('Shortcut', 'Copy', 'c', 'istring', 'Copy text'); + $this->schema->add('Shortcut', 'Paste', 'v', 'istring', 'Paste clipboard'); + $this->schema->add('Shortcut', 'Cut', 'x', 'istring', 'Cut text'); - $config = HTMLPurifier_Config::createDefault(); + $config = new HTMLPurifier_Config($this->schema); $config->autoFinalize = false; $config->loadIni(dirname(__FILE__) . '/ConfigTest-loadIni.ini'); @@ -225,8 +218,6 @@ class HTMLPurifier_ConfigTest extends HTMLPurifier_Harness // we actually want to use the old copy, because the definition // generation routines have dependencies on configuration values - $this->old_copy = HTMLPurifier_ConfigSchema::instance($this->old_copy); - $config = HTMLPurifier_Config::createDefault(); $config->set('HTML', 'Doctype', 'XHTML 1.0 Strict'); $config->autoFinalize = false; @@ -264,41 +255,39 @@ class HTMLPurifier_ConfigTest extends HTMLPurifier_Harness } function test_getHTMLDefinition_rawError() { - $this->old_copy = HTMLPurifier_ConfigSchema::instance($this->old_copy); $config = HTMLPurifier_Config::createDefault(); $this->expectError('Cannot retrieve raw version without specifying %HTML.DefinitionID'); $def =& $config->getHTMLDefinition(true); } function test_getCSSDefinition() { - $this->old_copy = HTMLPurifier_ConfigSchema::instance($this->old_copy); $config = HTMLPurifier_Config::createDefault(); $def = $config->getCSSDefinition(); $this->assertIsA($def, 'HTMLPurifier_CSSDefinition'); } function test_getDefinition() { - CS::defineNamespace('Cache', 'Cache stuff'); - CS::define('Cache', 'DefinitionImpl', null, 'string/null', 'Cache?'); - CS::defineNamespace('Crust', 'Krusty Krabs'); - $config = HTMLPurifier_Config::createDefault(); + $this->schema->addNamespace('Cache', 'Cache stuff'); + $this->schema->add('Cache', 'DefinitionImpl', null, 'string/null', 'Cache?'); + $this->schema->addNamespace('Crust', 'Krusty Krabs'); + $config = new HTMLPurifier_Config($this->schema); $this->expectError("Definition of Crust type not supported"); $config->getDefinition('Crust'); } function test_loadArray() { // setup a few dummy namespaces/directives for our testing - CS::defineNamespace('Zoo', 'Animals we have.'); - CS::define('Zoo', 'Aadvark', 0, 'int', 'Have?'); - CS::define('Zoo', 'Boar', 0, 'int', 'Have?'); - CS::define('Zoo', 'Camel', 0, 'int', 'Have?'); - CS::define( + $this->schema->addNamespace('Zoo', 'Animals we have.'); + $this->schema->add('Zoo', 'Aadvark', 0, 'int', 'Have?'); + $this->schema->add('Zoo', 'Boar', 0, 'int', 'Have?'); + $this->schema->add('Zoo', 'Camel', 0, 'int', 'Have?'); + $this->schema->add( 'Zoo', 'Others', array(), 'list', 'Other animals we have one of.' ); - $config_manual = HTMLPurifier_Config::createDefault(); - $config_loadabbr = HTMLPurifier_Config::createDefault(); - $config_loadfull = HTMLPurifier_Config::createDefault(); + $config_manual = new HTMLPurifier_Config($this->schema); + $config_loadabbr = new HTMLPurifier_Config($this->schema); + $config_loadfull = new HTMLPurifier_Config($this->schema); $config_manual->set('Zoo', 'Aadvark', 3); $config_manual->set('Zoo', 'Boar', 5); @@ -330,23 +319,23 @@ class HTMLPurifier_ConfigTest extends HTMLPurifier_Harness function test_create() { - CS::defineNamespace('Cake', 'Properties of it.'); - CS::define('Cake', 'Sprinkles', 666, 'int', 'Number of.'); - CS::define('Cake', 'Flavor', 'vanilla', 'string', 'Flavor of the batter.'); + $this->schema->addNamespace('Cake', 'Properties of it.'); + $this->schema->add('Cake', 'Sprinkles', 666, 'int', 'Number of.'); + $this->schema->add('Cake', 'Flavor', 'vanilla', 'string', 'Flavor of the batter.'); - $config = HTMLPurifier_Config::createDefault(); + $config = new HTMLPurifier_Config($this->schema); $config->set('Cake', 'Sprinkles', 42); // test flat pass-through - $created_config = HTMLPurifier_Config::create($config); + $created_config = HTMLPurifier_Config::create($config, $this->schema); $this->assertIdentical($config, $created_config); // test loadArray - $created_config = HTMLPurifier_Config::create(array('Cake.Sprinkles' => 42)); + $created_config = HTMLPurifier_Config::create(array('Cake.Sprinkles' => 42), $this->schema); $this->assertIdentical($config, $created_config); // test loadIni - $created_config = HTMLPurifier_Config::create(dirname(__FILE__) . '/ConfigTest-create.ini'); + $created_config = HTMLPurifier_Config::create(dirname(__FILE__) . '/ConfigTest-create.ini', $this->schema); $this->assertIdentical($config, $created_config); } @@ -355,10 +344,10 @@ class HTMLPurifier_ConfigTest extends HTMLPurifier_Harness // test finalization - CS::defineNamespace('Poem', 'Violets are red, roses are blue...'); - CS::define('Poem', 'Meter', 'iambic', 'string', 'Rhythm of poem.'); + $this->schema->addNamespace('Poem', 'Violets are red, roses are blue...'); + $this->schema->add('Poem', 'Meter', 'iambic', 'string', 'Rhythm of poem.'); - $config = HTMLPurifier_Config::createDefault(); + $config = new HTMLPurifier_Config($this->schema); $config->autoFinalize = false; $config->set('Poem', 'Meter', 'irregular'); @@ -376,19 +365,19 @@ class HTMLPurifier_ConfigTest extends HTMLPurifier_Harness } - function test_loadArrayFromForm() { + function __onlytest_loadArrayFromForm() { - CS::defineNamespace('Pancake', 'This should not be user customizable'); - CS::define('Pancake', 'Mix', 'buttermilk', 'string', 'Type of pancake mix to use.'); - CS::define('Pancake', 'Served', true, 'bool', 'But this is customizable by user.'); - CS::defineNamespace('Toppings', 'This is user customizable'); - CS::define('Toppings', 'Syrup', true, 'bool', 'Absolutely standard!'); - CS::define('Toppings', 'Flavor', 'maple', 'string', 'What flavor is the syrup?'); - CS::define('Toppings', 'Strawberries', 3, 'int', 'Quite delightful fruit.'); - CS::define('Toppings', 'Calories', 2000, 'int/null', 'Some things are best left unknown.'); - CS::define('Toppings', 'DefinitionID', null, 'string/null', 'Do not let this be set'); - CS::define('Toppings', 'DefinitionRev', 1, 'int', 'Do not let this be set'); - CS::define('Toppings', 'Protected', 1, 'int', 'Do not let this be set'); + $this->schema->addNamespace('Pancake', 'This should not be user customizable'); + $this->schema->add('Pancake', 'Mix', 'buttermilk', 'string', 'Type of pancake mix to use.'); + $this->schema->add('Pancake', 'Served', true, 'bool', 'But this is customizable by user.'); + $this->schema->addNamespace('Toppings', 'This is user customizable'); + $this->schema->add('Toppings', 'Syrup', true, 'bool', 'Absolutely standard!'); + $this->schema->add('Toppings', 'Flavor', 'maple', 'string', 'What flavor is the syrup?'); + $this->schema->add('Toppings', 'Strawberries', 3, 'int', 'Quite delightful fruit.'); + $this->schema->add('Toppings', 'Calories', 2000, 'int/null', 'Some things are best left unknown.'); + $this->schema->add('Toppings', 'DefinitionID', null, 'string/null', 'Do not let this be set'); + $this->schema->add('Toppings', 'DefinitionRev', 1, 'int', 'Do not let this be set'); + $this->schema->add('Toppings', 'Protected', 1, 'int', 'Do not let this be set'); $get = array( 'breakfast' => array( @@ -411,9 +400,14 @@ class HTMLPurifier_ConfigTest extends HTMLPurifier_Harness 'Toppings.Flavor' => "juice", 'Toppings.Strawberries' => 999, 'Toppings.Calories' => null - )); + ), $this->schema); - $config_result = HTMLPurifier_Config::loadArrayFromForm($get, 'breakfast', array('Pancake.Served', 'Toppings', '-Toppings.Protected')); + $config_result = HTMLPurifier_Config::loadArrayFromForm( + $get, 'breakfast', + array('Pancake.Served', 'Toppings', '-Toppings.Protected'), + true, // mq fix + $this->schema + ); $this->assertEqual($config_expect, $config_result); @@ -434,19 +428,19 @@ class HTMLPurifier_ConfigTest extends HTMLPurifier_Harness } function test_getAllowedDirectivesForForm() { - CS::defineNamespace('Unused', 'Not mentioned, so deny'); - CS::define('Unused', 'Unused', 'Foobar', 'string', 'Not mentioned, do not allow'); - CS::defineNamespace('Partial', 'Some are mentioned, allow only those'); - CS::define('Partial', 'Allowed', true, 'bool', 'Mentioned, allowed'); - CS::define('Partial', 'Unused', 'Foobar', 'string', 'Not mentioned, do not allow'); - CS::defineNamespace('All', 'Entire namespace allowed, allow all unless...'); - CS::define('All', 'Allowed', true, 'bool', 'Not mentioned, allowed'); - CS::define('All', 'Blacklisted', 'Foobar', 'string', 'Specifically blacklisted'); - CS::define('All', 'DefinitionID', 'Foobar', 'string/null', 'Special case, auto-blacklisted'); - CS::define('All', 'DefinitionRev', 2, 'int', 'Special case, auto-blacklisted'); + $this->schema->addNamespace('Unused', 'Not mentioned, so deny'); + $this->schema->add('Unused', 'Unused', 'Foobar', 'string', 'Not mentioned, do not allow'); + $this->schema->addNamespace('Partial', 'Some are mentioned, allow only those'); + $this->schema->add('Partial', 'Allowed', true, 'bool', 'Mentioned, allowed'); + $this->schema->add('Partial', 'Unused', 'Foobar', 'string', 'Not mentioned, do not allow'); + $this->schema->addNamespace('All', 'Entire namespace allowed, allow all unless...'); + $this->schema->add('All', 'Allowed', true, 'bool', 'Not mentioned, allowed'); + $this->schema->add('All', 'Blacklisted', 'Foobar', 'string', 'Specifically blacklisted'); + $this->schema->add('All', 'DefinitionID', 'Foobar', 'string/null', 'Special case, auto-blacklisted'); + $this->schema->add('All', 'DefinitionRev', 2, 'int', 'Special case, auto-blacklisted'); $input = array('Partial.Allowed', 'All', '-All.Blacklisted'); - $output = HTMLPurifier_Config::getAllowedDirectivesForForm($input); + $output = HTMLPurifier_Config::getAllowedDirectivesForForm($input, $this->schema); $expect = array( array('Partial', 'Allowed'), array('All', 'Allowed') diff --git a/tests/HTMLPurifier/GeneratorTest.php b/tests/HTMLPurifier/GeneratorTest.php index 97a06d2a..ffac8cd1 100644 --- a/tests/HTMLPurifier/GeneratorTest.php +++ b/tests/HTMLPurifier/GeneratorTest.php @@ -63,7 +63,6 @@ class HTMLPurifier_GeneratorTest extends HTMLPurifier_ComplexHarness foreach ($inputs as $i => $input) { $result = $this->obj->generateFromToken($input); $this->assertIdentical($result, $expect[$i]); - paintIf($result, $result != $expect[$i]); } } @@ -92,7 +91,6 @@ class HTMLPurifier_GeneratorTest extends HTMLPurifier_ComplexHarness foreach ($inputs as $i => $input) { $result = $this->obj->generateAttributes($input, 'irrelevant'); $this->assertIdentical($result, $expect[$i]); - paintIf($result, $result != $expect[$i]); } } diff --git a/tests/HTMLPurifier/Lexer/DirectLexTest.php b/tests/HTMLPurifier/Lexer/DirectLexTest.php index fb8f822d..4a149548 100644 --- a/tests/HTMLPurifier/Lexer/DirectLexTest.php +++ b/tests/HTMLPurifier/Lexer/DirectLexTest.php @@ -71,7 +71,6 @@ class HTMLPurifier_Lexer_DirectLexTest extends HTMLPurifier_Harness for($i = 0; $i < $size; $i++) { $result = $this->DirectLex->parseAttributeString($input[$i], $config, $context); $this->assertIdentical($expect[$i], $result, 'Test ' . $i . ': %s'); - paintIf($result, $expect[$i] != $result); } } diff --git a/tests/HTMLPurifier/PHPT/Smoketest.phpt b/tests/HTMLPurifier/PHPT/Smoketest.phpt new file mode 100644 index 00000000..02651c52 --- /dev/null +++ b/tests/HTMLPurifier/PHPT/Smoketest.phpt @@ -0,0 +1,6 @@ +--TEST-- +PHPT testing framework smoketest +--FILE-- +Foobar +--EXPECT-- +Foobar diff --git a/tests/PHPT/Controller/SimpleTest.php b/tests/PHPT/Controller/SimpleTest.php new file mode 100644 index 00000000..454c9098 --- /dev/null +++ b/tests/PHPT/Controller/SimpleTest.php @@ -0,0 +1,28 @@ +_path = $path; + parent::SimpleTestCase($path); + } + + public function testPhpt() { + if (is_dir($this->_path)) { + $factory = new PHPT_Suite_Factory(); + $suite = $factory->factory($this->_path, true); + } else { + $suite = new PHPT_Suite(array($this->_path)); + } + // Adapter class that relays messages to SimpleTest + $phpt_reporter = new PHPT_Reporter_SimpleTest($this->_reporter); + $suite->run($phpt_reporter); + } + +} diff --git a/tests/PHPT/Reporter/SimpleTest.php b/tests/PHPT/Reporter/SimpleTest.php new file mode 100644 index 00000000..0d206e46 --- /dev/null +++ b/tests/PHPT/Reporter/SimpleTest.php @@ -0,0 +1,72 @@ +reporter = $reporter; + } + + /** + * Called when the Reporter is started from a PHPT_Suite + * @todo Figure out if Suites can be named + */ + public function onSuiteStart(PHPT_Suite $suite) { + $this->reporter->paintGroupStart('PHPT Suite', $suite->count()); + } + + /** + * Called when the Reporter is finished in a PHPT_Suite + */ + public function onSuiteEnd(PHPT_Suite $suite) { + $this->reporter->paintGroupEnd('PHPT Suite'); + } + + /** + * Called when a Case is started + */ + public function onCaseStart(PHPT_Case $case) { + $this->reporter->paintCaseStart($case->name); + } + + /** + * Called when a Case ends + */ + public function onCaseEnd(PHPT_Case $case) { + $this->reporter->paintCaseEnd($case->name); + } + + /** + * Called when a Case runs without Exception + */ + public function onCasePass(PHPT_Case $case) { + $this->reporter->paintPass("{$case->name} in {$case->filename}"); + } + + /** + * Called when a PHPT_Case_VetoException is thrown during a Case's run() + */ + public function onCaseSkip(PHPT_Case $case, PHPT_Case_VetoException $veto) { + $this->reporter->paintSkip("{$case->name} in {$case->filename}"); + } + + /** + * Called when any Exception other than a PHPT_Case_VetoException is encountered + * during a Case's run() + */ + public function onCaseFail(PHPT_Case $case, PHPT_Case_FailureException $failure) { + $this->reporter->paintFail($failure->getReason()); + } + + public function onParserError(Exception $exception) { + $this->reporter->paintException($exception); + } + +} diff --git a/tests/common.php b/tests/common.php index 12007b34..f52ff6c3 100644 --- a/tests/common.php +++ b/tests/common.php @@ -5,6 +5,20 @@ if (!defined('HTMLPurifierTest')) { exit; } +// setup our own autoload, checking for HTMLPurifier library if spl_autoload_register +// is not allowed +function __autoload($class) { + if (!function_exists('spl_autoload_register')) { + if (HTMLPurifier_Bootstrap::autoload($class)) return true; + if (HTMLPurifierExtras::autoload($class)) return true; + } + require_once str_replace('_', '/', $class) . '.php'; + return true; +} +if (function_exists('spl_autoload_register')) { + spl_autoload_register('__autoload'); +} + // default settings (protect against register_globals) $GLOBALS['HTMLPurifierTest'] = array(); $GLOBALS['HTMLPurifierTest']['PEAR'] = false; // do PEAR tests @@ -43,10 +57,7 @@ if ( is_string($GLOBALS['HTMLPurifierTest']['PEAR']) ) { // after external libraries are loaded, turn on compile time errors error_reporting(E_ALL | E_STRICT); -// load SimpleTest addons -require_once 'HTMLPurifier/SimpleTest/Reporter.php'; -require_once 'CliTestCase.php'; -require_once 'Debugger.php'; +// load SimpleTest addon functions require_once 'generate_mock_once.func.php'; require_once 'path2class.func.php'; require_once 'tally_errors.func.php'; // compat @@ -104,3 +115,17 @@ function htmlpurifier_args(&$AC, $aliases, $o, $v) { if (is_string($AC[$o])) $AC[$o] = $v; if (is_bool($AC[$o])) $AC[$o] = true; } + +/** + * Adds a test-class; depending on the file's extension this may involve + * a regular UnitTestCase or a special PHPT test + */ +function htmlpurifier_add_test($test, $test_file) { + $info = pathinfo($test_file); + if (!isset($info['extension']) || $info['extension'] == 'phpt') { + $test->addTestCase(new PHPT_Controller_SimpleTest($test_file)); + } else { + require_once $test_file; + $test->addTestClass(path2class($test_file)); + } +} \ No newline at end of file diff --git a/tests/index.php b/tests/index.php index 06445037..bfd96a16 100755 --- a/tests/index.php +++ b/tests/index.php @@ -25,23 +25,23 @@ $AC['standalone'] = false; $AC['file'] = ''; $AC['xml'] = false; $AC['dry'] = false; +$AC['php'] = 'php'; $aliases = array( 'f' => 'file', ); htmlpurifier_parse_args($AC, $aliases); -// clean out cache if necessary -if ($AC['flush']) shell_exec('php ../maintenance/flush-definition-cache.php'); - -// setup our own autoload for earlier PHP versions -if (!function_exists('spl_autoload_register')) { - function __autoload($class) { - return // we're using the fact that once one OR is true, the rest is skipped - HTMLPurifier_Bootstrap::autoload($class) || - HTMLPurifierExtras::autoload($class); - } +if (!SimpleReporter::inCli()) { + // Undo any dangerous parameters + $AC['php'] = 'php'; } +$phpt = PHPT_Registry::getInstance(); +$phpt->php = $AC['php']; + +// clean out cache if necessary +if ($AC['flush']) shell_exec($AC['php'] . ' ../maintenance/flush-definition-cache.php'); + // initialize and load alternative classes require_once '../extras/HTMLPurifierExtras.auto.php'; @@ -81,8 +81,7 @@ if ($AC['file']) { if ($AC['file']) { $test = new TestSuite($AC['file']); - require_once $AC['file']; - $test->addTestClass(path2class($AC['file'])); + htmlpurifier_add_test($test, $AC['file']); } else { @@ -90,8 +89,7 @@ if ($AC['file']) { if ($AC['standalone']) $standalone = ' (standalone)'; $test = new TestSuite('All HTML Purifier tests on PHP ' . PHP_VERSION . $standalone); foreach ($test_files as $test_file) { - require_once $test_file; - $test->addTestClass(path2class($test_file)); + htmlpurifier_add_test($test, $test_file); } } diff --git a/tests/multitest.php b/tests/multitest.php index f9319bf6..f562e502 100644 --- a/tests/multitest.php +++ b/tests/multitest.php @@ -37,6 +37,7 @@ $AC['exclude-standalone'] = false; $AC['file'] = ''; $AC['xml'] = false; $AC['quiet'] = false; +$AC['php'] = 'php'; $aliases = array( 'f' => 'file', 'q' => 'quiet', @@ -44,11 +45,11 @@ $aliases = array( htmlpurifier_parse_args($AC, $aliases); // Calls generate-includes.php automatically -shell_exec("php ../maintenance/merge-library.php"); +shell_exec($AC['php'] . ' ../maintenance/merge-library.php'); // Not strictly necessary, but its a good idea -shell_exec("php ../maintenance/generate-schema-cache.php"); -shell_exec('php ../maintenance/flush-definition-cache.php'); +shell_exec($AC['php'] . ' ../maintenance/generate-schema-cache.php'); +shell_exec($AC['php'] . ' ../maintenance/flush-definition-cache.php'); $test = new TestSuite('HTML Purifier Multiple Versions Test'); $file = ''; @@ -73,8 +74,8 @@ foreach ($versions_to_test as $version) { $version = $version[0]; $flush = '--flush'; } - if (!$AC['exclude-normal']) $test->addTestCase(new CliTestCase("$phpv $version index.php --xml $flush $file", $AC['quiet'], $size)); - if (!$AC['exclude-standalone']) $test->addTestCase(new CliTestCase("$phpv $version index.php --xml --standalone $file", $AC['quiet'], $size)); + if (!$AC['exclude-normal']) $test->addTestCase(new CliTestCase("$phpv $version index.php --xml $flush --php=\"$phpv $version\" $file", $AC['quiet'], $size)); + if (!$AC['exclude-standalone']) $test->addTestCase(new CliTestCase("$phpv $version index.php --xml --standalone --php=\"$phpv $version\" $file", $AC['quiet'], $size)); } // This is the HTML Purifier website's test XML file. We could @@ -88,4 +89,4 @@ if ($AC['xml']) { } $test->run($reporter); -shell_exec('php ../maintenance/flush-definition-cache.php'); +shell_exec($AC['php'] . ' ../maintenance/flush-definition-cache.php'); diff --git a/tests/test_files.php b/tests/test_files.php index f6c1b7a7..aaa1e929 100644 --- a/tests/test_files.php +++ b/tests/test_files.php @@ -140,3 +140,7 @@ $test_files[] = 'ConfigSchema/StringHashAdapterTest.php'; $test_files[] = 'ConfigSchema/StringHashReverseAdapterTest.php'; $test_files[] = 'ConfigSchema/StringHashParserTest.php'; $test_files[] = 'ConfigSchema/StringHashTest.php'; + +// PHPT tests + +$test_files[] = 'HTMLPurifier/PHPT';