summaryrefslogtreecommitdiff
path: root/t
diff options
context:
space:
mode:
authorPierre Schmitz <pierre@archlinux.de>2008-08-15 01:29:47 +0200
committerPierre Schmitz <pierre@archlinux.de>2008-08-15 01:29:47 +0200
commit370e83bb0dfd0c70de268c93bf07ad5ee0897192 (patch)
tree491674f4c242e4d6ba0d04eafa305174c35a3391 /t
parentf4debf0f12d0524d2b2427c55ea3f16b680fad97 (diff)
Update auf 1.13.0
Diffstat (limited to 't')
-rw-r--r--t/.htaccess1
-rw-r--r--t/README8
-rw-r--r--t/Search.inc165
-rw-r--r--t/Test.php496
-rw-r--r--t/inc/Database.t55
-rw-r--r--t/inc/Global.t154
-rw-r--r--t/inc/IP.t3
-rw-r--r--t/inc/ImageFunctions.t56
-rw-r--r--t/inc/Language.t30
-rw-r--r--t/inc/Licenses.t3
-rw-r--r--t/inc/LocalFile.t77
-rw-r--r--t/inc/Parser.t39
-rw-r--r--t/inc/Revision.t79
-rw-r--r--t/inc/Sanitizer.t3
-rw-r--r--t/inc/Search.t14
-rw-r--r--t/inc/Title.t3
-rw-r--r--t/inc/Xml.t3
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
diff --git a/t/README b/t/README
index 2bf42aba..b3b9f420 100644
--- a/t/README
+++ b/t/README
@@ -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
diff --git a/t/inc/IP.t b/t/inc/IP.t
index 82a61fe1..eb717252 100644
--- a/t/inc/IP.t
+++ b/t/inc/IP.t
@@ -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: */
-?>