2 // $Id: SpamTest.php,v 1.13 2007/06/09 03:16:08 henoheno Exp $
3 // Copyright (C) 2007 heno
5 // Design test case for spam.php (called from runner.php)
7 if (! defined('SPAM_INI_FILE')) define('SPAM_INI_FILE', 'spam.ini.php');
9 require_once('spam.php');
10 require_once('PHPUnit/PHPUnit.php');
12 class SpamTest extends PHPUnit_TestCase
14 function setup_string_null()
20 '[array(foobar)]' => array('foobar'),
27 function testFunc_array_count_leaves()
29 // Empty array = 0, if option is not set
31 $this->assertEquals(0, array_count_leaves($array, FALSE));
32 $this->assertEquals(1, array_count_leaves($array, TRUE));
38 $this->assertEquals(0, array_count_leaves($array, FALSE));
39 $this->assertEquals(1, array_count_leaves($array, TRUE));
42 foreach(array(NULL, TRUE, FALSE, -1, 0, 1, '', 'foobar') as $value) {
43 $this->assertEquals(1, array_count_leaves($value, FALSE));
44 $this->assertEquals(1, array_count_leaves($value, TRUE));
51 array(), // Empty array
57 'k3' => array(), // Empty array
62 'k6' => array(), // Empty array
67 'k9' => array(), // Empty array
72 'k12' => array(), // Empty array
75 $this->assertEquals(14, array_count_leaves($array, FALSE));
76 $this->assertEquals(19, array_count_leaves($array, TRUE));
79 function testPhpFunc_array_unique()
81 $this->assertEquals(array(1), array_unique(array(1, 1)));
83 // Keys are preserved, array()s inside are preserved
85 array(0, 2 => array(1, 1), 3 => 2),
87 array(0, 0, array(1, 1), 2, 2)
93 array(0, 2 => array(1, 1), 3 => 2),
94 array_unique(array(0, 0, array(1, 1), 2, 2))
97 // ONLY the first array() is preserved
99 array(0 => array(1, 1)),
100 array_unique(array_unique(array(0 => array(1, 1), 'a' => array(2,2), 'b' => array(3, 3))))
104 // And array_unique_recursive()
105 function testPhPFunc_array_merge_recursive()
109 $result = array_merge_recursive($array1, $array2);
110 $this->assertEquals(array(1, 1), $result);
111 $result = array_unique_recursive($result);
112 $this->assertEquals(array(1), $result);
116 $result = array(2, 1);
117 $this->assertEquals($result, array_merge_recursive($array1, $array2));
119 // All NUMERIC keys are always renumbered from 0
120 $array1 = array('10' => 'f3');
121 $array2 = array('10' => 'f4');
122 $result = array('f3', 'f4');
123 $this->assertEquals($result, array_merge_recursive($array1, $array2));
125 // One more thing ...
126 $array1 = array('20' => 'f5');
128 $result = array('f5');
129 $this->assertEquals($result, array_merge_recursive($array1, $array2));
131 // Non-numeric keys and values will be marged as you think
132 $array1 = array('a' => 'f1');
133 $array2 = array('a' => 'f2');
134 $result = array('a' => array('f1', 'f2'));
135 $this->assertEquals($result, array_merge_recursive($array1, $array2));
137 // Non-numeric keys: An array and a value will be marged
138 $array1 = array('b' => array('k1'));
139 $array2 = array('b' => 'k2');
140 $result = array('b' => array('k1', 'k2'));
141 $this->assertEquals($result, array_merge_recursive($array1, $array2));
172 $this->assertEquals($result, array_merge_recursive($array1, $array2));
174 // Values will not be unique
175 $array1 = array(5, 4);
176 $array2 = array(4, 5);
177 $result = array_merge_recursive($array1, $array2);
178 $this->assertEquals(array(5, 4, 4, 5), $result);
179 $result = array_unique_recursive($result);
180 $this->assertEquals(array(5, 4), $result);
182 // One more thing ...
183 $array1 = array('b' => array('k3'));
184 $array2 = array('b' => 'k3');
185 $result = array_merge_recursive($array1, $array2);
186 $this->assertEquals(array('b' => array('k3', 'k3')), $result);
187 $result = array_unique_recursive($result);
188 $this->assertEquals(array('b' => array('k3')), $result);
191 function testFunc_uri_pickup()
193 // 1st argument: Null
194 foreach($this->setup_string_null() as $key => $value){
195 $this->assertEquals(0, count(uri_pickup($value)), $key);
198 // 1st argument: Some
199 $test_string = <<<EOF
200 TTP://wwW.Example.Org#TTP_and_www
201 https://nasty.example.org:443/foo/xxx#port443/slash
202 sftp://foobar.example.org:80/dfsdfs#ftp_bat_port80
203 ftp://cnn.example.com&story=breaking_news@10.0.0.1/top_story.htm
204 http://192.168.1.4:443#IPv4
206 $results = uri_pickup_normalize(uri_pickup($test_string));
207 $this->assertEquals(5, count($results));
209 // ttp://wwW.Example.Org:80#TTP_and_www
210 $this->assertEquals('http', $results[0]['scheme']);
211 $this->assertEquals('', $results[0]['userinfo']);
212 $this->assertEquals('example.org', $results[0]['host']);
213 $this->assertEquals('', $results[0]['port']);
214 $this->assertEquals('/', $results[0]['path']);
215 $this->assertEquals('', $results[0]['file']);
216 $this->assertEquals('', $results[0]['query']);
217 $this->assertEquals('ttp_and_www', $results[0]['fragment']);
219 // https://nasty.example.org:443/foo/xxx#port443/slash
220 $this->assertEquals('https', $results[1]['scheme']);
221 $this->assertEquals('', $results[1]['userinfo']);
222 $this->assertEquals('nasty.example.org', $results[1]['host']);
223 $this->assertEquals('', $results[1]['port']);
224 $this->assertEquals('/foo/', $results[1]['path']);
225 $this->assertEquals('xxx', $results[1]['file']);
226 $this->assertEquals('', $results[1]['query']);
227 $this->assertEquals('port443', $results[1]['fragment']);
229 // sftp://foobar.example.org:80/dfsdfs#sftp_bat_port80
230 $this->assertEquals('sftp', $results[2]['scheme']);
231 $this->assertEquals('', $results[2]['userinfo']);
232 $this->assertEquals('foobar.example.org', $results[2]['host']);
233 $this->assertEquals('80', $results[2]['port']);
234 $this->assertEquals('/', $results[2]['path']);
235 $this->assertEquals('dfsdfs', $results[2]['file']);
236 $this->assertEquals('', $results[2]['query']);
237 $this->assertEquals('ftp_bat_port80', $results[2]['fragment']);
239 // ftp://cnn.example.com&story=breaking_news@10.0.0.1/top_story.htm
240 $this->assertEquals('ftp', $results[3]['scheme']);
241 $this->assertEquals('cnn.example.com&story=breaking_news', $results[3]['userinfo']);
242 $this->assertEquals('10.0.0.1', $results[3]['host']);
243 $this->assertEquals('', $results[3]['port']);
244 $this->assertEquals('/', $results[3]['path']);
245 $this->assertEquals('top_story.htm', $results[3]['file']);
246 $this->assertEquals('', $results[3]['query']);
247 $this->assertEquals('', $results[3]['fragment']);
250 function testFunc_scheme_normalize()
253 foreach($this->setup_string_null() as $key => $value){
254 $this->assertEquals('', scheme_normalize($value), $key);
258 $this->assertEquals('http', scheme_normalize('HTTP'));
261 $this->assertEquals('pop3', scheme_normalize('pop'));
262 $this->assertEquals('nntp', scheme_normalize('news'));
263 $this->assertEquals('imap', scheme_normalize('imap4'));
264 $this->assertEquals('nntps', scheme_normalize('snntp'));
265 $this->assertEquals('nntps', scheme_normalize('snews'));
266 $this->assertEquals('pop3s', scheme_normalize('spop3'));
267 $this->assertEquals('pop3s', scheme_normalize('pops'));
270 $this->assertEquals('http', scheme_normalize('ttp'));
271 $this->assertEquals('https', scheme_normalize('ttps'));
273 // Abbrevs considererd harmless
274 $this->assertEquals('', scheme_normalize('ttp', FALSE));
275 $this->assertEquals('', scheme_normalize('ttps', FALSE));
278 function testFunc_host_normalize()
281 foreach($this->setup_string_null() as $key => $value){
282 $this->assertEquals('', host_normalize($value), $key);
285 // Hostname is case-insensitive
286 $this->assertEquals('example.org', host_normalize('ExAMPle.ORG'));
288 // Cut 'www' (destructive)
289 $this->assertEquals('example.org', host_normalize('WWW.example.org'));
292 function testFunc_port_normalize()
294 $scheme = 'dont_care';
296 // 1st argument: Null
297 $this->assertEquals('', port_normalize(NULL, $scheme));
298 $this->assertEquals('', port_normalize(TRUE, $scheme));
299 $this->assertEquals('', port_normalize(FALSE, $scheme));
300 $this->assertEquals('', port_normalize(array('foobar'), $scheme));
301 $this->assertEquals('', port_normalize('', $scheme));
303 // 1st argument: Known port
304 $this->assertEquals('', port_normalize( -1, $scheme));
305 $this->assertEquals(0, port_normalize( 0, $scheme));
306 $this->assertEquals(1, port_normalize( 1, $scheme));
307 $this->assertEquals('', port_normalize( 21, 'ftp'));
308 $this->assertEquals('', port_normalize( 22, 'ssh'));
309 $this->assertEquals('', port_normalize( 23, 'telnet'));
310 $this->assertEquals('', port_normalize( 25, 'smtp'));
311 $this->assertEquals('', port_normalize( 69, 'tftp'));
312 $this->assertEquals('', port_normalize( 70, 'gopher'));
313 $this->assertEquals('', port_normalize( 79, 'finger'));
314 $this->assertEquals('', port_normalize( 80, 'http'));
315 $this->assertEquals('', port_normalize( 110, 'pop3'));
316 $this->assertEquals('', port_normalize( 115, 'sftp'));
317 $this->assertEquals('', port_normalize( 119, 'nntp'));
318 $this->assertEquals('', port_normalize( 143, 'imap'));
319 $this->assertEquals('', port_normalize( 194, 'irc'));
320 $this->assertEquals('', port_normalize( 210, 'wais'));
321 $this->assertEquals('', port_normalize( 443, 'https'));
322 $this->assertEquals('', port_normalize( 563, 'nntps'));
323 $this->assertEquals('', port_normalize( 873, 'rsync'));
324 $this->assertEquals('', port_normalize( 990, 'ftps'));
325 $this->assertEquals('', port_normalize( 992, 'telnets'));
326 $this->assertEquals('', port_normalize( 993, 'imaps'));
327 $this->assertEquals('', port_normalize( 994, 'ircs'));
328 $this->assertEquals('', port_normalize( 995, 'pop3s'));
329 $this->assertEquals('', port_normalize( 3306, 'mysql'));
330 $this->assertEquals(8080, port_normalize( 8080, $scheme));
331 $this->assertEquals(65535, port_normalize(65535, $scheme));
332 $this->assertEquals(65536, port_normalize(65536, $scheme)); // Seems not invalid in RFC
334 // 1st argument: Invalid type
335 $this->assertEquals('1x', port_normalize('001', $scheme) . 'x');
336 $this->assertEquals('', port_normalize('+0', $scheme));
337 $this->assertEquals('', port_normalize('0-1', $scheme)); // intval() says '0'
338 $this->assertEquals('', port_normalize('str', $scheme));
340 // 2nd and 3rd argument: Null
341 $this->assertEquals(80, port_normalize(80, NULL, TRUE));
342 $this->assertEquals(80, port_normalize(80, TRUE, TRUE));
343 $this->assertEquals(80, port_normalize(80, FALSE, TRUE));
344 $this->assertEquals(80, port_normalize(80, array('foobar'), TRUE));
345 $this->assertEquals(80, port_normalize(80, '', TRUE));
347 // 2nd and 3rd argument: Do $scheme_normalize
348 $this->assertEquals('', port_normalize(80, 'TTP', TRUE));
349 $this->assertEquals('', port_normalize(110, 'POP', TRUE));
350 $this->assertEquals(80, port_normalize(80, 'HTTP', FALSE));
353 function testFunc_path_normalize()
355 // 1st argument: Null
356 foreach($this->setup_string_null() as $key => $value){
357 $this->assertEquals('/', path_normalize($value), $key);
360 // 1st argument: CASE sensitive
361 $this->assertEquals('/ExAMPle', path_normalize('ExAMPle'));
362 $this->assertEquals('/#hoge', path_normalize('#hoge'));
363 $this->assertEquals('/a/b/c/d', path_normalize('/a/b/./c////./d'));
364 $this->assertEquals('/b/', path_normalize('/a/../../../b/'));
367 $this->assertEquals('\\b\\c\\d\\', path_normalize('\\a\\..\\b\\.\\c\\\\.\\d\\', '\\'));
368 $this->assertEquals('str1str3str', path_normalize('str1strstr2str..str3str', 'str'));
369 $this->assertEquals('/do/../nothing/', path_normalize('/do/../nothing/', TRUE));
370 $this->assertEquals('/do/../nothing/', path_normalize('/do/../nothing/', array('a')));
371 $this->assertEquals('', path_normalize(array('a'), array('b')));
374 function testFunc_file_normalize()
376 // 1st argument: Null
377 foreach($this->setup_string_null() as $key => $value){
378 $this->assertEquals('', file_normalize($value), $key);
381 // 1st argument: Cut DirectoryIndexes (Destructive)
401 // Apache 2.0.59 default 'index.html' variants
403 'index.html.cz.iso8859-2',
412 'index.html.he.iso8859-8',
413 'index.html.hr.iso8859-2',
415 'index.html.ja.iso2022-jp',
416 'index.html.ko.euc-kr',
417 'index.html.lb.utf8',
421 'index.html.po.iso8859-2',
424 'index.html.ru.cp866',
425 'index.html.ru.cp-1251',
426 'index.html.ru.iso-ru',
427 'index.html.ru.koi8-r',
428 'index.html.ru.utf8',
430 'index.html.var', // default
431 'index.html.zh-cn.gb2312',
432 'index.html.zh-tw.big5',
434 'index.html.po.iso8859-2',
435 'index.html.zh-tw.big5',
437 'index.ja.en.de.html',
441 'index.html.en.ja.ca.z',
443 $this->assertEquals('', file_normalize($arg));
446 //$this->assertEquals('foo/', file_normalize('foo/index.html'));
448 //$this->assertEquals('ExAMPle', file_normalize('ExAMPle'));
449 //$this->assertEquals('exe.exe', file_normalize('exe.exe'));
450 //$this->assertEquals('sample.html', file_normalize('sample.html.en'));
451 //$this->assertEquals('sample.html', file_normalize('sample.html.pt-br'));
452 //$this->assertEquals('sample.html', file_normalize('sample.html.po.iso8859-2'));
453 //$this->assertEquals('sample.html', file_normalize('sample.html.zh-tw.big5'));
456 function testFunc_query_normalize()
458 // 1st argument: Null
459 foreach($this->setup_string_null() as $key => $value){
460 $this->assertEquals('', query_normalize($value), $key);
463 $this->assertEquals('a=0dd&b&c&d&f=d', query_normalize('&&&&f=d&b&d&c&a=0dd'));
464 $this->assertEquals('eg=foobar', query_normalize('nothing==&eg=dummy&eg=padding&eg=foobar'));
467 function testFunc_generate_glob_regex()
469 // 1st argument: Null
470 foreach($this->setup_string_null() as $key => $value){
471 $this->assertEquals('', generate_glob_regex($value), $key);
474 $this->assertEquals('.*\.txt', generate_glob_regex('*.txt'));
475 $this->assertEquals('A.A', generate_glob_regex('A?A'));
478 function testFunc_generate_host_regex()
480 // 1st argument: Null
481 foreach($this->setup_string_null() as $key => $value){
482 $this->assertEquals('', generate_host_regex($value), $key);
485 $this->assertEquals('localhost', generate_host_regex('localhost'));
486 $this->assertEquals('example\.org', generate_host_regex('example.org'));
487 $this->assertEquals('(?:.*\.)?example\.org', generate_host_regex('.example.org'));
488 $this->assertEquals('.*\.example\.org', generate_host_regex('*.example.org'));
489 $this->assertEquals('.*\..*\.example\.org', generate_host_regex('*.*.example.org'));
490 $this->assertEquals('10\.20\.30\.40', generate_host_regex('10.20.30.40'));
492 // Should match with 192.168.0.0/16
493 //$this->assertEquals('192\.168\.', generate_host_regex('192.168.'));
496 function testFunc_get_blocklist()
498 if (! defined('SPAM_INI_FILE') || ! file_exists(SPAM_INI_FILE)) {
499 $this->fail('SPAM_INI_FILE not defined or not found');
503 // get_blocklist_add()
506 get_blocklist_add($array, 'foo', 'bar');
507 $this->assertEquals(1, count($array));
508 $this->assertEquals('bar', $array['foo']);
510 get_blocklist_add($array, 'hoge', 'fuga');
511 $this->assertEquals(2, count($array));
512 $this->assertEquals('bar', $array['foo']);
513 $this->assertEquals('fuga', $array['hoge']);
515 get_blocklist_add($array, -1, '*.txt');
516 $this->assertEquals(3, count($array));
517 $this->assertEquals('bar', $array['foo']);
518 $this->assertEquals('fuga', $array['hoge']);
519 $this->assertEquals('/^.*\.txt$/i', $array['*.txt']);
523 $array = get_blocklist();
524 $this->assertTrue(isset($array['C']));
525 $this->assertTrue(isset($array['goodhost']));
527 $array = get_blocklist('B-1');
528 $this->assertTrue(isset($array['*.blogspot.com']));
530 $array = get_blocklist('goodhost');
531 $this->assertTrue(isset($array['IANA-examples']));
535 function testFunc_array_joinbranch_leaf()
537 // 1st argument: Null
538 foreach($this->setup_string_null() as $value){
540 $result = array_joinbranch_leaf($array);
541 $this->assertEquals(array(), $result);
542 $this->assertEquals($value, $array);
546 $array = array(array());
547 $result = array_joinbranch_leaf($array);
548 $this->assertEquals(array(), $result);
549 $this->assertEquals(array(array()), $array);
551 $a = array('F' => array('B' => array('C' => array('d' => array('' => 'foobar')))));
552 $b = array('R' => array('S' => array('T' => array('U' => 'hoge' ))));
556 $result = array_joinbranch_leaf($array);
557 $this->assertEquals(array('F.B.C.d.' => 5 ), $result);
558 $this->assertEquals(array('F.B.C.d.' => 'foobar'), $array);
560 // Single, delim = '', limit
562 $result = array_joinbranch_leaf($array, '', 2);
563 $this->assertEquals(array('FBC' => 3), $result);
564 $this->assertEquals(array('FBC' => array('d' => array('' => 'foobar'))), $array);
566 // Single, delim = '#', reverse
568 $result = array_joinbranch_leaf($array, '#', 0, TRUE);
569 $this->assertEquals(array('#d#C#B#F' => 5 ), $result);
570 $this->assertEquals(array('#d#C#B#F' => 'foobar'), $array);
573 $array = array('I' => $a, '@' => $b);
574 $result = array_joinbranch_leaf($array);
584 '@.R.S.T.U' => 'hoge',
585 'I.F.B.C.d.' => 'foobar'