FAST_TESTS=$(BASE_TEST) $(INCLUDES_TESTS)
ALL_TESTS=$(BASE_TEST) $(INCLUDES_TESTS) $(MAINTENANCE_TESTS)
-test: Test.php
+test: t/Test.php
$(PROVE_BIN) $(ALL_TESTS)
-fast: Test.php
+fast: t/Test.php
$(PROVE_BIN) $(FAST_TESTS)
-verbose: Test.php
+verbose: t/Test.php
$(PROVE_BIN) -v $(ALL_TESTS) | egrep -v '^ok'
+++ /dev/null
-<?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
-
-*/
-
-?>
} else {
global $IP;
$relative = wfRelativePath( $filename, $IP );
- print $this->term->color( 1 ) .
- "Reading tests from \"$relative\"..." .
- $this->term->reset() .
- "\n";
+ $this->showRunFile( $relative );
}
$data = array();
/**
* "Running test $desc..."
*/
- private function showTesting( $desc ) {
+ protected function showTesting( $desc ) {
print "Running test $desc... ";
}
* @param string $desc The test name
* @return bool
*/
- private function showSuccess( $desc ) {
+ protected function showSuccess( $desc ) {
if( $this->showProgress ) {
print $this->term->color( '1;32' ) . 'PASSED' . $this->term->reset() . "\n";
}
* @param string $html Actual HTML output
* @return bool
*/
- private function showFailure( $desc, $result, $html ) {
+ protected function showFailure( $desc, $result, $html ) {
if( $this->showFailure ) {
if( !$this->showProgress ) {
# In quiet mode we didn't show the 'Testing' message before the
* @param string $outFileTail Tailing for the output file name
* @return string
*/
- private function quickDiff( $input, $output, $inFileTail='expected', $outFileTail='actual' ) {
+ protected function quickDiff( $input, $output, $inFileTail='expected', $outFileTail='actual' ) {
$prefix = wfTempDir() . "/mwParser-" . mt_rand();
$infile = "$prefix-$inFileTail";
* @param string $text
* @return string
*/
- private function colorDiff( $text ) {
+ protected function colorDiff( $text ) {
return preg_replace(
array( '/^(-.*)$/m', '/^(\+.*)$/m' ),
array( $this->term->color( 34 ) . '$1' . $this->term->reset(),
$text );
}
+ /**
+ * Show "Reading tests from ..."
+ *
+ * @param String $path
+ */
+ protected function showRunFile( $path ){
+ print $this->term->color( 1 ) .
+ "Reading tests from \"$path\"..." .
+ $this->term->reset() .
+ "\n";
+ }
+
/**
* Insert a temporary test article
* @param string $name the title, including any prefix
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:
--- /dev/null
+<?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
+
+*/
#!/usr/bin/env php
<?php
-require 'Test.php';
+require 't/Test.php';
plan( 1120 );
}
/* vim: set filetype=php: */
-?>
#!/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}"
);
}
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();
}
/* vim: set filetype=php: */
-?>
#!/usr/bin/env php
<?php
-require 'Test.php';
+require 't/Test.php';
plan(3);
#echo $lc->html;
/* vim: set filetype=php: */
-?>
--- /dev/null
+#!/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: */
#!/usr/bin/env php
<?php
-require 'Test.php';
+require 't/Test.php';
plan( 13 );
);
/* vim: set filetype=php: */
-?>
#!/usr/bin/env php
<?php
-require 'Test.php';
+require 't/Test.php';
plan( 2 + 255 );
}
/* vim: set filetype=php: */
-?>
#!/usr/bin/env php
<?php
-require 'Test.php';
+require 't/Test.php';
plan( 8 );
cmp_ok( Xml::closeElement( 'element' ), '==', '</element>', 'closeElement() shortcut' );
/* vim: set filetype=php: */
-?>