diff options
author | Pierre Schmitz <pierre@archlinux.de> | 2008-08-15 01:29:47 +0200 |
---|---|---|
committer | Pierre Schmitz <pierre@archlinux.de> | 2008-08-15 01:29:47 +0200 |
commit | 370e83bb0dfd0c70de268c93bf07ad5ee0897192 (patch) | |
tree | 491674f4c242e4d6ba0d04eafa305174c35a3391 /t | |
parent | f4debf0f12d0524d2b2427c55ea3f16b680fad97 (diff) |
Update auf 1.13.0
Diffstat (limited to 't')
-rw-r--r-- | t/.htaccess | 1 | ||||
-rw-r--r-- | t/README | 8 | ||||
-rw-r--r-- | t/Search.inc | 165 | ||||
-rw-r--r-- | t/Test.php | 496 | ||||
-rw-r--r-- | t/inc/Database.t | 55 | ||||
-rw-r--r-- | t/inc/Global.t | 154 | ||||
-rw-r--r-- | t/inc/IP.t | 3 | ||||
-rw-r--r-- | t/inc/ImageFunctions.t | 56 | ||||
-rw-r--r-- | t/inc/Language.t | 30 | ||||
-rw-r--r-- | t/inc/Licenses.t | 3 | ||||
-rw-r--r-- | t/inc/LocalFile.t | 77 | ||||
-rw-r--r-- | t/inc/Parser.t | 39 | ||||
-rw-r--r-- | t/inc/Revision.t | 79 | ||||
-rw-r--r-- | t/inc/Sanitizer.t | 3 | ||||
-rw-r--r-- | t/inc/Search.t | 14 | ||||
-rw-r--r-- | t/inc/Title.t | 3 | ||||
-rw-r--r-- | t/inc/Xml.t | 3 |
17 files changed, 1157 insertions, 32 deletions
diff --git a/t/.htaccess b/t/.htaccess new file mode 100644 index 00000000..3a428827 --- /dev/null +++ b/t/.htaccess @@ -0,0 +1 @@ +Deny from all @@ -6,17 +6,15 @@ F<t> - MediaWiki test tree This is the MediaWiki test tree (well, one of them), tests in this directory are self-contained programs that produce TAP output via the -F<Test.php> module (/trunk/Test/Test.php) (see +F<Test.php> module (/trunk/phase3/t/Test.php) (see http://search.cpan.org/~petdance/TAP-1.00/TAP.pm#THE_TAP_FORMAT for information on the TAP format). =head1 Running the tests -You'll need F<Test.php> to run the tests, it lives in the -F<trunk/Test> directory and can be copied or linked to the F<phase3> -directory. +To run all tests, you can run - ln -s ../Test/Test.php . + make test Since the tests are self-contained PHP programs you can run them (Xml.t here) as: diff --git a/t/Search.inc b/t/Search.inc new file mode 100644 index 00000000..fa8a8b97 --- /dev/null +++ b/t/Search.inc @@ -0,0 +1,165 @@ +<?php + +$wgCommandLineMode = true; +$self = 'Search.t'; +define( 'MEDIAWIKI', true ); +require 't/Test.php'; +require 'includes/Defines.php'; +require 'includes/ProfilerStub.php'; +require 'LocalSettings.php'; +require 'AdminSettings.php'; +require 'includes/Setup.php'; + +function buildTestDatabase( $tables ) { + global $wgDBprefix, $wgDBserver, $wgDBadminuser, $wgDBadminpassword, $wgDBname, $wgDBtype; + $oldPrefix = $wgDBprefix; + $wgDBprefix = 'parsertest'; + $class = 'Database' . ucfirst( $wgDBtype ); + $db = new $class ( + $wgDBserver, + $wgDBadminuser, + $wgDBadminpassword, + $wgDBname ); + if( $db->isOpen() ) { + if ( !( stristr( $db->getSoftwareLink(), 'MySQL') && version_compare( $db->getServerVersion(), '4.1', '<' ) ) ) { + # Database that supports CREATE TABLE ... LIKE + foreach ($tables as $tbl) { + $newTableName = $db->tableName( $tbl ); + #$tableName = $oldPrefix . $tbl; + $tableName = $tbl; + $db->query("CREATE TEMPORARY TABLE $newTableName (LIKE $tableName)"); + } + } else { + # Hack for MySQL versions < 4.1, which don't support + # "CREATE TABLE ... LIKE". Note that + # "CREATE TEMPORARY TABLE ... SELECT * FROM ... LIMIT 0" + # would not create the indexes we need.... + foreach ($tables as $tbl) { + $res = $db->query("SHOW CREATE TABLE $tbl"); + $row = $db->fetchRow($res); + $create = $row[1]; + $create_tmp = preg_replace('/CREATE TABLE `(.*?)`/', 'CREATE TEMPORARY TABLE `' + . $wgDBprefix . '\\1`', $create); + if ($create === $create_tmp) { + # Couldn't do replacement + wfDie( "could not create temporary table $tbl" ); + } + $db->query($create_tmp); + } + + } + return $db; + } else { + // Something amiss + return null; + } +} + +class SearchEngineTest { + var $db, $search; + + function __construct( SearchEngine $search ){ + $this->search = $search; + $this->db = $this->search->db; + } + + function insertSearchData() { + $this->db->safeQuery( <<<END + INSERT INTO ! (page_id,page_namespace,page_title,page_latest) + VALUES (1, 0, 'Main_Page', 1), + (2, 1, 'Main_Page', 2), + (3, 0, 'Smithee', 3), + (4, 1, 'Smithee', 4), + (5, 0, 'Unrelated_page', 5), + (6, 0, 'Another_page', 6), + (7, 4, 'Help', 7), + (8, 0, 'Thppt', 8), + (9, 0, 'Alan_Smithee', 9), + (10, 0, 'Pages', 10) +END + , $this->db->tableName( 'page' ) ); + $this->db->safeQuery( <<<END + INSERT INTO ! (rev_id,rev_page) + VALUES (1, 1), + (2, 2), + (3, 3), + (4, 4), + (5, 5), + (6, 6), + (7, 7), + (8, 8), + (9, 9), + (10, 10) +END + , $this->db->tableName( 'revision' ) ); + $this->db->safeQuery( <<<END + INSERT INTO ! (old_id,old_text) + VALUES (1, 'This is a main page'), + (2, 'This is a talk page to the main page, see [[smithee]]'), + (3, 'A smithee is one who smiths. See also [[Alan Smithee]]'), + (4, 'This article sucks.'), + (5, 'Nothing in this page is about the S word.'), + (6, 'This page also is unrelated.'), + (7, 'Help me!'), + (8, 'Blah blah'), + (9, 'yum'), + (10,'are food') +END + , $this->db->tableName( 'text' ) ); + $this->db->safeQuery( <<<END + INSERT INTO ! (si_page,si_title,si_text) + VALUES (1, 'main page', 'this is a main page'), + (2, 'main page', 'this is a talk page to the main page, see smithee'), + (3, 'smithee', 'a smithee is one who smiths see also alan smithee'), + (4, 'smithee', 'this article sucks'), + (5, 'unrelated page', 'nothing in this page is about the s word'), + (6, 'another page', 'this page also is unrelated'), + (7, 'help', 'help me'), + (8, 'thppt', 'blah blah'), + (9, 'alan smithee', 'yum'), + (10, 'pages', 'are food') +END + , $this->db->tableName( 'searchindex' ) ); + } + + function fetchIds( $results ) { + $matches = array(); + while( $row = $results->next() ) { + $matches[] = $row->getTitle()->getPrefixedText(); + } + $results->free(); + # Search is not guaranteed to return results in a certain order; + # sort them numerically so we will compare simply that we received + # the expected matches. + sort( $matches ); + return $matches; + } + + function run(){ + if( is_null( $this->db ) ){ + fail( "Can't find a database to test with." ); + return; + } + + $this->insertSearchData(); + plan( 4 ); + + $exp = array( 'Smithee' ); + $got = $this->fetchIds( $this->search->searchText( 'smithee' ) ); + is( $got, $exp, "Plain search" ); + + $exp = array( 'Alan Smithee', 'Smithee' ); + $got = $this->fetchIds( $this->search->searchTitle( 'smithee' ) ); + is( $got, $exp, "Title search" ); + + $this->search->setNamespaces( array( 0, 1, 4 ) ); + + $exp = array( 'Smithee', 'Talk:Main Page', ); + $got = $this->fetchIds( $this->search->searchText( 'smithee' ) ); + is( $got, $exp, "Power search" ); + + $exp = array( 'Alan Smithee', 'Smithee', 'Talk:Smithee', ); + $got = $this->fetchIds( $this->search->searchTitle( 'smithee' ) ); + is( $got, $exp, "Title power search" ); + } +}
\ No newline at end of file diff --git a/t/Test.php b/t/Test.php new file mode 100644 index 00000000..7904f3ba --- /dev/null +++ b/t/Test.php @@ -0,0 +1,496 @@ +<?php +# See the end of this file for documentation + +# The latest release of this test framework can always be found on CPAN: +# http://search.cpan.org/search?query=Test.php + +register_shutdown_function('_test_ends'); + +$__Test = array( + # How many tests are planned + 'planned' => null, + + # How many tests we've run, if 'planned' is still null by the time we're + # done we report the total count at the end + 'run' => 0, + + # Are are we currently within todo_start()/todo_end() ? + 'todo' => array(), +); + +function plan($plan, $why = '') +{ + global $__Test; + + $__Test['planned'] = true; + + switch ($plan) + { + case 'no_plan': + $__Test['planned'] = false; + break; + case 'skip_all'; + printf("1..0%s\n", $why ? " # Skip $why" : ''); + exit; + default: + printf("1..%d\n", $plan); + break; + } +} + +function pass($desc = '') +{ + return _proclaim(true, $desc); +} + +function fail($desc = '') +{ + return _proclaim(false, $desc); +} + +function ok($cond, $desc = '') { + return _proclaim($cond, $desc); +} + +function is($got, $expected, $desc = '') { + $pass = $got == $expected; + return _proclaim($pass, $desc, /* todo */ false, $got, $expected); +} + +function isnt($got, $expected, $desc = '') { + $pass = $got != $expected; + return _proclaim($pass, $desc, /* todo */ false, $got, $expected, /* negated */ true); +} + +function like($got, $expected, $desc = '') { + $pass = preg_match($expected, $got); + return _proclaim($pass, $desc, /* todo */ false, $got, $expected); +} + +function unlike($got, $expected, $desc = '') { + $pass = !preg_match($expected, $got); + return _proclaim($pass, $desc, /* todo */ false, $got, $expected, /* negated */ true); +} + +function cmp_ok($got, $op, $expected, $desc = '') +{ + $pass = null; + + # See http://www.php.net/manual/en/language.operators.comparison.php + switch ($op) + { + case '==': + $pass = $got == $expected; + break; + case '===': + $pass = $got === $expected; + break; + case '!=': + case '<>': + $pass = $got != $expected; + break; + case '!==': + $pass = $got !== $expected; + break; + case '<': + $pass = $got < $expected; + break; + case '>': + $pass = $got > $expected; + break; + case '<=': + $pass = $got <= $expected; + break; + case '>=': + $pass = $got >= $expected; + break; + default: + if (function_exists($op)) { + $pass = $op($got, $expected); + } else { + die("No such operator or function $op\n"); + } + } + + return _proclaim($pass, $desc, /* todo */ false, $got, "$got $op $expected"); +} + +function diag($message) +{ + if (is_array($message)) + { + $message = implode("\n", $message); + } + + foreach (explode("\n", $message) as $line) + { + echo "# $line\n"; + } +} + +function include_ok($file, $desc = '') +{ + $pass = include $file; + return _proclaim($pass, $desc == '' ? "include $file" : $desc); +} + +function require_ok($file, $desc = '') +{ + $pass = require $file; + return _proclaim($pass, $desc == '' ? "require $file" : $desc); +} + +function is_deeply($got, $expected, $desc = '') +{ + $diff = _cmp_deeply($got, $expected); + $pass = is_null($diff); + + if (!$pass) { + $got = strlen($diff['gpath']) ? ($diff['gpath'] . ' = ' . $diff['got']) + : _repl($got); + $expected = strlen($diff['epath']) ? ($diff['epath'] . ' = ' . $diff['expected']) + : _repl($expected); + } + + _proclaim($pass, $desc, /* todo */ false, $got, $expected); +} + +function isa_ok($obj, $expected, $desc = '') +{ + $pass = is_a($obj, $expected); + _proclaim($pass, $desc, /* todo */ false, $name, $expected); +} + +function todo_start($why = '') +{ + global $__Test; + + $__Test['todo'][] = $why; +} + +function todo_end() +{ + global $__Test; + + if (count($__Test['todo']) == 0) { + die("todo_end() called without a matching todo_start() call"); + } else { + array_pop($__Test['todo']); + } +} + +# +# The code below consists of private utility functions for the above functions +# + +function _proclaim( + $cond, # bool + $desc = '', + $todo = false, + $got = null, + $expected = null, + $negate = false) { + + global $__Test; + + $__Test['run'] += 1; + + # We're in a TODO block via todo_start()/todo_end(). TODO via specific + # functions is currently unimplemented and will probably stay that way + if (count($__Test['todo'])) { + $todo = true; + } + + # Everything after the first # is special, so escape user-supplied messages + $desc = str_replace('#', '\\#', $desc); + $desc = str_replace("\n", '\\n', $desc); + + $ok = $cond ? "ok" : "not ok"; + $directive = ''; + + if ($todo) { + $todo_idx = count($__Test['todo']) - 1; + $directive .= ' # TODO ' . $__Test['todo'][$todo_idx]; + } + + printf("%s %d %s%s\n", $ok, $__Test['run'], $desc, $directive); + + # report a failure + if (!$cond) { + # Every public function in this file calls _proclaim so our culprit is + # the second item in the stack + $caller = debug_backtrace(); + $call = $caller['1']; + + diag( + sprintf(" Failed%stest '%s'\n in %s at line %d\n got: %s\n expected: %s", + $todo ? ' TODO ' : ' ', + $desc, + $call['file'], + $call['line'], + $got, + $expected + ) + ); + } + + return $cond; +} + +function _test_ends() +{ + global $__Test; + + if (count($__Test['todo']) != 0) { + $todos = join("', '", $__Test['todo']); + die("Missing todo_end() for '$todos'"); + } + + if (!$__Test['planned']) { + printf("1..%d\n", $__Test['run']); + } +} + +# +# All of the below is for is_deeply() +# + +function _repl($obj, $deep = true) { + if (is_string($obj)) { + return "'" . $obj . "'"; + } else if (is_numeric($obj)) { + return $obj; + } else if (is_null($obj)) { + return 'null'; + } else if (is_bool($obj)) { + return $obj ? 'true' : 'false'; + } else if (is_array($obj)) { + return _repl_array($obj, $deep); + }else { + return gettype($obj); + } +} + +function _diff($gpath, $got, $epath, $expected) { + return array( + 'gpath' => $gpath, + 'got' => $got, + 'epath' => $epath, + 'expected' => $expected + ); +} + +function _idx($obj, $path = '') { + return $path . '[' . _repl($obj) . ']'; +} + +function _cmp_deeply($got, $exp, $path = '') { + if (is_array($exp)) { + + if (!is_array($got)) { + return _diff($path, _repl($got), $path, _repl($exp)); + } + + $gk = array_keys($got); + $ek = array_keys($exp); + $mc = max(count($gk), count($ek)); + + for ($el = 0; $el < $mc; $el++) { + # One array shorter than the other? + if ($el >= count($ek)) { + return _diff(_idx($gk[$el], $path), _repl($got[$gk[$el]]), + 'missing', 'nothing'); + } else if ($el >= count($gk)) { + return _diff('missing', 'nothing', + _idx($ek[$el], $path), _repl($exp[$ek[$el]])); + } + + # Keys differ? + if ($gk[$el] != $ek[$el]) { + return _diff(_idx($gk[$el], $path), _repl($got[$gk[$el]]), + _idx($ek[$el], $path), _repl($exp[$ek[$el]])); + } + + # Recurse + $rc = _cmp_deeply($got[$gk[$el]], $exp[$ek[$el]], _idx($gk[$el], $path)); + if (!is_null($rc)) { + return $rc; + } + } + } + else { + # Default to serialize hack + if (serialize($got) != serialize($exp)) { + return _diff($path, _repl($got), $path, _repl($exp)); + } + } + + return null; +} + +function _plural($n, $singular, $plural = null) { + if (is_null($plural)) { + $plural = $singular . 's'; + } + return $n == 1 ? "$n $singular" : "$n $plural"; +} + +function _repl_array($obj, $deep) { + if ($deep) { + $slice = array_slice($obj, 0, 3); # Increase from 3 to show more + $repl = array(); + $next = 0; + foreach ($slice as $idx => $el) { + $elrep = _repl($el, false); + if (is_numeric($idx) && $next == $idx) { + // Numeric index + $next++; + } else { + // Out of sequence or non-numeric + $elrep = _repl($idx, false) . ' => ' . $elrep; + } + $repl[] = $elrep; + } + $more = count($obj) - count($slice); + if ($more > 0) { + $repl[] = '... ' . _plural($more, 'more element') . ' ...'; + } + return 'array(' . join(', ', $repl) . ')'; + } + else { + return 'array(' . count($obj) . ')'; + } +} + +/* + +=head1 NAME + +Test.php - TAP test framework for PHP with a L<Test::More>-like interface + +=head1 SYNOPSIS + + #!/usr/bin/env php + <?php + require 'Test.php'; + + plan($num); # plan $num tests + # or + plan('no_plan'); # We don't know how many + # or + plan('skip_all'); # Skip all tests + # or + plan('skip_all', $reason); # Skip all tests with a reason + + diag('message in test output') # Trailing \n not required + + # $test_name is always optional and should be a short description of + # the test, e.g. "some_function() returns an integer" + + # Various ways to say "ok" + ok($got == $expected, $test_name); + + # Compare with == and != + is($got, $expected, $test_name); + isnt($got, $expected, $test_name); + + # Run a preg regex match on some data + like($got, $regex, $test_name); + unlike($got, $regex, $test_name); + + # Compare something with a given comparison operator + cmp_ok($got, '==', $expected, $test_name); + # Compare something with a comparison function (should return bool) + cmp_ok($got, $func, $expected, $test_name); + + # Recursively check datastructures for equalness + is_deeply($got, $expected, $test_name); + + # Always pass or fail a test under an optional name + pass($test_name); + fail($test_name); + + # TODO tests, these are expected to fail but won't fail the test run, + # unexpected success will be reported + todo_start("integer arithmetic still working"); + ok(1 + 2 == 3); + { + # TODOs can be nested + todo_start("string comparison still working") + is("foo", "bar"); + todo_end(); + } + todo_end(); + ?> + +=head1 DESCRIPTION + +F<Test.php> is an implementation of Perl's L<Test::More> for PHP. Like +Test::More it produces language agnostic TAP output (see L<TAP>) which +can then be gathered, formatted and summarized by a program that +understands TAP such as prove(1). + +=head1 HOWTO + +First place the F<Test.php> in the project root or somewhere else in +the include path where C<require> and C<include> will find it. + +Then make a place to put your tests in, it's customary to place TAP +tests in a directory named F<t> under the root but they can be +anywhere you like. Make a test in this directory or one of its subdirs +and try running it with php(1): + + $ php t/pass.t + 1..1 + ok 1 This dummy test passed + +The TAP output consists of very simple output, of course reading +larger output is going to be harder which is where prove(1) comes +in. prove is a harness program that reads test output and produces +reports based on it: + + $ prove t/pass.t + t/pass....ok + All tests successful. + Files=1, Tests=1, 0 wallclock secs ( 0.03 cusr + 0.02 csys = 0.05 CPU) + +To run all the tests in the F<t> directory recursively use C<prove -r +t>. This can be put in a F<Makefile> under a I<test> target, for +example: + + test: Test.php + prove -r t + +For reference the example test file above looks like this, the shebang +on the first line is needed so that prove(1) and other test harness +programs know they're dealing with a PHP file. + + #!/usr/bin/env php + <?php + + require 'Test.php'; + + plan(1); + pass('This dummy test passed'); + ?> + +=head1 SEE ALSO + +L<TAP> - The TAP protocol + +=head1 AUTHOR + +E<AElig>var ArnfjE<ouml>rE<eth> Bjarmason <avar@cpan.org> and Andy Armstrong <andy@hexten.net> + +=head1 LICENSING + +The author or authors of this code dedicate any and all copyright +interest in this code to the public domain. We make this dedication +for the benefit of the public at large and to the detriment of our +heirs and successors. We intend this dedication to be an overt act of +relinquishment in perpetuity of all present and future rights this +code under copyright law. + +=cut + +*/ diff --git a/t/inc/Database.t b/t/inc/Database.t new file mode 100644 index 00000000..5092be9d --- /dev/null +++ b/t/inc/Database.t @@ -0,0 +1,55 @@ +#!/usr/bin/env php +<?php + +define( 'MEDIAWIKI', true ); +require 't/Test.php'; + +require 'includes/Defines.php'; +require 'LocalSettings.php'; + +plan( 13 ); + +require_ok( 'includes/ProfilerStub.php' ); +require_ok( 'includes/GlobalFunctions.php' ); +require_ok( 'includes/Exception.php' ); +require_ok( 'includes/Database.php' ); + +$db = new Database( $wgDBserver, $wgDBuser, $wgDBpassword ); + +cmp_ok( $db->addQuotes( NULL ), '==', + 'NULL', 'Add quotes to NULL' ); + +cmp_ok( $db->addQuotes( 1234 ), '==', + "'1234'", 'Add quotes to int' ); + +cmp_ok( $db->addQuotes( 1234.5678 ), '==', + "'1234.5678'", 'Add quotes to float' ); + +cmp_ok( $db->addQuotes( 'string' ), '==', + "'string'", 'Add quotes to string' ); + +cmp_ok( $db->addQuotes( "string's cause trouble" ), '==', + "'string\'s cause trouble'", 'Add quotes to quoted string' ); + +$sql = $db->fillPrepared( + 'SELECT * FROM interwiki', array() ); +cmp_ok( $sql, '==', + 'SELECT * FROM interwiki', 'FillPrepared empty' ); + +$sql = $db->fillPrepared( + 'SELECT * FROM cur WHERE cur_namespace=? AND cur_title=?', + array( 4, "Snicker's_paradox" ) ); +cmp_ok( $sql, '==', + "SELECT * FROM cur WHERE cur_namespace='4' AND cur_title='Snicker\'s_paradox'", 'FillPrepared question' ); + +$sql = $db->fillPrepared( + 'SELECT user_id FROM ! WHERE user_name=?', + array( '"user"', "Slash's Dot" ) ); +cmp_ok( $sql, '==', + "SELECT user_id FROM \"user\" WHERE user_name='Slash\'s Dot'", 'FillPrepared quoted' ); + +$sql = $db->fillPrepared( + "SELECT * FROM cur WHERE cur_title='This_\\&_that,_WTF\\?\\!'", + array( '"user"', "Slash's Dot" ) ); +cmp_ok( $sql, '==', + "SELECT * FROM cur WHERE cur_title='This_&_that,_WTF?!'", 'FillPrepared raw' ); diff --git a/t/inc/Global.t b/t/inc/Global.t new file mode 100644 index 00000000..adf8d135 --- /dev/null +++ b/t/inc/Global.t @@ -0,0 +1,154 @@ +#!/usr/bin/env php +<?php + +define( 'MEDIAWIKI', true ); +require 't/Test.php'; + +require 'includes/Defines.php'; +require 'LocalSettings.php'; + +plan( 48 ); + +require_ok( 'includes/ProfilerStub.php' ); +require_ok( 'includes/GlobalFunctions.php' ); + +$wgReadOnly = null; +$wgReadOnlyFile = tempnam(wfTempDir(), "mwtest_readonly"); +unlink( $wgReadOnlyFile ); + +isnt( wfRandom(), wfRandom(), "Two differents random" ); + +is( wfUrlencode( "\xE7\x89\xB9\xE5\x88\xA5:Contributions/Foobar" ), + "%E7%89%B9%E5%88%A5:Contributions/Foobar", 'Urlencode' ); + +is( wfReadOnly(), false, 'Empty read only' ); + +is( wfReadOnly(), false, 'Empty read only, second time' ); + +$f = fopen( $wgReadOnlyFile, "wt" ); +fwrite( $f, 'Message' ); +fclose( $f ); +$wgReadOnly = null; + +is( wfReadOnly(), true, 'Read only file set' ); + +is( wfReadOnly(), true, 'Read only file set, second time' ); + +unlink( $wgReadOnlyFile ); +$wgReadOnly = null; + +is( wfReadOnly(), false, 'Read only reset' ); + +is( wfReadOnly(), false, 'Read only reset, second time' ); + + +is( wfQuotedPrintable( "\xc4\x88u legebla?", "UTF-8" ), + "=?UTF-8?Q?=C4=88u=20legebla=3F?=", 'Quoted printable' ); + +$start = wfTime(); +is( gettype( $start ), 'float', 'Time (type)' ); +$end = wfTime(); +cmp_ok( $end, '>', $start, 'Time' ); + +$arr = wfArrayToCGI( + array( 'baz' => 'AT&T', 'ignore' => '' ), + array( 'foo' => 'bar', 'baz' => 'overridden value' ) ); +is( $arr, "baz=AT%26T&foo=bar", 'Array to CGI' ); + +$mime = mimeTypeMatch( 'text/html', array( + 'application/xhtml+xml' => 1.0, + 'text/html' => 0.7, + 'text/plain' => 0.3 +) ); +is( $mime, 'text/html', 'Mime (1)' ); + +$mime = mimeTypeMatch( 'text/html', array( + 'image/*' => 1.0, + 'text/*' => 0.5 +) ); +is( $mime, 'text/*', 'Mime (2)' ); + +$mime = mimeTypeMatch( 'text/html', array( '*/*' => 1.0 ) ); +is( $mime, '*/*', 'Mime (3)' ); + +$mime = mimeTypeMatch( 'text/html', array( + 'image/png' => 1.0, + 'image/svg+xml' => 0.5 +) ); +is( $mime, null, 'Mime (4)' ); + +$mime = wfNegotiateType( + array( 'application/xhtml+xml' => 1.0, + 'text/html' => 0.7, + 'text/plain' => 0.5, + 'text/*' => 0.2 ), + array( 'text/html' => 1.0 ) ); +is( $mime, 'text/html', 'Negotiate Mime (1)' ); + +$mime = wfNegotiateType( + array( 'application/xhtml+xml' => 1.0, + 'text/html' => 0.7, + 'text/plain' => 0.5, + 'text/*' => 0.2 ), + array( 'application/xhtml+xml' => 1.0, + 'text/html' => 0.5 ) ); +is( $mime, 'application/xhtml+xml', 'Negotiate Mime (2)' ); + +$mime = wfNegotiateType( + array( 'text/html' => 1.0, + 'text/plain' => 0.5, + 'text/*' => 0.5, + 'application/xhtml+xml' => 0.2 ), + array( 'application/xhtml+xml' => 1.0, + 'text/html' => 0.5 ) ); +is( $mime, 'text/html', 'Negotiate Mime (3)' ); + +$mime = wfNegotiateType( + array( 'text/*' => 1.0, + 'image/*' => 0.7, + '*/*' => 0.3 ), + array( 'application/xhtml+xml' => 1.0, + 'text/html' => 0.5 ) ); +is( $mime, 'text/html', 'Negotiate Mime (4)' ); + +$mime = wfNegotiateType( + array( 'text/*' => 1.0 ), + array( 'application/xhtml+xml' => 1.0 ) ); +is( $mime, null, 'Negotiate Mime (5)' ); + +$t = gmmktime( 12, 34, 56, 1, 15, 2001 ); +is( wfTimestamp( TS_MW, $t ), '20010115123456', 'TS_UNIX to TS_MW' ); +is( wfTimestamp( TS_UNIX, $t ), 979562096, 'TS_UNIX to TS_UNIX' ); +is( wfTimestamp( TS_DB, $t ), '2001-01-15 12:34:56', 'TS_UNIX to TS_DB' ); +$t = '20010115123456'; +is( wfTimestamp( TS_MW, $t ), '20010115123456', 'TS_MW to TS_MW' ); +is( wfTimestamp( TS_UNIX, $t ), 979562096, 'TS_MW to TS_UNIX' ); +is( wfTimestamp( TS_DB, $t ), '2001-01-15 12:34:56', 'TS_MW to TS_DB' ); +$t = '2001-01-15 12:34:56'; +is( wfTimestamp( TS_MW, $t ), '20010115123456', 'TS_DB to TS_MW' ); +is( wfTimestamp( TS_UNIX, $t ), 979562096, 'TS_DB to TS_UNIX' ); +is( wfTimestamp( TS_DB, $t ), '2001-01-15 12:34:56', 'TS_DB to TS_DB' ); + +$sets = array( + '' => '', + '/' => '', + '\\' => '', + '//' => '', + '\\\\' => '', + 'a' => 'a', + 'aaaa' => 'aaaa', + '/a' => 'a', + '\\a' => 'a', + '/aaaa' => 'aaaa', + '\\aaaa' => 'aaaa', + '/aaaa/' => 'aaaa', + '\\aaaa\\' => 'aaaa', + '\\aaaa\\' => 'aaaa', + '/mnt/upload3/wikipedia/en/thumb/8/8b/Zork_Grand_Inquisitor_box_cover.jpg/93px-Zork_Grand_Inquisitor_box_cover.jpg' => '93px-Zork_Grand_Inquisitor_box_cover.jpg', + 'C:\\Progra~1\\Wikime~1\\Wikipe~1\\VIEWER.EXE' => 'VIEWER.EXE', + 'Östergötland_coat_of_arms.png' => 'Östergötland_coat_of_arms.png', +); +foreach( $sets as $from => $to ) { + is( $to, wfBaseName( $from ), + "wfBaseName('$from') => '$to'"); +}
\ No newline at end of file @@ -1,7 +1,7 @@ #!/usr/bin/env php <?php -require 'Test.php'; +require 't/Test.php'; plan( 1120 ); @@ -58,4 +58,3 @@ foreach ( $private as $p ) { } /* vim: set filetype=php: */ -?> diff --git a/t/inc/ImageFunctions.t b/t/inc/ImageFunctions.t new file mode 100644 index 00000000..3a69bf77 --- /dev/null +++ b/t/inc/ImageFunctions.t @@ -0,0 +1,56 @@ +#!/usr/bin/env php +<?php + +define( 'MEDIAWIKI', true ); +require 't/Test.php'; + +require 'includes/Defines.php'; + +$vals = array( + array( + 'width' => 50, + 'height' => 50, + 'tests' => array( + 50 => 50, + 17 => 17, + 18 => 18 ) ), + array( + 'width' => 366, + 'height' => 300, + 'tests' => array( + 50 => 61, + 17 => 21, + 18 => 22 ) ), + array( + 'width' => 300, + 'height' => 366, + 'tests' => array( + 50 => 41, + 17 => 14, + 18 => 15 ) ), + array( + 'width' => 100, + 'height' => 400, + 'tests' => array( + 50 => 12, + 17 => 4, + 18 => 4 ) ) +); + +plan( 3 + 3 * count( $vals ) ); + +require_ok( 'includes/ProfilerStub.php' ); +require_ok( 'includes/GlobalFunctions.php' ); +require_ok( 'includes/ImageFunctions.php' ); + +foreach( $vals as $row ) { + extract( $row ); + foreach( $tests as $max => $expected ) { + $y = round( $expected * $height / $width ); + $result = wfFitBoxWidth( $width, $height, $max ); + $y2 = round( $result * $height / $width ); + is( $result, $expected, + "($width, $height, $max) wanted: {$expected}x{$y}, got: {$result}x{$y2}" ); + } +} + diff --git a/t/inc/Language.t b/t/inc/Language.t index df5e491d..125d67c1 100644 --- a/t/inc/Language.t +++ b/t/inc/Language.t @@ -1,18 +1,18 @@ #!/usr/bin/env php <?php -require 'Test.php'; +require 't/Test.php'; # Test offset usage for a given language::userAdjust -function test_userAdjust( $langObj, $date, $offset, $expected ) { +function test_userAdjust( &$langObj, $date, $offset, $expected ) { global $wgLocalTZoffset; $wgLocalTZoffset = $offset; cmp_ok( - $langObj->userAdjust( $date, '' ), + strval( $langObj->userAdjust( $date, '' ) ), '==', - $expected, - "User adjust $date by $offset minutes should give $expected" + strval( $expected ), + "User adjust {$date} by {$offset} minutes should give {$expected}" ); } @@ -31,25 +31,22 @@ $userAdjust_tests = array( array( 20061231235959, -60, 20061231225959 ), ); -plan( 7 + count($userAdjust_tests) ); +plan( count($userAdjust_tests) ); +define( 'MEDIAWIKI', 1 ); -require_ok( 'includes/Defines.php' ); +# Don't use require_ok as these files need global variables + +require 'includes/Defines.php'; +require 'includes/ProfilerStub.php'; -# require_ok() doesn't work for these, find out why -define( 'MEDIAWIKI', 1 ); require 'LocalSettings.php'; require 'includes/DefaultSettings.php'; +require 'includes/Setup.php'; + # Create a language object -require_ok( 'languages/Language.php' ); -require_ok( 'includes/Title.php' ); $wgContLang = $en = Language::factory( 'en' ); -# We need an user to test the lang -require_ok( 'includes/GlobalFunctions.php' ); -require_ok( 'includes/ProfilerStub.php' ); -require_ok( 'includes/Exception.php' ); -require_ok( 'includes/User.php' ); global $wgUser; $wgUser = new User(); @@ -59,4 +56,3 @@ foreach( $userAdjust_tests as $data ) { } /* vim: set filetype=php: */ -?> diff --git a/t/inc/Licenses.t b/t/inc/Licenses.t index 7e9f67c8..81e7abe9 100644 --- a/t/inc/Licenses.t +++ b/t/inc/Licenses.t @@ -1,6 +1,6 @@ #!/usr/bin/env php <?php -require 'Test.php'; +require 't/Test.php'; plan(3); @@ -24,4 +24,3 @@ $str = " #echo $lc->html; /* vim: set filetype=php: */ -?> diff --git a/t/inc/LocalFile.t b/t/inc/LocalFile.t new file mode 100644 index 00000000..09df9e19 --- /dev/null +++ b/t/inc/LocalFile.t @@ -0,0 +1,77 @@ +#!/usr/bin/env php +<?php + +define( 'MEDIAWIKI', true ); +require 't/Test.php'; + +require 'includes/Defines.php'; +require 'includes/ProfilerStub.php'; +require 'LocalSettings.php'; +require 'includes/Setup.php'; + +/** + * These tests should work regardless of $wgCapitalLinks + */ + +$info = array( + 'name' => 'test', + 'directory' => '/testdir', + 'url' => '/testurl', + 'hashLevels' => 2, + 'transformVia404' => false, +); + +plan( 35 ); + +$repo_hl0 = new LocalRepo( array( 'hashLevels' => 0 ) + $info ); +$repo_hl2 = new LocalRepo( array( 'hashLevels' => 2 ) + $info ); +$repo_lc = new LocalRepo( array( 'initialCapital' => false ) + $info ); + +$file_hl0 = $repo_hl0->newFile( 'test!' ); +$file_hl2 = $repo_hl2->newFile( 'test!' ); +$file_lc = $repo_lc->newFile( 'test!' ); + +is( $file_hl0->getHashPath(), '', 'Get hash path, hasLev 0' ); +is( $file_hl2->getHashPath(), 'a/a2/', 'Get hash path, hasLev 2' ); +is( $file_lc->getHashPath(), 'c/c4/', 'Get hash path, lc first' ); + +is( $file_hl0->getRel(), 'Test!', 'Get rel path, hasLev 0' ); +is( $file_hl2->getRel(), 'a/a2/Test!', 'Get rel path, hasLev 2' ); +is( $file_lc->getRel(), 'c/c4/test!', 'Get rel path, lc first' ); + +is( $file_hl0->getUrlRel(), 'Test%21', 'Get rel url, hasLev 0' ); +is( $file_hl2->getUrlRel(), 'a/a2/Test%21', 'Get rel url, hasLev 2' ); +is( $file_lc->getUrlRel(), 'c/c4/test%21', 'Get rel url, lc first' ); + +is( $file_hl0->getArchivePath(), '/testdir/archive', 'Get archive path, hasLev 0' ); +is( $file_hl2->getArchivePath(), '/testdir/archive/a/a2', 'Get archive path, hasLev 2' ); +is( $file_hl0->getArchivePath( '!' ), '/testdir/archive/!', 'Get archive path, hasLev 0' ); +is( $file_hl2->getArchivePath( '!' ), '/testdir/archive/a/a2/!', 'Get archive path, hasLev 2' ); + +is( $file_hl0->getThumbPath(), '/testdir/thumb/Test!', 'Get thumb path, hasLev 0' ); +is( $file_hl2->getThumbPath(), '/testdir/thumb/a/a2/Test!', 'Get thumb path, hasLev 2' ); +is( $file_hl0->getThumbPath( 'x' ), '/testdir/thumb/Test!/x', 'Get thumb path, hasLev 0' ); +is( $file_hl2->getThumbPath( 'x' ), '/testdir/thumb/a/a2/Test!/x', 'Get thumb path, hasLev 2' ); + +is( $file_hl0->getArchiveUrl(), '/testurl/archive', 'Get archive url, hasLev 0' ); +is( $file_hl2->getArchiveUrl(), '/testurl/archive/a/a2', 'Get archive url, hasLev 2' ); +is( $file_hl0->getArchiveUrl( '!' ), '/testurl/archive/%21', 'Get archive url, hasLev 0' ); +is( $file_hl2->getArchiveUrl( '!' ), '/testurl/archive/a/a2/%21', 'Get archive url, hasLev 2' ); + +is( $file_hl0->getThumbUrl(), '/testurl/thumb/Test%21', 'Get thumb url, hasLev 0' ); +is( $file_hl2->getThumbUrl(), '/testurl/thumb/a/a2/Test%21', 'Get thumb url, hasLev 2' ); +is( $file_hl0->getThumbUrl( 'x' ), '/testurl/thumb/Test%21/x', 'Get thumb url, hasLev 0' ); +is( $file_hl2->getThumbUrl( 'x' ), '/testurl/thumb/a/a2/Test%21/x', 'Get thumb url, hasLev 2' ); + +is( $file_hl0->getArchiveVirtualUrl(), 'mwrepo://test/public/archive', 'Get archive virtual url, hasLev 0' ); +is( $file_hl2->getArchiveVirtualUrl(), 'mwrepo://test/public/archive/a/a2', 'Get archive virtual url, hasLev 2' ); +is( $file_hl0->getArchiveVirtualUrl( '!' ), 'mwrepo://test/public/archive/%21', 'Get archive virtual url, hasLev 0' ); +is( $file_hl2->getArchiveVirtualUrl( '!' ), 'mwrepo://test/public/archive/a/a2/%21', 'Get archive virtual url, hasLev 2' ); + +is( $file_hl0->getThumbVirtualUrl(), 'mwrepo://test/public/thumb/Test%21', 'Get thumb virtual url, hasLev 0' ); +is( $file_hl2->getThumbVirtualUrl(), 'mwrepo://test/public/thumb/a/a2/Test%21', 'Get thumb virtual url, hasLev 2' ); +is( $file_hl0->getThumbVirtualUrl( '!' ), 'mwrepo://test/public/thumb/Test%21/%21', 'Get thumb virtual url, hasLev 0' ); +is( $file_hl2->getThumbVirtualUrl( '!' ), 'mwrepo://test/public/thumb/a/a2/Test%21/%21', 'Get thumb virtual url, hasLev 2' ); + +is( $file_hl0->getUrl(), '/testurl/Test%21', 'Get url, hasLev 0' ); +is( $file_hl2->getUrl(), '/testurl/a/a2/Test%21', 'Get url, hasLev 2' ); diff --git a/t/inc/Parser.t b/t/inc/Parser.t new file mode 100644 index 00000000..9df21d9a --- /dev/null +++ b/t/inc/Parser.t @@ -0,0 +1,39 @@ +#!/usr/bin/env php +<?php + +require 't/Test.php'; +require 'maintenance/parserTests.inc'; + +error_reporting( E_ALL ^ E_NOTICE ); + +class ProveTestRecorder extends TestRecorder { + + function record( $name, $res ){} + function report(){} + function reportPercentage( $success, $total ){} +} + +class ProveParserTest extends ParserTest { + + function showSuccess( $desc ){ + pass( $desc ); + } + + function showFailure( $desc, $exp, $got ){ + _proclaim( false, $desc, false, $got, $exp ); + } + + function showRunFile( $path ){} +} + +$options = array( 'quick', 'quiet', 'compare' ); +$tester = new ProveParserTest(); +$tester->showProgress = false; +$tester->showFailure = false; +$tester->recorder = new ProveTestRecorder( $tester->term ); + +// Do not output the number of tests, if will be done automatically at the end + +$tester->runTestsFromFiles( $wgParserTestFiles ); + +/* vim: set filetype=php: */ diff --git a/t/inc/Revision.t b/t/inc/Revision.t new file mode 100644 index 00000000..a6f2849b --- /dev/null +++ b/t/inc/Revision.t @@ -0,0 +1,79 @@ +#!/usr/bin/env php +<?php + +define( 'MEDIAWIKI', true ); +require 't/Test.php'; + +plan( 19 ); + +require_ok( 'includes/Defines.php' ); +require_ok( 'includes/ProfilerStub.php' ); +require_ok( 'includes/GlobalFunctions.php' ); +require_ok( 'languages/Language.php' ); +require_ok( 'includes/Revision.php' ); + +$wgContLang = Language::factory( 'en' ); +$wgLegacyEncoding = false; +$wgCompressRevisions = false; +$wgInputEncoding = 'utf-8'; +$wgOutputEncoding = 'utf-8'; + +$row = new stdClass; +$row->old_flags = ''; +$row->old_text = 'This is a bunch of revision text.'; +cmp_ok( Revision::getRevisionText( $row ), '==', + 'This is a bunch of revision text.', 'Get revision text' ); + +$row = new stdClass; +$row->old_flags = 'gzip'; +$row->old_text = gzdeflate( 'This is a bunch of revision text.' ); +cmp_ok( Revision::getRevisionText( $row ), '==', + 'This is a bunch of revision text.', 'Get revision text with gzip compression' ); + +$wgLegacyEncoding = 'iso-8859-1'; + +$row = new stdClass; +$row->old_flags = 'utf-8'; +$row->old_text = "Wiki est l'\xc3\xa9cole superieur !"; +cmp_ok( Revision::getRevisionText( $row ), '==', + "Wiki est l'\xc3\xa9cole superieur !", 'Get revision text utf-8 native' ); + +$row = new stdClass; +$row->old_flags = ''; +$row->old_text = "Wiki est l'\xe9cole superieur !"; +cmp_ok( Revision::getRevisionText( $row ), '==', + "Wiki est l'\xc3\xa9cole superieur !", 'Get revision text utf-8 legacy' ); + +$row = new stdClass; +$row->old_flags = 'gzip,utf-8'; +$row->old_text = gzdeflate( "Wiki est l'\xc3\xa9cole superieur !" ); +cmp_ok( Revision::getRevisionText( $row ), '==', + "Wiki est l'\xc3\xa9cole superieur !", 'Get revision text utf-8 native and gzip' ); + +$row = new stdClass; +$row->old_flags = 'gzip'; +$row->old_text = gzdeflate( "Wiki est l'\xe9cole superieur !" ); +cmp_ok( Revision::getRevisionText( $row ), '==', + "Wiki est l'\xc3\xa9cole superieur !", 'Get revision text utf-8 native and gzip' ); + +$row = new stdClass; +$row->old_text = "Wiki est l'\xc3\xa9cole superieur !"; +$row->old_flags = Revision::compressRevisionText( $row->old_text ); +like( $row->old_flags, '/utf-8/', "Flags should contain 'utf-8'" ); +unlike( $row->old_flags, '/gzip/', "Flags should not contain 'gzip'" ); +cmp_ok( $row->old_text, '==', + "Wiki est l'\xc3\xa9cole superieur !", "Direct check" ); +cmp_ok( Revision::getRevisionText( $row ), '==', + "Wiki est l'\xc3\xa9cole superieur !", "getRevisionText" ); + +$wgCompressRevisions = true; + +$row = new stdClass; +$row->old_text = "Wiki est l'\xc3\xa9cole superieur !"; +$row->old_flags = Revision::compressRevisionText( $row->old_text ); +like( $row->old_flags, '/utf-8/', "Flags should contain 'utf-8'" ); +like( $row->old_flags, '/gzip/', "Flags should contain 'gzip'" ); +cmp_ok( gzinflate( $row->old_text ), '==', + "Wiki est l'\xc3\xa9cole superieur !", "Direct check" ); +cmp_ok( Revision::getRevisionText( $row ), '==', + "Wiki est l'\xc3\xa9cole superieur !", "getRevisionText" ); diff --git a/t/inc/Sanitizer.t b/t/inc/Sanitizer.t index 601f8a88..ae2c9a23 100644 --- a/t/inc/Sanitizer.t +++ b/t/inc/Sanitizer.t @@ -1,7 +1,7 @@ #!/usr/bin/env php <?php -require 'Test.php'; +require 't/Test.php'; plan( 13 ); @@ -62,4 +62,3 @@ cmp_ok( ); /* vim: set filetype=php: */ -?> diff --git a/t/inc/Search.t b/t/inc/Search.t new file mode 100644 index 00000000..2f06dcd9 --- /dev/null +++ b/t/inc/Search.t @@ -0,0 +1,14 @@ +#!/usr/bin/env php +<?php + +require 't/Search.inc'; + +$db = buildTestDatabase( array( 'page', 'revision', 'text', 'searchindex' ) ); +if( is_null( $db ) ){ + fail( 'no db' ); + exit(); +} +$t = new SearchEngineTest( new SearchMySQL( $db ) ); +$t->run(); + +/* vim: set filetype=php: */ diff --git a/t/inc/Title.t b/t/inc/Title.t index 53ebfcd8..7373b9f2 100644 --- a/t/inc/Title.t +++ b/t/inc/Title.t @@ -1,7 +1,7 @@ #!/usr/bin/env php <?php -require 'Test.php'; +require 't/Test.php'; plan( 2 + 255 ); @@ -30,4 +30,3 @@ foreach ( range( 1, 255 ) as $num ) { } /* vim: set filetype=php: */ -?> diff --git a/t/inc/Xml.t b/t/inc/Xml.t index 527cd7f5..b7cef881 100644 --- a/t/inc/Xml.t +++ b/t/inc/Xml.t @@ -1,7 +1,7 @@ #!/usr/bin/env php <?php -require 'Test.php'; +require 't/Test.php'; plan( 8 ); @@ -54,4 +54,3 @@ cmp_ok( cmp_ok( Xml::closeElement( 'element' ), '==', '</element>', 'closeElement() shortcut' ); /* vim: set filetype=php: */ -?> |