1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288
|
<?php
class HTMLPurifier_GeneratorTest extends HTMLPurifier_Harness
{
/**
* Entity lookup table to help for a few tests.
*/
private $_entity_lookup;
public function __construct() {
parent::__construct();
$this->_entity_lookup = HTMLPurifier_EntityLookup::instance();
}
public function setUp() {
parent::setUp();
$this->config->set('Output.Newline', "\n");
}
/**
* Creates a generator based on config and context member variables.
*/
protected function createGenerator() {
return new HTMLPurifier_Generator($this->config, $this->context);
}
protected function assertGenerateFromToken($token, $html) {
$generator = $this->createGenerator();
$result = $generator->generateFromToken($token);
$this->assertIdentical($result, $html);
}
function test_generateFromToken_text() {
$this->assertGenerateFromToken(
new HTMLPurifier_Token_Text('Foobar.<>'),
'Foobar.<>'
);
}
function test_generateFromToken_startWithAttr() {
$this->assertGenerateFromToken(
new HTMLPurifier_Token_Start('a',
array('href' => 'dyn?a=foo&b=bar')
),
'<a href="dyn?a=foo&b=bar">'
);
}
function test_generateFromToken_end() {
$this->assertGenerateFromToken(
new HTMLPurifier_Token_End('b'),
'</b>'
);
}
function test_generateFromToken_emptyWithAttr() {
$this->assertGenerateFromToken(
new HTMLPurifier_Token_Empty('br',
array('style' => 'font-family:"Courier New";')
),
'<br style="font-family:"Courier New";" />'
);
}
function test_generateFromToken_startNoAttr() {
$this->assertGenerateFromToken(
new HTMLPurifier_Token_Start('asdf'),
'<asdf>'
);
}
function test_generateFromToken_emptyNoAttr() {
$this->assertGenerateFromToken(
new HTMLPurifier_Token_Empty('br'),
'<br />'
);
}
function test_generateFromToken_error() {
$this->expectError('Cannot generate HTML from non-HTMLPurifier_Token object');
$this->assertGenerateFromToken( null, '' );
}
function test_generateFromToken_unicode() {
$theta_char = $this->_entity_lookup->table['theta'];
$this->assertGenerateFromToken(
new HTMLPurifier_Token_Text($theta_char),
$theta_char
);
}
function test_generateFromToken_backtick() {
$this->assertGenerateFromToken(
new HTMLPurifier_Token_Start('img', array('alt' => '`foo')),
'<img alt="`foo ">'
);
}
function test_generateFromToken_backtickDisabled() {
$this->config->set('Output.FixInnerHTML', false);
$this->assertGenerateFromToken(
new HTMLPurifier_Token_Start('img', array('alt' => '`')),
'<img alt="`">'
);
}
function test_generateFromToken_backtickNoChange() {
$this->assertGenerateFromToken(
new HTMLPurifier_Token_Start('img', array('alt' => '`foo` bar')),
'<img alt="`foo` bar">'
);
}
function assertGenerateAttributes($attr, $expect, $element = false) {
$generator = $this->createGenerator();
$result = $generator->generateAttributes($attr, $element);
$this->assertIdentical($result, $expect);
}
function test_generateAttributes_blank() {
$this->assertGenerateAttributes(array(), '');
}
function test_generateAttributes_basic() {
$this->assertGenerateAttributes(
array('href' => 'dyn?a=foo&b=bar'),
'href="dyn?a=foo&b=bar"'
);
}
function test_generateAttributes_doubleQuote() {
$this->assertGenerateAttributes(
array('style' => 'font-family:"Courier New";'),
'style="font-family:"Courier New";"'
);
}
function test_generateAttributes_singleQuote() {
$this->assertGenerateAttributes(
array('style' => 'font-family:\'Courier New\';'),
'style="font-family:\'Courier New\';"'
);
}
function test_generateAttributes_multiple() {
$this->assertGenerateAttributes(
array('src' => 'picture.jpg', 'alt' => 'Short & interesting'),
'src="picture.jpg" alt="Short & interesting"'
);
}
function test_generateAttributes_specialChar() {
$theta_char = $this->_entity_lookup->table['theta'];
$this->assertGenerateAttributes(
array('title' => 'Theta is ' . $theta_char),
'title="Theta is ' . $theta_char . '"'
);
}
function test_generateAttributes_minimized() {
$this->config->set('HTML.Doctype', 'HTML 4.01 Transitional');
$this->assertGenerateAttributes(
array('compact' => 'compact'), 'compact', 'menu'
);
}
function test_generateFromTokens() {
$this->assertGeneration(
array(
new HTMLPurifier_Token_Start('b'),
new HTMLPurifier_Token_Text('Foobar!'),
new HTMLPurifier_Token_End('b')
),
'<b>Foobar!</b>'
);
}
protected function assertGeneration($tokens, $expect) {
$generator = new HTMLPurifier_Generator($this->config, $this->context);
$result = $generator->generateFromTokens($tokens);
$this->assertIdentical($expect, $result);
}
function test_generateFromTokens_Scripting() {
$this->assertGeneration(
array(
new HTMLPurifier_Token_Start('script'),
new HTMLPurifier_Token_Text('alert(3 < 5);'),
new HTMLPurifier_Token_End('script')
),
"<script><!--//--><![CDATA[//><!--\nalert(3 < 5);\n//--><!]]></script>"
);
}
function test_generateFromTokens_Scripting_missingCloseTag() {
$this->assertGeneration(
array(
new HTMLPurifier_Token_Start('script'),
new HTMLPurifier_Token_Text('alert(3 < 5);'),
),
"<script>alert(3 < 5);"
);
}
function test_generateFromTokens_Scripting_doubleBlock() {
$this->assertGeneration(
array(
new HTMLPurifier_Token_Start('script'),
new HTMLPurifier_Token_Text('alert(3 < 5);'),
new HTMLPurifier_Token_Text('foo();'),
new HTMLPurifier_Token_End('script')
),
"<script>alert(3 < 5);foo();</script>"
);
}
function test_generateFromTokens_Scripting_disableWrapper() {
$this->config->set('Output.CommentScriptContents', false);
$this->assertGeneration(
array(
new HTMLPurifier_Token_Start('script'),
new HTMLPurifier_Token_Text('alert(3 < 5);'),
new HTMLPurifier_Token_End('script')
),
"<script>alert(3 < 5);</script>"
);
}
function test_generateFromTokens_XHTMLoff() {
$this->config->set('HTML.XHTML', false);
// omit trailing slash
$this->assertGeneration(
array( new HTMLPurifier_Token_Empty('br') ),
'<br>'
);
// there should be a test for attribute minimization, but it is
// impossible for something like that to happen due to our current
// definitions! fix it later
// namespaced attributes must be dropped
$this->assertGeneration(
array( new HTMLPurifier_Token_Start('p', array('xml:lang'=>'fr')) ),
'<p>'
);
}
function test_generateFromTokens_TidyFormat() {
// abort test if tidy isn't loaded
if (!extension_loaded('tidy')) return;
// just don't test; Tidy is exploding on me.
return;
$this->config->set('Core.TidyFormat', true);
$this->config->set('Output.Newline', "\n");
// nice wrapping please
$this->assertGeneration(
array(
new HTMLPurifier_Token_Start('div'),
new HTMLPurifier_Token_Text('Text'),
new HTMLPurifier_Token_End('div')
),
"<div>\n Text\n</div>\n"
);
}
function test_generateFromTokens_sortAttr() {
$this->config->set('Output.SortAttr', true);
$this->assertGeneration(
array( new HTMLPurifier_Token_Start('p', array('b'=>'c', 'a'=>'d')) ),
'<p a="d" b="c">'
);
}
}
// vim: et sw=4 sts=4
|