mirror of
https://github.com/Lastorder-DC/rhymix.git
synced 2026-01-14 00:39:57 +09:00
#17528788 : unittest framework added
git-svn-id: http://xe-core.googlecode.com/svn/sandbox@6001 201d5d3c-b55e-5fd7-737f-ddc643e51545
This commit is contained in:
parent
ea7c87ec0d
commit
7619bce790
99 changed files with 31041 additions and 0 deletions
7
tests/classes/context/Context.test.php
Normal file
7
tests/classes/context/Context.test.php
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
<?php
|
||||
class TestOfContext extends UnitTestCase {
|
||||
function testOK() {
|
||||
$this->assertTrue(true);
|
||||
}
|
||||
}
|
||||
?>
|
||||
17
tests/index.php
Normal file
17
tests/index.php
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
<?php
|
||||
define('__ZBXE__', true);
|
||||
require_once('../config/config.inc.php');
|
||||
require_once('simpletest/autorun.php');
|
||||
|
||||
class AllTests extends TestSuite {
|
||||
function AllTests() {
|
||||
$oContext = &Context::getInstance();
|
||||
$oContext->init();
|
||||
|
||||
$this->TestSuite('XpressEngine Test');
|
||||
$this->addFile(dirname(__FILE__).'/classes/context/Context.test.php');
|
||||
$this->addFile(dirname(__FILE__).'/modules/module/module.test.php');
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
19
tests/modules/module/module.test.php
Normal file
19
tests/modules/module/module.test.php
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
<?php
|
||||
class LockTest extends UnitTestCase {
|
||||
function testLock() {
|
||||
$oController = &getController('module');
|
||||
$this->assertNotNull($oController);
|
||||
$output = $oController->lock('lockTest', 60);
|
||||
$this->assertTrue($output->toBool());
|
||||
$deadline = $output->get('deadline');
|
||||
$output2 = $oController->lock('lockTest', 60);
|
||||
$this->assertFalse($output2->toBool());
|
||||
$output2 = $oController->unlock('lockTest', $deadline);
|
||||
$this->assertTrue($output2->toBool());
|
||||
$output2 = $oController->lock('lockTest', 60);
|
||||
$this->assertTrue($output2->toBool());
|
||||
$output2 = $oController->unlock('lockTest', $output2->get('deadline'));
|
||||
$this->assertTrue($output2->toBool());
|
||||
}
|
||||
}
|
||||
?>
|
||||
348
tests/simpletest/HELP_MY_TESTS_DONT_WORK_ANYMORE
Normal file
348
tests/simpletest/HELP_MY_TESTS_DONT_WORK_ANYMORE
Normal file
|
|
@ -0,0 +1,348 @@
|
|||
Simple Test interface changes
|
||||
=============================
|
||||
Because the SimpleTest tool set is still evolving it is likely that tests
|
||||
written with earlier versions will fail with the newest ones. The most
|
||||
dramatic changes are in the alpha releases. Here is a list of possible
|
||||
problems and their fixes...
|
||||
|
||||
No method getRelativeUrls() or getAbsoluteUrls()
|
||||
------------------------------------------------
|
||||
These methods were always a bit weird anyway, and
|
||||
the new parsing of the base tag makes them more so.
|
||||
They have been replaced with getUrls() instead. If
|
||||
you want the old functionality then simply chop
|
||||
off the current domain from getUrl().
|
||||
|
||||
Method setWildcard() removed in mocks
|
||||
-------------------------------------
|
||||
Even setWildcard() has been removed in 1.0.1beta now.
|
||||
If you want to test explicitely for a '*' string, then
|
||||
simply pass in new IdenticalExpectation('*') instead.
|
||||
|
||||
No method _getTest() on mocks
|
||||
-----------------------------
|
||||
This has finally been removed. It was a pretty esoteric
|
||||
flex point anyway. It was there to allow the mocks to
|
||||
work with other test tools, but no one does this.
|
||||
|
||||
No method assertError(), assertNoErrors(), swallowErrors()
|
||||
----------------------------------------------------------
|
||||
These have been deprecated in 1.0.1beta in favour of
|
||||
expectError() and expectException(). assertNoErrors() is
|
||||
redundant if you use expectError() as failures are now reported
|
||||
immediately.
|
||||
|
||||
No method TestCase::signal()
|
||||
----------------------------
|
||||
This has been deprecated in favour of triggering an error or
|
||||
throwing an exception. Deprecated as of 1.0.1beta.
|
||||
|
||||
No method TestCase::sendMessage()
|
||||
---------------------------------
|
||||
This has been deprecated as of 1.0.1beta.
|
||||
|
||||
Failure to connect now emits failures
|
||||
-------------------------------------
|
||||
It used to be that you would have to use the
|
||||
getTransferError() call on the web tester to see if
|
||||
there was a socket level error in a fetch. This check
|
||||
is now always carried out by the WebTestCase unless
|
||||
the fetch is prefaced with WebTestCase::ignoreErrors().
|
||||
The ignore directive only lasts for test case fetching
|
||||
action such as get() and click().
|
||||
|
||||
No method SimpleTestOptions::ignore()
|
||||
-------------------------------------
|
||||
This is deprecated in version 1.0.1beta and has been moved
|
||||
to SimpleTest::ignore() as that is more readable. In
|
||||
addition, parent classes are also ignored automatically.
|
||||
If you are using PHP5 you can skip this directive simply
|
||||
by marking your test case as abstract.
|
||||
|
||||
No method assertCopy()
|
||||
----------------------
|
||||
This is deprecated in 1.0.1 in favour of assertClone().
|
||||
The assertClone() method is slightly different in that
|
||||
the objects must be identical, but without being a
|
||||
reference. It is thus not a strict inversion of
|
||||
assertReference().
|
||||
|
||||
Constructor wildcard override has no effect in mocks
|
||||
----------------------------------------------------
|
||||
As of 1.0.1beta this is now set with setWildcard() instead
|
||||
of in the constructor.
|
||||
|
||||
No methods setStubBaseClass()/getStubBaseClass()
|
||||
------------------------------------------------
|
||||
As mocks are now used instead of stubs, these methods
|
||||
stopped working and are now removed as of the 1.0.1beta
|
||||
release. The mock objects may be freely used instead.
|
||||
|
||||
No method addPartialMockCode()
|
||||
------------------------------
|
||||
The ability to insert arbitrary partial mock code
|
||||
has been removed. This was a low value feature
|
||||
causing needless complications. It was removed
|
||||
in the 1.0.1beta release.
|
||||
|
||||
No method setMockBaseClass()
|
||||
----------------------------
|
||||
The ability to change the mock base class has been
|
||||
scheduled for removal and is deprecated since the
|
||||
1.0.1beta version. This was a rarely used feature
|
||||
except as a workaround for PHP5 limitations. As
|
||||
these limitations are being resolved it's hoped
|
||||
that the bundled mocks can be used directly.
|
||||
|
||||
No class Stub
|
||||
-------------
|
||||
Server stubs are deprecated from 1.0.1 as the mocks now
|
||||
have exactly the same interface. Just use mock objects
|
||||
instead.
|
||||
|
||||
No class SimpleTestOptions
|
||||
--------------------------
|
||||
This was replced by the shorter SimpleTest in 1.0.1beta1
|
||||
and is since deprecated.
|
||||
|
||||
No file simple_test.php
|
||||
-----------------------
|
||||
This was renamed test_case.php in 1.0.1beta to more accurately
|
||||
reflect it's purpose. This file should never be directly
|
||||
included in test suites though, as it's part of the
|
||||
underlying mechanics and has a tendency to be refactored.
|
||||
|
||||
No class WantedPatternExpectation
|
||||
---------------------------------
|
||||
This was deprecated in 1.0.1alpha in favour of the simpler
|
||||
name PatternExpectation.
|
||||
|
||||
No class NoUnwantedPatternExpectation
|
||||
-------------------------------------
|
||||
This was deprecated in 1.0.1alpha in favour of the simpler
|
||||
name NoPatternExpectation.
|
||||
|
||||
No method assertNoUnwantedPattern()
|
||||
-----------------------------------
|
||||
This has been renamed to assertNoPattern() in 1.0.1alpha and
|
||||
the old form is deprecated.
|
||||
|
||||
No method assertWantedPattern()
|
||||
-------------------------------
|
||||
This has been renamed to assertPattern() in 1.0.1alpha and
|
||||
the old form is deprecated.
|
||||
|
||||
No method assertExpectation()
|
||||
-----------------------------
|
||||
This was renamed as assert() in 1.0.1alpha and the old form
|
||||
has been deprecated.
|
||||
|
||||
No class WildcardExpectation
|
||||
----------------------------
|
||||
This was a mostly internal class for the mock objects. It was
|
||||
renamed AnythingExpectation to bring it closer to JMock and
|
||||
NMock in version 1.0.1alpha.
|
||||
|
||||
Missing UnitTestCase::assertErrorPattern()
|
||||
------------------------------------------
|
||||
This method is deprecated for version 1.0.1 onwards.
|
||||
This method has been subsumed by assertError() that can now
|
||||
take an expectation. Simply pass a PatternExpectation
|
||||
into assertError() to simulate the old behaviour.
|
||||
|
||||
No HTML when matching page elements
|
||||
-----------------------------------
|
||||
This behaviour has been switched to using plain text as if it
|
||||
were seen by the user of the browser. This means that HTML tags
|
||||
are suppressed, entities are converted and whitespace is
|
||||
normalised. This should make it easier to match items in forms.
|
||||
Also images are replaced with their "alt" text so that they
|
||||
can be matched as well.
|
||||
|
||||
No method SimpleRunner::_getTestCase()
|
||||
--------------------------------------
|
||||
This was made public as getTestCase() in 1.0RC2.
|
||||
|
||||
No method restartSession()
|
||||
--------------------------
|
||||
This was renamed to restart() in the WebTestCase, SimpleBrowser
|
||||
and the underlying SimpleUserAgent in 1.0RC2. Because it was
|
||||
undocumented anyway, no attempt was made at backward
|
||||
compatibility.
|
||||
|
||||
My custom test case ignored by tally()
|
||||
--------------------------------------
|
||||
The _assertTrue method has had it's signature changed due to a bug
|
||||
in the PHP 5.0.1 release. You must now use getTest() from within
|
||||
that method to get the test case. Mock compatibility with other
|
||||
unit testers is now deprecated as of 1.0.1alpha as PEAR::PHPUnit2
|
||||
should soon have mock support of it's own.
|
||||
|
||||
Broken code extending SimpleRunner
|
||||
----------------------------------
|
||||
This was replaced with SimpleScorer so that I could use the runner
|
||||
name in another class. This happened in RC1 development and there
|
||||
is no easy backward compatibility fix. The solution is simply to
|
||||
extend SimpleScorer instead.
|
||||
|
||||
Missing method getBaseCookieValue()
|
||||
-----------------------------------
|
||||
This was renamed getCurrentCookieValue() in RC1.
|
||||
|
||||
Missing files from the SimpleTest suite
|
||||
---------------------------------------
|
||||
Versions of SimpleTest prior to Beta6 required a SIMPLE_TEST constant
|
||||
to point at the SimpleTest folder location before any of the toolset
|
||||
was loaded. This is no longer documented as it is now unnecessary
|
||||
for later versions. If you are using an earlier version you may
|
||||
need this constant. Consult the documentation that was bundled with
|
||||
the release that you are using or upgrade to Beta6 or later.
|
||||
|
||||
No method SimpleBrowser::getCurrentUrl()
|
||||
--------------------------------------
|
||||
This is replaced with the more versatile showRequest() for
|
||||
debugging. It only existed in this context for version Beta5.
|
||||
Later versions will have SimpleBrowser::getHistory() for tracking
|
||||
paths through pages. It is renamed as getUrl() since 1.0RC1.
|
||||
|
||||
No method Stub::setStubBaseClass()
|
||||
----------------------------------
|
||||
This method has finally been removed in 1.0RC1. Use
|
||||
SimpleTestOptions::setStubBaseClass() instead.
|
||||
|
||||
No class CommandLineReporter
|
||||
----------------------------
|
||||
This was renamed to TextReporter in Beta3 and the deprecated version
|
||||
was removed in 1.0RC1.
|
||||
|
||||
No method requireReturn()
|
||||
-------------------------
|
||||
This was deprecated in Beta3 and is now removed.
|
||||
|
||||
No method expectCookie()
|
||||
------------------------
|
||||
This method was abruptly removed in Beta4 so as to simplify the internals
|
||||
until another mechanism can replace it. As a workaround it is necessary
|
||||
to assert that the cookie has changed by setting it before the page
|
||||
fetch and then assert the desired value.
|
||||
|
||||
No method clickSubmitByFormId()
|
||||
-------------------------------
|
||||
This method had an incorrect name as no button was involved. It was
|
||||
renamed to submitByFormId() in Beta4 and the old version deprecated.
|
||||
Now removed.
|
||||
|
||||
No method paintStart() or paintEnd()
|
||||
------------------------------------
|
||||
You should only get this error if you have subclassed the lower level
|
||||
reporting and test runner machinery. These methods have been broken
|
||||
down into events for test methods, events for test cases and events
|
||||
for group tests. The new methods are...
|
||||
|
||||
paintStart() --> paintMethodStart(), paintCaseStart(), paintGroupStart()
|
||||
paintEnd() --> paintMethodEnd(), paintCaseEnd(), paintGroupEnd()
|
||||
|
||||
This change was made in Beta3, ironically to make it easier to subclass
|
||||
the inner machinery. Simply duplicating the code you had in the previous
|
||||
methods should provide a temporary fix.
|
||||
|
||||
No class TestDisplay
|
||||
--------------------
|
||||
This has been folded into SimpleReporter in Beta3 and is now deprecated.
|
||||
It was removed in RC1.
|
||||
|
||||
No method WebTestCase::fetch()
|
||||
------------------------------
|
||||
This was renamed get() in Alpha8. It is removed in Beta3.
|
||||
|
||||
No method submit()
|
||||
------------------
|
||||
This has been renamed clickSubmit() in Beta1. The old method was
|
||||
removed in Beta2.
|
||||
|
||||
No method clearHistory()
|
||||
------------------------
|
||||
This method is deprecated in Beta2 and removed in RC1.
|
||||
|
||||
No method getCallCount()
|
||||
------------------------
|
||||
This method has been deprecated since Beta1 and has now been
|
||||
removed. There are now more ways to set expectations on counts
|
||||
and so this method should be unecessery. Removed in RC1.
|
||||
|
||||
Cannot find file *
|
||||
------------------
|
||||
The following public name changes have occoured...
|
||||
|
||||
simple_html_test.php --> reporter.php
|
||||
simple_mock.php --> mock_objects.php
|
||||
simple_unit.php --> unit_tester.php
|
||||
simple_web.php --> web_tester.php
|
||||
|
||||
The old names were deprecated in Alpha8 and removed in Beta1.
|
||||
|
||||
No method attachObserver()
|
||||
--------------------------
|
||||
Prior to the Alpha8 release the old internal observer pattern was
|
||||
gutted and replaced with a visitor. This is to trade flexibility of
|
||||
test case expansion against the ease of writing user interfaces.
|
||||
|
||||
Code such as...
|
||||
|
||||
$test = &new MyTestCase();
|
||||
$test->attachObserver(new TestHtmlDisplay());
|
||||
$test->run();
|
||||
|
||||
...should be rewritten as...
|
||||
|
||||
$test = &new MyTestCase();
|
||||
$test->run(new HtmlReporter());
|
||||
|
||||
If you previously attached multiple observers then the workaround
|
||||
is to run the tests twice, once with each, until they can be combined.
|
||||
For one observer the old method is simulated in Alpha 8, but is
|
||||
removed in Beta1.
|
||||
|
||||
No class TestHtmlDisplay
|
||||
------------------------
|
||||
This class has been renamed to HtmlReporter in Alpha8. It is supported,
|
||||
but deprecated in Beta1 and removed in Beta2. If you have subclassed
|
||||
the display for your own design, then you will have to extend this
|
||||
class (HtmlReporter) instead.
|
||||
|
||||
If you have accessed the event queue by overriding the notify() method
|
||||
then I am afraid you are in big trouble :(. The reporter is now
|
||||
carried around the test suite by the runner classes and the methods
|
||||
called directly. In the unlikely event that this is a problem and
|
||||
you don't want to upgrade the test tool then simplest is to write your
|
||||
own runner class and invoke the tests with...
|
||||
|
||||
$test->accept(new MyRunner(new MyReporter()));
|
||||
|
||||
...rather than the run method. This should be easier to extend
|
||||
anyway and gives much more control. Even this method is overhauled
|
||||
in Beta3 where the runner class can be set within the test case. Really
|
||||
the best thing to do is to upgrade to this version as whatever you were
|
||||
trying to achieve before should now be very much easier.
|
||||
|
||||
Missing set options method
|
||||
--------------------------
|
||||
All test suite options are now in one class called SimpleTestOptions.
|
||||
This means that options are set differently...
|
||||
|
||||
GroupTest::ignore() --> SimpleTestOptions::ignore()
|
||||
Mock::setMockBaseClass() --> SimpleTestOptions::setMockBaseClass()
|
||||
|
||||
These changed in Alpha8 and the old versions are now removed in RC1.
|
||||
|
||||
No method setExpected*()
|
||||
------------------------
|
||||
The mock expectations changed their names in Alpha4 and the old names
|
||||
ceased to be supported in Alpha8. The changes are...
|
||||
|
||||
setExpectedArguments() --> expectArguments()
|
||||
setExpectedArgumentsSequence() --> expectArgumentsAt()
|
||||
setExpectedCallCount() --> expectCallCount()
|
||||
setMaximumCallCount() --> expectMaximumCallCount()
|
||||
|
||||
The parameters remained the same.
|
||||
502
tests/simpletest/LICENSE
Normal file
502
tests/simpletest/LICENSE
Normal file
|
|
@ -0,0 +1,502 @@
|
|||
GNU LESSER GENERAL PUBLIC LICENSE
|
||||
Version 2.1, February 1999
|
||||
|
||||
Copyright (C) 1991, 1999 Free Software Foundation, Inc.
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
[This is the first released version of the Lesser GPL. It also counts
|
||||
as the successor of the GNU Library Public License, version 2, hence
|
||||
the version number 2.1.]
|
||||
|
||||
Preamble
|
||||
|
||||
The licenses for most software are designed to take away your
|
||||
freedom to share and change it. By contrast, the GNU General Public
|
||||
Licenses are intended to guarantee your freedom to share and change
|
||||
free software--to make sure the software is free for all its users.
|
||||
|
||||
This license, the Lesser General Public License, applies to some
|
||||
specially designated software packages--typically libraries--of the
|
||||
Free Software Foundation and other authors who decide to use it. You
|
||||
can use it too, but we suggest you first think carefully about whether
|
||||
this license or the ordinary General Public License is the better
|
||||
strategy to use in any particular case, based on the explanations below.
|
||||
|
||||
When we speak of free software, we are referring to freedom of use,
|
||||
not price. Our General Public Licenses are designed to make sure that
|
||||
you have the freedom to distribute copies of free software (and charge
|
||||
for this service if you wish); that you receive source code or can get
|
||||
it if you want it; that you can change the software and use pieces of
|
||||
it in new free programs; and that you are informed that you can do
|
||||
these things.
|
||||
|
||||
To protect your rights, we need to make restrictions that forbid
|
||||
distributors to deny you these rights or to ask you to surrender these
|
||||
rights. These restrictions translate to certain responsibilities for
|
||||
you if you distribute copies of the library or if you modify it.
|
||||
|
||||
For example, if you distribute copies of the library, whether gratis
|
||||
or for a fee, you must give the recipients all the rights that we gave
|
||||
you. You must make sure that they, too, receive or can get the source
|
||||
code. If you link other code with the library, you must provide
|
||||
complete object files to the recipients, so that they can relink them
|
||||
with the library after making changes to the library and recompiling
|
||||
it. And you must show them these terms so they know their rights.
|
||||
|
||||
We protect your rights with a two-step method: (1) we copyright the
|
||||
library, and (2) we offer you this license, which gives you legal
|
||||
permission to copy, distribute and/or modify the library.
|
||||
|
||||
To protect each distributor, we want to make it very clear that
|
||||
there is no warranty for the free library. Also, if the library is
|
||||
modified by someone else and passed on, the recipients should know
|
||||
that what they have is not the original version, so that the original
|
||||
author's reputation will not be affected by problems that might be
|
||||
introduced by others.
|
||||
|
||||
Finally, software patents pose a constant threat to the existence of
|
||||
any free program. We wish to make sure that a company cannot
|
||||
effectively restrict the users of a free program by obtaining a
|
||||
restrictive license from a patent holder. Therefore, we insist that
|
||||
any patent license obtained for a version of the library must be
|
||||
consistent with the full freedom of use specified in this license.
|
||||
|
||||
Most GNU software, including some libraries, is covered by the
|
||||
ordinary GNU General Public License. This license, the GNU Lesser
|
||||
General Public License, applies to certain designated libraries, and
|
||||
is quite different from the ordinary General Public License. We use
|
||||
this license for certain libraries in order to permit linking those
|
||||
libraries into non-free programs.
|
||||
|
||||
When a program is linked with a library, whether statically or using
|
||||
a shared library, the combination of the two is legally speaking a
|
||||
combined work, a derivative of the original library. The ordinary
|
||||
General Public License therefore permits such linking only if the
|
||||
entire combination fits its criteria of freedom. The Lesser General
|
||||
Public License permits more lax criteria for linking other code with
|
||||
the library.
|
||||
|
||||
We call this license the "Lesser" General Public License because it
|
||||
does Less to protect the user's freedom than the ordinary General
|
||||
Public License. It also provides other free software developers Less
|
||||
of an advantage over competing non-free programs. These disadvantages
|
||||
are the reason we use the ordinary General Public License for many
|
||||
libraries. However, the Lesser license provides advantages in certain
|
||||
special circumstances.
|
||||
|
||||
For example, on rare occasions, there may be a special need to
|
||||
encourage the widest possible use of a certain library, so that it becomes
|
||||
a de-facto standard. To achieve this, non-free programs must be
|
||||
allowed to use the library. A more frequent case is that a free
|
||||
library does the same job as widely used non-free libraries. In this
|
||||
case, there is little to gain by limiting the free library to free
|
||||
software only, so we use the Lesser General Public License.
|
||||
|
||||
In other cases, permission to use a particular library in non-free
|
||||
programs enables a greater number of people to use a large body of
|
||||
free software. For example, permission to use the GNU C Library in
|
||||
non-free programs enables many more people to use the whole GNU
|
||||
operating system, as well as its variant, the GNU/Linux operating
|
||||
system.
|
||||
|
||||
Although the Lesser General Public License is Less protective of the
|
||||
users' freedom, it does ensure that the user of a program that is
|
||||
linked with the Library has the freedom and the wherewithal to run
|
||||
that program using a modified version of the Library.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow. Pay close attention to the difference between a
|
||||
"work based on the library" and a "work that uses the library". The
|
||||
former contains code derived from the library, whereas the latter must
|
||||
be combined with the library in order to run.
|
||||
|
||||
GNU LESSER GENERAL PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. This License Agreement applies to any software library or other
|
||||
program which contains a notice placed by the copyright holder or
|
||||
other authorized party saying it may be distributed under the terms of
|
||||
this Lesser General Public License (also called "this License").
|
||||
Each licensee is addressed as "you".
|
||||
|
||||
A "library" means a collection of software functions and/or data
|
||||
prepared so as to be conveniently linked with application programs
|
||||
(which use some of those functions and data) to form executables.
|
||||
|
||||
The "Library", below, refers to any such software library or work
|
||||
which has been distributed under these terms. A "work based on the
|
||||
Library" means either the Library or any derivative work under
|
||||
copyright law: that is to say, a work containing the Library or a
|
||||
portion of it, either verbatim or with modifications and/or translated
|
||||
straightforwardly into another language. (Hereinafter, translation is
|
||||
included without limitation in the term "modification".)
|
||||
|
||||
"Source code" for a work means the preferred form of the work for
|
||||
making modifications to it. For a library, complete source code means
|
||||
all the source code for all modules it contains, plus any associated
|
||||
interface definition files, plus the scripts used to control compilation
|
||||
and installation of the library.
|
||||
|
||||
Activities other than copying, distribution and modification are not
|
||||
covered by this License; they are outside its scope. The act of
|
||||
running a program using the Library is not restricted, and output from
|
||||
such a program is covered only if its contents constitute a work based
|
||||
on the Library (independent of the use of the Library in a tool for
|
||||
writing it). Whether that is true depends on what the Library does
|
||||
and what the program that uses the Library does.
|
||||
|
||||
1. You may copy and distribute verbatim copies of the Library's
|
||||
complete source code as you receive it, in any medium, provided that
|
||||
you conspicuously and appropriately publish on each copy an
|
||||
appropriate copyright notice and disclaimer of warranty; keep intact
|
||||
all the notices that refer to this License and to the absence of any
|
||||
warranty; and distribute a copy of this License along with the
|
||||
Library.
|
||||
|
||||
You may charge a fee for the physical act of transferring a copy,
|
||||
and you may at your option offer warranty protection in exchange for a
|
||||
fee.
|
||||
|
||||
2. You may modify your copy or copies of the Library or any portion
|
||||
of it, thus forming a work based on the Library, and copy and
|
||||
distribute such modifications or work under the terms of Section 1
|
||||
above, provided that you also meet all of these conditions:
|
||||
|
||||
a) The modified work must itself be a software library.
|
||||
|
||||
b) You must cause the files modified to carry prominent notices
|
||||
stating that you changed the files and the date of any change.
|
||||
|
||||
c) You must cause the whole of the work to be licensed at no
|
||||
charge to all third parties under the terms of this License.
|
||||
|
||||
d) If a facility in the modified Library refers to a function or a
|
||||
table of data to be supplied by an application program that uses
|
||||
the facility, other than as an argument passed when the facility
|
||||
is invoked, then you must make a good faith effort to ensure that,
|
||||
in the event an application does not supply such function or
|
||||
table, the facility still operates, and performs whatever part of
|
||||
its purpose remains meaningful.
|
||||
|
||||
(For example, a function in a library to compute square roots has
|
||||
a purpose that is entirely well-defined independent of the
|
||||
application. Therefore, Subsection 2d requires that any
|
||||
application-supplied function or table used by this function must
|
||||
be optional: if the application does not supply it, the square
|
||||
root function must still compute square roots.)
|
||||
|
||||
These requirements apply to the modified work as a whole. If
|
||||
identifiable sections of that work are not derived from the Library,
|
||||
and can be reasonably considered independent and separate works in
|
||||
themselves, then this License, and its terms, do not apply to those
|
||||
sections when you distribute them as separate works. But when you
|
||||
distribute the same sections as part of a whole which is a work based
|
||||
on the Library, the distribution of the whole must be on the terms of
|
||||
this License, whose permissions for other licensees extend to the
|
||||
entire whole, and thus to each and every part regardless of who wrote
|
||||
it.
|
||||
|
||||
Thus, it is not the intent of this section to claim rights or contest
|
||||
your rights to work written entirely by you; rather, the intent is to
|
||||
exercise the right to control the distribution of derivative or
|
||||
collective works based on the Library.
|
||||
|
||||
In addition, mere aggregation of another work not based on the Library
|
||||
with the Library (or with a work based on the Library) on a volume of
|
||||
a storage or distribution medium does not bring the other work under
|
||||
the scope of this License.
|
||||
|
||||
3. You may opt to apply the terms of the ordinary GNU General Public
|
||||
License instead of this License to a given copy of the Library. To do
|
||||
this, you must alter all the notices that refer to this License, so
|
||||
that they refer to the ordinary GNU General Public License, version 2,
|
||||
instead of to this License. (If a newer version than version 2 of the
|
||||
ordinary GNU General Public License has appeared, then you can specify
|
||||
that version instead if you wish.) Do not make any other change in
|
||||
these notices.
|
||||
|
||||
Once this change is made in a given copy, it is irreversible for
|
||||
that copy, so the ordinary GNU General Public License applies to all
|
||||
subsequent copies and derivative works made from that copy.
|
||||
|
||||
This option is useful when you wish to copy part of the code of
|
||||
the Library into a program that is not a library.
|
||||
|
||||
4. You may copy and distribute the Library (or a portion or
|
||||
derivative of it, under Section 2) in object code or executable form
|
||||
under the terms of Sections 1 and 2 above provided that you accompany
|
||||
it with the complete corresponding machine-readable source code, which
|
||||
must be distributed under the terms of Sections 1 and 2 above on a
|
||||
medium customarily used for software interchange.
|
||||
|
||||
If distribution of object code is made by offering access to copy
|
||||
from a designated place, then offering equivalent access to copy the
|
||||
source code from the same place satisfies the requirement to
|
||||
distribute the source code, even though third parties are not
|
||||
compelled to copy the source along with the object code.
|
||||
|
||||
5. A program that contains no derivative of any portion of the
|
||||
Library, but is designed to work with the Library by being compiled or
|
||||
linked with it, is called a "work that uses the Library". Such a
|
||||
work, in isolation, is not a derivative work of the Library, and
|
||||
therefore falls outside the scope of this License.
|
||||
|
||||
However, linking a "work that uses the Library" with the Library
|
||||
creates an executable that is a derivative of the Library (because it
|
||||
contains portions of the Library), rather than a "work that uses the
|
||||
library". The executable is therefore covered by this License.
|
||||
Section 6 states terms for distribution of such executables.
|
||||
|
||||
When a "work that uses the Library" uses material from a header file
|
||||
that is part of the Library, the object code for the work may be a
|
||||
derivative work of the Library even though the source code is not.
|
||||
Whether this is true is especially significant if the work can be
|
||||
linked without the Library, or if the work is itself a library. The
|
||||
threshold for this to be true is not precisely defined by law.
|
||||
|
||||
If such an object file uses only numerical parameters, data
|
||||
structure layouts and accessors, and small macros and small inline
|
||||
functions (ten lines or less in length), then the use of the object
|
||||
file is unrestricted, regardless of whether it is legally a derivative
|
||||
work. (Executables containing this object code plus portions of the
|
||||
Library will still fall under Section 6.)
|
||||
|
||||
Otherwise, if the work is a derivative of the Library, you may
|
||||
distribute the object code for the work under the terms of Section 6.
|
||||
Any executables containing that work also fall under Section 6,
|
||||
whether or not they are linked directly with the Library itself.
|
||||
|
||||
6. As an exception to the Sections above, you may also combine or
|
||||
link a "work that uses the Library" with the Library to produce a
|
||||
work containing portions of the Library, and distribute that work
|
||||
under terms of your choice, provided that the terms permit
|
||||
modification of the work for the customer's own use and reverse
|
||||
engineering for debugging such modifications.
|
||||
|
||||
You must give prominent notice with each copy of the work that the
|
||||
Library is used in it and that the Library and its use are covered by
|
||||
this License. You must supply a copy of this License. If the work
|
||||
during execution displays copyright notices, you must include the
|
||||
copyright notice for the Library among them, as well as a reference
|
||||
directing the user to the copy of this License. Also, you must do one
|
||||
of these things:
|
||||
|
||||
a) Accompany the work with the complete corresponding
|
||||
machine-readable source code for the Library including whatever
|
||||
changes were used in the work (which must be distributed under
|
||||
Sections 1 and 2 above); and, if the work is an executable linked
|
||||
with the Library, with the complete machine-readable "work that
|
||||
uses the Library", as object code and/or source code, so that the
|
||||
user can modify the Library and then relink to produce a modified
|
||||
executable containing the modified Library. (It is understood
|
||||
that the user who changes the contents of definitions files in the
|
||||
Library will not necessarily be able to recompile the application
|
||||
to use the modified definitions.)
|
||||
|
||||
b) Use a suitable shared library mechanism for linking with the
|
||||
Library. A suitable mechanism is one that (1) uses at run time a
|
||||
copy of the library already present on the user's computer system,
|
||||
rather than copying library functions into the executable, and (2)
|
||||
will operate properly with a modified version of the library, if
|
||||
the user installs one, as long as the modified version is
|
||||
interface-compatible with the version that the work was made with.
|
||||
|
||||
c) Accompany the work with a written offer, valid for at
|
||||
least three years, to give the same user the materials
|
||||
specified in Subsection 6a, above, for a charge no more
|
||||
than the cost of performing this distribution.
|
||||
|
||||
d) If distribution of the work is made by offering access to copy
|
||||
from a designated place, offer equivalent access to copy the above
|
||||
specified materials from the same place.
|
||||
|
||||
e) Verify that the user has already received a copy of these
|
||||
materials or that you have already sent this user a copy.
|
||||
|
||||
For an executable, the required form of the "work that uses the
|
||||
Library" must include any data and utility programs needed for
|
||||
reproducing the executable from it. However, as a special exception,
|
||||
the materials to be distributed need not include anything that is
|
||||
normally distributed (in either source or binary form) with the major
|
||||
components (compiler, kernel, and so on) of the operating system on
|
||||
which the executable runs, unless that component itself accompanies
|
||||
the executable.
|
||||
|
||||
It may happen that this requirement contradicts the license
|
||||
restrictions of other proprietary libraries that do not normally
|
||||
accompany the operating system. Such a contradiction means you cannot
|
||||
use both them and the Library together in an executable that you
|
||||
distribute.
|
||||
|
||||
7. You may place library facilities that are a work based on the
|
||||
Library side-by-side in a single library together with other library
|
||||
facilities not covered by this License, and distribute such a combined
|
||||
library, provided that the separate distribution of the work based on
|
||||
the Library and of the other library facilities is otherwise
|
||||
permitted, and provided that you do these two things:
|
||||
|
||||
a) Accompany the combined library with a copy of the same work
|
||||
based on the Library, uncombined with any other library
|
||||
facilities. This must be distributed under the terms of the
|
||||
Sections above.
|
||||
|
||||
b) Give prominent notice with the combined library of the fact
|
||||
that part of it is a work based on the Library, and explaining
|
||||
where to find the accompanying uncombined form of the same work.
|
||||
|
||||
8. You may not copy, modify, sublicense, link with, or distribute
|
||||
the Library except as expressly provided under this License. Any
|
||||
attempt otherwise to copy, modify, sublicense, link with, or
|
||||
distribute the Library is void, and will automatically terminate your
|
||||
rights under this License. However, parties who have received copies,
|
||||
or rights, from you under this License will not have their licenses
|
||||
terminated so long as such parties remain in full compliance.
|
||||
|
||||
9. You are not required to accept this License, since you have not
|
||||
signed it. However, nothing else grants you permission to modify or
|
||||
distribute the Library or its derivative works. These actions are
|
||||
prohibited by law if you do not accept this License. Therefore, by
|
||||
modifying or distributing the Library (or any work based on the
|
||||
Library), you indicate your acceptance of this License to do so, and
|
||||
all its terms and conditions for copying, distributing or modifying
|
||||
the Library or works based on it.
|
||||
|
||||
10. Each time you redistribute the Library (or any work based on the
|
||||
Library), the recipient automatically receives a license from the
|
||||
original licensor to copy, distribute, link with or modify the Library
|
||||
subject to these terms and conditions. You may not impose any further
|
||||
restrictions on the recipients' exercise of the rights granted herein.
|
||||
You are not responsible for enforcing compliance by third parties with
|
||||
this License.
|
||||
|
||||
11. If, as a consequence of a court judgment or allegation of patent
|
||||
infringement or for any other reason (not limited to patent issues),
|
||||
conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot
|
||||
distribute so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you
|
||||
may not distribute the Library at all. For example, if a patent
|
||||
license would not permit royalty-free redistribution of the Library by
|
||||
all those who receive copies directly or indirectly through you, then
|
||||
the only way you could satisfy both it and this License would be to
|
||||
refrain entirely from distribution of the Library.
|
||||
|
||||
If any portion of this section is held invalid or unenforceable under any
|
||||
particular circumstance, the balance of the section is intended to apply,
|
||||
and the section as a whole is intended to apply in other circumstances.
|
||||
|
||||
It is not the purpose of this section to induce you to infringe any
|
||||
patents or other property right claims or to contest validity of any
|
||||
such claims; this section has the sole purpose of protecting the
|
||||
integrity of the free software distribution system which is
|
||||
implemented by public license practices. Many people have made
|
||||
generous contributions to the wide range of software distributed
|
||||
through that system in reliance on consistent application of that
|
||||
system; it is up to the author/donor to decide if he or she is willing
|
||||
to distribute software through any other system and a licensee cannot
|
||||
impose that choice.
|
||||
|
||||
This section is intended to make thoroughly clear what is believed to
|
||||
be a consequence of the rest of this License.
|
||||
|
||||
12. If the distribution and/or use of the Library is restricted in
|
||||
certain countries either by patents or by copyrighted interfaces, the
|
||||
original copyright holder who places the Library under this License may add
|
||||
an explicit geographical distribution limitation excluding those countries,
|
||||
so that distribution is permitted only in or among countries not thus
|
||||
excluded. In such case, this License incorporates the limitation as if
|
||||
written in the body of this License.
|
||||
|
||||
13. The Free Software Foundation may publish revised and/or new
|
||||
versions of the Lesser General Public License from time to time.
|
||||
Such new versions will be similar in spirit to the present version,
|
||||
but may differ in detail to address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the Library
|
||||
specifies a version number of this License which applies to it and
|
||||
"any later version", you have the option of following the terms and
|
||||
conditions either of that version or of any later version published by
|
||||
the Free Software Foundation. If the Library does not specify a
|
||||
license version number, you may choose any version ever published by
|
||||
the Free Software Foundation.
|
||||
|
||||
14. If you wish to incorporate parts of the Library into other free
|
||||
programs whose distribution conditions are incompatible with these,
|
||||
write to the author to ask for permission. For software which is
|
||||
copyrighted by the Free Software Foundation, write to the Free
|
||||
Software Foundation; we sometimes make exceptions for this. Our
|
||||
decision will be guided by the two goals of preserving the free status
|
||||
of all derivatives of our free software and of promoting the sharing
|
||||
and reuse of software generally.
|
||||
|
||||
NO WARRANTY
|
||||
|
||||
15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
|
||||
WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
|
||||
EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
|
||||
OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
|
||||
KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
|
||||
LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
|
||||
THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
|
||||
|
||||
16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
|
||||
WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
|
||||
AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
|
||||
FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
|
||||
CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
|
||||
LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
|
||||
RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
|
||||
FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
|
||||
SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
|
||||
DAMAGES.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Libraries
|
||||
|
||||
If you develop a new library, and you want it to be of the greatest
|
||||
possible use to the public, we recommend making it free software that
|
||||
everyone can redistribute and change. You can do so by permitting
|
||||
redistribution under these terms (or, alternatively, under the terms of the
|
||||
ordinary General Public License).
|
||||
|
||||
To apply these terms, attach the following notices to the library. It is
|
||||
safest to attach them to the start of each source file to most effectively
|
||||
convey the exclusion of warranty; and each file should have at least the
|
||||
"copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the library's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
You should also get your employer (if you work as a programmer) or your
|
||||
school, if any, to sign a "copyright disclaimer" for the library, if
|
||||
necessary. Here is a sample; alter the names:
|
||||
|
||||
Yoyodyne, Inc., hereby disclaims all copyright interest in the
|
||||
library `Frob' (a library for tweaking knobs) written by James Random Hacker.
|
||||
|
||||
<signature of Ty Coon>, 1 April 1990
|
||||
Ty Coon, President of Vice
|
||||
|
||||
That's all there is to it!
|
||||
108
tests/simpletest/README
Normal file
108
tests/simpletest/README
Normal file
|
|
@ -0,0 +1,108 @@
|
|||
SimpleTest
|
||||
==========
|
||||
You probably got this package from...
|
||||
http://simpletest.sourceforge.net/projects/simpletest/
|
||||
|
||||
If there is no licence agreement with this package please download
|
||||
a version from the location above. You must read and accept that
|
||||
licence to use this software. The file is titled simply LICENSE.
|
||||
|
||||
What is it? It's a framework for unit testing, web site testing and
|
||||
mock objects for PHP 4.2.0+ (and PHP 5.0 to 5.3 without E_STRICT).
|
||||
|
||||
If you have used JUnit, you will find this PHP unit testing version very
|
||||
similar. Also included is a mock objects and server stubs generator.
|
||||
The stubs can have return values set for different arguments, can have
|
||||
sequences set also by arguments and can return items by reference.
|
||||
The mocks inherit all of this functionality and can also have
|
||||
expectations set, again in sequences and for different arguments.
|
||||
|
||||
A web tester similar in concept to JWebUnit is also included. There is no
|
||||
JavaScript or tables support, but forms, authentication, cookies and
|
||||
frames are handled.
|
||||
|
||||
You can see a release schedule at http://www.lastcraft.com/overview.php
|
||||
which is also copied to the documentation folder with this release.
|
||||
A full PHPDocumenter API documentation exists at
|
||||
http://simpletest.sourceforge.net/.
|
||||
|
||||
The user interface is minimal
|
||||
in the extreme, but a lot of information flows from the test suite.
|
||||
After version 1.0 we will release a better web UI, but we are leaving XUL
|
||||
and GTk versions to volunteers as everybody has their own opinion
|
||||
on a good GUI, and we don't want to discourage development by shipping
|
||||
one with the toolkit. YOucan download an Eclipse plug-in separately.
|
||||
|
||||
You are looking at a second full release. The unit tests for SimpleTest
|
||||
itself can be run here...
|
||||
|
||||
simpletest/test/unit_tests.php
|
||||
|
||||
And tests involving live network connections as well are here...
|
||||
|
||||
simpletest/test/all_tests.php
|
||||
|
||||
The full tests will typically overrun the 8Mb limit often allowed
|
||||
to a PHP process. A workaround is to run the tests on the command
|
||||
with a custom php.ini file if you do not have access to your server
|
||||
version.
|
||||
|
||||
You will have to edit the all_tests.php file if you are accesssing
|
||||
the internet through a proxy server. See the comments in all_tests.php
|
||||
for instructions.
|
||||
|
||||
The full tests read some test data from the LastCraft site. If the site
|
||||
is down or has been modified for a later version then you will get
|
||||
spurious errors. A unit_tests.php failure on the other hand would be
|
||||
very serious. As far as we know we haven't yet managed to check in any
|
||||
unit test failures, so please correct us if you find one.
|
||||
|
||||
Even if all of the tests run please verify that your existing test suites
|
||||
also function as expected. If they don't see the file...
|
||||
|
||||
HELP_MY_TESTS_DONT_WORK_ANYMORE
|
||||
|
||||
This contains information on interface changes. It also points out
|
||||
deprecated interfaces, so you should read this even if all of
|
||||
your current tests appear to run.
|
||||
|
||||
There is a documentation folder which contains the core reference information
|
||||
in English and French, although this information is fairly basic.
|
||||
You can find a tutorial on...
|
||||
|
||||
http://www.lastcraft.com/first_test_tutorial.php
|
||||
|
||||
...to get you started and this material will eventually become included
|
||||
with the project documentation. A French translation exists at...
|
||||
|
||||
http://www.onpk.net/index.php/2005/01/12/254-tutoriel-simpletest-decouvrir-les-tests-unitaires.
|
||||
|
||||
If you download and use, and possibly even extend this tool, please let us
|
||||
know. Any feedback, even bad, is always welcome and we will work to get
|
||||
your suggestions into the next release. Ideally please send your
|
||||
comments to...
|
||||
|
||||
simpletest-support@lists.sourceforge.net
|
||||
|
||||
...so that others can read them too. We usually try to respond within 48
|
||||
hours.
|
||||
|
||||
There is no change log except at Sourceforge. You can visit the
|
||||
release notes to see the completed TODO list after each cycle and also the
|
||||
status of any bugs, but if the bug is recent then it will be fixed in SVN only.
|
||||
The SVN check-ins always have all the tests passing and so SVN snapshots should
|
||||
be pretty usable, although the code may not look so good internally.
|
||||
|
||||
Oh, yes. It is called "Simple" because it should be simple to
|
||||
use. We intend to add a complete set of tools for a test first
|
||||
and "test as you code" type of development. "Simple" does not
|
||||
mean "Lite" in this context.
|
||||
|
||||
Thanks to everyone who has sent comments and offered suggestions. They
|
||||
really are invaluable, but sadly you are too many to mention in full.
|
||||
Thanks to all on the advanced PHP forum on SitePoint, especially Harry
|
||||
Feucks. Early adopters are always an inspiration.
|
||||
|
||||
Marcus Baker, Jason Sweat, Travis Swicegood, Perrick Penet and Edward Z. Yang.
|
||||
--
|
||||
marcus@lastcraft.com
|
||||
1
tests/simpletest/VERSION
Normal file
1
tests/simpletest/VERSION
Normal file
|
|
@ -0,0 +1 @@
|
|||
1.0.1
|
||||
238
tests/simpletest/authentication.php
Normal file
238
tests/simpletest/authentication.php
Normal file
|
|
@ -0,0 +1,238 @@
|
|||
<?php
|
||||
/**
|
||||
* Base include file for SimpleTest
|
||||
* @package SimpleTest
|
||||
* @subpackage WebTester
|
||||
* @version $Id: authentication.php 1720 2008-04-07 02:32:43Z lastcraft $
|
||||
*/
|
||||
/**
|
||||
* include http class
|
||||
*/
|
||||
require_once(dirname(__FILE__) . '/http.php');
|
||||
|
||||
/**
|
||||
* Represents a single security realm's identity.
|
||||
* @package SimpleTest
|
||||
* @subpackage WebTester
|
||||
*/
|
||||
class SimpleRealm {
|
||||
var $_type;
|
||||
var $_root;
|
||||
var $_username;
|
||||
var $_password;
|
||||
|
||||
/**
|
||||
* Starts with the initial entry directory.
|
||||
* @param string $type Authentication type for this
|
||||
* realm. Only Basic authentication
|
||||
* is currently supported.
|
||||
* @param SimpleUrl $url Somewhere in realm.
|
||||
* @access public
|
||||
*/
|
||||
function SimpleRealm($type, $url) {
|
||||
$this->_type = $type;
|
||||
$this->_root = $url->getBasePath();
|
||||
$this->_username = false;
|
||||
$this->_password = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds another location to the realm.
|
||||
* @param SimpleUrl $url Somewhere in realm.
|
||||
* @access public
|
||||
*/
|
||||
function stretch($url) {
|
||||
$this->_root = $this->_getCommonPath($this->_root, $url->getPath());
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds the common starting path.
|
||||
* @param string $first Path to compare.
|
||||
* @param string $second Path to compare.
|
||||
* @return string Common directories.
|
||||
* @access private
|
||||
*/
|
||||
function _getCommonPath($first, $second) {
|
||||
$first = explode('/', $first);
|
||||
$second = explode('/', $second);
|
||||
for ($i = 0; $i < min(count($first), count($second)); $i++) {
|
||||
if ($first[$i] != $second[$i]) {
|
||||
return implode('/', array_slice($first, 0, $i)) . '/';
|
||||
}
|
||||
}
|
||||
return implode('/', $first) . '/';
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the identity to try within this realm.
|
||||
* @param string $username Username in authentication dialog.
|
||||
* @param string $username Password in authentication dialog.
|
||||
* @access public
|
||||
*/
|
||||
function setIdentity($username, $password) {
|
||||
$this->_username = $username;
|
||||
$this->_password = $password;
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for current identity.
|
||||
* @return string Last succesful username.
|
||||
* @access public
|
||||
*/
|
||||
function getUsername() {
|
||||
return $this->_username;
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for current identity.
|
||||
* @return string Last succesful password.
|
||||
* @access public
|
||||
*/
|
||||
function getPassword() {
|
||||
return $this->_password;
|
||||
}
|
||||
|
||||
/**
|
||||
* Test to see if the URL is within the directory
|
||||
* tree of the realm.
|
||||
* @param SimpleUrl $url URL to test.
|
||||
* @return boolean True if subpath.
|
||||
* @access public
|
||||
*/
|
||||
function isWithin($url) {
|
||||
if ($this->_isIn($this->_root, $url->getBasePath())) {
|
||||
return true;
|
||||
}
|
||||
if ($this->_isIn($this->_root, $url->getBasePath() . $url->getPage() . '/')) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests to see if one string is a substring of
|
||||
* another.
|
||||
* @param string $part Small bit.
|
||||
* @param string $whole Big bit.
|
||||
* @return boolean True if the small bit is
|
||||
* in the big bit.
|
||||
* @access private
|
||||
*/
|
||||
function _isIn($part, $whole) {
|
||||
return strpos($whole, $part) === 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Manages security realms.
|
||||
* @package SimpleTest
|
||||
* @subpackage WebTester
|
||||
*/
|
||||
class SimpleAuthenticator {
|
||||
var $_realms;
|
||||
|
||||
/**
|
||||
* Clears the realms.
|
||||
* @access public
|
||||
*/
|
||||
function SimpleAuthenticator() {
|
||||
$this->restartSession();
|
||||
}
|
||||
|
||||
/**
|
||||
* Starts with no realms set up.
|
||||
* @access public
|
||||
*/
|
||||
function restartSession() {
|
||||
$this->_realms = array();
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a new realm centered the current URL.
|
||||
* Browsers vary wildly on their behaviour in this
|
||||
* regard. Mozilla ignores the realm and presents
|
||||
* only when challenged, wasting bandwidth. IE
|
||||
* just carries on presenting until a new challenge
|
||||
* occours. SimpleTest tries to follow the spirit of
|
||||
* the original standards committee and treats the
|
||||
* base URL as the root of a file tree shaped realm.
|
||||
* @param SimpleUrl $url Base of realm.
|
||||
* @param string $type Authentication type for this
|
||||
* realm. Only Basic authentication
|
||||
* is currently supported.
|
||||
* @param string $realm Name of realm.
|
||||
* @access public
|
||||
*/
|
||||
function addRealm($url, $type, $realm) {
|
||||
$this->_realms[$url->getHost()][$realm] = new SimpleRealm($type, $url);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the current identity to be presented
|
||||
* against that realm.
|
||||
* @param string $host Server hosting realm.
|
||||
* @param string $realm Name of realm.
|
||||
* @param string $username Username for realm.
|
||||
* @param string $password Password for realm.
|
||||
* @access public
|
||||
*/
|
||||
function setIdentityForRealm($host, $realm, $username, $password) {
|
||||
if (isset($this->_realms[$host][$realm])) {
|
||||
$this->_realms[$host][$realm]->setIdentity($username, $password);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds the name of the realm by comparing URLs.
|
||||
* @param SimpleUrl $url URL to test.
|
||||
* @return SimpleRealm Name of realm.
|
||||
* @access private
|
||||
*/
|
||||
function _findRealmFromUrl($url) {
|
||||
if (! isset($this->_realms[$url->getHost()])) {
|
||||
return false;
|
||||
}
|
||||
foreach ($this->_realms[$url->getHost()] as $name => $realm) {
|
||||
if ($realm->isWithin($url)) {
|
||||
return $realm;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Presents the appropriate headers for this location.
|
||||
* @param SimpleHttpRequest $request Request to modify.
|
||||
* @param SimpleUrl $url Base of realm.
|
||||
* @access public
|
||||
*/
|
||||
function addHeaders(&$request, $url) {
|
||||
if ($url->getUsername() && $url->getPassword()) {
|
||||
$username = $url->getUsername();
|
||||
$password = $url->getPassword();
|
||||
} elseif ($realm = $this->_findRealmFromUrl($url)) {
|
||||
$username = $realm->getUsername();
|
||||
$password = $realm->getPassword();
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
$this->addBasicHeaders($request, $username, $password);
|
||||
}
|
||||
|
||||
/**
|
||||
* Presents the appropriate headers for this
|
||||
* location for basic authentication.
|
||||
* @param SimpleHttpRequest $request Request to modify.
|
||||
* @param string $username Username for realm.
|
||||
* @param string $password Password for realm.
|
||||
* @access public
|
||||
* @static
|
||||
*/
|
||||
function addBasicHeaders(&$request, $username, $password) {
|
||||
if ($username && $password) {
|
||||
$request->addHeaderLine(
|
||||
'Authorization: Basic ' . base64_encode("$username:$password"));
|
||||
}
|
||||
}
|
||||
}
|
||||
?>
|
||||
87
tests/simpletest/autorun.php
Normal file
87
tests/simpletest/autorun.php
Normal file
|
|
@ -0,0 +1,87 @@
|
|||
<?php
|
||||
/**
|
||||
* Autorunner which runs all tests cases found in a file
|
||||
* that includes this module.
|
||||
* @package SimpleTest
|
||||
* @version $Id: autorun.php 1721 2008-04-07 19:27:10Z lastcraft $
|
||||
*/
|
||||
require_once dirname(__FILE__) . '/unit_tester.php';
|
||||
require_once dirname(__FILE__) . '/mock_objects.php';
|
||||
require_once dirname(__FILE__) . '/collector.php';
|
||||
require_once dirname(__FILE__) . '/default_reporter.php';
|
||||
|
||||
$GLOBALS['SIMPLETEST_AUTORUNNER_INITIAL_CLASSES'] = get_declared_classes();
|
||||
register_shutdown_function('simpletest_autorun');
|
||||
|
||||
/**
|
||||
* Exit handler to run all recent test cases if no test has
|
||||
* so far been run. Uses the DefaultReporter which can have
|
||||
* it's output controlled with SimpleTest::prefer().
|
||||
*/
|
||||
function simpletest_autorun() {
|
||||
if (tests_have_run()) {
|
||||
return;
|
||||
}
|
||||
$candidates = array_intersect(
|
||||
capture_new_classes(),
|
||||
classes_defined_in_initial_file());
|
||||
$loader = new SimpleFileLoader();
|
||||
$suite = $loader->createSuiteFromClasses(
|
||||
basename(initial_file()),
|
||||
$loader->selectRunnableTests($candidates));
|
||||
$result = $suite->run(new DefaultReporter());
|
||||
if (SimpleReporter::inCli()) {
|
||||
exit($result ? 0 : 1);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks the current test context to see if a test has
|
||||
* ever been run.
|
||||
* @return boolean True if tests have run.
|
||||
*/
|
||||
function tests_have_run() {
|
||||
if ($context = SimpleTest::getContext()) {
|
||||
return (boolean)$context->getTest();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* The first autorun file.
|
||||
* @return string Filename of first autorun script.
|
||||
*/
|
||||
function initial_file() {
|
||||
static $file = false;
|
||||
if (! $file) {
|
||||
$file = reset(get_included_files());
|
||||
}
|
||||
return $file;
|
||||
}
|
||||
|
||||
/**
|
||||
* Just the classes from the first autorun script. May
|
||||
* get a few false positives, as it just does a regex based
|
||||
* on following the word "class".
|
||||
* @return array List of all possible classes in first
|
||||
* autorun script.
|
||||
*/
|
||||
function classes_defined_in_initial_file() {
|
||||
if (preg_match_all('/\bclass\s+(\w+)/i', file_get_contents(initial_file()), $matches)) {
|
||||
return array_map('strtolower', $matches[1]);
|
||||
}
|
||||
return array();
|
||||
}
|
||||
|
||||
/**
|
||||
* Every class since the first autorun include. This
|
||||
* is safe enough if require_once() is alwyas used.
|
||||
* @return array Class names.
|
||||
*/
|
||||
function capture_new_classes() {
|
||||
global $SIMPLETEST_AUTORUNNER_INITIAL_CLASSES;
|
||||
return array_map('strtolower', array_diff(get_declared_classes(),
|
||||
$SIMPLETEST_AUTORUNNER_INITIAL_CLASSES ?
|
||||
$SIMPLETEST_AUTORUNNER_INITIAL_CLASSES : array()));
|
||||
}
|
||||
?>
|
||||
1098
tests/simpletest/browser.php
Normal file
1098
tests/simpletest/browser.php
Normal file
File diff suppressed because it is too large
Load diff
122
tests/simpletest/collector.php
Normal file
122
tests/simpletest/collector.php
Normal file
|
|
@ -0,0 +1,122 @@
|
|||
<?php
|
||||
/**
|
||||
* This file contains the following classes: {@link SimpleCollector},
|
||||
* {@link SimplePatternCollector}.
|
||||
*
|
||||
* @author Travis Swicegood <development@domain51.com>
|
||||
* @package SimpleTest
|
||||
* @subpackage UnitTester
|
||||
* @version $Id: collector.php 1723 2008-04-08 00:34:10Z lastcraft $
|
||||
*/
|
||||
|
||||
/**
|
||||
* The basic collector for {@link GroupTest}
|
||||
*
|
||||
* @see collect(), GroupTest::collect()
|
||||
* @package SimpleTest
|
||||
* @subpackage UnitTester
|
||||
*/
|
||||
class SimpleCollector {
|
||||
|
||||
/**
|
||||
* Strips off any kind of slash at the end so as to normalise the path.
|
||||
* @param string $path Path to normalise.
|
||||
* @return string Path without trailing slash.
|
||||
*/
|
||||
function _removeTrailingSlash($path) {
|
||||
if (substr($path, -1) == DIRECTORY_SEPARATOR) {
|
||||
return substr($path, 0, -1);
|
||||
} elseif (substr($path, -1) == '/') {
|
||||
return substr($path, 0, -1);
|
||||
} else {
|
||||
return $path;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Scans the directory and adds what it can.
|
||||
* @param object $test Group test with {@link GroupTest::addTestFile()} method.
|
||||
* @param string $path Directory to scan.
|
||||
* @see _attemptToAdd()
|
||||
*/
|
||||
function collect(&$test, $path) {
|
||||
$path = $this->_removeTrailingSlash($path);
|
||||
if ($handle = opendir($path)) {
|
||||
while (($entry = readdir($handle)) !== false) {
|
||||
if ($this->_isHidden($entry)) {
|
||||
continue;
|
||||
}
|
||||
$this->_handle($test, $path . DIRECTORY_SEPARATOR . $entry);
|
||||
}
|
||||
closedir($handle);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This method determines what should be done with a given file and adds
|
||||
* it via {@link GroupTest::addTestFile()} if necessary.
|
||||
*
|
||||
* This method should be overriden to provide custom matching criteria,
|
||||
* such as pattern matching, recursive matching, etc. For an example, see
|
||||
* {@link SimplePatternCollector::_handle()}.
|
||||
*
|
||||
* @param object $test Group test with {@link GroupTest::addTestFile()} method.
|
||||
* @param string $filename A filename as generated by {@link collect()}
|
||||
* @see collect()
|
||||
* @access protected
|
||||
*/
|
||||
function _handle(&$test, $file) {
|
||||
if (is_dir($file)) {
|
||||
return;
|
||||
}
|
||||
$test->addTestFile($file);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests for hidden files so as to skip them. Currently
|
||||
* only tests for Unix hidden files.
|
||||
* @param string $filename Plain filename.
|
||||
* @return boolean True if hidden file.
|
||||
* @access private
|
||||
*/
|
||||
function _isHidden($filename) {
|
||||
return strncmp($filename, '.', 1) == 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* An extension to {@link SimpleCollector} that only adds files matching a
|
||||
* given pattern.
|
||||
*
|
||||
* @package SimpleTest
|
||||
* @subpackage UnitTester
|
||||
* @see SimpleCollector
|
||||
*/
|
||||
class SimplePatternCollector extends SimpleCollector {
|
||||
var $_pattern;
|
||||
|
||||
/**
|
||||
*
|
||||
* @param string $pattern Perl compatible regex to test name against
|
||||
* See {@link http://us4.php.net/manual/en/reference.pcre.pattern.syntax.php PHP's PCRE}
|
||||
* for full documentation of valid pattern.s
|
||||
*/
|
||||
function SimplePatternCollector($pattern = '/php$/i') {
|
||||
$this->_pattern = $pattern;
|
||||
}
|
||||
|
||||
/**
|
||||
* Attempts to add files that match a given pattern.
|
||||
*
|
||||
* @see SimpleCollector::_handle()
|
||||
* @param object $test Group test with {@link GroupTest::addTestFile()} method.
|
||||
* @param string $path Directory to scan.
|
||||
* @access protected
|
||||
*/
|
||||
function _handle(&$test, $filename) {
|
||||
if (preg_match($this->_pattern, $filename)) {
|
||||
parent::_handle($test, $filename);
|
||||
}
|
||||
}
|
||||
}
|
||||
?>
|
||||
173
tests/simpletest/compatibility.php
Normal file
173
tests/simpletest/compatibility.php
Normal file
|
|
@ -0,0 +1,173 @@
|
|||
<?php
|
||||
/**
|
||||
* base include file for SimpleTest
|
||||
* @package SimpleTest
|
||||
* @version $Id: compatibility.php 1723 2008-04-08 00:34:10Z lastcraft $
|
||||
*/
|
||||
|
||||
/**
|
||||
* Static methods for compatibility between different
|
||||
* PHP versions.
|
||||
* @package SimpleTest
|
||||
*/
|
||||
class SimpleTestCompatibility {
|
||||
|
||||
/**
|
||||
* Creates a copy whether in PHP5 or PHP4.
|
||||
* @param object $object Thing to copy.
|
||||
* @return object A copy.
|
||||
* @access public
|
||||
* @static
|
||||
*/
|
||||
function copy($object) {
|
||||
if (version_compare(phpversion(), '5') >= 0) {
|
||||
eval('$copy = clone $object;');
|
||||
return $copy;
|
||||
}
|
||||
return $object;
|
||||
}
|
||||
|
||||
/**
|
||||
* Identity test. Drops back to equality + types for PHP5
|
||||
* objects as the === operator counts as the
|
||||
* stronger reference constraint.
|
||||
* @param mixed $first Test subject.
|
||||
* @param mixed $second Comparison object.
|
||||
* @return boolean True if identical.
|
||||
* @access public
|
||||
* @static
|
||||
*/
|
||||
function isIdentical($first, $second) {
|
||||
if (version_compare(phpversion(), '5') >= 0) {
|
||||
return SimpleTestCompatibility::_isIdenticalType($first, $second);
|
||||
}
|
||||
if ($first != $second) {
|
||||
return false;
|
||||
}
|
||||
return ($first === $second);
|
||||
}
|
||||
|
||||
/**
|
||||
* Recursive type test.
|
||||
* @param mixed $first Test subject.
|
||||
* @param mixed $second Comparison object.
|
||||
* @return boolean True if same type.
|
||||
* @access private
|
||||
* @static
|
||||
*/
|
||||
function _isIdenticalType($first, $second) {
|
||||
if (gettype($first) != gettype($second)) {
|
||||
return false;
|
||||
}
|
||||
if (is_object($first) && is_object($second)) {
|
||||
if (get_class($first) != get_class($second)) {
|
||||
return false;
|
||||
}
|
||||
return SimpleTestCompatibility::_isArrayOfIdenticalTypes(
|
||||
get_object_vars($first),
|
||||
get_object_vars($second));
|
||||
}
|
||||
if (is_array($first) && is_array($second)) {
|
||||
return SimpleTestCompatibility::_isArrayOfIdenticalTypes($first, $second);
|
||||
}
|
||||
if ($first !== $second) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Recursive type test for each element of an array.
|
||||
* @param mixed $first Test subject.
|
||||
* @param mixed $second Comparison object.
|
||||
* @return boolean True if identical.
|
||||
* @access private
|
||||
* @static
|
||||
*/
|
||||
function _isArrayOfIdenticalTypes($first, $second) {
|
||||
if (array_keys($first) != array_keys($second)) {
|
||||
return false;
|
||||
}
|
||||
foreach (array_keys($first) as $key) {
|
||||
$is_identical = SimpleTestCompatibility::_isIdenticalType(
|
||||
$first[$key],
|
||||
$second[$key]);
|
||||
if (! $is_identical) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Test for two variables being aliases.
|
||||
* @param mixed $first Test subject.
|
||||
* @param mixed $second Comparison object.
|
||||
* @return boolean True if same.
|
||||
* @access public
|
||||
* @static
|
||||
*/
|
||||
function isReference(&$first, &$second) {
|
||||
if (version_compare(phpversion(), '5', '>=') && is_object($first)) {
|
||||
return ($first === $second);
|
||||
}
|
||||
if (is_object($first) && is_object($second)) {
|
||||
$id = uniqid("test");
|
||||
$first->$id = true;
|
||||
$is_ref = isset($second->$id);
|
||||
unset($first->$id);
|
||||
return $is_ref;
|
||||
}
|
||||
$temp = $first;
|
||||
$first = uniqid("test");
|
||||
$is_ref = ($first === $second);
|
||||
$first = $temp;
|
||||
return $is_ref;
|
||||
}
|
||||
|
||||
/**
|
||||
* Test to see if an object is a member of a
|
||||
* class hiearchy.
|
||||
* @param object $object Object to test.
|
||||
* @param string $class Root name of hiearchy.
|
||||
* @return boolean True if class in hiearchy.
|
||||
* @access public
|
||||
* @static
|
||||
*/
|
||||
function isA($object, $class) {
|
||||
if (version_compare(phpversion(), '5') >= 0) {
|
||||
if (! class_exists($class, false)) {
|
||||
if (function_exists('interface_exists')) {
|
||||
if (! interface_exists($class, false)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
eval("\$is_a = \$object instanceof $class;");
|
||||
return $is_a;
|
||||
}
|
||||
if (function_exists('is_a')) {
|
||||
return is_a($object, $class);
|
||||
}
|
||||
return ((strtolower($class) == get_class($object))
|
||||
or (is_subclass_of($object, $class)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a socket timeout for each chunk.
|
||||
* @param resource $handle Socket handle.
|
||||
* @param integer $timeout Limit in seconds.
|
||||
* @access public
|
||||
* @static
|
||||
*/
|
||||
function setTimeout($handle, $timeout) {
|
||||
if (function_exists('stream_set_timeout')) {
|
||||
stream_set_timeout($handle, $timeout, 0);
|
||||
} elseif (function_exists('socket_set_timeout')) {
|
||||
socket_set_timeout($handle, $timeout, 0);
|
||||
} elseif (function_exists('set_socket_timeout')) {
|
||||
set_socket_timeout($handle, $timeout, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
?>
|
||||
380
tests/simpletest/cookies.php
Normal file
380
tests/simpletest/cookies.php
Normal file
|
|
@ -0,0 +1,380 @@
|
|||
<?php
|
||||
/**
|
||||
* Base include file for SimpleTest
|
||||
* @package SimpleTest
|
||||
* @subpackage WebTester
|
||||
* @version $Id: cookies.php 1723 2008-04-08 00:34:10Z lastcraft $
|
||||
*/
|
||||
|
||||
/**#@+
|
||||
* include other SimpleTest class files
|
||||
*/
|
||||
require_once(dirname(__FILE__) . '/url.php');
|
||||
/**#@-*/
|
||||
|
||||
/**
|
||||
* Cookie data holder. Cookie rules are full of pretty
|
||||
* arbitary stuff. I have used...
|
||||
* http://wp.netscape.com/newsref/std/cookie_spec.html
|
||||
* http://www.cookiecentral.com/faq/
|
||||
* @package SimpleTest
|
||||
* @subpackage WebTester
|
||||
*/
|
||||
class SimpleCookie {
|
||||
var $_host;
|
||||
var $_name;
|
||||
var $_value;
|
||||
var $_path;
|
||||
var $_expiry;
|
||||
var $_is_secure;
|
||||
|
||||
/**
|
||||
* Constructor. Sets the stored values.
|
||||
* @param string $name Cookie key.
|
||||
* @param string $value Value of cookie.
|
||||
* @param string $path Cookie path if not host wide.
|
||||
* @param string $expiry Expiry date as string.
|
||||
* @param boolean $is_secure Currently ignored.
|
||||
*/
|
||||
function SimpleCookie($name, $value = false, $path = false, $expiry = false, $is_secure = false) {
|
||||
$this->_host = false;
|
||||
$this->_name = $name;
|
||||
$this->_value = $value;
|
||||
$this->_path = ($path ? $this->_fixPath($path) : "/");
|
||||
$this->_expiry = false;
|
||||
if (is_string($expiry)) {
|
||||
$this->_expiry = strtotime($expiry);
|
||||
} elseif (is_integer($expiry)) {
|
||||
$this->_expiry = $expiry;
|
||||
}
|
||||
$this->_is_secure = $is_secure;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the host. The cookie rules determine
|
||||
* that the first two parts are taken for
|
||||
* certain TLDs and three for others. If the
|
||||
* new host does not match these rules then the
|
||||
* call will fail.
|
||||
* @param string $host New hostname.
|
||||
* @return boolean True if hostname is valid.
|
||||
* @access public
|
||||
*/
|
||||
function setHost($host) {
|
||||
if ($host = $this->_truncateHost($host)) {
|
||||
$this->_host = $host;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for the truncated host to which this
|
||||
* cookie applies.
|
||||
* @return string Truncated hostname.
|
||||
* @access public
|
||||
*/
|
||||
function getHost() {
|
||||
return $this->_host;
|
||||
}
|
||||
|
||||
/**
|
||||
* Test for a cookie being valid for a host name.
|
||||
* @param string $host Host to test against.
|
||||
* @return boolean True if the cookie would be valid
|
||||
* here.
|
||||
*/
|
||||
function isValidHost($host) {
|
||||
return ($this->_truncateHost($host) === $this->getHost());
|
||||
}
|
||||
|
||||
/**
|
||||
* Extracts just the domain part that determines a
|
||||
* cookie's host validity.
|
||||
* @param string $host Host name to truncate.
|
||||
* @return string Domain or false on a bad host.
|
||||
* @access private
|
||||
*/
|
||||
function _truncateHost($host) {
|
||||
$tlds = SimpleUrl::getAllTopLevelDomains();
|
||||
if (preg_match('/[a-z\-]+\.(' . $tlds . ')$/i', $host, $matches)) {
|
||||
return $matches[0];
|
||||
} elseif (preg_match('/[a-z\-]+\.[a-z\-]+\.[a-z\-]+$/i', $host, $matches)) {
|
||||
return $matches[0];
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for name.
|
||||
* @return string Cookie key.
|
||||
* @access public
|
||||
*/
|
||||
function getName() {
|
||||
return $this->_name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for value. A deleted cookie will
|
||||
* have an empty string for this.
|
||||
* @return string Cookie value.
|
||||
* @access public
|
||||
*/
|
||||
function getValue() {
|
||||
return $this->_value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for path.
|
||||
* @return string Valid cookie path.
|
||||
* @access public
|
||||
*/
|
||||
function getPath() {
|
||||
return $this->_path;
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests a path to see if the cookie applies
|
||||
* there. The test path must be longer or
|
||||
* equal to the cookie path.
|
||||
* @param string $path Path to test against.
|
||||
* @return boolean True if cookie valid here.
|
||||
* @access public
|
||||
*/
|
||||
function isValidPath($path) {
|
||||
return (strncmp(
|
||||
$this->_fixPath($path),
|
||||
$this->getPath(),
|
||||
strlen($this->getPath())) == 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for expiry.
|
||||
* @return string Expiry string.
|
||||
* @access public
|
||||
*/
|
||||
function getExpiry() {
|
||||
if (! $this->_expiry) {
|
||||
return false;
|
||||
}
|
||||
return gmdate("D, d M Y H:i:s", $this->_expiry) . " GMT";
|
||||
}
|
||||
|
||||
/**
|
||||
* Test to see if cookie is expired against
|
||||
* the cookie format time or timestamp.
|
||||
* Will give true for a session cookie.
|
||||
* @param integer/string $now Time to test against. Result
|
||||
* will be false if this time
|
||||
* is later than the cookie expiry.
|
||||
* Can be either a timestamp integer
|
||||
* or a cookie format date.
|
||||
* @access public
|
||||
*/
|
||||
function isExpired($now) {
|
||||
if (! $this->_expiry) {
|
||||
return true;
|
||||
}
|
||||
if (is_string($now)) {
|
||||
$now = strtotime($now);
|
||||
}
|
||||
return ($this->_expiry < $now);
|
||||
}
|
||||
|
||||
/**
|
||||
* Ages the cookie by the specified number of
|
||||
* seconds.
|
||||
* @param integer $interval In seconds.
|
||||
* @public
|
||||
*/
|
||||
function agePrematurely($interval) {
|
||||
if ($this->_expiry) {
|
||||
$this->_expiry -= $interval;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for the secure flag.
|
||||
* @return boolean True if cookie needs SSL.
|
||||
* @access public
|
||||
*/
|
||||
function isSecure() {
|
||||
return $this->_is_secure;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a trailing and leading slash to the path
|
||||
* if missing.
|
||||
* @param string $path Path to fix.
|
||||
* @access private
|
||||
*/
|
||||
function _fixPath($path) {
|
||||
if (substr($path, 0, 1) != '/') {
|
||||
$path = '/' . $path;
|
||||
}
|
||||
if (substr($path, -1, 1) != '/') {
|
||||
$path .= '/';
|
||||
}
|
||||
return $path;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Repository for cookies. This stuff is a
|
||||
* tiny bit browser dependent.
|
||||
* @package SimpleTest
|
||||
* @subpackage WebTester
|
||||
*/
|
||||
class SimpleCookieJar {
|
||||
var $_cookies;
|
||||
|
||||
/**
|
||||
* Constructor. Jar starts empty.
|
||||
* @access public
|
||||
*/
|
||||
function SimpleCookieJar() {
|
||||
$this->_cookies = array();
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes expired and temporary cookies as if
|
||||
* the browser was closed and re-opened.
|
||||
* @param string/integer $now Time to test expiry against.
|
||||
* @access public
|
||||
*/
|
||||
function restartSession($date = false) {
|
||||
$surviving_cookies = array();
|
||||
for ($i = 0; $i < count($this->_cookies); $i++) {
|
||||
if (! $this->_cookies[$i]->getValue()) {
|
||||
continue;
|
||||
}
|
||||
if (! $this->_cookies[$i]->getExpiry()) {
|
||||
continue;
|
||||
}
|
||||
if ($date && $this->_cookies[$i]->isExpired($date)) {
|
||||
continue;
|
||||
}
|
||||
$surviving_cookies[] = $this->_cookies[$i];
|
||||
}
|
||||
$this->_cookies = $surviving_cookies;
|
||||
}
|
||||
|
||||
/**
|
||||
* Ages all cookies in the cookie jar.
|
||||
* @param integer $interval The old session is moved
|
||||
* into the past by this number
|
||||
* of seconds. Cookies now over
|
||||
* age will be removed.
|
||||
* @access public
|
||||
*/
|
||||
function agePrematurely($interval) {
|
||||
for ($i = 0; $i < count($this->_cookies); $i++) {
|
||||
$this->_cookies[$i]->agePrematurely($interval);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets an additional cookie. If a cookie has
|
||||
* the same name and path it is replaced.
|
||||
* @param string $name Cookie key.
|
||||
* @param string $value Value of cookie.
|
||||
* @param string $host Host upon which the cookie is valid.
|
||||
* @param string $path Cookie path if not host wide.
|
||||
* @param string $expiry Expiry date.
|
||||
* @access public
|
||||
*/
|
||||
function setCookie($name, $value, $host = false, $path = '/', $expiry = false) {
|
||||
$cookie = new SimpleCookie($name, $value, $path, $expiry);
|
||||
if ($host) {
|
||||
$cookie->setHost($host);
|
||||
}
|
||||
$this->_cookies[$this->_findFirstMatch($cookie)] = $cookie;
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds a matching cookie to write over or the
|
||||
* first empty slot if none.
|
||||
* @param SimpleCookie $cookie Cookie to write into jar.
|
||||
* @return integer Available slot.
|
||||
* @access private
|
||||
*/
|
||||
function _findFirstMatch($cookie) {
|
||||
for ($i = 0; $i < count($this->_cookies); $i++) {
|
||||
$is_match = $this->_isMatch(
|
||||
$cookie,
|
||||
$this->_cookies[$i]->getHost(),
|
||||
$this->_cookies[$i]->getPath(),
|
||||
$this->_cookies[$i]->getName());
|
||||
if ($is_match) {
|
||||
return $i;
|
||||
}
|
||||
}
|
||||
return count($this->_cookies);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads the most specific cookie value from the
|
||||
* browser cookies. Looks for the longest path that
|
||||
* matches.
|
||||
* @param string $host Host to search.
|
||||
* @param string $path Applicable path.
|
||||
* @param string $name Name of cookie to read.
|
||||
* @return string False if not present, else the
|
||||
* value as a string.
|
||||
* @access public
|
||||
*/
|
||||
function getCookieValue($host, $path, $name) {
|
||||
$longest_path = '';
|
||||
foreach ($this->_cookies as $cookie) {
|
||||
if ($this->_isMatch($cookie, $host, $path, $name)) {
|
||||
if (strlen($cookie->getPath()) > strlen($longest_path)) {
|
||||
$value = $cookie->getValue();
|
||||
$longest_path = $cookie->getPath();
|
||||
}
|
||||
}
|
||||
}
|
||||
return (isset($value) ? $value : false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests cookie for matching against search
|
||||
* criteria.
|
||||
* @param SimpleTest $cookie Cookie to test.
|
||||
* @param string $host Host must match.
|
||||
* @param string $path Cookie path must be shorter than
|
||||
* this path.
|
||||
* @param string $name Name must match.
|
||||
* @return boolean True if matched.
|
||||
* @access private
|
||||
*/
|
||||
function _isMatch($cookie, $host, $path, $name) {
|
||||
if ($cookie->getName() != $name) {
|
||||
return false;
|
||||
}
|
||||
if ($host && $cookie->getHost() && ! $cookie->isValidHost($host)) {
|
||||
return false;
|
||||
}
|
||||
if (! $cookie->isValidPath($path)) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Uses a URL to sift relevant cookies by host and
|
||||
* path. Results are list of strings of form "name=value".
|
||||
* @param SimpleUrl $url Url to select by.
|
||||
* @return array Valid name and value pairs.
|
||||
* @access public
|
||||
*/
|
||||
function selectAsPairs($url) {
|
||||
$pairs = array();
|
||||
foreach ($this->_cookies as $cookie) {
|
||||
if ($this->_isMatch($cookie, $url->getHost(), $url->getPath(), $cookie->getName())) {
|
||||
$pairs[] = $cookie->getName() . '=' . $cookie->getValue();
|
||||
}
|
||||
}
|
||||
return $pairs;
|
||||
}
|
||||
}
|
||||
?>
|
||||
133
tests/simpletest/default_reporter.php
Normal file
133
tests/simpletest/default_reporter.php
Normal file
|
|
@ -0,0 +1,133 @@
|
|||
<?php
|
||||
/**
|
||||
* Optional include file for SimpleTest
|
||||
* @package SimpleTest
|
||||
* @subpackage UnitTester
|
||||
* @version $Id: default_reporter.php 1704 2008-03-25 00:47:04Z lastcraft $
|
||||
*/
|
||||
|
||||
/**#@+
|
||||
* include other SimpleTest class files
|
||||
*/
|
||||
require_once(dirname(__FILE__) . '/simpletest.php');
|
||||
require_once(dirname(__FILE__) . '/scorer.php');
|
||||
require_once(dirname(__FILE__) . '/reporter.php');
|
||||
require_once(dirname(__FILE__) . '/xml.php');
|
||||
/**#@-*/
|
||||
|
||||
/**
|
||||
* Parser for command line arguments. Extracts
|
||||
* the a specific test to run and engages XML
|
||||
* reporting when necessary.
|
||||
* @package SimpleTest
|
||||
* @subpackage UnitTester
|
||||
*/
|
||||
class SimpleCommandLineParser {
|
||||
var $_to_property = array(
|
||||
'case' => '_case', 'c' => '_case',
|
||||
'test' => '_test', 't' => '_test',
|
||||
'xml' => '_xml', 'x' => '_xml');
|
||||
var $_case = '';
|
||||
var $_test = '';
|
||||
var $_xml = false;
|
||||
var $_no_skips = false;
|
||||
|
||||
/**
|
||||
* Parses raw command line arguments into object properties.
|
||||
* @param string $arguments Raw commend line arguments.
|
||||
*/
|
||||
function SimpleCommandLineParser($arguments) {
|
||||
if (! is_array($arguments)) {
|
||||
return;
|
||||
}
|
||||
foreach ($arguments as $i => $argument) {
|
||||
if (preg_match('/^--?(test|case|t|c)=(.+)$/', $argument, $matches)) {
|
||||
$property = $this->_to_property[$matches[1]];
|
||||
$this->$property = $matches[2];
|
||||
} elseif (preg_match('/^--?(test|case|t|c)$/', $argument, $matches)) {
|
||||
$property = $this->_to_property[$matches[1]];
|
||||
if (isset($arguments[$i + 1])) {
|
||||
$this->$property = $arguments[$i + 1];
|
||||
}
|
||||
} elseif (preg_match('/^--?(xml|x)$/', $argument)) {
|
||||
$this->_xml = true;
|
||||
} elseif (preg_match('/^--?(no-skip|no-skips|s)$/', $argument)) {
|
||||
$this->_no_skips = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Run only this test.
|
||||
* @return string Test name to run.
|
||||
* @access public
|
||||
*/
|
||||
function getTest() {
|
||||
return $this->_test;
|
||||
}
|
||||
|
||||
/**
|
||||
* Run only this test suite.
|
||||
* @return string Test class name to run.
|
||||
* @access public
|
||||
*/
|
||||
function getTestCase() {
|
||||
return $this->_case;
|
||||
}
|
||||
|
||||
/**
|
||||
* Output should be XML or not.
|
||||
* @return boolean True if XML desired.
|
||||
* @access public
|
||||
*/
|
||||
function isXml() {
|
||||
return $this->_xml;
|
||||
}
|
||||
|
||||
/**
|
||||
* Output should suppress skip messages.
|
||||
* @return boolean True for no skips.
|
||||
* @access public
|
||||
*/
|
||||
function noSkips() {
|
||||
return $this->_no_skips;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The default reporter used by SimpleTest's autorun
|
||||
* feature. The actual reporters used are dependency
|
||||
* injected and can be overridden.
|
||||
* @package SimpleTest
|
||||
* @subpackage UnitTester
|
||||
*/
|
||||
class DefaultReporter extends SimpleReporterDecorator {
|
||||
|
||||
/**
|
||||
* Assembles the appopriate reporter for the environment.
|
||||
*/
|
||||
function DefaultReporter() {
|
||||
if (SimpleReporter::inCli()) {
|
||||
global $argv;
|
||||
$parser = new SimpleCommandLineParser($argv);
|
||||
$interfaces = $parser->isXml() ? array('XmlReporter') : array('TextReporter');
|
||||
$reporter = &new SelectiveReporter(
|
||||
SimpleTest::preferred($interfaces),
|
||||
$parser->getTestCase(),
|
||||
$parser->getTest());
|
||||
if ($parser->noSkips()) {
|
||||
$reporter = &new NoSkipsReporter($reporter);
|
||||
}
|
||||
} else {
|
||||
$reporter = &new SelectiveReporter(
|
||||
SimpleTest::preferred('HtmlReporter'),
|
||||
@$_GET['c'],
|
||||
@$_GET['t']);
|
||||
if (@$_GET['skips'] == 'no' || @$_GET['show-skips'] == 'no') {
|
||||
$reporter = &new NoSkipsReporter($reporter);
|
||||
}
|
||||
}
|
||||
$this->SimpleReporterDecorator($reporter);
|
||||
}
|
||||
}
|
||||
?>
|
||||
96
tests/simpletest/detached.php
Normal file
96
tests/simpletest/detached.php
Normal file
|
|
@ -0,0 +1,96 @@
|
|||
<?php
|
||||
/**
|
||||
* base include file for SimpleTest
|
||||
* @package SimpleTest
|
||||
* @subpackage UnitTester
|
||||
* @version $Id: detached.php 1723 2008-04-08 00:34:10Z lastcraft $
|
||||
*/
|
||||
|
||||
/**#@+
|
||||
* include other SimpleTest class files
|
||||
*/
|
||||
require_once(dirname(__FILE__) . '/xml.php');
|
||||
require_once(dirname(__FILE__) . '/shell_tester.php');
|
||||
/**#@-*/
|
||||
|
||||
/**
|
||||
* Runs an XML formated test in a separate process.
|
||||
* @package SimpleTest
|
||||
* @subpackage UnitTester
|
||||
*/
|
||||
class DetachedTestCase {
|
||||
var $_command;
|
||||
var $_dry_command;
|
||||
var $_size;
|
||||
|
||||
/**
|
||||
* Sets the location of the remote test.
|
||||
* @param string $command Test script.
|
||||
* @param string $dry_command Script for dry run.
|
||||
* @access public
|
||||
*/
|
||||
function DetachedTestCase($command, $dry_command = false) {
|
||||
$this->_command = $command;
|
||||
$this->_dry_command = $dry_command ? $dry_command : $command;
|
||||
$this->_size = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for the test name for subclasses.
|
||||
* @return string Name of the test.
|
||||
* @access public
|
||||
*/
|
||||
function getLabel() {
|
||||
return $this->_command;
|
||||
}
|
||||
|
||||
/**
|
||||
* Runs the top level test for this class. Currently
|
||||
* reads the data as a single chunk. I'll fix this
|
||||
* once I have added iteration to the browser.
|
||||
* @param SimpleReporter $reporter Target of test results.
|
||||
* @returns boolean True if no failures.
|
||||
* @access public
|
||||
*/
|
||||
function run(&$reporter) {
|
||||
$shell = &new SimpleShell();
|
||||
$shell->execute($this->_command);
|
||||
$parser = &$this->_createParser($reporter);
|
||||
if (! $parser->parse($shell->getOutput())) {
|
||||
trigger_error('Cannot parse incoming XML from [' . $this->_command . ']');
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for the number of subtests.
|
||||
* @return integer Number of test cases.
|
||||
* @access public
|
||||
*/
|
||||
function getSize() {
|
||||
if ($this->_size === false) {
|
||||
$shell = &new SimpleShell();
|
||||
$shell->execute($this->_dry_command);
|
||||
$reporter = &new SimpleReporter();
|
||||
$parser = &$this->_createParser($reporter);
|
||||
if (! $parser->parse($shell->getOutput())) {
|
||||
trigger_error('Cannot parse incoming XML from [' . $this->_dry_command . ']');
|
||||
return false;
|
||||
}
|
||||
$this->_size = $reporter->getTestCaseCount();
|
||||
}
|
||||
return $this->_size;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates the XML parser.
|
||||
* @param SimpleReporter $reporter Target of test results.
|
||||
* @return SimpleTestXmlListener XML reader.
|
||||
* @access protected
|
||||
*/
|
||||
function &_createParser(&$reporter) {
|
||||
return new SimpleTestXmlParser($reporter);
|
||||
}
|
||||
}
|
||||
?>
|
||||
360
tests/simpletest/dumper.php
Normal file
360
tests/simpletest/dumper.php
Normal file
|
|
@ -0,0 +1,360 @@
|
|||
<?php
|
||||
/**
|
||||
* base include file for SimpleTest
|
||||
* @package SimpleTest
|
||||
* @subpackage UnitTester
|
||||
* @version $Id: dumper.php 1723 2008-04-08 00:34:10Z lastcraft $
|
||||
*/
|
||||
/**
|
||||
* does type matter
|
||||
*/
|
||||
if (! defined('TYPE_MATTERS')) {
|
||||
define('TYPE_MATTERS', true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Displays variables as text and does diffs.
|
||||
* @package SimpleTest
|
||||
* @subpackage UnitTester
|
||||
*/
|
||||
class SimpleDumper {
|
||||
|
||||
/**
|
||||
* Renders a variable in a shorter form than print_r().
|
||||
* @param mixed $value Variable to render as a string.
|
||||
* @return string Human readable string form.
|
||||
* @access public
|
||||
*/
|
||||
function describeValue($value) {
|
||||
$type = $this->getType($value);
|
||||
switch($type) {
|
||||
case "Null":
|
||||
return "NULL";
|
||||
case "Boolean":
|
||||
return "Boolean: " . ($value ? "true" : "false");
|
||||
case "Array":
|
||||
return "Array: " . count($value) . " items";
|
||||
case "Object":
|
||||
return "Object: of " . get_class($value);
|
||||
case "String":
|
||||
return "String: " . $this->clipString($value, 200);
|
||||
default:
|
||||
return "$type: $value";
|
||||
}
|
||||
return "Unknown";
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the string representation of a type.
|
||||
* @param mixed $value Variable to check against.
|
||||
* @return string Type.
|
||||
* @access public
|
||||
*/
|
||||
function getType($value) {
|
||||
if (! isset($value)) {
|
||||
return "Null";
|
||||
} elseif (is_bool($value)) {
|
||||
return "Boolean";
|
||||
} elseif (is_string($value)) {
|
||||
return "String";
|
||||
} elseif (is_integer($value)) {
|
||||
return "Integer";
|
||||
} elseif (is_float($value)) {
|
||||
return "Float";
|
||||
} elseif (is_array($value)) {
|
||||
return "Array";
|
||||
} elseif (is_resource($value)) {
|
||||
return "Resource";
|
||||
} elseif (is_object($value)) {
|
||||
return "Object";
|
||||
}
|
||||
return "Unknown";
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a human readable description of the
|
||||
* difference between two variables. Uses a
|
||||
* dynamic call.
|
||||
* @param mixed $first First variable.
|
||||
* @param mixed $second Value to compare with.
|
||||
* @param boolean $identical If true then type anomolies count.
|
||||
* @return string Description of difference.
|
||||
* @access public
|
||||
*/
|
||||
function describeDifference($first, $second, $identical = false) {
|
||||
if ($identical) {
|
||||
if (! $this->_isTypeMatch($first, $second)) {
|
||||
return "with type mismatch as [" . $this->describeValue($first) .
|
||||
"] does not match [" . $this->describeValue($second) . "]";
|
||||
}
|
||||
}
|
||||
$type = $this->getType($first);
|
||||
if ($type == "Unknown") {
|
||||
return "with unknown type";
|
||||
}
|
||||
$method = '_describe' . $type . 'Difference';
|
||||
return $this->$method($first, $second, $identical);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests to see if types match.
|
||||
* @param mixed $first First variable.
|
||||
* @param mixed $second Value to compare with.
|
||||
* @return boolean True if matches.
|
||||
* @access private
|
||||
*/
|
||||
function _isTypeMatch($first, $second) {
|
||||
return ($this->getType($first) == $this->getType($second));
|
||||
}
|
||||
|
||||
/**
|
||||
* Clips a string to a maximum length.
|
||||
* @param string $value String to truncate.
|
||||
* @param integer $size Minimum string size to show.
|
||||
* @param integer $position Centre of string section.
|
||||
* @return string Shortened version.
|
||||
* @access public
|
||||
*/
|
||||
function clipString($value, $size, $position = 0) {
|
||||
$length = strlen($value);
|
||||
if ($length <= $size) {
|
||||
return $value;
|
||||
}
|
||||
$position = min($position, $length);
|
||||
$start = ($size/2 > $position ? 0 : $position - $size/2);
|
||||
if ($start + $size > $length) {
|
||||
$start = $length - $size;
|
||||
}
|
||||
$value = substr($value, $start, $size);
|
||||
return ($start > 0 ? "..." : "") . $value . ($start + $size < $length ? "..." : "");
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a human readable description of the
|
||||
* difference between two variables. The minimal
|
||||
* version.
|
||||
* @param null $first First value.
|
||||
* @param mixed $second Value to compare with.
|
||||
* @return string Human readable description.
|
||||
* @access private
|
||||
*/
|
||||
function _describeGenericDifference($first, $second) {
|
||||
return "as [" . $this->describeValue($first) .
|
||||
"] does not match [" .
|
||||
$this->describeValue($second) . "]";
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a human readable description of the
|
||||
* difference between a null and another variable.
|
||||
* @param null $first First null.
|
||||
* @param mixed $second Null to compare with.
|
||||
* @param boolean $identical If true then type anomolies count.
|
||||
* @return string Human readable description.
|
||||
* @access private
|
||||
*/
|
||||
function _describeNullDifference($first, $second, $identical) {
|
||||
return $this->_describeGenericDifference($first, $second);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a human readable description of the
|
||||
* difference between a boolean and another variable.
|
||||
* @param boolean $first First boolean.
|
||||
* @param mixed $second Boolean to compare with.
|
||||
* @param boolean $identical If true then type anomolies count.
|
||||
* @return string Human readable description.
|
||||
* @access private
|
||||
*/
|
||||
function _describeBooleanDifference($first, $second, $identical) {
|
||||
return $this->_describeGenericDifference($first, $second);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a human readable description of the
|
||||
* difference between a string and another variable.
|
||||
* @param string $first First string.
|
||||
* @param mixed $second String to compare with.
|
||||
* @param boolean $identical If true then type anomolies count.
|
||||
* @return string Human readable description.
|
||||
* @access private
|
||||
*/
|
||||
function _describeStringDifference($first, $second, $identical) {
|
||||
if (is_object($second) || is_array($second)) {
|
||||
return $this->_describeGenericDifference($first, $second);
|
||||
}
|
||||
$position = $this->_stringDiffersAt($first, $second);
|
||||
$message = "at character $position";
|
||||
$message .= " with [" .
|
||||
$this->clipString($first, 200, $position) . "] and [" .
|
||||
$this->clipString($second, 200, $position) . "]";
|
||||
return $message;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a human readable description of the
|
||||
* difference between an integer and another variable.
|
||||
* @param integer $first First number.
|
||||
* @param mixed $second Number to compare with.
|
||||
* @param boolean $identical If true then type anomolies count.
|
||||
* @return string Human readable description.
|
||||
* @access private
|
||||
*/
|
||||
function _describeIntegerDifference($first, $second, $identical) {
|
||||
if (is_object($second) || is_array($second)) {
|
||||
return $this->_describeGenericDifference($first, $second);
|
||||
}
|
||||
return "because [" . $this->describeValue($first) .
|
||||
"] differs from [" .
|
||||
$this->describeValue($second) . "] by " .
|
||||
abs($first - $second);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a human readable description of the
|
||||
* difference between two floating point numbers.
|
||||
* @param float $first First float.
|
||||
* @param mixed $second Float to compare with.
|
||||
* @param boolean $identical If true then type anomolies count.
|
||||
* @return string Human readable description.
|
||||
* @access private
|
||||
*/
|
||||
function _describeFloatDifference($first, $second, $identical) {
|
||||
if (is_object($second) || is_array($second)) {
|
||||
return $this->_describeGenericDifference($first, $second);
|
||||
}
|
||||
return "because [" . $this->describeValue($first) .
|
||||
"] differs from [" .
|
||||
$this->describeValue($second) . "] by " .
|
||||
abs($first - $second);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a human readable description of the
|
||||
* difference between two arrays.
|
||||
* @param array $first First array.
|
||||
* @param mixed $second Array to compare with.
|
||||
* @param boolean $identical If true then type anomolies count.
|
||||
* @return string Human readable description.
|
||||
* @access private
|
||||
*/
|
||||
function _describeArrayDifference($first, $second, $identical) {
|
||||
if (! is_array($second)) {
|
||||
return $this->_describeGenericDifference($first, $second);
|
||||
}
|
||||
if (! $this->_isMatchingKeys($first, $second, $identical)) {
|
||||
return "as key list [" .
|
||||
implode(", ", array_keys($first)) . "] does not match key list [" .
|
||||
implode(", ", array_keys($second)) . "]";
|
||||
}
|
||||
foreach (array_keys($first) as $key) {
|
||||
if ($identical && ($first[$key] === $second[$key])) {
|
||||
continue;
|
||||
}
|
||||
if (! $identical && ($first[$key] == $second[$key])) {
|
||||
continue;
|
||||
}
|
||||
return "with member [$key] " . $this->describeDifference(
|
||||
$first[$key],
|
||||
$second[$key],
|
||||
$identical);
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
/**
|
||||
* Compares two arrays to see if their key lists match.
|
||||
* For an identical match, the ordering and types of the keys
|
||||
* is significant.
|
||||
* @param array $first First array.
|
||||
* @param array $second Array to compare with.
|
||||
* @param boolean $identical If true then type anomolies count.
|
||||
* @return boolean True if matching.
|
||||
* @access private
|
||||
*/
|
||||
function _isMatchingKeys($first, $second, $identical) {
|
||||
$first_keys = array_keys($first);
|
||||
$second_keys = array_keys($second);
|
||||
if ($identical) {
|
||||
return ($first_keys === $second_keys);
|
||||
}
|
||||
sort($first_keys);
|
||||
sort($second_keys);
|
||||
return ($first_keys == $second_keys);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a human readable description of the
|
||||
* difference between a resource and another variable.
|
||||
* @param resource $first First resource.
|
||||
* @param mixed $second Resource to compare with.
|
||||
* @param boolean $identical If true then type anomolies count.
|
||||
* @return string Human readable description.
|
||||
* @access private
|
||||
*/
|
||||
function _describeResourceDifference($first, $second, $identical) {
|
||||
return $this->_describeGenericDifference($first, $second);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a human readable description of the
|
||||
* difference between two objects.
|
||||
* @param object $first First object.
|
||||
* @param mixed $second Object to compare with.
|
||||
* @param boolean $identical If true then type anomolies count.
|
||||
* @return string Human readable description.
|
||||
* @access private
|
||||
*/
|
||||
function _describeObjectDifference($first, $second, $identical) {
|
||||
if (! is_object($second)) {
|
||||
return $this->_describeGenericDifference($first, $second);
|
||||
}
|
||||
return $this->_describeArrayDifference(
|
||||
get_object_vars($first),
|
||||
get_object_vars($second),
|
||||
$identical);
|
||||
}
|
||||
|
||||
/**
|
||||
* Find the first character position that differs
|
||||
* in two strings by binary chop.
|
||||
* @param string $first First string.
|
||||
* @param string $second String to compare with.
|
||||
* @return integer Position of first differing
|
||||
* character.
|
||||
* @access private
|
||||
*/
|
||||
function _stringDiffersAt($first, $second) {
|
||||
if (! $first || ! $second) {
|
||||
return 0;
|
||||
}
|
||||
if (strlen($first) < strlen($second)) {
|
||||
list($first, $second) = array($second, $first);
|
||||
}
|
||||
$position = 0;
|
||||
$step = strlen($first);
|
||||
while ($step > 1) {
|
||||
$step = (integer)(($step + 1) / 2);
|
||||
if (strncmp($first, $second, $position + $step) == 0) {
|
||||
$position += $step;
|
||||
}
|
||||
}
|
||||
return $position;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends a formatted dump of a variable to a string.
|
||||
* @param mixed $variable Variable to display.
|
||||
* @return string Output from print_r().
|
||||
* @access public
|
||||
* @static
|
||||
*/
|
||||
function dump($variable) {
|
||||
ob_start();
|
||||
print_r($variable);
|
||||
$formatted = ob_get_contents();
|
||||
ob_end_clean();
|
||||
return $formatted;
|
||||
}
|
||||
}
|
||||
?>
|
||||
307
tests/simpletest/eclipse.php
Normal file
307
tests/simpletest/eclipse.php
Normal file
|
|
@ -0,0 +1,307 @@
|
|||
<?php
|
||||
/**
|
||||
* base include file for eclipse plugin
|
||||
* @package SimpleTest
|
||||
* @subpackage Eclipse
|
||||
* @version $Id: eclipse.php 1723 2008-04-08 00:34:10Z lastcraft $
|
||||
*/
|
||||
/**#@+
|
||||
* simpletest include files
|
||||
*/
|
||||
include_once 'unit_tester.php';
|
||||
include_once 'test_case.php';
|
||||
include_once 'invoker.php';
|
||||
include_once 'socket.php';
|
||||
include_once 'mock_objects.php';
|
||||
/**#@-*/
|
||||
|
||||
/**
|
||||
* base reported class for eclipse plugin
|
||||
* @package SimpleTest
|
||||
* @subpackage Eclipse
|
||||
*/
|
||||
class EclipseReporter extends SimpleScorer {
|
||||
|
||||
/**
|
||||
* Reporter to be run inside of Eclipse interface.
|
||||
* @param object $listener Eclipse listener (?).
|
||||
* @param boolean $cc Whether to include test coverage.
|
||||
*/
|
||||
function EclipseReporter(&$listener, $cc=false){
|
||||
$this->_listener = &$listener;
|
||||
$this->SimpleScorer();
|
||||
$this->_case = "";
|
||||
$this->_group = "";
|
||||
$this->_method = "";
|
||||
$this->_cc = $cc;
|
||||
$this->_error = false;
|
||||
$this->_fail = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Means to display human readable object comparisons.
|
||||
* @return SimpleDumper Visual comparer.
|
||||
*/
|
||||
function getDumper() {
|
||||
return new SimpleDumper();
|
||||
}
|
||||
|
||||
/**
|
||||
* Localhost connection from Eclipse.
|
||||
* @param integer $port Port to connect to Eclipse.
|
||||
* @param string $host Normally localhost.
|
||||
* @return SimpleSocket Connection to Eclipse.
|
||||
*/
|
||||
function &createListener($port, $host="127.0.0.1"){
|
||||
$tmplistener = &new SimpleSocket($host, $port, 5);
|
||||
return $tmplistener;
|
||||
}
|
||||
|
||||
/**
|
||||
* Wraps the test in an output buffer.
|
||||
* @param SimpleInvoker $invoker Current test runner.
|
||||
* @return EclipseInvoker Decorator with output buffering.
|
||||
* @access public
|
||||
*/
|
||||
function &createInvoker(&$invoker){
|
||||
$eclinvoker = &new EclipseInvoker($invoker, $this->_listener);
|
||||
return $eclinvoker;
|
||||
}
|
||||
|
||||
/**
|
||||
* C style escaping.
|
||||
* @param string $raw String with backslashes, quotes and whitespace.
|
||||
* @return string Replaced with C backslashed tokens.
|
||||
*/
|
||||
function escapeVal($raw){
|
||||
$needle = array("\\","\"","/","\b","\f","\n","\r","\t");
|
||||
$replace = array('\\\\','\"','\/','\b','\f','\n','\r','\t');
|
||||
return str_replace($needle, $replace, $raw);
|
||||
}
|
||||
|
||||
/**
|
||||
* Stash the first passing item. Clicking the test
|
||||
* item goes to first pass.
|
||||
* @param string $message Test message, but we only wnat the first.
|
||||
* @access public
|
||||
*/
|
||||
function paintPass($message){
|
||||
if (! $this->_pass){
|
||||
$this->_message = $this->escapeVal($message);
|
||||
}
|
||||
$this->_pass = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Stash the first failing item. Clicking the test
|
||||
* item goes to first fail.
|
||||
* @param string $message Test message, but we only wnat the first.
|
||||
* @access public
|
||||
*/
|
||||
function paintFail($message){
|
||||
//only get the first failure or error
|
||||
if (! $this->_fail && ! $this->_error){
|
||||
$this->_fail = true;
|
||||
$this->_message = $this->escapeVal($message);
|
||||
$this->_listener->write('{status:"fail",message:"'.$this->_message.'",group:"'.$this->_group.'",case:"'.$this->_case.'",method:"'.$this->_method.'"}');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Stash the first error. Clicking the test
|
||||
* item goes to first error.
|
||||
* @param string $message Test message, but we only wnat the first.
|
||||
* @access public
|
||||
*/
|
||||
function paintError($message){
|
||||
if (! $this->_fail && ! $this->_error){
|
||||
$this->_error = true;
|
||||
$this->_message = $this->escapeVal($message);
|
||||
$this->_listener->write('{status:"error",message:"'.$this->_message.'",group:"'.$this->_group.'",case:"'.$this->_case.'",method:"'.$this->_method.'"}');
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Stash the first exception. Clicking the test
|
||||
* item goes to first message.
|
||||
* @param string $message Test message, but we only wnat the first.
|
||||
* @access public
|
||||
*/
|
||||
function paintException($exception){
|
||||
if (! $this->_fail && ! $this->_error){
|
||||
$this->_error = true;
|
||||
$message = 'Unexpected exception of type[' . get_class($exception) .
|
||||
'] with message [' . $exception->getMessage() . '] in [' .
|
||||
$exception->getFile() .' line '. $exception->getLine() . ']';
|
||||
$this->_message = $this->escapeVal($message);
|
||||
$this->_listener->write(
|
||||
'{status:"error",message:"' . $this->_message . '",group:"' .
|
||||
$this->_group . '",case:"' . $this->_case . '",method:"' . $this->_method
|
||||
. '"}');
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* We don't display any special header.
|
||||
* @param string $test_name First test top level
|
||||
* to start.
|
||||
* @access public
|
||||
*/
|
||||
function paintHeader($test_name) {
|
||||
}
|
||||
|
||||
/**
|
||||
* We don't display any special footer.
|
||||
* @param string $test_name The top level test.
|
||||
* @access public
|
||||
*/
|
||||
function paintFooter($test_name) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Paints nothing at the start of a test method, but stash
|
||||
* the method name for later.
|
||||
* @param string $test_name Name of test that is starting.
|
||||
* @access public
|
||||
*/
|
||||
function paintMethodStart($method) {
|
||||
$this->_pass = false;
|
||||
$this->_fail = false;
|
||||
$this->_error = false;
|
||||
$this->_method = $this->escapeVal($method);
|
||||
}
|
||||
|
||||
/**
|
||||
* Only send one message if the test passes, after that
|
||||
* suppress the message.
|
||||
* @param string $test_name Name of test that is ending.
|
||||
* @access public
|
||||
*/
|
||||
function paintMethodEnd($method){
|
||||
if ($this->_fail || $this->_error || ! $this->_pass){
|
||||
} else {
|
||||
$this->_listener->write(
|
||||
'{status:"pass",message:"' . $this->_message . '",group:"' .
|
||||
$this->_group . '",case:"' . $this->_case . '",method:"' .
|
||||
$this->_method . '"}');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Stashes the test case name for the later failure message.
|
||||
* @param string $test_name Name of test or other label.
|
||||
* @access public
|
||||
*/
|
||||
function paintCaseStart($case){
|
||||
$this->_case = $this->escapeVal($case);
|
||||
}
|
||||
|
||||
/**
|
||||
* Drops the name.
|
||||
* @param string $test_name Name of test or other label.
|
||||
* @access public
|
||||
*/
|
||||
function paintCaseEnd($case){
|
||||
$this->_case = "";
|
||||
}
|
||||
|
||||
/**
|
||||
* Stashes the name of the test suite. Starts test coverage
|
||||
* if enabled.
|
||||
* @param string $group Name of test or other label.
|
||||
* @param integer $size Number of test cases starting.
|
||||
* @access public
|
||||
*/
|
||||
function paintGroupStart($group, $size){
|
||||
$this->_group = $this->escapeVal($group);
|
||||
if ($this->_cc){
|
||||
if (extension_loaded('xdebug')){
|
||||
xdebug_start_code_coverage(XDEBUG_CC_UNUSED | XDEBUG_CC_DEAD_CODE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Paints coverage report if enabled.
|
||||
* @param string $group Name of test or other label.
|
||||
* @access public
|
||||
*/
|
||||
function paintGroupEnd($group){
|
||||
$this->_group = "";
|
||||
$cc = "";
|
||||
if ($this->_cc){
|
||||
if (extension_loaded('xdebug')){
|
||||
$arrfiles = xdebug_get_code_coverage();
|
||||
xdebug_stop_code_coverage();
|
||||
$thisdir = dirname(__FILE__);
|
||||
$thisdirlen = strlen($thisdir);
|
||||
foreach ($arrfiles as $index=>$file){
|
||||
if (substr($index, 0, $thisdirlen)===$thisdir){
|
||||
continue;
|
||||
}
|
||||
$lcnt = 0;
|
||||
$ccnt = 0;
|
||||
foreach ($file as $line){
|
||||
if ($line == -2){
|
||||
continue;
|
||||
}
|
||||
$lcnt++;
|
||||
if ($line==1){
|
||||
$ccnt++;
|
||||
}
|
||||
}
|
||||
if ($lcnt > 0){
|
||||
$cc .= round(($ccnt/$lcnt) * 100, 2) . '%';
|
||||
}else{
|
||||
$cc .= "0.00%";
|
||||
}
|
||||
$cc.= "\t". $index . "\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
$this->_listener->write('{status:"coverage",message:"' .
|
||||
EclipseReporter::escapeVal($cc) . '"}');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Invoker decorator for Eclipse. Captures output until
|
||||
* the end of the test.
|
||||
* @package SimpleTest
|
||||
* @subpackage Eclipse
|
||||
*/
|
||||
class EclipseInvoker extends SimpleInvokerDecorator{
|
||||
function EclipseInvoker(&$invoker, &$listener) {
|
||||
$this->_listener = &$listener;
|
||||
$this->SimpleInvokerDecorator($invoker);
|
||||
}
|
||||
|
||||
/**
|
||||
* Starts output buffering.
|
||||
* @param string $method Test method to call.
|
||||
* @access public
|
||||
*/
|
||||
function before($method){
|
||||
ob_start();
|
||||
$this->_invoker->before($method);
|
||||
}
|
||||
|
||||
/**
|
||||
* Stops output buffering and send the captured output
|
||||
* to the listener.
|
||||
* @param string $method Test method to call.
|
||||
* @access public
|
||||
*/
|
||||
function after($method) {
|
||||
$this->_invoker->after($method);
|
||||
$output = ob_get_contents();
|
||||
ob_end_clean();
|
||||
if ($output !== ""){
|
||||
$result = $this->_listener->write('{status:"info",message:"' .
|
||||
EclipseReporter::escapeVal($output) . '"}');
|
||||
}
|
||||
}
|
||||
}
|
||||
?>
|
||||
552
tests/simpletest/encoding.php
Normal file
552
tests/simpletest/encoding.php
Normal file
|
|
@ -0,0 +1,552 @@
|
|||
<?php
|
||||
/**
|
||||
* base include file for SimpleTest
|
||||
* @package SimpleTest
|
||||
* @subpackage WebTester
|
||||
* @version $Id: encoding.php 1723 2008-04-08 00:34:10Z lastcraft $
|
||||
*/
|
||||
|
||||
/**#@+
|
||||
* include other SimpleTest class files
|
||||
*/
|
||||
require_once(dirname(__FILE__) . '/socket.php');
|
||||
/**#@-*/
|
||||
|
||||
/**
|
||||
* Single post parameter.
|
||||
* @package SimpleTest
|
||||
* @subpackage WebTester
|
||||
*/
|
||||
class SimpleEncodedPair {
|
||||
var $_key;
|
||||
var $_value;
|
||||
|
||||
/**
|
||||
* Stashes the data for rendering later.
|
||||
* @param string $key Form element name.
|
||||
* @param string $value Data to send.
|
||||
*/
|
||||
function SimpleEncodedPair($key, $value) {
|
||||
$this->_key = $key;
|
||||
$this->_value = $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* The pair as a single string.
|
||||
* @return string Encoded pair.
|
||||
* @access public
|
||||
*/
|
||||
function asRequest() {
|
||||
return urlencode($this->_key) . '=' . urlencode($this->_value);
|
||||
}
|
||||
|
||||
/**
|
||||
* The MIME part as a string.
|
||||
* @return string MIME part encoding.
|
||||
* @access public
|
||||
*/
|
||||
function asMime() {
|
||||
$part = 'Content-Disposition: form-data; ';
|
||||
$part .= "name=\"" . $this->_key . "\"\r\n";
|
||||
$part .= "\r\n" . $this->_value;
|
||||
return $part;
|
||||
}
|
||||
|
||||
/**
|
||||
* Is this the value we are looking for?
|
||||
* @param string $key Identifier.
|
||||
* @return boolean True if matched.
|
||||
* @access public
|
||||
*/
|
||||
function isKey($key) {
|
||||
return $key == $this->_key;
|
||||
}
|
||||
|
||||
/**
|
||||
* Is this the value we are looking for?
|
||||
* @return string Identifier.
|
||||
* @access public
|
||||
*/
|
||||
function getKey() {
|
||||
return $this->_key;
|
||||
}
|
||||
|
||||
/**
|
||||
* Is this the value we are looking for?
|
||||
* @return string Content.
|
||||
* @access public
|
||||
*/
|
||||
function getValue() {
|
||||
return $this->_value;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Single post parameter.
|
||||
* @package SimpleTest
|
||||
* @subpackage WebTester
|
||||
*/
|
||||
class SimpleAttachment {
|
||||
var $_key;
|
||||
var $_content;
|
||||
var $_filename;
|
||||
|
||||
/**
|
||||
* Stashes the data for rendering later.
|
||||
* @param string $key Key to add value to.
|
||||
* @param string $content Raw data.
|
||||
* @param hash $filename Original filename.
|
||||
*/
|
||||
function SimpleAttachment($key, $content, $filename) {
|
||||
$this->_key = $key;
|
||||
$this->_content = $content;
|
||||
$this->_filename = $filename;
|
||||
}
|
||||
|
||||
/**
|
||||
* The pair as a single string.
|
||||
* @return string Encoded pair.
|
||||
* @access public
|
||||
*/
|
||||
function asRequest() {
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* The MIME part as a string.
|
||||
* @return string MIME part encoding.
|
||||
* @access public
|
||||
*/
|
||||
function asMime() {
|
||||
$part = 'Content-Disposition: form-data; ';
|
||||
$part .= 'name="' . $this->_key . '"; ';
|
||||
$part .= 'filename="' . $this->_filename . '"';
|
||||
$part .= "\r\nContent-Type: " . $this->_deduceMimeType();
|
||||
$part .= "\r\n\r\n" . $this->_content;
|
||||
return $part;
|
||||
}
|
||||
|
||||
/**
|
||||
* Attempts to figure out the MIME type from the
|
||||
* file extension and the content.
|
||||
* @return string MIME type.
|
||||
* @access private
|
||||
*/
|
||||
function _deduceMimeType() {
|
||||
if ($this->_isOnlyAscii($this->_content)) {
|
||||
return 'text/plain';
|
||||
}
|
||||
return 'application/octet-stream';
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests each character is in the range 0-127.
|
||||
* @param string $ascii String to test.
|
||||
* @access private
|
||||
*/
|
||||
function _isOnlyAscii($ascii) {
|
||||
for ($i = 0, $length = strlen($ascii); $i < $length; $i++) {
|
||||
if (ord($ascii[$i]) > 127) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Is this the value we are looking for?
|
||||
* @param string $key Identifier.
|
||||
* @return boolean True if matched.
|
||||
* @access public
|
||||
*/
|
||||
function isKey($key) {
|
||||
return $key == $this->_key;
|
||||
}
|
||||
|
||||
/**
|
||||
* Is this the value we are looking for?
|
||||
* @return string Identifier.
|
||||
* @access public
|
||||
*/
|
||||
function getKey() {
|
||||
return $this->_key;
|
||||
}
|
||||
|
||||
/**
|
||||
* Is this the value we are looking for?
|
||||
* @return string Content.
|
||||
* @access public
|
||||
*/
|
||||
function getValue() {
|
||||
return $this->_filename;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Bundle of GET/POST parameters. Can include
|
||||
* repeated parameters.
|
||||
* @package SimpleTest
|
||||
* @subpackage WebTester
|
||||
*/
|
||||
class SimpleEncoding {
|
||||
var $_request;
|
||||
|
||||
/**
|
||||
* Starts empty.
|
||||
* @param array $query Hash of parameters.
|
||||
* Multiple values are
|
||||
* as lists on a single key.
|
||||
* @access public
|
||||
*/
|
||||
function SimpleEncoding($query = false) {
|
||||
if (! $query) {
|
||||
$query = array();
|
||||
}
|
||||
$this->clear();
|
||||
$this->merge($query);
|
||||
}
|
||||
|
||||
/**
|
||||
* Empties the request of parameters.
|
||||
* @access public
|
||||
*/
|
||||
function clear() {
|
||||
$this->_request = array();
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a parameter to the query.
|
||||
* @param string $key Key to add value to.
|
||||
* @param string/array $value New data.
|
||||
* @access public
|
||||
*/
|
||||
function add($key, $value) {
|
||||
if ($value === false) {
|
||||
return;
|
||||
}
|
||||
if (is_array($value)) {
|
||||
foreach ($value as $item) {
|
||||
$this->_addPair($key, $item);
|
||||
}
|
||||
} else {
|
||||
$this->_addPair($key, $value);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a new value into the request.
|
||||
* @param string $key Key to add value to.
|
||||
* @param string/array $value New data.
|
||||
* @access private
|
||||
*/
|
||||
function _addPair($key, $value) {
|
||||
$this->_request[] = new SimpleEncodedPair($key, $value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a MIME part to the query. Does nothing for a
|
||||
* form encoded packet.
|
||||
* @param string $key Key to add value to.
|
||||
* @param string $content Raw data.
|
||||
* @param hash $filename Original filename.
|
||||
* @access public
|
||||
*/
|
||||
function attach($key, $content, $filename) {
|
||||
$this->_request[] = new SimpleAttachment($key, $content, $filename);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a set of parameters to this query.
|
||||
* @param array/SimpleQueryString $query Multiple values are
|
||||
* as lists on a single key.
|
||||
* @access public
|
||||
*/
|
||||
function merge($query) {
|
||||
if (is_object($query)) {
|
||||
$this->_request = array_merge($this->_request, $query->getAll());
|
||||
} elseif (is_array($query)) {
|
||||
foreach ($query as $key => $value) {
|
||||
$this->add($key, $value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for single value.
|
||||
* @return string/array False if missing, string
|
||||
* if present and array if
|
||||
* multiple entries.
|
||||
* @access public
|
||||
*/
|
||||
function getValue($key) {
|
||||
$values = array();
|
||||
foreach ($this->_request as $pair) {
|
||||
if ($pair->isKey($key)) {
|
||||
$values[] = $pair->getValue();
|
||||
}
|
||||
}
|
||||
if (count($values) == 0) {
|
||||
return false;
|
||||
} elseif (count($values) == 1) {
|
||||
return $values[0];
|
||||
} else {
|
||||
return $values;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for listing of pairs.
|
||||
* @return array All pair objects.
|
||||
* @access public
|
||||
*/
|
||||
function getAll() {
|
||||
return $this->_request;
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders the query string as a URL encoded
|
||||
* request part.
|
||||
* @return string Part of URL.
|
||||
* @access protected
|
||||
*/
|
||||
function _encode() {
|
||||
$statements = array();
|
||||
foreach ($this->_request as $pair) {
|
||||
if ($statement = $pair->asRequest()) {
|
||||
$statements[] = $statement;
|
||||
}
|
||||
}
|
||||
return implode('&', $statements);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Bundle of GET parameters. Can include
|
||||
* repeated parameters.
|
||||
* @package SimpleTest
|
||||
* @subpackage WebTester
|
||||
*/
|
||||
class SimpleGetEncoding extends SimpleEncoding {
|
||||
|
||||
/**
|
||||
* Starts empty.
|
||||
* @param array $query Hash of parameters.
|
||||
* Multiple values are
|
||||
* as lists on a single key.
|
||||
* @access public
|
||||
*/
|
||||
function SimpleGetEncoding($query = false) {
|
||||
$this->SimpleEncoding($query);
|
||||
}
|
||||
|
||||
/**
|
||||
* HTTP request method.
|
||||
* @return string Always GET.
|
||||
* @access public
|
||||
*/
|
||||
function getMethod() {
|
||||
return 'GET';
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes no extra headers.
|
||||
* @param SimpleSocket $socket Socket to write to.
|
||||
* @access public
|
||||
*/
|
||||
function writeHeadersTo(&$socket) {
|
||||
}
|
||||
|
||||
/**
|
||||
* No data is sent to the socket as the data is encoded into
|
||||
* the URL.
|
||||
* @param SimpleSocket $socket Socket to write to.
|
||||
* @access public
|
||||
*/
|
||||
function writeTo(&$socket) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders the query string as a URL encoded
|
||||
* request part for attaching to a URL.
|
||||
* @return string Part of URL.
|
||||
* @access public
|
||||
*/
|
||||
function asUrlRequest() {
|
||||
return $this->_encode();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Bundle of URL parameters for a HEAD request.
|
||||
* @package SimpleTest
|
||||
* @subpackage WebTester
|
||||
*/
|
||||
class SimpleHeadEncoding extends SimpleGetEncoding {
|
||||
|
||||
/**
|
||||
* Starts empty.
|
||||
* @param array $query Hash of parameters.
|
||||
* Multiple values are
|
||||
* as lists on a single key.
|
||||
* @access public
|
||||
*/
|
||||
function SimpleHeadEncoding($query = false) {
|
||||
$this->SimpleGetEncoding($query);
|
||||
}
|
||||
|
||||
/**
|
||||
* HTTP request method.
|
||||
* @return string Always HEAD.
|
||||
* @access public
|
||||
*/
|
||||
function getMethod() {
|
||||
return 'HEAD';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Bundle of POST parameters. Can include
|
||||
* repeated parameters.
|
||||
* @package SimpleTest
|
||||
* @subpackage WebTester
|
||||
*/
|
||||
class SimplePostEncoding extends SimpleEncoding {
|
||||
|
||||
/**
|
||||
* Starts empty.
|
||||
* @param array $query Hash of parameters.
|
||||
* Multiple values are
|
||||
* as lists on a single key.
|
||||
* @access public
|
||||
*/
|
||||
function SimplePostEncoding($query = false) {
|
||||
if (is_array($query) and $this->hasMoreThanOneLevel($query)) {
|
||||
$query = $this->rewriteArrayWithMultipleLevels($query);
|
||||
}
|
||||
$this->SimpleEncoding($query);
|
||||
}
|
||||
|
||||
function hasMoreThanOneLevel($query) {
|
||||
foreach ($query as $key => $value) {
|
||||
if (is_array($value)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
function rewriteArrayWithMultipleLevels($query) {
|
||||
$query_ = array();
|
||||
foreach ($query as $key => $value) {
|
||||
if (is_array($value)) {
|
||||
foreach ($value as $sub_key => $sub_value) {
|
||||
$query_[$key."[".$sub_key."]"] = $sub_value;
|
||||
}
|
||||
} else {
|
||||
$query_[$key] = $value;
|
||||
}
|
||||
}
|
||||
if ($this->hasMoreThanOneLevel($query_)) {
|
||||
$query_ = $this->rewriteArrayWithMultipleLevels($query_);
|
||||
}
|
||||
|
||||
return $query_;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* HTTP request method.
|
||||
* @return string Always POST.
|
||||
* @access public
|
||||
*/
|
||||
function getMethod() {
|
||||
return 'POST';
|
||||
}
|
||||
|
||||
/**
|
||||
* Dispatches the form headers down the socket.
|
||||
* @param SimpleSocket $socket Socket to write to.
|
||||
* @access public
|
||||
*/
|
||||
function writeHeadersTo(&$socket) {
|
||||
$socket->write("Content-Length: " . (integer)strlen($this->_encode()) . "\r\n");
|
||||
$socket->write("Content-Type: application/x-www-form-urlencoded\r\n");
|
||||
}
|
||||
|
||||
/**
|
||||
* Dispatches the form data down the socket.
|
||||
* @param SimpleSocket $socket Socket to write to.
|
||||
* @access public
|
||||
*/
|
||||
function writeTo(&$socket) {
|
||||
$socket->write($this->_encode());
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders the query string as a URL encoded
|
||||
* request part for attaching to a URL.
|
||||
* @return string Part of URL.
|
||||
* @access public
|
||||
*/
|
||||
function asUrlRequest() {
|
||||
return '';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Bundle of POST parameters in the multipart
|
||||
* format. Can include file uploads.
|
||||
* @package SimpleTest
|
||||
* @subpackage WebTester
|
||||
*/
|
||||
class SimpleMultipartEncoding extends SimplePostEncoding {
|
||||
var $_boundary;
|
||||
|
||||
/**
|
||||
* Starts empty.
|
||||
* @param array $query Hash of parameters.
|
||||
* Multiple values are
|
||||
* as lists on a single key.
|
||||
* @access public
|
||||
*/
|
||||
function SimpleMultipartEncoding($query = false, $boundary = false) {
|
||||
$this->SimplePostEncoding($query);
|
||||
$this->_boundary = ($boundary === false ? uniqid('st') : $boundary);
|
||||
}
|
||||
|
||||
/**
|
||||
* Dispatches the form headers down the socket.
|
||||
* @param SimpleSocket $socket Socket to write to.
|
||||
* @access public
|
||||
*/
|
||||
function writeHeadersTo(&$socket) {
|
||||
$socket->write("Content-Length: " . (integer)strlen($this->_encode()) . "\r\n");
|
||||
$socket->write("Content-Type: multipart/form-data, boundary=" . $this->_boundary . "\r\n");
|
||||
}
|
||||
|
||||
/**
|
||||
* Dispatches the form data down the socket.
|
||||
* @param SimpleSocket $socket Socket to write to.
|
||||
* @access public
|
||||
*/
|
||||
function writeTo(&$socket) {
|
||||
$socket->write($this->_encode());
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders the query string as a URL encoded
|
||||
* request part.
|
||||
* @return string Part of URL.
|
||||
* @access public
|
||||
*/
|
||||
function _encode() {
|
||||
$stream = '';
|
||||
foreach ($this->_request as $pair) {
|
||||
$stream .= "--" . $this->_boundary . "\r\n";
|
||||
$stream .= $pair->asMime() . "\r\n";
|
||||
}
|
||||
$stream .= "--" . $this->_boundary . "--\r\n";
|
||||
return $stream;
|
||||
}
|
||||
}
|
||||
?>
|
||||
288
tests/simpletest/errors.php
Normal file
288
tests/simpletest/errors.php
Normal file
|
|
@ -0,0 +1,288 @@
|
|||
<?php
|
||||
/**
|
||||
* base include file for SimpleTest
|
||||
* @package SimpleTest
|
||||
* @subpackage UnitTester
|
||||
* @version $Id: errors.php 1672 2008-03-02 04:47:34Z edwardzyang $
|
||||
*/
|
||||
|
||||
/**
|
||||
* @ignore - PHP5 compatibility fix.
|
||||
*/
|
||||
if (! defined('E_STRICT')) {
|
||||
define('E_STRICT', 2048);
|
||||
}
|
||||
|
||||
/**#@+
|
||||
* Includes SimpleTest files.
|
||||
*/
|
||||
require_once dirname(__FILE__) . '/invoker.php';
|
||||
require_once dirname(__FILE__) . '/test_case.php';
|
||||
require_once dirname(__FILE__) . '/expectation.php';
|
||||
/**#@-*/
|
||||
|
||||
/**
|
||||
* Extension that traps errors into an error queue.
|
||||
* @package SimpleTest
|
||||
* @subpackage UnitTester
|
||||
*/
|
||||
class SimpleErrorTrappingInvoker extends SimpleInvokerDecorator {
|
||||
|
||||
/**
|
||||
* Stores the invoker to wrap.
|
||||
* @param SimpleInvoker $invoker Test method runner.
|
||||
*/
|
||||
function SimpleErrorTrappingInvoker(&$invoker) {
|
||||
$this->SimpleInvokerDecorator($invoker);
|
||||
}
|
||||
|
||||
/**
|
||||
* Invokes a test method and dispatches any
|
||||
* untrapped errors. Called back from
|
||||
* the visiting runner.
|
||||
* @param string $method Test method to call.
|
||||
* @access public
|
||||
*/
|
||||
function invoke($method) {
|
||||
$queue = &$this->_createErrorQueue();
|
||||
set_error_handler('SimpleTestErrorHandler');
|
||||
parent::invoke($method);
|
||||
restore_error_handler();
|
||||
$queue->tally();
|
||||
}
|
||||
|
||||
/**
|
||||
* Wires up the error queue for a single test.
|
||||
* @return SimpleErrorQueue Queue connected to the test.
|
||||
* @access private
|
||||
*/
|
||||
function &_createErrorQueue() {
|
||||
$context = &SimpleTest::getContext();
|
||||
$test = &$this->getTestCase();
|
||||
$queue = &$context->get('SimpleErrorQueue');
|
||||
$queue->setTestCase($test);
|
||||
return $queue;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Error queue used to record trapped
|
||||
* errors.
|
||||
* @package SimpleTest
|
||||
* @subpackage UnitTester
|
||||
*/
|
||||
class SimpleErrorQueue {
|
||||
var $_queue;
|
||||
var $_expectation_queue;
|
||||
var $_test;
|
||||
var $_using_expect_style = false;
|
||||
|
||||
/**
|
||||
* Starts with an empty queue.
|
||||
*/
|
||||
function SimpleErrorQueue() {
|
||||
$this->clear();
|
||||
}
|
||||
|
||||
/**
|
||||
* Discards the contents of the error queue.
|
||||
* @access public
|
||||
*/
|
||||
function clear() {
|
||||
$this->_queue = array();
|
||||
$this->_expectation_queue = array();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the currently running test case.
|
||||
* @param SimpleTestCase $test Test case to send messages to.
|
||||
* @access public
|
||||
*/
|
||||
function setTestCase(&$test) {
|
||||
$this->_test = &$test;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets up an expectation of an error. If this is
|
||||
* not fulfilled at the end of the test, a failure
|
||||
* will occour. If the error does happen, then this
|
||||
* will cancel it out and send a pass message.
|
||||
* @param SimpleExpectation $expected Expected error match.
|
||||
* @param string $message Message to display.
|
||||
* @access public
|
||||
*/
|
||||
function expectError($expected, $message) {
|
||||
$this->_using_expect_style = true;
|
||||
array_push($this->_expectation_queue, array($expected, $message));
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds an error to the front of the queue.
|
||||
* @param integer $severity PHP error code.
|
||||
* @param string $content Text of error.
|
||||
* @param string $filename File error occoured in.
|
||||
* @param integer $line Line number of error.
|
||||
* @access public
|
||||
*/
|
||||
function add($severity, $content, $filename, $line) {
|
||||
$content = str_replace('%', '%%', $content);
|
||||
if ($this->_using_expect_style) {
|
||||
$this->_testLatestError($severity, $content, $filename, $line);
|
||||
} else {
|
||||
array_push(
|
||||
$this->_queue,
|
||||
array($severity, $content, $filename, $line));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Any errors still in the queue are sent to the test
|
||||
* case. Any unfulfilled expectations trigger failures.
|
||||
* @access public
|
||||
*/
|
||||
function tally() {
|
||||
while (list($severity, $message, $file, $line) = $this->extract()) {
|
||||
$severity = $this->getSeverityAsString($severity);
|
||||
$this->_test->error($severity, $message, $file, $line);
|
||||
}
|
||||
while (list($expected, $message) = $this->_extractExpectation()) {
|
||||
$this->_test->assert($expected, false, "%s -> Expected error not caught");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the error against the most recent expected
|
||||
* error.
|
||||
* @param integer $severity PHP error code.
|
||||
* @param string $content Text of error.
|
||||
* @param string $filename File error occoured in.
|
||||
* @param integer $line Line number of error.
|
||||
* @access private
|
||||
*/
|
||||
function _testLatestError($severity, $content, $filename, $line) {
|
||||
if ($expectation = $this->_extractExpectation()) {
|
||||
list($expected, $message) = $expectation;
|
||||
$this->_test->assert($expected, $content, sprintf(
|
||||
$message,
|
||||
"%s -> PHP error [$content] severity [" .
|
||||
$this->getSeverityAsString($severity) .
|
||||
"] in [$filename] line [$line]"));
|
||||
} else {
|
||||
$this->_test->error($severity, $content, $filename, $line);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Pulls the earliest error from the queue.
|
||||
* @return mixed False if none, or a list of error
|
||||
* information. Elements are: severity
|
||||
* as the PHP error code, the error message,
|
||||
* the file with the error, the line number
|
||||
* and a list of PHP super global arrays.
|
||||
* @access public
|
||||
*/
|
||||
function extract() {
|
||||
if (count($this->_queue)) {
|
||||
return array_shift($this->_queue);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Pulls the earliest expectation from the queue.
|
||||
* @return SimpleExpectation False if none.
|
||||
* @access private
|
||||
*/
|
||||
function _extractExpectation() {
|
||||
if (count($this->_expectation_queue)) {
|
||||
return array_shift($this->_expectation_queue);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
*/
|
||||
function assertNoErrors($message) {
|
||||
return $this->_test->assert(
|
||||
new TrueExpectation(),
|
||||
count($this->_queue) == 0,
|
||||
sprintf($message, 'Should be no errors'));
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
*/
|
||||
function assertError($expected, $message) {
|
||||
if (count($this->_queue) == 0) {
|
||||
$this->_test->fail(sprintf($message, 'Expected error not found'));
|
||||
return false;
|
||||
}
|
||||
list($severity, $content, $file, $line) = $this->extract();
|
||||
$severity = $this->getSeverityAsString($severity);
|
||||
return $this->_test->assert(
|
||||
$expected,
|
||||
$content,
|
||||
sprintf($message, "Expected PHP error [$content] severity [$severity] in [$file] line [$line]"));
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts an error code into it's string
|
||||
* representation.
|
||||
* @param $severity PHP integer error code.
|
||||
* @return String version of error code.
|
||||
* @access public
|
||||
* @static
|
||||
*/
|
||||
function getSeverityAsString($severity) {
|
||||
static $map = array(
|
||||
E_STRICT => 'E_STRICT',
|
||||
E_ERROR => 'E_ERROR',
|
||||
E_WARNING => 'E_WARNING',
|
||||
E_PARSE => 'E_PARSE',
|
||||
E_NOTICE => 'E_NOTICE',
|
||||
E_CORE_ERROR => 'E_CORE_ERROR',
|
||||
E_CORE_WARNING => 'E_CORE_WARNING',
|
||||
E_COMPILE_ERROR => 'E_COMPILE_ERROR',
|
||||
E_COMPILE_WARNING => 'E_COMPILE_WARNING',
|
||||
E_USER_ERROR => 'E_USER_ERROR',
|
||||
E_USER_WARNING => 'E_USER_WARNING',
|
||||
E_USER_NOTICE => 'E_USER_NOTICE');
|
||||
if (defined('E_RECOVERABLE_ERROR')) {
|
||||
$map[E_RECOVERABLE_ERROR] = 'E_RECOVERABLE_ERROR';
|
||||
}
|
||||
if (defined('E_DEPRECATED')) {
|
||||
$map[E_DEPRECATED] = 'E_DEPRECATED';
|
||||
}
|
||||
return $map[$severity];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Error handler that simply stashes any errors into the global
|
||||
* error queue. Simulates the existing behaviour with respect to
|
||||
* logging errors, but this feature may be removed in future.
|
||||
* @param $severity PHP error code.
|
||||
* @param $message Text of error.
|
||||
* @param $filename File error occoured in.
|
||||
* @param $line Line number of error.
|
||||
* @param $super_globals Hash of PHP super global arrays.
|
||||
* @static
|
||||
* @access public
|
||||
*/
|
||||
function SimpleTestErrorHandler($severity, $message, $filename = null, $line = null, $super_globals = null, $mask = null) {
|
||||
$severity = $severity & error_reporting();
|
||||
if ($severity) {
|
||||
restore_error_handler();
|
||||
if (ini_get('log_errors')) {
|
||||
$label = SimpleErrorQueue::getSeverityAsString($severity);
|
||||
error_log("$label: $message in $filename on line $line");
|
||||
}
|
||||
$context = &SimpleTest::getContext();
|
||||
$queue = &$context->get('SimpleErrorQueue');
|
||||
$queue->add($severity, $message, $filename, $line);
|
||||
set_error_handler('SimpleTestErrorHandler');
|
||||
}
|
||||
return true;
|
||||
}
|
||||
?>
|
||||
198
tests/simpletest/exceptions.php
Normal file
198
tests/simpletest/exceptions.php
Normal file
|
|
@ -0,0 +1,198 @@
|
|||
<?php
|
||||
/**
|
||||
* base include file for SimpleTest
|
||||
* @package SimpleTest
|
||||
* @subpackage UnitTester
|
||||
* @version $Id: exceptions.php 1672 2008-03-02 04:47:34Z edwardzyang $
|
||||
*/
|
||||
|
||||
/**#@+
|
||||
* Include required SimpleTest files
|
||||
*/
|
||||
require_once dirname(__FILE__) . '/invoker.php';
|
||||
require_once dirname(__FILE__) . '/expectation.php';
|
||||
/**#@-*/
|
||||
|
||||
/**
|
||||
* Extension that traps exceptions and turns them into
|
||||
* an error message. PHP5 only.
|
||||
* @package SimpleTest
|
||||
* @subpackage UnitTester
|
||||
*/
|
||||
class SimpleExceptionTrappingInvoker extends SimpleInvokerDecorator {
|
||||
|
||||
/**
|
||||
* Stores the invoker to be wrapped.
|
||||
* @param SimpleInvoker $invoker Test method runner.
|
||||
*/
|
||||
function SimpleExceptionTrappingInvoker($invoker) {
|
||||
$this->SimpleInvokerDecorator($invoker);
|
||||
}
|
||||
|
||||
/**
|
||||
* Invokes a test method whilst trapping expected
|
||||
* exceptions. Any left over unthrown exceptions
|
||||
* are then reported as failures.
|
||||
* @param string $method Test method to call.
|
||||
*/
|
||||
function invoke($method) {
|
||||
$trap = SimpleTest::getContext()->get('SimpleExceptionTrap');
|
||||
$trap->clear();
|
||||
try {
|
||||
$has_thrown = false;
|
||||
parent::invoke($method);
|
||||
} catch (Exception $exception) {
|
||||
$has_thrown = true;
|
||||
if (! $trap->isExpected($this->getTestCase(), $exception)) {
|
||||
$this->getTestCase()->exception($exception);
|
||||
}
|
||||
$trap->clear();
|
||||
}
|
||||
if ($message = $trap->getOutstanding()) {
|
||||
$this->getTestCase()->fail($message);
|
||||
}
|
||||
if ($has_thrown) {
|
||||
try {
|
||||
parent::getTestCase()->tearDown();
|
||||
} catch (Exception $e) { }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests exceptions either by type or the exact
|
||||
* exception. This could be improved to accept
|
||||
* a pattern expectation to test the error
|
||||
* message, but that will have to come later.
|
||||
* @package SimpleTest
|
||||
* @subpackage UnitTester
|
||||
*/
|
||||
class ExceptionExpectation extends SimpleExpectation {
|
||||
private $expected;
|
||||
|
||||
/**
|
||||
* Sets up the conditions to test against.
|
||||
* If the expected value is a string, then
|
||||
* it will act as a test of the class name.
|
||||
* An exception as the comparison will
|
||||
* trigger an identical match. Writing this
|
||||
* down now makes it look doubly dumb. I hope
|
||||
* come up with a better scheme later.
|
||||
* @param mixed $expected A class name or an actual
|
||||
* exception to compare with.
|
||||
* @param string $message Message to display.
|
||||
*/
|
||||
function __construct($expected, $message = '%s') {
|
||||
$this->expected = $expected;
|
||||
parent::__construct($message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Carry out the test.
|
||||
* @param Exception $compare Value to check.
|
||||
* @return boolean True if matched.
|
||||
*/
|
||||
function test($compare) {
|
||||
if (is_string($this->expected)) {
|
||||
return ($compare instanceof $this->expected);
|
||||
}
|
||||
if (get_class($compare) != get_class($this->expected)) {
|
||||
return false;
|
||||
}
|
||||
return $compare->getMessage() == $this->expected->getMessage();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the message to display describing the test.
|
||||
* @param Exception $compare Exception to match.
|
||||
* @return string Final message.
|
||||
*/
|
||||
function testMessage($compare) {
|
||||
if (is_string($this->expected)) {
|
||||
return "Exception [" . $this->describeException($compare) .
|
||||
"] should be type [" . $this->expected . "]";
|
||||
}
|
||||
return "Exception [" . $this->describeException($compare) .
|
||||
"] should match [" .
|
||||
$this->describeException($this->expected) . "]";
|
||||
}
|
||||
|
||||
/**
|
||||
* Summary of an Exception object.
|
||||
* @param Exception $compare Exception to describe.
|
||||
* @return string Text description.
|
||||
*/
|
||||
protected function describeException($exception) {
|
||||
return get_class($exception) . ": " . $exception->getMessage();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Stores expected exceptions for when they
|
||||
* get thrown. Saves the irritating try...catch
|
||||
* block.
|
||||
* @package SimpleTest
|
||||
* @subpackage UnitTester
|
||||
*/
|
||||
class SimpleExceptionTrap {
|
||||
private $expected;
|
||||
private $message;
|
||||
|
||||
/**
|
||||
* Clears down the queue ready for action.
|
||||
*/
|
||||
function __construct() {
|
||||
$this->clear();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets up an expectation of an exception.
|
||||
* This has the effect of intercepting an
|
||||
* exception that matches.
|
||||
* @param SimpleExpectation $expected Expected exception to match.
|
||||
* @param string $message Message to display.
|
||||
* @access public
|
||||
*/
|
||||
function expectException($expected = false, $message = '%s') {
|
||||
if ($expected === false) {
|
||||
$expected = new AnythingExpectation();
|
||||
}
|
||||
if (! SimpleExpectation::isExpectation($expected)) {
|
||||
$expected = new ExceptionExpectation($expected);
|
||||
}
|
||||
$this->expected = $expected;
|
||||
$this->message = $message;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compares the expected exception with any
|
||||
* in the queue. Issues a pass or fail and
|
||||
* returns the state of the test.
|
||||
* @param SimpleTestCase $test Test case to send messages to.
|
||||
* @param Exception $exception Exception to compare.
|
||||
* @return boolean False on no match.
|
||||
*/
|
||||
function isExpected($test, $exception) {
|
||||
if ($this->expected) {
|
||||
return $test->assert($this->expected, $exception, $this->message);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests for any left over exception.
|
||||
* @return string/false The failure message or false if none.
|
||||
*/
|
||||
function getOutstanding() {
|
||||
return sprintf($this->message, 'Failed to trap exception');
|
||||
}
|
||||
|
||||
/**
|
||||
* Discards the contents of the error queue.
|
||||
*/
|
||||
function clear() {
|
||||
$this->expected = false;
|
||||
$this->message = false;
|
||||
}
|
||||
}
|
||||
?>
|
||||
895
tests/simpletest/expectation.php
Normal file
895
tests/simpletest/expectation.php
Normal file
|
|
@ -0,0 +1,895 @@
|
|||
<?php
|
||||
/**
|
||||
* base include file for SimpleTest
|
||||
* @package SimpleTest
|
||||
* @subpackage UnitTester
|
||||
* @version $Id: expectation.php 1723 2008-04-08 00:34:10Z lastcraft $
|
||||
*/
|
||||
|
||||
/**#@+
|
||||
* include other SimpleTest class files
|
||||
*/
|
||||
require_once(dirname(__FILE__) . '/dumper.php');
|
||||
require_once(dirname(__FILE__) . '/compatibility.php');
|
||||
/**#@-*/
|
||||
|
||||
/**
|
||||
* Assertion that can display failure information.
|
||||
* Also includes various helper methods.
|
||||
* @package SimpleTest
|
||||
* @subpackage UnitTester
|
||||
* @abstract
|
||||
*/
|
||||
class SimpleExpectation {
|
||||
var $_dumper = false;
|
||||
var $_message;
|
||||
|
||||
/**
|
||||
* Creates a dumper for displaying values and sets
|
||||
* the test message.
|
||||
* @param string $message Customised message on failure.
|
||||
*/
|
||||
function SimpleExpectation($message = '%s') {
|
||||
$this->_message = $message;
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the expectation. True if correct.
|
||||
* @param mixed $compare Comparison value.
|
||||
* @return boolean True if correct.
|
||||
* @access public
|
||||
* @abstract
|
||||
*/
|
||||
function test($compare) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a human readable test message.
|
||||
* @param mixed $compare Comparison value.
|
||||
* @return string Description of success
|
||||
* or failure.
|
||||
* @access public
|
||||
* @abstract
|
||||
*/
|
||||
function testMessage($compare) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Overlays the generated message onto the stored user
|
||||
* message. An additional message can be interjected.
|
||||
* @param mixed $compare Comparison value.
|
||||
* @param SimpleDumper $dumper For formatting the results.
|
||||
* @return string Description of success
|
||||
* or failure.
|
||||
* @access public
|
||||
*/
|
||||
function overlayMessage($compare, $dumper) {
|
||||
$this->_dumper = $dumper;
|
||||
return sprintf($this->_message, $this->testMessage($compare));
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for the dumper.
|
||||
* @return SimpleDumper Current value dumper.
|
||||
* @access protected
|
||||
*/
|
||||
function &_getDumper() {
|
||||
if (! $this->_dumper) {
|
||||
$dumper = &new SimpleDumper();
|
||||
return $dumper;
|
||||
}
|
||||
return $this->_dumper;
|
||||
}
|
||||
|
||||
/**
|
||||
* Test to see if a value is an expectation object.
|
||||
* A useful utility method.
|
||||
* @param mixed $expectation Hopefully an Epectation
|
||||
* class.
|
||||
* @return boolean True if descended from
|
||||
* this class.
|
||||
* @access public
|
||||
* @static
|
||||
*/
|
||||
function isExpectation($expectation) {
|
||||
return is_object($expectation) &&
|
||||
SimpleTestCompatibility::isA($expectation, 'SimpleExpectation');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A wildcard expectation always matches.
|
||||
* @package SimpleTest
|
||||
* @subpackage MockObjects
|
||||
*/
|
||||
class AnythingExpectation extends SimpleExpectation {
|
||||
|
||||
/**
|
||||
* Tests the expectation. Always true.
|
||||
* @param mixed $compare Ignored.
|
||||
* @return boolean True.
|
||||
* @access public
|
||||
*/
|
||||
function test($compare) {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a human readable test message.
|
||||
* @param mixed $compare Comparison value.
|
||||
* @return string Description of success
|
||||
* or failure.
|
||||
* @access public
|
||||
*/
|
||||
function testMessage($compare) {
|
||||
$dumper = &$this->_getDumper();
|
||||
return 'Anything always matches [' . $dumper->describeValue($compare) . ']';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* An expectation that never matches.
|
||||
* @package SimpleTest
|
||||
* @subpackage MockObjects
|
||||
*/
|
||||
class FailedExpectation extends SimpleExpectation {
|
||||
|
||||
/**
|
||||
* Tests the expectation. Always false.
|
||||
* @param mixed $compare Ignored.
|
||||
* @return boolean True.
|
||||
* @access public
|
||||
*/
|
||||
function test($compare) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a human readable test message.
|
||||
* @param mixed $compare Comparison value.
|
||||
* @return string Description of failure.
|
||||
* @access public
|
||||
*/
|
||||
function testMessage($compare) {
|
||||
$dumper = &$this->_getDumper();
|
||||
return 'Failed expectation never matches [' . $dumper->describeValue($compare) . ']';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* An expectation that passes on boolean true.
|
||||
* @package SimpleTest
|
||||
* @subpackage MockObjects
|
||||
*/
|
||||
class TrueExpectation extends SimpleExpectation {
|
||||
|
||||
/**
|
||||
* Tests the expectation.
|
||||
* @param mixed $compare Should be true.
|
||||
* @return boolean True on match.
|
||||
* @access public
|
||||
*/
|
||||
function test($compare) {
|
||||
return (boolean)$compare;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a human readable test message.
|
||||
* @param mixed $compare Comparison value.
|
||||
* @return string Description of success
|
||||
* or failure.
|
||||
* @access public
|
||||
*/
|
||||
function testMessage($compare) {
|
||||
$dumper = &$this->_getDumper();
|
||||
return 'Expected true, got [' . $dumper->describeValue($compare) . ']';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* An expectation that passes on boolean false.
|
||||
* @package SimpleTest
|
||||
* @subpackage MockObjects
|
||||
*/
|
||||
class FalseExpectation extends SimpleExpectation {
|
||||
|
||||
/**
|
||||
* Tests the expectation.
|
||||
* @param mixed $compare Should be false.
|
||||
* @return boolean True on match.
|
||||
* @access public
|
||||
*/
|
||||
function test($compare) {
|
||||
return ! (boolean)$compare;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a human readable test message.
|
||||
* @param mixed $compare Comparison value.
|
||||
* @return string Description of success
|
||||
* or failure.
|
||||
* @access public
|
||||
*/
|
||||
function testMessage($compare) {
|
||||
$dumper = &$this->_getDumper();
|
||||
return 'Expected false, got [' . $dumper->describeValue($compare) . ']';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Test for equality.
|
||||
* @package SimpleTest
|
||||
* @subpackage UnitTester
|
||||
*/
|
||||
class EqualExpectation extends SimpleExpectation {
|
||||
var $_value;
|
||||
|
||||
/**
|
||||
* Sets the value to compare against.
|
||||
* @param mixed $value Test value to match.
|
||||
* @param string $message Customised message on failure.
|
||||
* @access public
|
||||
*/
|
||||
function EqualExpectation($value, $message = '%s') {
|
||||
$this->SimpleExpectation($message);
|
||||
$this->_value = $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the expectation. True if it matches the
|
||||
* held value.
|
||||
* @param mixed $compare Comparison value.
|
||||
* @return boolean True if correct.
|
||||
* @access public
|
||||
*/
|
||||
function test($compare) {
|
||||
return (($this->_value == $compare) && ($compare == $this->_value));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a human readable test message.
|
||||
* @param mixed $compare Comparison value.
|
||||
* @return string Description of success
|
||||
* or failure.
|
||||
* @access public
|
||||
*/
|
||||
function testMessage($compare) {
|
||||
if ($this->test($compare)) {
|
||||
return "Equal expectation [" . $this->_dumper->describeValue($this->_value) . "]";
|
||||
} else {
|
||||
return "Equal expectation fails " .
|
||||
$this->_dumper->describeDifference($this->_value, $compare);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for comparison value.
|
||||
* @return mixed Held value to compare with.
|
||||
* @access protected
|
||||
*/
|
||||
function _getValue() {
|
||||
return $this->_value;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Test for inequality.
|
||||
* @package SimpleTest
|
||||
* @subpackage UnitTester
|
||||
*/
|
||||
class NotEqualExpectation extends EqualExpectation {
|
||||
|
||||
/**
|
||||
* Sets the value to compare against.
|
||||
* @param mixed $value Test value to match.
|
||||
* @param string $message Customised message on failure.
|
||||
* @access public
|
||||
*/
|
||||
function NotEqualExpectation($value, $message = '%s') {
|
||||
$this->EqualExpectation($value, $message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the expectation. True if it differs from the
|
||||
* held value.
|
||||
* @param mixed $compare Comparison value.
|
||||
* @return boolean True if correct.
|
||||
* @access public
|
||||
*/
|
||||
function test($compare) {
|
||||
return ! parent::test($compare);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a human readable test message.
|
||||
* @param mixed $compare Comparison value.
|
||||
* @return string Description of success
|
||||
* or failure.
|
||||
* @access public
|
||||
*/
|
||||
function testMessage($compare) {
|
||||
$dumper = &$this->_getDumper();
|
||||
if ($this->test($compare)) {
|
||||
return "Not equal expectation passes " .
|
||||
$dumper->describeDifference($this->_getValue(), $compare);
|
||||
} else {
|
||||
return "Not equal expectation fails [" .
|
||||
$dumper->describeValue($this->_getValue()) .
|
||||
"] matches";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Test for being within a range.
|
||||
* @package SimpleTest
|
||||
* @subpackage UnitTester
|
||||
*/
|
||||
class WithinMarginExpectation extends SimpleExpectation {
|
||||
var $_upper;
|
||||
var $_lower;
|
||||
|
||||
/**
|
||||
* Sets the value to compare against and the fuzziness of
|
||||
* the match. Used for comparing floating point values.
|
||||
* @param mixed $value Test value to match.
|
||||
* @param mixed $margin Fuzziness of match.
|
||||
* @param string $message Customised message on failure.
|
||||
* @access public
|
||||
*/
|
||||
function WithinMarginExpectation($value, $margin, $message = '%s') {
|
||||
$this->SimpleExpectation($message);
|
||||
$this->_upper = $value + $margin;
|
||||
$this->_lower = $value - $margin;
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the expectation. True if it matches the
|
||||
* held value.
|
||||
* @param mixed $compare Comparison value.
|
||||
* @return boolean True if correct.
|
||||
* @access public
|
||||
*/
|
||||
function test($compare) {
|
||||
return (($compare <= $this->_upper) && ($compare >= $this->_lower));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a human readable test message.
|
||||
* @param mixed $compare Comparison value.
|
||||
* @return string Description of success
|
||||
* or failure.
|
||||
* @access public
|
||||
*/
|
||||
function testMessage($compare) {
|
||||
if ($this->test($compare)) {
|
||||
return $this->_withinMessage($compare);
|
||||
} else {
|
||||
return $this->_outsideMessage($compare);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a the message for being within the range.
|
||||
* @param mixed $compare Value being tested.
|
||||
* @access private
|
||||
*/
|
||||
function _withinMessage($compare) {
|
||||
return "Within expectation [" . $this->_dumper->describeValue($this->_lower) . "] and [" .
|
||||
$this->_dumper->describeValue($this->_upper) . "]";
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a the message for being within the range.
|
||||
* @param mixed $compare Value being tested.
|
||||
* @access private
|
||||
*/
|
||||
function _outsideMessage($compare) {
|
||||
if ($compare > $this->_upper) {
|
||||
return "Outside expectation " .
|
||||
$this->_dumper->describeDifference($compare, $this->_upper);
|
||||
} else {
|
||||
return "Outside expectation " .
|
||||
$this->_dumper->describeDifference($compare, $this->_lower);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Test for being outside of a range.
|
||||
* @package SimpleTest
|
||||
* @subpackage UnitTester
|
||||
*/
|
||||
class OutsideMarginExpectation extends WithinMarginExpectation {
|
||||
|
||||
/**
|
||||
* Sets the value to compare against and the fuzziness of
|
||||
* the match. Used for comparing floating point values.
|
||||
* @param mixed $value Test value to not match.
|
||||
* @param mixed $margin Fuzziness of match.
|
||||
* @param string $message Customised message on failure.
|
||||
* @access public
|
||||
*/
|
||||
function OutsideMarginExpectation($value, $margin, $message = '%s') {
|
||||
$this->WithinMarginExpectation($value, $margin, $message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the expectation. True if it matches the
|
||||
* held value.
|
||||
* @param mixed $compare Comparison value.
|
||||
* @return boolean True if correct.
|
||||
* @access public
|
||||
*/
|
||||
function test($compare) {
|
||||
return ! parent::test($compare);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a human readable test message.
|
||||
* @param mixed $compare Comparison value.
|
||||
* @return string Description of success
|
||||
* or failure.
|
||||
* @access public
|
||||
*/
|
||||
function testMessage($compare) {
|
||||
if (! $this->test($compare)) {
|
||||
return $this->_withinMessage($compare);
|
||||
} else {
|
||||
return $this->_outsideMessage($compare);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Test for reference.
|
||||
* @package SimpleTest
|
||||
* @subpackage UnitTester
|
||||
*/
|
||||
class ReferenceExpectation extends SimpleExpectation {
|
||||
var $_value;
|
||||
|
||||
/**
|
||||
* Sets the reference value to compare against.
|
||||
* @param mixed $value Test reference to match.
|
||||
* @param string $message Customised message on failure.
|
||||
* @access public
|
||||
*/
|
||||
function ReferenceExpectation(&$value, $message = '%s') {
|
||||
$this->SimpleExpectation($message);
|
||||
$this->_value =& $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the expectation. True if it exactly
|
||||
* references the held value.
|
||||
* @param mixed $compare Comparison reference.
|
||||
* @return boolean True if correct.
|
||||
* @access public
|
||||
*/
|
||||
function test(&$compare) {
|
||||
return SimpleTestCompatibility::isReference($this->_value, $compare);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a human readable test message.
|
||||
* @param mixed $compare Comparison value.
|
||||
* @return string Description of success
|
||||
* or failure.
|
||||
* @access public
|
||||
*/
|
||||
function testMessage($compare) {
|
||||
if ($this->test($compare)) {
|
||||
return "Reference expectation [" . $this->_dumper->describeValue($this->_value) . "]";
|
||||
} else {
|
||||
return "Reference expectation fails " .
|
||||
$this->_dumper->describeDifference($this->_value, $compare);
|
||||
}
|
||||
}
|
||||
|
||||
function _getValue() {
|
||||
return $this->_value;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Test for identity.
|
||||
* @package SimpleTest
|
||||
* @subpackage UnitTester
|
||||
*/
|
||||
class IdenticalExpectation extends EqualExpectation {
|
||||
|
||||
/**
|
||||
* Sets the value to compare against.
|
||||
* @param mixed $value Test value to match.
|
||||
* @param string $message Customised message on failure.
|
||||
* @access public
|
||||
*/
|
||||
function IdenticalExpectation($value, $message = '%s') {
|
||||
$this->EqualExpectation($value, $message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the expectation. True if it exactly
|
||||
* matches the held value.
|
||||
* @param mixed $compare Comparison value.
|
||||
* @return boolean True if correct.
|
||||
* @access public
|
||||
*/
|
||||
function test($compare) {
|
||||
return SimpleTestCompatibility::isIdentical($this->_getValue(), $compare);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a human readable test message.
|
||||
* @param mixed $compare Comparison value.
|
||||
* @return string Description of success
|
||||
* or failure.
|
||||
* @access public
|
||||
*/
|
||||
function testMessage($compare) {
|
||||
$dumper = &$this->_getDumper();
|
||||
if ($this->test($compare)) {
|
||||
return "Identical expectation [" . $dumper->describeValue($this->_getValue()) . "]";
|
||||
} else {
|
||||
return "Identical expectation [" . $dumper->describeValue($this->_getValue()) .
|
||||
"] fails with [" .
|
||||
$dumper->describeValue($compare) . "] " .
|
||||
$dumper->describeDifference($this->_getValue(), $compare, TYPE_MATTERS);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Test for non-identity.
|
||||
* @package SimpleTest
|
||||
* @subpackage UnitTester
|
||||
*/
|
||||
class NotIdenticalExpectation extends IdenticalExpectation {
|
||||
|
||||
/**
|
||||
* Sets the value to compare against.
|
||||
* @param mixed $value Test value to match.
|
||||
* @param string $message Customised message on failure.
|
||||
* @access public
|
||||
*/
|
||||
function NotIdenticalExpectation($value, $message = '%s') {
|
||||
$this->IdenticalExpectation($value, $message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the expectation. True if it differs from the
|
||||
* held value.
|
||||
* @param mixed $compare Comparison value.
|
||||
* @return boolean True if correct.
|
||||
* @access public
|
||||
*/
|
||||
function test($compare) {
|
||||
return ! parent::test($compare);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a human readable test message.
|
||||
* @param mixed $compare Comparison value.
|
||||
* @return string Description of success
|
||||
* or failure.
|
||||
* @access public
|
||||
*/
|
||||
function testMessage($compare) {
|
||||
$dumper = &$this->_getDumper();
|
||||
if ($this->test($compare)) {
|
||||
return "Not identical expectation passes " .
|
||||
$dumper->describeDifference($this->_getValue(), $compare, TYPE_MATTERS);
|
||||
} else {
|
||||
return "Not identical expectation [" . $dumper->describeValue($this->_getValue()) . "] matches";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Test for a pattern using Perl regex rules.
|
||||
* @package SimpleTest
|
||||
* @subpackage UnitTester
|
||||
*/
|
||||
class PatternExpectation extends SimpleExpectation {
|
||||
var $_pattern;
|
||||
|
||||
/**
|
||||
* Sets the value to compare against.
|
||||
* @param string $pattern Pattern to search for.
|
||||
* @param string $message Customised message on failure.
|
||||
* @access public
|
||||
*/
|
||||
function PatternExpectation($pattern, $message = '%s') {
|
||||
$this->SimpleExpectation($message);
|
||||
$this->_pattern = $pattern;
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for the pattern.
|
||||
* @return string Perl regex as string.
|
||||
* @access protected
|
||||
*/
|
||||
function _getPattern() {
|
||||
return $this->_pattern;
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the expectation. True if the Perl regex
|
||||
* matches the comparison value.
|
||||
* @param string $compare Comparison value.
|
||||
* @return boolean True if correct.
|
||||
* @access public
|
||||
*/
|
||||
function test($compare) {
|
||||
return (boolean)preg_match($this->_getPattern(), $compare);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a human readable test message.
|
||||
* @param mixed $compare Comparison value.
|
||||
* @return string Description of success
|
||||
* or failure.
|
||||
* @access public
|
||||
*/
|
||||
function testMessage($compare) {
|
||||
if ($this->test($compare)) {
|
||||
return $this->_describePatternMatch($this->_getPattern(), $compare);
|
||||
} else {
|
||||
$dumper = &$this->_getDumper();
|
||||
return "Pattern [" . $this->_getPattern() .
|
||||
"] not detected in [" .
|
||||
$dumper->describeValue($compare) . "]";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Describes a pattern match including the string
|
||||
* found and it's position.
|
||||
* @param string $pattern Regex to match against.
|
||||
* @param string $subject Subject to search.
|
||||
* @access protected
|
||||
*/
|
||||
function _describePatternMatch($pattern, $subject) {
|
||||
preg_match($pattern, $subject, $matches);
|
||||
$position = strpos($subject, $matches[0]);
|
||||
$dumper = $this->_getDumper();
|
||||
return "Pattern [$pattern] detected at character [$position] in [" .
|
||||
$dumper->describeValue($subject) . "] as [" .
|
||||
$matches[0] . "] in region [" .
|
||||
$dumper->clipString($subject, 100, $position) . "]";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @package SimpleTest
|
||||
* @subpackage UnitTester
|
||||
* @deprecated
|
||||
*/
|
||||
class WantedPatternExpectation extends PatternExpectation {
|
||||
}
|
||||
|
||||
/**
|
||||
* Fail if a pattern is detected within the
|
||||
* comparison.
|
||||
* @package SimpleTest
|
||||
* @subpackage UnitTester
|
||||
*/
|
||||
class NoPatternExpectation extends PatternExpectation {
|
||||
|
||||
/**
|
||||
* Sets the reject pattern
|
||||
* @param string $pattern Pattern to search for.
|
||||
* @param string $message Customised message on failure.
|
||||
* @access public
|
||||
*/
|
||||
function NoPatternExpectation($pattern, $message = '%s') {
|
||||
$this->PatternExpectation($pattern, $message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the expectation. False if the Perl regex
|
||||
* matches the comparison value.
|
||||
* @param string $compare Comparison value.
|
||||
* @return boolean True if correct.
|
||||
* @access public
|
||||
*/
|
||||
function test($compare) {
|
||||
return ! parent::test($compare);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a human readable test message.
|
||||
* @param string $compare Comparison value.
|
||||
* @return string Description of success
|
||||
* or failure.
|
||||
* @access public
|
||||
*/
|
||||
function testMessage($compare) {
|
||||
if ($this->test($compare)) {
|
||||
$dumper = &$this->_getDumper();
|
||||
return "Pattern [" . $this->_getPattern() .
|
||||
"] not detected in [" .
|
||||
$dumper->describeValue($compare) . "]";
|
||||
} else {
|
||||
return $this->_describePatternMatch($this->_getPattern(), $compare);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @package SimpleTest
|
||||
* @subpackage UnitTester
|
||||
* @deprecated
|
||||
*/
|
||||
class UnwantedPatternExpectation extends NoPatternExpectation {
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests either type or class name if it's an object.
|
||||
* @package SimpleTest
|
||||
* @subpackage UnitTester
|
||||
*/
|
||||
class IsAExpectation extends SimpleExpectation {
|
||||
var $_type;
|
||||
|
||||
/**
|
||||
* Sets the type to compare with.
|
||||
* @param string $type Type or class name.
|
||||
* @param string $message Customised message on failure.
|
||||
* @access public
|
||||
*/
|
||||
function IsAExpectation($type, $message = '%s') {
|
||||
$this->SimpleExpectation($message);
|
||||
$this->_type = $type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for type to check against.
|
||||
* @return string Type or class name.
|
||||
* @access protected
|
||||
*/
|
||||
function _getType() {
|
||||
return $this->_type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the expectation. True if the type or
|
||||
* class matches the string value.
|
||||
* @param string $compare Comparison value.
|
||||
* @return boolean True if correct.
|
||||
* @access public
|
||||
*/
|
||||
function test($compare) {
|
||||
if (is_object($compare)) {
|
||||
return SimpleTestCompatibility::isA($compare, $this->_type);
|
||||
} else {
|
||||
return (strtolower(gettype($compare)) == $this->_canonicalType($this->_type));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Coerces type name into a gettype() match.
|
||||
* @param string $type User type.
|
||||
* @return string Simpler type.
|
||||
* @access private
|
||||
*/
|
||||
function _canonicalType($type) {
|
||||
$type = strtolower($type);
|
||||
$map = array(
|
||||
'bool' => 'boolean',
|
||||
'float' => 'double',
|
||||
'real' => 'double',
|
||||
'int' => 'integer');
|
||||
if (isset($map[$type])) {
|
||||
$type = $map[$type];
|
||||
}
|
||||
return $type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a human readable test message.
|
||||
* @param mixed $compare Comparison value.
|
||||
* @return string Description of success
|
||||
* or failure.
|
||||
* @access public
|
||||
*/
|
||||
function testMessage($compare) {
|
||||
$dumper = &$this->_getDumper();
|
||||
return "Value [" . $dumper->describeValue($compare) .
|
||||
"] should be type [" . $this->_type . "]";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests either type or class name if it's an object.
|
||||
* Will succeed if the type does not match.
|
||||
* @package SimpleTest
|
||||
* @subpackage UnitTester
|
||||
*/
|
||||
class NotAExpectation extends IsAExpectation {
|
||||
var $_type;
|
||||
|
||||
/**
|
||||
* Sets the type to compare with.
|
||||
* @param string $type Type or class name.
|
||||
* @param string $message Customised message on failure.
|
||||
* @access public
|
||||
*/
|
||||
function NotAExpectation($type, $message = '%s') {
|
||||
$this->IsAExpectation($type, $message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the expectation. False if the type or
|
||||
* class matches the string value.
|
||||
* @param string $compare Comparison value.
|
||||
* @return boolean True if different.
|
||||
* @access public
|
||||
*/
|
||||
function test($compare) {
|
||||
return ! parent::test($compare);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a human readable test message.
|
||||
* @param mixed $compare Comparison value.
|
||||
* @return string Description of success
|
||||
* or failure.
|
||||
* @access public
|
||||
*/
|
||||
function testMessage($compare) {
|
||||
$dumper = &$this->_getDumper();
|
||||
return "Value [" . $dumper->describeValue($compare) .
|
||||
"] should not be type [" . $this->_getType() . "]";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests for existance of a method in an object
|
||||
* @package SimpleTest
|
||||
* @subpackage UnitTester
|
||||
*/
|
||||
class MethodExistsExpectation extends SimpleExpectation {
|
||||
var $_method;
|
||||
|
||||
/**
|
||||
* Sets the value to compare against.
|
||||
* @param string $method Method to check.
|
||||
* @param string $message Customised message on failure.
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
function MethodExistsExpectation($method, $message = '%s') {
|
||||
$this->SimpleExpectation($message);
|
||||
$this->_method = &$method;
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the expectation. True if the method exists in the test object.
|
||||
* @param string $compare Comparison method name.
|
||||
* @return boolean True if correct.
|
||||
* @access public
|
||||
*/
|
||||
function test($compare) {
|
||||
return (boolean)(is_object($compare) && method_exists($compare, $this->_method));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a human readable test message.
|
||||
* @param mixed $compare Comparison value.
|
||||
* @return string Description of success
|
||||
* or failure.
|
||||
* @access public
|
||||
*/
|
||||
function testMessage($compare) {
|
||||
$dumper = &$this->_getDumper();
|
||||
if (! is_object($compare)) {
|
||||
return 'No method on non-object [' . $dumper->describeValue($compare) . ']';
|
||||
}
|
||||
$method = $this->_method;
|
||||
return "Object [" . $dumper->describeValue($compare) .
|
||||
"] should contain method [$method]";
|
||||
}
|
||||
}
|
||||
?>
|
||||
198
tests/simpletest/extensions/pear_test_case.php
Normal file
198
tests/simpletest/extensions/pear_test_case.php
Normal file
|
|
@ -0,0 +1,198 @@
|
|||
<?php
|
||||
/**
|
||||
* adapter for SimpleTest to use PEAR PHPUnit test cases
|
||||
* @package SimpleTest
|
||||
* @subpackage Extensions
|
||||
* @version $Id: pear_test_case.php 1388 2006-11-10 20:59:59Z lastcraft $
|
||||
*/
|
||||
|
||||
/**#@+
|
||||
* include SimpleTest files
|
||||
*/
|
||||
require_once(dirname(__FILE__) . '/../dumper.php');
|
||||
require_once(dirname(__FILE__) . '/../compatibility.php');
|
||||
require_once(dirname(__FILE__) . '/../test_case.php');
|
||||
require_once(dirname(__FILE__) . '/../expectation.php');
|
||||
/**#@-*/
|
||||
|
||||
/**
|
||||
* Adapter for PEAR PHPUnit test case to allow
|
||||
* legacy PEAR test cases to be used with SimpleTest.
|
||||
* @package SimpleTest
|
||||
* @subpackage Extensions
|
||||
*/
|
||||
class PHPUnit_TestCase extends SimpleTestCase {
|
||||
var $_loosely_typed;
|
||||
|
||||
/**
|
||||
* Constructor. Sets the test name.
|
||||
* @param $label Test name to display.
|
||||
* @public
|
||||
*/
|
||||
function PHPUnit_TestCase($label = false) {
|
||||
$this->SimpleTestCase($label);
|
||||
$this->_loosely_typed = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Will test straight equality if set to loose
|
||||
* typing, or identity if not.
|
||||
* @param $first First value.
|
||||
* @param $second Comparison value.
|
||||
* @param $message Message to display.
|
||||
* @public
|
||||
*/
|
||||
function assertEquals($first, $second, $message = "%s", $delta = 0) {
|
||||
if ($this->_loosely_typed) {
|
||||
$expectation = &new EqualExpectation($first);
|
||||
} else {
|
||||
$expectation = &new IdenticalExpectation($first);
|
||||
}
|
||||
$this->assert($expectation, $second, $message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Passes if the value tested is not null.
|
||||
* @param $value Value to test against.
|
||||
* @param $message Message to display.
|
||||
* @public
|
||||
*/
|
||||
function assertNotNull($value, $message = "%s") {
|
||||
parent::assert(new TrueExpectation(), isset($value), $message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Passes if the value tested is null.
|
||||
* @param $value Value to test against.
|
||||
* @param $message Message to display.
|
||||
* @public
|
||||
*/
|
||||
function assertNull($value, $message = "%s") {
|
||||
parent::assert(new TrueExpectation(), !isset($value), $message);
|
||||
}
|
||||
|
||||
/**
|
||||
* In PHP5 the identity test tests for the same
|
||||
* object. This is a reference test in PHP4.
|
||||
* @param $first First object handle.
|
||||
* @param $second Hopefully the same handle.
|
||||
* @param $message Message to display.
|
||||
* @public
|
||||
*/
|
||||
function assertSame(&$first, &$second, $message = "%s") {
|
||||
$dumper = &new SimpleDumper();
|
||||
$message = sprintf(
|
||||
$message,
|
||||
"[" . $dumper->describeValue($first) .
|
||||
"] and [" . $dumper->describeValue($second) .
|
||||
"] should reference the same object");
|
||||
return $this->assert(
|
||||
new TrueExpectation(),
|
||||
SimpleTestCompatibility::isReference($first, $second),
|
||||
$message);
|
||||
}
|
||||
|
||||
/**
|
||||
* In PHP5 the identity test tests for the same
|
||||
* object. This is a reference test in PHP4.
|
||||
* @param $first First object handle.
|
||||
* @param $second Hopefully a different handle.
|
||||
* @param $message Message to display.
|
||||
* @public
|
||||
*/
|
||||
function assertNotSame(&$first, &$second, $message = "%s") {
|
||||
$dumper = &new SimpleDumper();
|
||||
$message = sprintf(
|
||||
$message,
|
||||
"[" . $dumper->describeValue($first) .
|
||||
"] and [" . $dumper->describeValue($second) .
|
||||
"] should not be the same object");
|
||||
return $this->assert(
|
||||
new falseExpectation(),
|
||||
SimpleTestCompatibility::isReference($first, $second),
|
||||
$message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends pass if the test condition resolves true,
|
||||
* a fail otherwise.
|
||||
* @param $condition Condition to test true.
|
||||
* @param $message Message to display.
|
||||
* @public
|
||||
*/
|
||||
function assertTrue($condition, $message = "%s") {
|
||||
parent::assert(new TrueExpectation(), $condition, $message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends pass if the test condition resolves false,
|
||||
* a fail otherwise.
|
||||
* @param $condition Condition to test false.
|
||||
* @param $message Message to display.
|
||||
* @public
|
||||
*/
|
||||
function assertFalse($condition, $message = "%s") {
|
||||
parent::assert(new FalseExpectation(), $condition, $message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests a regex match. Needs refactoring.
|
||||
* @param $pattern Regex to match.
|
||||
* @param $subject String to search in.
|
||||
* @param $message Message to display.
|
||||
* @public
|
||||
*/
|
||||
function assertRegExp($pattern, $subject, $message = "%s") {
|
||||
$this->assert(new PatternExpectation($pattern), $subject, $message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the type of a value.
|
||||
* @param $value Value to take type of.
|
||||
* @param $type Hoped for type.
|
||||
* @param $message Message to display.
|
||||
* @public
|
||||
*/
|
||||
function assertType($value, $type, $message = "%s") {
|
||||
parent::assert(new TrueExpectation(), gettype($value) == strtolower($type), $message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets equality operation to act as a simple equal
|
||||
* comparison only, allowing a broader range of
|
||||
* matches.
|
||||
* @param $loosely_typed True for broader comparison.
|
||||
* @public
|
||||
*/
|
||||
function setLooselyTyped($loosely_typed) {
|
||||
$this->_loosely_typed = $loosely_typed;
|
||||
}
|
||||
|
||||
/**
|
||||
* For progress indication during
|
||||
* a test amongst other things.
|
||||
* @return Usually one.
|
||||
* @public
|
||||
*/
|
||||
function countTestCases() {
|
||||
return $this->getSize();
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for name, normally just the class
|
||||
* name.
|
||||
* @public
|
||||
*/
|
||||
function getName() {
|
||||
return $this->getLabel();
|
||||
}
|
||||
|
||||
/**
|
||||
* Does nothing. For compatibility only.
|
||||
* @param $name Dummy
|
||||
* @public
|
||||
*/
|
||||
function setName($name) {
|
||||
}
|
||||
}
|
||||
?>
|
||||
96
tests/simpletest/extensions/phpunit_test_case.php
Normal file
96
tests/simpletest/extensions/phpunit_test_case.php
Normal file
|
|
@ -0,0 +1,96 @@
|
|||
<?php
|
||||
/**
|
||||
* adapter for SimpleTest to use PHPUnit test cases
|
||||
* @package SimpleTest
|
||||
* @subpackage Extensions
|
||||
* @version $Id: phpunit_test_case.php 1530 2007-06-04 23:35:45Z lastcraft $
|
||||
*/
|
||||
|
||||
/**#@+
|
||||
* include SimpleTest files
|
||||
*/
|
||||
require_once(dirname(__FILE__) . '/../unit_tester.php');
|
||||
require_once(dirname(__FILE__) . '/../expectation.php');
|
||||
/**#@-*/
|
||||
|
||||
/**
|
||||
* Adapter for sourceforge PHPUnit test case to allow
|
||||
* legacy test cases to be used with SimpleTest.
|
||||
* @package SimpleTest
|
||||
* @subpackage Extensions
|
||||
*/
|
||||
class TestCase extends SimpleTestCase {
|
||||
|
||||
/**
|
||||
* Constructor. Sets the test name.
|
||||
* @param $label Test name to display.
|
||||
* @public
|
||||
*/
|
||||
function TestCase($label = false) {
|
||||
$this->SimpleTestCase($label);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends pass if the test condition resolves true,
|
||||
* a fail otherwise.
|
||||
* @param $condition Condition to test true.
|
||||
* @param $message Message to display.
|
||||
* @public
|
||||
*/
|
||||
function assert($condition, $message = false) {
|
||||
parent::assert(new TrueExpectation(), $condition, $message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Will test straight equality if set to loose
|
||||
* typing, or identity if not.
|
||||
* @param $first First value.
|
||||
* @param $second Comparison value.
|
||||
* @param $message Message to display.
|
||||
* @public
|
||||
*/
|
||||
function assertEquals($first, $second, $message = false) {
|
||||
parent::assert(new EqualExpectation($first), $second, $message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Simple string equality.
|
||||
* @param $first First value.
|
||||
* @param $second Comparison value.
|
||||
* @param $message Message to display.
|
||||
* @public
|
||||
*/
|
||||
function assertEqualsMultilineStrings($first, $second, $message = false) {
|
||||
parent::assert(new EqualExpectation($first), $second, $message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests a regex match.
|
||||
* @param $pattern Regex to match.
|
||||
* @param $subject String to search in.
|
||||
* @param $message Message to display.
|
||||
* @public
|
||||
*/
|
||||
function assertRegexp($pattern, $subject, $message = false) {
|
||||
parent::assert(new PatternExpectation($pattern), $subject, $message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends an error which we interpret as a fail
|
||||
* with a different message for compatibility.
|
||||
* @param $message Message to display.
|
||||
* @public
|
||||
*/
|
||||
function error($message) {
|
||||
parent::fail("Error triggered [$message]");
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for name.
|
||||
* @public
|
||||
*/
|
||||
function name() {
|
||||
return $this->getLabel();
|
||||
}
|
||||
}
|
||||
?>
|
||||
42
tests/simpletest/extensions/testdox.php
Normal file
42
tests/simpletest/extensions/testdox.php
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
<?php
|
||||
|
||||
class TestDoxReporter extends SimpleReporter
|
||||
{
|
||||
var $_test_case_pattern = '/^TestOf(.*)$/';
|
||||
|
||||
function TestDoxReporter($test_case_pattern = '/^TestOf(.*)$/') {
|
||||
parent::SimpleScorer();
|
||||
$this->_test_case_pattern = empty($test_case_pattern) ? '/^(.*)$/' : $test_case_pattern;
|
||||
}
|
||||
|
||||
function paintCaseStart($test_name) {
|
||||
preg_match($this->_test_case_pattern, $test_name, $matches);
|
||||
if (!empty($matches[1])) {
|
||||
echo $matches[1] . "\n";
|
||||
} else {
|
||||
echo $test_name . "\n";
|
||||
}
|
||||
}
|
||||
|
||||
function paintCaseEnd() {
|
||||
echo "\n";
|
||||
}
|
||||
|
||||
function paintMethodStart($test_name) {
|
||||
if (!preg_match('/^test(.*)$/i', $test_name, $matches)) {
|
||||
return;
|
||||
}
|
||||
$test_name = $matches[1];
|
||||
|
||||
$test_name = preg_replace('/([A-Z])([A-Z])/', '$1 $2', $test_name);
|
||||
echo '- ' . strtolower(preg_replace('/([a-zA-Z])([A-Z0-9])/', '$1 $2', $test_name));
|
||||
}
|
||||
|
||||
function paintMethodEnd() {
|
||||
echo "\n";
|
||||
}
|
||||
|
||||
function paintFail() {
|
||||
echo " [FAILED]";
|
||||
}
|
||||
}
|
||||
108
tests/simpletest/extensions/testdox/test.php
Normal file
108
tests/simpletest/extensions/testdox/test.php
Normal file
|
|
@ -0,0 +1,108 @@
|
|||
<?php
|
||||
// $Id: test.php 1641 2008-01-22 20:13:52Z pp11 $
|
||||
require_once dirname(__FILE__) . '/../../autorun.php';
|
||||
require_once dirname(__FILE__) . '/../testdox.php';
|
||||
|
||||
// uncomment to see test dox in action
|
||||
//SimpleTest::prefer(new TestDoxReporter());
|
||||
|
||||
class TestOfTestDoxReporter extends UnitTestCase
|
||||
{
|
||||
function testIsAnInstanceOfSimpleScorerAndReporter() {
|
||||
$dox = new TestDoxReporter();
|
||||
$this->assertIsA($dox, 'SimpleScorer');
|
||||
$this->assertIsA($dox, 'SimpleReporter');
|
||||
}
|
||||
|
||||
function testOutputsNameOfTestCase() {
|
||||
$dox = new TestDoxReporter();
|
||||
ob_start();
|
||||
$dox->paintCaseStart('TestOfTestDoxReporter');
|
||||
$buffer = ob_get_clean();
|
||||
$this->assertWantedPattern('/^TestDoxReporter/', $buffer);
|
||||
}
|
||||
|
||||
function testOutputOfTestCaseNameFilteredByConstructParameter() {
|
||||
$dox = new TestDoxReporter('/^(.*)Test$/');
|
||||
ob_start();
|
||||
$dox->paintCaseStart('SomeGreatWidgetTest');
|
||||
$buffer = ob_get_clean();
|
||||
$this->assertWantedPattern('/^SomeGreatWidget/', $buffer);
|
||||
}
|
||||
|
||||
function testIfTest_case_patternIsEmptyAssumeEverythingMatches() {
|
||||
$dox = new TestDoxReporter('');
|
||||
ob_start();
|
||||
$dox->paintCaseStart('TestOfTestDoxReporter');
|
||||
$buffer = ob_get_clean();
|
||||
$this->assertWantedPattern('/^TestOfTestDoxReporter/', $buffer);
|
||||
}
|
||||
|
||||
function testEmptyLineInsertedWhenCaseEnds() {
|
||||
$dox = new TestDoxReporter();
|
||||
ob_start();
|
||||
$dox->paintCaseEnd('TestOfTestDoxReporter');
|
||||
$buffer = ob_get_clean();
|
||||
$this->assertEqual("\n", $buffer);
|
||||
}
|
||||
|
||||
function testPaintsTestMethodInTestDoxFormat() {
|
||||
$dox = new TestDoxReporter();
|
||||
ob_start();
|
||||
$dox->paintMethodStart('testSomeGreatTestCase');
|
||||
$buffer = ob_get_clean();
|
||||
$this->assertEqual("- some great test case", $buffer);
|
||||
unset($buffer);
|
||||
|
||||
$random = rand(100, 200);
|
||||
ob_start();
|
||||
$dox->paintMethodStart("testRandomNumberIs{$random}");
|
||||
$buffer = ob_get_clean();
|
||||
$this->assertEqual("- random number is {$random}", $buffer);
|
||||
}
|
||||
|
||||
function testDoesNotOutputAnythingOnNoneTestMethods() {
|
||||
$dox = new TestDoxReporter();
|
||||
ob_start();
|
||||
$dox->paintMethodStart('nonMatchingMethod');
|
||||
$buffer = ob_get_clean();
|
||||
$this->assertEqual('', $buffer);
|
||||
}
|
||||
|
||||
function testPaintMethodAddLineBreak() {
|
||||
$dox = new TestDoxReporter();
|
||||
ob_start();
|
||||
$dox->paintMethodEnd('someMethod');
|
||||
$buffer = ob_get_clean();
|
||||
$this->assertEqual("\n", $buffer);
|
||||
$this->assertNoErrors();
|
||||
}
|
||||
|
||||
function testProperlySpacesSingleLettersInMethodName() {
|
||||
$dox = new TestDoxReporter();
|
||||
ob_start();
|
||||
$dox->paintMethodStart('testAVerySimpleAgainAVerySimpleMethod');
|
||||
$buffer = ob_get_clean();
|
||||
$this->assertEqual('- a very simple again a very simple method', $buffer);
|
||||
}
|
||||
|
||||
function testOnFailureThisPrintsFailureNotice() {
|
||||
$dox = new TestDoxReporter();
|
||||
ob_start();
|
||||
$dox->paintFail();
|
||||
$buffer = ob_get_clean();
|
||||
$this->assertEqual(' [FAILED]', $buffer);
|
||||
}
|
||||
|
||||
function testWhenMatchingMethodNamesTestPrefixIsCaseInsensitive() {
|
||||
$dox = new TestDoxReporter();
|
||||
ob_start();
|
||||
$dox->paintMethodStart('TESTSupportsAllUppercaseTestPrefixEvenThoughIDoNotKnowWhyYouWouldDoThat');
|
||||
$buffer = ob_get_clean();
|
||||
$this->assertEqual(
|
||||
'- supports all uppercase test prefix even though i do not know why you would do that',
|
||||
$buffer
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
355
tests/simpletest/form.php
Normal file
355
tests/simpletest/form.php
Normal file
|
|
@ -0,0 +1,355 @@
|
|||
<?php
|
||||
/**
|
||||
* Base include file for SimpleTest.
|
||||
* @package SimpleTest
|
||||
* @subpackage WebTester
|
||||
* @version $Id: form.php 1672 2008-03-02 04:47:34Z edwardzyang $
|
||||
*/
|
||||
|
||||
/**#@+
|
||||
* include SimpleTest files
|
||||
*/
|
||||
require_once(dirname(__FILE__) . '/tag.php');
|
||||
require_once(dirname(__FILE__) . '/encoding.php');
|
||||
require_once(dirname(__FILE__) . '/selector.php');
|
||||
/**#@-*/
|
||||
|
||||
/**
|
||||
* Form tag class to hold widget values.
|
||||
* @package SimpleTest
|
||||
* @subpackage WebTester
|
||||
*/
|
||||
class SimpleForm {
|
||||
var $_method;
|
||||
var $_action;
|
||||
var $_encoding;
|
||||
var $_default_target;
|
||||
var $_id;
|
||||
var $_buttons;
|
||||
var $_images;
|
||||
var $_widgets;
|
||||
var $_radios;
|
||||
var $_checkboxes;
|
||||
|
||||
/**
|
||||
* Starts with no held controls/widgets.
|
||||
* @param SimpleTag $tag Form tag to read.
|
||||
* @param SimplePage $page Holding page.
|
||||
*/
|
||||
function SimpleForm($tag, &$page) {
|
||||
$this->_method = $tag->getAttribute('method');
|
||||
$this->_action = $this->_createAction($tag->getAttribute('action'), $page);
|
||||
$this->_encoding = $this->_setEncodingClass($tag);
|
||||
$this->_default_target = false;
|
||||
$this->_id = $tag->getAttribute('id');
|
||||
$this->_buttons = array();
|
||||
$this->_images = array();
|
||||
$this->_widgets = array();
|
||||
$this->_radios = array();
|
||||
$this->_checkboxes = array();
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates the request packet to be sent by the form.
|
||||
* @param SimpleTag $tag Form tag to read.
|
||||
* @return string Packet class.
|
||||
* @access private
|
||||
*/
|
||||
function _setEncodingClass($tag) {
|
||||
if (strtolower($tag->getAttribute('method')) == 'post') {
|
||||
if (strtolower($tag->getAttribute('enctype')) == 'multipart/form-data') {
|
||||
return 'SimpleMultipartEncoding';
|
||||
}
|
||||
return 'SimplePostEncoding';
|
||||
}
|
||||
return 'SimpleGetEncoding';
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the frame target within a frameset.
|
||||
* @param string $frame Name of frame.
|
||||
* @access public
|
||||
*/
|
||||
function setDefaultTarget($frame) {
|
||||
$this->_default_target = $frame;
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for method of form submission.
|
||||
* @return string Either get or post.
|
||||
* @access public
|
||||
*/
|
||||
function getMethod() {
|
||||
return ($this->_method ? strtolower($this->_method) : 'get');
|
||||
}
|
||||
|
||||
/**
|
||||
* Combined action attribute with current location
|
||||
* to get an absolute form target.
|
||||
* @param string $action Action attribute from form tag.
|
||||
* @param SimpleUrl $base Page location.
|
||||
* @return SimpleUrl Absolute form target.
|
||||
*/
|
||||
function _createAction($action, &$page) {
|
||||
if (($action === '') || ($action === false)) {
|
||||
return $page->expandUrl($page->getUrl());
|
||||
}
|
||||
return $page->expandUrl(new SimpleUrl($action));;
|
||||
}
|
||||
|
||||
/**
|
||||
* Absolute URL of the target.
|
||||
* @return SimpleUrl URL target.
|
||||
* @access public
|
||||
*/
|
||||
function getAction() {
|
||||
$url = $this->_action;
|
||||
if ($this->_default_target && ! $url->getTarget()) {
|
||||
$url->setTarget($this->_default_target);
|
||||
}
|
||||
return $url;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates the encoding for the current values in the
|
||||
* form.
|
||||
* @return SimpleFormEncoding Request to submit.
|
||||
* @access private
|
||||
*/
|
||||
function _encode() {
|
||||
$class = $this->_encoding;
|
||||
$encoding = new $class();
|
||||
for ($i = 0, $count = count($this->_widgets); $i < $count; $i++) {
|
||||
$this->_widgets[$i]->write($encoding);
|
||||
}
|
||||
return $encoding;
|
||||
}
|
||||
|
||||
/**
|
||||
* ID field of form for unique identification.
|
||||
* @return string Unique tag ID.
|
||||
* @access public
|
||||
*/
|
||||
function getId() {
|
||||
return $this->_id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a tag contents to the form.
|
||||
* @param SimpleWidget $tag Input tag to add.
|
||||
* @access public
|
||||
*/
|
||||
function addWidget(&$tag) {
|
||||
if (strtolower($tag->getAttribute('type')) == 'submit') {
|
||||
$this->_buttons[] = &$tag;
|
||||
} elseif (strtolower($tag->getAttribute('type')) == 'image') {
|
||||
$this->_images[] = &$tag;
|
||||
} elseif ($tag->getName()) {
|
||||
$this->_setWidget($tag);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the widget into the form, grouping radio
|
||||
* buttons if any.
|
||||
* @param SimpleWidget $tag Incoming form control.
|
||||
* @access private
|
||||
*/
|
||||
function _setWidget(&$tag) {
|
||||
if (strtolower($tag->getAttribute('type')) == 'radio') {
|
||||
$this->_addRadioButton($tag);
|
||||
} elseif (strtolower($tag->getAttribute('type')) == 'checkbox') {
|
||||
$this->_addCheckbox($tag);
|
||||
} else {
|
||||
$this->_widgets[] = &$tag;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a radio button, building a group if necessary.
|
||||
* @param SimpleRadioButtonTag $tag Incoming form control.
|
||||
* @access private
|
||||
*/
|
||||
function _addRadioButton(&$tag) {
|
||||
if (! isset($this->_radios[$tag->getName()])) {
|
||||
$this->_widgets[] = &new SimpleRadioGroup();
|
||||
$this->_radios[$tag->getName()] = count($this->_widgets) - 1;
|
||||
}
|
||||
$this->_widgets[$this->_radios[$tag->getName()]]->addWidget($tag);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a checkbox, making it a group on a repeated name.
|
||||
* @param SimpleCheckboxTag $tag Incoming form control.
|
||||
* @access private
|
||||
*/
|
||||
function _addCheckbox(&$tag) {
|
||||
if (! isset($this->_checkboxes[$tag->getName()])) {
|
||||
$this->_widgets[] = &$tag;
|
||||
$this->_checkboxes[$tag->getName()] = count($this->_widgets) - 1;
|
||||
} else {
|
||||
$index = $this->_checkboxes[$tag->getName()];
|
||||
if (! SimpleTestCompatibility::isA($this->_widgets[$index], 'SimpleCheckboxGroup')) {
|
||||
$previous = &$this->_widgets[$index];
|
||||
$this->_widgets[$index] = &new SimpleCheckboxGroup();
|
||||
$this->_widgets[$index]->addWidget($previous);
|
||||
}
|
||||
$this->_widgets[$index]->addWidget($tag);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Extracts current value from form.
|
||||
* @param SimpleSelector $selector Criteria to apply.
|
||||
* @return string/array Value(s) as string or null
|
||||
* if not set.
|
||||
* @access public
|
||||
*/
|
||||
function getValue($selector) {
|
||||
for ($i = 0, $count = count($this->_widgets); $i < $count; $i++) {
|
||||
if ($selector->isMatch($this->_widgets[$i])) {
|
||||
return $this->_widgets[$i]->getValue();
|
||||
}
|
||||
}
|
||||
foreach ($this->_buttons as $button) {
|
||||
if ($selector->isMatch($button)) {
|
||||
return $button->getValue();
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a widget value within the form.
|
||||
* @param SimpleSelector $selector Criteria to apply.
|
||||
* @param string $value Value to input into the widget.
|
||||
* @return boolean True if value is legal, false
|
||||
* otherwise. If the field is not
|
||||
* present, nothing will be set.
|
||||
* @access public
|
||||
*/
|
||||
function setField($selector, $value, $position=false) {
|
||||
$success = false;
|
||||
$_position = 0;
|
||||
for ($i = 0, $count = count($this->_widgets); $i < $count; $i++) {
|
||||
if ($selector->isMatch($this->_widgets[$i])) {
|
||||
$_position++;
|
||||
if ($position === false or $_position === (int)$position) {
|
||||
if ($this->_widgets[$i]->setValue($value)) {
|
||||
$success = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return $success;
|
||||
}
|
||||
|
||||
/**
|
||||
* Used by the page object to set widgets labels to
|
||||
* external label tags.
|
||||
* @param SimpleSelector $selector Criteria to apply.
|
||||
* @access public
|
||||
*/
|
||||
function attachLabelBySelector($selector, $label) {
|
||||
for ($i = 0, $count = count($this->_widgets); $i < $count; $i++) {
|
||||
if ($selector->isMatch($this->_widgets[$i])) {
|
||||
if (method_exists($this->_widgets[$i], 'setLabel')) {
|
||||
$this->_widgets[$i]->setLabel($label);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Test to see if a form has a submit button.
|
||||
* @param SimpleSelector $selector Criteria to apply.
|
||||
* @return boolean True if present.
|
||||
* @access public
|
||||
*/
|
||||
function hasSubmit($selector) {
|
||||
foreach ($this->_buttons as $button) {
|
||||
if ($selector->isMatch($button)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Test to see if a form has an image control.
|
||||
* @param SimpleSelector $selector Criteria to apply.
|
||||
* @return boolean True if present.
|
||||
* @access public
|
||||
*/
|
||||
function hasImage($selector) {
|
||||
foreach ($this->_images as $image) {
|
||||
if ($selector->isMatch($image)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the submit values for a selected button.
|
||||
* @param SimpleSelector $selector Criteria to apply.
|
||||
* @param hash $additional Additional data for the form.
|
||||
* @return SimpleEncoding Submitted values or false
|
||||
* if there is no such button
|
||||
* in the form.
|
||||
* @access public
|
||||
*/
|
||||
function submitButton($selector, $additional = false) {
|
||||
$additional = $additional ? $additional : array();
|
||||
foreach ($this->_buttons as $button) {
|
||||
if ($selector->isMatch($button)) {
|
||||
$encoding = $this->_encode();
|
||||
$button->write($encoding);
|
||||
if ($additional) {
|
||||
$encoding->merge($additional);
|
||||
}
|
||||
return $encoding;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the submit values for an image.
|
||||
* @param SimpleSelector $selector Criteria to apply.
|
||||
* @param integer $x X-coordinate of click.
|
||||
* @param integer $y Y-coordinate of click.
|
||||
* @param hash $additional Additional data for the form.
|
||||
* @return SimpleEncoding Submitted values or false
|
||||
* if there is no such button in the
|
||||
* form.
|
||||
* @access public
|
||||
*/
|
||||
function submitImage($selector, $x, $y, $additional = false) {
|
||||
$additional = $additional ? $additional : array();
|
||||
foreach ($this->_images as $image) {
|
||||
if ($selector->isMatch($image)) {
|
||||
$encoding = $this->_encode();
|
||||
$image->write($encoding, $x, $y);
|
||||
if ($additional) {
|
||||
$encoding->merge($additional);
|
||||
}
|
||||
return $encoding;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Simply submits the form without the submit button
|
||||
* value. Used when there is only one button or it
|
||||
* is unimportant.
|
||||
* @return hash Submitted values.
|
||||
* @access public
|
||||
*/
|
||||
function submit() {
|
||||
return $this->_encode();
|
||||
}
|
||||
}
|
||||
?>
|
||||
596
tests/simpletest/frames.php
Normal file
596
tests/simpletest/frames.php
Normal file
|
|
@ -0,0 +1,596 @@
|
|||
<?php
|
||||
/**
|
||||
* Base include file for SimpleTest
|
||||
* @package SimpleTest
|
||||
* @subpackage WebTester
|
||||
* @version $Id: frames.php 1672 2008-03-02 04:47:34Z edwardzyang $
|
||||
*/
|
||||
|
||||
/**#@+
|
||||
* include other SimpleTest class files
|
||||
*/
|
||||
require_once(dirname(__FILE__) . '/page.php');
|
||||
require_once(dirname(__FILE__) . '/user_agent.php');
|
||||
/**#@-*/
|
||||
|
||||
/**
|
||||
* A composite page. Wraps a frameset page and
|
||||
* adds subframes. The original page will be
|
||||
* mostly ignored. Implements the SimplePage
|
||||
* interface so as to be interchangeable.
|
||||
* @package SimpleTest
|
||||
* @subpackage WebTester
|
||||
*/
|
||||
class SimpleFrameset {
|
||||
var $_frameset;
|
||||
var $_frames;
|
||||
var $_focus;
|
||||
var $_names;
|
||||
|
||||
/**
|
||||
* Stashes the frameset page. Will make use of the
|
||||
* browser to fetch the sub frames recursively.
|
||||
* @param SimplePage $page Frameset page.
|
||||
*/
|
||||
function SimpleFrameset(&$page) {
|
||||
$this->_frameset = &$page;
|
||||
$this->_frames = array();
|
||||
$this->_focus = false;
|
||||
$this->_names = array();
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a parsed page to the frameset.
|
||||
* @param SimplePage $page Frame page.
|
||||
* @param string $name Name of frame in frameset.
|
||||
* @access public
|
||||
*/
|
||||
function addFrame(&$page, $name = false) {
|
||||
$this->_frames[] = &$page;
|
||||
if ($name) {
|
||||
$this->_names[$name] = count($this->_frames) - 1;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Replaces existing frame with another. If the
|
||||
* frame is nested, then the call is passed down
|
||||
* one level.
|
||||
* @param array $path Path of frame in frameset.
|
||||
* @param SimplePage $page Frame source.
|
||||
* @access public
|
||||
*/
|
||||
function setFrame($path, &$page) {
|
||||
$name = array_shift($path);
|
||||
if (isset($this->_names[$name])) {
|
||||
$index = $this->_names[$name];
|
||||
} else {
|
||||
$index = $name - 1;
|
||||
}
|
||||
if (count($path) == 0) {
|
||||
$this->_frames[$index] = &$page;
|
||||
return;
|
||||
}
|
||||
$this->_frames[$index]->setFrame($path, $page);
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for current frame focus. Will be
|
||||
* false if no frame has focus. Will have the nested
|
||||
* frame focus if any.
|
||||
* @return array Labels or indexes of nested frames.
|
||||
* @access public
|
||||
*/
|
||||
function getFrameFocus() {
|
||||
if ($this->_focus === false) {
|
||||
return array();
|
||||
}
|
||||
return array_merge(
|
||||
array($this->_getPublicNameFromIndex($this->_focus)),
|
||||
$this->_frames[$this->_focus]->getFrameFocus());
|
||||
}
|
||||
|
||||
/**
|
||||
* Turns an internal array index into the frames list
|
||||
* into a public name, or if none, then a one offset
|
||||
* index.
|
||||
* @param integer $subject Internal index.
|
||||
* @return integer/string Public name.
|
||||
* @access private
|
||||
*/
|
||||
function _getPublicNameFromIndex($subject) {
|
||||
foreach ($this->_names as $name => $index) {
|
||||
if ($subject == $index) {
|
||||
return $name;
|
||||
}
|
||||
}
|
||||
return $subject + 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the focus by index. The integer index starts from 1.
|
||||
* If already focused and the target frame also has frames,
|
||||
* then the nested frame will be focused.
|
||||
* @param integer $choice Chosen frame.
|
||||
* @return boolean True if frame exists.
|
||||
* @access public
|
||||
*/
|
||||
function setFrameFocusByIndex($choice) {
|
||||
if (is_integer($this->_focus)) {
|
||||
if ($this->_frames[$this->_focus]->hasFrames()) {
|
||||
return $this->_frames[$this->_focus]->setFrameFocusByIndex($choice);
|
||||
}
|
||||
}
|
||||
if (($choice < 1) || ($choice > count($this->_frames))) {
|
||||
return false;
|
||||
}
|
||||
$this->_focus = $choice - 1;
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the focus by name. If already focused and the
|
||||
* target frame also has frames, then the nested frame
|
||||
* will be focused.
|
||||
* @param string $name Chosen frame.
|
||||
* @return boolean True if frame exists.
|
||||
* @access public
|
||||
*/
|
||||
function setFrameFocus($name) {
|
||||
if (is_integer($this->_focus)) {
|
||||
if ($this->_frames[$this->_focus]->hasFrames()) {
|
||||
return $this->_frames[$this->_focus]->setFrameFocus($name);
|
||||
}
|
||||
}
|
||||
if (in_array($name, array_keys($this->_names))) {
|
||||
$this->_focus = $this->_names[$name];
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Clears the frame focus.
|
||||
* @access public
|
||||
*/
|
||||
function clearFrameFocus() {
|
||||
$this->_focus = false;
|
||||
$this->_clearNestedFramesFocus();
|
||||
}
|
||||
|
||||
/**
|
||||
* Clears the frame focus for any nested frames.
|
||||
* @access private
|
||||
*/
|
||||
function _clearNestedFramesFocus() {
|
||||
for ($i = 0; $i < count($this->_frames); $i++) {
|
||||
$this->_frames[$i]->clearFrameFocus();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Test for the presence of a frameset.
|
||||
* @return boolean Always true.
|
||||
* @access public
|
||||
*/
|
||||
function hasFrames() {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for frames information.
|
||||
* @return array/string Recursive hash of frame URL strings.
|
||||
* The key is either a numerical
|
||||
* index or the name attribute.
|
||||
* @access public
|
||||
*/
|
||||
function getFrames() {
|
||||
$report = array();
|
||||
for ($i = 0; $i < count($this->_frames); $i++) {
|
||||
$report[$this->_getPublicNameFromIndex($i)] =
|
||||
$this->_frames[$i]->getFrames();
|
||||
}
|
||||
return $report;
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for raw text of either all the pages or
|
||||
* the frame in focus.
|
||||
* @return string Raw unparsed content.
|
||||
* @access public
|
||||
*/
|
||||
function getRaw() {
|
||||
if (is_integer($this->_focus)) {
|
||||
return $this->_frames[$this->_focus]->getRaw();
|
||||
}
|
||||
$raw = '';
|
||||
for ($i = 0; $i < count($this->_frames); $i++) {
|
||||
$raw .= $this->_frames[$i]->getRaw();
|
||||
}
|
||||
return $raw;
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for plain text of either all the pages or
|
||||
* the frame in focus.
|
||||
* @return string Plain text content.
|
||||
* @access public
|
||||
*/
|
||||
function getText() {
|
||||
if (is_integer($this->_focus)) {
|
||||
return $this->_frames[$this->_focus]->getText();
|
||||
}
|
||||
$raw = '';
|
||||
for ($i = 0; $i < count($this->_frames); $i++) {
|
||||
$raw .= ' ' . $this->_frames[$i]->getText();
|
||||
}
|
||||
return trim($raw);
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for last error.
|
||||
* @return string Error from last response.
|
||||
* @access public
|
||||
*/
|
||||
function getTransportError() {
|
||||
if (is_integer($this->_focus)) {
|
||||
return $this->_frames[$this->_focus]->getTransportError();
|
||||
}
|
||||
return $this->_frameset->getTransportError();
|
||||
}
|
||||
|
||||
/**
|
||||
* Request method used to fetch this frame.
|
||||
* @return string GET, POST or HEAD.
|
||||
* @access public
|
||||
*/
|
||||
function getMethod() {
|
||||
if (is_integer($this->_focus)) {
|
||||
return $this->_frames[$this->_focus]->getMethod();
|
||||
}
|
||||
return $this->_frameset->getMethod();
|
||||
}
|
||||
|
||||
/**
|
||||
* Original resource name.
|
||||
* @return SimpleUrl Current url.
|
||||
* @access public
|
||||
*/
|
||||
function getUrl() {
|
||||
if (is_integer($this->_focus)) {
|
||||
$url = $this->_frames[$this->_focus]->getUrl();
|
||||
$url->setTarget($this->_getPublicNameFromIndex($this->_focus));
|
||||
} else {
|
||||
$url = $this->_frameset->getUrl();
|
||||
}
|
||||
return $url;
|
||||
}
|
||||
|
||||
/**
|
||||
* Page base URL.
|
||||
* @return SimpleUrl Current url.
|
||||
* @access public
|
||||
*/
|
||||
function getBaseUrl() {
|
||||
if (is_integer($this->_focus)) {
|
||||
$url = $this->_frames[$this->_focus]->getBaseUrl();
|
||||
} else {
|
||||
$url = $this->_frameset->getBaseUrl();
|
||||
}
|
||||
return $url;
|
||||
}
|
||||
|
||||
/**
|
||||
* Expands expandomatic URLs into fully qualified
|
||||
* URLs for the frameset page.
|
||||
* @param SimpleUrl $url Relative URL.
|
||||
* @return SimpleUrl Absolute URL.
|
||||
* @access public
|
||||
*/
|
||||
function expandUrl($url) {
|
||||
return $this->_frameset->expandUrl($url);
|
||||
}
|
||||
|
||||
/**
|
||||
* Original request data.
|
||||
* @return mixed Sent content.
|
||||
* @access public
|
||||
*/
|
||||
function getRequestData() {
|
||||
if (is_integer($this->_focus)) {
|
||||
return $this->_frames[$this->_focus]->getRequestData();
|
||||
}
|
||||
return $this->_frameset->getRequestData();
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for current MIME type.
|
||||
* @return string MIME type as string; e.g. 'text/html'
|
||||
* @access public
|
||||
*/
|
||||
function getMimeType() {
|
||||
if (is_integer($this->_focus)) {
|
||||
return $this->_frames[$this->_focus]->getMimeType();
|
||||
}
|
||||
return $this->_frameset->getMimeType();
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for last response code.
|
||||
* @return integer Last HTTP response code received.
|
||||
* @access public
|
||||
*/
|
||||
function getResponseCode() {
|
||||
if (is_integer($this->_focus)) {
|
||||
return $this->_frames[$this->_focus]->getResponseCode();
|
||||
}
|
||||
return $this->_frameset->getResponseCode();
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for last Authentication type. Only valid
|
||||
* straight after a challenge (401).
|
||||
* @return string Description of challenge type.
|
||||
* @access public
|
||||
*/
|
||||
function getAuthentication() {
|
||||
if (is_integer($this->_focus)) {
|
||||
return $this->_frames[$this->_focus]->getAuthentication();
|
||||
}
|
||||
return $this->_frameset->getAuthentication();
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for last Authentication realm. Only valid
|
||||
* straight after a challenge (401).
|
||||
* @return string Name of security realm.
|
||||
* @access public
|
||||
*/
|
||||
function getRealm() {
|
||||
if (is_integer($this->_focus)) {
|
||||
return $this->_frames[$this->_focus]->getRealm();
|
||||
}
|
||||
return $this->_frameset->getRealm();
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for outgoing header information.
|
||||
* @return string Header block.
|
||||
* @access public
|
||||
*/
|
||||
function getRequest() {
|
||||
if (is_integer($this->_focus)) {
|
||||
return $this->_frames[$this->_focus]->getRequest();
|
||||
}
|
||||
return $this->_frameset->getRequest();
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for raw header information.
|
||||
* @return string Header block.
|
||||
* @access public
|
||||
*/
|
||||
function getHeaders() {
|
||||
if (is_integer($this->_focus)) {
|
||||
return $this->_frames[$this->_focus]->getHeaders();
|
||||
}
|
||||
return $this->_frameset->getHeaders();
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for parsed title.
|
||||
* @return string Title or false if no title is present.
|
||||
* @access public
|
||||
*/
|
||||
function getTitle() {
|
||||
return $this->_frameset->getTitle();
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for a list of all fixed links.
|
||||
* @return array List of urls as strings.
|
||||
* @access public
|
||||
*/
|
||||
function getUrls() {
|
||||
if (is_integer($this->_focus)) {
|
||||
return $this->_frames[$this->_focus]->getUrls();
|
||||
}
|
||||
$urls = array();
|
||||
foreach ($this->_frames as $frame) {
|
||||
$urls = array_merge($urls, $frame->getUrls());
|
||||
}
|
||||
return array_values(array_unique($urls));
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for URLs by the link label. Label will match
|
||||
* regardess of whitespace issues and case.
|
||||
* @param string $label Text of link.
|
||||
* @return array List of links with that label.
|
||||
* @access public
|
||||
*/
|
||||
function getUrlsByLabel($label) {
|
||||
if (is_integer($this->_focus)) {
|
||||
return $this->_tagUrlsWithFrame(
|
||||
$this->_frames[$this->_focus]->getUrlsByLabel($label),
|
||||
$this->_focus);
|
||||
}
|
||||
$urls = array();
|
||||
foreach ($this->_frames as $index => $frame) {
|
||||
$urls = array_merge(
|
||||
$urls,
|
||||
$this->_tagUrlsWithFrame(
|
||||
$frame->getUrlsByLabel($label),
|
||||
$index));
|
||||
}
|
||||
return $urls;
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for a URL by the id attribute. If in a frameset
|
||||
* then the first link found with that ID attribute is
|
||||
* returned only. Focus on a frame if you want one from
|
||||
* a specific part of the frameset.
|
||||
* @param string $id Id attribute of link.
|
||||
* @return string URL with that id.
|
||||
* @access public
|
||||
*/
|
||||
function getUrlById($id) {
|
||||
foreach ($this->_frames as $index => $frame) {
|
||||
if ($url = $frame->getUrlById($id)) {
|
||||
if (! $url->gettarget()) {
|
||||
$url->setTarget($this->_getPublicNameFromIndex($index));
|
||||
}
|
||||
return $url;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Attaches the intended frame index to a list of URLs.
|
||||
* @param array $urls List of SimpleUrls.
|
||||
* @param string $frame Name of frame or index.
|
||||
* @return array List of tagged URLs.
|
||||
* @access private
|
||||
*/
|
||||
function _tagUrlsWithFrame($urls, $frame) {
|
||||
$tagged = array();
|
||||
foreach ($urls as $url) {
|
||||
if (! $url->getTarget()) {
|
||||
$url->setTarget($this->_getPublicNameFromIndex($frame));
|
||||
}
|
||||
$tagged[] = $url;
|
||||
}
|
||||
return $tagged;
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds a held form by button label. Will only
|
||||
* search correctly built forms.
|
||||
* @param SimpleSelector $selector Button finder.
|
||||
* @return SimpleForm Form object containing
|
||||
* the button.
|
||||
* @access public
|
||||
*/
|
||||
function &getFormBySubmit($selector) {
|
||||
$form = &$this->_findForm('getFormBySubmit', $selector);
|
||||
return $form;
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds a held form by image using a selector.
|
||||
* Will only search correctly built forms. The first
|
||||
* form found either within the focused frame, or
|
||||
* across frames, will be the one returned.
|
||||
* @param SimpleSelector $selector Image finder.
|
||||
* @return SimpleForm Form object containing
|
||||
* the image.
|
||||
* @access public
|
||||
*/
|
||||
function &getFormByImage($selector) {
|
||||
$form = &$this->_findForm('getFormByImage', $selector);
|
||||
return $form;
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds a held form by the form ID. A way of
|
||||
* identifying a specific form when we have control
|
||||
* of the HTML code. The first form found
|
||||
* either within the focused frame, or across frames,
|
||||
* will be the one returned.
|
||||
* @param string $id Form label.
|
||||
* @return SimpleForm Form object containing the matching ID.
|
||||
* @access public
|
||||
*/
|
||||
function &getFormById($id) {
|
||||
$form = &$this->_findForm('getFormById', $id);
|
||||
return $form;
|
||||
}
|
||||
|
||||
/**
|
||||
* General form finder. Will search all the frames or
|
||||
* just the one in focus.
|
||||
* @param string $method Method to use to find in a page.
|
||||
* @param string $attribute Label, name or ID.
|
||||
* @return SimpleForm Form object containing the matching ID.
|
||||
* @access private
|
||||
*/
|
||||
function &_findForm($method, $attribute) {
|
||||
if (is_integer($this->_focus)) {
|
||||
$form = &$this->_findFormInFrame(
|
||||
$this->_frames[$this->_focus],
|
||||
$this->_focus,
|
||||
$method,
|
||||
$attribute);
|
||||
return $form;
|
||||
}
|
||||
for ($i = 0; $i < count($this->_frames); $i++) {
|
||||
$form = &$this->_findFormInFrame(
|
||||
$this->_frames[$i],
|
||||
$i,
|
||||
$method,
|
||||
$attribute);
|
||||
if ($form) {
|
||||
return $form;
|
||||
}
|
||||
}
|
||||
$null = null;
|
||||
return $null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds a form in a page using a form finding method. Will
|
||||
* also tag the form with the frame name it belongs in.
|
||||
* @param SimplePage $page Page content of frame.
|
||||
* @param integer $index Internal frame representation.
|
||||
* @param string $method Method to use to find in a page.
|
||||
* @param string $attribute Label, name or ID.
|
||||
* @return SimpleForm Form object containing the matching ID.
|
||||
* @access private
|
||||
*/
|
||||
function &_findFormInFrame(&$page, $index, $method, $attribute) {
|
||||
$form = &$this->_frames[$index]->$method($attribute);
|
||||
if (isset($form)) {
|
||||
$form->setDefaultTarget($this->_getPublicNameFromIndex($index));
|
||||
}
|
||||
return $form;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a field on each form in which the field is
|
||||
* available.
|
||||
* @param SimpleSelector $selector Field finder.
|
||||
* @param string $value Value to set field to.
|
||||
* @return boolean True if value is valid.
|
||||
* @access public
|
||||
*/
|
||||
function setField($selector, $value) {
|
||||
if (is_integer($this->_focus)) {
|
||||
$this->_frames[$this->_focus]->setField($selector, $value);
|
||||
} else {
|
||||
for ($i = 0; $i < count($this->_frames); $i++) {
|
||||
$this->_frames[$i]->setField($selector, $value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for a form element value within a page.
|
||||
* @param SimpleSelector $selector Field finder.
|
||||
* @return string/boolean A string if the field is
|
||||
* present, false if unchecked
|
||||
* and null if missing.
|
||||
* @access public
|
||||
*/
|
||||
function getField($selector) {
|
||||
for ($i = 0; $i < count($this->_frames); $i++) {
|
||||
$value = $this->_frames[$i]->getField($selector);
|
||||
if (isset($value)) {
|
||||
return $value;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
?>
|
||||
624
tests/simpletest/http.php
Normal file
624
tests/simpletest/http.php
Normal file
|
|
@ -0,0 +1,624 @@
|
|||
<?php
|
||||
/**
|
||||
* base include file for SimpleTest
|
||||
* @package SimpleTest
|
||||
* @subpackage WebTester
|
||||
* @version $Id: http.php 1722 2008-04-07 19:30:56Z lastcraft $
|
||||
*/
|
||||
|
||||
/**#@+
|
||||
* include other SimpleTest class files
|
||||
*/
|
||||
require_once(dirname(__FILE__) . '/socket.php');
|
||||
require_once(dirname(__FILE__) . '/cookies.php');
|
||||
require_once(dirname(__FILE__) . '/url.php');
|
||||
/**#@-*/
|
||||
|
||||
/**
|
||||
* Creates HTTP headers for the end point of
|
||||
* a HTTP request.
|
||||
* @package SimpleTest
|
||||
* @subpackage WebTester
|
||||
*/
|
||||
class SimpleRoute {
|
||||
var $_url;
|
||||
|
||||
/**
|
||||
* Sets the target URL.
|
||||
* @param SimpleUrl $url URL as object.
|
||||
* @access public
|
||||
*/
|
||||
function SimpleRoute($url) {
|
||||
$this->_url = $url;
|
||||
}
|
||||
|
||||
/**
|
||||
* Resource name.
|
||||
* @return SimpleUrl Current url.
|
||||
* @access protected
|
||||
*/
|
||||
function getUrl() {
|
||||
return $this->_url;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates the first line which is the actual request.
|
||||
* @param string $method HTTP request method, usually GET.
|
||||
* @return string Request line content.
|
||||
* @access protected
|
||||
*/
|
||||
function _getRequestLine($method) {
|
||||
return $method . ' ' . $this->_url->getPath() .
|
||||
$this->_url->getEncodedRequest() . ' HTTP/1.0';
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates the host part of the request.
|
||||
* @return string Host line content.
|
||||
* @access protected
|
||||
*/
|
||||
function _getHostLine() {
|
||||
$line = 'Host: ' . $this->_url->getHost();
|
||||
if ($this->_url->getPort()) {
|
||||
$line .= ':' . $this->_url->getPort();
|
||||
}
|
||||
return $line;
|
||||
}
|
||||
|
||||
/**
|
||||
* Opens a socket to the route.
|
||||
* @param string $method HTTP request method, usually GET.
|
||||
* @param integer $timeout Connection timeout.
|
||||
* @return SimpleSocket New socket.
|
||||
* @access public
|
||||
*/
|
||||
function &createConnection($method, $timeout) {
|
||||
$default_port = ('https' == $this->_url->getScheme()) ? 443 : 80;
|
||||
$socket = &$this->_createSocket(
|
||||
$this->_url->getScheme() ? $this->_url->getScheme() : 'http',
|
||||
$this->_url->getHost(),
|
||||
$this->_url->getPort() ? $this->_url->getPort() : $default_port,
|
||||
$timeout);
|
||||
if (! $socket->isError()) {
|
||||
$socket->write($this->_getRequestLine($method) . "\r\n");
|
||||
$socket->write($this->_getHostLine() . "\r\n");
|
||||
$socket->write("Connection: close\r\n");
|
||||
}
|
||||
return $socket;
|
||||
}
|
||||
|
||||
/**
|
||||
* Factory for socket.
|
||||
* @param string $scheme Protocol to use.
|
||||
* @param string $host Hostname to connect to.
|
||||
* @param integer $port Remote port.
|
||||
* @param integer $timeout Connection timeout.
|
||||
* @return SimpleSocket/SimpleSecureSocket New socket.
|
||||
* @access protected
|
||||
*/
|
||||
function &_createSocket($scheme, $host, $port, $timeout) {
|
||||
if (in_array($scheme, array('https'))) {
|
||||
$socket = &new SimpleSecureSocket($host, $port, $timeout);
|
||||
} else {
|
||||
$socket = &new SimpleSocket($host, $port, $timeout);
|
||||
}
|
||||
return $socket;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates HTTP headers for the end point of
|
||||
* a HTTP request via a proxy server.
|
||||
* @package SimpleTest
|
||||
* @subpackage WebTester
|
||||
*/
|
||||
class SimpleProxyRoute extends SimpleRoute {
|
||||
var $_proxy;
|
||||
var $_username;
|
||||
var $_password;
|
||||
|
||||
/**
|
||||
* Stashes the proxy address.
|
||||
* @param SimpleUrl $url URL as object.
|
||||
* @param string $proxy Proxy URL.
|
||||
* @param string $username Username for autentication.
|
||||
* @param string $password Password for autentication.
|
||||
* @access public
|
||||
*/
|
||||
function SimpleProxyRoute($url, $proxy, $username = false, $password = false) {
|
||||
$this->SimpleRoute($url);
|
||||
$this->_proxy = $proxy;
|
||||
$this->_username = $username;
|
||||
$this->_password = $password;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates the first line which is the actual request.
|
||||
* @param string $method HTTP request method, usually GET.
|
||||
* @param SimpleUrl $url URL as object.
|
||||
* @return string Request line content.
|
||||
* @access protected
|
||||
*/
|
||||
function _getRequestLine($method) {
|
||||
$url = $this->getUrl();
|
||||
$scheme = $url->getScheme() ? $url->getScheme() : 'http';
|
||||
$port = $url->getPort() ? ':' . $url->getPort() : '';
|
||||
return $method . ' ' . $scheme . '://' . $url->getHost() . $port .
|
||||
$url->getPath() . $url->getEncodedRequest() . ' HTTP/1.0';
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates the host part of the request.
|
||||
* @param SimpleUrl $url URL as object.
|
||||
* @return string Host line content.
|
||||
* @access protected
|
||||
*/
|
||||
function _getHostLine() {
|
||||
$host = 'Host: ' . $this->_proxy->getHost();
|
||||
$port = $this->_proxy->getPort() ? $this->_proxy->getPort() : 8080;
|
||||
return "$host:$port";
|
||||
}
|
||||
|
||||
/**
|
||||
* Opens a socket to the route.
|
||||
* @param string $method HTTP request method, usually GET.
|
||||
* @param integer $timeout Connection timeout.
|
||||
* @return SimpleSocket New socket.
|
||||
* @access public
|
||||
*/
|
||||
function &createConnection($method, $timeout) {
|
||||
$socket = &$this->_createSocket(
|
||||
$this->_proxy->getScheme() ? $this->_proxy->getScheme() : 'http',
|
||||
$this->_proxy->getHost(),
|
||||
$this->_proxy->getPort() ? $this->_proxy->getPort() : 8080,
|
||||
$timeout);
|
||||
if ($socket->isError()) {
|
||||
return $socket;
|
||||
}
|
||||
$socket->write($this->_getRequestLine($method) . "\r\n");
|
||||
$socket->write($this->_getHostLine() . "\r\n");
|
||||
if ($this->_username && $this->_password) {
|
||||
$socket->write('Proxy-Authorization: Basic ' .
|
||||
base64_encode($this->_username . ':' . $this->_password) .
|
||||
"\r\n");
|
||||
}
|
||||
$socket->write("Connection: close\r\n");
|
||||
return $socket;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* HTTP request for a web page. Factory for
|
||||
* HttpResponse object.
|
||||
* @package SimpleTest
|
||||
* @subpackage WebTester
|
||||
*/
|
||||
class SimpleHttpRequest {
|
||||
var $_route;
|
||||
var $_encoding;
|
||||
var $_headers;
|
||||
var $_cookies;
|
||||
|
||||
/**
|
||||
* Builds the socket request from the different pieces.
|
||||
* These include proxy information, URL, cookies, headers,
|
||||
* request method and choice of encoding.
|
||||
* @param SimpleRoute $route Request route.
|
||||
* @param SimpleFormEncoding $encoding Content to send with
|
||||
* request.
|
||||
* @access public
|
||||
*/
|
||||
function SimpleHttpRequest(&$route, $encoding) {
|
||||
$this->_route = &$route;
|
||||
$this->_encoding = $encoding;
|
||||
$this->_headers = array();
|
||||
$this->_cookies = array();
|
||||
}
|
||||
|
||||
/**
|
||||
* Dispatches the content to the route's socket.
|
||||
* @param integer $timeout Connection timeout.
|
||||
* @return SimpleHttpResponse A response which may only have
|
||||
* an error, but hopefully has a
|
||||
* complete web page.
|
||||
* @access public
|
||||
*/
|
||||
function &fetch($timeout) {
|
||||
$socket = &$this->_route->createConnection($this->_encoding->getMethod(), $timeout);
|
||||
if (! $socket->isError()) {
|
||||
$this->_dispatchRequest($socket, $this->_encoding);
|
||||
}
|
||||
$response = &$this->_createResponse($socket);
|
||||
return $response;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends the headers.
|
||||
* @param SimpleSocket $socket Open socket.
|
||||
* @param string $method HTTP request method,
|
||||
* usually GET.
|
||||
* @param SimpleFormEncoding $encoding Content to send with request.
|
||||
* @access private
|
||||
*/
|
||||
function _dispatchRequest(&$socket, $encoding) {
|
||||
foreach ($this->_headers as $header_line) {
|
||||
$socket->write($header_line . "\r\n");
|
||||
}
|
||||
if (count($this->_cookies) > 0) {
|
||||
$socket->write("Cookie: " . implode(";", $this->_cookies) . "\r\n");
|
||||
}
|
||||
$encoding->writeHeadersTo($socket);
|
||||
$socket->write("\r\n");
|
||||
$encoding->writeTo($socket);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a header line to the request.
|
||||
* @param string $header_line Text of full header line.
|
||||
* @access public
|
||||
*/
|
||||
function addHeaderLine($header_line) {
|
||||
$this->_headers[] = $header_line;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads all the relevant cookies from the
|
||||
* cookie jar.
|
||||
* @param SimpleCookieJar $jar Jar to read
|
||||
* @param SimpleUrl $url Url to use for scope.
|
||||
* @access public
|
||||
*/
|
||||
function readCookiesFromJar($jar, $url) {
|
||||
$this->_cookies = $jar->selectAsPairs($url);
|
||||
}
|
||||
|
||||
/**
|
||||
* Wraps the socket in a response parser.
|
||||
* @param SimpleSocket $socket Responding socket.
|
||||
* @return SimpleHttpResponse Parsed response object.
|
||||
* @access protected
|
||||
*/
|
||||
function &_createResponse(&$socket) {
|
||||
$response = &new SimpleHttpResponse(
|
||||
$socket,
|
||||
$this->_route->getUrl(),
|
||||
$this->_encoding);
|
||||
return $response;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Collection of header lines in the response.
|
||||
* @package SimpleTest
|
||||
* @subpackage WebTester
|
||||
*/
|
||||
class SimpleHttpHeaders {
|
||||
var $_raw_headers;
|
||||
var $_response_code;
|
||||
var $_http_version;
|
||||
var $_mime_type;
|
||||
var $_location;
|
||||
var $_cookies;
|
||||
var $_authentication;
|
||||
var $_realm;
|
||||
|
||||
/**
|
||||
* Parses the incoming header block.
|
||||
* @param string $headers Header block.
|
||||
* @access public
|
||||
*/
|
||||
function SimpleHttpHeaders($headers) {
|
||||
$this->_raw_headers = $headers;
|
||||
$this->_response_code = false;
|
||||
$this->_http_version = false;
|
||||
$this->_mime_type = '';
|
||||
$this->_location = false;
|
||||
$this->_cookies = array();
|
||||
$this->_authentication = false;
|
||||
$this->_realm = false;
|
||||
foreach (split("\r\n", $headers) as $header_line) {
|
||||
$this->_parseHeaderLine($header_line);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for parsed HTTP protocol version.
|
||||
* @return integer HTTP error code.
|
||||
* @access public
|
||||
*/
|
||||
function getHttpVersion() {
|
||||
return $this->_http_version;
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for raw header block.
|
||||
* @return string All headers as raw string.
|
||||
* @access public
|
||||
*/
|
||||
function getRaw() {
|
||||
return $this->_raw_headers;
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for parsed HTTP error code.
|
||||
* @return integer HTTP error code.
|
||||
* @access public
|
||||
*/
|
||||
function getResponseCode() {
|
||||
return (integer)$this->_response_code;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the redirected URL or false if
|
||||
* no redirection.
|
||||
* @return string URL or false for none.
|
||||
* @access public
|
||||
*/
|
||||
function getLocation() {
|
||||
return $this->_location;
|
||||
}
|
||||
|
||||
/**
|
||||
* Test to see if the response is a valid redirect.
|
||||
* @return boolean True if valid redirect.
|
||||
* @access public
|
||||
*/
|
||||
function isRedirect() {
|
||||
return in_array($this->_response_code, array(301, 302, 303, 307)) &&
|
||||
(boolean)$this->getLocation();
|
||||
}
|
||||
|
||||
/**
|
||||
* Test to see if the response is an authentication
|
||||
* challenge.
|
||||
* @return boolean True if challenge.
|
||||
* @access public
|
||||
*/
|
||||
function isChallenge() {
|
||||
return ($this->_response_code == 401) &&
|
||||
(boolean)$this->_authentication &&
|
||||
(boolean)$this->_realm;
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for MIME type header information.
|
||||
* @return string MIME type.
|
||||
* @access public
|
||||
*/
|
||||
function getMimeType() {
|
||||
return $this->_mime_type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for authentication type.
|
||||
* @return string Type.
|
||||
* @access public
|
||||
*/
|
||||
function getAuthentication() {
|
||||
return $this->_authentication;
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for security realm.
|
||||
* @return string Realm.
|
||||
* @access public
|
||||
*/
|
||||
function getRealm() {
|
||||
return $this->_realm;
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes new cookies to the cookie jar.
|
||||
* @param SimpleCookieJar $jar Jar to write to.
|
||||
* @param SimpleUrl $url Host and path to write under.
|
||||
* @access public
|
||||
*/
|
||||
function writeCookiesToJar(&$jar, $url) {
|
||||
foreach ($this->_cookies as $cookie) {
|
||||
$jar->setCookie(
|
||||
$cookie->getName(),
|
||||
$cookie->getValue(),
|
||||
$url->getHost(),
|
||||
$cookie->getPath(),
|
||||
$cookie->getExpiry());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Called on each header line to accumulate the held
|
||||
* data within the class.
|
||||
* @param string $header_line One line of header.
|
||||
* @access protected
|
||||
*/
|
||||
function _parseHeaderLine($header_line) {
|
||||
if (preg_match('/HTTP\/(\d+\.\d+)\s+(\d+)/i', $header_line, $matches)) {
|
||||
$this->_http_version = $matches[1];
|
||||
$this->_response_code = $matches[2];
|
||||
}
|
||||
if (preg_match('/Content-type:\s*(.*)/i', $header_line, $matches)) {
|
||||
$this->_mime_type = trim($matches[1]);
|
||||
}
|
||||
if (preg_match('/Location:\s*(.*)/i', $header_line, $matches)) {
|
||||
$this->_location = trim($matches[1]);
|
||||
}
|
||||
if (preg_match('/Set-cookie:(.*)/i', $header_line, $matches)) {
|
||||
$this->_cookies[] = $this->_parseCookie($matches[1]);
|
||||
}
|
||||
if (preg_match('/WWW-Authenticate:\s+(\S+)\s+realm=\"(.*?)\"/i', $header_line, $matches)) {
|
||||
$this->_authentication = $matches[1];
|
||||
$this->_realm = trim($matches[2]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse the Set-cookie content.
|
||||
* @param string $cookie_line Text after "Set-cookie:"
|
||||
* @return SimpleCookie New cookie object.
|
||||
* @access private
|
||||
*/
|
||||
function _parseCookie($cookie_line) {
|
||||
$parts = split(";", $cookie_line);
|
||||
$cookie = array();
|
||||
preg_match('/\s*(.*?)\s*=(.*)/', array_shift($parts), $cookie);
|
||||
foreach ($parts as $part) {
|
||||
if (preg_match('/\s*(.*?)\s*=(.*)/', $part, $matches)) {
|
||||
$cookie[$matches[1]] = trim($matches[2]);
|
||||
}
|
||||
}
|
||||
return new SimpleCookie(
|
||||
$cookie[1],
|
||||
trim($cookie[2]),
|
||||
isset($cookie["path"]) ? $cookie["path"] : "",
|
||||
isset($cookie["expires"]) ? $cookie["expires"] : false);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Basic HTTP response.
|
||||
* @package SimpleTest
|
||||
* @subpackage WebTester
|
||||
*/
|
||||
class SimpleHttpResponse extends SimpleStickyError {
|
||||
var $_url;
|
||||
var $_encoding;
|
||||
var $_sent;
|
||||
var $_content;
|
||||
var $_headers;
|
||||
|
||||
/**
|
||||
* Constructor. Reads and parses the incoming
|
||||
* content and headers.
|
||||
* @param SimpleSocket $socket Network connection to fetch
|
||||
* response text from.
|
||||
* @param SimpleUrl $url Resource name.
|
||||
* @param mixed $encoding Record of content sent.
|
||||
* @access public
|
||||
*/
|
||||
function SimpleHttpResponse(&$socket, $url, $encoding) {
|
||||
$this->SimpleStickyError();
|
||||
$this->_url = $url;
|
||||
$this->_encoding = $encoding;
|
||||
$this->_sent = $socket->getSent();
|
||||
$this->_content = false;
|
||||
$raw = $this->_readAll($socket);
|
||||
if ($socket->isError()) {
|
||||
$this->_setError('Error reading socket [' . $socket->getError() . ']');
|
||||
return;
|
||||
}
|
||||
$this->_parse($raw);
|
||||
}
|
||||
|
||||
/**
|
||||
* Splits up the headers and the rest of the content.
|
||||
* @param string $raw Content to parse.
|
||||
* @access private
|
||||
*/
|
||||
function _parse($raw) {
|
||||
if (! $raw) {
|
||||
$this->_setError('Nothing fetched');
|
||||
$this->_headers = &new SimpleHttpHeaders('');
|
||||
} elseif (! strstr($raw, "\r\n\r\n")) {
|
||||
$this->_setError('Could not split headers from content');
|
||||
$this->_headers = &new SimpleHttpHeaders($raw);
|
||||
} else {
|
||||
list($headers, $this->_content) = split("\r\n\r\n", $raw, 2);
|
||||
$this->_headers = &new SimpleHttpHeaders($headers);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Original request method.
|
||||
* @return string GET, POST or HEAD.
|
||||
* @access public
|
||||
*/
|
||||
function getMethod() {
|
||||
return $this->_encoding->getMethod();
|
||||
}
|
||||
|
||||
/**
|
||||
* Resource name.
|
||||
* @return SimpleUrl Current url.
|
||||
* @access public
|
||||
*/
|
||||
function getUrl() {
|
||||
return $this->_url;
|
||||
}
|
||||
|
||||
/**
|
||||
* Original request data.
|
||||
* @return mixed Sent content.
|
||||
* @access public
|
||||
*/
|
||||
function getRequestData() {
|
||||
return $this->_encoding;
|
||||
}
|
||||
|
||||
/**
|
||||
* Raw request that was sent down the wire.
|
||||
* @return string Bytes actually sent.
|
||||
* @access public
|
||||
*/
|
||||
function getSent() {
|
||||
return $this->_sent;
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for the content after the last
|
||||
* header line.
|
||||
* @return string All content.
|
||||
* @access public
|
||||
*/
|
||||
function getContent() {
|
||||
return $this->_content;
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for header block. The response is the
|
||||
* combination of this and the content.
|
||||
* @return SimpleHeaders Wrapped header block.
|
||||
* @access public
|
||||
*/
|
||||
function getHeaders() {
|
||||
return $this->_headers;
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for any new cookies.
|
||||
* @return array List of new cookies.
|
||||
* @access public
|
||||
*/
|
||||
function getNewCookies() {
|
||||
return $this->_headers->getNewCookies();
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads the whole of the socket output into a
|
||||
* single string.
|
||||
* @param SimpleSocket $socket Unread socket.
|
||||
* @return string Raw output if successful
|
||||
* else false.
|
||||
* @access private
|
||||
*/
|
||||
function _readAll(&$socket) {
|
||||
$all = '';
|
||||
while (! $this->_isLastPacket($next = $socket->read())) {
|
||||
$all .= $next;
|
||||
}
|
||||
return $all;
|
||||
}
|
||||
|
||||
/**
|
||||
* Test to see if the packet from the socket is the
|
||||
* last one.
|
||||
* @param string $packet Chunk to interpret.
|
||||
* @return boolean True if empty or EOF.
|
||||
* @access private
|
||||
*/
|
||||
function _isLastPacket($packet) {
|
||||
if (is_string($packet)) {
|
||||
return $packet === '';
|
||||
}
|
||||
return ! $packet;
|
||||
}
|
||||
}
|
||||
?>
|
||||
139
tests/simpletest/invoker.php
Normal file
139
tests/simpletest/invoker.php
Normal file
|
|
@ -0,0 +1,139 @@
|
|||
<?php
|
||||
/**
|
||||
* Base include file for SimpleTest
|
||||
* @package SimpleTest
|
||||
* @subpackage UnitTester
|
||||
* @version $Id: invoker.php 1722 2008-04-07 19:30:56Z lastcraft $
|
||||
*/
|
||||
|
||||
/**#@+
|
||||
* Includes SimpleTest files and defined the root constant
|
||||
* for dependent libraries.
|
||||
*/
|
||||
require_once(dirname(__FILE__) . '/errors.php');
|
||||
require_once(dirname(__FILE__) . '/compatibility.php');
|
||||
require_once(dirname(__FILE__) . '/scorer.php');
|
||||
require_once(dirname(__FILE__) . '/expectation.php');
|
||||
require_once(dirname(__FILE__) . '/dumper.php');
|
||||
if (! defined('SIMPLE_TEST')) {
|
||||
define('SIMPLE_TEST', dirname(__FILE__) . '/');
|
||||
}
|
||||
/**#@-*/
|
||||
|
||||
/**
|
||||
* This is called by the class runner to run a
|
||||
* single test method. Will also run the setUp()
|
||||
* and tearDown() methods.
|
||||
* @package SimpleTest
|
||||
* @subpackage UnitTester
|
||||
*/
|
||||
class SimpleInvoker {
|
||||
var $_test_case;
|
||||
|
||||
/**
|
||||
* Stashes the test case for later.
|
||||
* @param SimpleTestCase $test_case Test case to run.
|
||||
*/
|
||||
function SimpleInvoker(&$test_case) {
|
||||
$this->_test_case = &$test_case;
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for test case being run.
|
||||
* @return SimpleTestCase Test case.
|
||||
* @access public
|
||||
*/
|
||||
function &getTestCase() {
|
||||
return $this->_test_case;
|
||||
}
|
||||
|
||||
/**
|
||||
* Runs test level set up. Used for changing
|
||||
* the mechanics of base test cases.
|
||||
* @param string $method Test method to call.
|
||||
* @access public
|
||||
*/
|
||||
function before($method) {
|
||||
$this->_test_case->before($method);
|
||||
}
|
||||
|
||||
/**
|
||||
* Invokes a test method and buffered with setUp()
|
||||
* and tearDown() calls.
|
||||
* @param string $method Test method to call.
|
||||
* @access public
|
||||
*/
|
||||
function invoke($method) {
|
||||
$this->_test_case->setUp();
|
||||
$this->_test_case->$method();
|
||||
$this->_test_case->tearDown();
|
||||
}
|
||||
|
||||
/**
|
||||
* Runs test level clean up. Used for changing
|
||||
* the mechanics of base test cases.
|
||||
* @param string $method Test method to call.
|
||||
* @access public
|
||||
*/
|
||||
function after($method) {
|
||||
$this->_test_case->after($method);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Do nothing decorator. Just passes the invocation
|
||||
* straight through.
|
||||
* @package SimpleTest
|
||||
* @subpackage UnitTester
|
||||
*/
|
||||
class SimpleInvokerDecorator {
|
||||
var $_invoker;
|
||||
|
||||
/**
|
||||
* Stores the invoker to wrap.
|
||||
* @param SimpleInvoker $invoker Test method runner.
|
||||
*/
|
||||
function SimpleInvokerDecorator(&$invoker) {
|
||||
$this->_invoker = &$invoker;
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for test case being run.
|
||||
* @return SimpleTestCase Test case.
|
||||
* @access public
|
||||
*/
|
||||
function &getTestCase() {
|
||||
return $this->_invoker->getTestCase();
|
||||
}
|
||||
|
||||
/**
|
||||
* Runs test level set up. Used for changing
|
||||
* the mechanics of base test cases.
|
||||
* @param string $method Test method to call.
|
||||
* @access public
|
||||
*/
|
||||
function before($method) {
|
||||
$this->_invoker->before($method);
|
||||
}
|
||||
|
||||
/**
|
||||
* Invokes a test method and buffered with setUp()
|
||||
* and tearDown() calls.
|
||||
* @param string $method Test method to call.
|
||||
* @access public
|
||||
*/
|
||||
function invoke($method) {
|
||||
$this->_invoker->invoke($method);
|
||||
}
|
||||
|
||||
/**
|
||||
* Runs test level clean up. Used for changing
|
||||
* the mechanics of base test cases.
|
||||
* @param string $method Test method to call.
|
||||
* @access public
|
||||
*/
|
||||
function after($method) {
|
||||
$this->_invoker->after($method);
|
||||
}
|
||||
}
|
||||
?>
|
||||
1581
tests/simpletest/mock_objects.php
Normal file
1581
tests/simpletest/mock_objects.php
Normal file
File diff suppressed because it is too large
Load diff
983
tests/simpletest/page.php
Normal file
983
tests/simpletest/page.php
Normal file
|
|
@ -0,0 +1,983 @@
|
|||
<?php
|
||||
/**
|
||||
* Base include file for SimpleTest
|
||||
* @package SimpleTest
|
||||
* @subpackage WebTester
|
||||
* @version $Id: page.php 1672 2008-03-02 04:47:34Z edwardzyang $
|
||||
*/
|
||||
|
||||
/**#@+
|
||||
* include other SimpleTest class files
|
||||
*/
|
||||
require_once(dirname(__FILE__) . '/http.php');
|
||||
require_once(dirname(__FILE__) . '/parser.php');
|
||||
require_once(dirname(__FILE__) . '/tag.php');
|
||||
require_once(dirname(__FILE__) . '/form.php');
|
||||
require_once(dirname(__FILE__) . '/selector.php');
|
||||
/**#@-*/
|
||||
|
||||
/**
|
||||
* Creates tags and widgets given HTML tag
|
||||
* attributes.
|
||||
* @package SimpleTest
|
||||
* @subpackage WebTester
|
||||
*/
|
||||
class SimpleTagBuilder {
|
||||
|
||||
/**
|
||||
* Factory for the tag objects. Creates the
|
||||
* appropriate tag object for the incoming tag name
|
||||
* and attributes.
|
||||
* @param string $name HTML tag name.
|
||||
* @param hash $attributes Element attributes.
|
||||
* @return SimpleTag Tag object.
|
||||
* @access public
|
||||
*/
|
||||
function createTag($name, $attributes) {
|
||||
static $map = array(
|
||||
'a' => 'SimpleAnchorTag',
|
||||
'title' => 'SimpleTitleTag',
|
||||
'base' => 'SimpleBaseTag',
|
||||
'button' => 'SimpleButtonTag',
|
||||
'textarea' => 'SimpleTextAreaTag',
|
||||
'option' => 'SimpleOptionTag',
|
||||
'label' => 'SimpleLabelTag',
|
||||
'form' => 'SimpleFormTag',
|
||||
'frame' => 'SimpleFrameTag');
|
||||
$attributes = $this->_keysToLowerCase($attributes);
|
||||
if (array_key_exists($name, $map)) {
|
||||
$tag_class = $map[$name];
|
||||
return new $tag_class($attributes);
|
||||
} elseif ($name == 'select') {
|
||||
return $this->_createSelectionTag($attributes);
|
||||
} elseif ($name == 'input') {
|
||||
return $this->_createInputTag($attributes);
|
||||
}
|
||||
return new SimpleTag($name, $attributes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Factory for selection fields.
|
||||
* @param hash $attributes Element attributes.
|
||||
* @return SimpleTag Tag object.
|
||||
* @access protected
|
||||
*/
|
||||
function _createSelectionTag($attributes) {
|
||||
if (isset($attributes['multiple'])) {
|
||||
return new MultipleSelectionTag($attributes);
|
||||
}
|
||||
return new SimpleSelectionTag($attributes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Factory for input tags.
|
||||
* @param hash $attributes Element attributes.
|
||||
* @return SimpleTag Tag object.
|
||||
* @access protected
|
||||
*/
|
||||
function _createInputTag($attributes) {
|
||||
if (! isset($attributes['type'])) {
|
||||
return new SimpleTextTag($attributes);
|
||||
}
|
||||
$type = strtolower(trim($attributes['type']));
|
||||
$map = array(
|
||||
'submit' => 'SimpleSubmitTag',
|
||||
'image' => 'SimpleImageSubmitTag',
|
||||
'checkbox' => 'SimpleCheckboxTag',
|
||||
'radio' => 'SimpleRadioButtonTag',
|
||||
'text' => 'SimpleTextTag',
|
||||
'hidden' => 'SimpleTextTag',
|
||||
'password' => 'SimpleTextTag',
|
||||
'file' => 'SimpleUploadTag');
|
||||
if (array_key_exists($type, $map)) {
|
||||
$tag_class = $map[$type];
|
||||
return new $tag_class($attributes);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Make the keys lower case for case insensitive look-ups.
|
||||
* @param hash $map Hash to convert.
|
||||
* @return hash Unchanged values, but keys lower case.
|
||||
* @access private
|
||||
*/
|
||||
function _keysToLowerCase($map) {
|
||||
$lower = array();
|
||||
foreach ($map as $key => $value) {
|
||||
$lower[strtolower($key)] = $value;
|
||||
}
|
||||
return $lower;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* SAX event handler. Maintains a list of
|
||||
* open tags and dispatches them as they close.
|
||||
* @package SimpleTest
|
||||
* @subpackage WebTester
|
||||
*/
|
||||
class SimplePageBuilder extends SimpleSaxListener {
|
||||
var $_tags;
|
||||
var $_page;
|
||||
var $_private_content_tag;
|
||||
|
||||
/**
|
||||
* Sets the builder up empty.
|
||||
* @access public
|
||||
*/
|
||||
function SimplePageBuilder() {
|
||||
$this->SimpleSaxListener();
|
||||
}
|
||||
|
||||
/**
|
||||
* Frees up any references so as to allow the PHP garbage
|
||||
* collection from unset() to work.
|
||||
* @access public
|
||||
*/
|
||||
function free() {
|
||||
unset($this->_tags);
|
||||
unset($this->_page);
|
||||
unset($this->_private_content_tags);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads the raw content and send events
|
||||
* into the page to be built.
|
||||
* @param $response SimpleHttpResponse Fetched response.
|
||||
* @return SimplePage Newly parsed page.
|
||||
* @access public
|
||||
*/
|
||||
function &parse($response) {
|
||||
$this->_tags = array();
|
||||
$this->_page = &$this->_createPage($response);
|
||||
$parser = &$this->_createParser($this);
|
||||
$parser->parse($response->getContent());
|
||||
$this->_page->acceptPageEnd();
|
||||
return $this->_page;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an empty page.
|
||||
* @return SimplePage New unparsed page.
|
||||
* @access protected
|
||||
*/
|
||||
function &_createPage($response) {
|
||||
$page = &new SimplePage($response);
|
||||
return $page;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates the parser used with the builder.
|
||||
* @param $listener SimpleSaxListener Target of parser.
|
||||
* @return SimpleSaxParser Parser to generate
|
||||
* events for the builder.
|
||||
* @access protected
|
||||
*/
|
||||
function &_createParser(&$listener) {
|
||||
$parser = &new SimpleHtmlSaxParser($listener);
|
||||
return $parser;
|
||||
}
|
||||
|
||||
/**
|
||||
* Start of element event. Opens a new tag.
|
||||
* @param string $name Element name.
|
||||
* @param hash $attributes Attributes without content
|
||||
* are marked as true.
|
||||
* @return boolean False on parse error.
|
||||
* @access public
|
||||
*/
|
||||
function startElement($name, $attributes) {
|
||||
$factory = &new SimpleTagBuilder();
|
||||
$tag = $factory->createTag($name, $attributes);
|
||||
if (! $tag) {
|
||||
return true;
|
||||
}
|
||||
if ($tag->getTagName() == 'label') {
|
||||
$this->_page->acceptLabelStart($tag);
|
||||
$this->_openTag($tag);
|
||||
return true;
|
||||
}
|
||||
if ($tag->getTagName() == 'form') {
|
||||
$this->_page->acceptFormStart($tag);
|
||||
return true;
|
||||
}
|
||||
if ($tag->getTagName() == 'frameset') {
|
||||
$this->_page->acceptFramesetStart($tag);
|
||||
return true;
|
||||
}
|
||||
if ($tag->getTagName() == 'frame') {
|
||||
$this->_page->acceptFrame($tag);
|
||||
return true;
|
||||
}
|
||||
if ($tag->isPrivateContent() && ! isset($this->_private_content_tag)) {
|
||||
$this->_private_content_tag = &$tag;
|
||||
}
|
||||
if ($tag->expectEndTag()) {
|
||||
$this->_openTag($tag);
|
||||
return true;
|
||||
}
|
||||
$this->_page->acceptTag($tag);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* End of element event.
|
||||
* @param string $name Element name.
|
||||
* @return boolean False on parse error.
|
||||
* @access public
|
||||
*/
|
||||
function endElement($name) {
|
||||
if ($name == 'label') {
|
||||
$this->_page->acceptLabelEnd();
|
||||
return true;
|
||||
}
|
||||
if ($name == 'form') {
|
||||
$this->_page->acceptFormEnd();
|
||||
return true;
|
||||
}
|
||||
if ($name == 'frameset') {
|
||||
$this->_page->acceptFramesetEnd();
|
||||
return true;
|
||||
}
|
||||
if ($this->_hasNamedTagOnOpenTagStack($name)) {
|
||||
$tag = array_pop($this->_tags[$name]);
|
||||
if ($tag->isPrivateContent() && $this->_private_content_tag->getTagName() == $name) {
|
||||
unset($this->_private_content_tag);
|
||||
}
|
||||
$this->_addContentTagToOpenTags($tag);
|
||||
$this->_page->acceptTag($tag);
|
||||
return true;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Test to see if there are any open tags awaiting
|
||||
* closure that match the tag name.
|
||||
* @param string $name Element name.
|
||||
* @return boolean True if any are still open.
|
||||
* @access private
|
||||
*/
|
||||
function _hasNamedTagOnOpenTagStack($name) {
|
||||
return isset($this->_tags[$name]) && (count($this->_tags[$name]) > 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Unparsed, but relevant data. The data is added
|
||||
* to every open tag.
|
||||
* @param string $text May include unparsed tags.
|
||||
* @return boolean False on parse error.
|
||||
* @access public
|
||||
*/
|
||||
function addContent($text) {
|
||||
if (isset($this->_private_content_tag)) {
|
||||
$this->_private_content_tag->addContent($text);
|
||||
} else {
|
||||
$this->_addContentToAllOpenTags($text);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Any content fills all currently open tags unless it
|
||||
* is part of an option tag.
|
||||
* @param string $text May include unparsed tags.
|
||||
* @access private
|
||||
*/
|
||||
function _addContentToAllOpenTags($text) {
|
||||
foreach (array_keys($this->_tags) as $name) {
|
||||
for ($i = 0, $count = count($this->_tags[$name]); $i < $count; $i++) {
|
||||
$this->_tags[$name][$i]->addContent($text);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Parsed data in tag form. The parsed tag is added
|
||||
* to every open tag. Used for adding options to select
|
||||
* fields only.
|
||||
* @param SimpleTag $tag Option tags only.
|
||||
* @access private
|
||||
*/
|
||||
function _addContentTagToOpenTags(&$tag) {
|
||||
if ($tag->getTagName() != 'option') {
|
||||
return;
|
||||
}
|
||||
foreach (array_keys($this->_tags) as $name) {
|
||||
for ($i = 0, $count = count($this->_tags[$name]); $i < $count; $i++) {
|
||||
$this->_tags[$name][$i]->addTag($tag);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Opens a tag for receiving content. Multiple tags
|
||||
* will be receiving input at the same time.
|
||||
* @param SimpleTag $tag New content tag.
|
||||
* @access private
|
||||
*/
|
||||
function _openTag(&$tag) {
|
||||
$name = $tag->getTagName();
|
||||
if (! in_array($name, array_keys($this->_tags))) {
|
||||
$this->_tags[$name] = array();
|
||||
}
|
||||
$this->_tags[$name][] = &$tag;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A wrapper for a web page.
|
||||
* @package SimpleTest
|
||||
* @subpackage WebTester
|
||||
*/
|
||||
class SimplePage {
|
||||
var $_links;
|
||||
var $_title;
|
||||
var $_last_widget;
|
||||
var $_label;
|
||||
var $_left_over_labels;
|
||||
var $_open_forms;
|
||||
var $_complete_forms;
|
||||
var $_frameset;
|
||||
var $_frames;
|
||||
var $_frameset_nesting_level;
|
||||
var $_transport_error;
|
||||
var $_raw;
|
||||
var $_text;
|
||||
var $_sent;
|
||||
var $_headers;
|
||||
var $_method;
|
||||
var $_url;
|
||||
var $_base = false;
|
||||
var $_request_data;
|
||||
|
||||
/**
|
||||
* Parses a page ready to access it's contents.
|
||||
* @param SimpleHttpResponse $response Result of HTTP fetch.
|
||||
* @access public
|
||||
*/
|
||||
function SimplePage($response = false) {
|
||||
$this->_links = array();
|
||||
$this->_title = false;
|
||||
$this->_left_over_labels = array();
|
||||
$this->_open_forms = array();
|
||||
$this->_complete_forms = array();
|
||||
$this->_frameset = false;
|
||||
$this->_frames = array();
|
||||
$this->_frameset_nesting_level = 0;
|
||||
$this->_text = false;
|
||||
if ($response) {
|
||||
$this->_extractResponse($response);
|
||||
} else {
|
||||
$this->_noResponse();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Extracts all of the response information.
|
||||
* @param SimpleHttpResponse $response Response being parsed.
|
||||
* @access private
|
||||
*/
|
||||
function _extractResponse($response) {
|
||||
$this->_transport_error = $response->getError();
|
||||
$this->_raw = $response->getContent();
|
||||
$this->_sent = $response->getSent();
|
||||
$this->_headers = $response->getHeaders();
|
||||
$this->_method = $response->getMethod();
|
||||
$this->_url = $response->getUrl();
|
||||
$this->_request_data = $response->getRequestData();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets up a missing response.
|
||||
* @access private
|
||||
*/
|
||||
function _noResponse() {
|
||||
$this->_transport_error = 'No page fetched yet';
|
||||
$this->_raw = false;
|
||||
$this->_sent = false;
|
||||
$this->_headers = false;
|
||||
$this->_method = 'GET';
|
||||
$this->_url = false;
|
||||
$this->_request_data = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Original request as bytes sent down the wire.
|
||||
* @return mixed Sent content.
|
||||
* @access public
|
||||
*/
|
||||
function getRequest() {
|
||||
return $this->_sent;
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for raw text of page.
|
||||
* @return string Raw unparsed content.
|
||||
* @access public
|
||||
*/
|
||||
function getRaw() {
|
||||
return $this->_raw;
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for plain text of page as a text browser
|
||||
* would see it.
|
||||
* @return string Plain text of page.
|
||||
* @access public
|
||||
*/
|
||||
function getText() {
|
||||
if (! $this->_text) {
|
||||
$this->_text = SimpleHtmlSaxParser::normalise($this->_raw);
|
||||
}
|
||||
return $this->_text;
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for raw headers of page.
|
||||
* @return string Header block as text.
|
||||
* @access public
|
||||
*/
|
||||
function getHeaders() {
|
||||
if ($this->_headers) {
|
||||
return $this->_headers->getRaw();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Original request method.
|
||||
* @return string GET, POST or HEAD.
|
||||
* @access public
|
||||
*/
|
||||
function getMethod() {
|
||||
return $this->_method;
|
||||
}
|
||||
|
||||
/**
|
||||
* Original resource name.
|
||||
* @return SimpleUrl Current url.
|
||||
* @access public
|
||||
*/
|
||||
function getUrl() {
|
||||
return $this->_url;
|
||||
}
|
||||
|
||||
/**
|
||||
* Base URL if set via BASE tag page url otherwise
|
||||
* @return SimpleUrl Base url.
|
||||
* @access public
|
||||
*/
|
||||
function getBaseUrl() {
|
||||
return $this->_base;
|
||||
}
|
||||
|
||||
/**
|
||||
* Original request data.
|
||||
* @return mixed Sent content.
|
||||
* @access public
|
||||
*/
|
||||
function getRequestData() {
|
||||
return $this->_request_data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for last error.
|
||||
* @return string Error from last response.
|
||||
* @access public
|
||||
*/
|
||||
function getTransportError() {
|
||||
return $this->_transport_error;
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for current MIME type.
|
||||
* @return string MIME type as string; e.g. 'text/html'
|
||||
* @access public
|
||||
*/
|
||||
function getMimeType() {
|
||||
if ($this->_headers) {
|
||||
return $this->_headers->getMimeType();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for HTTP response code.
|
||||
* @return integer HTTP response code received.
|
||||
* @access public
|
||||
*/
|
||||
function getResponseCode() {
|
||||
if ($this->_headers) {
|
||||
return $this->_headers->getResponseCode();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for last Authentication type. Only valid
|
||||
* straight after a challenge (401).
|
||||
* @return string Description of challenge type.
|
||||
* @access public
|
||||
*/
|
||||
function getAuthentication() {
|
||||
if ($this->_headers) {
|
||||
return $this->_headers->getAuthentication();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for last Authentication realm. Only valid
|
||||
* straight after a challenge (401).
|
||||
* @return string Name of security realm.
|
||||
* @access public
|
||||
*/
|
||||
function getRealm() {
|
||||
if ($this->_headers) {
|
||||
return $this->_headers->getRealm();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for current frame focus. Will be
|
||||
* false as no frames.
|
||||
* @return array Always empty.
|
||||
* @access public
|
||||
*/
|
||||
function getFrameFocus() {
|
||||
return array();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the focus by index. The integer index starts from 1.
|
||||
* @param integer $choice Chosen frame.
|
||||
* @return boolean Always false.
|
||||
* @access public
|
||||
*/
|
||||
function setFrameFocusByIndex($choice) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the focus by name. Always fails for a leaf page.
|
||||
* @param string $name Chosen frame.
|
||||
* @return boolean False as no frames.
|
||||
* @access public
|
||||
*/
|
||||
function setFrameFocus($name) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Clears the frame focus. Does nothing for a leaf page.
|
||||
* @access public
|
||||
*/
|
||||
function clearFrameFocus() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a tag to the page.
|
||||
* @param SimpleTag $tag Tag to accept.
|
||||
* @access public
|
||||
*/
|
||||
function acceptTag(&$tag) {
|
||||
if ($tag->getTagName() == "a") {
|
||||
$this->_addLink($tag);
|
||||
} elseif ($tag->getTagName() == "base") {
|
||||
$this->_setBase($tag);
|
||||
} elseif ($tag->getTagName() == "title") {
|
||||
$this->_setTitle($tag);
|
||||
} elseif ($this->_isFormElement($tag->getTagName())) {
|
||||
for ($i = 0; $i < count($this->_open_forms); $i++) {
|
||||
$this->_open_forms[$i]->addWidget($tag);
|
||||
}
|
||||
$this->_last_widget = &$tag;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Opens a label for a described widget.
|
||||
* @param SimpleFormTag $tag Tag to accept.
|
||||
* @access public
|
||||
*/
|
||||
function acceptLabelStart(&$tag) {
|
||||
$this->_label = &$tag;
|
||||
unset($this->_last_widget);
|
||||
}
|
||||
|
||||
/**
|
||||
* Closes the most recently opened label.
|
||||
* @access public
|
||||
*/
|
||||
function acceptLabelEnd() {
|
||||
if (isset($this->_label)) {
|
||||
if (isset($this->_last_widget)) {
|
||||
$this->_last_widget->setLabel($this->_label->getText());
|
||||
unset($this->_last_widget);
|
||||
} else {
|
||||
$this->_left_over_labels[] = SimpleTestCompatibility::copy($this->_label);
|
||||
}
|
||||
unset($this->_label);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests to see if a tag is a possible form
|
||||
* element.
|
||||
* @param string $name HTML element name.
|
||||
* @return boolean True if form element.
|
||||
* @access private
|
||||
*/
|
||||
function _isFormElement($name) {
|
||||
return in_array($name, array('input', 'button', 'textarea', 'select'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Opens a form. New widgets go here.
|
||||
* @param SimpleFormTag $tag Tag to accept.
|
||||
* @access public
|
||||
*/
|
||||
function acceptFormStart(&$tag) {
|
||||
$this->_open_forms[] = &new SimpleForm($tag, $this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Closes the most recently opened form.
|
||||
* @access public
|
||||
*/
|
||||
function acceptFormEnd() {
|
||||
if (count($this->_open_forms)) {
|
||||
$this->_complete_forms[] = array_pop($this->_open_forms);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Opens a frameset. A frameset may contain nested
|
||||
* frameset tags.
|
||||
* @param SimpleFramesetTag $tag Tag to accept.
|
||||
* @access public
|
||||
*/
|
||||
function acceptFramesetStart(&$tag) {
|
||||
if (! $this->_isLoadingFrames()) {
|
||||
$this->_frameset = &$tag;
|
||||
}
|
||||
$this->_frameset_nesting_level++;
|
||||
}
|
||||
|
||||
/**
|
||||
* Closes the most recently opened frameset.
|
||||
* @access public
|
||||
*/
|
||||
function acceptFramesetEnd() {
|
||||
if ($this->_isLoadingFrames()) {
|
||||
$this->_frameset_nesting_level--;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Takes a single frame tag and stashes it in
|
||||
* the current frame set.
|
||||
* @param SimpleFrameTag $tag Tag to accept.
|
||||
* @access public
|
||||
*/
|
||||
function acceptFrame(&$tag) {
|
||||
if ($this->_isLoadingFrames()) {
|
||||
if ($tag->getAttribute('src')) {
|
||||
$this->_frames[] = &$tag;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Test to see if in the middle of reading
|
||||
* a frameset.
|
||||
* @return boolean True if inframeset.
|
||||
* @access private
|
||||
*/
|
||||
function _isLoadingFrames() {
|
||||
if (! $this->_frameset) {
|
||||
return false;
|
||||
}
|
||||
return ($this->_frameset_nesting_level > 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test to see if link is an absolute one.
|
||||
* @param string $url Url to test.
|
||||
* @return boolean True if absolute.
|
||||
* @access protected
|
||||
*/
|
||||
function _linkIsAbsolute($url) {
|
||||
$parsed = new SimpleUrl($url);
|
||||
return (boolean)($parsed->getScheme() && $parsed->getHost());
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a link to the page.
|
||||
* @param SimpleAnchorTag $tag Link to accept.
|
||||
* @access protected
|
||||
*/
|
||||
function _addLink($tag) {
|
||||
$this->_links[] = $tag;
|
||||
}
|
||||
|
||||
/**
|
||||
* Marker for end of complete page. Any work in
|
||||
* progress can now be closed.
|
||||
* @access public
|
||||
*/
|
||||
function acceptPageEnd() {
|
||||
while (count($this->_open_forms)) {
|
||||
$this->_complete_forms[] = array_pop($this->_open_forms);
|
||||
}
|
||||
foreach ($this->_left_over_labels as $label) {
|
||||
for ($i = 0, $count = count($this->_complete_forms); $i < $count; $i++) {
|
||||
$this->_complete_forms[$i]->attachLabelBySelector(
|
||||
new SimpleById($label->getFor()),
|
||||
$label->getText());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Test for the presence of a frameset.
|
||||
* @return boolean True if frameset.
|
||||
* @access public
|
||||
*/
|
||||
function hasFrames() {
|
||||
return (boolean)$this->_frameset;
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for frame name and source URL for every frame that
|
||||
* will need to be loaded. Immediate children only.
|
||||
* @return boolean/array False if no frameset or
|
||||
* otherwise a hash of frame URLs.
|
||||
* The key is either a numerical
|
||||
* base one index or the name attribute.
|
||||
* @access public
|
||||
*/
|
||||
function getFrameset() {
|
||||
if (! $this->_frameset) {
|
||||
return false;
|
||||
}
|
||||
$urls = array();
|
||||
for ($i = 0; $i < count($this->_frames); $i++) {
|
||||
$name = $this->_frames[$i]->getAttribute('name');
|
||||
$url = new SimpleUrl($this->_frames[$i]->getAttribute('src'));
|
||||
$urls[$name ? $name : $i + 1] = $this->expandUrl($url);
|
||||
}
|
||||
return $urls;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetches a list of loaded frames.
|
||||
* @return array/string Just the URL for a single page.
|
||||
* @access public
|
||||
*/
|
||||
function getFrames() {
|
||||
$url = $this->expandUrl($this->getUrl());
|
||||
return $url->asString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for a list of all links.
|
||||
* @return array List of urls with scheme of
|
||||
* http or https and hostname.
|
||||
* @access public
|
||||
*/
|
||||
function getUrls() {
|
||||
$all = array();
|
||||
foreach ($this->_links as $link) {
|
||||
$url = $this->_getUrlFromLink($link);
|
||||
$all[] = $url->asString();
|
||||
}
|
||||
return $all;
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for URLs by the link label. Label will match
|
||||
* regardess of whitespace issues and case.
|
||||
* @param string $label Text of link.
|
||||
* @return array List of links with that label.
|
||||
* @access public
|
||||
*/
|
||||
function getUrlsByLabel($label) {
|
||||
$matches = array();
|
||||
foreach ($this->_links as $link) {
|
||||
if ($link->getText() == $label) {
|
||||
$matches[] = $this->_getUrlFromLink($link);
|
||||
}
|
||||
}
|
||||
return $matches;
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for a URL by the id attribute.
|
||||
* @param string $id Id attribute of link.
|
||||
* @return SimpleUrl URL with that id of false if none.
|
||||
* @access public
|
||||
*/
|
||||
function getUrlById($id) {
|
||||
foreach ($this->_links as $link) {
|
||||
if ($link->getAttribute('id') === (string)$id) {
|
||||
return $this->_getUrlFromLink($link);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a link tag into a target URL.
|
||||
* @param SimpleAnchor $link Parsed link.
|
||||
* @return SimpleUrl URL with frame target if any.
|
||||
* @access private
|
||||
*/
|
||||
function _getUrlFromLink($link) {
|
||||
$url = $this->expandUrl($link->getHref());
|
||||
if ($link->getAttribute('target')) {
|
||||
$url->setTarget($link->getAttribute('target'));
|
||||
}
|
||||
return $url;
|
||||
}
|
||||
|
||||
/**
|
||||
* Expands expandomatic URLs into fully qualified
|
||||
* URLs.
|
||||
* @param SimpleUrl $url Relative URL.
|
||||
* @return SimpleUrl Absolute URL.
|
||||
* @access public
|
||||
*/
|
||||
function expandUrl($url) {
|
||||
if (! is_object($url)) {
|
||||
$url = new SimpleUrl($url);
|
||||
}
|
||||
$location = $this->getBaseUrl() ? $this->getBaseUrl() : new SimpleUrl();
|
||||
return $url->makeAbsolute($location->makeAbsolute($this->getUrl()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the base url for the page.
|
||||
* @param SimpleTag $tag Base URL for page.
|
||||
* @access protected
|
||||
*/
|
||||
function _setBase(&$tag) {
|
||||
$url = $tag->getAttribute('href');
|
||||
$this->_base = new SimpleUrl($url);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the title tag contents.
|
||||
* @param SimpleTitleTag $tag Title of page.
|
||||
* @access protected
|
||||
*/
|
||||
function _setTitle(&$tag) {
|
||||
$this->_title = &$tag;
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for parsed title.
|
||||
* @return string Title or false if no title is present.
|
||||
* @access public
|
||||
*/
|
||||
function getTitle() {
|
||||
if ($this->_title) {
|
||||
return $this->_title->getText();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds a held form by button label. Will only
|
||||
* search correctly built forms.
|
||||
* @param SimpleSelector $selector Button finder.
|
||||
* @return SimpleForm Form object containing
|
||||
* the button.
|
||||
* @access public
|
||||
*/
|
||||
function &getFormBySubmit($selector) {
|
||||
for ($i = 0; $i < count($this->_complete_forms); $i++) {
|
||||
if ($this->_complete_forms[$i]->hasSubmit($selector)) {
|
||||
return $this->_complete_forms[$i];
|
||||
}
|
||||
}
|
||||
$null = null;
|
||||
return $null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds a held form by image using a selector.
|
||||
* Will only search correctly built forms.
|
||||
* @param SimpleSelector $selector Image finder.
|
||||
* @return SimpleForm Form object containing
|
||||
* the image.
|
||||
* @access public
|
||||
*/
|
||||
function &getFormByImage($selector) {
|
||||
for ($i = 0; $i < count($this->_complete_forms); $i++) {
|
||||
if ($this->_complete_forms[$i]->hasImage($selector)) {
|
||||
return $this->_complete_forms[$i];
|
||||
}
|
||||
}
|
||||
$null = null;
|
||||
return $null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds a held form by the form ID. A way of
|
||||
* identifying a specific form when we have control
|
||||
* of the HTML code.
|
||||
* @param string $id Form label.
|
||||
* @return SimpleForm Form object containing the matching ID.
|
||||
* @access public
|
||||
*/
|
||||
function &getFormById($id) {
|
||||
for ($i = 0; $i < count($this->_complete_forms); $i++) {
|
||||
if ($this->_complete_forms[$i]->getId() == $id) {
|
||||
return $this->_complete_forms[$i];
|
||||
}
|
||||
}
|
||||
$null = null;
|
||||
return $null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a field on each form in which the field is
|
||||
* available.
|
||||
* @param SimpleSelector $selector Field finder.
|
||||
* @param string $value Value to set field to.
|
||||
* @return boolean True if value is valid.
|
||||
* @access public
|
||||
*/
|
||||
function setField($selector, $value, $position=false) {
|
||||
$is_set = false;
|
||||
for ($i = 0; $i < count($this->_complete_forms); $i++) {
|
||||
if ($this->_complete_forms[$i]->setField($selector, $value, $position)) {
|
||||
$is_set = true;
|
||||
}
|
||||
}
|
||||
return $is_set;
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for a form element value within a page.
|
||||
* @param SimpleSelector $selector Field finder.
|
||||
* @return string/boolean A string if the field is
|
||||
* present, false if unchecked
|
||||
* and null if missing.
|
||||
* @access public
|
||||
*/
|
||||
function getField($selector) {
|
||||
for ($i = 0; $i < count($this->_complete_forms); $i++) {
|
||||
$value = $this->_complete_forms[$i]->getValue($selector);
|
||||
if (isset($value)) {
|
||||
return $value;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
?>
|
||||
764
tests/simpletest/parser.php
Normal file
764
tests/simpletest/parser.php
Normal file
|
|
@ -0,0 +1,764 @@
|
|||
<?php
|
||||
/**
|
||||
* base include file for SimpleTest
|
||||
* @package SimpleTest
|
||||
* @subpackage MockObjects
|
||||
* @version $Id: parser.php 1723 2008-04-08 00:34:10Z lastcraft $
|
||||
*/
|
||||
|
||||
/**#@+
|
||||
* Lexer mode stack constants
|
||||
*/
|
||||
foreach (array('LEXER_ENTER', 'LEXER_MATCHED',
|
||||
'LEXER_UNMATCHED', 'LEXER_EXIT',
|
||||
'LEXER_SPECIAL') as $i => $constant) {
|
||||
if (! defined($constant)) {
|
||||
define($constant, $i + 1);
|
||||
}
|
||||
}
|
||||
/**#@-*/
|
||||
|
||||
/**
|
||||
* Compounded regular expression. Any of
|
||||
* the contained patterns could match and
|
||||
* when one does, it's label is returned.
|
||||
* @package SimpleTest
|
||||
* @subpackage WebTester
|
||||
*/
|
||||
class ParallelRegex {
|
||||
var $_patterns;
|
||||
var $_labels;
|
||||
var $_regex;
|
||||
var $_case;
|
||||
|
||||
/**
|
||||
* Constructor. Starts with no patterns.
|
||||
* @param boolean $case True for case sensitive, false
|
||||
* for insensitive.
|
||||
* @access public
|
||||
*/
|
||||
function ParallelRegex($case) {
|
||||
$this->_case = $case;
|
||||
$this->_patterns = array();
|
||||
$this->_labels = array();
|
||||
$this->_regex = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a pattern with an optional label.
|
||||
* @param string $pattern Perl style regex, but ( and )
|
||||
* lose the usual meaning.
|
||||
* @param string $label Label of regex to be returned
|
||||
* on a match.
|
||||
* @access public
|
||||
*/
|
||||
function addPattern($pattern, $label = true) {
|
||||
$count = count($this->_patterns);
|
||||
$this->_patterns[$count] = $pattern;
|
||||
$this->_labels[$count] = $label;
|
||||
$this->_regex = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Attempts to match all patterns at once against
|
||||
* a string.
|
||||
* @param string $subject String to match against.
|
||||
* @param string $match First matched portion of
|
||||
* subject.
|
||||
* @return boolean True on success.
|
||||
* @access public
|
||||
*/
|
||||
function match($subject, &$match) {
|
||||
if (count($this->_patterns) == 0) {
|
||||
return false;
|
||||
}
|
||||
if (! preg_match($this->_getCompoundedRegex(), $subject, $matches)) {
|
||||
$match = '';
|
||||
return false;
|
||||
}
|
||||
$match = $matches[0];
|
||||
for ($i = 1; $i < count($matches); $i++) {
|
||||
if ($matches[$i]) {
|
||||
return $this->_labels[$i - 1];
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compounds the patterns into a single
|
||||
* regular expression separated with the
|
||||
* "or" operator. Caches the regex.
|
||||
* Will automatically escape (, ) and / tokens.
|
||||
* @param array $patterns List of patterns in order.
|
||||
* @access private
|
||||
*/
|
||||
function _getCompoundedRegex() {
|
||||
if ($this->_regex == null) {
|
||||
for ($i = 0, $count = count($this->_patterns); $i < $count; $i++) {
|
||||
$this->_patterns[$i] = '(' . str_replace(
|
||||
array('/', '(', ')'),
|
||||
array('\/', '\(', '\)'),
|
||||
$this->_patterns[$i]) . ')';
|
||||
}
|
||||
$this->_regex = "/" . implode("|", $this->_patterns) . "/" . $this->_getPerlMatchingFlags();
|
||||
}
|
||||
return $this->_regex;
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for perl regex mode flags to use.
|
||||
* @return string Perl regex flags.
|
||||
* @access private
|
||||
*/
|
||||
function _getPerlMatchingFlags() {
|
||||
return ($this->_case ? "msS" : "msSi");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* States for a stack machine.
|
||||
* @package SimpleTest
|
||||
* @subpackage WebTester
|
||||
*/
|
||||
class SimpleStateStack {
|
||||
var $_stack;
|
||||
|
||||
/**
|
||||
* Constructor. Starts in named state.
|
||||
* @param string $start Starting state name.
|
||||
* @access public
|
||||
*/
|
||||
function SimpleStateStack($start) {
|
||||
$this->_stack = array($start);
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for current state.
|
||||
* @return string State.
|
||||
* @access public
|
||||
*/
|
||||
function getCurrent() {
|
||||
return $this->_stack[count($this->_stack) - 1];
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a state to the stack and sets it
|
||||
* to be the current state.
|
||||
* @param string $state New state.
|
||||
* @access public
|
||||
*/
|
||||
function enter($state) {
|
||||
array_push($this->_stack, $state);
|
||||
}
|
||||
|
||||
/**
|
||||
* Leaves the current state and reverts
|
||||
* to the previous one.
|
||||
* @return boolean False if we drop off
|
||||
* the bottom of the list.
|
||||
* @access public
|
||||
*/
|
||||
function leave() {
|
||||
if (count($this->_stack) == 1) {
|
||||
return false;
|
||||
}
|
||||
array_pop($this->_stack);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Accepts text and breaks it into tokens.
|
||||
* Some optimisation to make the sure the
|
||||
* content is only scanned by the PHP regex
|
||||
* parser once. Lexer modes must not start
|
||||
* with leading underscores.
|
||||
* @package SimpleTest
|
||||
* @subpackage WebTester
|
||||
*/
|
||||
class SimpleLexer {
|
||||
var $_regexes;
|
||||
var $_parser;
|
||||
var $_mode;
|
||||
var $_mode_handlers;
|
||||
var $_case;
|
||||
|
||||
/**
|
||||
* Sets up the lexer in case insensitive matching
|
||||
* by default.
|
||||
* @param SimpleSaxParser $parser Handling strategy by
|
||||
* reference.
|
||||
* @param string $start Starting handler.
|
||||
* @param boolean $case True for case sensitive.
|
||||
* @access public
|
||||
*/
|
||||
function SimpleLexer(&$parser, $start = "accept", $case = false) {
|
||||
$this->_case = $case;
|
||||
$this->_regexes = array();
|
||||
$this->_parser = &$parser;
|
||||
$this->_mode = &new SimpleStateStack($start);
|
||||
$this->_mode_handlers = array($start => $start);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a token search pattern for a particular
|
||||
* parsing mode. The pattern does not change the
|
||||
* current mode.
|
||||
* @param string $pattern Perl style regex, but ( and )
|
||||
* lose the usual meaning.
|
||||
* @param string $mode Should only apply this
|
||||
* pattern when dealing with
|
||||
* this type of input.
|
||||
* @access public
|
||||
*/
|
||||
function addPattern($pattern, $mode = "accept") {
|
||||
if (! isset($this->_regexes[$mode])) {
|
||||
$this->_regexes[$mode] = new ParallelRegex($this->_case);
|
||||
}
|
||||
$this->_regexes[$mode]->addPattern($pattern);
|
||||
if (! isset($this->_mode_handlers[$mode])) {
|
||||
$this->_mode_handlers[$mode] = $mode;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a pattern that will enter a new parsing
|
||||
* mode. Useful for entering parenthesis, strings,
|
||||
* tags, etc.
|
||||
* @param string $pattern Perl style regex, but ( and )
|
||||
* lose the usual meaning.
|
||||
* @param string $mode Should only apply this
|
||||
* pattern when dealing with
|
||||
* this type of input.
|
||||
* @param string $new_mode Change parsing to this new
|
||||
* nested mode.
|
||||
* @access public
|
||||
*/
|
||||
function addEntryPattern($pattern, $mode, $new_mode) {
|
||||
if (! isset($this->_regexes[$mode])) {
|
||||
$this->_regexes[$mode] = new ParallelRegex($this->_case);
|
||||
}
|
||||
$this->_regexes[$mode]->addPattern($pattern, $new_mode);
|
||||
if (! isset($this->_mode_handlers[$new_mode])) {
|
||||
$this->_mode_handlers[$new_mode] = $new_mode;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a pattern that will exit the current mode
|
||||
* and re-enter the previous one.
|
||||
* @param string $pattern Perl style regex, but ( and )
|
||||
* lose the usual meaning.
|
||||
* @param string $mode Mode to leave.
|
||||
* @access public
|
||||
*/
|
||||
function addExitPattern($pattern, $mode) {
|
||||
if (! isset($this->_regexes[$mode])) {
|
||||
$this->_regexes[$mode] = new ParallelRegex($this->_case);
|
||||
}
|
||||
$this->_regexes[$mode]->addPattern($pattern, "__exit");
|
||||
if (! isset($this->_mode_handlers[$mode])) {
|
||||
$this->_mode_handlers[$mode] = $mode;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a pattern that has a special mode. Acts as an entry
|
||||
* and exit pattern in one go, effectively calling a special
|
||||
* parser handler for this token only.
|
||||
* @param string $pattern Perl style regex, but ( and )
|
||||
* lose the usual meaning.
|
||||
* @param string $mode Should only apply this
|
||||
* pattern when dealing with
|
||||
* this type of input.
|
||||
* @param string $special Use this mode for this one token.
|
||||
* @access public
|
||||
*/
|
||||
function addSpecialPattern($pattern, $mode, $special) {
|
||||
if (! isset($this->_regexes[$mode])) {
|
||||
$this->_regexes[$mode] = new ParallelRegex($this->_case);
|
||||
}
|
||||
$this->_regexes[$mode]->addPattern($pattern, "_$special");
|
||||
if (! isset($this->_mode_handlers[$special])) {
|
||||
$this->_mode_handlers[$special] = $special;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a mapping from a mode to another handler.
|
||||
* @param string $mode Mode to be remapped.
|
||||
* @param string $handler New target handler.
|
||||
* @access public
|
||||
*/
|
||||
function mapHandler($mode, $handler) {
|
||||
$this->_mode_handlers[$mode] = $handler;
|
||||
}
|
||||
|
||||
/**
|
||||
* Splits the page text into tokens. Will fail
|
||||
* if the handlers report an error or if no
|
||||
* content is consumed. If successful then each
|
||||
* unparsed and parsed token invokes a call to the
|
||||
* held listener.
|
||||
* @param string $raw Raw HTML text.
|
||||
* @return boolean True on success, else false.
|
||||
* @access public
|
||||
*/
|
||||
function parse($raw) {
|
||||
if (! isset($this->_parser)) {
|
||||
return false;
|
||||
}
|
||||
$length = strlen($raw);
|
||||
while (is_array($parsed = $this->_reduce($raw))) {
|
||||
list($raw, $unmatched, $matched, $mode) = $parsed;
|
||||
if (! $this->_dispatchTokens($unmatched, $matched, $mode)) {
|
||||
return false;
|
||||
}
|
||||
if ($raw === '') {
|
||||
return true;
|
||||
}
|
||||
if (strlen($raw) == $length) {
|
||||
return false;
|
||||
}
|
||||
$length = strlen($raw);
|
||||
}
|
||||
if (! $parsed) {
|
||||
return false;
|
||||
}
|
||||
return $this->_invokeParser($raw, LEXER_UNMATCHED);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends the matched token and any leading unmatched
|
||||
* text to the parser changing the lexer to a new
|
||||
* mode if one is listed.
|
||||
* @param string $unmatched Unmatched leading portion.
|
||||
* @param string $matched Actual token match.
|
||||
* @param string $mode Mode after match. A boolean
|
||||
* false mode causes no change.
|
||||
* @return boolean False if there was any error
|
||||
* from the parser.
|
||||
* @access private
|
||||
*/
|
||||
function _dispatchTokens($unmatched, $matched, $mode = false) {
|
||||
if (! $this->_invokeParser($unmatched, LEXER_UNMATCHED)) {
|
||||
return false;
|
||||
}
|
||||
if (is_bool($mode)) {
|
||||
return $this->_invokeParser($matched, LEXER_MATCHED);
|
||||
}
|
||||
if ($this->_isModeEnd($mode)) {
|
||||
if (! $this->_invokeParser($matched, LEXER_EXIT)) {
|
||||
return false;
|
||||
}
|
||||
return $this->_mode->leave();
|
||||
}
|
||||
if ($this->_isSpecialMode($mode)) {
|
||||
$this->_mode->enter($this->_decodeSpecial($mode));
|
||||
if (! $this->_invokeParser($matched, LEXER_SPECIAL)) {
|
||||
return false;
|
||||
}
|
||||
return $this->_mode->leave();
|
||||
}
|
||||
$this->_mode->enter($mode);
|
||||
return $this->_invokeParser($matched, LEXER_ENTER);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests to see if the new mode is actually to leave
|
||||
* the current mode and pop an item from the matching
|
||||
* mode stack.
|
||||
* @param string $mode Mode to test.
|
||||
* @return boolean True if this is the exit mode.
|
||||
* @access private
|
||||
*/
|
||||
function _isModeEnd($mode) {
|
||||
return ($mode === "__exit");
|
||||
}
|
||||
|
||||
/**
|
||||
* Test to see if the mode is one where this mode
|
||||
* is entered for this token only and automatically
|
||||
* leaves immediately afterwoods.
|
||||
* @param string $mode Mode to test.
|
||||
* @return boolean True if this is the exit mode.
|
||||
* @access private
|
||||
*/
|
||||
function _isSpecialMode($mode) {
|
||||
return (strncmp($mode, "_", 1) == 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Strips the magic underscore marking single token
|
||||
* modes.
|
||||
* @param string $mode Mode to decode.
|
||||
* @return string Underlying mode name.
|
||||
* @access private
|
||||
*/
|
||||
function _decodeSpecial($mode) {
|
||||
return substr($mode, 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Calls the parser method named after the current
|
||||
* mode. Empty content will be ignored. The lexer
|
||||
* has a parser handler for each mode in the lexer.
|
||||
* @param string $content Text parsed.
|
||||
* @param boolean $is_match Token is recognised rather
|
||||
* than unparsed data.
|
||||
* @access private
|
||||
*/
|
||||
function _invokeParser($content, $is_match) {
|
||||
if (($content === '') || ($content === false)) {
|
||||
return true;
|
||||
}
|
||||
$handler = $this->_mode_handlers[$this->_mode->getCurrent()];
|
||||
return $this->_parser->$handler($content, $is_match);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tries to match a chunk of text and if successful
|
||||
* removes the recognised chunk and any leading
|
||||
* unparsed data. Empty strings will not be matched.
|
||||
* @param string $raw The subject to parse. This is the
|
||||
* content that will be eaten.
|
||||
* @return array/boolean Three item list of unparsed
|
||||
* content followed by the
|
||||
* recognised token and finally the
|
||||
* action the parser is to take.
|
||||
* True if no match, false if there
|
||||
* is a parsing error.
|
||||
* @access private
|
||||
*/
|
||||
function _reduce($raw) {
|
||||
if ($action = $this->_regexes[$this->_mode->getCurrent()]->match($raw, $match)) {
|
||||
$unparsed_character_count = strpos($raw, $match);
|
||||
$unparsed = substr($raw, 0, $unparsed_character_count);
|
||||
$raw = substr($raw, $unparsed_character_count + strlen($match));
|
||||
return array($raw, $unparsed, $match, $action);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Breaks HTML into SAX events.
|
||||
* @package SimpleTest
|
||||
* @subpackage WebTester
|
||||
*/
|
||||
class SimpleHtmlLexer extends SimpleLexer {
|
||||
|
||||
/**
|
||||
* Sets up the lexer with case insensitive matching
|
||||
* and adds the HTML handlers.
|
||||
* @param SimpleSaxParser $parser Handling strategy by
|
||||
* reference.
|
||||
* @access public
|
||||
*/
|
||||
function SimpleHtmlLexer(&$parser) {
|
||||
$this->SimpleLexer($parser, 'text');
|
||||
$this->mapHandler('text', 'acceptTextToken');
|
||||
$this->_addSkipping();
|
||||
foreach ($this->_getParsedTags() as $tag) {
|
||||
$this->_addTag($tag);
|
||||
}
|
||||
$this->_addInTagTokens();
|
||||
}
|
||||
|
||||
/**
|
||||
* List of parsed tags. Others are ignored.
|
||||
* @return array List of searched for tags.
|
||||
* @access private
|
||||
*/
|
||||
function _getParsedTags() {
|
||||
return array('a', 'base', 'title', 'form', 'input', 'button', 'textarea', 'select',
|
||||
'option', 'frameset', 'frame', 'label');
|
||||
}
|
||||
|
||||
/**
|
||||
* The lexer has to skip certain sections such
|
||||
* as server code, client code and styles.
|
||||
* @access private
|
||||
*/
|
||||
function _addSkipping() {
|
||||
$this->mapHandler('css', 'ignore');
|
||||
$this->addEntryPattern('<style', 'text', 'css');
|
||||
$this->addExitPattern('</style>', 'css');
|
||||
$this->mapHandler('js', 'ignore');
|
||||
$this->addEntryPattern('<script', 'text', 'js');
|
||||
$this->addExitPattern('</script>', 'js');
|
||||
$this->mapHandler('comment', 'ignore');
|
||||
$this->addEntryPattern('<!--', 'text', 'comment');
|
||||
$this->addExitPattern('-->', 'comment');
|
||||
}
|
||||
|
||||
/**
|
||||
* Pattern matches to start and end a tag.
|
||||
* @param string $tag Name of tag to scan for.
|
||||
* @access private
|
||||
*/
|
||||
function _addTag($tag) {
|
||||
$this->addSpecialPattern("</$tag>", 'text', 'acceptEndToken');
|
||||
$this->addEntryPattern("<$tag", 'text', 'tag');
|
||||
}
|
||||
|
||||
/**
|
||||
* Pattern matches to parse the inside of a tag
|
||||
* including the attributes and their quoting.
|
||||
* @access private
|
||||
*/
|
||||
function _addInTagTokens() {
|
||||
$this->mapHandler('tag', 'acceptStartToken');
|
||||
$this->addSpecialPattern('\s+', 'tag', 'ignore');
|
||||
$this->_addAttributeTokens();
|
||||
$this->addExitPattern('/>', 'tag');
|
||||
$this->addExitPattern('>', 'tag');
|
||||
}
|
||||
|
||||
/**
|
||||
* Matches attributes that are either single quoted,
|
||||
* double quoted or unquoted.
|
||||
* @access private
|
||||
*/
|
||||
function _addAttributeTokens() {
|
||||
$this->mapHandler('dq_attribute', 'acceptAttributeToken');
|
||||
$this->addEntryPattern('=\s*"', 'tag', 'dq_attribute');
|
||||
$this->addPattern("\\\\\"", 'dq_attribute');
|
||||
$this->addExitPattern('"', 'dq_attribute');
|
||||
$this->mapHandler('sq_attribute', 'acceptAttributeToken');
|
||||
$this->addEntryPattern("=\s*'", 'tag', 'sq_attribute');
|
||||
$this->addPattern("\\\\'", 'sq_attribute');
|
||||
$this->addExitPattern("'", 'sq_attribute');
|
||||
$this->mapHandler('uq_attribute', 'acceptAttributeToken');
|
||||
$this->addSpecialPattern('=\s*[^>\s]*', 'tag', 'uq_attribute');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts HTML tokens into selected SAX events.
|
||||
* @package SimpleTest
|
||||
* @subpackage WebTester
|
||||
*/
|
||||
class SimpleHtmlSaxParser {
|
||||
var $_lexer;
|
||||
var $_listener;
|
||||
var $_tag;
|
||||
var $_attributes;
|
||||
var $_current_attribute;
|
||||
|
||||
/**
|
||||
* Sets the listener.
|
||||
* @param SimpleSaxListener $listener SAX event handler.
|
||||
* @access public
|
||||
*/
|
||||
function SimpleHtmlSaxParser(&$listener) {
|
||||
$this->_listener = &$listener;
|
||||
$this->_lexer = &$this->createLexer($this);
|
||||
$this->_tag = '';
|
||||
$this->_attributes = array();
|
||||
$this->_current_attribute = '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Runs the content through the lexer which
|
||||
* should call back to the acceptors.
|
||||
* @param string $raw Page text to parse.
|
||||
* @return boolean False if parse error.
|
||||
* @access public
|
||||
*/
|
||||
function parse($raw) {
|
||||
return $this->_lexer->parse($raw);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets up the matching lexer. Starts in 'text' mode.
|
||||
* @param SimpleSaxParser $parser Event generator, usually $self.
|
||||
* @return SimpleLexer Lexer suitable for this parser.
|
||||
* @access public
|
||||
* @static
|
||||
*/
|
||||
function &createLexer(&$parser) {
|
||||
$lexer = &new SimpleHtmlLexer($parser);
|
||||
return $lexer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Accepts a token from the tag mode. If the
|
||||
* starting element completes then the element
|
||||
* is dispatched and the current attributes
|
||||
* set back to empty. The element or attribute
|
||||
* name is converted to lower case.
|
||||
* @param string $token Incoming characters.
|
||||
* @param integer $event Lexer event type.
|
||||
* @return boolean False if parse error.
|
||||
* @access public
|
||||
*/
|
||||
function acceptStartToken($token, $event) {
|
||||
if ($event == LEXER_ENTER) {
|
||||
$this->_tag = strtolower(substr($token, 1));
|
||||
return true;
|
||||
}
|
||||
if ($event == LEXER_EXIT) {
|
||||
$success = $this->_listener->startElement(
|
||||
$this->_tag,
|
||||
$this->_attributes);
|
||||
$this->_tag = '';
|
||||
$this->_attributes = array();
|
||||
return $success;
|
||||
}
|
||||
if ($token != '=') {
|
||||
$this->_current_attribute = strtolower(SimpleHtmlSaxParser::decodeHtml($token));
|
||||
$this->_attributes[$this->_current_attribute] = '';
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Accepts a token from the end tag mode.
|
||||
* The element name is converted to lower case.
|
||||
* @param string $token Incoming characters.
|
||||
* @param integer $event Lexer event type.
|
||||
* @return boolean False if parse error.
|
||||
* @access public
|
||||
*/
|
||||
function acceptEndToken($token, $event) {
|
||||
if (! preg_match('/<\/(.*)>/', $token, $matches)) {
|
||||
return false;
|
||||
}
|
||||
return $this->_listener->endElement(strtolower($matches[1]));
|
||||
}
|
||||
|
||||
/**
|
||||
* Part of the tag data.
|
||||
* @param string $token Incoming characters.
|
||||
* @param integer $event Lexer event type.
|
||||
* @return boolean False if parse error.
|
||||
* @access public
|
||||
*/
|
||||
function acceptAttributeToken($token, $event) {
|
||||
if ($this->_current_attribute) {
|
||||
if ($event == LEXER_UNMATCHED) {
|
||||
$this->_attributes[$this->_current_attribute] .=
|
||||
SimpleHtmlSaxParser::decodeHtml($token);
|
||||
}
|
||||
if ($event == LEXER_SPECIAL) {
|
||||
$this->_attributes[$this->_current_attribute] .=
|
||||
preg_replace('/^=\s*/' , '', SimpleHtmlSaxParser::decodeHtml($token));
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* A character entity.
|
||||
* @param string $token Incoming characters.
|
||||
* @param integer $event Lexer event type.
|
||||
* @return boolean False if parse error.
|
||||
* @access public
|
||||
*/
|
||||
function acceptEntityToken($token, $event) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Character data between tags regarded as
|
||||
* important.
|
||||
* @param string $token Incoming characters.
|
||||
* @param integer $event Lexer event type.
|
||||
* @return boolean False if parse error.
|
||||
* @access public
|
||||
*/
|
||||
function acceptTextToken($token, $event) {
|
||||
return $this->_listener->addContent($token);
|
||||
}
|
||||
|
||||
/**
|
||||
* Incoming data to be ignored.
|
||||
* @param string $token Incoming characters.
|
||||
* @param integer $event Lexer event type.
|
||||
* @return boolean False if parse error.
|
||||
* @access public
|
||||
*/
|
||||
function ignore($token, $event) {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Decodes any HTML entities.
|
||||
* @param string $html Incoming HTML.
|
||||
* @return string Outgoing plain text.
|
||||
* @access public
|
||||
* @static
|
||||
*/
|
||||
function decodeHtml($html) {
|
||||
return html_entity_decode($html, ENT_QUOTES);
|
||||
}
|
||||
|
||||
/**
|
||||
* Turns HTML into text browser visible text. Images
|
||||
* are converted to their alt text and tags are supressed.
|
||||
* Entities are converted to their visible representation.
|
||||
* @param string $html HTML to convert.
|
||||
* @return string Plain text.
|
||||
* @access public
|
||||
* @static
|
||||
*/
|
||||
function normalise($html) {
|
||||
$text = preg_replace('|<!--.*?-->|', '', $html);
|
||||
$text = preg_replace('|<script[^>]*>.*?</script>|', '', $text);
|
||||
$text = preg_replace('|<img[^>]*alt\s*=\s*"([^"]*)"[^>]*>|', ' \1 ', $text);
|
||||
$text = preg_replace('|<img[^>]*alt\s*=\s*\'([^\']*)\'[^>]*>|', ' \1 ', $text);
|
||||
$text = preg_replace('|<img[^>]*alt\s*=\s*([a-zA-Z_]+)[^>]*>|', ' \1 ', $text);
|
||||
$text = preg_replace('|<[^>]*>|', '', $text);
|
||||
$text = SimpleHtmlSaxParser::decodeHtml($text);
|
||||
$text = preg_replace('|\s+|', ' ', $text);
|
||||
return trim(trim($text), "\xA0"); // TODO: The \xAO is a . Add a test for this.
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* SAX event handler.
|
||||
* @package SimpleTest
|
||||
* @subpackage WebTester
|
||||
* @abstract
|
||||
*/
|
||||
class SimpleSaxListener {
|
||||
|
||||
/**
|
||||
* Sets the document to write to.
|
||||
* @access public
|
||||
*/
|
||||
function SimpleSaxListener() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Start of element event.
|
||||
* @param string $name Element name.
|
||||
* @param hash $attributes Name value pairs.
|
||||
* Attributes without content
|
||||
* are marked as true.
|
||||
* @return boolean False on parse error.
|
||||
* @access public
|
||||
*/
|
||||
function startElement($name, $attributes) {
|
||||
}
|
||||
|
||||
/**
|
||||
* End of element event.
|
||||
* @param string $name Element name.
|
||||
* @return boolean False on parse error.
|
||||
* @access public
|
||||
*/
|
||||
function endElement($name) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Unparsed, but relevant data.
|
||||
* @param string $text May include unparsed tags.
|
||||
* @return boolean False on parse error.
|
||||
* @access public
|
||||
*/
|
||||
function addContent($text) {
|
||||
}
|
||||
}
|
||||
?>
|
||||
136
tests/simpletest/reflection_php4.php
Normal file
136
tests/simpletest/reflection_php4.php
Normal file
|
|
@ -0,0 +1,136 @@
|
|||
<?php
|
||||
/**
|
||||
* base include file for SimpleTest
|
||||
* @package SimpleTest
|
||||
* @subpackage UnitTester
|
||||
* @version $Id: reflection_php4.php 1672 2008-03-02 04:47:34Z edwardzyang $
|
||||
*/
|
||||
|
||||
/**
|
||||
* Version specific reflection API.
|
||||
* @package SimpleTest
|
||||
* @subpackage UnitTester
|
||||
* @ignore duplicate with reflection_php5.php
|
||||
*/
|
||||
class SimpleReflection {
|
||||
var $_interface;
|
||||
|
||||
/**
|
||||
* Stashes the class/interface.
|
||||
* @param string $interface Class or interface
|
||||
* to inspect.
|
||||
*/
|
||||
function SimpleReflection($interface) {
|
||||
$this->_interface = $interface;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks that a class has been declared.
|
||||
* @return boolean True if defined.
|
||||
* @access public
|
||||
*/
|
||||
function classExists() {
|
||||
return class_exists($this->_interface);
|
||||
}
|
||||
|
||||
/**
|
||||
* Needed to kill the autoload feature in PHP5
|
||||
* for classes created dynamically.
|
||||
* @return boolean True if defined.
|
||||
* @access public
|
||||
*/
|
||||
function classExistsSansAutoload() {
|
||||
return class_exists($this->_interface);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks that a class or interface has been
|
||||
* declared.
|
||||
* @return boolean True if defined.
|
||||
* @access public
|
||||
*/
|
||||
function classOrInterfaceExists() {
|
||||
return class_exists($this->_interface);
|
||||
}
|
||||
|
||||
/**
|
||||
* Needed to kill the autoload feature in PHP5
|
||||
* for classes created dynamically.
|
||||
* @return boolean True if defined.
|
||||
* @access public
|
||||
*/
|
||||
function classOrInterfaceExistsSansAutoload() {
|
||||
return class_exists($this->_interface);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the list of methods on a class or
|
||||
* interface.
|
||||
* @returns array List of method names.
|
||||
* @access public
|
||||
*/
|
||||
function getMethods() {
|
||||
return get_class_methods($this->_interface);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the list of interfaces from a class. If the
|
||||
* class name is actually an interface then just that
|
||||
* interface is returned.
|
||||
* @returns array List of interfaces.
|
||||
* @access public
|
||||
*/
|
||||
function getInterfaces() {
|
||||
return array();
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds the parent class name.
|
||||
* @returns string Parent class name.
|
||||
* @access public
|
||||
*/
|
||||
function getParent() {
|
||||
return strtolower(get_parent_class($this->_interface));
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines if the class is abstract, which for PHP 4
|
||||
* will never be the case.
|
||||
* @returns boolean True if abstract.
|
||||
* @access public
|
||||
*/
|
||||
function isAbstract() {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines if the the entity is an interface, which for PHP 4
|
||||
* will never be the case.
|
||||
* @returns boolean True if interface.
|
||||
* @access public
|
||||
*/
|
||||
function isInterface() {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Scans for final methods, but as it's PHP 4 there
|
||||
* aren't any.
|
||||
* @returns boolean True if the class has a final method.
|
||||
* @access public
|
||||
*/
|
||||
function hasFinal() {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the source code matching the declaration
|
||||
* of a method.
|
||||
* @param string $method Method name.
|
||||
* @access public
|
||||
*/
|
||||
function getSignature($method) {
|
||||
return "function &$method()";
|
||||
}
|
||||
}
|
||||
?>
|
||||
380
tests/simpletest/reflection_php5.php
Normal file
380
tests/simpletest/reflection_php5.php
Normal file
|
|
@ -0,0 +1,380 @@
|
|||
<?php
|
||||
/**
|
||||
* base include file for SimpleTest
|
||||
* @package SimpleTest
|
||||
* @subpackage UnitTester
|
||||
* @version $Id: reflection_php5.php 1683 2008-03-05 21:57:08Z lastcraft $
|
||||
*/
|
||||
|
||||
/**
|
||||
* Version specific reflection API.
|
||||
* @package SimpleTest
|
||||
* @subpackage UnitTester
|
||||
*/
|
||||
class SimpleReflection {
|
||||
var $_interface;
|
||||
|
||||
/**
|
||||
* Stashes the class/interface.
|
||||
* @param string $interface Class or interface
|
||||
* to inspect.
|
||||
*/
|
||||
function SimpleReflection($interface) {
|
||||
$this->_interface = $interface;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks that a class has been declared. Versions
|
||||
* before PHP5.0.2 need a check that it's not really
|
||||
* an interface.
|
||||
* @return boolean True if defined.
|
||||
* @access public
|
||||
*/
|
||||
function classExists() {
|
||||
if (! class_exists($this->_interface)) {
|
||||
return false;
|
||||
}
|
||||
$reflection = new ReflectionClass($this->_interface);
|
||||
return ! $reflection->isInterface();
|
||||
}
|
||||
|
||||
/**
|
||||
* Needed to kill the autoload feature in PHP5
|
||||
* for classes created dynamically.
|
||||
* @return boolean True if defined.
|
||||
* @access public
|
||||
*/
|
||||
function classExistsSansAutoload() {
|
||||
return class_exists($this->_interface, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks that a class or interface has been
|
||||
* declared.
|
||||
* @return boolean True if defined.
|
||||
* @access public
|
||||
*/
|
||||
function classOrInterfaceExists() {
|
||||
return $this->_classOrInterfaceExistsWithAutoload($this->_interface, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Needed to kill the autoload feature in PHP5
|
||||
* for classes created dynamically.
|
||||
* @return boolean True if defined.
|
||||
* @access public
|
||||
*/
|
||||
function classOrInterfaceExistsSansAutoload() {
|
||||
return $this->_classOrInterfaceExistsWithAutoload($this->_interface, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Needed to select the autoload feature in PHP5
|
||||
* for classes created dynamically.
|
||||
* @param string $interface Class or interface name.
|
||||
* @param boolean $autoload True totriggerautoload.
|
||||
* @return boolean True if interface defined.
|
||||
* @access private
|
||||
*/
|
||||
function _classOrInterfaceExistsWithAutoload($interface, $autoload) {
|
||||
if (function_exists('interface_exists')) {
|
||||
if (interface_exists($this->_interface, $autoload)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return class_exists($this->_interface, $autoload);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the list of methods on a class or
|
||||
* interface.
|
||||
* @returns array List of method names.
|
||||
* @access public
|
||||
*/
|
||||
function getMethods() {
|
||||
return array_unique(get_class_methods($this->_interface));
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the list of interfaces from a class. If the
|
||||
* class name is actually an interface then just that
|
||||
* interface is returned.
|
||||
* @returns array List of interfaces.
|
||||
* @access public
|
||||
*/
|
||||
function getInterfaces() {
|
||||
$reflection = new ReflectionClass($this->_interface);
|
||||
if ($reflection->isInterface()) {
|
||||
return array($this->_interface);
|
||||
}
|
||||
return $this->_onlyParents($reflection->getInterfaces());
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the list of methods for the implemented
|
||||
* interfaces only.
|
||||
* @returns array List of enforced method signatures.
|
||||
* @access public
|
||||
*/
|
||||
function getInterfaceMethods() {
|
||||
$methods = array();
|
||||
foreach ($this->getInterfaces() as $interface) {
|
||||
$methods = array_merge($methods, get_class_methods($interface));
|
||||
}
|
||||
return array_unique($methods);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks to see if the method signature has to be tightly
|
||||
* specified.
|
||||
* @param string $method Method name.
|
||||
* @returns boolean True if enforced.
|
||||
* @access private
|
||||
*/
|
||||
function _isInterfaceMethod($method) {
|
||||
return in_array($method, $this->getInterfaceMethods());
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds the parent class name.
|
||||
* @returns string Parent class name.
|
||||
* @access public
|
||||
*/
|
||||
function getParent() {
|
||||
$reflection = new ReflectionClass($this->_interface);
|
||||
$parent = $reflection->getParentClass();
|
||||
if ($parent) {
|
||||
return $parent->getName();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Trivially determines if the class is abstract.
|
||||
* @returns boolean True if abstract.
|
||||
* @access public
|
||||
*/
|
||||
function isAbstract() {
|
||||
$reflection = new ReflectionClass($this->_interface);
|
||||
return $reflection->isAbstract();
|
||||
}
|
||||
|
||||
/**
|
||||
* Trivially determines if the class is an interface.
|
||||
* @returns boolean True if interface.
|
||||
* @access public
|
||||
*/
|
||||
function isInterface() {
|
||||
$reflection = new ReflectionClass($this->_interface);
|
||||
return $reflection->isInterface();
|
||||
}
|
||||
|
||||
/**
|
||||
* Scans for final methods, as they screw up inherited
|
||||
* mocks by not allowing you to override them.
|
||||
* @returns boolean True if the class has a final method.
|
||||
* @access public
|
||||
*/
|
||||
function hasFinal() {
|
||||
$reflection = new ReflectionClass($this->_interface);
|
||||
foreach ($reflection->getMethods() as $method) {
|
||||
if ($method->isFinal()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Whittles a list of interfaces down to only the
|
||||
* necessary top level parents.
|
||||
* @param array $interfaces Reflection API interfaces
|
||||
* to reduce.
|
||||
* @returns array List of parent interface names.
|
||||
* @access private
|
||||
*/
|
||||
function _onlyParents($interfaces) {
|
||||
$parents = array();
|
||||
$blacklist = array();
|
||||
foreach ($interfaces as $interface) {
|
||||
foreach($interfaces as $possible_parent) {
|
||||
if ($interface->getName() == $possible_parent->getName()) {
|
||||
continue;
|
||||
}
|
||||
if ($interface->isSubClassOf($possible_parent)) {
|
||||
$blacklist[$possible_parent->getName()] = true;
|
||||
}
|
||||
}
|
||||
if (!isset($blacklist[$interface->getName()])) {
|
||||
$parents[] = $interface->getName();
|
||||
}
|
||||
}
|
||||
return $parents;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether a method is abstract or not.
|
||||
* @param string $name Method name.
|
||||
* @return bool true if method is abstract, else false
|
||||
* @access private
|
||||
*/
|
||||
function _isAbstractMethod($name) {
|
||||
$interface = new ReflectionClass($this->_interface);
|
||||
if (! $interface->hasMethod($name)) {
|
||||
return false;
|
||||
}
|
||||
return $interface->getMethod($name)->isAbstract();
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether a method is the constructor.
|
||||
* @param string $name Method name.
|
||||
* @return bool true if method is the constructor
|
||||
* @access private
|
||||
*/
|
||||
function _isConstructor($name) {
|
||||
return ($name == '__construct') || ($name == $this->_interface);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether a method is abstract in all parents or not.
|
||||
* @param string $name Method name.
|
||||
* @return bool true if method is abstract in parent, else false
|
||||
* @access private
|
||||
*/
|
||||
function _isAbstractMethodInParents($name) {
|
||||
$interface = new ReflectionClass($this->_interface);
|
||||
$parent = $interface->getParentClass();
|
||||
while($parent) {
|
||||
if (! $parent->hasMethod($name)) {
|
||||
return false;
|
||||
}
|
||||
if ($parent->getMethod($name)->isAbstract()) {
|
||||
return true;
|
||||
}
|
||||
$parent = $parent->getParentClass();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether a method is static or not.
|
||||
* @param string $name Method name
|
||||
* @return bool true if method is static, else false
|
||||
* @access private
|
||||
*/
|
||||
function _isStaticMethod($name) {
|
||||
$interface = new ReflectionClass($this->_interface);
|
||||
if (! $interface->hasMethod($name)) {
|
||||
return false;
|
||||
}
|
||||
return $interface->getMethod($name)->isStatic();
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes the source code matching the declaration
|
||||
* of a method.
|
||||
* @param string $name Method name.
|
||||
* @return string Method signature up to last
|
||||
* bracket.
|
||||
* @access public
|
||||
*/
|
||||
function getSignature($name) {
|
||||
if ($name == '__set') {
|
||||
return 'function __set($key, $value)';
|
||||
}
|
||||
if ($name == '__call') {
|
||||
return 'function __call($method, $arguments)';
|
||||
}
|
||||
if (version_compare(phpversion(), '5.1.0', '>=')) {
|
||||
if (in_array($name, array('__get', '__isset', $name == '__unset'))) {
|
||||
return "function {$name}(\$key)";
|
||||
}
|
||||
}
|
||||
if ($name == '__toString') {
|
||||
return "function $name()";
|
||||
}
|
||||
if ($this->_isInterfaceMethod($name) ||
|
||||
$this->_isAbstractMethod($name) ||
|
||||
$this->_isAbstractMethodInParents($name) ||
|
||||
$this->_isStaticMethod($name)) {
|
||||
return $this->_getFullSignature($name);
|
||||
}
|
||||
return "function $name()";
|
||||
}
|
||||
|
||||
/**
|
||||
* For a signature specified in an interface, full
|
||||
* details must be replicated to be a valid implementation.
|
||||
* @param string $name Method name.
|
||||
* @return string Method signature up to last
|
||||
* bracket.
|
||||
* @access private
|
||||
*/
|
||||
function _getFullSignature($name) {
|
||||
$interface = new ReflectionClass($this->_interface);
|
||||
$method = $interface->getMethod($name);
|
||||
$reference = $method->returnsReference() ? '&' : '';
|
||||
$static = $method->isStatic() ? 'static ' : '';
|
||||
return "{$static}function $reference$name(" .
|
||||
implode(', ', $this->_getParameterSignatures($method)) .
|
||||
")";
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the source code for each parameter.
|
||||
* @param ReflectionMethod $method Method object from
|
||||
* reflection API
|
||||
* @return array List of strings, each
|
||||
* a snippet of code.
|
||||
* @access private
|
||||
*/
|
||||
function _getParameterSignatures($method) {
|
||||
$signatures = array();
|
||||
foreach ($method->getParameters() as $parameter) {
|
||||
$signature = '';
|
||||
$type = $parameter->getClass();
|
||||
if (is_null($type) && version_compare(phpversion(), '5.1.0', '>=') && $parameter->isArray()) {
|
||||
$signature .= 'array ';
|
||||
} elseif (!is_null($type)) {
|
||||
$signature .= $type->getName() . ' ';
|
||||
}
|
||||
if ($parameter->isPassedByReference()) {
|
||||
$signature .= '&';
|
||||
}
|
||||
$signature .= '$' . $this->_suppressSpurious($parameter->getName());
|
||||
if ($this->_isOptional($parameter)) {
|
||||
$signature .= ' = null';
|
||||
}
|
||||
$signatures[] = $signature;
|
||||
}
|
||||
return $signatures;
|
||||
}
|
||||
|
||||
/**
|
||||
* The SPL library has problems with the
|
||||
* Reflection library. In particular, you can
|
||||
* get extra characters in parameter names :(.
|
||||
* @param string $name Parameter name.
|
||||
* @return string Cleaner name.
|
||||
* @access private
|
||||
*/
|
||||
function _suppressSpurious($name) {
|
||||
return str_replace(array('[', ']', ' '), '', $name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test of a reflection parameter being optional
|
||||
* that works with early versions of PHP5.
|
||||
* @param reflectionParameter $parameter Is this optional.
|
||||
* @return boolean True if optional.
|
||||
* @access private
|
||||
*/
|
||||
function _isOptional($parameter) {
|
||||
if (method_exists($parameter, 'isOptional')) {
|
||||
return $parameter->isOptional();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
?>
|
||||
117
tests/simpletest/remote.php
Normal file
117
tests/simpletest/remote.php
Normal file
|
|
@ -0,0 +1,117 @@
|
|||
<?php
|
||||
/**
|
||||
* base include file for SimpleTest
|
||||
* @package SimpleTest
|
||||
* @subpackage UnitTester
|
||||
* @version $Id: remote.php 1723 2008-04-08 00:34:10Z lastcraft $
|
||||
*/
|
||||
|
||||
/**#@+
|
||||
* include other SimpleTest class files
|
||||
*/
|
||||
require_once(dirname(__FILE__) . '/browser.php');
|
||||
require_once(dirname(__FILE__) . '/xml.php');
|
||||
require_once(dirname(__FILE__) . '/test_case.php');
|
||||
/**#@-*/
|
||||
|
||||
/**
|
||||
* Runs an XML formated test on a remote server.
|
||||
* @package SimpleTest
|
||||
* @subpackage UnitTester
|
||||
*/
|
||||
class RemoteTestCase {
|
||||
var $_url;
|
||||
var $_dry_url;
|
||||
var $_size;
|
||||
|
||||
/**
|
||||
* Sets the location of the remote test.
|
||||
* @param string $url Test location.
|
||||
* @param string $dry_url Location for dry run.
|
||||
* @access public
|
||||
*/
|
||||
function RemoteTestCase($url, $dry_url = false) {
|
||||
$this->_url = $url;
|
||||
$this->_dry_url = $dry_url ? $dry_url : $url;
|
||||
$this->_size = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for the test name for subclasses.
|
||||
* @return string Name of the test.
|
||||
* @access public
|
||||
*/
|
||||
function getLabel() {
|
||||
return $this->_url;
|
||||
}
|
||||
|
||||
/**
|
||||
* Runs the top level test for this class. Currently
|
||||
* reads the data as a single chunk. I'll fix this
|
||||
* once I have added iteration to the browser.
|
||||
* @param SimpleReporter $reporter Target of test results.
|
||||
* @returns boolean True if no failures.
|
||||
* @access public
|
||||
*/
|
||||
function run(&$reporter) {
|
||||
$browser = &$this->_createBrowser();
|
||||
$xml = $browser->get($this->_url);
|
||||
if (! $xml) {
|
||||
trigger_error('Cannot read remote test URL [' . $this->_url . ']');
|
||||
return false;
|
||||
}
|
||||
$parser = &$this->_createParser($reporter);
|
||||
if (! $parser->parse($xml)) {
|
||||
trigger_error('Cannot parse incoming XML from [' . $this->_url . ']');
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new web browser object for fetching
|
||||
* the XML report.
|
||||
* @return SimpleBrowser New browser.
|
||||
* @access protected
|
||||
*/
|
||||
function &_createBrowser() {
|
||||
$browser = &new SimpleBrowser();
|
||||
return $browser;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates the XML parser.
|
||||
* @param SimpleReporter $reporter Target of test results.
|
||||
* @return SimpleTestXmlListener XML reader.
|
||||
* @access protected
|
||||
*/
|
||||
function &_createParser(&$reporter) {
|
||||
$parser = &new SimpleTestXmlParser($reporter);
|
||||
return $parser;
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for the number of subtests.
|
||||
* @return integer Number of test cases.
|
||||
* @access public
|
||||
*/
|
||||
function getSize() {
|
||||
if ($this->_size === false) {
|
||||
$browser = &$this->_createBrowser();
|
||||
$xml = $browser->get($this->_dry_url);
|
||||
if (! $xml) {
|
||||
trigger_error('Cannot read remote test URL [' . $this->_dry_url . ']');
|
||||
return false;
|
||||
}
|
||||
$reporter = &new SimpleReporter();
|
||||
$parser = &$this->_createParser($reporter);
|
||||
if (! $parser->parse($xml)) {
|
||||
trigger_error('Cannot parse incoming XML from [' . $this->_dry_url . ']');
|
||||
return false;
|
||||
}
|
||||
$this->_size = $reporter->getTestCaseCount();
|
||||
}
|
||||
return $this->_size;
|
||||
}
|
||||
}
|
||||
?>
|
||||
447
tests/simpletest/reporter.php
Normal file
447
tests/simpletest/reporter.php
Normal file
|
|
@ -0,0 +1,447 @@
|
|||
<?php
|
||||
/**
|
||||
* base include file for SimpleTest
|
||||
* @package SimpleTest
|
||||
* @subpackage UnitTester
|
||||
* @version $Id: reporter.php 1702 2008-03-25 00:08:04Z lastcraft $
|
||||
*/
|
||||
|
||||
/**#@+
|
||||
* include other SimpleTest class files
|
||||
*/
|
||||
require_once(dirname(__FILE__) . '/scorer.php');
|
||||
/**#@-*/
|
||||
|
||||
/**
|
||||
* Sample minimal test displayer. Generates only
|
||||
* failure messages and a pass count.
|
||||
* @package SimpleTest
|
||||
* @subpackage UnitTester
|
||||
*/
|
||||
class HtmlReporter extends SimpleReporter {
|
||||
var $_character_set;
|
||||
|
||||
/**
|
||||
* Does nothing yet. The first output will
|
||||
* be sent on the first test start. For use
|
||||
* by a web browser.
|
||||
* @access public
|
||||
*/
|
||||
function HtmlReporter($character_set = 'ISO-8859-1') {
|
||||
$this->SimpleReporter();
|
||||
$this->_character_set = $character_set;
|
||||
}
|
||||
|
||||
/**
|
||||
* Paints the top of the web page setting the
|
||||
* title to the name of the starting test.
|
||||
* @param string $test_name Name class of test.
|
||||
* @access public
|
||||
*/
|
||||
function paintHeader($test_name) {
|
||||
$this->sendNoCacheHeaders();
|
||||
print "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" \"http://www.w3.org/TR/html4/loose.dtd\">";
|
||||
print "<html>\n<head>\n<title>$test_name</title>\n";
|
||||
print "<meta http-equiv=\"Content-Type\" content=\"text/html; charset=" .
|
||||
$this->_character_set . "\">\n";
|
||||
print "<style type=\"text/css\">\n";
|
||||
print $this->_getCss() . "\n";
|
||||
print "</style>\n";
|
||||
print "</head>\n<body>\n";
|
||||
print "<h1>$test_name</h1>\n";
|
||||
flush();
|
||||
}
|
||||
|
||||
/**
|
||||
* Send the headers necessary to ensure the page is
|
||||
* reloaded on every request. Otherwise you could be
|
||||
* scratching your head over out of date test data.
|
||||
* @access public
|
||||
* @static
|
||||
*/
|
||||
function sendNoCacheHeaders() {
|
||||
if (! headers_sent()) {
|
||||
header("Expires: Mon, 26 Jul 1997 05:00:00 GMT");
|
||||
header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT");
|
||||
header("Cache-Control: no-store, no-cache, must-revalidate");
|
||||
header("Cache-Control: post-check=0, pre-check=0", false);
|
||||
header("Pragma: no-cache");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Paints the CSS. Add additional styles here.
|
||||
* @return string CSS code as text.
|
||||
* @access protected
|
||||
*/
|
||||
function _getCss() {
|
||||
return ".fail { background-color: inherit; color: red; }" .
|
||||
".pass { background-color: inherit; color: green; }" .
|
||||
" pre { background-color: lightgray; color: inherit; }";
|
||||
}
|
||||
|
||||
/**
|
||||
* Paints the end of the test with a summary of
|
||||
* the passes and failures.
|
||||
* @param string $test_name Name class of test.
|
||||
* @access public
|
||||
*/
|
||||
function paintFooter($test_name) {
|
||||
$colour = ($this->getFailCount() + $this->getExceptionCount() > 0 ? "red" : "green");
|
||||
print "<div style=\"";
|
||||
print "padding: 8px; margin-top: 1em; background-color: $colour; color: white;";
|
||||
print "\">";
|
||||
print $this->getTestCaseProgress() . "/" . $this->getTestCaseCount();
|
||||
print " test cases complete:\n";
|
||||
print "<strong>" . $this->getPassCount() . "</strong> passes, ";
|
||||
print "<strong>" . $this->getFailCount() . "</strong> fails and ";
|
||||
print "<strong>" . $this->getExceptionCount() . "</strong> exceptions.";
|
||||
print "</div>\n";
|
||||
print "</body>\n</html>\n";
|
||||
}
|
||||
|
||||
/**
|
||||
* Paints the test failure with a breadcrumbs
|
||||
* trail of the nesting test suites below the
|
||||
* top level test.
|
||||
* @param string $message Failure message displayed in
|
||||
* the context of the other tests.
|
||||
* @access public
|
||||
*/
|
||||
function paintFail($message) {
|
||||
parent::paintFail($message);
|
||||
print "<span class=\"fail\">Fail</span>: ";
|
||||
$breadcrumb = $this->getTestList();
|
||||
array_shift($breadcrumb);
|
||||
print implode(" -> ", $breadcrumb);
|
||||
print " -> " . $this->_htmlEntities($message) . "<br />\n";
|
||||
}
|
||||
|
||||
/**
|
||||
* Paints a PHP error.
|
||||
* @param string $message Message is ignored.
|
||||
* @access public
|
||||
*/
|
||||
function paintError($message) {
|
||||
parent::paintError($message);
|
||||
print "<span class=\"fail\">Exception</span>: ";
|
||||
$breadcrumb = $this->getTestList();
|
||||
array_shift($breadcrumb);
|
||||
print implode(" -> ", $breadcrumb);
|
||||
print " -> <strong>" . $this->_htmlEntities($message) . "</strong><br />\n";
|
||||
}
|
||||
|
||||
/**
|
||||
* Paints a PHP exception.
|
||||
* @param Exception $exception Exception to display.
|
||||
* @access public
|
||||
*/
|
||||
function paintException($exception) {
|
||||
parent::paintException($exception);
|
||||
print "<span class=\"fail\">Exception</span>: ";
|
||||
$breadcrumb = $this->getTestList();
|
||||
array_shift($breadcrumb);
|
||||
print implode(" -> ", $breadcrumb);
|
||||
$message = 'Unexpected exception of type [' . get_class($exception) .
|
||||
'] with message ['. $exception->getMessage() .
|
||||
'] in ['. $exception->getFile() .
|
||||
' line ' . $exception->getLine() . ']';
|
||||
print " -> <strong>" . $this->_htmlEntities($message) . "</strong><br />\n";
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints the message for skipping tests.
|
||||
* @param string $message Text of skip condition.
|
||||
* @access public
|
||||
*/
|
||||
function paintSkip($message) {
|
||||
parent::paintSkip($message);
|
||||
print "<span class=\"pass\">Skipped</span>: ";
|
||||
$breadcrumb = $this->getTestList();
|
||||
array_shift($breadcrumb);
|
||||
print implode(" -> ", $breadcrumb);
|
||||
print " -> " . $this->_htmlEntities($message) . "<br />\n";
|
||||
}
|
||||
|
||||
/**
|
||||
* Paints formatted text such as dumped variables.
|
||||
* @param string $message Text to show.
|
||||
* @access public
|
||||
*/
|
||||
function paintFormattedMessage($message) {
|
||||
print '<pre>' . $this->_htmlEntities($message) . '</pre>';
|
||||
}
|
||||
|
||||
/**
|
||||
* Character set adjusted entity conversion.
|
||||
* @param string $message Plain text or Unicode message.
|
||||
* @return string Browser readable message.
|
||||
* @access protected
|
||||
*/
|
||||
function _htmlEntities($message) {
|
||||
return htmlentities($message, ENT_COMPAT, $this->_character_set);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sample minimal test displayer. Generates only
|
||||
* failure messages and a pass count. For command
|
||||
* line use. I've tried to make it look like JUnit,
|
||||
* but I wanted to output the errors as they arrived
|
||||
* which meant dropping the dots.
|
||||
* @package SimpleTest
|
||||
* @subpackage UnitTester
|
||||
*/
|
||||
class TextReporter extends SimpleReporter {
|
||||
|
||||
/**
|
||||
* Does nothing yet. The first output will
|
||||
* be sent on the first test start.
|
||||
* @access public
|
||||
*/
|
||||
function TextReporter() {
|
||||
$this->SimpleReporter();
|
||||
}
|
||||
|
||||
/**
|
||||
* Paints the title only.
|
||||
* @param string $test_name Name class of test.
|
||||
* @access public
|
||||
*/
|
||||
function paintHeader($test_name) {
|
||||
if (! SimpleReporter::inCli()) {
|
||||
header('Content-type: text/plain');
|
||||
}
|
||||
print "$test_name\n";
|
||||
flush();
|
||||
}
|
||||
|
||||
/**
|
||||
* Paints the end of the test with a summary of
|
||||
* the passes and failures.
|
||||
* @param string $test_name Name class of test.
|
||||
* @access public
|
||||
*/
|
||||
function paintFooter($test_name) {
|
||||
if ($this->getFailCount() + $this->getExceptionCount() == 0) {
|
||||
print "OK\n";
|
||||
} else {
|
||||
print "FAILURES!!!\n";
|
||||
}
|
||||
print "Test cases run: " . $this->getTestCaseProgress() .
|
||||
"/" . $this->getTestCaseCount() .
|
||||
", Passes: " . $this->getPassCount() .
|
||||
", Failures: " . $this->getFailCount() .
|
||||
", Exceptions: " . $this->getExceptionCount() . "\n";
|
||||
}
|
||||
|
||||
/**
|
||||
* Paints the test failure as a stack trace.
|
||||
* @param string $message Failure message displayed in
|
||||
* the context of the other tests.
|
||||
* @access public
|
||||
*/
|
||||
function paintFail($message) {
|
||||
parent::paintFail($message);
|
||||
print $this->getFailCount() . ") $message\n";
|
||||
$breadcrumb = $this->getTestList();
|
||||
array_shift($breadcrumb);
|
||||
print "\tin " . implode("\n\tin ", array_reverse($breadcrumb));
|
||||
print "\n";
|
||||
}
|
||||
|
||||
/**
|
||||
* Paints a PHP error or exception.
|
||||
* @param string $message Message to be shown.
|
||||
* @access public
|
||||
* @abstract
|
||||
*/
|
||||
function paintError($message) {
|
||||
parent::paintError($message);
|
||||
print "Exception " . $this->getExceptionCount() . "!\n$message\n";
|
||||
$breadcrumb = $this->getTestList();
|
||||
array_shift($breadcrumb);
|
||||
print "\tin " . implode("\n\tin ", array_reverse($breadcrumb));
|
||||
print "\n";
|
||||
}
|
||||
|
||||
/**
|
||||
* Paints a PHP error or exception.
|
||||
* @param Exception $exception Exception to describe.
|
||||
* @access public
|
||||
* @abstract
|
||||
*/
|
||||
function paintException($exception) {
|
||||
parent::paintException($exception);
|
||||
$message = 'Unexpected exception of type [' . get_class($exception) .
|
||||
'] with message ['. $exception->getMessage() .
|
||||
'] in ['. $exception->getFile() .
|
||||
' line ' . $exception->getLine() . ']';
|
||||
print "Exception " . $this->getExceptionCount() . "!\n$message\n";
|
||||
$breadcrumb = $this->getTestList();
|
||||
array_shift($breadcrumb);
|
||||
print "\tin " . implode("\n\tin ", array_reverse($breadcrumb));
|
||||
print "\n";
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints the message for skipping tests.
|
||||
* @param string $message Text of skip condition.
|
||||
* @access public
|
||||
*/
|
||||
function paintSkip($message) {
|
||||
parent::paintSkip($message);
|
||||
print "Skip: $message\n";
|
||||
}
|
||||
|
||||
/**
|
||||
* Paints formatted text such as dumped variables.
|
||||
* @param string $message Text to show.
|
||||
* @access public
|
||||
*/
|
||||
function paintFormattedMessage($message) {
|
||||
print "$message\n";
|
||||
flush();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Runs just a single test group, a single case or
|
||||
* even a single test within that case.
|
||||
* @package SimpleTest
|
||||
* @subpackage UnitTester
|
||||
*/
|
||||
class SelectiveReporter extends SimpleReporterDecorator {
|
||||
var $_just_this_case = false;
|
||||
var $_just_this_test = false;
|
||||
var $_on;
|
||||
|
||||
/**
|
||||
* Selects the test case or group to be run,
|
||||
* and optionally a specific test.
|
||||
* @param SimpleScorer $reporter Reporter to receive events.
|
||||
* @param string $just_this_case Only this case or group will run.
|
||||
* @param string $just_this_test Only this test method will run.
|
||||
*/
|
||||
function SelectiveReporter(&$reporter, $just_this_case = false, $just_this_test = false) {
|
||||
if (isset($just_this_case) && $just_this_case) {
|
||||
$this->_just_this_case = strtolower($just_this_case);
|
||||
$this->_off();
|
||||
} else {
|
||||
$this->_on();
|
||||
}
|
||||
if (isset($just_this_test) && $just_this_test) {
|
||||
$this->_just_this_test = strtolower($just_this_test);
|
||||
}
|
||||
$this->SimpleReporterDecorator($reporter);
|
||||
}
|
||||
|
||||
/**
|
||||
* Compares criteria to actual the case/group name.
|
||||
* @param string $test_case The incoming test.
|
||||
* @return boolean True if matched.
|
||||
* @access protected
|
||||
*/
|
||||
function _matchesTestCase($test_case) {
|
||||
return $this->_just_this_case == strtolower($test_case);
|
||||
}
|
||||
|
||||
/**
|
||||
* Compares criteria to actual the test name. If no
|
||||
* name was specified at the beginning, then all tests
|
||||
* can run.
|
||||
* @param string $method The incoming test method.
|
||||
* @return boolean True if matched.
|
||||
* @access protected
|
||||
*/
|
||||
function _shouldRunTest($test_case, $method) {
|
||||
if ($this->_isOn() || $this->_matchesTestCase($test_case)) {
|
||||
if ($this->_just_this_test) {
|
||||
return $this->_just_this_test == strtolower($method);
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Switch on testing for the group or subgroup.
|
||||
* @access private
|
||||
*/
|
||||
function _on() {
|
||||
$this->_on = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Switch off testing for the group or subgroup.
|
||||
* @access private
|
||||
*/
|
||||
function _off() {
|
||||
$this->_on = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Is this group actually being tested?
|
||||
* @return boolean True if the current test group is active.
|
||||
* @access private
|
||||
*/
|
||||
function _isOn() {
|
||||
return $this->_on;
|
||||
}
|
||||
|
||||
/**
|
||||
* Veto everything that doesn't match the method wanted.
|
||||
* @param string $test_case Name of test case.
|
||||
* @param string $method Name of test method.
|
||||
* @return boolean True if test should be run.
|
||||
* @access public
|
||||
*/
|
||||
function shouldInvoke($test_case, $method) {
|
||||
if ($this->_shouldRunTest($test_case, $method)) {
|
||||
return $this->_reporter->shouldInvoke($test_case, $method);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Paints the start of a group test.
|
||||
* @param string $test_case Name of test or other label.
|
||||
* @param integer $size Number of test cases starting.
|
||||
* @access public
|
||||
*/
|
||||
function paintGroupStart($test_case, $size) {
|
||||
if ($this->_just_this_case && $this->_matchesTestCase($test_case)) {
|
||||
$this->_on();
|
||||
}
|
||||
$this->_reporter->paintGroupStart($test_case, $size);
|
||||
}
|
||||
|
||||
/**
|
||||
* Paints the end of a group test.
|
||||
* @param string $test_case Name of test or other label.
|
||||
* @access public
|
||||
*/
|
||||
function paintGroupEnd($test_case) {
|
||||
$this->_reporter->paintGroupEnd($test_case);
|
||||
if ($this->_just_this_case && $this->_matchesTestCase($test_case)) {
|
||||
$this->_off();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Suppresses skip messages.
|
||||
* @package SimpleTest
|
||||
* @subpackage UnitTester
|
||||
*/
|
||||
class NoSkipsReporter extends SimpleReporterDecorator {
|
||||
|
||||
/**
|
||||
* Does nothing.
|
||||
* @param string $message Text of skip condition.
|
||||
* @access public
|
||||
*/
|
||||
function paintSkip($message) { }
|
||||
}
|
||||
?>
|
||||
863
tests/simpletest/scorer.php
Normal file
863
tests/simpletest/scorer.php
Normal file
|
|
@ -0,0 +1,863 @@
|
|||
<?php
|
||||
/**
|
||||
* base include file for SimpleTest
|
||||
* @package SimpleTest
|
||||
* @subpackage UnitTester
|
||||
* @version $Id: scorer.php 1723 2008-04-08 00:34:10Z lastcraft $
|
||||
*/
|
||||
|
||||
/**#@+*/
|
||||
require_once(dirname(__FILE__) . '/invoker.php');
|
||||
/**#@-*/
|
||||
|
||||
/**
|
||||
* Can receive test events and display them. Display
|
||||
* is achieved by making display methods available
|
||||
* and visiting the incoming event.
|
||||
* @package SimpleTest
|
||||
* @subpackage UnitTester
|
||||
* @abstract
|
||||
*/
|
||||
class SimpleScorer {
|
||||
var $_passes;
|
||||
var $_fails;
|
||||
var $_exceptions;
|
||||
var $_is_dry_run;
|
||||
|
||||
/**
|
||||
* Starts the test run with no results.
|
||||
* @access public
|
||||
*/
|
||||
function SimpleScorer() {
|
||||
$this->_passes = 0;
|
||||
$this->_fails = 0;
|
||||
$this->_exceptions = 0;
|
||||
$this->_is_dry_run = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Signals that the next evaluation will be a dry
|
||||
* run. That is, the structure events will be
|
||||
* recorded, but no tests will be run.
|
||||
* @param boolean $is_dry Dry run if true.
|
||||
* @access public
|
||||
*/
|
||||
function makeDry($is_dry = true) {
|
||||
$this->_is_dry_run = $is_dry;
|
||||
}
|
||||
|
||||
/**
|
||||
* The reporter has a veto on what should be run.
|
||||
* @param string $test_case_name name of test case.
|
||||
* @param string $method Name of test method.
|
||||
* @access public
|
||||
*/
|
||||
function shouldInvoke($test_case_name, $method) {
|
||||
return ! $this->_is_dry_run;
|
||||
}
|
||||
|
||||
/**
|
||||
* Can wrap the invoker in preperation for running
|
||||
* a test.
|
||||
* @param SimpleInvoker $invoker Individual test runner.
|
||||
* @return SimpleInvoker Wrapped test runner.
|
||||
* @access public
|
||||
*/
|
||||
function &createInvoker(&$invoker) {
|
||||
return $invoker;
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for current status. Will be false
|
||||
* if there have been any failures or exceptions.
|
||||
* Used for command line tools.
|
||||
* @return boolean True if no failures.
|
||||
* @access public
|
||||
*/
|
||||
function getStatus() {
|
||||
if ($this->_exceptions + $this->_fails > 0) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Paints the start of a group test.
|
||||
* @param string $test_name Name of test or other label.
|
||||
* @param integer $size Number of test cases starting.
|
||||
* @access public
|
||||
*/
|
||||
function paintGroupStart($test_name, $size) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Paints the end of a group test.
|
||||
* @param string $test_name Name of test or other label.
|
||||
* @access public
|
||||
*/
|
||||
function paintGroupEnd($test_name) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Paints the start of a test case.
|
||||
* @param string $test_name Name of test or other label.
|
||||
* @access public
|
||||
*/
|
||||
function paintCaseStart($test_name) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Paints the end of a test case.
|
||||
* @param string $test_name Name of test or other label.
|
||||
* @access public
|
||||
*/
|
||||
function paintCaseEnd($test_name) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Paints the start of a test method.
|
||||
* @param string $test_name Name of test or other label.
|
||||
* @access public
|
||||
*/
|
||||
function paintMethodStart($test_name) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Paints the end of a test method.
|
||||
* @param string $test_name Name of test or other label.
|
||||
* @access public
|
||||
*/
|
||||
function paintMethodEnd($test_name) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Increments the pass count.
|
||||
* @param string $message Message is ignored.
|
||||
* @access public
|
||||
*/
|
||||
function paintPass($message) {
|
||||
$this->_passes++;
|
||||
}
|
||||
|
||||
/**
|
||||
* Increments the fail count.
|
||||
* @param string $message Message is ignored.
|
||||
* @access public
|
||||
*/
|
||||
function paintFail($message) {
|
||||
$this->_fails++;
|
||||
}
|
||||
|
||||
/**
|
||||
* Deals with PHP 4 throwing an error.
|
||||
* @param string $message Text of error formatted by
|
||||
* the test case.
|
||||
* @access public
|
||||
*/
|
||||
function paintError($message) {
|
||||
$this->_exceptions++;
|
||||
}
|
||||
|
||||
/**
|
||||
* Deals with PHP 5 throwing an exception.
|
||||
* @param Exception $exception The actual exception thrown.
|
||||
* @access public
|
||||
*/
|
||||
function paintException($exception) {
|
||||
$this->_exceptions++;
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints the message for skipping tests.
|
||||
* @param string $message Text of skip condition.
|
||||
* @access public
|
||||
*/
|
||||
function paintSkip($message) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for the number of passes so far.
|
||||
* @return integer Number of passes.
|
||||
* @access public
|
||||
*/
|
||||
function getPassCount() {
|
||||
return $this->_passes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for the number of fails so far.
|
||||
* @return integer Number of fails.
|
||||
* @access public
|
||||
*/
|
||||
function getFailCount() {
|
||||
return $this->_fails;
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for the number of untrapped errors
|
||||
* so far.
|
||||
* @return integer Number of exceptions.
|
||||
* @access public
|
||||
*/
|
||||
function getExceptionCount() {
|
||||
return $this->_exceptions;
|
||||
}
|
||||
|
||||
/**
|
||||
* Paints a simple supplementary message.
|
||||
* @param string $message Text to display.
|
||||
* @access public
|
||||
*/
|
||||
function paintMessage($message) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Paints a formatted ASCII message such as a
|
||||
* variable dump.
|
||||
* @param string $message Text to display.
|
||||
* @access public
|
||||
*/
|
||||
function paintFormattedMessage($message) {
|
||||
}
|
||||
|
||||
/**
|
||||
* By default just ignores user generated events.
|
||||
* @param string $type Event type as text.
|
||||
* @param mixed $payload Message or object.
|
||||
* @access public
|
||||
*/
|
||||
function paintSignal($type, $payload) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Recipient of generated test messages that can display
|
||||
* page footers and headers. Also keeps track of the
|
||||
* test nesting. This is the main base class on which
|
||||
* to build the finished test (page based) displays.
|
||||
* @package SimpleTest
|
||||
* @subpackage UnitTester
|
||||
*/
|
||||
class SimpleReporter extends SimpleScorer {
|
||||
var $_test_stack;
|
||||
var $_size;
|
||||
var $_progress;
|
||||
|
||||
/**
|
||||
* Starts the display with no results in.
|
||||
* @access public
|
||||
*/
|
||||
function SimpleReporter() {
|
||||
$this->SimpleScorer();
|
||||
$this->_test_stack = array();
|
||||
$this->_size = null;
|
||||
$this->_progress = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the formatter for variables and other small
|
||||
* generic data items.
|
||||
* @return SimpleDumper Formatter.
|
||||
* @access public
|
||||
*/
|
||||
function getDumper() {
|
||||
return new SimpleDumper();
|
||||
}
|
||||
|
||||
/**
|
||||
* Paints the start of a group test. Will also paint
|
||||
* the page header and footer if this is the
|
||||
* first test. Will stash the size if the first
|
||||
* start.
|
||||
* @param string $test_name Name of test that is starting.
|
||||
* @param integer $size Number of test cases starting.
|
||||
* @access public
|
||||
*/
|
||||
function paintGroupStart($test_name, $size) {
|
||||
if (! isset($this->_size)) {
|
||||
$this->_size = $size;
|
||||
}
|
||||
if (count($this->_test_stack) == 0) {
|
||||
$this->paintHeader($test_name);
|
||||
}
|
||||
$this->_test_stack[] = $test_name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Paints the end of a group test. Will paint the page
|
||||
* footer if the stack of tests has unwound.
|
||||
* @param string $test_name Name of test that is ending.
|
||||
* @param integer $progress Number of test cases ending.
|
||||
* @access public
|
||||
*/
|
||||
function paintGroupEnd($test_name) {
|
||||
array_pop($this->_test_stack);
|
||||
if (count($this->_test_stack) == 0) {
|
||||
$this->paintFooter($test_name);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Paints the start of a test case. Will also paint
|
||||
* the page header and footer if this is the
|
||||
* first test. Will stash the size if the first
|
||||
* start.
|
||||
* @param string $test_name Name of test that is starting.
|
||||
* @access public
|
||||
*/
|
||||
function paintCaseStart($test_name) {
|
||||
if (! isset($this->_size)) {
|
||||
$this->_size = 1;
|
||||
}
|
||||
if (count($this->_test_stack) == 0) {
|
||||
$this->paintHeader($test_name);
|
||||
}
|
||||
$this->_test_stack[] = $test_name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Paints the end of a test case. Will paint the page
|
||||
* footer if the stack of tests has unwound.
|
||||
* @param string $test_name Name of test that is ending.
|
||||
* @access public
|
||||
*/
|
||||
function paintCaseEnd($test_name) {
|
||||
$this->_progress++;
|
||||
array_pop($this->_test_stack);
|
||||
if (count($this->_test_stack) == 0) {
|
||||
$this->paintFooter($test_name);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Paints the start of a test method.
|
||||
* @param string $test_name Name of test that is starting.
|
||||
* @access public
|
||||
*/
|
||||
function paintMethodStart($test_name) {
|
||||
$this->_test_stack[] = $test_name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Paints the end of a test method. Will paint the page
|
||||
* footer if the stack of tests has unwound.
|
||||
* @param string $test_name Name of test that is ending.
|
||||
* @access public
|
||||
*/
|
||||
function paintMethodEnd($test_name) {
|
||||
array_pop($this->_test_stack);
|
||||
}
|
||||
|
||||
/**
|
||||
* Paints the test document header.
|
||||
* @param string $test_name First test top level
|
||||
* to start.
|
||||
* @access public
|
||||
* @abstract
|
||||
*/
|
||||
function paintHeader($test_name) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Paints the test document footer.
|
||||
* @param string $test_name The top level test.
|
||||
* @access public
|
||||
* @abstract
|
||||
*/
|
||||
function paintFooter($test_name) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for internal test stack. For
|
||||
* subclasses that need to see the whole test
|
||||
* history for display purposes.
|
||||
* @return array List of methods in nesting order.
|
||||
* @access public
|
||||
*/
|
||||
function getTestList() {
|
||||
return $this->_test_stack;
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for total test size in number
|
||||
* of test cases. Null until the first
|
||||
* test is started.
|
||||
* @return integer Total number of cases at start.
|
||||
* @access public
|
||||
*/
|
||||
function getTestCaseCount() {
|
||||
return $this->_size;
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for the number of test cases
|
||||
* completed so far.
|
||||
* @return integer Number of ended cases.
|
||||
* @access public
|
||||
*/
|
||||
function getTestCaseProgress() {
|
||||
return $this->_progress;
|
||||
}
|
||||
|
||||
/**
|
||||
* Static check for running in the comand line.
|
||||
* @return boolean True if CLI.
|
||||
* @access public
|
||||
* @static
|
||||
*/
|
||||
function inCli() {
|
||||
return php_sapi_name() == 'cli';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* For modifying the behaviour of the visual reporters.
|
||||
* @package SimpleTest
|
||||
* @subpackage UnitTester
|
||||
*/
|
||||
class SimpleReporterDecorator {
|
||||
var $_reporter;
|
||||
|
||||
/**
|
||||
* Mediates between the reporter and the test case.
|
||||
* @param SimpleScorer $reporter Reporter to receive events.
|
||||
*/
|
||||
function SimpleReporterDecorator(&$reporter) {
|
||||
$this->_reporter = &$reporter;
|
||||
}
|
||||
|
||||
/**
|
||||
* Signals that the next evaluation will be a dry
|
||||
* run. That is, the structure events will be
|
||||
* recorded, but no tests will be run.
|
||||
* @param boolean $is_dry Dry run if true.
|
||||
* @access public
|
||||
*/
|
||||
function makeDry($is_dry = true) {
|
||||
$this->_reporter->makeDry($is_dry);
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for current status. Will be false
|
||||
* if there have been any failures or exceptions.
|
||||
* Used for command line tools.
|
||||
* @return boolean True if no failures.
|
||||
* @access public
|
||||
*/
|
||||
function getStatus() {
|
||||
return $this->_reporter->getStatus();
|
||||
}
|
||||
|
||||
/**
|
||||
* The reporter has a veto on what should be run.
|
||||
* @param string $test_case_name name of test case.
|
||||
* @param string $method Name of test method.
|
||||
* @return boolean True if test should be run.
|
||||
* @access public
|
||||
*/
|
||||
function shouldInvoke($test_case_name, $method) {
|
||||
return $this->_reporter->shouldInvoke($test_case_name, $method);
|
||||
}
|
||||
|
||||
/**
|
||||
* Can wrap the invoker in preperation for running
|
||||
* a test.
|
||||
* @param SimpleInvoker $invoker Individual test runner.
|
||||
* @return SimpleInvoker Wrapped test runner.
|
||||
* @access public
|
||||
*/
|
||||
function &createInvoker(&$invoker) {
|
||||
return $this->_reporter->createInvoker($invoker);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the formatter for variables and other small
|
||||
* generic data items.
|
||||
* @return SimpleDumper Formatter.
|
||||
* @access public
|
||||
*/
|
||||
function getDumper() {
|
||||
return $this->_reporter->getDumper();
|
||||
}
|
||||
|
||||
/**
|
||||
* Paints the start of a group test.
|
||||
* @param string $test_name Name of test or other label.
|
||||
* @param integer $size Number of test cases starting.
|
||||
* @access public
|
||||
*/
|
||||
function paintGroupStart($test_name, $size) {
|
||||
$this->_reporter->paintGroupStart($test_name, $size);
|
||||
}
|
||||
|
||||
/**
|
||||
* Paints the end of a group test.
|
||||
* @param string $test_name Name of test or other label.
|
||||
* @access public
|
||||
*/
|
||||
function paintGroupEnd($test_name) {
|
||||
$this->_reporter->paintGroupEnd($test_name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Paints the start of a test case.
|
||||
* @param string $test_name Name of test or other label.
|
||||
* @access public
|
||||
*/
|
||||
function paintCaseStart($test_name) {
|
||||
$this->_reporter->paintCaseStart($test_name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Paints the end of a test case.
|
||||
* @param string $test_name Name of test or other label.
|
||||
* @access public
|
||||
*/
|
||||
function paintCaseEnd($test_name) {
|
||||
$this->_reporter->paintCaseEnd($test_name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Paints the start of a test method.
|
||||
* @param string $test_name Name of test or other label.
|
||||
* @access public
|
||||
*/
|
||||
function paintMethodStart($test_name) {
|
||||
$this->_reporter->paintMethodStart($test_name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Paints the end of a test method.
|
||||
* @param string $test_name Name of test or other label.
|
||||
* @access public
|
||||
*/
|
||||
function paintMethodEnd($test_name) {
|
||||
$this->_reporter->paintMethodEnd($test_name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Chains to the wrapped reporter.
|
||||
* @param string $message Message is ignored.
|
||||
* @access public
|
||||
*/
|
||||
function paintPass($message) {
|
||||
$this->_reporter->paintPass($message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Chains to the wrapped reporter.
|
||||
* @param string $message Message is ignored.
|
||||
* @access public
|
||||
*/
|
||||
function paintFail($message) {
|
||||
$this->_reporter->paintFail($message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Chains to the wrapped reporter.
|
||||
* @param string $message Text of error formatted by
|
||||
* the test case.
|
||||
* @access public
|
||||
*/
|
||||
function paintError($message) {
|
||||
$this->_reporter->paintError($message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Chains to the wrapped reporter.
|
||||
* @param Exception $exception Exception to show.
|
||||
* @access public
|
||||
*/
|
||||
function paintException($exception) {
|
||||
$this->_reporter->paintException($exception);
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints the message for skipping tests.
|
||||
* @param string $message Text of skip condition.
|
||||
* @access public
|
||||
*/
|
||||
function paintSkip($message) {
|
||||
$this->_reporter->paintSkip($message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Chains to the wrapped reporter.
|
||||
* @param string $message Text to display.
|
||||
* @access public
|
||||
*/
|
||||
function paintMessage($message) {
|
||||
$this->_reporter->paintMessage($message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Chains to the wrapped reporter.
|
||||
* @param string $message Text to display.
|
||||
* @access public
|
||||
*/
|
||||
function paintFormattedMessage($message) {
|
||||
$this->_reporter->paintFormattedMessage($message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Chains to the wrapped reporter.
|
||||
* @param string $type Event type as text.
|
||||
* @param mixed $payload Message or object.
|
||||
* @return boolean Should return false if this
|
||||
* type of signal should fail the
|
||||
* test suite.
|
||||
* @access public
|
||||
*/
|
||||
function paintSignal($type, &$payload) {
|
||||
$this->_reporter->paintSignal($type, $payload);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* For sending messages to multiple reporters at
|
||||
* the same time.
|
||||
* @package SimpleTest
|
||||
* @subpackage UnitTester
|
||||
*/
|
||||
class MultipleReporter {
|
||||
var $_reporters = array();
|
||||
|
||||
/**
|
||||
* Adds a reporter to the subscriber list.
|
||||
* @param SimpleScorer $reporter Reporter to receive events.
|
||||
* @access public
|
||||
*/
|
||||
function attachReporter(&$reporter) {
|
||||
$this->_reporters[] = &$reporter;
|
||||
}
|
||||
|
||||
/**
|
||||
* Signals that the next evaluation will be a dry
|
||||
* run. That is, the structure events will be
|
||||
* recorded, but no tests will be run.
|
||||
* @param boolean $is_dry Dry run if true.
|
||||
* @access public
|
||||
*/
|
||||
function makeDry($is_dry = true) {
|
||||
for ($i = 0; $i < count($this->_reporters); $i++) {
|
||||
$this->_reporters[$i]->makeDry($is_dry);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for current status. Will be false
|
||||
* if there have been any failures or exceptions.
|
||||
* If any reporter reports a failure, the whole
|
||||
* suite fails.
|
||||
* @return boolean True if no failures.
|
||||
* @access public
|
||||
*/
|
||||
function getStatus() {
|
||||
for ($i = 0; $i < count($this->_reporters); $i++) {
|
||||
if (! $this->_reporters[$i]->getStatus()) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* The reporter has a veto on what should be run.
|
||||
* It requires all reporters to want to run the method.
|
||||
* @param string $test_case_name name of test case.
|
||||
* @param string $method Name of test method.
|
||||
* @access public
|
||||
*/
|
||||
function shouldInvoke($test_case_name, $method) {
|
||||
for ($i = 0; $i < count($this->_reporters); $i++) {
|
||||
if (! $this->_reporters[$i]->shouldInvoke($test_case_name, $method)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Every reporter gets a chance to wrap the invoker.
|
||||
* @param SimpleInvoker $invoker Individual test runner.
|
||||
* @return SimpleInvoker Wrapped test runner.
|
||||
* @access public
|
||||
*/
|
||||
function &createInvoker(&$invoker) {
|
||||
for ($i = 0; $i < count($this->_reporters); $i++) {
|
||||
$invoker = &$this->_reporters[$i]->createInvoker($invoker);
|
||||
}
|
||||
return $invoker;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the formatter for variables and other small
|
||||
* generic data items.
|
||||
* @return SimpleDumper Formatter.
|
||||
* @access public
|
||||
*/
|
||||
function getDumper() {
|
||||
return new SimpleDumper();
|
||||
}
|
||||
|
||||
/**
|
||||
* Paints the start of a group test.
|
||||
* @param string $test_name Name of test or other label.
|
||||
* @param integer $size Number of test cases starting.
|
||||
* @access public
|
||||
*/
|
||||
function paintGroupStart($test_name, $size) {
|
||||
for ($i = 0; $i < count($this->_reporters); $i++) {
|
||||
$this->_reporters[$i]->paintGroupStart($test_name, $size);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Paints the end of a group test.
|
||||
* @param string $test_name Name of test or other label.
|
||||
* @access public
|
||||
*/
|
||||
function paintGroupEnd($test_name) {
|
||||
for ($i = 0; $i < count($this->_reporters); $i++) {
|
||||
$this->_reporters[$i]->paintGroupEnd($test_name);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Paints the start of a test case.
|
||||
* @param string $test_name Name of test or other label.
|
||||
* @access public
|
||||
*/
|
||||
function paintCaseStart($test_name) {
|
||||
for ($i = 0; $i < count($this->_reporters); $i++) {
|
||||
$this->_reporters[$i]->paintCaseStart($test_name);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Paints the end of a test case.
|
||||
* @param string $test_name Name of test or other label.
|
||||
* @access public
|
||||
*/
|
||||
function paintCaseEnd($test_name) {
|
||||
for ($i = 0; $i < count($this->_reporters); $i++) {
|
||||
$this->_reporters[$i]->paintCaseEnd($test_name);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Paints the start of a test method.
|
||||
* @param string $test_name Name of test or other label.
|
||||
* @access public
|
||||
*/
|
||||
function paintMethodStart($test_name) {
|
||||
for ($i = 0; $i < count($this->_reporters); $i++) {
|
||||
$this->_reporters[$i]->paintMethodStart($test_name);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Paints the end of a test method.
|
||||
* @param string $test_name Name of test or other label.
|
||||
* @access public
|
||||
*/
|
||||
function paintMethodEnd($test_name) {
|
||||
for ($i = 0; $i < count($this->_reporters); $i++) {
|
||||
$this->_reporters[$i]->paintMethodEnd($test_name);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Chains to the wrapped reporter.
|
||||
* @param string $message Message is ignored.
|
||||
* @access public
|
||||
*/
|
||||
function paintPass($message) {
|
||||
for ($i = 0; $i < count($this->_reporters); $i++) {
|
||||
$this->_reporters[$i]->paintPass($message);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Chains to the wrapped reporter.
|
||||
* @param string $message Message is ignored.
|
||||
* @access public
|
||||
*/
|
||||
function paintFail($message) {
|
||||
for ($i = 0; $i < count($this->_reporters); $i++) {
|
||||
$this->_reporters[$i]->paintFail($message);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Chains to the wrapped reporter.
|
||||
* @param string $message Text of error formatted by
|
||||
* the test case.
|
||||
* @access public
|
||||
*/
|
||||
function paintError($message) {
|
||||
for ($i = 0; $i < count($this->_reporters); $i++) {
|
||||
$this->_reporters[$i]->paintError($message);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Chains to the wrapped reporter.
|
||||
* @param Exception $exception Exception to display.
|
||||
* @access public
|
||||
*/
|
||||
function paintException($exception) {
|
||||
for ($i = 0; $i < count($this->_reporters); $i++) {
|
||||
$this->_reporters[$i]->paintException($exception);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints the message for skipping tests.
|
||||
* @param string $message Text of skip condition.
|
||||
* @access public
|
||||
*/
|
||||
function paintSkip($message) {
|
||||
for ($i = 0; $i < count($this->_reporters); $i++) {
|
||||
$this->_reporters[$i]->paintSkip($message);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Chains to the wrapped reporter.
|
||||
* @param string $message Text to display.
|
||||
* @access public
|
||||
*/
|
||||
function paintMessage($message) {
|
||||
for ($i = 0; $i < count($this->_reporters); $i++) {
|
||||
$this->_reporters[$i]->paintMessage($message);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Chains to the wrapped reporter.
|
||||
* @param string $message Text to display.
|
||||
* @access public
|
||||
*/
|
||||
function paintFormattedMessage($message) {
|
||||
for ($i = 0; $i < count($this->_reporters); $i++) {
|
||||
$this->_reporters[$i]->paintFormattedMessage($message);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Chains to the wrapped reporter.
|
||||
* @param string $type Event type as text.
|
||||
* @param mixed $payload Message or object.
|
||||
* @return boolean Should return false if this
|
||||
* type of signal should fail the
|
||||
* test suite.
|
||||
* @access public
|
||||
*/
|
||||
function paintSignal($type, &$payload) {
|
||||
for ($i = 0; $i < count($this->_reporters); $i++) {
|
||||
$this->_reporters[$i]->paintSignal($type, $payload);
|
||||
}
|
||||
}
|
||||
}
|
||||
?>
|
||||
137
tests/simpletest/selector.php
Normal file
137
tests/simpletest/selector.php
Normal file
|
|
@ -0,0 +1,137 @@
|
|||
<?php
|
||||
/**
|
||||
* Base include file for SimpleTest.
|
||||
* @package SimpleTest
|
||||
* @subpackage WebTester
|
||||
* @version $Id: selector.php 1723 2008-04-08 00:34:10Z lastcraft $
|
||||
*/
|
||||
|
||||
/**#@+
|
||||
* include SimpleTest files
|
||||
*/
|
||||
require_once(dirname(__FILE__) . '/tag.php');
|
||||
require_once(dirname(__FILE__) . '/encoding.php');
|
||||
/**#@-*/
|
||||
|
||||
/**
|
||||
* Used to extract form elements for testing against.
|
||||
* Searches by name attribute.
|
||||
* @package SimpleTest
|
||||
* @subpackage WebTester
|
||||
*/
|
||||
class SimpleByName {
|
||||
var $_name;
|
||||
|
||||
/**
|
||||
* Stashes the name for later comparison.
|
||||
* @param string $name Name attribute to match.
|
||||
*/
|
||||
function SimpleByName($name) {
|
||||
$this->_name = $name;
|
||||
}
|
||||
|
||||
function getName() {
|
||||
return $this->_name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compares with name attribute of widget.
|
||||
* @param SimpleWidget $widget Control to compare.
|
||||
* @access public
|
||||
*/
|
||||
function isMatch($widget) {
|
||||
return ($widget->getName() == $this->_name);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Used to extract form elements for testing against.
|
||||
* Searches by visible label or alt text.
|
||||
* @package SimpleTest
|
||||
* @subpackage WebTester
|
||||
*/
|
||||
class SimpleByLabel {
|
||||
var $_label;
|
||||
|
||||
/**
|
||||
* Stashes the name for later comparison.
|
||||
* @param string $label Visible text to match.
|
||||
*/
|
||||
function SimpleByLabel($label) {
|
||||
$this->_label = $label;
|
||||
}
|
||||
|
||||
/**
|
||||
* Comparison. Compares visible text of widget or
|
||||
* related label.
|
||||
* @param SimpleWidget $widget Control to compare.
|
||||
* @access public
|
||||
*/
|
||||
function isMatch($widget) {
|
||||
if (! method_exists($widget, 'isLabel')) {
|
||||
return false;
|
||||
}
|
||||
return $widget->isLabel($this->_label);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Used to extract form elements for testing against.
|
||||
* Searches dy id attribute.
|
||||
* @package SimpleTest
|
||||
* @subpackage WebTester
|
||||
*/
|
||||
class SimpleById {
|
||||
var $_id;
|
||||
|
||||
/**
|
||||
* Stashes the name for later comparison.
|
||||
* @param string $id ID atribute to match.
|
||||
*/
|
||||
function SimpleById($id) {
|
||||
$this->_id = $id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Comparison. Compares id attribute of widget.
|
||||
* @param SimpleWidget $widget Control to compare.
|
||||
* @access public
|
||||
*/
|
||||
function isMatch($widget) {
|
||||
return $widget->isId($this->_id);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Used to extract form elements for testing against.
|
||||
* Searches by visible label, name or alt text.
|
||||
* @package SimpleTest
|
||||
* @subpackage WebTester
|
||||
*/
|
||||
class SimpleByLabelOrName {
|
||||
var $_label;
|
||||
|
||||
/**
|
||||
* Stashes the name/label for later comparison.
|
||||
* @param string $label Visible text to match.
|
||||
*/
|
||||
function SimpleByLabelOrName($label) {
|
||||
$this->_label = $label;
|
||||
}
|
||||
|
||||
/**
|
||||
* Comparison. Compares visible text of widget or
|
||||
* related label or name.
|
||||
* @param SimpleWidget $widget Control to compare.
|
||||
* @access public
|
||||
*/
|
||||
function isMatch($widget) {
|
||||
if (method_exists($widget, 'isLabel')) {
|
||||
if ($widget->isLabel($this->_label)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return ($widget->getName() == $this->_label);
|
||||
}
|
||||
}
|
||||
?>
|
||||
333
tests/simpletest/shell_tester.php
Normal file
333
tests/simpletest/shell_tester.php
Normal file
|
|
@ -0,0 +1,333 @@
|
|||
<?php
|
||||
/**
|
||||
* base include file for SimpleTest
|
||||
* @package SimpleTest
|
||||
* @subpackage UnitTester
|
||||
* @version $Id: shell_tester.php 1723 2008-04-08 00:34:10Z lastcraft $
|
||||
*/
|
||||
|
||||
/**#@+
|
||||
* include other SimpleTest class files
|
||||
*/
|
||||
require_once(dirname(__FILE__) . '/test_case.php');
|
||||
/**#@-*/
|
||||
|
||||
/**
|
||||
* Wrapper for exec() functionality.
|
||||
* @package SimpleTest
|
||||
* @subpackage UnitTester
|
||||
*/
|
||||
class SimpleShell {
|
||||
var $_output;
|
||||
|
||||
/**
|
||||
* Executes the shell comand and stashes the output.
|
||||
* @access public
|
||||
*/
|
||||
function SimpleShell() {
|
||||
$this->_output = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Actually runs the command. Does not trap the
|
||||
* error stream output as this need PHP 4.3+.
|
||||
* @param string $command The actual command line
|
||||
* to run.
|
||||
* @return integer Exit code.
|
||||
* @access public
|
||||
*/
|
||||
function execute($command) {
|
||||
$this->_output = false;
|
||||
exec($command, $this->_output, $ret);
|
||||
return $ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for the last output.
|
||||
* @return string Output as text.
|
||||
* @access public
|
||||
*/
|
||||
function getOutput() {
|
||||
return implode("\n", $this->_output);
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for the last output.
|
||||
* @return array Output as array of lines.
|
||||
* @access public
|
||||
*/
|
||||
function getOutputAsList() {
|
||||
return $this->_output;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Test case for testing of command line scripts and
|
||||
* utilities. Usually scripts that are external to the
|
||||
* PHP code, but support it in some way.
|
||||
* @package SimpleTest
|
||||
* @subpackage UnitTester
|
||||
*/
|
||||
class ShellTestCase extends SimpleTestCase {
|
||||
var $_current_shell;
|
||||
var $_last_status;
|
||||
var $_last_command;
|
||||
|
||||
/**
|
||||
* Creates an empty test case. Should be subclassed
|
||||
* with test methods for a functional test case.
|
||||
* @param string $label Name of test case. Will use
|
||||
* the class name if none specified.
|
||||
* @access public
|
||||
*/
|
||||
function ShellTestCase($label = false) {
|
||||
$this->SimpleTestCase($label);
|
||||
$this->_current_shell = &$this->_createShell();
|
||||
$this->_last_status = false;
|
||||
$this->_last_command = '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Executes a command and buffers the results.
|
||||
* @param string $command Command to run.
|
||||
* @return boolean True if zero exit code.
|
||||
* @access public
|
||||
*/
|
||||
function execute($command) {
|
||||
$shell = &$this->_getShell();
|
||||
$this->_last_status = $shell->execute($command);
|
||||
$this->_last_command = $command;
|
||||
return ($this->_last_status === 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Dumps the output of the last command.
|
||||
* @access public
|
||||
*/
|
||||
function dumpOutput() {
|
||||
$this->dump($this->getOutput());
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for the last output.
|
||||
* @return string Output as text.
|
||||
* @access public
|
||||
*/
|
||||
function getOutput() {
|
||||
$shell = &$this->_getShell();
|
||||
return $shell->getOutput();
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for the last output.
|
||||
* @return array Output as array of lines.
|
||||
* @access public
|
||||
*/
|
||||
function getOutputAsList() {
|
||||
$shell = &$this->_getShell();
|
||||
return $shell->getOutputAsList();
|
||||
}
|
||||
|
||||
/**
|
||||
* Called from within the test methods to register
|
||||
* passes and failures.
|
||||
* @param boolean $result Pass on true.
|
||||
* @param string $message Message to display describing
|
||||
* the test state.
|
||||
* @return boolean True on pass
|
||||
* @access public
|
||||
*/
|
||||
function assertTrue($result, $message = false) {
|
||||
return $this->assert(new TrueExpectation(), $result, $message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Will be true on false and vice versa. False
|
||||
* is the PHP definition of false, so that null,
|
||||
* empty strings, zero and an empty array all count
|
||||
* as false.
|
||||
* @param boolean $result Pass on false.
|
||||
* @param string $message Message to display.
|
||||
* @return boolean True on pass
|
||||
* @access public
|
||||
*/
|
||||
function assertFalse($result, $message = '%s') {
|
||||
return $this->assert(new FalseExpectation(), $result, $message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Will trigger a pass if the two parameters have
|
||||
* the same value only. Otherwise a fail. This
|
||||
* is for testing hand extracted text, etc.
|
||||
* @param mixed $first Value to compare.
|
||||
* @param mixed $second Value to compare.
|
||||
* @param string $message Message to display.
|
||||
* @return boolean True on pass
|
||||
* @access public
|
||||
*/
|
||||
function assertEqual($first, $second, $message = "%s") {
|
||||
return $this->assert(
|
||||
new EqualExpectation($first),
|
||||
$second,
|
||||
$message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Will trigger a pass if the two parameters have
|
||||
* a different value. Otherwise a fail. This
|
||||
* is for testing hand extracted text, etc.
|
||||
* @param mixed $first Value to compare.
|
||||
* @param mixed $second Value to compare.
|
||||
* @param string $message Message to display.
|
||||
* @return boolean True on pass
|
||||
* @access public
|
||||
*/
|
||||
function assertNotEqual($first, $second, $message = "%s") {
|
||||
return $this->assert(
|
||||
new NotEqualExpectation($first),
|
||||
$second,
|
||||
$message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the last status code from the shell.
|
||||
* @param integer $status Expected status of last
|
||||
* command.
|
||||
* @param string $message Message to display.
|
||||
* @return boolean True if pass.
|
||||
* @access public
|
||||
*/
|
||||
function assertExitCode($status, $message = "%s") {
|
||||
$message = sprintf($message, "Expected status code of [$status] from [" .
|
||||
$this->_last_command . "], but got [" .
|
||||
$this->_last_status . "]");
|
||||
return $this->assertTrue($status === $this->_last_status, $message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Attempt to exactly match the combined STDERR and
|
||||
* STDOUT output.
|
||||
* @param string $expected Expected output.
|
||||
* @param string $message Message to display.
|
||||
* @return boolean True if pass.
|
||||
* @access public
|
||||
*/
|
||||
function assertOutput($expected, $message = "%s") {
|
||||
$shell = &$this->_getShell();
|
||||
return $this->assert(
|
||||
new EqualExpectation($expected),
|
||||
$shell->getOutput(),
|
||||
$message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Scans the output for a Perl regex. If found
|
||||
* anywhere it passes, else it fails.
|
||||
* @param string $pattern Regex to search for.
|
||||
* @param string $message Message to display.
|
||||
* @return boolean True if pass.
|
||||
* @access public
|
||||
*/
|
||||
function assertOutputPattern($pattern, $message = "%s") {
|
||||
$shell = &$this->_getShell();
|
||||
return $this->assert(
|
||||
new PatternExpectation($pattern),
|
||||
$shell->getOutput(),
|
||||
$message);
|
||||
}
|
||||
|
||||
/**
|
||||
* If a Perl regex is found anywhere in the current
|
||||
* output then a failure is generated, else a pass.
|
||||
* @param string $pattern Regex to search for.
|
||||
* @param $message Message to display.
|
||||
* @return boolean True if pass.
|
||||
* @access public
|
||||
*/
|
||||
function assertNoOutputPattern($pattern, $message = "%s") {
|
||||
$shell = &$this->_getShell();
|
||||
return $this->assert(
|
||||
new NoPatternExpectation($pattern),
|
||||
$shell->getOutput(),
|
||||
$message);
|
||||
}
|
||||
|
||||
/**
|
||||
* File existence check.
|
||||
* @param string $path Full filename and path.
|
||||
* @param string $message Message to display.
|
||||
* @return boolean True if pass.
|
||||
* @access public
|
||||
*/
|
||||
function assertFileExists($path, $message = "%s") {
|
||||
$message = sprintf($message, "File [$path] should exist");
|
||||
return $this->assertTrue(file_exists($path), $message);
|
||||
}
|
||||
|
||||
/**
|
||||
* File non-existence check.
|
||||
* @param string $path Full filename and path.
|
||||
* @param string $message Message to display.
|
||||
* @return boolean True if pass.
|
||||
* @access public
|
||||
*/
|
||||
function assertFileNotExists($path, $message = "%s") {
|
||||
$message = sprintf($message, "File [$path] should not exist");
|
||||
return $this->assertFalse(file_exists($path), $message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Scans a file for a Perl regex. If found
|
||||
* anywhere it passes, else it fails.
|
||||
* @param string $pattern Regex to search for.
|
||||
* @param string $path Full filename and path.
|
||||
* @param string $message Message to display.
|
||||
* @return boolean True if pass.
|
||||
* @access public
|
||||
*/
|
||||
function assertFilePattern($pattern, $path, $message = "%s") {
|
||||
$shell = &$this->_getShell();
|
||||
return $this->assert(
|
||||
new PatternExpectation($pattern),
|
||||
implode('', file($path)),
|
||||
$message);
|
||||
}
|
||||
|
||||
/**
|
||||
* If a Perl regex is found anywhere in the named
|
||||
* file then a failure is generated, else a pass.
|
||||
* @param string $pattern Regex to search for.
|
||||
* @param string $path Full filename and path.
|
||||
* @param string $message Message to display.
|
||||
* @return boolean True if pass.
|
||||
* @access public
|
||||
*/
|
||||
function assertNoFilePattern($pattern, $path, $message = "%s") {
|
||||
$shell = &$this->_getShell();
|
||||
return $this->assert(
|
||||
new NoPatternExpectation($pattern),
|
||||
implode('', file($path)),
|
||||
$message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for current shell. Used for testing the
|
||||
* the tester itself.
|
||||
* @return Shell Current shell.
|
||||
* @access protected
|
||||
*/
|
||||
function &_getShell() {
|
||||
return $this->_current_shell;
|
||||
}
|
||||
|
||||
/**
|
||||
* Factory for the shell to run the command on.
|
||||
* @return Shell New shell object.
|
||||
* @access protected
|
||||
*/
|
||||
function &_createShell() {
|
||||
$shell = &new SimpleShell();
|
||||
return $shell;
|
||||
}
|
||||
}
|
||||
?>
|
||||
478
tests/simpletest/simpletest.php
Normal file
478
tests/simpletest/simpletest.php
Normal file
|
|
@ -0,0 +1,478 @@
|
|||
<?php
|
||||
/**
|
||||
* Global state for SimpleTest and kicker script in future versions.
|
||||
* @package SimpleTest
|
||||
* @subpackage UnitTester
|
||||
* @version $Id: simpletest.php 1723 2008-04-08 00:34:10Z lastcraft $
|
||||
*/
|
||||
|
||||
/**#@+
|
||||
* include SimpleTest files
|
||||
*/
|
||||
if (version_compare(phpversion(), '5') >= 0) {
|
||||
require_once(dirname(__FILE__) . '/reflection_php5.php');
|
||||
} else {
|
||||
require_once(dirname(__FILE__) . '/reflection_php4.php');
|
||||
}
|
||||
require_once(dirname(__FILE__) . '/default_reporter.php');
|
||||
require_once(dirname(__FILE__) . '/compatibility.php');
|
||||
/**#@-*/
|
||||
|
||||
/**
|
||||
* Registry and test context. Includes a few
|
||||
* global options that I'm slowly getting rid of.
|
||||
* @package SimpleTest
|
||||
* @subpackage UnitTester
|
||||
*/
|
||||
class SimpleTest {
|
||||
|
||||
/**
|
||||
* Reads the SimpleTest version from the release file.
|
||||
* @return string Version string.
|
||||
* @static
|
||||
* @access public
|
||||
*/
|
||||
function getVersion() {
|
||||
$content = file(dirname(__FILE__) . '/VERSION');
|
||||
return trim($content[0]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the name of a test case to ignore, usually
|
||||
* because the class is an abstract case that should
|
||||
* not be run. Once PHP4 is dropped this will disappear
|
||||
* as a public method and "abstract" will rule.
|
||||
* @param string $class Add a class to ignore.
|
||||
* @static
|
||||
* @access public
|
||||
*/
|
||||
function ignore($class) {
|
||||
$registry = &SimpleTest::_getRegistry();
|
||||
$registry['IgnoreList'][strtolower($class)] = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Scans the now complete ignore list, and adds
|
||||
* all parent classes to the list. If a class
|
||||
* is not a runnable test case, then it's parents
|
||||
* wouldn't be either. This is syntactic sugar
|
||||
* to cut down on ommissions of ignore()'s or
|
||||
* missing abstract declarations. This cannot
|
||||
* be done whilst loading classes wiithout forcing
|
||||
* a particular order on the class declarations and
|
||||
* the ignore() calls. It's just nice to have the ignore()
|
||||
* calls at the top of the file before the actual declarations.
|
||||
* @param array $classes Class names of interest.
|
||||
* @static
|
||||
* @access public
|
||||
*/
|
||||
function ignoreParentsIfIgnored($classes) {
|
||||
$registry = &SimpleTest::_getRegistry();
|
||||
foreach ($classes as $class) {
|
||||
if (SimpleTest::isIgnored($class)) {
|
||||
$reflection = new SimpleReflection($class);
|
||||
if ($parent = $reflection->getParent()) {
|
||||
SimpleTest::ignore($parent);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Puts the object to the global pool of 'preferred' objects
|
||||
* which can be retrieved with SimpleTest :: preferred() method.
|
||||
* Instances of the same class are overwritten.
|
||||
* @param object $object Preferred object
|
||||
* @static
|
||||
* @access public
|
||||
* @see preferred()
|
||||
*/
|
||||
function prefer(&$object) {
|
||||
$registry = &SimpleTest::_getRegistry();
|
||||
$registry['Preferred'][] = &$object;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves 'preferred' objects from global pool. Class filter
|
||||
* can be applied in order to retrieve the object of the specific
|
||||
* class
|
||||
* @param array|string $classes Allowed classes or interfaces.
|
||||
* @static
|
||||
* @access public
|
||||
* @return array|object|null
|
||||
* @see prefer()
|
||||
*/
|
||||
function &preferred($classes) {
|
||||
if (! is_array($classes)) {
|
||||
$classes = array($classes);
|
||||
}
|
||||
$registry = &SimpleTest::_getRegistry();
|
||||
for ($i = count($registry['Preferred']) - 1; $i >= 0; $i--) {
|
||||
foreach ($classes as $class) {
|
||||
if (SimpleTestCompatibility::isA($registry['Preferred'][$i], $class)) {
|
||||
return $registry['Preferred'][$i];
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Test to see if a test case is in the ignore
|
||||
* list. Quite obviously the ignore list should
|
||||
* be a separate object and will be one day.
|
||||
* This method is internal to SimpleTest. Don't
|
||||
* use it.
|
||||
* @param string $class Class name to test.
|
||||
* @return boolean True if should not be run.
|
||||
* @access public
|
||||
* @static
|
||||
*/
|
||||
function isIgnored($class) {
|
||||
$registry = &SimpleTest::_getRegistry();
|
||||
return isset($registry['IgnoreList'][strtolower($class)]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
*/
|
||||
function setMockBaseClass($mock_base) {
|
||||
$registry = &SimpleTest::_getRegistry();
|
||||
$registry['MockBaseClass'] = $mock_base;
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
*/
|
||||
function getMockBaseClass() {
|
||||
$registry = &SimpleTest::_getRegistry();
|
||||
return $registry['MockBaseClass'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets proxy to use on all requests for when
|
||||
* testing from behind a firewall. Set host
|
||||
* to false to disable. This will take effect
|
||||
* if there are no other proxy settings.
|
||||
* @param string $proxy Proxy host as URL.
|
||||
* @param string $username Proxy username for authentication.
|
||||
* @param string $password Proxy password for authentication.
|
||||
* @access public
|
||||
*/
|
||||
function useProxy($proxy, $username = false, $password = false) {
|
||||
$registry = &SimpleTest::_getRegistry();
|
||||
$registry['DefaultProxy'] = $proxy;
|
||||
$registry['DefaultProxyUsername'] = $username;
|
||||
$registry['DefaultProxyPassword'] = $password;
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for default proxy host.
|
||||
* @return string Proxy URL.
|
||||
* @access public
|
||||
*/
|
||||
function getDefaultProxy() {
|
||||
$registry = &SimpleTest::_getRegistry();
|
||||
return $registry['DefaultProxy'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for default proxy username.
|
||||
* @return string Proxy username for authentication.
|
||||
* @access public
|
||||
*/
|
||||
function getDefaultProxyUsername() {
|
||||
$registry = &SimpleTest::_getRegistry();
|
||||
return $registry['DefaultProxyUsername'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for default proxy password.
|
||||
* @return string Proxy password for authentication.
|
||||
* @access public
|
||||
*/
|
||||
function getDefaultProxyPassword() {
|
||||
$registry = &SimpleTest::_getRegistry();
|
||||
return $registry['DefaultProxyPassword'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for global registry of options.
|
||||
* @return hash All stored values.
|
||||
* @access private
|
||||
* @static
|
||||
*/
|
||||
function &_getRegistry() {
|
||||
static $registry = false;
|
||||
if (! $registry) {
|
||||
$registry = SimpleTest::_getDefaults();
|
||||
}
|
||||
return $registry;
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for the context of the current
|
||||
* test run.
|
||||
* @return SimpleTestContext Current test run.
|
||||
* @access public
|
||||
* @static
|
||||
*/
|
||||
function &getContext() {
|
||||
static $context = false;
|
||||
if (! $context) {
|
||||
$context = new SimpleTestContext();
|
||||
}
|
||||
return $context;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constant default values.
|
||||
* @return hash All registry defaults.
|
||||
* @access private
|
||||
* @static
|
||||
*/
|
||||
function _getDefaults() {
|
||||
return array(
|
||||
'StubBaseClass' => 'SimpleStub',
|
||||
'MockBaseClass' => 'SimpleMock',
|
||||
'IgnoreList' => array(),
|
||||
'DefaultProxy' => false,
|
||||
'DefaultProxyUsername' => false,
|
||||
'DefaultProxyPassword' => false,
|
||||
'Preferred' => array(new HtmlReporter(), new TextReporter(), new XmlReporter()));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Container for all components for a specific
|
||||
* test run. Makes things like error queues
|
||||
* available to PHP event handlers, and also
|
||||
* gets around some nasty reference issues in
|
||||
* the mocks.
|
||||
* @package SimpleTest
|
||||
*/
|
||||
class SimpleTestContext {
|
||||
var $_test;
|
||||
var $_reporter;
|
||||
var $_resources;
|
||||
|
||||
/**
|
||||
* Clears down the current context.
|
||||
* @access public
|
||||
*/
|
||||
function clear() {
|
||||
$this->_resources = array();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the current test case instance. This
|
||||
* global instance can be used by the mock objects
|
||||
* to send message to the test cases.
|
||||
* @param SimpleTestCase $test Test case to register.
|
||||
* @access public
|
||||
*/
|
||||
function setTest(&$test) {
|
||||
$this->clear();
|
||||
$this->_test = &$test;
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for currently running test case.
|
||||
* @return SimpleTestCase Current test.
|
||||
* @access public
|
||||
*/
|
||||
function &getTest() {
|
||||
return $this->_test;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the current reporter. This
|
||||
* global instance can be used by the mock objects
|
||||
* to send messages.
|
||||
* @param SimpleReporter $reporter Reporter to register.
|
||||
* @access public
|
||||
*/
|
||||
function setReporter(&$reporter) {
|
||||
$this->clear();
|
||||
$this->_reporter = &$reporter;
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for current reporter.
|
||||
* @return SimpleReporter Current reporter.
|
||||
* @access public
|
||||
*/
|
||||
function &getReporter() {
|
||||
return $this->_reporter;
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for the Singleton resource.
|
||||
* @return object Global resource.
|
||||
* @access public
|
||||
* @static
|
||||
*/
|
||||
function &get($resource) {
|
||||
if (! isset($this->_resources[$resource])) {
|
||||
$this->_resources[$resource] = &new $resource();
|
||||
}
|
||||
return $this->_resources[$resource];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Interrogates the stack trace to recover the
|
||||
* failure point.
|
||||
* @package SimpleTest
|
||||
* @subpackage UnitTester
|
||||
*/
|
||||
class SimpleStackTrace {
|
||||
var $_prefixes;
|
||||
|
||||
/**
|
||||
* Stashes the list of target prefixes.
|
||||
* @param array $prefixes List of method prefixes
|
||||
* to search for.
|
||||
*/
|
||||
function SimpleStackTrace($prefixes) {
|
||||
$this->_prefixes = $prefixes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Extracts the last method name that was not within
|
||||
* Simpletest itself. Captures a stack trace if none given.
|
||||
* @param array $stack List of stack frames.
|
||||
* @return string Snippet of test report with line
|
||||
* number and file.
|
||||
* @access public
|
||||
*/
|
||||
function traceMethod($stack = false) {
|
||||
$stack = $stack ? $stack : $this->_captureTrace();
|
||||
foreach ($stack as $frame) {
|
||||
if ($this->_frameLiesWithinSimpleTestFolder($frame)) {
|
||||
continue;
|
||||
}
|
||||
if ($this->_frameMatchesPrefix($frame)) {
|
||||
return ' at [' . $frame['file'] . ' line ' . $frame['line'] . ']';
|
||||
}
|
||||
}
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Test to see if error is generated by SimpleTest itself.
|
||||
* @param array $frame PHP stack frame.
|
||||
* @return boolean True if a SimpleTest file.
|
||||
* @access private
|
||||
*/
|
||||
function _frameLiesWithinSimpleTestFolder($frame) {
|
||||
if (isset($frame['file'])) {
|
||||
$path = substr(SIMPLE_TEST, 0, -1);
|
||||
if (strpos($frame['file'], $path) === 0) {
|
||||
if (dirname($frame['file']) == $path) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Tries to determine if the method call is an assert, etc.
|
||||
* @param array $frame PHP stack frame.
|
||||
* @return boolean True if matches a target.
|
||||
* @access private
|
||||
*/
|
||||
function _frameMatchesPrefix($frame) {
|
||||
foreach ($this->_prefixes as $prefix) {
|
||||
if (strncmp($frame['function'], $prefix, strlen($prefix)) == 0) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Grabs a current stack trace.
|
||||
* @return array Fulle trace.
|
||||
* @access private
|
||||
*/
|
||||
function _captureTrace() {
|
||||
if (function_exists('debug_backtrace')) {
|
||||
return array_reverse(debug_backtrace());
|
||||
}
|
||||
return array();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @package SimpleTest
|
||||
* @subpackage UnitTester
|
||||
* @deprecated
|
||||
*/
|
||||
class SimpleTestOptions extends SimpleTest {
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
*/
|
||||
function getVersion() {
|
||||
return Simpletest::getVersion();
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
*/
|
||||
function ignore($class) {
|
||||
return Simpletest::ignore($class);
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
*/
|
||||
function isIgnored($class) {
|
||||
return Simpletest::isIgnored($class);
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
*/
|
||||
function setMockBaseClass($mock_base) {
|
||||
return Simpletest::setMockBaseClass($mock_base);
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
*/
|
||||
function getMockBaseClass() {
|
||||
return Simpletest::getMockBaseClass();
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
*/
|
||||
function useProxy($proxy, $username = false, $password = false) {
|
||||
return Simpletest::useProxy($proxy, $username, $password);
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
*/
|
||||
function getDefaultProxy() {
|
||||
return Simpletest::getDefaultProxy();
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
*/
|
||||
function getDefaultProxyUsername() {
|
||||
return Simpletest::getDefaultProxyUsername();
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
*/
|
||||
function getDefaultProxyPassword() {
|
||||
return Simpletest::getDefaultProxyPassword();
|
||||
}
|
||||
}
|
||||
?>
|
||||
216
tests/simpletest/socket.php
Normal file
216
tests/simpletest/socket.php
Normal file
|
|
@ -0,0 +1,216 @@
|
|||
<?php
|
||||
/**
|
||||
* base include file for SimpleTest
|
||||
* @package SimpleTest
|
||||
* @subpackage MockObjects
|
||||
* @version $Id: socket.php 1723 2008-04-08 00:34:10Z lastcraft $
|
||||
*/
|
||||
|
||||
/**#@+
|
||||
* include SimpleTest files
|
||||
*/
|
||||
require_once(dirname(__FILE__) . '/compatibility.php');
|
||||
/**#@-*/
|
||||
|
||||
/**
|
||||
* Stashes an error for later. Useful for constructors
|
||||
* until PHP gets exceptions.
|
||||
* @package SimpleTest
|
||||
* @subpackage WebTester
|
||||
*/
|
||||
class SimpleStickyError {
|
||||
var $_error = 'Constructor not chained';
|
||||
|
||||
/**
|
||||
* Sets the error to empty.
|
||||
* @access public
|
||||
*/
|
||||
function SimpleStickyError() {
|
||||
$this->_clearError();
|
||||
}
|
||||
|
||||
/**
|
||||
* Test for an outstanding error.
|
||||
* @return boolean True if there is an error.
|
||||
* @access public
|
||||
*/
|
||||
function isError() {
|
||||
return ($this->_error != '');
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for an outstanding error.
|
||||
* @return string Empty string if no error otherwise
|
||||
* the error message.
|
||||
* @access public
|
||||
*/
|
||||
function getError() {
|
||||
return $this->_error;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the internal error.
|
||||
* @param string Error message to stash.
|
||||
* @access protected
|
||||
*/
|
||||
function _setError($error) {
|
||||
$this->_error = $error;
|
||||
}
|
||||
|
||||
/**
|
||||
* Resets the error state to no error.
|
||||
* @access protected
|
||||
*/
|
||||
function _clearError() {
|
||||
$this->_setError('');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Wrapper for TCP/IP socket.
|
||||
* @package SimpleTest
|
||||
* @subpackage WebTester
|
||||
*/
|
||||
class SimpleSocket extends SimpleStickyError {
|
||||
var $_handle;
|
||||
var $_is_open = false;
|
||||
var $_sent = '';
|
||||
var $lock_size;
|
||||
|
||||
/**
|
||||
* Opens a socket for reading and writing.
|
||||
* @param string $host Hostname to send request to.
|
||||
* @param integer $port Port on remote machine to open.
|
||||
* @param integer $timeout Connection timeout in seconds.
|
||||
* @param integer $block_size Size of chunk to read.
|
||||
* @access public
|
||||
*/
|
||||
function SimpleSocket($host, $port, $timeout, $block_size = 255) {
|
||||
$this->SimpleStickyError();
|
||||
if (! ($this->_handle = $this->_openSocket($host, $port, $error_number, $error, $timeout))) {
|
||||
$this->_setError("Cannot open [$host:$port] with [$error] within [$timeout] seconds");
|
||||
return;
|
||||
}
|
||||
$this->_is_open = true;
|
||||
$this->_block_size = $block_size;
|
||||
SimpleTestCompatibility::setTimeout($this->_handle, $timeout);
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes some data to the socket and saves alocal copy.
|
||||
* @param string $message String to send to socket.
|
||||
* @return boolean True if successful.
|
||||
* @access public
|
||||
*/
|
||||
function write($message) {
|
||||
if ($this->isError() || ! $this->isOpen()) {
|
||||
return false;
|
||||
}
|
||||
$count = fwrite($this->_handle, $message);
|
||||
if (! $count) {
|
||||
if ($count === false) {
|
||||
$this->_setError('Cannot write to socket');
|
||||
$this->close();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
fflush($this->_handle);
|
||||
$this->_sent .= $message;
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads data from the socket. The error suppresion
|
||||
* is a workaround for PHP4 always throwing a warning
|
||||
* with a secure socket.
|
||||
* @return integer/boolean Incoming bytes. False
|
||||
* on error.
|
||||
* @access public
|
||||
*/
|
||||
function read() {
|
||||
if ($this->isError() || ! $this->isOpen()) {
|
||||
return false;
|
||||
}
|
||||
$raw = @fread($this->_handle, $this->_block_size);
|
||||
if ($raw === false) {
|
||||
$this->_setError('Cannot read from socket');
|
||||
$this->close();
|
||||
}
|
||||
return $raw;
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for socket open state.
|
||||
* @return boolean True if open.
|
||||
* @access public
|
||||
*/
|
||||
function isOpen() {
|
||||
return $this->_is_open;
|
||||
}
|
||||
|
||||
/**
|
||||
* Closes the socket preventing further reads.
|
||||
* Cannot be reopened once closed.
|
||||
* @return boolean True if successful.
|
||||
* @access public
|
||||
*/
|
||||
function close() {
|
||||
$this->_is_open = false;
|
||||
return fclose($this->_handle);
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for content so far.
|
||||
* @return string Bytes sent only.
|
||||
* @access public
|
||||
*/
|
||||
function getSent() {
|
||||
return $this->_sent;
|
||||
}
|
||||
|
||||
/**
|
||||
* Actually opens the low level socket.
|
||||
* @param string $host Host to connect to.
|
||||
* @param integer $port Port on host.
|
||||
* @param integer $error_number Recipient of error code.
|
||||
* @param string $error Recipoent of error message.
|
||||
* @param integer $timeout Maximum time to wait for connection.
|
||||
* @access protected
|
||||
*/
|
||||
function _openSocket($host, $port, &$error_number, &$error, $timeout) {
|
||||
return @fsockopen($host, $port, $error_number, $error, $timeout);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Wrapper for TCP/IP socket over TLS.
|
||||
* @package SimpleTest
|
||||
* @subpackage WebTester
|
||||
*/
|
||||
class SimpleSecureSocket extends SimpleSocket {
|
||||
|
||||
/**
|
||||
* Opens a secure socket for reading and writing.
|
||||
* @param string $host Hostname to send request to.
|
||||
* @param integer $port Port on remote machine to open.
|
||||
* @param integer $timeout Connection timeout in seconds.
|
||||
* @access public
|
||||
*/
|
||||
function SimpleSecureSocket($host, $port, $timeout) {
|
||||
$this->SimpleSocket($host, $port, $timeout);
|
||||
}
|
||||
|
||||
/**
|
||||
* Actually opens the low level socket.
|
||||
* @param string $host Host to connect to.
|
||||
* @param integer $port Port on host.
|
||||
* @param integer $error_number Recipient of error code.
|
||||
* @param string $error Recipient of error message.
|
||||
* @param integer $timeout Maximum time to wait for connection.
|
||||
* @access protected
|
||||
*/
|
||||
function _openSocket($host, $port, &$error_number, &$error, $timeout) {
|
||||
return parent::_openSocket("tls://$host", $port, $error_number, $error, $timeout);
|
||||
}
|
||||
}
|
||||
?>
|
||||
1418
tests/simpletest/tag.php
Normal file
1418
tests/simpletest/tag.php
Normal file
File diff suppressed because it is too large
Load diff
1633
tests/simpletest/test/acceptance_test.php
Normal file
1633
tests/simpletest/test/acceptance_test.php
Normal file
File diff suppressed because it is too large
Load diff
77
tests/simpletest/test/adapter_test.php
Normal file
77
tests/simpletest/test/adapter_test.php
Normal file
|
|
@ -0,0 +1,77 @@
|
|||
<?php
|
||||
// $Id: adapter_test.php 1505 2007-04-30 23:39:59Z lastcraft $
|
||||
require_once(dirname(__FILE__) . '/../autorun.php');
|
||||
require_once(dirname(__FILE__) . '/../extensions/pear_test_case.php');
|
||||
require_once(dirname(__FILE__) . '/../extensions/phpunit_test_case.php');
|
||||
|
||||
class SameTestClass {
|
||||
}
|
||||
|
||||
class TestOfPearAdapter extends PHPUnit_TestCase {
|
||||
|
||||
function testBoolean() {
|
||||
$this->assertTrue(true, "PEAR true");
|
||||
$this->assertFalse(false, "PEAR false");
|
||||
}
|
||||
|
||||
function testName() {
|
||||
$this->assertTrue($this->getName() == get_class($this));
|
||||
}
|
||||
|
||||
function testPass() {
|
||||
$this->pass("PEAR pass");
|
||||
}
|
||||
|
||||
function testNulls() {
|
||||
$value = null;
|
||||
$this->assertNull($value, "PEAR null");
|
||||
$value = 0;
|
||||
$this->assertNotNull($value, "PEAR not null");
|
||||
}
|
||||
|
||||
function testType() {
|
||||
$this->assertType("Hello", "string", "PEAR type");
|
||||
}
|
||||
|
||||
function testEquals() {
|
||||
$this->assertEquals(12, 12, "PEAR identity");
|
||||
$this->setLooselyTyped(true);
|
||||
$this->assertEquals("12", 12, "PEAR equality");
|
||||
}
|
||||
|
||||
function testSame() {
|
||||
$same = &new SameTestClass();
|
||||
$this->assertSame($same, $same, "PEAR same");
|
||||
}
|
||||
|
||||
function testRegExp() {
|
||||
$this->assertRegExp('/hello/', "A big hello from me", "PEAR regex");
|
||||
}
|
||||
}
|
||||
|
||||
class TestOfPhpUnitAdapter extends TestCase {
|
||||
function TestOfPhpUnitAdapter() {
|
||||
$this->TestCase('TestOfPhpUnitAdapter');
|
||||
}
|
||||
|
||||
function testBoolean() {
|
||||
$this->assert(true, 'PHP Unit true');
|
||||
}
|
||||
|
||||
function testName() {
|
||||
$this->assert($this->name() == 'TestOfPhpUnitAdapter');
|
||||
}
|
||||
|
||||
function testEquals() {
|
||||
$this->assertEquals(12, 12, 'PHP Unit equality');
|
||||
}
|
||||
|
||||
function testMultilineEquals() {
|
||||
$this->assertEquals("a\nb\n", "a\nb\n", 'PHP Unit equality');
|
||||
}
|
||||
|
||||
function testRegExp() {
|
||||
$this->assertRegexp('/hello/', 'A big hello from me', 'PHPUnit regex');
|
||||
}
|
||||
}
|
||||
?>
|
||||
13
tests/simpletest/test/all_tests.php
Normal file
13
tests/simpletest/test/all_tests.php
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
<?php
|
||||
require_once(dirname(__FILE__) . '/../autorun.php');
|
||||
|
||||
class AllTests extends TestSuite {
|
||||
function AllTests() {
|
||||
$this->TestSuite('All tests for SimpleTest ' . SimpleTest::getVersion());
|
||||
$this->addFile(dirname(__FILE__) . '/unit_tests.php');
|
||||
$this->addFile(dirname(__FILE__) . '/shell_test.php');
|
||||
$this->addFile(dirname(__FILE__) . '/live_test.php');
|
||||
$this->addFile(dirname(__FILE__) . '/acceptance_test.php');
|
||||
}
|
||||
}
|
||||
?>
|
||||
145
tests/simpletest/test/authentication_test.php
Normal file
145
tests/simpletest/test/authentication_test.php
Normal file
|
|
@ -0,0 +1,145 @@
|
|||
<?php
|
||||
// $Id: authentication_test.php 1505 2007-04-30 23:39:59Z lastcraft $
|
||||
require_once(dirname(__FILE__) . '/../autorun.php');
|
||||
require_once(dirname(__FILE__) . '/../authentication.php');
|
||||
require_once(dirname(__FILE__) . '/../http.php');
|
||||
Mock::generate('SimpleHttpRequest');
|
||||
|
||||
class TestOfRealm extends UnitTestCase {
|
||||
|
||||
function testWithinSameUrl() {
|
||||
$realm = &new SimpleRealm(
|
||||
'Basic',
|
||||
new SimpleUrl('http://www.here.com/path/hello.html'));
|
||||
$this->assertTrue($realm->isWithin(
|
||||
new SimpleUrl('http://www.here.com/path/hello.html')));
|
||||
}
|
||||
|
||||
function testInsideWithLongerUrl() {
|
||||
$realm = &new SimpleRealm(
|
||||
'Basic',
|
||||
new SimpleUrl('http://www.here.com/path/'));
|
||||
$this->assertTrue($realm->isWithin(
|
||||
new SimpleUrl('http://www.here.com/path/hello.html')));
|
||||
}
|
||||
|
||||
function testBelowRootIsOutside() {
|
||||
$realm = &new SimpleRealm(
|
||||
'Basic',
|
||||
new SimpleUrl('http://www.here.com/path/'));
|
||||
$this->assertTrue($realm->isWithin(
|
||||
new SimpleUrl('http://www.here.com/path/more/hello.html')));
|
||||
}
|
||||
|
||||
function testOldNetscapeDefinitionIsOutside() {
|
||||
$realm = &new SimpleRealm(
|
||||
'Basic',
|
||||
new SimpleUrl('http://www.here.com/path/'));
|
||||
$this->assertFalse($realm->isWithin(
|
||||
new SimpleUrl('http://www.here.com/pathmore/hello.html')));
|
||||
}
|
||||
|
||||
function testInsideWithMissingTrailingSlash() {
|
||||
$realm = &new SimpleRealm(
|
||||
'Basic',
|
||||
new SimpleUrl('http://www.here.com/path/'));
|
||||
$this->assertTrue($realm->isWithin(
|
||||
new SimpleUrl('http://www.here.com/path')));
|
||||
}
|
||||
|
||||
function testDifferentPageNameStillInside() {
|
||||
$realm = &new SimpleRealm(
|
||||
'Basic',
|
||||
new SimpleUrl('http://www.here.com/path/hello.html'));
|
||||
$this->assertTrue($realm->isWithin(
|
||||
new SimpleUrl('http://www.here.com/path/goodbye.html')));
|
||||
}
|
||||
|
||||
function testNewUrlInSameDirectoryDoesNotChangeRealm() {
|
||||
$realm = &new SimpleRealm(
|
||||
'Basic',
|
||||
new SimpleUrl('http://www.here.com/path/hello.html'));
|
||||
$realm->stretch(new SimpleUrl('http://www.here.com/path/goodbye.html'));
|
||||
$this->assertTrue($realm->isWithin(
|
||||
new SimpleUrl('http://www.here.com/path/index.html')));
|
||||
$this->assertFalse($realm->isWithin(
|
||||
new SimpleUrl('http://www.here.com/index.html')));
|
||||
}
|
||||
|
||||
function testNewUrlMakesRealmTheCommonPath() {
|
||||
$realm = &new SimpleRealm(
|
||||
'Basic',
|
||||
new SimpleUrl('http://www.here.com/path/here/hello.html'));
|
||||
$realm->stretch(new SimpleUrl('http://www.here.com/path/there/goodbye.html'));
|
||||
$this->assertTrue($realm->isWithin(
|
||||
new SimpleUrl('http://www.here.com/path/here/index.html')));
|
||||
$this->assertTrue($realm->isWithin(
|
||||
new SimpleUrl('http://www.here.com/path/there/index.html')));
|
||||
$this->assertTrue($realm->isWithin(
|
||||
new SimpleUrl('http://www.here.com/path/index.html')));
|
||||
$this->assertFalse($realm->isWithin(
|
||||
new SimpleUrl('http://www.here.com/index.html')));
|
||||
$this->assertFalse($realm->isWithin(
|
||||
new SimpleUrl('http://www.here.com/paths/index.html')));
|
||||
$this->assertFalse($realm->isWithin(
|
||||
new SimpleUrl('http://www.here.com/pathindex.html')));
|
||||
}
|
||||
}
|
||||
|
||||
class TestOfAuthenticator extends UnitTestCase {
|
||||
|
||||
function testNoRealms() {
|
||||
$request = &new MockSimpleHttpRequest();
|
||||
$request->expectNever('addHeaderLine');
|
||||
$authenticator = &new SimpleAuthenticator();
|
||||
$authenticator->addHeaders($request, new SimpleUrl('http://here.com/'));
|
||||
}
|
||||
|
||||
function &createSingleRealm() {
|
||||
$authenticator = &new SimpleAuthenticator();
|
||||
$authenticator->addRealm(
|
||||
new SimpleUrl('http://www.here.com/path/hello.html'),
|
||||
'Basic',
|
||||
'Sanctuary');
|
||||
$authenticator->setIdentityForRealm('www.here.com', 'Sanctuary', 'test', 'secret');
|
||||
return $authenticator;
|
||||
}
|
||||
|
||||
function testOutsideRealm() {
|
||||
$request = &new MockSimpleHttpRequest();
|
||||
$request->expectNever('addHeaderLine');
|
||||
$authenticator = &$this->createSingleRealm();
|
||||
$authenticator->addHeaders(
|
||||
$request,
|
||||
new SimpleUrl('http://www.here.com/hello.html'));
|
||||
}
|
||||
|
||||
function testWithinRealm() {
|
||||
$request = &new MockSimpleHttpRequest();
|
||||
$request->expectOnce('addHeaderLine');
|
||||
$authenticator = &$this->createSingleRealm();
|
||||
$authenticator->addHeaders(
|
||||
$request,
|
||||
new SimpleUrl('http://www.here.com/path/more/hello.html'));
|
||||
}
|
||||
|
||||
function testRestartingClearsRealm() {
|
||||
$request = &new MockSimpleHttpRequest();
|
||||
$request->expectNever('addHeaderLine');
|
||||
$authenticator = &$this->createSingleRealm();
|
||||
$authenticator->restartSession();
|
||||
$authenticator->addHeaders(
|
||||
$request,
|
||||
new SimpleUrl('http://www.here.com/hello.html'));
|
||||
}
|
||||
|
||||
function testDifferentHostIsOutsideRealm() {
|
||||
$request = &new MockSimpleHttpRequest();
|
||||
$request->expectNever('addHeaderLine');
|
||||
$authenticator = &$this->createSingleRealm();
|
||||
$authenticator->addHeaders(
|
||||
$request,
|
||||
new SimpleUrl('http://here.com/path/hello.html'));
|
||||
}
|
||||
}
|
||||
?>
|
||||
13
tests/simpletest/test/autorun_test.php
Normal file
13
tests/simpletest/test/autorun_test.php
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
<?php
|
||||
require_once(dirname(__FILE__) . '/../autorun.php');
|
||||
require_once(dirname(__FILE__) . '/support/test1.php');
|
||||
|
||||
class LoadIfIncludedTestCase extends UnitTestCase {
|
||||
function test_load_if_included() {
|
||||
$tests = new GroupTest();
|
||||
$tests->addFile(dirname(__FILE__) . '/support/test1.php');
|
||||
$this->assertEqual($tests->getSize(), 1);
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
10
tests/simpletest/test/bad_test_suite.php
Normal file
10
tests/simpletest/test/bad_test_suite.php
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
<?php
|
||||
require_once(dirname(__FILE__) . '/../autorun.php');
|
||||
|
||||
class BadTestCases extends TestSuite {
|
||||
function BadTestCases() {
|
||||
$this->TestSuite('Two bad test cases');
|
||||
$this->addFile(dirname(__FILE__) . '/support/empty_test_file.php');
|
||||
}
|
||||
}
|
||||
?>
|
||||
779
tests/simpletest/test/browser_test.php
Normal file
779
tests/simpletest/test/browser_test.php
Normal file
|
|
@ -0,0 +1,779 @@
|
|||
<?php
|
||||
// $Id: browser_test.php 1624 2008-01-01 15:00:43Z pp11 $
|
||||
require_once(dirname(__FILE__) . '/../autorun.php');
|
||||
require_once(dirname(__FILE__) . '/../browser.php');
|
||||
require_once(dirname(__FILE__) . '/../user_agent.php');
|
||||
require_once(dirname(__FILE__) . '/../http.php');
|
||||
require_once(dirname(__FILE__) . '/../page.php');
|
||||
require_once(dirname(__FILE__) . '/../encoding.php');
|
||||
|
||||
Mock::generate('SimpleHttpResponse');
|
||||
Mock::generate('SimplePage');
|
||||
Mock::generate('SimpleForm');
|
||||
Mock::generate('SimpleUserAgent');
|
||||
Mock::generatePartial(
|
||||
'SimpleBrowser',
|
||||
'MockParseSimpleBrowser',
|
||||
array('_createUserAgent', '_parse'));
|
||||
Mock::generatePartial(
|
||||
'SimpleBrowser',
|
||||
'MockUserAgentSimpleBrowser',
|
||||
array('_createUserAgent'));
|
||||
|
||||
class TestOfHistory extends UnitTestCase {
|
||||
|
||||
function testEmptyHistoryHasFalseContents() {
|
||||
$history = &new SimpleBrowserHistory();
|
||||
$this->assertIdentical($history->getUrl(), false);
|
||||
$this->assertIdentical($history->getParameters(), false);
|
||||
}
|
||||
|
||||
function testCannotMoveInEmptyHistory() {
|
||||
$history = &new SimpleBrowserHistory();
|
||||
$this->assertFalse($history->back());
|
||||
$this->assertFalse($history->forward());
|
||||
}
|
||||
|
||||
function testCurrentTargetAccessors() {
|
||||
$history = &new SimpleBrowserHistory();
|
||||
$history->recordEntry(
|
||||
new SimpleUrl('http://www.here.com/'),
|
||||
new SimpleGetEncoding());
|
||||
$this->assertIdentical($history->getUrl(), new SimpleUrl('http://www.here.com/'));
|
||||
$this->assertIdentical($history->getParameters(), new SimpleGetEncoding());
|
||||
}
|
||||
|
||||
function testSecondEntryAccessors() {
|
||||
$history = &new SimpleBrowserHistory();
|
||||
$history->recordEntry(
|
||||
new SimpleUrl('http://www.first.com/'),
|
||||
new SimpleGetEncoding());
|
||||
$history->recordEntry(
|
||||
new SimpleUrl('http://www.second.com/'),
|
||||
new SimplePostEncoding(array('a' => 1)));
|
||||
$this->assertIdentical($history->getUrl(), new SimpleUrl('http://www.second.com/'));
|
||||
$this->assertIdentical(
|
||||
$history->getParameters(),
|
||||
new SimplePostEncoding(array('a' => 1)));
|
||||
}
|
||||
|
||||
function testGoingBackwards() {
|
||||
$history = &new SimpleBrowserHistory();
|
||||
$history->recordEntry(
|
||||
new SimpleUrl('http://www.first.com/'),
|
||||
new SimpleGetEncoding());
|
||||
$history->recordEntry(
|
||||
new SimpleUrl('http://www.second.com/'),
|
||||
new SimplePostEncoding(array('a' => 1)));
|
||||
$this->assertTrue($history->back());
|
||||
$this->assertIdentical($history->getUrl(), new SimpleUrl('http://www.first.com/'));
|
||||
$this->assertIdentical($history->getParameters(), new SimpleGetEncoding());
|
||||
}
|
||||
|
||||
function testGoingBackwardsOffBeginning() {
|
||||
$history = &new SimpleBrowserHistory();
|
||||
$history->recordEntry(
|
||||
new SimpleUrl('http://www.first.com/'),
|
||||
new SimpleGetEncoding());
|
||||
$this->assertFalse($history->back());
|
||||
$this->assertIdentical($history->getUrl(), new SimpleUrl('http://www.first.com/'));
|
||||
$this->assertIdentical($history->getParameters(), new SimpleGetEncoding());
|
||||
}
|
||||
|
||||
function testGoingForwardsOffEnd() {
|
||||
$history = &new SimpleBrowserHistory();
|
||||
$history->recordEntry(
|
||||
new SimpleUrl('http://www.first.com/'),
|
||||
new SimpleGetEncoding());
|
||||
$this->assertFalse($history->forward());
|
||||
$this->assertIdentical($history->getUrl(), new SimpleUrl('http://www.first.com/'));
|
||||
$this->assertIdentical($history->getParameters(), new SimpleGetEncoding());
|
||||
}
|
||||
|
||||
function testGoingBackwardsAndForwards() {
|
||||
$history = &new SimpleBrowserHistory();
|
||||
$history->recordEntry(
|
||||
new SimpleUrl('http://www.first.com/'),
|
||||
new SimpleGetEncoding());
|
||||
$history->recordEntry(
|
||||
new SimpleUrl('http://www.second.com/'),
|
||||
new SimplePostEncoding(array('a' => 1)));
|
||||
$this->assertTrue($history->back());
|
||||
$this->assertTrue($history->forward());
|
||||
$this->assertIdentical($history->getUrl(), new SimpleUrl('http://www.second.com/'));
|
||||
$this->assertIdentical(
|
||||
$history->getParameters(),
|
||||
new SimplePostEncoding(array('a' => 1)));
|
||||
}
|
||||
|
||||
function testNewEntryReplacesNextOne() {
|
||||
$history = &new SimpleBrowserHistory();
|
||||
$history->recordEntry(
|
||||
new SimpleUrl('http://www.first.com/'),
|
||||
new SimpleGetEncoding());
|
||||
$history->recordEntry(
|
||||
new SimpleUrl('http://www.second.com/'),
|
||||
new SimplePostEncoding(array('a' => 1)));
|
||||
$history->back();
|
||||
$history->recordEntry(
|
||||
new SimpleUrl('http://www.third.com/'),
|
||||
new SimpleGetEncoding());
|
||||
$this->assertIdentical($history->getUrl(), new SimpleUrl('http://www.third.com/'));
|
||||
$this->assertIdentical($history->getParameters(), new SimpleGetEncoding());
|
||||
}
|
||||
|
||||
function testNewEntryDropsFutureEntries() {
|
||||
$history = &new SimpleBrowserHistory();
|
||||
$history->recordEntry(
|
||||
new SimpleUrl('http://www.first.com/'),
|
||||
new SimpleGetEncoding());
|
||||
$history->recordEntry(
|
||||
new SimpleUrl('http://www.second.com/'),
|
||||
new SimpleGetEncoding());
|
||||
$history->recordEntry(
|
||||
new SimpleUrl('http://www.third.com/'),
|
||||
new SimpleGetEncoding());
|
||||
$history->back();
|
||||
$history->back();
|
||||
$history->recordEntry(
|
||||
new SimpleUrl('http://www.fourth.com/'),
|
||||
new SimpleGetEncoding());
|
||||
$this->assertIdentical($history->getUrl(), new SimpleUrl('http://www.fourth.com/'));
|
||||
$this->assertFalse($history->forward());
|
||||
$history->back();
|
||||
$this->assertIdentical($history->getUrl(), new SimpleUrl('http://www.first.com/'));
|
||||
$this->assertFalse($history->back());
|
||||
}
|
||||
}
|
||||
|
||||
class TestOfParsedPageAccess extends UnitTestCase {
|
||||
|
||||
function &loadPage(&$page) {
|
||||
$response = &new MockSimpleHttpResponse($this);
|
||||
|
||||
$agent = &new MockSimpleUserAgent($this);
|
||||
$agent->setReturnReference('fetchResponse', $response);
|
||||
|
||||
$browser = &new MockParseSimpleBrowser($this);
|
||||
$browser->setReturnReference('_createUserAgent', $agent);
|
||||
$browser->setReturnReference('_parse', $page);
|
||||
$browser->SimpleBrowser();
|
||||
|
||||
$browser->get('http://this.com/page.html');
|
||||
return $browser;
|
||||
}
|
||||
|
||||
function testAccessorsWhenNoPage() {
|
||||
$agent = &new MockSimpleUserAgent($this);
|
||||
|
||||
$browser = &new MockParseSimpleBrowser($this);
|
||||
$browser->setReturnReference('_createUserAgent', $agent);
|
||||
$browser->SimpleBrowser();
|
||||
|
||||
$this->assertEqual($browser->getContent(), '');
|
||||
}
|
||||
|
||||
function testParse() {
|
||||
$page = &new MockSimplePage();
|
||||
$page->setReturnValue('getRequest', "GET here.html\r\n\r\n");
|
||||
$page->setReturnValue('getRaw', 'Raw HTML');
|
||||
$page->setReturnValue('getTitle', 'Here');
|
||||
$page->setReturnValue('getFrameFocus', 'Frame');
|
||||
$page->setReturnValue('getMimeType', 'text/html');
|
||||
$page->setReturnValue('getResponseCode', 200);
|
||||
$page->setReturnValue('getAuthentication', 'Basic');
|
||||
$page->setReturnValue('getRealm', 'Somewhere');
|
||||
$page->setReturnValue('getTransportError', 'Ouch!');
|
||||
|
||||
$browser = &$this->loadPage($page);
|
||||
|
||||
$this->assertEqual($browser->getRequest(), "GET here.html\r\n\r\n");
|
||||
$this->assertEqual($browser->getContent(), 'Raw HTML');
|
||||
$this->assertEqual($browser->getTitle(), 'Here');
|
||||
$this->assertEqual($browser->getFrameFocus(), 'Frame');
|
||||
$this->assertIdentical($browser->getResponseCode(), 200);
|
||||
$this->assertEqual($browser->getMimeType(), 'text/html');
|
||||
$this->assertEqual($browser->getAuthentication(), 'Basic');
|
||||
$this->assertEqual($browser->getRealm(), 'Somewhere');
|
||||
$this->assertEqual($browser->getTransportError(), 'Ouch!');
|
||||
}
|
||||
|
||||
function testLinkAffirmationWhenPresent() {
|
||||
$page = &new MockSimplePage();
|
||||
$page->setReturnValue('getUrlsByLabel', array('http://www.nowhere.com'));
|
||||
$page->expectOnce('getUrlsByLabel', array('a link label'));
|
||||
$browser = &$this->loadPage($page);
|
||||
$this->assertIdentical($browser->getLink('a link label'), 'http://www.nowhere.com');
|
||||
}
|
||||
|
||||
function testLinkAffirmationByIdWhenPresent() {
|
||||
$page = &new MockSimplePage();
|
||||
$page->setReturnValue('getUrlById', 'a_page.com', array(99));
|
||||
$page->setReturnValue('getUrlById', false, array('*'));
|
||||
$browser = &$this->loadPage($page);
|
||||
$this->assertIdentical($browser->getLinkById(99), 'a_page.com');
|
||||
$this->assertFalse($browser->getLinkById(98));
|
||||
}
|
||||
|
||||
function testSettingFieldIsPassedToPage() {
|
||||
$page = &new MockSimplePage();
|
||||
$page->expectOnce('setField', array(new SimpleByLabelOrName('key'), 'Value', false));
|
||||
$page->setReturnValue('getField', 'Value');
|
||||
$browser = &$this->loadPage($page);
|
||||
$this->assertEqual($browser->getField('key'), 'Value');
|
||||
$browser->setField('key', 'Value');
|
||||
}
|
||||
}
|
||||
|
||||
class TestOfBrowserNavigation extends UnitTestCase {
|
||||
|
||||
function &createBrowser(&$agent, &$page) {
|
||||
$browser = &new MockParseSimpleBrowser();
|
||||
$browser->setReturnReference('_createUserAgent', $agent);
|
||||
$browser->setReturnReference('_parse', $page);
|
||||
$browser->SimpleBrowser();
|
||||
return $browser;
|
||||
}
|
||||
|
||||
function testClickLinkRequestsPage() {
|
||||
$agent = &new MockSimpleUserAgent();
|
||||
$agent->setReturnReference('fetchResponse', new MockSimpleHttpResponse());
|
||||
$agent->expectArgumentsAt(
|
||||
0,
|
||||
'fetchResponse',
|
||||
array(new SimpleUrl('http://this.com/page.html'), new SimpleGetEncoding()));
|
||||
$agent->expectArgumentsAt(
|
||||
1,
|
||||
'fetchResponse',
|
||||
array(new SimpleUrl('http://this.com/new.html'), new SimpleGetEncoding()));
|
||||
$agent->expectCallCount('fetchResponse', 2);
|
||||
|
||||
$page = &new MockSimplePage();
|
||||
$page->setReturnValue('getUrlsByLabel', array(new SimpleUrl('http://this.com/new.html')));
|
||||
$page->expectOnce('getUrlsByLabel', array('New'));
|
||||
$page->setReturnValue('getRaw', 'A page');
|
||||
|
||||
$browser = &$this->createBrowser($agent, $page);
|
||||
$browser->get('http://this.com/page.html');
|
||||
$this->assertTrue($browser->clickLink('New'));
|
||||
}
|
||||
|
||||
function testClickLinkWithUnknownFrameStillRequestsWholePage() {
|
||||
$agent = &new MockSimpleUserAgent();
|
||||
$agent->setReturnReference('fetchResponse', new MockSimpleHttpResponse());
|
||||
$agent->expectArgumentsAt(
|
||||
0,
|
||||
'fetchResponse',
|
||||
array(new SimpleUrl('http://this.com/page.html'), new SimpleGetEncoding()));
|
||||
$target = new SimpleUrl('http://this.com/new.html');
|
||||
$target->setTarget('missing');
|
||||
$agent->expectArgumentsAt(
|
||||
1,
|
||||
'fetchResponse',
|
||||
array($target, new SimpleGetEncoding()));
|
||||
$agent->expectCallCount('fetchResponse', 2);
|
||||
|
||||
$parsed_url = new SimpleUrl('http://this.com/new.html');
|
||||
$parsed_url->setTarget('missing');
|
||||
|
||||
$page = &new MockSimplePage();
|
||||
$page->setReturnValue('getUrlsByLabel', array($parsed_url));
|
||||
$page->setReturnValue('hasFrames', false);
|
||||
$page->expectOnce('getUrlsByLabel', array('New'));
|
||||
$page->setReturnValue('getRaw', 'A page');
|
||||
|
||||
$browser = &$this->createBrowser($agent, $page);
|
||||
$browser->get('http://this.com/page.html');
|
||||
$this->assertTrue($browser->clickLink('New'));
|
||||
}
|
||||
|
||||
function testClickingMissingLinkFails() {
|
||||
$agent = &new MockSimpleUserAgent($this);
|
||||
$agent->setReturnReference('fetchResponse', new MockSimpleHttpResponse());
|
||||
|
||||
$page = &new MockSimplePage();
|
||||
$page->setReturnValue('getUrlsByLabel', array());
|
||||
$page->setReturnValue('getRaw', 'stuff');
|
||||
|
||||
$browser = &$this->createBrowser($agent, $page);
|
||||
$this->assertTrue($browser->get('http://this.com/page.html'));
|
||||
$this->assertFalse($browser->clickLink('New'));
|
||||
}
|
||||
|
||||
function testClickIndexedLink() {
|
||||
$agent = &new MockSimpleUserAgent();
|
||||
$agent->setReturnReference('fetchResponse', new MockSimpleHttpResponse());
|
||||
$agent->expectArgumentsAt(
|
||||
1,
|
||||
'fetchResponse',
|
||||
array(new SimpleUrl('1.html'), new SimpleGetEncoding()));
|
||||
$agent->expectCallCount('fetchResponse', 2);
|
||||
|
||||
$page = &new MockSimplePage();
|
||||
$page->setReturnValue(
|
||||
'getUrlsByLabel',
|
||||
array(new SimpleUrl('0.html'), new SimpleUrl('1.html')));
|
||||
$page->setReturnValue('getRaw', 'A page');
|
||||
|
||||
$browser = &$this->createBrowser($agent, $page);
|
||||
$browser->get('http://this.com/page.html');
|
||||
$this->assertTrue($browser->clickLink('New', 1));
|
||||
}
|
||||
|
||||
function testClinkLinkById() {
|
||||
$agent = &new MockSimpleUserAgent();
|
||||
$agent->setReturnReference('fetchResponse', new MockSimpleHttpResponse());
|
||||
$agent->expectArgumentsAt(1, 'fetchResponse', array(
|
||||
new SimpleUrl('http://this.com/link.html'),
|
||||
new SimpleGetEncoding()));
|
||||
$agent->expectCallCount('fetchResponse', 2);
|
||||
|
||||
$page = &new MockSimplePage();
|
||||
$page->setReturnValue('getUrlById', new SimpleUrl('http://this.com/link.html'));
|
||||
$page->expectOnce('getUrlById', array(2));
|
||||
$page->setReturnValue('getRaw', 'A page');
|
||||
|
||||
$browser = &$this->createBrowser($agent, $page);
|
||||
$browser->get('http://this.com/page.html');
|
||||
$this->assertTrue($browser->clickLinkById(2));
|
||||
}
|
||||
|
||||
function testClickingMissingLinkIdFails() {
|
||||
$agent = &new MockSimpleUserAgent();
|
||||
$agent->setReturnReference('fetchResponse', new MockSimpleHttpResponse());
|
||||
|
||||
$page = &new MockSimplePage();
|
||||
$page->setReturnValue('getUrlById', false);
|
||||
|
||||
$browser = &$this->createBrowser($agent, $page);
|
||||
$browser->get('http://this.com/page.html');
|
||||
$this->assertFalse($browser->clickLink(0));
|
||||
}
|
||||
|
||||
function testSubmitFormByLabel() {
|
||||
$agent = &new MockSimpleUserAgent();
|
||||
$agent->setReturnReference('fetchResponse', new MockSimpleHttpResponse());
|
||||
$agent->expectArgumentsAt(1, 'fetchResponse', array(
|
||||
new SimpleUrl('http://this.com/handler.html'),
|
||||
new SimplePostEncoding(array('a' => 'A'))));
|
||||
$agent->expectCallCount('fetchResponse', 2);
|
||||
|
||||
$form = &new MockSimpleForm();
|
||||
$form->setReturnValue('getAction', new SimpleUrl('http://this.com/handler.html'));
|
||||
$form->setReturnValue('getMethod', 'post');
|
||||
$form->setReturnValue('submitButton', new SimplePostEncoding(array('a' => 'A')));
|
||||
$form->expectOnce('submitButton', array(new SimpleByLabel('Go'), false));
|
||||
|
||||
$page = &new MockSimplePage();
|
||||
$page->setReturnReference('getFormBySubmit', $form);
|
||||
$page->expectOnce('getFormBySubmit', array(new SimpleByLabel('Go')));
|
||||
$page->setReturnValue('getRaw', 'stuff');
|
||||
|
||||
$browser = &$this->createBrowser($agent, $page);
|
||||
$browser->get('http://this.com/page.html');
|
||||
$this->assertTrue($browser->clickSubmit('Go'));
|
||||
}
|
||||
|
||||
function testDefaultSubmitFormByLabel() {
|
||||
$agent = &new MockSimpleUserAgent();
|
||||
$agent->setReturnReference('fetchResponse', new MockSimpleHttpResponse());
|
||||
$agent->expectArgumentsAt(1, 'fetchResponse', array(
|
||||
new SimpleUrl('http://this.com/page.html'),
|
||||
new SimpleGetEncoding(array('a' => 'A'))));
|
||||
$agent->expectCallCount('fetchResponse', 2);
|
||||
|
||||
$form = &new MockSimpleForm();
|
||||
$form->setReturnValue('getAction', new SimpleUrl('http://this.com/page.html'));
|
||||
$form->setReturnValue('getMethod', 'get');
|
||||
$form->setReturnValue('submitButton', new SimpleGetEncoding(array('a' => 'A')));
|
||||
|
||||
$page = &new MockSimplePage();
|
||||
$page->setReturnReference('getFormBySubmit', $form);
|
||||
$page->expectOnce('getFormBySubmit', array(new SimpleByLabel('Submit')));
|
||||
$page->setReturnValue('getRaw', 'stuff');
|
||||
$page->setReturnValue('getUrl', new SimpleUrl('http://this.com/page.html'));
|
||||
|
||||
$browser = &$this->createBrowser($agent, $page);
|
||||
$browser->get('http://this.com/page.html');
|
||||
$this->assertTrue($browser->clickSubmit());
|
||||
}
|
||||
|
||||
function testSubmitFormByName() {
|
||||
$agent = &new MockSimpleUserAgent();
|
||||
$agent->setReturnReference('fetchResponse', new MockSimpleHttpResponse());
|
||||
|
||||
$form = &new MockSimpleForm();
|
||||
$form->setReturnValue('getAction', new SimpleUrl('http://this.com/handler.html'));
|
||||
$form->setReturnValue('getMethod', 'post');
|
||||
$form->setReturnValue('submitButton', new SimplePostEncoding(array('a' => 'A')));
|
||||
|
||||
$page = &new MockSimplePage();
|
||||
$page->setReturnReference('getFormBySubmit', $form);
|
||||
$page->expectOnce('getFormBySubmit', array(new SimpleByName('me')));
|
||||
$page->setReturnValue('getRaw', 'stuff');
|
||||
|
||||
$browser = &$this->createBrowser($agent, $page);
|
||||
$browser->get('http://this.com/page.html');
|
||||
$this->assertTrue($browser->clickSubmitByName('me'));
|
||||
}
|
||||
|
||||
function testSubmitFormById() {
|
||||
$agent = &new MockSimpleUserAgent();
|
||||
$agent->setReturnReference('fetchResponse', new MockSimpleHttpResponse());
|
||||
|
||||
$form = &new MockSimpleForm();
|
||||
$form->setReturnValue('getAction', new SimpleUrl('http://this.com/handler.html'));
|
||||
$form->setReturnValue('getMethod', 'post');
|
||||
$form->setReturnValue('submitButton', new SimplePostEncoding(array('a' => 'A')));
|
||||
$form->expectOnce('submitButton', array(new SimpleById(99), false));
|
||||
|
||||
$page = &new MockSimplePage();
|
||||
$page->setReturnReference('getFormBySubmit', $form);
|
||||
$page->expectOnce('getFormBySubmit', array(new SimpleById(99)));
|
||||
$page->setReturnValue('getRaw', 'stuff');
|
||||
|
||||
$browser = &$this->createBrowser($agent, $page);
|
||||
$browser->get('http://this.com/page.html');
|
||||
$this->assertTrue($browser->clickSubmitById(99));
|
||||
}
|
||||
|
||||
function testSubmitFormByImageLabel() {
|
||||
$agent = &new MockSimpleUserAgent();
|
||||
$agent->setReturnReference('fetchResponse', new MockSimpleHttpResponse());
|
||||
|
||||
$form = &new MockSimpleForm();
|
||||
$form->setReturnValue('getAction', new SimpleUrl('http://this.com/handler.html'));
|
||||
$form->setReturnValue('getMethod', 'post');
|
||||
$form->setReturnValue('submitImage', new SimplePostEncoding(array('a' => 'A')));
|
||||
$form->expectOnce('submitImage', array(new SimpleByLabel('Go!'), 10, 11, false));
|
||||
|
||||
$page = &new MockSimplePage();
|
||||
$page->setReturnReference('getFormByImage', $form);
|
||||
$page->expectOnce('getFormByImage', array(new SimpleByLabel('Go!')));
|
||||
$page->setReturnValue('getRaw', 'stuff');
|
||||
|
||||
$browser = &$this->createBrowser($agent, $page);
|
||||
$browser->get('http://this.com/page.html');
|
||||
$this->assertTrue($browser->clickImage('Go!', 10, 11));
|
||||
}
|
||||
|
||||
function testSubmitFormByImageName() {
|
||||
$agent = &new MockSimpleUserAgent();
|
||||
$agent->setReturnReference('fetchResponse', new MockSimpleHttpResponse());
|
||||
|
||||
$form = &new MockSimpleForm();
|
||||
$form->setReturnValue('getAction', new SimpleUrl('http://this.com/handler.html'));
|
||||
$form->setReturnValue('getMethod', 'post');
|
||||
$form->setReturnValue('submitImage', new SimplePostEncoding(array('a' => 'A')));
|
||||
$form->expectOnce('submitImage', array(new SimpleByName('a'), 10, 11, false));
|
||||
|
||||
$page = &new MockSimplePage();
|
||||
$page->setReturnReference('getFormByImage', $form);
|
||||
$page->expectOnce('getFormByImage', array(new SimpleByName('a')));
|
||||
$page->setReturnValue('getRaw', 'stuff');
|
||||
|
||||
$browser = &$this->createBrowser($agent, $page);
|
||||
$browser->get('http://this.com/page.html');
|
||||
$this->assertTrue($browser->clickImageByName('a', 10, 11));
|
||||
}
|
||||
|
||||
function testSubmitFormByImageId() {
|
||||
$agent = &new MockSimpleUserAgent();
|
||||
$agent->setReturnReference('fetchResponse', new MockSimpleHttpResponse());
|
||||
|
||||
$form = &new MockSimpleForm();
|
||||
$form->setReturnValue('getAction', new SimpleUrl('http://this.com/handler.html'));
|
||||
$form->setReturnValue('getMethod', 'post');
|
||||
$form->setReturnValue('submitImage', new SimplePostEncoding(array('a' => 'A')));
|
||||
$form->expectOnce('submitImage', array(new SimpleById(99), 10, 11, false));
|
||||
|
||||
$page = &new MockSimplePage();
|
||||
$page->setReturnReference('getFormByImage', $form);
|
||||
$page->expectOnce('getFormByImage', array(new SimpleById(99)));
|
||||
$page->setReturnValue('getRaw', 'stuff');
|
||||
|
||||
$browser = &$this->createBrowser($agent, $page);
|
||||
$browser->get('http://this.com/page.html');
|
||||
$this->assertTrue($browser->clickImageById(99, 10, 11));
|
||||
}
|
||||
|
||||
function testSubmitFormByFormId() {
|
||||
$agent = &new MockSimpleUserAgent();
|
||||
$agent->setReturnReference('fetchResponse', new MockSimpleHttpResponse());
|
||||
$agent->expectArgumentsAt(1, 'fetchResponse', array(
|
||||
new SimpleUrl('http://this.com/handler.html'),
|
||||
new SimplePostEncoding(array('a' => 'A'))));
|
||||
$agent->expectCallCount('fetchResponse', 2);
|
||||
|
||||
$form = &new MockSimpleForm();
|
||||
$form->setReturnValue('getAction', new SimpleUrl('http://this.com/handler.html'));
|
||||
$form->setReturnValue('getMethod', 'post');
|
||||
$form->setReturnValue('submit', new SimplePostEncoding(array('a' => 'A')));
|
||||
|
||||
$page = &new MockSimplePage();
|
||||
$page->setReturnReference('getFormById', $form);
|
||||
$page->expectOnce('getFormById', array(33));
|
||||
$page->setReturnValue('getRaw', 'stuff');
|
||||
|
||||
$browser = &$this->createBrowser($agent, $page);
|
||||
$browser->get('http://this.com/page.html');
|
||||
$this->assertTrue($browser->submitFormById(33));
|
||||
}
|
||||
}
|
||||
|
||||
class TestOfBrowserFrames extends UnitTestCase {
|
||||
|
||||
function &createBrowser(&$agent) {
|
||||
$browser = &new MockUserAgentSimpleBrowser();
|
||||
$browser->setReturnReference('_createUserAgent', $agent);
|
||||
$browser->SimpleBrowser();
|
||||
return $browser;
|
||||
}
|
||||
|
||||
function &createUserAgent($pages) {
|
||||
$agent = &new MockSimpleUserAgent();
|
||||
foreach ($pages as $url => $raw) {
|
||||
$url = new SimpleUrl($url);
|
||||
$response = &new MockSimpleHttpResponse();
|
||||
$response->setReturnValue('getUrl', $url);
|
||||
$response->setReturnValue('getContent', $raw);
|
||||
$agent->setReturnReference('fetchResponse', $response, array($url, '*'));
|
||||
}
|
||||
return $agent;
|
||||
}
|
||||
|
||||
function testSimplePageHasNoFrames() {
|
||||
$browser = &$this->createBrowser($this->createUserAgent(
|
||||
array('http://site.with.no.frames/' => 'A non-framed page')));
|
||||
$this->assertEqual(
|
||||
$browser->get('http://site.with.no.frames/'),
|
||||
'A non-framed page');
|
||||
$this->assertIdentical($browser->getFrames(), 'http://site.with.no.frames/');
|
||||
}
|
||||
|
||||
function testFramesetWithNoFrames() {
|
||||
$browser = &$this->createBrowser($this->createUserAgent(
|
||||
array('http://site.with.no.frames/' => '<frameset></frameset>')));
|
||||
$this->assertEqual($browser->get('http://site.with.no.frames/'), '');
|
||||
$this->assertIdentical($browser->getFrames(), array());
|
||||
}
|
||||
|
||||
function testFramesetWithSingleFrame() {
|
||||
$frameset = '<frameset><frame name="a" src="frame.html"></frameset>';
|
||||
$browser = &$this->createBrowser($this->createUserAgent(array(
|
||||
'http://site.with.one.frame/' => $frameset,
|
||||
'http://site.with.one.frame/frame.html' => 'A frame')));
|
||||
$this->assertEqual($browser->get('http://site.with.one.frame/'), 'A frame');
|
||||
$this->assertIdentical(
|
||||
$browser->getFrames(),
|
||||
array('a' => 'http://site.with.one.frame/frame.html'));
|
||||
}
|
||||
|
||||
function testTitleTakenFromFramesetPage() {
|
||||
$frameset = '<title>Frameset title</title>' .
|
||||
'<frameset><frame name="a" src="frame.html"></frameset>';
|
||||
$browser = &$this->createBrowser($this->createUserAgent(array(
|
||||
'http://site.with.one.frame/' => $frameset,
|
||||
'http://site.with.one.frame/frame.html' => '<title>Page title</title>')));
|
||||
$browser->get('http://site.with.one.frame/');
|
||||
$this->assertEqual($browser->getTitle(), 'Frameset title');
|
||||
}
|
||||
|
||||
function testFramesetWithSingleUnnamedFrame() {
|
||||
$frameset = '<frameset><frame src="frame.html"></frameset>';
|
||||
$browser = &$this->createBrowser($this->createUserAgent(array(
|
||||
'http://site.with.one.frame/' => $frameset,
|
||||
'http://site.with.one.frame/frame.html' => 'One frame')));
|
||||
$this->assertEqual(
|
||||
$browser->get('http://site.with.one.frame/'),
|
||||
'One frame');
|
||||
$this->assertIdentical(
|
||||
$browser->getFrames(),
|
||||
array(1 => 'http://site.with.one.frame/frame.html'));
|
||||
}
|
||||
|
||||
function testFramesetWithMultipleFrames() {
|
||||
$frameset = '<frameset>' .
|
||||
'<frame name="a" src="frame_a.html">' .
|
||||
'<frame name="b" src="frame_b.html">' .
|
||||
'<frame name="c" src="frame_c.html">' .
|
||||
'</frameset>';
|
||||
$browser = &$this->createBrowser($this->createUserAgent(array(
|
||||
'http://site.with.frames/' => $frameset,
|
||||
'http://site.with.frames/frame_a.html' => 'A frame',
|
||||
'http://site.with.frames/frame_b.html' => 'B frame',
|
||||
'http://site.with.frames/frame_c.html' => 'C frame')));
|
||||
$this->assertEqual(
|
||||
$browser->get('http://site.with.frames/'),
|
||||
'A frameB frameC frame');
|
||||
$this->assertIdentical($browser->getFrames(), array(
|
||||
'a' => 'http://site.with.frames/frame_a.html',
|
||||
'b' => 'http://site.with.frames/frame_b.html',
|
||||
'c' => 'http://site.with.frames/frame_c.html'));
|
||||
}
|
||||
|
||||
function testFrameFocusByName() {
|
||||
$frameset = '<frameset>' .
|
||||
'<frame name="a" src="frame_a.html">' .
|
||||
'<frame name="b" src="frame_b.html">' .
|
||||
'<frame name="c" src="frame_c.html">' .
|
||||
'</frameset>';
|
||||
$browser = &$this->createBrowser($this->createUserAgent(array(
|
||||
'http://site.with.frames/' => $frameset,
|
||||
'http://site.with.frames/frame_a.html' => 'A frame',
|
||||
'http://site.with.frames/frame_b.html' => 'B frame',
|
||||
'http://site.with.frames/frame_c.html' => 'C frame')));
|
||||
$browser->get('http://site.with.frames/');
|
||||
$browser->setFrameFocus('a');
|
||||
$this->assertEqual($browser->getContent(), 'A frame');
|
||||
$browser->setFrameFocus('b');
|
||||
$this->assertEqual($browser->getContent(), 'B frame');
|
||||
$browser->setFrameFocus('c');
|
||||
$this->assertEqual($browser->getContent(), 'C frame');
|
||||
}
|
||||
|
||||
function testFramesetWithSomeNamedFrames() {
|
||||
$frameset = '<frameset>' .
|
||||
'<frame name="a" src="frame_a.html">' .
|
||||
'<frame src="frame_b.html">' .
|
||||
'<frame name="c" src="frame_c.html">' .
|
||||
'<frame src="frame_d.html">' .
|
||||
'</frameset>';
|
||||
$browser = &$this->createBrowser($this->createUserAgent(array(
|
||||
'http://site.with.frames/' => $frameset,
|
||||
'http://site.with.frames/frame_a.html' => 'A frame',
|
||||
'http://site.with.frames/frame_b.html' => 'B frame',
|
||||
'http://site.with.frames/frame_c.html' => 'C frame',
|
||||
'http://site.with.frames/frame_d.html' => 'D frame')));
|
||||
$this->assertEqual(
|
||||
$browser->get('http://site.with.frames/'),
|
||||
'A frameB frameC frameD frame');
|
||||
$this->assertIdentical($browser->getFrames(), array(
|
||||
'a' => 'http://site.with.frames/frame_a.html',
|
||||
2 => 'http://site.with.frames/frame_b.html',
|
||||
'c' => 'http://site.with.frames/frame_c.html',
|
||||
4 => 'http://site.with.frames/frame_d.html'));
|
||||
}
|
||||
|
||||
function testFrameFocusWithMixedNamesAndIndexes() {
|
||||
$frameset = '<frameset>' .
|
||||
'<frame name="a" src="frame_a.html">' .
|
||||
'<frame src="frame_b.html">' .
|
||||
'<frame name="c" src="frame_c.html">' .
|
||||
'<frame src="frame_d.html">' .
|
||||
'</frameset>';
|
||||
$browser = &$this->createBrowser($this->createUserAgent(array(
|
||||
'http://site.with.frames/' => $frameset,
|
||||
'http://site.with.frames/frame_a.html' => 'A frame',
|
||||
'http://site.with.frames/frame_b.html' => 'B frame',
|
||||
'http://site.with.frames/frame_c.html' => 'C frame',
|
||||
'http://site.with.frames/frame_d.html' => 'D frame')));
|
||||
$browser->get('http://site.with.frames/');
|
||||
$browser->setFrameFocus('a');
|
||||
$this->assertEqual($browser->getContent(), 'A frame');
|
||||
$browser->setFrameFocus(2);
|
||||
$this->assertEqual($browser->getContent(), 'B frame');
|
||||
$browser->setFrameFocus('c');
|
||||
$this->assertEqual($browser->getContent(), 'C frame');
|
||||
$browser->setFrameFocus(4);
|
||||
$this->assertEqual($browser->getContent(), 'D frame');
|
||||
$browser->clearFrameFocus();
|
||||
$this->assertEqual($browser->getContent(), 'A frameB frameC frameD frame');
|
||||
}
|
||||
|
||||
function testNestedFrameset() {
|
||||
$inner = '<frameset>' .
|
||||
'<frame name="page" src="page.html">' .
|
||||
'</frameset>';
|
||||
$outer = '<frameset>' .
|
||||
'<frame name="inner" src="inner.html">' .
|
||||
'</frameset>';
|
||||
$browser = &$this->createBrowser($this->createUserAgent(array(
|
||||
'http://site.with.nested.frame/' => $outer,
|
||||
'http://site.with.nested.frame/inner.html' => $inner,
|
||||
'http://site.with.nested.frame/page.html' => 'The page')));
|
||||
$this->assertEqual(
|
||||
$browser->get('http://site.with.nested.frame/'),
|
||||
'The page');
|
||||
$this->assertIdentical($browser->getFrames(), array(
|
||||
'inner' => array(
|
||||
'page' => 'http://site.with.nested.frame/page.html')));
|
||||
}
|
||||
|
||||
function testCanNavigateToNestedFrame() {
|
||||
$inner = '<frameset>' .
|
||||
'<frame name="one" src="one.html">' .
|
||||
'<frame name="two" src="two.html">' .
|
||||
'</frameset>';
|
||||
$outer = '<frameset>' .
|
||||
'<frame name="inner" src="inner.html">' .
|
||||
'<frame name="three" src="three.html">' .
|
||||
'</frameset>';
|
||||
$browser = &$this->createBrowser($this->createUserAgent(array(
|
||||
'http://site.with.nested.frames/' => $outer,
|
||||
'http://site.with.nested.frames/inner.html' => $inner,
|
||||
'http://site.with.nested.frames/one.html' => 'Page one',
|
||||
'http://site.with.nested.frames/two.html' => 'Page two',
|
||||
'http://site.with.nested.frames/three.html' => 'Page three')));
|
||||
|
||||
$browser->get('http://site.with.nested.frames/');
|
||||
$this->assertEqual($browser->getContent(), 'Page onePage twoPage three');
|
||||
|
||||
$this->assertTrue($browser->setFrameFocus('inner'));
|
||||
$this->assertEqual($browser->getFrameFocus(), array('inner'));
|
||||
$this->assertTrue($browser->setFrameFocus('one'));
|
||||
$this->assertEqual($browser->getFrameFocus(), array('inner', 'one'));
|
||||
$this->assertEqual($browser->getContent(), 'Page one');
|
||||
|
||||
$this->assertTrue($browser->setFrameFocus('two'));
|
||||
$this->assertEqual($browser->getFrameFocus(), array('inner', 'two'));
|
||||
$this->assertEqual($browser->getContent(), 'Page two');
|
||||
|
||||
$browser->clearFrameFocus();
|
||||
$this->assertTrue($browser->setFrameFocus('three'));
|
||||
$this->assertEqual($browser->getFrameFocus(), array('three'));
|
||||
$this->assertEqual($browser->getContent(), 'Page three');
|
||||
|
||||
$this->assertTrue($browser->setFrameFocus('inner'));
|
||||
$this->assertEqual($browser->getContent(), 'Page onePage two');
|
||||
}
|
||||
|
||||
function testCanNavigateToNestedFrameByIndex() {
|
||||
$inner = '<frameset>' .
|
||||
'<frame src="one.html">' .
|
||||
'<frame src="two.html">' .
|
||||
'</frameset>';
|
||||
$outer = '<frameset>' .
|
||||
'<frame src="inner.html">' .
|
||||
'<frame src="three.html">' .
|
||||
'</frameset>';
|
||||
$browser = &$this->createBrowser($this->createUserAgent(array(
|
||||
'http://site.with.nested.frames/' => $outer,
|
||||
'http://site.with.nested.frames/inner.html' => $inner,
|
||||
'http://site.with.nested.frames/one.html' => 'Page one',
|
||||
'http://site.with.nested.frames/two.html' => 'Page two',
|
||||
'http://site.with.nested.frames/three.html' => 'Page three')));
|
||||
|
||||
$browser->get('http://site.with.nested.frames/');
|
||||
$this->assertEqual($browser->getContent(), 'Page onePage twoPage three');
|
||||
|
||||
$this->assertTrue($browser->setFrameFocusByIndex(1));
|
||||
$this->assertEqual($browser->getFrameFocus(), array(1));
|
||||
$this->assertTrue($browser->setFrameFocusByIndex(1));
|
||||
$this->assertEqual($browser->getFrameFocus(), array(1, 1));
|
||||
$this->assertEqual($browser->getContent(), 'Page one');
|
||||
|
||||
$this->assertTrue($browser->setFrameFocusByIndex(2));
|
||||
$this->assertEqual($browser->getFrameFocus(), array(1, 2));
|
||||
$this->assertEqual($browser->getContent(), 'Page two');
|
||||
|
||||
$browser->clearFrameFocus();
|
||||
$this->assertTrue($browser->setFrameFocusByIndex(2));
|
||||
$this->assertEqual($browser->getFrameFocus(), array(2));
|
||||
$this->assertEqual($browser->getContent(), 'Page three');
|
||||
|
||||
$this->assertTrue($browser->setFrameFocusByIndex(1));
|
||||
$this->assertEqual($browser->getContent(), 'Page onePage two');
|
||||
}
|
||||
}
|
||||
?>
|
||||
51
tests/simpletest/test/collector_test.php
Normal file
51
tests/simpletest/test/collector_test.php
Normal file
|
|
@ -0,0 +1,51 @@
|
|||
<?php
|
||||
// $Id: collector_test.php 1505 2007-04-30 23:39:59Z lastcraft $
|
||||
require_once(dirname(__FILE__) . '/../autorun.php');
|
||||
require_once(dirname(__FILE__) . '/../collector.php');
|
||||
SimpleTest::ignore('MockTestSuite');
|
||||
Mock::generate('TestSuite');
|
||||
|
||||
class PathEqualExpectation extends EqualExpectation {
|
||||
function PathEqualExpectation($value, $message = '%s') {
|
||||
$this->EqualExpectation(str_replace("\\", '/', $value), $message);
|
||||
}
|
||||
|
||||
function test($compare) {
|
||||
return parent::test(str_replace("\\", '/', $compare));
|
||||
}
|
||||
}
|
||||
|
||||
class TestOfCollector extends UnitTestCase {
|
||||
|
||||
function testCollectionIsAddedToGroup() {
|
||||
$suite = &new MockTestSuite();
|
||||
$suite->expectMinimumCallCount('addTestFile', 2);
|
||||
$suite->expectArguments(
|
||||
'addTestFile',
|
||||
array(new PatternExpectation('/collectable\\.(1|2)$/')));
|
||||
$collector = &new SimpleCollector();
|
||||
$collector->collect($suite, dirname(__FILE__) . '/support/collector/');
|
||||
}
|
||||
}
|
||||
|
||||
class TestOfPatternCollector extends UnitTestCase {
|
||||
|
||||
function testAddingEverythingToGroup() {
|
||||
$suite = &new MockTestSuite();
|
||||
$suite->expectCallCount('addTestFile', 2);
|
||||
$suite->expectArguments(
|
||||
'addTestFile',
|
||||
array(new PatternExpectation('/collectable\\.(1|2)$/')));
|
||||
$collector = &new SimplePatternCollector('/.*/');
|
||||
$collector->collect($suite, dirname(__FILE__) . '/support/collector/');
|
||||
}
|
||||
|
||||
function testOnlyMatchedFilesAreAddedToGroup() {
|
||||
$suite = &new MockTestSuite();
|
||||
$suite->expectOnce('addTestFile', array(new PathEqualExpectation(
|
||||
dirname(__FILE__) . '/support/collector/collectable.1')));
|
||||
$collector = &new SimplePatternCollector('/1$/');
|
||||
$collector->collect($suite, dirname(__FILE__) . '/support/collector/');
|
||||
}
|
||||
}
|
||||
?>
|
||||
40
tests/simpletest/test/command_line_test.php
Normal file
40
tests/simpletest/test/command_line_test.php
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
<?php
|
||||
require_once(dirname(__FILE__) . '/../autorun.php');
|
||||
require_once(dirname(__FILE__) . '/../default_reporter.php');
|
||||
|
||||
class TestOfCommandLineParsing extends UnitTestCase {
|
||||
|
||||
function testDefaultsToEmptyStringToMeanNullToTheSelectiveReporter() {
|
||||
$parser = new SimpleCommandLineParser(array());
|
||||
$this->assertIdentical($parser->getTest(), '');
|
||||
$this->assertIdentical($parser->getTestCase(), '');
|
||||
}
|
||||
|
||||
function testNotXmlByDefault() {
|
||||
$parser = new SimpleCommandLineParser(array());
|
||||
$this->assertFalse($parser->isXml());
|
||||
}
|
||||
|
||||
function testCanDetectRequestForXml() {
|
||||
$parser = new SimpleCommandLineParser(array('--xml'));
|
||||
$this->assertTrue($parser->isXml());
|
||||
}
|
||||
|
||||
function testCanReadAssignmentSyntax() {
|
||||
$parser = new SimpleCommandLineParser(array('--test=myTest'));
|
||||
$this->assertEqual($parser->getTest(), 'myTest');
|
||||
}
|
||||
|
||||
function testCanReadFollowOnSyntax() {
|
||||
$parser = new SimpleCommandLineParser(array('--test', 'myTest'));
|
||||
$this->assertEqual($parser->getTest(), 'myTest');
|
||||
}
|
||||
|
||||
function testCanReadShortForms() {
|
||||
$parser = new SimpleCommandLineParser(array('-t', 'myTest', '-c', 'MyClass', '-x'));
|
||||
$this->assertEqual($parser->getTest(), 'myTest');
|
||||
$this->assertEqual($parser->getTestCase(), 'MyClass');
|
||||
$this->assertTrue($parser->isXml());
|
||||
}
|
||||
}
|
||||
?>
|
||||
97
tests/simpletest/test/compatibility_test.php
Normal file
97
tests/simpletest/test/compatibility_test.php
Normal file
|
|
@ -0,0 +1,97 @@
|
|||
<?php
|
||||
// $Id: compatibility_test.php 1505 2007-04-30 23:39:59Z lastcraft $
|
||||
require_once(dirname(__FILE__) . '/../autorun.php');
|
||||
require_once(dirname(__FILE__) . '/../compatibility.php');
|
||||
|
||||
class ComparisonClass {
|
||||
}
|
||||
|
||||
class ComparisonSubclass extends ComparisonClass {
|
||||
}
|
||||
|
||||
if (version_compare(phpversion(), '5') >= 0) {
|
||||
eval('interface ComparisonInterface { }');
|
||||
eval('class ComparisonClassWithInterface implements ComparisonInterface { }');
|
||||
}
|
||||
|
||||
class TestOfCompatibility extends UnitTestCase {
|
||||
|
||||
function testIsA() {
|
||||
$this->assertTrue(SimpleTestCompatibility::isA(
|
||||
new ComparisonClass(),
|
||||
'ComparisonClass'));
|
||||
$this->assertFalse(SimpleTestCompatibility::isA(
|
||||
new ComparisonClass(),
|
||||
'ComparisonSubclass'));
|
||||
$this->assertTrue(SimpleTestCompatibility::isA(
|
||||
new ComparisonSubclass(),
|
||||
'ComparisonClass'));
|
||||
}
|
||||
|
||||
function testIdentityOfNumericStrings() {
|
||||
$numericString1 = "123";
|
||||
$numericString2 = "00123";
|
||||
$this->assertNotIdentical($numericString1, $numericString2);
|
||||
}
|
||||
|
||||
function testIdentityOfObjects() {
|
||||
$object1 = new ComparisonClass();
|
||||
$object2 = new ComparisonClass();
|
||||
$this->assertIdentical($object1, $object2);
|
||||
}
|
||||
|
||||
function testReferences () {
|
||||
$thing = "Hello";
|
||||
$thing_reference = &$thing;
|
||||
$thing_copy = $thing;
|
||||
$this->assertTrue(SimpleTestCompatibility::isReference(
|
||||
$thing,
|
||||
$thing));
|
||||
$this->assertTrue(SimpleTestCompatibility::isReference(
|
||||
$thing,
|
||||
$thing_reference));
|
||||
$this->assertFalse(SimpleTestCompatibility::isReference(
|
||||
$thing,
|
||||
$thing_copy));
|
||||
}
|
||||
|
||||
function testObjectReferences () {
|
||||
$object = &new ComparisonClass();
|
||||
$object_reference = &$object;
|
||||
$object_copy = new ComparisonClass();
|
||||
$object_assignment = $object;
|
||||
$this->assertTrue(SimpleTestCompatibility::isReference(
|
||||
$object,
|
||||
$object));
|
||||
$this->assertTrue(SimpleTestCompatibility::isReference(
|
||||
$object,
|
||||
$object_reference));
|
||||
$this->assertFalse(SimpleTestCompatibility::isReference(
|
||||
$object,
|
||||
$object_copy));
|
||||
if (version_compare(phpversion(), '5', '>=')) {
|
||||
$this->assertTrue(SimpleTestCompatibility::isReference(
|
||||
$object,
|
||||
$object_assignment));
|
||||
} else {
|
||||
$this->assertFalse(SimpleTestCompatibility::isReference(
|
||||
$object,
|
||||
$object_assignment));
|
||||
}
|
||||
}
|
||||
|
||||
function testInteraceComparison() {
|
||||
if (version_compare(phpversion(), '5', '<')) {
|
||||
return;
|
||||
}
|
||||
|
||||
$object = new ComparisonClassWithInterface();
|
||||
$this->assertFalse(SimpleTestCompatibility::isA(
|
||||
new ComparisonClass(),
|
||||
'ComparisonInterface'));
|
||||
$this->assertTrue(SimpleTestCompatibility::isA(
|
||||
new ComparisonClassWithInterface(),
|
||||
'ComparisonInterface'));
|
||||
}
|
||||
}
|
||||
?>
|
||||
227
tests/simpletest/test/cookies_test.php
Normal file
227
tests/simpletest/test/cookies_test.php
Normal file
|
|
@ -0,0 +1,227 @@
|
|||
<?php
|
||||
// $Id: cookies_test.php 1506 2007-05-07 00:58:03Z lastcraft $
|
||||
require_once(dirname(__FILE__) . '/../autorun.php');
|
||||
require_once(dirname(__FILE__) . '/../cookies.php');
|
||||
|
||||
class TestOfCookie extends UnitTestCase {
|
||||
|
||||
function testCookieDefaults() {
|
||||
$cookie = new SimpleCookie("name");
|
||||
$this->assertFalse($cookie->getValue());
|
||||
$this->assertEqual($cookie->getPath(), "/");
|
||||
$this->assertIdentical($cookie->getHost(), false);
|
||||
$this->assertFalse($cookie->getExpiry());
|
||||
$this->assertFalse($cookie->isSecure());
|
||||
}
|
||||
|
||||
function testCookieAccessors() {
|
||||
$cookie = new SimpleCookie(
|
||||
"name",
|
||||
"value",
|
||||
"/path",
|
||||
"Mon, 18 Nov 2002 15:50:29 GMT",
|
||||
true);
|
||||
$this->assertEqual($cookie->getName(), "name");
|
||||
$this->assertEqual($cookie->getValue(), "value");
|
||||
$this->assertEqual($cookie->getPath(), "/path/");
|
||||
$this->assertEqual($cookie->getExpiry(), "Mon, 18 Nov 2002 15:50:29 GMT");
|
||||
$this->assertTrue($cookie->isSecure());
|
||||
}
|
||||
|
||||
function testFullHostname() {
|
||||
$cookie = new SimpleCookie("name");
|
||||
$this->assertTrue($cookie->setHost("host.name.here"));
|
||||
$this->assertEqual($cookie->getHost(), "host.name.here");
|
||||
$this->assertTrue($cookie->setHost("host.com"));
|
||||
$this->assertEqual($cookie->getHost(), "host.com");
|
||||
}
|
||||
|
||||
function testHostTruncation() {
|
||||
$cookie = new SimpleCookie("name");
|
||||
$cookie->setHost("this.host.name.here");
|
||||
$this->assertEqual($cookie->getHost(), "host.name.here");
|
||||
$cookie->setHost("this.host.com");
|
||||
$this->assertEqual($cookie->getHost(), "host.com");
|
||||
$this->assertTrue($cookie->setHost("dashes.in-host.com"));
|
||||
$this->assertEqual($cookie->getHost(), "in-host.com");
|
||||
}
|
||||
|
||||
function testBadHosts() {
|
||||
$cookie = new SimpleCookie("name");
|
||||
$this->assertFalse($cookie->setHost("gibberish"));
|
||||
$this->assertFalse($cookie->setHost("host.here"));
|
||||
$this->assertFalse($cookie->setHost("host..com"));
|
||||
$this->assertFalse($cookie->setHost("..."));
|
||||
$this->assertFalse($cookie->setHost("host.com."));
|
||||
}
|
||||
|
||||
function testHostValidity() {
|
||||
$cookie = new SimpleCookie("name");
|
||||
$cookie->setHost("this.host.name.here");
|
||||
$this->assertTrue($cookie->isValidHost("host.name.here"));
|
||||
$this->assertTrue($cookie->isValidHost("that.host.name.here"));
|
||||
$this->assertFalse($cookie->isValidHost("bad.host"));
|
||||
$this->assertFalse($cookie->isValidHost("nearly.name.here"));
|
||||
}
|
||||
|
||||
function testPathValidity() {
|
||||
$cookie = new SimpleCookie("name", "value", "/path");
|
||||
$this->assertFalse($cookie->isValidPath("/"));
|
||||
$this->assertTrue($cookie->isValidPath("/path/"));
|
||||
$this->assertTrue($cookie->isValidPath("/path/more"));
|
||||
}
|
||||
|
||||
function testSessionExpiring() {
|
||||
$cookie = new SimpleCookie("name", "value", "/path");
|
||||
$this->assertTrue($cookie->isExpired(0));
|
||||
}
|
||||
|
||||
function testTimestampExpiry() {
|
||||
$cookie = new SimpleCookie("name", "value", "/path", 456);
|
||||
$this->assertFalse($cookie->isExpired(0));
|
||||
$this->assertTrue($cookie->isExpired(457));
|
||||
$this->assertFalse($cookie->isExpired(455));
|
||||
}
|
||||
|
||||
function testDateExpiry() {
|
||||
$cookie = new SimpleCookie(
|
||||
"name",
|
||||
"value",
|
||||
"/path",
|
||||
"Mon, 18 Nov 2002 15:50:29 GMT");
|
||||
$this->assertTrue($cookie->isExpired("Mon, 18 Nov 2002 15:50:30 GMT"));
|
||||
$this->assertFalse($cookie->isExpired("Mon, 18 Nov 2002 15:50:28 GMT"));
|
||||
}
|
||||
|
||||
function testAging() {
|
||||
$cookie = new SimpleCookie("name", "value", "/path", 200);
|
||||
$cookie->agePrematurely(199);
|
||||
$this->assertFalse($cookie->isExpired(0));
|
||||
$cookie->agePrematurely(2);
|
||||
$this->assertTrue($cookie->isExpired(0));
|
||||
}
|
||||
}
|
||||
|
||||
class TestOfCookieJar extends UnitTestCase {
|
||||
|
||||
function testAddCookie() {
|
||||
$jar = new SimpleCookieJar();
|
||||
$jar->setCookie("a", "A");
|
||||
$this->assertEqual($jar->selectAsPairs(new SimpleUrl('/')), array('a=A'));
|
||||
}
|
||||
|
||||
function testHostFilter() {
|
||||
$jar = new SimpleCookieJar();
|
||||
$jar->setCookie('a', 'A', 'my-host.com');
|
||||
$jar->setCookie('b', 'B', 'another-host.com');
|
||||
$jar->setCookie('c', 'C');
|
||||
$this->assertEqual(
|
||||
$jar->selectAsPairs(new SimpleUrl('my-host.com')),
|
||||
array('a=A', 'c=C'));
|
||||
$this->assertEqual(
|
||||
$jar->selectAsPairs(new SimpleUrl('another-host.com')),
|
||||
array('b=B', 'c=C'));
|
||||
$this->assertEqual(
|
||||
$jar->selectAsPairs(new SimpleUrl('www.another-host.com')),
|
||||
array('b=B', 'c=C'));
|
||||
$this->assertEqual(
|
||||
$jar->selectAsPairs(new SimpleUrl('new-host.org')),
|
||||
array('c=C'));
|
||||
$this->assertEqual(
|
||||
$jar->selectAsPairs(new SimpleUrl('/')),
|
||||
array('a=A', 'b=B', 'c=C'));
|
||||
}
|
||||
|
||||
function testPathFilter() {
|
||||
$jar = new SimpleCookieJar();
|
||||
$jar->setCookie('a', 'A', false, '/path/');
|
||||
$this->assertEqual($jar->selectAsPairs(new SimpleUrl('/')), array());
|
||||
$this->assertEqual($jar->selectAsPairs(new SimpleUrl('/elsewhere')), array());
|
||||
$this->assertEqual($jar->selectAsPairs(new SimpleUrl('/path/')), array('a=A'));
|
||||
$this->assertEqual($jar->selectAsPairs(new SimpleUrl('/path')), array('a=A'));
|
||||
$this->assertEqual($jar->selectAsPairs(new SimpleUrl('/pa')), array());
|
||||
$this->assertEqual($jar->selectAsPairs(new SimpleUrl('/path/here')), array('a=A'));
|
||||
}
|
||||
|
||||
function testPathFilterDeeply() {
|
||||
$jar = new SimpleCookieJar();
|
||||
$jar->setCookie('a', 'A', false, '/path/more_path/');
|
||||
$this->assertEqual($jar->selectAsPairs(new SimpleUrl('/path/')), array());
|
||||
$this->assertEqual($jar->selectAsPairs(new SimpleUrl('/path')), array());
|
||||
$this->assertEqual($jar->selectAsPairs(new SimpleUrl('/pa')), array());
|
||||
$this->assertEqual($jar->selectAsPairs(new SimpleUrl('/path/more_path/')), array('a=A'));
|
||||
$this->assertEqual($jar->selectAsPairs(new SimpleUrl('/path/more_path/and_more')), array('a=A'));
|
||||
$this->assertEqual($jar->selectAsPairs(new SimpleUrl('/path/not_here/')), array());
|
||||
}
|
||||
|
||||
function testMultipleCookieWithDifferentPathsButSameName() {
|
||||
$jar = new SimpleCookieJar();
|
||||
$jar->setCookie('a', 'abc', false, '/');
|
||||
$jar->setCookie('a', '123', false, '/path/here/');
|
||||
$this->assertEqual(
|
||||
$jar->selectAsPairs(new SimpleUrl('/')),
|
||||
array('a=abc'));
|
||||
$this->assertEqual(
|
||||
$jar->selectAsPairs(new SimpleUrl('my-host.com/')),
|
||||
array('a=abc'));
|
||||
$this->assertEqual(
|
||||
$jar->selectAsPairs(new SimpleUrl('my-host.com/path/')),
|
||||
array('a=abc'));
|
||||
$this->assertEqual(
|
||||
$jar->selectAsPairs(new SimpleUrl('my-host.com/path/here')),
|
||||
array('a=abc', 'a=123'));
|
||||
$this->assertEqual(
|
||||
$jar->selectAsPairs(new SimpleUrl('my-host.com/path/here/there')),
|
||||
array('a=abc', 'a=123'));
|
||||
}
|
||||
|
||||
function testOverwrite() {
|
||||
$jar = new SimpleCookieJar();
|
||||
$jar->setCookie('a', 'abc', false, '/');
|
||||
$jar->setCookie('a', 'cde', false, '/');
|
||||
$this->assertEqual($jar->selectAsPairs(new SimpleUrl('/')), array('a=cde'));
|
||||
}
|
||||
|
||||
function testClearSessionCookies() {
|
||||
$jar = new SimpleCookieJar();
|
||||
$jar->setCookie('a', 'A', false, '/');
|
||||
$jar->restartSession();
|
||||
$this->assertEqual($jar->selectAsPairs(new SimpleUrl('/')), array());
|
||||
}
|
||||
|
||||
function testExpiryFilterByDate() {
|
||||
$jar = new SimpleCookieJar();
|
||||
$jar->setCookie('a', 'A', false, '/', 'Wed, 25-Dec-02 04:24:20 GMT');
|
||||
$jar->restartSession("Wed, 25-Dec-02 04:24:19 GMT");
|
||||
$this->assertEqual($jar->selectAsPairs(new SimpleUrl('/')), array('a=A'));
|
||||
$jar->restartSession("Wed, 25-Dec-02 04:24:21 GMT");
|
||||
$this->assertEqual($jar->selectAsPairs(new SimpleUrl('/')), array());
|
||||
}
|
||||
|
||||
function testExpiryFilterByAgeing() {
|
||||
$jar = new SimpleCookieJar();
|
||||
$jar->setCookie('a', 'A', false, '/', 'Wed, 25-Dec-02 04:24:20 GMT');
|
||||
$jar->restartSession("Wed, 25-Dec-02 04:24:19 GMT");
|
||||
$this->assertEqual($jar->selectAsPairs(new SimpleUrl('/')), array('a=A'));
|
||||
$jar->agePrematurely(2);
|
||||
$jar->restartSession("Wed, 25-Dec-02 04:24:19 GMT");
|
||||
$this->assertEqual($jar->selectAsPairs(new SimpleUrl('/')), array());
|
||||
}
|
||||
|
||||
function testCookieClearing() {
|
||||
$jar = new SimpleCookieJar();
|
||||
$jar->setCookie('a', 'abc', false, '/');
|
||||
$jar->setCookie('a', '', false, '/');
|
||||
$this->assertEqual($jar->selectAsPairs(new SimpleUrl('/')), array('a='));
|
||||
}
|
||||
|
||||
function testCookieClearByLoweringDate() {
|
||||
$jar = new SimpleCookieJar();
|
||||
$jar->setCookie('a', 'abc', false, '/', 'Wed, 25-Dec-02 04:24:21 GMT');
|
||||
$jar->setCookie('a', 'def', false, '/', 'Wed, 25-Dec-02 04:24:19 GMT');
|
||||
$this->assertEqual($jar->selectAsPairs(new SimpleUrl('/')), array('a=def'));
|
||||
$jar->restartSession('Wed, 25-Dec-02 04:24:20 GMT');
|
||||
$this->assertEqual($jar->selectAsPairs(new SimpleUrl('/')), array());
|
||||
}
|
||||
}
|
||||
?>
|
||||
15
tests/simpletest/test/detached_test.php
Normal file
15
tests/simpletest/test/detached_test.php
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
<?php
|
||||
// $Id: detached_test.php 1505 2007-04-30 23:39:59Z lastcraft $
|
||||
require_once('../detached.php');
|
||||
require_once('../reporter.php');
|
||||
|
||||
// The following URL will depend on your own installation.
|
||||
$command = 'php ' . dirname(__FILE__) . '/visual_test.php xml';
|
||||
|
||||
$test = &new TestSuite('Remote tests');
|
||||
$test->addTestCase(new DetachedTestCase($command));
|
||||
if (SimpleReporter::inCli()) {
|
||||
exit ($test->run(new TextReporter()) ? 0 : 1);
|
||||
}
|
||||
$test->run(new HtmlReporter());
|
||||
?>
|
||||
88
tests/simpletest/test/dumper_test.php
Normal file
88
tests/simpletest/test/dumper_test.php
Normal file
|
|
@ -0,0 +1,88 @@
|
|||
<?php
|
||||
// $Id: dumper_test.php 1505 2007-04-30 23:39:59Z lastcraft $
|
||||
require_once(dirname(__FILE__) . '/../autorun.php');
|
||||
|
||||
class DumperDummy {
|
||||
}
|
||||
|
||||
class TestOfTextFormatting extends UnitTestCase {
|
||||
|
||||
function testClipping() {
|
||||
$dumper = new SimpleDumper();
|
||||
$this->assertEqual(
|
||||
$dumper->clipString("Hello", 6),
|
||||
"Hello",
|
||||
"Hello, 6->%s");
|
||||
$this->assertEqual(
|
||||
$dumper->clipString("Hello", 5),
|
||||
"Hello",
|
||||
"Hello, 5->%s");
|
||||
$this->assertEqual(
|
||||
$dumper->clipString("Hello world", 3),
|
||||
"Hel...",
|
||||
"Hello world, 3->%s");
|
||||
$this->assertEqual(
|
||||
$dumper->clipString("Hello world", 6, 3),
|
||||
"Hello ...",
|
||||
"Hello world, 6, 3->%s");
|
||||
$this->assertEqual(
|
||||
$dumper->clipString("Hello world", 3, 6),
|
||||
"...o w...",
|
||||
"Hello world, 3, 6->%s");
|
||||
$this->assertEqual(
|
||||
$dumper->clipString("Hello world", 4, 11),
|
||||
"...orld",
|
||||
"Hello world, 4, 11->%s");
|
||||
$this->assertEqual(
|
||||
$dumper->clipString("Hello world", 4, 12),
|
||||
"...orld",
|
||||
"Hello world, 4, 12->%s");
|
||||
}
|
||||
|
||||
function testDescribeNull() {
|
||||
$dumper = new SimpleDumper();
|
||||
$this->assertPattern('/null/i', $dumper->describeValue(null));
|
||||
}
|
||||
|
||||
function testDescribeBoolean() {
|
||||
$dumper = new SimpleDumper();
|
||||
$this->assertPattern('/boolean/i', $dumper->describeValue(true));
|
||||
$this->assertPattern('/true/i', $dumper->describeValue(true));
|
||||
$this->assertPattern('/false/i', $dumper->describeValue(false));
|
||||
}
|
||||
|
||||
function testDescribeString() {
|
||||
$dumper = new SimpleDumper();
|
||||
$this->assertPattern('/string/i', $dumper->describeValue('Hello'));
|
||||
$this->assertPattern('/Hello/', $dumper->describeValue('Hello'));
|
||||
}
|
||||
|
||||
function testDescribeInteger() {
|
||||
$dumper = new SimpleDumper();
|
||||
$this->assertPattern('/integer/i', $dumper->describeValue(35));
|
||||
$this->assertPattern('/35/', $dumper->describeValue(35));
|
||||
}
|
||||
|
||||
function testDescribeFloat() {
|
||||
$dumper = new SimpleDumper();
|
||||
$this->assertPattern('/float/i', $dumper->describeValue(0.99));
|
||||
$this->assertPattern('/0\.99/', $dumper->describeValue(0.99));
|
||||
}
|
||||
|
||||
function testDescribeArray() {
|
||||
$dumper = new SimpleDumper();
|
||||
$this->assertPattern('/array/i', $dumper->describeValue(array(1, 4)));
|
||||
$this->assertPattern('/2/i', $dumper->describeValue(array(1, 4)));
|
||||
}
|
||||
|
||||
function testDescribeObject() {
|
||||
$dumper = new SimpleDumper();
|
||||
$this->assertPattern(
|
||||
'/object/i',
|
||||
$dumper->describeValue(new DumperDummy()));
|
||||
$this->assertPattern(
|
||||
'/DumperDummy/i',
|
||||
$dumper->describeValue(new DumperDummy()));
|
||||
}
|
||||
}
|
||||
?>
|
||||
32
tests/simpletest/test/eclipse_test.php
Normal file
32
tests/simpletest/test/eclipse_test.php
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
<?php
|
||||
// $Id: eclipse_test.php 1505 2007-04-30 23:39:59Z lastcraft $
|
||||
|
||||
//To run this from the eclipse plugin...you need to make sure that the
|
||||
//SimpleTest path in the preferences is the same as the location of the
|
||||
//eclipse.php file below otherwise you end up with two "different" eclipse.php
|
||||
//files included and that does not work...
|
||||
|
||||
include_once(dirname(__FILE__) . '/../eclipse.php');
|
||||
Mock::generate('SimpleSocket');
|
||||
|
||||
class TestOfEclipse extends UnitTestCase {
|
||||
|
||||
function testPass() {
|
||||
$listener = &new MockSimpleSocket();
|
||||
|
||||
$fullpath = realpath(dirname(__FILE__).'/support/test1.php');
|
||||
$testpath = EclipseReporter::escapeVal($fullpath);
|
||||
$expected = "{status:\"pass\",message:\"pass1 at [$testpath line 4]\",group:\"$testpath\",case:\"test1\",method:\"test_pass\"}";
|
||||
//this should work...but it doesn't so the next line and the last line are the hacks
|
||||
//$listener->expectOnce('write',array($expected));
|
||||
$listener->setReturnValue('write',-1);
|
||||
|
||||
$pathparts = pathinfo($fullpath);
|
||||
$filename = $pathparts['basename'];
|
||||
$test= &new TestSuite($filename);
|
||||
$test->addTestFile($fullpath);
|
||||
$test->run(new EclipseReporter(&$listener));
|
||||
$this->assertEqual($expected,$listener->output);
|
||||
}
|
||||
}
|
||||
?>
|
||||
213
tests/simpletest/test/encoding_test.php
Normal file
213
tests/simpletest/test/encoding_test.php
Normal file
|
|
@ -0,0 +1,213 @@
|
|||
<?php
|
||||
// $Id: encoding_test.php 1571 2007-09-07 17:14:32Z pp11 $
|
||||
require_once(dirname(__FILE__) . '/../autorun.php');
|
||||
require_once(dirname(__FILE__) . '/../url.php');
|
||||
require_once(dirname(__FILE__) . '/../socket.php');
|
||||
|
||||
Mock::generate('SimpleSocket');
|
||||
|
||||
class TestOfEncodedParts extends UnitTestCase {
|
||||
|
||||
function testFormEncodedAsKeyEqualsValue() {
|
||||
$pair = new SimpleEncodedPair('a', 'A');
|
||||
$this->assertEqual($pair->asRequest(), 'a=A');
|
||||
}
|
||||
|
||||
function testMimeEncodedAsHeadersAndContent() {
|
||||
$pair = new SimpleEncodedPair('a', 'A');
|
||||
$this->assertEqual(
|
||||
$pair->asMime(),
|
||||
"Content-Disposition: form-data; name=\"a\"\r\n\r\nA");
|
||||
}
|
||||
|
||||
function testAttachmentEncodedAsHeadersWithDispositionAndContent() {
|
||||
$part = new SimpleAttachment('a', 'A', 'aaa.txt');
|
||||
$this->assertEqual(
|
||||
$part->asMime(),
|
||||
"Content-Disposition: form-data; name=\"a\"; filename=\"aaa.txt\"\r\n" .
|
||||
"Content-Type: text/plain\r\n\r\nA");
|
||||
}
|
||||
}
|
||||
|
||||
class TestOfEncoding extends UnitTestCase {
|
||||
var $_content_so_far;
|
||||
|
||||
function write($content) {
|
||||
$this->_content_so_far .= $content;
|
||||
}
|
||||
|
||||
function clear() {
|
||||
$this->_content_so_far = '';
|
||||
}
|
||||
|
||||
function assertWritten($encoding, $content, $message = '%s') {
|
||||
$this->clear();
|
||||
$encoding->writeTo($this);
|
||||
$this->assertIdentical($this->_content_so_far, $content, $message);
|
||||
}
|
||||
|
||||
function testGetEmpty() {
|
||||
$encoding = &new SimpleGetEncoding();
|
||||
$this->assertIdentical($encoding->getValue('a'), false);
|
||||
$this->assertIdentical($encoding->asUrlRequest(), '');
|
||||
}
|
||||
|
||||
function testPostEmpty() {
|
||||
$encoding = &new SimplePostEncoding();
|
||||
$this->assertIdentical($encoding->getValue('a'), false);
|
||||
$this->assertWritten($encoding, '');
|
||||
}
|
||||
|
||||
function testPrefilled() {
|
||||
$encoding = &new SimplePostEncoding(array('a' => 'aaa'));
|
||||
$this->assertIdentical($encoding->getValue('a'), 'aaa');
|
||||
$this->assertWritten($encoding, 'a=aaa');
|
||||
}
|
||||
|
||||
function testPrefilledWithTwoLevels() {
|
||||
$query = array('a' => array('aa' => 'aaa'));
|
||||
$encoding = &new SimplePostEncoding($query);
|
||||
$this->assertTrue($encoding->hasMoreThanOneLevel($query));
|
||||
$this->assertEqual($encoding->rewriteArrayWithMultipleLevels($query), array('a[aa]' => 'aaa'));
|
||||
$this->assertIdentical($encoding->getValue('a[aa]'), 'aaa');
|
||||
$this->assertWritten($encoding, 'a%5Baa%5D=aaa');
|
||||
}
|
||||
|
||||
function testPrefilledWithThreeLevels() {
|
||||
$query = array('a' => array('aa' => array('aaa' => 'aaaa')));
|
||||
$encoding = &new SimplePostEncoding($query);
|
||||
$this->assertTrue($encoding->hasMoreThanOneLevel($query));
|
||||
$this->assertEqual($encoding->rewriteArrayWithMultipleLevels($query), array('a[aa][aaa]' => 'aaaa'));
|
||||
$this->assertIdentical($encoding->getValue('a[aa][aaa]'), 'aaaa');
|
||||
$this->assertWritten($encoding, 'a%5Baa%5D%5Baaa%5D=aaaa');
|
||||
}
|
||||
|
||||
function testPrefilledWithObject() {
|
||||
$encoding = &new SimplePostEncoding(new SimpleEncoding(array('a' => 'aaa')));
|
||||
$this->assertIdentical($encoding->getValue('a'), 'aaa');
|
||||
$this->assertWritten($encoding, 'a=aaa');
|
||||
}
|
||||
|
||||
function testMultiplePrefilled() {
|
||||
$query = array('a' => array('a1', 'a2'));
|
||||
$encoding = &new SimplePostEncoding($query);
|
||||
$this->assertTrue($encoding->hasMoreThanOneLevel($query));
|
||||
$this->assertEqual($encoding->rewriteArrayWithMultipleLevels($query), array('a[0]' => 'a1', 'a[1]' => 'a2'));
|
||||
$this->assertIdentical($encoding->getValue('a[0]'), 'a1');
|
||||
$this->assertIdentical($encoding->getValue('a[1]'), 'a2');
|
||||
$this->assertWritten($encoding, 'a%5B0%5D=a1&a%5B1%5D=a2');
|
||||
}
|
||||
|
||||
function testSingleParameter() {
|
||||
$encoding = &new SimplePostEncoding();
|
||||
$encoding->add('a', 'Hello');
|
||||
$this->assertEqual($encoding->getValue('a'), 'Hello');
|
||||
$this->assertWritten($encoding, 'a=Hello');
|
||||
}
|
||||
|
||||
function testFalseParameter() {
|
||||
$encoding = &new SimplePostEncoding();
|
||||
$encoding->add('a', false);
|
||||
$this->assertEqual($encoding->getValue('a'), false);
|
||||
$this->assertWritten($encoding, '');
|
||||
}
|
||||
|
||||
function testUrlEncoding() {
|
||||
$encoding = &new SimplePostEncoding();
|
||||
$encoding->add('a', 'Hello there!');
|
||||
$this->assertWritten($encoding, 'a=Hello+there%21');
|
||||
}
|
||||
|
||||
function testUrlEncodingOfKey() {
|
||||
$encoding = &new SimplePostEncoding();
|
||||
$encoding->add('a!', 'Hello');
|
||||
$this->assertWritten($encoding, 'a%21=Hello');
|
||||
}
|
||||
|
||||
function testMultipleParameter() {
|
||||
$encoding = &new SimplePostEncoding();
|
||||
$encoding->add('a', 'Hello');
|
||||
$encoding->add('b', 'Goodbye');
|
||||
$this->assertWritten($encoding, 'a=Hello&b=Goodbye');
|
||||
}
|
||||
|
||||
function testEmptyParameters() {
|
||||
$encoding = &new SimplePostEncoding();
|
||||
$encoding->add('a', '');
|
||||
$encoding->add('b', '');
|
||||
$this->assertWritten($encoding, 'a=&b=');
|
||||
}
|
||||
|
||||
function testRepeatedParameter() {
|
||||
$encoding = &new SimplePostEncoding();
|
||||
$encoding->add('a', 'Hello');
|
||||
$encoding->add('a', 'Goodbye');
|
||||
$this->assertIdentical($encoding->getValue('a'), array('Hello', 'Goodbye'));
|
||||
$this->assertWritten($encoding, 'a=Hello&a=Goodbye');
|
||||
}
|
||||
|
||||
function testAddingLists() {
|
||||
$encoding = &new SimplePostEncoding();
|
||||
$encoding->add('a', array('Hello', 'Goodbye'));
|
||||
$this->assertIdentical($encoding->getValue('a'), array('Hello', 'Goodbye'));
|
||||
$this->assertWritten($encoding, 'a=Hello&a=Goodbye');
|
||||
}
|
||||
|
||||
function testMergeInHash() {
|
||||
$encoding = &new SimpleGetEncoding(array('a' => 'A1', 'b' => 'B'));
|
||||
$encoding->merge(array('a' => 'A2'));
|
||||
$this->assertIdentical($encoding->getValue('a'), array('A1', 'A2'));
|
||||
$this->assertIdentical($encoding->getValue('b'), 'B');
|
||||
}
|
||||
|
||||
function testMergeInObject() {
|
||||
$encoding = &new SimpleGetEncoding(array('a' => 'A1', 'b' => 'B'));
|
||||
$encoding->merge(new SimpleEncoding(array('a' => 'A2')));
|
||||
$this->assertIdentical($encoding->getValue('a'), array('A1', 'A2'));
|
||||
$this->assertIdentical($encoding->getValue('b'), 'B');
|
||||
}
|
||||
|
||||
function testPrefilledMultipart() {
|
||||
$encoding = &new SimpleMultipartEncoding(array('a' => 'aaa'), 'boundary');
|
||||
$this->assertIdentical($encoding->getValue('a'), 'aaa');
|
||||
$this->assertwritten($encoding,
|
||||
"--boundary\r\n" .
|
||||
"Content-Disposition: form-data; name=\"a\"\r\n" .
|
||||
"\r\n" .
|
||||
"aaa\r\n" .
|
||||
"--boundary--\r\n");
|
||||
}
|
||||
|
||||
function testAttachment() {
|
||||
$encoding = &new SimpleMultipartEncoding(array(), 'boundary');
|
||||
$encoding->attach('a', 'aaa', 'aaa.txt');
|
||||
$this->assertIdentical($encoding->getValue('a'), 'aaa.txt');
|
||||
$this->assertwritten($encoding,
|
||||
"--boundary\r\n" .
|
||||
"Content-Disposition: form-data; name=\"a\"; filename=\"aaa.txt\"\r\n" .
|
||||
"Content-Type: text/plain\r\n" .
|
||||
"\r\n" .
|
||||
"aaa\r\n" .
|
||||
"--boundary--\r\n");
|
||||
}
|
||||
}
|
||||
|
||||
class TestOfFormHeaders extends UnitTestCase {
|
||||
|
||||
function testEmptyEncodingWritesZeroContentLength() {
|
||||
$socket = &new MockSimpleSocket();
|
||||
$socket->expectArgumentsAt(0, 'write', array("Content-Length: 0\r\n"));
|
||||
$socket->expectArgumentsAt(1, 'write', array("Content-Type: application/x-www-form-urlencoded\r\n"));
|
||||
$encoding = &new SimplePostEncoding();
|
||||
$encoding->writeHeadersTo($socket);
|
||||
}
|
||||
|
||||
function testEmptyMultipartEncodingWritesEndBoundaryContentLength() {
|
||||
$socket = &new MockSimpleSocket();
|
||||
$socket->expectArgumentsAt(0, 'write', array("Content-Length: 14\r\n"));
|
||||
$socket->expectArgumentsAt(1, 'write', array("Content-Type: multipart/form-data, boundary=boundary\r\n"));
|
||||
$encoding = &new SimpleMultipartEncoding(array(), 'boundary');
|
||||
$encoding->writeHeadersTo($socket);
|
||||
}
|
||||
}
|
||||
?>
|
||||
300
tests/simpletest/test/errors_test.php
Normal file
300
tests/simpletest/test/errors_test.php
Normal file
|
|
@ -0,0 +1,300 @@
|
|||
<?php
|
||||
require_once(dirname(__FILE__) . '/../autorun.php');
|
||||
require_once(dirname(__FILE__) . '/../errors.php');
|
||||
require_once(dirname(__FILE__) . '/../expectation.php');
|
||||
require_once(dirname(__FILE__) . '/../test_case.php');
|
||||
Mock::generate('SimpleTestCase');
|
||||
Mock::generate('SimpleExpectation');
|
||||
SimpleTest::ignore('MockSimpleTestCase');
|
||||
|
||||
class TestOfErrorQueue extends UnitTestCase {
|
||||
|
||||
function setUp() {
|
||||
$context = &SimpleTest::getContext();
|
||||
$queue = &$context->get('SimpleErrorQueue');
|
||||
$queue->clear();
|
||||
}
|
||||
|
||||
function tearDown() {
|
||||
$context = &SimpleTest::getContext();
|
||||
$queue = &$context->get('SimpleErrorQueue');
|
||||
$queue->clear();
|
||||
}
|
||||
|
||||
function testOrder() {
|
||||
$context = &SimpleTest::getContext();
|
||||
$queue = &$context->get('SimpleErrorQueue');
|
||||
$queue->add(1024, 'Ouch', 'here.php', 100);
|
||||
$queue->add(512, 'Yuk', 'there.php', 101);
|
||||
$this->assertEqual(
|
||||
$queue->extract(),
|
||||
array(1024, 'Ouch', 'here.php', 100));
|
||||
$this->assertEqual(
|
||||
$queue->extract(),
|
||||
array(512, 'Yuk', 'there.php', 101));
|
||||
$this->assertFalse($queue->extract());
|
||||
}
|
||||
|
||||
function testAssertNoErrorsGivesTrueWhenNoErrors() {
|
||||
$test = &new MockSimpleTestCase();
|
||||
$test->expectOnce('assert', array(
|
||||
new IdenticalExpectation(new TrueExpectation()),
|
||||
true,
|
||||
'Should be no errors'));
|
||||
$test->setReturnValue('assert', true);
|
||||
$queue = &new SimpleErrorQueue();
|
||||
$queue->setTestCase($test);
|
||||
$this->assertTrue($queue->assertNoErrors('%s'));
|
||||
}
|
||||
|
||||
function testAssertNoErrorsIssuesFailWhenErrors() {
|
||||
$test = &new MockSimpleTestCase();
|
||||
$test->expectOnce('assert', array(
|
||||
new IdenticalExpectation(new TrueExpectation()),
|
||||
false,
|
||||
'Should be no errors'));
|
||||
$test->setReturnValue('assert', false);
|
||||
$queue = &new SimpleErrorQueue();
|
||||
$queue->setTestCase($test);
|
||||
$queue->add(1024, 'Ouch', 'here.php', 100);
|
||||
$this->assertFalse($queue->assertNoErrors('%s'));
|
||||
}
|
||||
|
||||
function testAssertErrorFailsWhenNoError() {
|
||||
$test = &new MockSimpleTestCase();
|
||||
$test->expectOnce('fail', array('Expected error not found'));
|
||||
$test->setReturnValue('assert', false);
|
||||
$queue = &new SimpleErrorQueue();
|
||||
$queue->setTestCase($test);
|
||||
$this->assertFalse($queue->assertError(false, '%s'));
|
||||
}
|
||||
|
||||
function testAssertErrorFailsWhenErrorDoesntMatchTheExpectation() {
|
||||
$test = &new MockSimpleTestCase();
|
||||
$test->expectOnce('assert', array(
|
||||
new IdenticalExpectation(new FailedExpectation()),
|
||||
'B',
|
||||
'Expected PHP error [B] severity [E_USER_NOTICE] in [b.php] line [100]'));
|
||||
$test->setReturnValue('assert', false);
|
||||
$queue = &new SimpleErrorQueue();
|
||||
$queue->setTestCase($test);
|
||||
$queue->add(1024, 'B', 'b.php', 100);
|
||||
$this->assertFalse($queue->assertError(new FailedExpectation(), '%s'));
|
||||
}
|
||||
|
||||
function testExpectationMatchCancelsIncomingError() {
|
||||
$test = &new MockSimpleTestCase();
|
||||
$test->expectOnce('assert', array(
|
||||
new IdenticalExpectation(new AnythingExpectation()),
|
||||
'B',
|
||||
'a message'));
|
||||
$test->setReturnValue('assert', true);
|
||||
$test->expectNever('error');
|
||||
$queue = &new SimpleErrorQueue();
|
||||
$queue->setTestCase($test);
|
||||
$queue->expectError(new AnythingExpectation(), 'a message');
|
||||
$queue->add(1024, 'B', 'b.php', 100);
|
||||
}
|
||||
}
|
||||
|
||||
class TestOfErrorTrap extends UnitTestCase {
|
||||
var $_old;
|
||||
|
||||
function setUp() {
|
||||
$this->_old = error_reporting(E_ALL);
|
||||
set_error_handler('SimpleTestErrorHandler');
|
||||
}
|
||||
|
||||
function tearDown() {
|
||||
restore_error_handler();
|
||||
error_reporting($this->_old);
|
||||
}
|
||||
|
||||
function testQueueStartsEmpty() {
|
||||
$context = &SimpleTest::getContext();
|
||||
$queue = &$context->get('SimpleErrorQueue');
|
||||
$this->assertFalse($queue->extract());
|
||||
}
|
||||
|
||||
function testTrappedErrorPlacedInQueue() {
|
||||
trigger_error('Ouch!');
|
||||
$context = &SimpleTest::getContext();
|
||||
$queue = &$context->get('SimpleErrorQueue');
|
||||
list($severity, $message, $file, $line) = $queue->extract();
|
||||
$this->assertEqual($message, 'Ouch!');
|
||||
$this->assertEqual($file, __FILE__);
|
||||
$this->assertFalse($queue->extract());
|
||||
}
|
||||
|
||||
function testErrorsAreSwallowedByMatchingExpectation() {
|
||||
$this->expectError('Ouch!');
|
||||
trigger_error('Ouch!');
|
||||
}
|
||||
|
||||
function testErrorsAreSwallowedInOrder() {
|
||||
$this->expectError('a');
|
||||
$this->expectError('b');
|
||||
trigger_error('a');
|
||||
trigger_error('b');
|
||||
}
|
||||
|
||||
function testAnyErrorCanBeSwallowed() {
|
||||
$this->expectError();
|
||||
trigger_error('Ouch!');
|
||||
}
|
||||
|
||||
function testErrorCanBeSwallowedByPatternMatching() {
|
||||
$this->expectError(new PatternExpectation('/ouch/i'));
|
||||
trigger_error('Ouch!');
|
||||
}
|
||||
|
||||
function testErrorWithPercentsPassesWithNoSprintfError() {
|
||||
$this->expectError("%");
|
||||
trigger_error('%');
|
||||
}
|
||||
}
|
||||
|
||||
class TestOfErrors extends UnitTestCase {
|
||||
var $_old;
|
||||
|
||||
function setUp() {
|
||||
$this->_old = error_reporting(E_ALL);
|
||||
}
|
||||
|
||||
function tearDown() {
|
||||
error_reporting($this->_old);
|
||||
}
|
||||
|
||||
function testDefaultWhenAllReported() {
|
||||
error_reporting(E_ALL);
|
||||
trigger_error('Ouch!');
|
||||
$this->assertError('Ouch!');
|
||||
}
|
||||
|
||||
function testNoticeWhenReported() {
|
||||
error_reporting(E_ALL);
|
||||
trigger_error('Ouch!', E_USER_NOTICE);
|
||||
$this->assertError('Ouch!');
|
||||
}
|
||||
|
||||
function testWarningWhenReported() {
|
||||
error_reporting(E_ALL);
|
||||
trigger_error('Ouch!', E_USER_WARNING);
|
||||
$this->assertError('Ouch!');
|
||||
}
|
||||
|
||||
function testErrorWhenReported() {
|
||||
error_reporting(E_ALL);
|
||||
trigger_error('Ouch!', E_USER_ERROR);
|
||||
$this->assertError('Ouch!');
|
||||
}
|
||||
|
||||
function testNoNoticeWhenNotReported() {
|
||||
error_reporting(0);
|
||||
trigger_error('Ouch!', E_USER_NOTICE);
|
||||
}
|
||||
|
||||
function testNoWarningWhenNotReported() {
|
||||
error_reporting(0);
|
||||
trigger_error('Ouch!', E_USER_WARNING);
|
||||
}
|
||||
|
||||
function testNoticeSuppressedWhenReported() {
|
||||
error_reporting(E_ALL);
|
||||
@trigger_error('Ouch!', E_USER_NOTICE);
|
||||
}
|
||||
|
||||
function testWarningSuppressedWhenReported() {
|
||||
error_reporting(E_ALL);
|
||||
@trigger_error('Ouch!', E_USER_WARNING);
|
||||
}
|
||||
|
||||
function testErrorWithPercentsReportedWithNoSprintfError() {
|
||||
trigger_error('%');
|
||||
$this->assertError('%');
|
||||
}
|
||||
}
|
||||
|
||||
class TestOfPHP52RecoverableErrors extends UnitTestCase {
|
||||
function skip() {
|
||||
$this->skipIf(
|
||||
version_compare(phpversion(), '5.2', '<'),
|
||||
'E_RECOVERABLE_ERROR not tested for PHP below 5.2');
|
||||
}
|
||||
|
||||
function testError() {
|
||||
eval('
|
||||
class RecoverableErrorTestingStub {
|
||||
function ouch(RecoverableErrorTestingStub $obj) {
|
||||
}
|
||||
}
|
||||
');
|
||||
|
||||
$stub = new RecoverableErrorTestingStub();
|
||||
$this->expectError(new PatternExpectation('/must be an instance of RecoverableErrorTestingStub/i'));
|
||||
$stub->ouch(new stdClass());
|
||||
}
|
||||
}
|
||||
|
||||
class TestOfErrorsExcludingPHP52AndAbove extends UnitTestCase {
|
||||
function skip() {
|
||||
$this->skipIf(
|
||||
version_compare(phpversion(), '5.2', '>='),
|
||||
'E_USER_ERROR not tested for PHP 5.2 and above');
|
||||
}
|
||||
|
||||
function testNoErrorWhenNotReported() {
|
||||
error_reporting(0);
|
||||
trigger_error('Ouch!', E_USER_ERROR);
|
||||
}
|
||||
|
||||
function testErrorSuppressedWhenReported() {
|
||||
error_reporting(E_ALL);
|
||||
@trigger_error('Ouch!', E_USER_ERROR);
|
||||
}
|
||||
}
|
||||
|
||||
SimpleTest::ignore('TestOfNotEnoughErrors');
|
||||
/**
|
||||
* This test is ignored as it is used by {@link TestRunnerForLeftOverAndNotEnoughErrors}
|
||||
* to verify that it fails as expected.
|
||||
*
|
||||
* @ignore
|
||||
*/
|
||||
class TestOfNotEnoughErrors extends UnitTestCase {
|
||||
function testExpectTwoErrorsThrowOne() {
|
||||
$this->expectError('Error 1');
|
||||
trigger_error('Error 1');
|
||||
$this->expectError('Error 2');
|
||||
}
|
||||
}
|
||||
|
||||
SimpleTest::ignore('TestOfLeftOverErrors');
|
||||
/**
|
||||
* This test is ignored as it is used by {@link TestRunnerForLeftOverAndNotEnoughErrors}
|
||||
* to verify that it fails as expected.
|
||||
*
|
||||
* @ignore
|
||||
*/
|
||||
class TestOfLeftOverErrors extends UnitTestCase {
|
||||
function testExpectOneErrorGetTwo() {
|
||||
$this->expectError('Error 1');
|
||||
trigger_error('Error 1');
|
||||
trigger_error('Error 2');
|
||||
}
|
||||
}
|
||||
|
||||
class TestRunnerForLeftOverAndNotEnoughErrors extends UnitTestCase {
|
||||
function testRunLeftOverErrorsTestCase() {
|
||||
$test = new TestOfLeftOverErrors();
|
||||
$this->assertFalse($test->run(new SimpleReporter()));
|
||||
}
|
||||
|
||||
function testRunNotEnoughErrors() {
|
||||
$test = new TestOfNotEnoughErrors();
|
||||
$this->assertFalse($test->run(new SimpleReporter()));
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: Add stacked error handler test
|
||||
?>
|
||||
153
tests/simpletest/test/exceptions_test.php
Normal file
153
tests/simpletest/test/exceptions_test.php
Normal file
|
|
@ -0,0 +1,153 @@
|
|||
<?php
|
||||
// $Id: exceptions_test.php 1618 2007-12-29 22:52:30Z lastcraft $
|
||||
require_once(dirname(__FILE__) . '/../autorun.php');
|
||||
require_once(dirname(__FILE__) . '/../exceptions.php');
|
||||
require_once(dirname(__FILE__) . '/../expectation.php');
|
||||
require_once(dirname(__FILE__) . '/../test_case.php');
|
||||
Mock::generate('SimpleTestCase');
|
||||
Mock::generate('SimpleExpectation');
|
||||
|
||||
class MyTestException extends Exception {}
|
||||
class HigherTestException extends MyTestException {}
|
||||
class OtherTestException extends Exception {}
|
||||
|
||||
class TestOfExceptionExpectation extends UnitTestCase {
|
||||
|
||||
function testExceptionClassAsStringWillMatchExceptionsRootedOnThatClass() {
|
||||
$expectation = new ExceptionExpectation('MyTestException');
|
||||
$this->assertTrue($expectation->test(new MyTestException()));
|
||||
$this->assertTrue($expectation->test(new HigherTestException()));
|
||||
$this->assertFalse($expectation->test(new OtherTestException()));
|
||||
}
|
||||
|
||||
function testMatchesClassAndMessageWhenExceptionExpected() {
|
||||
$expectation = new ExceptionExpectation(new MyTestException('Hello'));
|
||||
$this->assertTrue($expectation->test(new MyTestException('Hello')));
|
||||
$this->assertFalse($expectation->test(new HigherTestException('Hello')));
|
||||
$this->assertFalse($expectation->test(new OtherTestException('Hello')));
|
||||
$this->assertFalse($expectation->test(new MyTestException('Goodbye')));
|
||||
$this->assertFalse($expectation->test(new MyTestException()));
|
||||
}
|
||||
|
||||
function testMessagelessExceptionMatchesOnlyOnClass() {
|
||||
$expectation = new ExceptionExpectation(new MyTestException());
|
||||
$this->assertTrue($expectation->test(new MyTestException()));
|
||||
$this->assertFalse($expectation->test(new HigherTestException()));
|
||||
}
|
||||
}
|
||||
|
||||
class TestOfExceptionTrap extends UnitTestCase {
|
||||
|
||||
function testNoExceptionsInQueueMeansNoTestMessages() {
|
||||
$test = new MockSimpleTestCase();
|
||||
$test->expectNever('assert');
|
||||
$queue = new SimpleExceptionTrap();
|
||||
$this->assertFalse($queue->isExpected($test, new Exception()));
|
||||
}
|
||||
|
||||
function testMatchingExceptionGivesTrue() {
|
||||
$expectation = new MockSimpleExpectation();
|
||||
$expectation->setReturnValue('test', true);
|
||||
$test = new MockSimpleTestCase();
|
||||
$test->setReturnValue('assert', true);
|
||||
$queue = new SimpleExceptionTrap();
|
||||
$queue->expectException($expectation, 'message');
|
||||
$this->assertTrue($queue->isExpected($test, new Exception()));
|
||||
}
|
||||
|
||||
function testMatchingExceptionTriggersAssertion() {
|
||||
$test = new MockSimpleTestCase();
|
||||
$test->expectOnce('assert', array(
|
||||
'*',
|
||||
new ExceptionExpectation(new Exception()),
|
||||
'message'));
|
||||
$queue = new SimpleExceptionTrap();
|
||||
$queue->expectException(new ExceptionExpectation(new Exception()), 'message');
|
||||
$queue->isExpected($test, new Exception());
|
||||
}
|
||||
}
|
||||
|
||||
class TestOfCatchingExceptions extends UnitTestCase {
|
||||
|
||||
function testCanCatchAnyExpectedException() {
|
||||
$this->expectException();
|
||||
throw new Exception();
|
||||
}
|
||||
|
||||
function testCanMatchExceptionByClass() {
|
||||
$this->expectException('MyTestException');
|
||||
throw new HigherTestException();
|
||||
}
|
||||
|
||||
function testCanMatchExceptionExactly() {
|
||||
$this->expectException(new Exception('Ouch'));
|
||||
throw new Exception('Ouch');
|
||||
}
|
||||
|
||||
function testLastListedExceptionIsTheOneThatCounts() {
|
||||
$this->expectException('OtherTestException');
|
||||
$this->expectException('MyTestException');
|
||||
throw new HigherTestException();
|
||||
}
|
||||
}
|
||||
|
||||
class TestOfCallingTearDownAfterExceptions extends UnitTestCase {
|
||||
private $debri = 0;
|
||||
|
||||
function tearDown() {
|
||||
$this->debri--;
|
||||
}
|
||||
|
||||
function testLeaveSomeDebri() {
|
||||
$this->debri++;
|
||||
$this->expectException();
|
||||
throw new Exception(__FUNCTION__);
|
||||
}
|
||||
|
||||
function testDebriWasRemovedOnce() {
|
||||
$this->assertEqual($this->debri, 0);
|
||||
}
|
||||
}
|
||||
|
||||
class TestOfExceptionThrownInSetUpDoesNotRunTestBody extends UnitTestCase {
|
||||
|
||||
function setUp() {
|
||||
$this->expectException();
|
||||
throw new Exception();
|
||||
}
|
||||
|
||||
function testShouldNotBeRun() {
|
||||
$this->fail('This test body should not be run');
|
||||
}
|
||||
|
||||
function testShouldNotBeRunEither() {
|
||||
$this->fail('This test body should not be run either');
|
||||
}
|
||||
}
|
||||
|
||||
class TestOfExpectExceptionWithSetUp extends UnitTestCase {
|
||||
|
||||
function setUp() {
|
||||
$this->expectException();
|
||||
}
|
||||
|
||||
function testThisExceptionShouldBeCaught() {
|
||||
throw new Exception();
|
||||
}
|
||||
|
||||
function testJustThrowingMyTestException() {
|
||||
throw new MyTestException();
|
||||
}
|
||||
}
|
||||
|
||||
class TestOfThrowingExceptionsInTearDown extends UnitTestCase {
|
||||
|
||||
function tearDown() {
|
||||
throw new Exception();
|
||||
}
|
||||
|
||||
function testDoesntFatal() {
|
||||
$this->expectException();
|
||||
}
|
||||
}
|
||||
?>
|
||||
245
tests/simpletest/test/expectation_test.php
Normal file
245
tests/simpletest/test/expectation_test.php
Normal file
|
|
@ -0,0 +1,245 @@
|
|||
<?php
|
||||
// $Id: expectation_test.php 1539 2007-06-09 08:35:54Z pachanga $
|
||||
require_once(dirname(__FILE__) . '/../autorun.php');
|
||||
require_once(dirname(__FILE__) . '/../expectation.php');
|
||||
|
||||
class TestOfEquality extends UnitTestCase {
|
||||
|
||||
function testBoolean() {
|
||||
$is_true = &new EqualExpectation(true);
|
||||
$this->assertTrue($is_true->test(true));
|
||||
$this->assertFalse($is_true->test(false));
|
||||
}
|
||||
|
||||
function testStringMatch() {
|
||||
$hello = &new EqualExpectation("Hello");
|
||||
$this->assertTrue($hello->test("Hello"));
|
||||
$this->assertFalse($hello->test("Goodbye"));
|
||||
}
|
||||
|
||||
function testInteger() {
|
||||
$fifteen = &new EqualExpectation(15);
|
||||
$this->assertTrue($fifteen->test(15));
|
||||
$this->assertFalse($fifteen->test(14));
|
||||
}
|
||||
|
||||
function testFloat() {
|
||||
$pi = &new EqualExpectation(3.14);
|
||||
$this->assertTrue($pi->test(3.14));
|
||||
$this->assertFalse($pi->test(3.15));
|
||||
}
|
||||
|
||||
function testArray() {
|
||||
$colours = &new EqualExpectation(array("r", "g", "b"));
|
||||
$this->assertTrue($colours->test(array("r", "g", "b")));
|
||||
$this->assertFalse($colours->test(array("g", "b", "r")));
|
||||
}
|
||||
|
||||
function testHash() {
|
||||
$is_blue = &new EqualExpectation(array("r" => 0, "g" => 0, "b" => 255));
|
||||
$this->assertTrue($is_blue->test(array("r" => 0, "g" => 0, "b" => 255)));
|
||||
$this->assertFalse($is_blue->test(array("r" => 0, "g" => 255, "b" => 0)));
|
||||
}
|
||||
|
||||
function testHashWithOutOfOrderKeysShouldStillMatch() {
|
||||
$any_order = &new EqualExpectation(array('a' => 1, 'b' => 2));
|
||||
$this->assertTrue($any_order->test(array('b' => 2, 'a' => 1)));
|
||||
}
|
||||
}
|
||||
|
||||
class TestOfWithin extends UnitTestCase {
|
||||
|
||||
function testWithinFloatingPointMargin() {
|
||||
$within = new WithinMarginExpectation(1.0, 0.2);
|
||||
$this->assertFalse($within->test(0.7));
|
||||
$this->assertTrue($within->test(0.8));
|
||||
$this->assertTrue($within->test(0.9));
|
||||
$this->assertTrue($within->test(1.1));
|
||||
$this->assertTrue($within->test(1.2));
|
||||
$this->assertFalse($within->test(1.3));
|
||||
}
|
||||
|
||||
function testOutsideFloatingPointMargin() {
|
||||
$within = new OutsideMarginExpectation(1.0, 0.2);
|
||||
$this->assertTrue($within->test(0.7));
|
||||
$this->assertFalse($within->test(0.8));
|
||||
$this->assertFalse($within->test(1.2));
|
||||
$this->assertTrue($within->test(1.3));
|
||||
}
|
||||
}
|
||||
|
||||
class TestOfInequality extends UnitTestCase {
|
||||
|
||||
function testStringMismatch() {
|
||||
$not_hello = &new NotEqualExpectation("Hello");
|
||||
$this->assertTrue($not_hello->test("Goodbye"));
|
||||
$this->assertFalse($not_hello->test("Hello"));
|
||||
}
|
||||
}
|
||||
|
||||
class RecursiveNasty {
|
||||
var $_me;
|
||||
|
||||
function RecursiveNasty() {
|
||||
$this->_me = $this;
|
||||
}
|
||||
}
|
||||
|
||||
class TestOfIdentity extends UnitTestCase {
|
||||
|
||||
function testType() {
|
||||
$string = &new IdenticalExpectation("37");
|
||||
$this->assertTrue($string->test("37"));
|
||||
$this->assertFalse($string->test(37));
|
||||
$this->assertFalse($string->test("38"));
|
||||
}
|
||||
|
||||
function _testNastyPhp5Bug() {
|
||||
$this->assertFalse(new RecursiveNasty() != new RecursiveNasty());
|
||||
}
|
||||
|
||||
function _testReallyHorribleRecursiveStructure() {
|
||||
$hopeful = &new IdenticalExpectation(new RecursiveNasty());
|
||||
$this->assertTrue($hopeful->test(new RecursiveNasty()));
|
||||
}
|
||||
}
|
||||
|
||||
class DummyReferencedObject{}
|
||||
|
||||
class TestOfReference extends UnitTestCase {
|
||||
|
||||
function testReference() {
|
||||
$foo = "foo";
|
||||
$ref =& $foo;
|
||||
$not_ref = $foo;
|
||||
$bar = "bar";
|
||||
|
||||
$expect = &new ReferenceExpectation($foo);
|
||||
$this->assertTrue($expect->test($ref));
|
||||
$this->assertFalse($expect->test($not_ref));
|
||||
$this->assertFalse($expect->test($bar));
|
||||
}
|
||||
|
||||
function testObjectsReferencesDualityForPhp5AndPhp4() {
|
||||
$dummy = new DummyReferencedObject();
|
||||
$ref =& $dummy;
|
||||
$not_ref = $dummy;
|
||||
|
||||
$hopeful = &new ReferenceExpectation($dummy);
|
||||
$this->assertTrue($hopeful->test($ref));
|
||||
|
||||
if (version_compare(phpversion(), '5') >= 0) {
|
||||
$this->assertTrue($hopeful->test($not_ref));
|
||||
} else {
|
||||
$this->assertFalse($hopeful->test($not_ref));
|
||||
}
|
||||
}
|
||||
|
||||
function testReallyHorribleRecursiveStructure() {
|
||||
$nasty = new RecursiveNasty();
|
||||
$ref =& $nasty;
|
||||
$hopeful = &new ReferenceExpectation($nasty);
|
||||
$this->assertTrue($hopeful->test($ref));
|
||||
}
|
||||
}
|
||||
|
||||
class TestOfNonIdentity extends UnitTestCase {
|
||||
|
||||
function testType() {
|
||||
$string = &new NotIdenticalExpectation("37");
|
||||
$this->assertTrue($string->test("38"));
|
||||
$this->assertTrue($string->test(37));
|
||||
$this->assertFalse($string->test("37"));
|
||||
}
|
||||
}
|
||||
|
||||
class TestOfPatterns extends UnitTestCase {
|
||||
|
||||
function testWanted() {
|
||||
$pattern = &new PatternExpectation('/hello/i');
|
||||
$this->assertTrue($pattern->test("Hello world"));
|
||||
$this->assertFalse($pattern->test("Goodbye world"));
|
||||
}
|
||||
|
||||
function testUnwanted() {
|
||||
$pattern = &new NoPatternExpectation('/hello/i');
|
||||
$this->assertFalse($pattern->test("Hello world"));
|
||||
$this->assertTrue($pattern->test("Goodbye world"));
|
||||
}
|
||||
}
|
||||
|
||||
class ExpectedMethodTarget {
|
||||
function hasThisMethod() {}
|
||||
}
|
||||
|
||||
class TestOfMethodExistence extends UnitTestCase {
|
||||
|
||||
function testHasMethod() {
|
||||
$instance = &new ExpectedMethodTarget();
|
||||
$expectation = &new MethodExistsExpectation('hasThisMethod');
|
||||
$this->assertTrue($expectation->test($instance));
|
||||
$expectation = &new MethodExistsExpectation('doesNotHaveThisMethod');
|
||||
$this->assertFalse($expectation->test($instance));
|
||||
}
|
||||
}
|
||||
|
||||
class TestOfIsA extends UnitTestCase {
|
||||
|
||||
function testString() {
|
||||
$expectation = &new IsAExpectation('string');
|
||||
$this->assertTrue($expectation->test('Hello'));
|
||||
$this->assertFalse($expectation->test(5));
|
||||
}
|
||||
|
||||
function testBoolean() {
|
||||
$expectation = &new IsAExpectation('boolean');
|
||||
$this->assertTrue($expectation->test(true));
|
||||
$this->assertFalse($expectation->test(1));
|
||||
}
|
||||
|
||||
function testBool() {
|
||||
$expectation = &new IsAExpectation('bool');
|
||||
$this->assertTrue($expectation->test(true));
|
||||
$this->assertFalse($expectation->test(1));
|
||||
}
|
||||
|
||||
function testDouble() {
|
||||
$expectation = &new IsAExpectation('double');
|
||||
$this->assertTrue($expectation->test(5.0));
|
||||
$this->assertFalse($expectation->test(5));
|
||||
}
|
||||
|
||||
function testFloat() {
|
||||
$expectation = &new IsAExpectation('float');
|
||||
$this->assertTrue($expectation->test(5.0));
|
||||
$this->assertFalse($expectation->test(5));
|
||||
}
|
||||
|
||||
function testReal() {
|
||||
$expectation = &new IsAExpectation('real');
|
||||
$this->assertTrue($expectation->test(5.0));
|
||||
$this->assertFalse($expectation->test(5));
|
||||
}
|
||||
|
||||
function testInteger() {
|
||||
$expectation = &new IsAExpectation('integer');
|
||||
$this->assertTrue($expectation->test(5));
|
||||
$this->assertFalse($expectation->test(5.0));
|
||||
}
|
||||
|
||||
function testInt() {
|
||||
$expectation = &new IsAExpectation('int');
|
||||
$this->assertTrue($expectation->test(5));
|
||||
$this->assertFalse($expectation->test(5.0));
|
||||
}
|
||||
}
|
||||
|
||||
class TestOfNotA extends UnitTestCase {
|
||||
|
||||
function testString() {
|
||||
$expectation = &new NotAExpectation('string');
|
||||
$this->assertFalse($expectation->test('Hello'));
|
||||
$this->assertTrue($expectation->test(5));
|
||||
}
|
||||
}
|
||||
?>
|
||||
323
tests/simpletest/test/form_test.php
Normal file
323
tests/simpletest/test/form_test.php
Normal file
|
|
@ -0,0 +1,323 @@
|
|||
<?php
|
||||
// $Id: form_test.php 1624 2008-01-01 15:00:43Z pp11 $
|
||||
require_once(dirname(__FILE__) . '/../autorun.php');
|
||||
require_once(dirname(__FILE__) . '/../url.php');
|
||||
require_once(dirname(__FILE__) . '/../form.php');
|
||||
require_once(dirname(__FILE__) . '/../page.php');
|
||||
require_once(dirname(__FILE__) . '/../encoding.php');
|
||||
Mock::generate('SimplePage');
|
||||
|
||||
class TestOfForm extends UnitTestCase {
|
||||
|
||||
function &page($url, $action = false) {
|
||||
$page = &new MockSimplePage();
|
||||
$page->setReturnValue('getUrl', new SimpleUrl($url));
|
||||
$page->setReturnValue('expandUrl', new SimpleUrl($url));
|
||||
return $page;
|
||||
}
|
||||
|
||||
function testFormAttributes() {
|
||||
$tag = &new SimpleFormTag(array('method' => 'GET', 'action' => 'here.php', 'id' => '33'));
|
||||
$form = &new SimpleForm($tag, $this->page('http://host/a/index.html'));
|
||||
$this->assertEqual($form->getMethod(), 'get');
|
||||
$this->assertIdentical($form->getId(), '33');
|
||||
$this->assertNull($form->getValue(new SimpleByName('a')));
|
||||
}
|
||||
|
||||
function testAction() {
|
||||
$page = &new MockSimplePage();
|
||||
$page->expectOnce('expandUrl', array(new SimpleUrl('here.php')));
|
||||
$page->setReturnValue('expandUrl', new SimpleUrl('http://host/here.php'));
|
||||
$tag = &new SimpleFormTag(array('method' => 'GET', 'action' => 'here.php'));
|
||||
$form = &new SimpleForm($tag, $page);
|
||||
$this->assertEqual($form->getAction(), new SimpleUrl('http://host/here.php'));
|
||||
}
|
||||
|
||||
function testEmptyAction() {
|
||||
$tag = &new SimpleFormTag(array('method' => 'GET', 'action' => '', 'id' => '33'));
|
||||
$form = &new SimpleForm($tag, $this->page('http://host/a/index.html'));
|
||||
$this->assertEqual(
|
||||
$form->getAction(),
|
||||
new SimpleUrl('http://host/a/index.html'));
|
||||
}
|
||||
|
||||
function testMissingAction() {
|
||||
$tag = &new SimpleFormTag(array('method' => 'GET'));
|
||||
$form = &new SimpleForm($tag, $this->page('http://host/a/index.html'));
|
||||
$this->assertEqual(
|
||||
$form->getAction(),
|
||||
new SimpleUrl('http://host/a/index.html'));
|
||||
}
|
||||
|
||||
function testRootAction() {
|
||||
$page = &new MockSimplePage();
|
||||
$page->expectOnce('expandUrl', array(new SimpleUrl('/')));
|
||||
$page->setReturnValue('expandUrl', new SimpleUrl('http://host/'));
|
||||
$tag = &new SimpleFormTag(array('method' => 'GET', 'action' => '/'));
|
||||
$form = &new SimpleForm($tag, $page);
|
||||
$this->assertEqual(
|
||||
$form->getAction(),
|
||||
new SimpleUrl('http://host/'));
|
||||
}
|
||||
|
||||
function testDefaultFrameTargetOnForm() {
|
||||
$page = &new MockSimplePage();
|
||||
$page->expectOnce('expandUrl', array(new SimpleUrl('here.php')));
|
||||
$page->setReturnValue('expandUrl', new SimpleUrl('http://host/here.php'));
|
||||
$tag = &new SimpleFormTag(array('method' => 'GET', 'action' => 'here.php'));
|
||||
$form = &new SimpleForm($tag, $page);
|
||||
$form->setDefaultTarget('frame');
|
||||
$expected = new SimpleUrl('http://host/here.php');
|
||||
$expected->setTarget('frame');
|
||||
$this->assertEqual($form->getAction(), $expected);
|
||||
}
|
||||
|
||||
function testTextWidget() {
|
||||
$form = &new SimpleForm(new SimpleFormTag(array()), $this->page('htp://host'));
|
||||
$form->addWidget(new SimpleTextTag(
|
||||
array('name' => 'me', 'type' => 'text', 'value' => 'Myself')));
|
||||
$this->assertIdentical($form->getValue(new SimpleByName('me')), 'Myself');
|
||||
$this->assertTrue($form->setField(new SimpleByName('me'), 'Not me'));
|
||||
$this->assertFalse($form->setField(new SimpleByName('not_present'), 'Not me'));
|
||||
$this->assertIdentical($form->getValue(new SimpleByName('me')), 'Not me');
|
||||
$this->assertNull($form->getValue(new SimpleByName('not_present')));
|
||||
}
|
||||
|
||||
function testTextWidgetById() {
|
||||
$form = &new SimpleForm(new SimpleFormTag(array()), $this->page('htp://host'));
|
||||
$form->addWidget(new SimpleTextTag(
|
||||
array('name' => 'me', 'type' => 'text', 'value' => 'Myself', 'id' => 50)));
|
||||
$this->assertIdentical($form->getValue(new SimpleById(50)), 'Myself');
|
||||
$this->assertTrue($form->setField(new SimpleById(50), 'Not me'));
|
||||
$this->assertIdentical($form->getValue(new SimpleById(50)), 'Not me');
|
||||
}
|
||||
|
||||
function testTextWidgetByLabel() {
|
||||
$form = &new SimpleForm(new SimpleFormTag(array()), $this->page('htp://host'));
|
||||
$widget = &new SimpleTextTag(array('name' => 'me', 'type' => 'text', 'value' => 'a'));
|
||||
$form->addWidget($widget);
|
||||
$widget->setLabel('thing');
|
||||
$this->assertIdentical($form->getValue(new SimpleByLabel('thing')), 'a');
|
||||
$this->assertTrue($form->setField(new SimpleByLabel('thing'), 'b'));
|
||||
$this->assertIdentical($form->getValue(new SimpleByLabel('thing')), 'b');
|
||||
}
|
||||
|
||||
function testSubmitEmpty() {
|
||||
$form = &new SimpleForm(new SimpleFormTag(array()), $this->page('htp://host'));
|
||||
$this->assertIdentical($form->submit(), new SimpleGetEncoding());
|
||||
}
|
||||
|
||||
function testSubmitButton() {
|
||||
$form = &new SimpleForm(new SimpleFormTag(array()), $this->page('http://host'));
|
||||
$form->addWidget(new SimpleSubmitTag(
|
||||
array('type' => 'submit', 'name' => 'go', 'value' => 'Go!', 'id' => '9')));
|
||||
$this->assertTrue($form->hasSubmit(new SimpleByName('go')));
|
||||
$this->assertEqual($form->getValue(new SimpleByName('go')), 'Go!');
|
||||
$this->assertEqual($form->getValue(new SimpleById(9)), 'Go!');
|
||||
$this->assertEqual(
|
||||
$form->submitButton(new SimpleByName('go')),
|
||||
new SimpleGetEncoding(array('go' => 'Go!')));
|
||||
$this->assertEqual(
|
||||
$form->submitButton(new SimpleByLabel('Go!')),
|
||||
new SimpleGetEncoding(array('go' => 'Go!')));
|
||||
$this->assertEqual(
|
||||
$form->submitButton(new SimpleById(9)),
|
||||
new SimpleGetEncoding(array('go' => 'Go!')));
|
||||
}
|
||||
|
||||
function testSubmitWithAdditionalParameters() {
|
||||
$form = &new SimpleForm(new SimpleFormTag(array()), $this->page('http://host'));
|
||||
$form->addWidget(new SimpleSubmitTag(
|
||||
array('type' => 'submit', 'name' => 'go', 'value' => 'Go!')));
|
||||
$this->assertEqual(
|
||||
$form->submitButton(new SimpleByLabel('Go!'), array('a' => 'A')),
|
||||
new SimpleGetEncoding(array('go' => 'Go!', 'a' => 'A')));
|
||||
}
|
||||
|
||||
function testSubmitButtonWithLabelOfSubmit() {
|
||||
$form = &new SimpleForm(new SimpleFormTag(array()), $this->page('http://host'));
|
||||
$form->addWidget(new SimpleSubmitTag(
|
||||
array('type' => 'submit', 'name' => 'test', 'value' => 'Submit')));
|
||||
$this->assertEqual(
|
||||
$form->submitButton(new SimpleByName('test')),
|
||||
new SimpleGetEncoding(array('test' => 'Submit')));
|
||||
$this->assertEqual(
|
||||
$form->submitButton(new SimpleByLabel('Submit')),
|
||||
new SimpleGetEncoding(array('test' => 'Submit')));
|
||||
}
|
||||
|
||||
function testSubmitButtonWithWhitespacePaddedLabelOfSubmit() {
|
||||
$form = &new SimpleForm(new SimpleFormTag(array()), $this->page('http://host'));
|
||||
$form->addWidget(new SimpleSubmitTag(
|
||||
array('type' => 'submit', 'name' => 'test', 'value' => ' Submit ')));
|
||||
$this->assertEqual(
|
||||
$form->submitButton(new SimpleByLabel('Submit')),
|
||||
new SimpleGetEncoding(array('test' => ' Submit ')));
|
||||
}
|
||||
|
||||
function testImageSubmitButton() {
|
||||
$form = &new SimpleForm(new SimpleFormTag(array()), $this->page('htp://host'));
|
||||
$form->addWidget(new SimpleImageSubmitTag(array(
|
||||
'type' => 'image',
|
||||
'src' => 'source.jpg',
|
||||
'name' => 'go',
|
||||
'alt' => 'Go!',
|
||||
'id' => '9')));
|
||||
$this->assertTrue($form->hasImage(new SimpleByLabel('Go!')));
|
||||
$this->assertEqual(
|
||||
$form->submitImage(new SimpleByLabel('Go!'), 100, 101),
|
||||
new SimpleGetEncoding(array('go.x' => 100, 'go.y' => 101)));
|
||||
$this->assertTrue($form->hasImage(new SimpleByName('go')));
|
||||
$this->assertEqual(
|
||||
$form->submitImage(new SimpleByName('go'), 100, 101),
|
||||
new SimpleGetEncoding(array('go.x' => 100, 'go.y' => 101)));
|
||||
$this->assertTrue($form->hasImage(new SimpleById(9)));
|
||||
$this->assertEqual(
|
||||
$form->submitImage(new SimpleById(9), 100, 101),
|
||||
new SimpleGetEncoding(array('go.x' => 100, 'go.y' => 101)));
|
||||
}
|
||||
|
||||
function testImageSubmitButtonWithAdditionalData() {
|
||||
$form = &new SimpleForm(new SimpleFormTag(array()), $this->page('htp://host'));
|
||||
$form->addWidget(new SimpleImageSubmitTag(array(
|
||||
'type' => 'image',
|
||||
'src' => 'source.jpg',
|
||||
'name' => 'go',
|
||||
'alt' => 'Go!')));
|
||||
$this->assertEqual(
|
||||
$form->submitImage(new SimpleByLabel('Go!'), 100, 101, array('a' => 'A')),
|
||||
new SimpleGetEncoding(array('go.x' => 100, 'go.y' => 101, 'a' => 'A')));
|
||||
}
|
||||
|
||||
function testButtonTag() {
|
||||
$form = &new SimpleForm(new SimpleFormTag(array()), $this->page('http://host'));
|
||||
$widget = &new SimpleButtonTag(
|
||||
array('type' => 'submit', 'name' => 'go', 'value' => 'Go', 'id' => '9'));
|
||||
$widget->addContent('Go!');
|
||||
$form->addWidget($widget);
|
||||
$this->assertTrue($form->hasSubmit(new SimpleByName('go')));
|
||||
$this->assertTrue($form->hasSubmit(new SimpleByLabel('Go!')));
|
||||
$this->assertEqual(
|
||||
$form->submitButton(new SimpleByName('go')),
|
||||
new SimpleGetEncoding(array('go' => 'Go')));
|
||||
$this->assertEqual(
|
||||
$form->submitButton(new SimpleByLabel('Go!')),
|
||||
new SimpleGetEncoding(array('go' => 'Go')));
|
||||
$this->assertEqual(
|
||||
$form->submitButton(new SimpleById(9)),
|
||||
new SimpleGetEncoding(array('go' => 'Go')));
|
||||
}
|
||||
|
||||
function testMultipleFieldsWithSameNameSubmitted() {
|
||||
$form = &new SimpleForm(new SimpleFormTag(array()), $this->page('htp://host'));
|
||||
$input = &new SimpleTextTag(array('name' => 'elements[]', 'value' => '1'));
|
||||
$form->addWidget($input);
|
||||
$input = &new SimpleTextTag(array('name' => 'elements[]', 'value' => '2'));
|
||||
$form->addWidget($input);
|
||||
$form->setField(new SimpleByLabelOrName('elements[]'), '3', 1);
|
||||
$form->setField(new SimpleByLabelOrName('elements[]'), '4', 2);
|
||||
$submit = $form->submit();
|
||||
$this->assertEqual(count($submit->_request), 2);
|
||||
$this->assertIdentical($submit->_request[0], new SimpleEncodedPair('elements[]', '3'));
|
||||
$this->assertIdentical($submit->_request[1], new SimpleEncodedPair('elements[]', '4'));
|
||||
}
|
||||
|
||||
function testSingleSelectFieldSubmitted() {
|
||||
$form = &new SimpleForm(new SimpleFormTag(array()), $this->page('htp://host'));
|
||||
$select = &new SimpleSelectionTag(array('name' => 'a'));
|
||||
$select->addTag(new SimpleOptionTag(
|
||||
array('value' => 'aaa', 'selected' => '')));
|
||||
$form->addWidget($select);
|
||||
$this->assertIdentical(
|
||||
$form->submit(),
|
||||
new SimpleGetEncoding(array('a' => 'aaa')));
|
||||
}
|
||||
|
||||
function testSingleSelectFieldSubmittedWithPost() {
|
||||
$form = &new SimpleForm(new SimpleFormTag(array('method' => 'post')), $this->page('htp://host'));
|
||||
$select = &new SimpleSelectionTag(array('name' => 'a'));
|
||||
$select->addTag(new SimpleOptionTag(
|
||||
array('value' => 'aaa', 'selected' => '')));
|
||||
$form->addWidget($select);
|
||||
$this->assertIdentical(
|
||||
$form->submit(),
|
||||
new SimplePostEncoding(array('a' => 'aaa')));
|
||||
}
|
||||
|
||||
function testUnchecked() {
|
||||
$form = &new SimpleForm(new SimpleFormTag(array()), $this->page('htp://host'));
|
||||
$form->addWidget(new SimpleCheckboxTag(
|
||||
array('name' => 'me', 'type' => 'checkbox')));
|
||||
$this->assertIdentical($form->getValue(new SimpleByName('me')), false);
|
||||
$this->assertTrue($form->setField(new SimpleByName('me'), 'on'));
|
||||
$this->assertEqual($form->getValue(new SimpleByName('me')), 'on');
|
||||
$this->assertFalse($form->setField(new SimpleByName('me'), 'other'));
|
||||
$this->assertEqual($form->getValue(new SimpleByName('me')), 'on');
|
||||
}
|
||||
|
||||
function testChecked() {
|
||||
$form = &new SimpleForm(new SimpleFormTag(array()), $this->page('htp://host'));
|
||||
$form->addWidget(new SimpleCheckboxTag(
|
||||
array('name' => 'me', 'value' => 'a', 'type' => 'checkbox', 'checked' => '')));
|
||||
$this->assertIdentical($form->getValue(new SimpleByName('me')), 'a');
|
||||
$this->assertTrue($form->setField(new SimpleByName('me'), 'a'));
|
||||
$this->assertEqual($form->getValue(new SimpleByName('me')), 'a');
|
||||
$this->assertTrue($form->setField(new SimpleByName('me'), false));
|
||||
$this->assertEqual($form->getValue(new SimpleByName('me')), false);
|
||||
}
|
||||
|
||||
function testSingleUncheckedRadioButton() {
|
||||
$form = &new SimpleForm(new SimpleFormTag(array()), $this->page('htp://host'));
|
||||
$form->addWidget(new SimpleRadioButtonTag(
|
||||
array('name' => 'me', 'value' => 'a', 'type' => 'radio')));
|
||||
$this->assertIdentical($form->getValue(new SimpleByName('me')), false);
|
||||
$this->assertTrue($form->setField(new SimpleByName('me'), 'a'));
|
||||
$this->assertEqual($form->getValue(new SimpleByName('me')), 'a');
|
||||
}
|
||||
|
||||
function testSingleCheckedRadioButton() {
|
||||
$form = &new SimpleForm(new SimpleFormTag(array()), $this->page('htp://host'));
|
||||
$form->addWidget(new SimpleRadioButtonTag(
|
||||
array('name' => 'me', 'value' => 'a', 'type' => 'radio', 'checked' => '')));
|
||||
$this->assertIdentical($form->getValue(new SimpleByName('me')), 'a');
|
||||
$this->assertFalse($form->setField(new SimpleByName('me'), 'other'));
|
||||
}
|
||||
|
||||
function testUncheckedRadioButtons() {
|
||||
$form = &new SimpleForm(new SimpleFormTag(array()), $this->page('htp://host'));
|
||||
$form->addWidget(new SimpleRadioButtonTag(
|
||||
array('name' => 'me', 'value' => 'a', 'type' => 'radio')));
|
||||
$form->addWidget(new SimpleRadioButtonTag(
|
||||
array('name' => 'me', 'value' => 'b', 'type' => 'radio')));
|
||||
$this->assertIdentical($form->getValue(new SimpleByName('me')), false);
|
||||
$this->assertTrue($form->setField(new SimpleByName('me'), 'a'));
|
||||
$this->assertIdentical($form->getValue(new SimpleByName('me')), 'a');
|
||||
$this->assertTrue($form->setField(new SimpleByName('me'), 'b'));
|
||||
$this->assertIdentical($form->getValue(new SimpleByName('me')), 'b');
|
||||
$this->assertFalse($form->setField(new SimpleByName('me'), 'c'));
|
||||
$this->assertIdentical($form->getValue(new SimpleByName('me')), 'b');
|
||||
}
|
||||
|
||||
function testCheckedRadioButtons() {
|
||||
$form = &new SimpleForm(new SimpleFormTag(array()), $this->page('htp://host'));
|
||||
$form->addWidget(new SimpleRadioButtonTag(
|
||||
array('name' => 'me', 'value' => 'a', 'type' => 'radio')));
|
||||
$form->addWidget(new SimpleRadioButtonTag(
|
||||
array('name' => 'me', 'value' => 'b', 'type' => 'radio', 'checked' => '')));
|
||||
$this->assertIdentical($form->getValue(new SimpleByName('me')), 'b');
|
||||
$this->assertTrue($form->setField(new SimpleByName('me'), 'a'));
|
||||
$this->assertIdentical($form->getValue(new SimpleByName('me')), 'a');
|
||||
}
|
||||
|
||||
function testMultipleFieldsWithSameKey() {
|
||||
$form = &new SimpleForm(new SimpleFormTag(array()), $this->page('htp://host'));
|
||||
$form->addWidget(new SimpleCheckboxTag(
|
||||
array('name' => 'a', 'type' => 'checkbox', 'value' => 'me')));
|
||||
$form->addWidget(new SimpleCheckboxTag(
|
||||
array('name' => 'a', 'type' => 'checkbox', 'value' => 'you')));
|
||||
$this->assertIdentical($form->getValue(new SimpleByName('a')), false);
|
||||
$this->assertTrue($form->setField(new SimpleByName('a'), 'me'));
|
||||
$this->assertIdentical($form->getValue(new SimpleByName('a')), 'me');
|
||||
}
|
||||
}
|
||||
?>
|
||||
549
tests/simpletest/test/frames_test.php
Normal file
549
tests/simpletest/test/frames_test.php
Normal file
|
|
@ -0,0 +1,549 @@
|
|||
<?php
|
||||
// $Id: frames_test.php 1555 2007-07-14 02:04:34Z lastcraft $
|
||||
require_once(dirname(__FILE__) . '/../autorun.php');
|
||||
require_once(dirname(__FILE__) . '/../tag.php');
|
||||
require_once(dirname(__FILE__) . '/../page.php');
|
||||
require_once(dirname(__FILE__) . '/../frames.php');
|
||||
Mock::generate('SimplePage');
|
||||
Mock::generate('SimpleForm');
|
||||
|
||||
class TestOfFrameset extends UnitTestCase {
|
||||
|
||||
function testTitleReadFromFramesetPage() {
|
||||
$page = &new MockSimplePage();
|
||||
$page->setReturnValue('getTitle', 'This page');
|
||||
$frameset = &new SimpleFrameset($page);
|
||||
$this->assertEqual($frameset->getTitle(), 'This page');
|
||||
}
|
||||
|
||||
function TestHeadersReadFromFramesetByDefault() {
|
||||
$page = &new MockSimplePage();
|
||||
$page->setReturnValue('getHeaders', 'Header: content');
|
||||
$page->setReturnValue('getMimeType', 'text/xml');
|
||||
$page->setReturnValue('getResponseCode', 401);
|
||||
$page->setReturnValue('getTransportError', 'Could not parse headers');
|
||||
$page->setReturnValue('getAuthentication', 'Basic');
|
||||
$page->setReturnValue('getRealm', 'Safe place');
|
||||
|
||||
$frameset = &new SimpleFrameset($page);
|
||||
|
||||
$this->assertIdentical($frameset->getHeaders(), 'Header: content');
|
||||
$this->assertIdentical($frameset->getMimeType(), 'text/xml');
|
||||
$this->assertIdentical($frameset->getResponseCode(), 401);
|
||||
$this->assertIdentical($frameset->getTransportError(), 'Could not parse headers');
|
||||
$this->assertIdentical($frameset->getAuthentication(), 'Basic');
|
||||
$this->assertIdentical($frameset->getRealm(), 'Safe place');
|
||||
}
|
||||
|
||||
function testEmptyFramesetHasNoContent() {
|
||||
$page = &new MockSimplePage();
|
||||
$page->setReturnValue('getRaw', 'This content');
|
||||
$frameset = &new SimpleFrameset($page);
|
||||
$this->assertEqual($frameset->getRaw(), '');
|
||||
}
|
||||
|
||||
function testRawContentIsFromOnlyFrame() {
|
||||
$page = &new MockSimplePage();
|
||||
$page->expectNever('getRaw');
|
||||
|
||||
$frame = &new MockSimplePage();
|
||||
$frame->setReturnValue('getRaw', 'Stuff');
|
||||
|
||||
$frameset = &new SimpleFrameset($page);
|
||||
$frameset->addFrame($frame);
|
||||
$this->assertEqual($frameset->getRaw(), 'Stuff');
|
||||
}
|
||||
|
||||
function testRawContentIsFromAllFrames() {
|
||||
$page = &new MockSimplePage();
|
||||
$page->expectNever('getRaw');
|
||||
|
||||
$frame1 = &new MockSimplePage();
|
||||
$frame1->setReturnValue('getRaw', 'Stuff1');
|
||||
|
||||
$frame2 = &new MockSimplePage();
|
||||
$frame2->setReturnValue('getRaw', 'Stuff2');
|
||||
|
||||
$frameset = &new SimpleFrameset($page);
|
||||
$frameset->addFrame($frame1);
|
||||
$frameset->addFrame($frame2);
|
||||
$this->assertEqual($frameset->getRaw(), 'Stuff1Stuff2');
|
||||
}
|
||||
|
||||
function testTextContentIsFromOnlyFrame() {
|
||||
$page = &new MockSimplePage();
|
||||
$page->expectNever('getText');
|
||||
|
||||
$frame = &new MockSimplePage();
|
||||
$frame->setReturnValue('getText', 'Stuff');
|
||||
|
||||
$frameset = &new SimpleFrameset($page);
|
||||
$frameset->addFrame($frame);
|
||||
$this->assertEqual($frameset->getText(), 'Stuff');
|
||||
}
|
||||
|
||||
function testTextContentIsFromAllFrames() {
|
||||
$page = &new MockSimplePage();
|
||||
$page->expectNever('getText');
|
||||
|
||||
$frame1 = &new MockSimplePage();
|
||||
$frame1->setReturnValue('getText', 'Stuff1');
|
||||
|
||||
$frame2 = &new MockSimplePage();
|
||||
$frame2->setReturnValue('getText', 'Stuff2');
|
||||
|
||||
$frameset = &new SimpleFrameset($page);
|
||||
$frameset->addFrame($frame1);
|
||||
$frameset->addFrame($frame2);
|
||||
$this->assertEqual($frameset->getText(), 'Stuff1 Stuff2');
|
||||
}
|
||||
|
||||
function testFieldFoundIsFirstInFramelist() {
|
||||
$frame1 = &new MockSimplePage();
|
||||
$frame1->setReturnValue('getField', null);
|
||||
$frame1->expectOnce('getField', array(new SimpleByName('a')));
|
||||
|
||||
$frame2 = &new MockSimplePage();
|
||||
$frame2->setReturnValue('getField', 'A');
|
||||
$frame2->expectOnce('getField', array(new SimpleByName('a')));
|
||||
|
||||
$frame3 = &new MockSimplePage();
|
||||
$frame3->expectNever('getField');
|
||||
|
||||
$page = &new MockSimplePage();
|
||||
$frameset = &new SimpleFrameset($page);
|
||||
$frameset->addFrame($frame1);
|
||||
$frameset->addFrame($frame2);
|
||||
$frameset->addFrame($frame3);
|
||||
$this->assertIdentical($frameset->getField(new SimpleByName('a')), 'A');
|
||||
}
|
||||
|
||||
function testFrameReplacementByIndex() {
|
||||
$page = &new MockSimplePage();
|
||||
$page->expectNever('getRaw');
|
||||
|
||||
$frame1 = &new MockSimplePage();
|
||||
$frame1->setReturnValue('getRaw', 'Stuff1');
|
||||
|
||||
$frame2 = &new MockSimplePage();
|
||||
$frame2->setReturnValue('getRaw', 'Stuff2');
|
||||
|
||||
$frameset = &new SimpleFrameset($page);
|
||||
$frameset->addFrame($frame1);
|
||||
$frameset->setFrame(array(1), $frame2);
|
||||
$this->assertEqual($frameset->getRaw(), 'Stuff2');
|
||||
}
|
||||
|
||||
function testFrameReplacementByName() {
|
||||
$page = &new MockSimplePage();
|
||||
$page->expectNever('getRaw');
|
||||
|
||||
$frame1 = &new MockSimplePage();
|
||||
$frame1->setReturnValue('getRaw', 'Stuff1');
|
||||
|
||||
$frame2 = &new MockSimplePage();
|
||||
$frame2->setReturnValue('getRaw', 'Stuff2');
|
||||
|
||||
$frameset = &new SimpleFrameset($page);
|
||||
$frameset->addFrame($frame1, 'a');
|
||||
$frameset->setFrame(array('a'), $frame2);
|
||||
$this->assertEqual($frameset->getRaw(), 'Stuff2');
|
||||
}
|
||||
}
|
||||
|
||||
class TestOfFrameNavigation extends UnitTestCase {
|
||||
|
||||
function testStartsWithoutFrameFocus() {
|
||||
$page = &new MockSimplePage();
|
||||
$frameset = &new SimpleFrameset($page);
|
||||
$frameset->addFrame($frame);
|
||||
$this->assertFalse($frameset->getFrameFocus());
|
||||
}
|
||||
|
||||
function testCanFocusOnSingleFrame() {
|
||||
$page = &new MockSimplePage();
|
||||
$page->expectNever('getRaw');
|
||||
|
||||
$frame = &new MockSimplePage();
|
||||
$frame->setReturnValue('getFrameFocus', array());
|
||||
$frame->setReturnValue('getRaw', 'Stuff');
|
||||
|
||||
$frameset = &new SimpleFrameset($page);
|
||||
$frameset->addFrame($frame);
|
||||
|
||||
$this->assertFalse($frameset->setFrameFocusByIndex(0));
|
||||
$this->assertTrue($frameset->setFrameFocusByIndex(1));
|
||||
$this->assertEqual($frameset->getRaw(), 'Stuff');
|
||||
$this->assertFalse($frameset->setFrameFocusByIndex(2));
|
||||
$this->assertIdentical($frameset->getFrameFocus(), array(1));
|
||||
}
|
||||
|
||||
function testContentComesFromFrameInFocus() {
|
||||
$page = &new MockSimplePage();
|
||||
|
||||
$frame1 = &new MockSimplePage();
|
||||
$frame1->setReturnValue('getRaw', 'Stuff1');
|
||||
$frame1->setReturnValue('getFrameFocus', array());
|
||||
|
||||
$frame2 = &new MockSimplePage();
|
||||
$frame2->setReturnValue('getRaw', 'Stuff2');
|
||||
$frame2->setReturnValue('getFrameFocus', array());
|
||||
|
||||
$frameset = &new SimpleFrameset($page);
|
||||
$frameset->addFrame($frame1);
|
||||
$frameset->addFrame($frame2);
|
||||
|
||||
$this->assertTrue($frameset->setFrameFocusByIndex(1));
|
||||
$this->assertEqual($frameset->getFrameFocus(), array(1));
|
||||
$this->assertEqual($frameset->getRaw(), 'Stuff1');
|
||||
|
||||
$this->assertTrue($frameset->setFrameFocusByIndex(2));
|
||||
$this->assertEqual($frameset->getFrameFocus(), array(2));
|
||||
$this->assertEqual($frameset->getRaw(), 'Stuff2');
|
||||
|
||||
$this->assertFalse($frameset->setFrameFocusByIndex(3));
|
||||
$this->assertEqual($frameset->getFrameFocus(), array(2));
|
||||
|
||||
$frameset->clearFrameFocus();
|
||||
$this->assertEqual($frameset->getRaw(), 'Stuff1Stuff2');
|
||||
}
|
||||
|
||||
function testCanFocusByName() {
|
||||
$page = &new MockSimplePage();
|
||||
|
||||
$frame1 = &new MockSimplePage();
|
||||
$frame1->setReturnValue('getRaw', 'Stuff1');
|
||||
$frame1->setReturnValue('getFrameFocus', array());
|
||||
|
||||
$frame2 = &new MockSimplePage();
|
||||
$frame2->setReturnValue('getRaw', 'Stuff2');
|
||||
$frame2->setReturnValue('getFrameFocus', array());
|
||||
|
||||
$frameset = &new SimpleFrameset($page);
|
||||
$frameset->addFrame($frame1, 'A');
|
||||
$frameset->addFrame($frame2, 'B');
|
||||
|
||||
$this->assertTrue($frameset->setFrameFocus('A'));
|
||||
$this->assertEqual($frameset->getFrameFocus(), array('A'));
|
||||
$this->assertEqual($frameset->getRaw(), 'Stuff1');
|
||||
|
||||
$this->assertTrue($frameset->setFrameFocusByIndex(2));
|
||||
$this->assertEqual($frameset->getFrameFocus(), array('B'));
|
||||
$this->assertEqual($frameset->getRaw(), 'Stuff2');
|
||||
|
||||
$this->assertFalse($frameset->setFrameFocus('z'));
|
||||
|
||||
$frameset->clearFrameFocus();
|
||||
$this->assertEqual($frameset->getRaw(), 'Stuff1Stuff2');
|
||||
}
|
||||
}
|
||||
|
||||
class TestOfFramesetPageInterface extends UnitTestCase {
|
||||
var $_page_interface;
|
||||
var $_frameset_interface;
|
||||
|
||||
function TestOfFramesetPageInterface() {
|
||||
$this->UnitTestCase();
|
||||
$this->_page_interface = $this->_getPageMethods();
|
||||
$this->_frameset_interface = $this->_getFramesetMethods();
|
||||
}
|
||||
|
||||
function assertListInAnyOrder($list, $expected) {
|
||||
sort($list);
|
||||
sort($expected);
|
||||
$this->assertEqual($list, $expected);
|
||||
}
|
||||
|
||||
function _getPageMethods() {
|
||||
$methods = array();
|
||||
foreach (get_class_methods('SimplePage') as $method) {
|
||||
if (strtolower($method) == strtolower('SimplePage')) {
|
||||
continue;
|
||||
}
|
||||
if (strtolower($method) == strtolower('getFrameset')) {
|
||||
continue;
|
||||
}
|
||||
if (strncmp($method, '_', 1) == 0) {
|
||||
continue;
|
||||
}
|
||||
if (strncmp($method, 'accept', 6) == 0) {
|
||||
continue;
|
||||
}
|
||||
$methods[] = $method;
|
||||
}
|
||||
return $methods;
|
||||
}
|
||||
|
||||
function _getFramesetMethods() {
|
||||
$methods = array();
|
||||
foreach (get_class_methods('SimpleFrameset') as $method) {
|
||||
if (strtolower($method) == strtolower('SimpleFrameset')) {
|
||||
continue;
|
||||
}
|
||||
if (strncmp($method, '_', 1) == 0) {
|
||||
continue;
|
||||
}
|
||||
if (strncmp($method, 'add', 3) == 0) {
|
||||
continue;
|
||||
}
|
||||
$methods[] = $method;
|
||||
}
|
||||
return $methods;
|
||||
}
|
||||
|
||||
function testFramsetHasPageInterface() {
|
||||
$difference = array();
|
||||
foreach ($this->_page_interface as $method) {
|
||||
if (! in_array($method, $this->_frameset_interface)) {
|
||||
$this->fail("No [$method] in Frameset class");
|
||||
return;
|
||||
}
|
||||
}
|
||||
$this->pass('Frameset covers Page interface');
|
||||
}
|
||||
|
||||
function testHeadersReadFromFrameIfInFocus() {
|
||||
$frame = &new MockSimplePage();
|
||||
$frame->setReturnValue('getUrl', new SimpleUrl('http://localhost/stuff'));
|
||||
|
||||
$frame->setReturnValue('getRequest', 'POST stuff');
|
||||
$frame->setReturnValue('getMethod', 'POST');
|
||||
$frame->setReturnValue('getRequestData', array('a' => 'A'));
|
||||
$frame->setReturnValue('getHeaders', 'Header: content');
|
||||
$frame->setReturnValue('getMimeType', 'text/xml');
|
||||
$frame->setReturnValue('getResponseCode', 401);
|
||||
$frame->setReturnValue('getTransportError', 'Could not parse headers');
|
||||
$frame->setReturnValue('getAuthentication', 'Basic');
|
||||
$frame->setReturnValue('getRealm', 'Safe place');
|
||||
|
||||
$frameset = &new SimpleFrameset(new MockSimplePage());
|
||||
$frameset->addFrame($frame);
|
||||
$frameset->setFrameFocusByIndex(1);
|
||||
|
||||
$url = new SimpleUrl('http://localhost/stuff');
|
||||
$url->setTarget(1);
|
||||
$this->assertIdentical($frameset->getUrl(), $url);
|
||||
|
||||
$this->assertIdentical($frameset->getRequest(), 'POST stuff');
|
||||
$this->assertIdentical($frameset->getMethod(), 'POST');
|
||||
$this->assertIdentical($frameset->getRequestData(), array('a' => 'A'));
|
||||
$this->assertIdentical($frameset->getHeaders(), 'Header: content');
|
||||
$this->assertIdentical($frameset->getMimeType(), 'text/xml');
|
||||
$this->assertIdentical($frameset->getResponseCode(), 401);
|
||||
$this->assertIdentical($frameset->getTransportError(), 'Could not parse headers');
|
||||
$this->assertIdentical($frameset->getAuthentication(), 'Basic');
|
||||
$this->assertIdentical($frameset->getRealm(), 'Safe place');
|
||||
}
|
||||
|
||||
function testUrlsComeFromBothFrames() {
|
||||
$page = &new MockSimplePage();
|
||||
$page->expectNever('getUrls');
|
||||
|
||||
$frame1 = &new MockSimplePage();
|
||||
$frame1->setReturnValue(
|
||||
'getUrls',
|
||||
array('http://www.lastcraft.com/', 'http://myserver/'));
|
||||
|
||||
$frame2 = &new MockSimplePage();
|
||||
$frame2->setReturnValue(
|
||||
'getUrls',
|
||||
array('http://www.lastcraft.com/', 'http://test/'));
|
||||
|
||||
$frameset = &new SimpleFrameset($page);
|
||||
$frameset->addFrame($frame1);
|
||||
$frameset->addFrame($frame2);
|
||||
$this->assertListInAnyOrder(
|
||||
$frameset->getUrls(),
|
||||
array('http://www.lastcraft.com/', 'http://myserver/', 'http://test/'));
|
||||
}
|
||||
|
||||
function testLabelledUrlsComeFromBothFrames() {
|
||||
$frame1 = &new MockSimplePage();
|
||||
$frame1->setReturnValue(
|
||||
'getUrlsByLabel',
|
||||
array(new SimpleUrl('goodbye.php')),
|
||||
array('a'));
|
||||
|
||||
$frame2 = &new MockSimplePage();
|
||||
$frame2->setReturnValue(
|
||||
'getUrlsByLabel',
|
||||
array(new SimpleUrl('hello.php')),
|
||||
array('a'));
|
||||
|
||||
$frameset = &new SimpleFrameset(new MockSimplePage());
|
||||
$frameset->addFrame($frame1);
|
||||
$frameset->addFrame($frame2, 'Two');
|
||||
|
||||
$expected1 = new SimpleUrl('goodbye.php');
|
||||
$expected1->setTarget(1);
|
||||
$expected2 = new SimpleUrl('hello.php');
|
||||
$expected2->setTarget('Two');
|
||||
$this->assertEqual(
|
||||
$frameset->getUrlsByLabel('a'),
|
||||
array($expected1, $expected2));
|
||||
}
|
||||
|
||||
function testUrlByIdComesFromFirstFrameToRespond() {
|
||||
$frame1 = &new MockSimplePage();
|
||||
$frame1->setReturnValue('getUrlById', new SimpleUrl('four.php'), array(4));
|
||||
$frame1->setReturnValue('getUrlById', false, array(5));
|
||||
|
||||
$frame2 = &new MockSimplePage();
|
||||
$frame2->setReturnValue('getUrlById', false, array(4));
|
||||
$frame2->setReturnValue('getUrlById', new SimpleUrl('five.php'), array(5));
|
||||
|
||||
$frameset = &new SimpleFrameset(new MockSimplePage());
|
||||
$frameset->addFrame($frame1);
|
||||
$frameset->addFrame($frame2);
|
||||
|
||||
$four = new SimpleUrl('four.php');
|
||||
$four->setTarget(1);
|
||||
$this->assertEqual($frameset->getUrlById(4), $four);
|
||||
$five = new SimpleUrl('five.php');
|
||||
$five->setTarget(2);
|
||||
$this->assertEqual($frameset->getUrlById(5), $five);
|
||||
}
|
||||
|
||||
function testReadUrlsFromFrameInFocus() {
|
||||
$frame1 = &new MockSimplePage();
|
||||
$frame1->setReturnValue('getUrls', array('a'));
|
||||
$frame1->setReturnValue('getUrlsByLabel', array(new SimpleUrl('l')));
|
||||
$frame1->setReturnValue('getUrlById', new SimpleUrl('i'));
|
||||
|
||||
$frame2 = &new MockSimplePage();
|
||||
$frame2->expectNever('getUrls');
|
||||
$frame2->expectNever('getUrlsByLabel');
|
||||
$frame2->expectNever('getUrlById');
|
||||
|
||||
$frameset = &new SimpleFrameset(new MockSimplePage());
|
||||
$frameset->addFrame($frame1, 'A');
|
||||
$frameset->addFrame($frame2, 'B');
|
||||
$frameset->setFrameFocus('A');
|
||||
|
||||
$this->assertIdentical($frameset->getUrls(), array('a'));
|
||||
$expected = new SimpleUrl('l');
|
||||
$expected->setTarget('A');
|
||||
$this->assertIdentical($frameset->getUrlsByLabel('label'), array($expected));
|
||||
$expected = new SimpleUrl('i');
|
||||
$expected->setTarget('A');
|
||||
$this->assertIdentical($frameset->getUrlById(99), $expected);
|
||||
}
|
||||
|
||||
function testReadFrameTaggedUrlsFromFrameInFocus() {
|
||||
$frame = &new MockSimplePage();
|
||||
|
||||
$by_label = new SimpleUrl('l');
|
||||
$by_label->setTarget('L');
|
||||
$frame->setReturnValue('getUrlsByLabel', array($by_label));
|
||||
|
||||
$by_id = new SimpleUrl('i');
|
||||
$by_id->setTarget('I');
|
||||
$frame->setReturnValue('getUrlById', $by_id);
|
||||
|
||||
$frameset = &new SimpleFrameset(new MockSimplePage());
|
||||
$frameset->addFrame($frame, 'A');
|
||||
$frameset->setFrameFocus('A');
|
||||
|
||||
$this->assertIdentical($frameset->getUrlsByLabel('label'), array($by_label));
|
||||
$this->assertIdentical($frameset->getUrlById(99), $by_id);
|
||||
}
|
||||
|
||||
function testFindingFormsById() {
|
||||
$frame = &new MockSimplePage();
|
||||
$form = &new MockSimpleForm();
|
||||
$frame->setReturnReference('getFormById', $form, array('a'));
|
||||
|
||||
$frameset = &new SimpleFrameset(new MockSimplePage());
|
||||
$frameset->addFrame(new MockSimplePage(), 'A');
|
||||
$frameset->addFrame($frame, 'B');
|
||||
$this->assertReference($frameset->getFormById('a'), $form);
|
||||
|
||||
$frameset->setFrameFocus('A');
|
||||
$this->assertNull($frameset->getFormById('a'));
|
||||
|
||||
$frameset->setFrameFocus('B');
|
||||
$this->assertReference($frameset->getFormById('a'), $form);
|
||||
}
|
||||
|
||||
function testFindingFormsBySubmit() {
|
||||
$frame = &new MockSimplePage();
|
||||
$form = &new MockSimpleForm();
|
||||
$frame->setReturnReference(
|
||||
'getFormBySubmit',
|
||||
$form,
|
||||
array(new SimpleByLabel('a')));
|
||||
|
||||
$frameset = &new SimpleFrameset(new MockSimplePage());
|
||||
$frameset->addFrame(new MockSimplePage(), 'A');
|
||||
$frameset->addFrame($frame, 'B');
|
||||
$this->assertReference($frameset->getFormBySubmit(new SimpleByLabel('a')), $form);
|
||||
|
||||
$frameset->setFrameFocus('A');
|
||||
$this->assertNull($frameset->getFormBySubmit(new SimpleByLabel('a')));
|
||||
|
||||
$frameset->setFrameFocus('B');
|
||||
$this->assertReference($frameset->getFormBySubmit(new SimpleByLabel('a')), $form);
|
||||
}
|
||||
|
||||
function testFindingFormsByImage() {
|
||||
$frame = &new MockSimplePage();
|
||||
$form = &new MockSimpleForm();
|
||||
$frame->setReturnReference(
|
||||
'getFormByImage',
|
||||
$form,
|
||||
array(new SimpleByLabel('a')));
|
||||
|
||||
$frameset = &new SimpleFrameset(new MockSimplePage());
|
||||
$frameset->addFrame(new MockSimplePage(), 'A');
|
||||
$frameset->addFrame($frame, 'B');
|
||||
$this->assertReference($frameset->getFormByImage(new SimpleByLabel('a')), $form);
|
||||
|
||||
$frameset->setFrameFocus('A');
|
||||
$this->assertNull($frameset->getFormByImage(new SimpleByLabel('a')));
|
||||
|
||||
$frameset->setFrameFocus('B');
|
||||
$this->assertReference($frameset->getFormByImage(new SimpleByLabel('a')), $form);
|
||||
}
|
||||
|
||||
function testSettingAllFrameFieldsWhenNoFrameFocus() {
|
||||
$frame1 = &new MockSimplePage();
|
||||
$frame1->expectOnce('setField', array(new SimpleById(22), 'A'));
|
||||
|
||||
$frame2 = &new MockSimplePage();
|
||||
$frame2->expectOnce('setField', array(new SimpleById(22), 'A'));
|
||||
|
||||
$frameset = &new SimpleFrameset(new MockSimplePage());
|
||||
$frameset->addFrame($frame1, 'A');
|
||||
$frameset->addFrame($frame2, 'B');
|
||||
$frameset->setField(new SimpleById(22), 'A');
|
||||
}
|
||||
|
||||
function testOnlySettingFieldFromFocusedFrame() {
|
||||
$frame1 = &new MockSimplePage();
|
||||
$frame1->expectOnce('setField', array(new SimpleByLabelOrName('a'), 'A'));
|
||||
|
||||
$frame2 = &new MockSimplePage();
|
||||
$frame2->expectNever('setField');
|
||||
|
||||
$frameset = &new SimpleFrameset(new MockSimplePage());
|
||||
$frameset->addFrame($frame1, 'A');
|
||||
$frameset->addFrame($frame2, 'B');
|
||||
$frameset->setFrameFocus('A');
|
||||
$frameset->setField(new SimpleByLabelOrName('a'), 'A');
|
||||
}
|
||||
|
||||
function testOnlyGettingFieldFromFocusedFrame() {
|
||||
$frame1 = &new MockSimplePage();
|
||||
$frame1->setReturnValue('getField', 'f', array(new SimpleByName('a')));
|
||||
|
||||
$frame2 = &new MockSimplePage();
|
||||
$frame2->expectNever('getField');
|
||||
|
||||
$frameset = &new SimpleFrameset(new MockSimplePage());
|
||||
$frameset->addFrame($frame1, 'A');
|
||||
$frameset->addFrame($frame2, 'B');
|
||||
$frameset->setFrameFocus('A');
|
||||
$this->assertIdentical($frameset->getField(new SimpleByName('a')), 'f');
|
||||
}
|
||||
}
|
||||
?>
|
||||
427
tests/simpletest/test/http_test.php
Normal file
427
tests/simpletest/test/http_test.php
Normal file
|
|
@ -0,0 +1,427 @@
|
|||
<?php
|
||||
// $Id: http_test.php 1505 2007-04-30 23:39:59Z lastcraft $
|
||||
require_once(dirname(__FILE__) . '/../autorun.php');
|
||||
require_once(dirname(__FILE__) . '/../encoding.php');
|
||||
require_once(dirname(__FILE__) . '/../http.php');
|
||||
require_once(dirname(__FILE__) . '/../socket.php');
|
||||
require_once(dirname(__FILE__) . '/../cookies.php');
|
||||
Mock::generate('SimpleSocket');
|
||||
Mock::generate('SimpleCookieJar');
|
||||
Mock::generate('SimpleRoute');
|
||||
Mock::generatePartial('SimpleRoute', 'PartialSimpleRoute', array('_createSocket'));
|
||||
Mock::generatePartial(
|
||||
'SimpleProxyRoute',
|
||||
'PartialSimpleProxyRoute',
|
||||
array('_createSocket'));
|
||||
|
||||
class TestOfDirectRoute extends UnitTestCase {
|
||||
|
||||
function testDefaultGetRequest() {
|
||||
$socket = &new MockSimpleSocket();
|
||||
$socket->expectArgumentsAt(0, 'write', array("GET /here.html HTTP/1.0\r\n"));
|
||||
$socket->expectArgumentsAt(1, 'write', array("Host: a.valid.host\r\n"));
|
||||
$socket->expectArgumentsAt(2, 'write', array("Connection: close\r\n"));
|
||||
$socket->expectCallCount('write', 3);
|
||||
|
||||
$route = &new PartialSimpleRoute();
|
||||
$route->setReturnReference('_createSocket', $socket);
|
||||
$route->SimpleRoute(new SimpleUrl('http://a.valid.host/here.html'));
|
||||
|
||||
$this->assertReference($route->createConnection('GET', 15), $socket);
|
||||
}
|
||||
|
||||
function testDefaultPostRequest() {
|
||||
$socket = &new MockSimpleSocket();
|
||||
$socket->expectArgumentsAt(0, 'write', array("POST /here.html HTTP/1.0\r\n"));
|
||||
$socket->expectArgumentsAt(1, 'write', array("Host: a.valid.host\r\n"));
|
||||
$socket->expectArgumentsAt(2, 'write', array("Connection: close\r\n"));
|
||||
$socket->expectCallCount('write', 3);
|
||||
|
||||
$route = &new PartialSimpleRoute();
|
||||
$route->setReturnReference('_createSocket', $socket);
|
||||
$route->SimpleRoute(new SimpleUrl('http://a.valid.host/here.html'));
|
||||
|
||||
$route->createConnection('POST', 15);
|
||||
}
|
||||
|
||||
function testGetWithPort() {
|
||||
$socket = &new MockSimpleSocket();
|
||||
$socket->expectArgumentsAt(0, 'write', array("GET /here.html HTTP/1.0\r\n"));
|
||||
$socket->expectArgumentsAt(1, 'write', array("Host: a.valid.host:81\r\n"));
|
||||
$socket->expectArgumentsAt(2, 'write', array("Connection: close\r\n"));
|
||||
$socket->expectCallCount('write', 3);
|
||||
|
||||
$route = &new PartialSimpleRoute();
|
||||
$route->setReturnReference('_createSocket', $socket);
|
||||
$route->SimpleRoute(new SimpleUrl('http://a.valid.host:81/here.html'));
|
||||
|
||||
$route->createConnection('GET', 15);
|
||||
}
|
||||
|
||||
function testGetWithParameters() {
|
||||
$socket = &new MockSimpleSocket();
|
||||
$socket->expectArgumentsAt(0, 'write', array("GET /here.html?a=1&b=2 HTTP/1.0\r\n"));
|
||||
$socket->expectArgumentsAt(1, 'write', array("Host: a.valid.host\r\n"));
|
||||
$socket->expectArgumentsAt(2, 'write', array("Connection: close\r\n"));
|
||||
$socket->expectCallCount('write', 3);
|
||||
|
||||
$route = &new PartialSimpleRoute();
|
||||
$route->setReturnReference('_createSocket', $socket);
|
||||
$route->SimpleRoute(new SimpleUrl('http://a.valid.host/here.html?a=1&b=2'));
|
||||
|
||||
$route->createConnection('GET', 15);
|
||||
}
|
||||
}
|
||||
|
||||
class TestOfProxyRoute extends UnitTestCase {
|
||||
|
||||
function testDefaultGet() {
|
||||
$socket = &new MockSimpleSocket();
|
||||
$socket->expectArgumentsAt(0, 'write', array("GET http://a.valid.host/here.html HTTP/1.0\r\n"));
|
||||
$socket->expectArgumentsAt(1, 'write', array("Host: my-proxy:8080\r\n"));
|
||||
$socket->expectArgumentsAt(2, 'write', array("Connection: close\r\n"));
|
||||
$socket->expectCallCount('write', 3);
|
||||
|
||||
$route = &new PartialSimpleProxyRoute();
|
||||
$route->setReturnReference('_createSocket', $socket);
|
||||
$route->SimpleProxyRoute(
|
||||
new SimpleUrl('http://a.valid.host/here.html'),
|
||||
new SimpleUrl('http://my-proxy'));
|
||||
$route->createConnection('GET', 15);
|
||||
}
|
||||
|
||||
function testDefaultPost() {
|
||||
$socket = &new MockSimpleSocket();
|
||||
$socket->expectArgumentsAt(0, 'write', array("POST http://a.valid.host/here.html HTTP/1.0\r\n"));
|
||||
$socket->expectArgumentsAt(1, 'write', array("Host: my-proxy:8080\r\n"));
|
||||
$socket->expectArgumentsAt(2, 'write', array("Connection: close\r\n"));
|
||||
$socket->expectCallCount('write', 3);
|
||||
|
||||
$route = &new PartialSimpleProxyRoute();
|
||||
$route->setReturnReference('_createSocket', $socket);
|
||||
$route->SimpleProxyRoute(
|
||||
new SimpleUrl('http://a.valid.host/here.html'),
|
||||
new SimpleUrl('http://my-proxy'));
|
||||
$route->createConnection('POST', 15);
|
||||
}
|
||||
|
||||
function testGetWithPort() {
|
||||
$socket = &new MockSimpleSocket();
|
||||
$socket->expectArgumentsAt(0, 'write', array("GET http://a.valid.host:81/here.html HTTP/1.0\r\n"));
|
||||
$socket->expectArgumentsAt(1, 'write', array("Host: my-proxy:8081\r\n"));
|
||||
$socket->expectArgumentsAt(2, 'write', array("Connection: close\r\n"));
|
||||
$socket->expectCallCount('write', 3);
|
||||
|
||||
$route = &new PartialSimpleProxyRoute();
|
||||
$route->setReturnReference('_createSocket', $socket);
|
||||
$route->SimpleProxyRoute(
|
||||
new SimpleUrl('http://a.valid.host:81/here.html'),
|
||||
new SimpleUrl('http://my-proxy:8081'));
|
||||
$route->createConnection('GET', 15);
|
||||
}
|
||||
|
||||
function testGetWithParameters() {
|
||||
$socket = &new MockSimpleSocket();
|
||||
$socket->expectArgumentsAt(0, 'write', array("GET http://a.valid.host/here.html?a=1&b=2 HTTP/1.0\r\n"));
|
||||
$socket->expectArgumentsAt(1, 'write', array("Host: my-proxy:8080\r\n"));
|
||||
$socket->expectArgumentsAt(2, 'write', array("Connection: close\r\n"));
|
||||
$socket->expectCallCount('write', 3);
|
||||
|
||||
$route = &new PartialSimpleProxyRoute();
|
||||
$route->setReturnReference('_createSocket', $socket);
|
||||
$route->SimpleProxyRoute(
|
||||
new SimpleUrl('http://a.valid.host/here.html?a=1&b=2'),
|
||||
new SimpleUrl('http://my-proxy'));
|
||||
$route->createConnection('GET', 15);
|
||||
}
|
||||
|
||||
function testGetWithAuthentication() {
|
||||
$encoded = base64_encode('Me:Secret');
|
||||
|
||||
$socket = &new MockSimpleSocket();
|
||||
$socket->expectArgumentsAt(0, 'write', array("GET http://a.valid.host/here.html HTTP/1.0\r\n"));
|
||||
$socket->expectArgumentsAt(1, 'write', array("Host: my-proxy:8080\r\n"));
|
||||
$socket->expectArgumentsAt(2, 'write', array("Proxy-Authorization: Basic $encoded\r\n"));
|
||||
$socket->expectArgumentsAt(3, 'write', array("Connection: close\r\n"));
|
||||
$socket->expectCallCount('write', 4);
|
||||
|
||||
$route = &new PartialSimpleProxyRoute();
|
||||
$route->setReturnReference('_createSocket', $socket);
|
||||
$route->SimpleProxyRoute(
|
||||
new SimpleUrl('http://a.valid.host/here.html'),
|
||||
new SimpleUrl('http://my-proxy'),
|
||||
'Me',
|
||||
'Secret');
|
||||
$route->createConnection('GET', 15);
|
||||
}
|
||||
}
|
||||
|
||||
class TestOfHttpRequest extends UnitTestCase {
|
||||
|
||||
function testReadingBadConnection() {
|
||||
$socket = &new MockSimpleSocket();
|
||||
|
||||
$route = &new MockSimpleRoute();
|
||||
$route->setReturnReference('createConnection', $socket);
|
||||
|
||||
$request = &new SimpleHttpRequest($route, new SimpleGetEncoding());
|
||||
$reponse = &$request->fetch(15);
|
||||
$this->assertTrue($reponse->isError());
|
||||
}
|
||||
|
||||
function testReadingGoodConnection() {
|
||||
$socket = &new MockSimpleSocket();
|
||||
$socket->expectOnce('write', array("\r\n"));
|
||||
|
||||
$route = &new MockSimpleRoute();
|
||||
$route->setReturnReference('createConnection', $socket);
|
||||
$route->expectArguments('createConnection', array('GET', 15));
|
||||
|
||||
$request = &new SimpleHttpRequest($route, new SimpleGetEncoding());
|
||||
$this->assertIsA($request->fetch(15), 'SimpleHttpResponse');
|
||||
}
|
||||
|
||||
function testWritingAdditionalHeaders() {
|
||||
$socket = &new MockSimpleSocket();
|
||||
$socket->expectArgumentsAt(0, 'write', array("My: stuff\r\n"));
|
||||
$socket->expectArgumentsAt(1, 'write', array("\r\n"));
|
||||
$socket->expectCallCount('write', 2);
|
||||
|
||||
$route = &new MockSimpleRoute();
|
||||
$route->setReturnReference('createConnection', $socket);
|
||||
|
||||
$request = &new SimpleHttpRequest($route, new SimpleGetEncoding());
|
||||
$request->addHeaderLine('My: stuff');
|
||||
$request->fetch(15);
|
||||
}
|
||||
|
||||
function testCookieWriting() {
|
||||
$socket = &new MockSimpleSocket();
|
||||
$socket->expectArgumentsAt(0, 'write', array("Cookie: a=A\r\n"));
|
||||
$socket->expectArgumentsAt(1, 'write', array("\r\n"));
|
||||
$socket->expectCallCount('write', 2);
|
||||
|
||||
$route = &new MockSimpleRoute();
|
||||
$route->setReturnReference('createConnection', $socket);
|
||||
|
||||
$jar = new SimpleCookieJar();
|
||||
$jar->setCookie('a', 'A');
|
||||
|
||||
$request = &new SimpleHttpRequest($route, new SimpleGetEncoding());
|
||||
$request->readCookiesFromJar($jar, new SimpleUrl('/'));
|
||||
$this->assertIsA($request->fetch(15), 'SimpleHttpResponse');
|
||||
}
|
||||
|
||||
function testMultipleCookieWriting() {
|
||||
$socket = &new MockSimpleSocket();
|
||||
$socket->expectArgumentsAt(0, 'write', array("Cookie: a=A;b=B\r\n"));
|
||||
|
||||
$route = &new MockSimpleRoute();
|
||||
$route->setReturnReference('createConnection', $socket);
|
||||
|
||||
$jar = new SimpleCookieJar();
|
||||
$jar->setCookie('a', 'A');
|
||||
$jar->setCookie('b', 'B');
|
||||
|
||||
$request = &new SimpleHttpRequest($route, new SimpleGetEncoding());
|
||||
$request->readCookiesFromJar($jar, new SimpleUrl('/'));
|
||||
$request->fetch(15);
|
||||
}
|
||||
}
|
||||
|
||||
class TestOfHttpPostRequest extends UnitTestCase {
|
||||
|
||||
function testReadingBadConnectionCausesErrorBecauseOfDeadSocket() {
|
||||
$socket = &new MockSimpleSocket();
|
||||
|
||||
$route = &new MockSimpleRoute();
|
||||
$route->setReturnReference('createConnection', $socket);
|
||||
|
||||
$request = &new SimpleHttpRequest($route, new SimplePostEncoding());
|
||||
$reponse = &$request->fetch(15);
|
||||
$this->assertTrue($reponse->isError());
|
||||
}
|
||||
|
||||
function testReadingGoodConnection() {
|
||||
$socket = &new MockSimpleSocket();
|
||||
$socket->expectArgumentsAt(0, 'write', array("Content-Length: 0\r\n"));
|
||||
$socket->expectArgumentsAt(1, 'write', array("Content-Type: application/x-www-form-urlencoded\r\n"));
|
||||
$socket->expectArgumentsAt(2, 'write', array("\r\n"));
|
||||
$socket->expectArgumentsAt(3, 'write', array(""));
|
||||
|
||||
$route = &new MockSimpleRoute();
|
||||
$route->setReturnReference('createConnection', $socket);
|
||||
$route->expectArguments('createConnection', array('POST', 15));
|
||||
|
||||
$request = &new SimpleHttpRequest($route, new SimplePostEncoding());
|
||||
$this->assertIsA($request->fetch(15), 'SimpleHttpResponse');
|
||||
}
|
||||
|
||||
function testContentHeadersCalculated() {
|
||||
$socket = &new MockSimpleSocket();
|
||||
$socket->expectArgumentsAt(0, 'write', array("Content-Length: 3\r\n"));
|
||||
$socket->expectArgumentsAt(1, 'write', array("Content-Type: application/x-www-form-urlencoded\r\n"));
|
||||
$socket->expectArgumentsAt(2, 'write', array("\r\n"));
|
||||
$socket->expectArgumentsAt(3, 'write', array("a=A"));
|
||||
|
||||
$route = &new MockSimpleRoute();
|
||||
$route->setReturnReference('createConnection', $socket);
|
||||
$route->expectArguments('createConnection', array('POST', 15));
|
||||
|
||||
$request = &new SimpleHttpRequest(
|
||||
$route,
|
||||
new SimplePostEncoding(array('a' => 'A')));
|
||||
$this->assertIsA($request->fetch(15), 'SimpleHttpResponse');
|
||||
}
|
||||
}
|
||||
|
||||
class TestOfHttpHeaders extends UnitTestCase {
|
||||
|
||||
function testParseBasicHeaders() {
|
||||
$headers = new SimpleHttpHeaders(
|
||||
"HTTP/1.1 200 OK\r\n" .
|
||||
"Date: Mon, 18 Nov 2002 15:50:29 GMT\r\n" .
|
||||
"Content-Type: text/plain\r\n" .
|
||||
"Server: Apache/1.3.24 (Win32) PHP/4.2.3\r\n" .
|
||||
"Connection: close");
|
||||
$this->assertIdentical($headers->getHttpVersion(), "1.1");
|
||||
$this->assertIdentical($headers->getResponseCode(), 200);
|
||||
$this->assertEqual($headers->getMimeType(), "text/plain");
|
||||
}
|
||||
|
||||
function testNonStandardResponseHeader() {
|
||||
$headers = new SimpleHttpHeaders(
|
||||
"HTTP/1.1 302 (HTTP-Version SP Status-Code CRLF)\r\n" .
|
||||
"Connection: close");
|
||||
$this->assertIdentical($headers->getResponseCode(), 302);
|
||||
}
|
||||
|
||||
function testCanParseMultipleCookies() {
|
||||
$jar = &new MockSimpleCookieJar();
|
||||
$jar->expectAt(0, 'setCookie', array('a', 'aaa', 'host', '/here/', 'Wed, 25 Dec 2002 04:24:20 GMT'));
|
||||
$jar->expectAt(1, 'setCookie', array('b', 'bbb', 'host', '/', false));
|
||||
|
||||
$headers = new SimpleHttpHeaders(
|
||||
"HTTP/1.1 200 OK\r\n" .
|
||||
"Date: Mon, 18 Nov 2002 15:50:29 GMT\r\n" .
|
||||
"Content-Type: text/plain\r\n" .
|
||||
"Server: Apache/1.3.24 (Win32) PHP/4.2.3\r\n" .
|
||||
"Set-Cookie: a=aaa; expires=Wed, 25-Dec-02 04:24:20 GMT; path=/here/\r\n" .
|
||||
"Set-Cookie: b=bbb\r\n" .
|
||||
"Connection: close");
|
||||
$headers->writeCookiesToJar($jar, new SimpleUrl('http://host'));
|
||||
}
|
||||
|
||||
function testCanRecogniseRedirect() {
|
||||
$headers = new SimpleHttpHeaders("HTTP/1.1 301 OK\r\n" .
|
||||
"Content-Type: text/plain\r\n" .
|
||||
"Content-Length: 0\r\n" .
|
||||
"Location: http://www.somewhere-else.com/\r\n" .
|
||||
"Connection: close");
|
||||
$this->assertIdentical($headers->getResponseCode(), 301);
|
||||
$this->assertEqual($headers->getLocation(), "http://www.somewhere-else.com/");
|
||||
$this->assertTrue($headers->isRedirect());
|
||||
}
|
||||
|
||||
function testCanParseChallenge() {
|
||||
$headers = new SimpleHttpHeaders("HTTP/1.1 401 Authorization required\r\n" .
|
||||
"Content-Type: text/plain\r\n" .
|
||||
"Connection: close\r\n" .
|
||||
"WWW-Authenticate: Basic realm=\"Somewhere\"");
|
||||
$this->assertEqual($headers->getAuthentication(), 'Basic');
|
||||
$this->assertEqual($headers->getRealm(), 'Somewhere');
|
||||
$this->assertTrue($headers->isChallenge());
|
||||
}
|
||||
}
|
||||
|
||||
class TestOfHttpResponse extends UnitTestCase {
|
||||
|
||||
function testBadRequest() {
|
||||
$socket = &new MockSimpleSocket();
|
||||
$socket->setReturnValue('getSent', '');
|
||||
|
||||
$response = &new SimpleHttpResponse($socket, new SimpleUrl('here'), new SimpleGetEncoding());
|
||||
$this->assertTrue($response->isError());
|
||||
$this->assertPattern('/Nothing fetched/', $response->getError());
|
||||
$this->assertIdentical($response->getContent(), false);
|
||||
$this->assertIdentical($response->getSent(), '');
|
||||
}
|
||||
|
||||
function testBadSocketDuringResponse() {
|
||||
$socket = &new MockSimpleSocket();
|
||||
$socket->setReturnValueAt(0, "read", "HTTP/1.1 200 OK\r\n");
|
||||
$socket->setReturnValueAt(1, "read", "Date: Mon, 18 Nov 2002 15:50:29 GMT\r\n");
|
||||
$socket->setReturnValue("read", "");
|
||||
$socket->setReturnValue('getSent', 'HTTP/1.1 ...');
|
||||
|
||||
$response = &new SimpleHttpResponse($socket, new SimpleUrl('here'), new SimpleGetEncoding());
|
||||
$this->assertTrue($response->isError());
|
||||
$this->assertEqual($response->getContent(), '');
|
||||
$this->assertEqual($response->getSent(), 'HTTP/1.1 ...');
|
||||
}
|
||||
|
||||
function testIncompleteHeader() {
|
||||
$socket = &new MockSimpleSocket();
|
||||
$socket->setReturnValueAt(0, "read", "HTTP/1.1 200 OK\r\n");
|
||||
$socket->setReturnValueAt(1, "read", "Date: Mon, 18 Nov 2002 15:50:29 GMT\r\n");
|
||||
$socket->setReturnValueAt(2, "read", "Content-Type: text/plain\r\n");
|
||||
$socket->setReturnValue("read", "");
|
||||
|
||||
$response = &new SimpleHttpResponse($socket, new SimpleUrl('here'), new SimpleGetEncoding());
|
||||
$this->assertTrue($response->isError());
|
||||
$this->assertEqual($response->getContent(), "");
|
||||
}
|
||||
|
||||
function testParseOfResponseHeadersWhenChunked() {
|
||||
$socket = &new MockSimpleSocket();
|
||||
$socket->setReturnValueAt(0, "read", "HTTP/1.1 200 OK\r\nDate: Mon, 18 Nov 2002 15:50:29 GMT\r\n");
|
||||
$socket->setReturnValueAt(1, "read", "Content-Type: text/plain\r\n");
|
||||
$socket->setReturnValueAt(2, "read", "Server: Apache/1.3.24 (Win32) PHP/4.2.3\r\nConne");
|
||||
$socket->setReturnValueAt(3, "read", "ction: close\r\n\r\nthis is a test file\n");
|
||||
$socket->setReturnValueAt(4, "read", "with two lines in it\n");
|
||||
$socket->setReturnValue("read", "");
|
||||
|
||||
$response = &new SimpleHttpResponse($socket, new SimpleUrl('here'), new SimpleGetEncoding());
|
||||
$this->assertFalse($response->isError());
|
||||
$this->assertEqual(
|
||||
$response->getContent(),
|
||||
"this is a test file\nwith two lines in it\n");
|
||||
$headers = $response->getHeaders();
|
||||
$this->assertIdentical($headers->getHttpVersion(), "1.1");
|
||||
$this->assertIdentical($headers->getResponseCode(), 200);
|
||||
$this->assertEqual($headers->getMimeType(), "text/plain");
|
||||
$this->assertFalse($headers->isRedirect());
|
||||
$this->assertFalse($headers->getLocation());
|
||||
}
|
||||
|
||||
function testRedirect() {
|
||||
$socket = &new MockSimpleSocket();
|
||||
$socket->setReturnValueAt(0, "read", "HTTP/1.1 301 OK\r\n");
|
||||
$socket->setReturnValueAt(1, "read", "Content-Type: text/plain\r\n");
|
||||
$socket->setReturnValueAt(2, "read", "Location: http://www.somewhere-else.com/\r\n");
|
||||
$socket->setReturnValueAt(3, "read", "Connection: close\r\n");
|
||||
$socket->setReturnValueAt(4, "read", "\r\n");
|
||||
$socket->setReturnValue("read", "");
|
||||
|
||||
$response = &new SimpleHttpResponse($socket, new SimpleUrl('here'), new SimpleGetEncoding());
|
||||
$headers = $response->getHeaders();
|
||||
$this->assertTrue($headers->isRedirect());
|
||||
$this->assertEqual($headers->getLocation(), "http://www.somewhere-else.com/");
|
||||
}
|
||||
|
||||
function testRedirectWithPort() {
|
||||
$socket = &new MockSimpleSocket();
|
||||
$socket->setReturnValueAt(0, "read", "HTTP/1.1 301 OK\r\n");
|
||||
$socket->setReturnValueAt(1, "read", "Content-Type: text/plain\r\n");
|
||||
$socket->setReturnValueAt(2, "read", "Location: http://www.somewhere-else.com:80/\r\n");
|
||||
$socket->setReturnValueAt(3, "read", "Connection: close\r\n");
|
||||
$socket->setReturnValueAt(4, "read", "\r\n");
|
||||
$socket->setReturnValue("read", "");
|
||||
|
||||
$response = &new SimpleHttpResponse($socket, new SimpleUrl('here'), new SimpleGetEncoding());
|
||||
$headers = $response->getHeaders();
|
||||
$this->assertTrue($headers->isRedirect());
|
||||
$this->assertEqual($headers->getLocation(), "http://www.somewhere-else.com:80/");
|
||||
}
|
||||
}
|
||||
?>
|
||||
137
tests/simpletest/test/interfaces_test.php
Normal file
137
tests/simpletest/test/interfaces_test.php
Normal file
|
|
@ -0,0 +1,137 @@
|
|||
<?php
|
||||
// $Id: interfaces_test.php 1699 2008-03-24 16:01:29Z lastcraft $
|
||||
require_once(dirname(__FILE__) . '/../autorun.php');
|
||||
if (function_exists('spl_classes')) {
|
||||
include(dirname(__FILE__) . '/support/spl_examples.php');
|
||||
}
|
||||
|
||||
interface DummyInterface {
|
||||
function aMethod();
|
||||
function anotherMethod($a);
|
||||
function &referenceMethod(&$a);
|
||||
}
|
||||
|
||||
Mock::generate('DummyInterface');
|
||||
Mock::generatePartial('DummyInterface', 'PartialDummyInterface', array());
|
||||
|
||||
class TestOfMockInterfaces extends UnitTestCase {
|
||||
|
||||
function testCanMockAnInterface() {
|
||||
$mock = new MockDummyInterface();
|
||||
$this->assertIsA($mock, 'SimpleMock');
|
||||
$this->assertIsA($mock, 'MockDummyInterface');
|
||||
$this->assertTrue(method_exists($mock, 'aMethod'));
|
||||
$this->assertTrue(method_exists($mock, 'anotherMethod'));
|
||||
$this->assertNull($mock->aMethod());
|
||||
}
|
||||
|
||||
function testMockedInterfaceExpectsParameters() {
|
||||
$mock = new MockDummyInterface();
|
||||
$mock->anotherMethod();
|
||||
$this->assertError();
|
||||
}
|
||||
|
||||
function testCannotPartiallyMockAnInterface() {
|
||||
$this->assertFalse(class_exists('PartialDummyInterface'));
|
||||
}
|
||||
}
|
||||
|
||||
class TestOfSpl extends UnitTestCase {
|
||||
|
||||
function skip() {
|
||||
$this->skipUnless(function_exists('spl_classes'), 'No SPL module loaded');
|
||||
}
|
||||
|
||||
function testCanMockAllSplClasses() {
|
||||
if (! function_exists('spl_classes')) {
|
||||
return;
|
||||
}
|
||||
foreach(spl_classes() as $class) {
|
||||
if ($class == 'SplHeap') {
|
||||
continue;
|
||||
}
|
||||
$mock_class = "Mock$class";
|
||||
Mock::generate($class);
|
||||
$this->assertIsA(new $mock_class(), $mock_class);
|
||||
}
|
||||
}
|
||||
|
||||
function testExtensionOfCommonSplClasses() {
|
||||
Mock::generate('IteratorImplementation');
|
||||
$this->assertIsA(
|
||||
new IteratorImplementation(),
|
||||
'IteratorImplementation');
|
||||
Mock::generate('IteratorAggregateImplementation');
|
||||
$this->assertIsA(
|
||||
new IteratorAggregateImplementation(),
|
||||
'IteratorAggregateImplementation');
|
||||
}
|
||||
}
|
||||
|
||||
class WithHint {
|
||||
function hinted(DummyInterface $object) { }
|
||||
}
|
||||
|
||||
class ImplementsDummy implements DummyInterface {
|
||||
function aMethod() { }
|
||||
function anotherMethod($a) { }
|
||||
function &referenceMethod(&$a) { }
|
||||
function extraMethod($a = false) { }
|
||||
}
|
||||
Mock::generate('ImplementsDummy');
|
||||
|
||||
class TestOfImplementations extends UnitTestCase {
|
||||
|
||||
function testMockedInterfaceCanPassThroughTypeHint() {
|
||||
$mock = new MockDummyInterface();
|
||||
$hinter = new WithHint();
|
||||
$hinter->hinted($mock);
|
||||
}
|
||||
|
||||
function testImplementedInterfacesAreCarried() {
|
||||
$mock = new MockImplementsDummy();
|
||||
$hinter = new WithHint();
|
||||
$hinter->hinted($mock);
|
||||
}
|
||||
|
||||
function testNoSpuriousWarningsWhenSkippingDefaultedParameter() {
|
||||
$mock = new MockImplementsDummy();
|
||||
$mock->extraMethod();
|
||||
}
|
||||
}
|
||||
|
||||
interface SampleClassWithConstruct {
|
||||
function __construct($something);
|
||||
}
|
||||
|
||||
class TestOfInterfaceMocksWithConstruct extends UnitTestCase {
|
||||
function testBasicConstructOfAnInterface() {
|
||||
Mock::generate('SampleClassWithConstruct');
|
||||
$this->assertNoErrors();
|
||||
}
|
||||
}
|
||||
|
||||
interface SampleInterfaceWithHintInSignature {
|
||||
function method(array $hinted);
|
||||
}
|
||||
|
||||
class TestOfInterfaceMocksWithHintInSignature extends UnitTestCase {
|
||||
function testBasicConstructOfAnInterfaceWithHintInSignature() {
|
||||
Mock::generate('SampleInterfaceWithHintInSignature');
|
||||
$this->assertNoErrors();
|
||||
$mock = new MockSampleInterfaceWithHintInSignature();
|
||||
$this->assertIsA($mock, 'SampleInterfaceWithHintInSignature');
|
||||
}
|
||||
}
|
||||
|
||||
interface SampleInterfaceWithClone {
|
||||
function __clone();
|
||||
}
|
||||
|
||||
class TestOfSampleInterfaceWithClone extends UnitTestCase {
|
||||
function testCanMockWithoutErrors() {
|
||||
Mock::generate('SampleInterfaceWithClone');
|
||||
$this->assertNoErrors();
|
||||
}
|
||||
}
|
||||
?>
|
||||
47
tests/simpletest/test/live_test.php
Normal file
47
tests/simpletest/test/live_test.php
Normal file
|
|
@ -0,0 +1,47 @@
|
|||
<?php
|
||||
// $Id: live_test.php 1505 2007-04-30 23:39:59Z lastcraft $
|
||||
require_once(dirname(__FILE__) . '/../autorun.php');
|
||||
require_once(dirname(__FILE__) . '/../socket.php');
|
||||
require_once(dirname(__FILE__) . '/../http.php');
|
||||
require_once(dirname(__FILE__) . '/../compatibility.php');
|
||||
|
||||
if (SimpleTest::getDefaultProxy()) {
|
||||
SimpleTest::ignore('LiveHttpTestCase');
|
||||
}
|
||||
|
||||
class LiveHttpTestCase extends UnitTestCase {
|
||||
|
||||
function testBadSocket() {
|
||||
$socket = &new SimpleSocket('bad_url', 111, 5);
|
||||
$this->assertTrue($socket->isError());
|
||||
$this->assertPattern(
|
||||
'/Cannot open \\[bad_url:111\\] with \\[/',
|
||||
$socket->getError());
|
||||
$this->assertFalse($socket->isOpen());
|
||||
$this->assertFalse($socket->write('A message'));
|
||||
}
|
||||
|
||||
function testSocketClosure() {
|
||||
$socket = &new SimpleSocket('www.lastcraft.com', 80, 15, 8);
|
||||
$this->assertTrue($socket->isOpen());
|
||||
$this->assertTrue($socket->write("GET /test/network_confirm.php HTTP/1.0\r\n"));
|
||||
$socket->write("Host: www.lastcraft.com\r\n");
|
||||
$socket->write("Connection: close\r\n\r\n");
|
||||
$this->assertEqual($socket->read(), "HTTP/1.1");
|
||||
$socket->close();
|
||||
$this->assertIdentical($socket->read(), false);
|
||||
}
|
||||
|
||||
function testRecordOfSentCharacters() {
|
||||
$socket = &new SimpleSocket('www.lastcraft.com', 80, 15);
|
||||
$this->assertTrue($socket->write("GET /test/network_confirm.php HTTP/1.0\r\n"));
|
||||
$socket->write("Host: www.lastcraft.com\r\n");
|
||||
$socket->write("Connection: close\r\n\r\n");
|
||||
$socket->close();
|
||||
$this->assertEqual($socket->getSent(),
|
||||
"GET /test/network_confirm.php HTTP/1.0\r\n" .
|
||||
"Host: www.lastcraft.com\r\n" .
|
||||
"Connection: close\r\n\r\n");
|
||||
}
|
||||
}
|
||||
?>
|
||||
994
tests/simpletest/test/mock_objects_test.php
Normal file
994
tests/simpletest/test/mock_objects_test.php
Normal file
|
|
@ -0,0 +1,994 @@
|
|||
<?php
|
||||
// $Id: mock_objects_test.php 1700 2008-03-24 16:17:48Z lastcraft $
|
||||
require_once(dirname(__FILE__) . '/../autorun.php');
|
||||
require_once(dirname(__FILE__) . '/../expectation.php');
|
||||
require_once(dirname(__FILE__) . '/../mock_objects.php');
|
||||
|
||||
class TestOfAnythingExpectation extends UnitTestCase {
|
||||
|
||||
function testSimpleInteger() {
|
||||
$expectation = new AnythingExpectation();
|
||||
$this->assertTrue($expectation->test(33));
|
||||
$this->assertTrue($expectation->test(false));
|
||||
$this->assertTrue($expectation->test(null));
|
||||
}
|
||||
}
|
||||
|
||||
class TestOfParametersExpectation extends UnitTestCase {
|
||||
|
||||
function testEmptyMatch() {
|
||||
$expectation = new ParametersExpectation(array());
|
||||
$this->assertTrue($expectation->test(array()));
|
||||
$this->assertFalse($expectation->test(array(33)));
|
||||
}
|
||||
|
||||
function testSingleMatch() {
|
||||
$expectation = new ParametersExpectation(array(0));
|
||||
$this->assertFalse($expectation->test(array(1)));
|
||||
$this->assertTrue($expectation->test(array(0)));
|
||||
}
|
||||
|
||||
function testAnyMatch() {
|
||||
$expectation = new ParametersExpectation(false);
|
||||
$this->assertTrue($expectation->test(array()));
|
||||
$this->assertTrue($expectation->test(array(1, 2)));
|
||||
}
|
||||
|
||||
function testMissingParameter() {
|
||||
$expectation = new ParametersExpectation(array(0));
|
||||
$this->assertFalse($expectation->test(array()));
|
||||
}
|
||||
|
||||
function testNullParameter() {
|
||||
$expectation = new ParametersExpectation(array(null));
|
||||
$this->assertTrue($expectation->test(array(null)));
|
||||
$this->assertFalse($expectation->test(array()));
|
||||
}
|
||||
|
||||
function testAnythingExpectations() {
|
||||
$expectation = new ParametersExpectation(array(new AnythingExpectation()));
|
||||
$this->assertFalse($expectation->test(array()));
|
||||
$this->assertIdentical($expectation->test(array(null)), true);
|
||||
$this->assertIdentical($expectation->test(array(13)), true);
|
||||
}
|
||||
|
||||
function testOtherExpectations() {
|
||||
$expectation = new ParametersExpectation(
|
||||
array(new PatternExpectation('/hello/i')));
|
||||
$this->assertFalse($expectation->test(array('Goodbye')));
|
||||
$this->assertTrue($expectation->test(array('hello')));
|
||||
$this->assertTrue($expectation->test(array('Hello')));
|
||||
}
|
||||
|
||||
function testIdentityOnly() {
|
||||
$expectation = new ParametersExpectation(array("0"));
|
||||
$this->assertFalse($expectation->test(array(0)));
|
||||
$this->assertTrue($expectation->test(array("0")));
|
||||
}
|
||||
|
||||
function testLongList() {
|
||||
$expectation = new ParametersExpectation(
|
||||
array("0", 0, new AnythingExpectation(), false));
|
||||
$this->assertTrue($expectation->test(array("0", 0, 37, false)));
|
||||
$this->assertFalse($expectation->test(array("0", 0, 37, true)));
|
||||
$this->assertFalse($expectation->test(array("0", 0, 37)));
|
||||
}
|
||||
}
|
||||
|
||||
class TestOfSimpleSignatureMap extends UnitTestCase {
|
||||
|
||||
function testEmpty() {
|
||||
$map = new SimpleSignatureMap();
|
||||
$this->assertFalse($map->isMatch("any", array()));
|
||||
$this->assertNull($map->findFirstAction("any", array()));
|
||||
}
|
||||
|
||||
function testExactReference() {
|
||||
$map = new SimpleSignatureMap();
|
||||
$ref = "Fred";
|
||||
$map->add(array(0), $ref);
|
||||
$this->assertEqual($map->findFirstAction(array(0)), "Fred");
|
||||
$ref2 = &$map->findFirstAction(array(0));
|
||||
$this->assertReference($ref2, $ref);
|
||||
}
|
||||
|
||||
function testDifferentCallSignaturesCanHaveDifferentReferences() {
|
||||
$map = new SimpleSignatureMap();
|
||||
$fred = 'Fred';
|
||||
$jim = 'jim';
|
||||
$map->add(array(0), $fred);
|
||||
$map->add(array('0'), $jim);
|
||||
$this->assertReference($fred, $map->findFirstAction(array(0)));
|
||||
$this->assertReference($jim, $map->findFirstAction(array('0')));
|
||||
}
|
||||
|
||||
function testWildcard() {
|
||||
$fred = 'Fred';
|
||||
$map = new SimpleSignatureMap();
|
||||
$map->add(array(new AnythingExpectation(), 1, 3), $fred);
|
||||
$this->assertTrue($map->isMatch(array(2, 1, 3)));
|
||||
$this->assertReference($map->findFirstAction(array(2, 1, 3)), $fred);
|
||||
}
|
||||
|
||||
function testAllWildcard() {
|
||||
$fred = 'Fred';
|
||||
$map = new SimpleSignatureMap();
|
||||
$this->assertFalse($map->isMatch(array(2, 1, 3)));
|
||||
$map->add('', $fred);
|
||||
$this->assertTrue($map->isMatch(array(2, 1, 3)));
|
||||
$this->assertReference($map->findFirstAction(array(2, 1, 3)), $fred);
|
||||
}
|
||||
|
||||
function testOrdering() {
|
||||
$map = new SimpleSignatureMap();
|
||||
$map->add(array(1, 2), new SimpleByValue("1, 2"));
|
||||
$map->add(array(1, 3), new SimpleByValue("1, 3"));
|
||||
$map->add(array(1), new SimpleByValue("1"));
|
||||
$map->add(array(1, 4), new SimpleByValue("1, 4"));
|
||||
$map->add(array(new AnythingExpectation()), new SimpleByValue("Any"));
|
||||
$map->add(array(2), new SimpleByValue("2"));
|
||||
$map->add("", new SimpleByValue("Default"));
|
||||
$map->add(array(), new SimpleByValue("None"));
|
||||
$this->assertEqual($map->findFirstAction(array(1, 2)), new SimpleByValue("1, 2"));
|
||||
$this->assertEqual($map->findFirstAction(array(1, 3)), new SimpleByValue("1, 3"));
|
||||
$this->assertEqual($map->findFirstAction(array(1, 4)), new SimpleByValue("1, 4"));
|
||||
$this->assertEqual($map->findFirstAction(array(1)), new SimpleByValue("1"));
|
||||
$this->assertEqual($map->findFirstAction(array(2)), new SimpleByValue("Any"));
|
||||
$this->assertEqual($map->findFirstAction(array(3)), new SimpleByValue("Any"));
|
||||
$this->assertEqual($map->findFirstAction(array()), new SimpleByValue("Default"));
|
||||
}
|
||||
}
|
||||
|
||||
class TestOfCallSchedule extends UnitTestCase {
|
||||
function testCanBeSetToAlwaysReturnTheSameReference() {
|
||||
$a = 5;
|
||||
$schedule = &new SimpleCallSchedule();
|
||||
$schedule->register('aMethod', false, new SimpleByReference($a));
|
||||
$this->assertReference($schedule->respond(0, 'aMethod', array()), $a);
|
||||
$this->assertReference($schedule->respond(1, 'aMethod', array()), $a);
|
||||
}
|
||||
|
||||
function testSpecificSignaturesOverrideTheAlwaysCase() {
|
||||
$any = 'any';
|
||||
$one = 'two';
|
||||
$schedule = &new SimpleCallSchedule();
|
||||
$schedule->register('aMethod', array(1), new SimpleByReference($one));
|
||||
$schedule->register('aMethod', false, new SimpleByReference($any));
|
||||
$this->assertReference($schedule->respond(0, 'aMethod', array(2)), $any);
|
||||
$this->assertReference($schedule->respond(0, 'aMethod', array(1)), $one);
|
||||
}
|
||||
|
||||
function testReturnsCanBeSetOverTime() {
|
||||
$one = 'one';
|
||||
$two = 'two';
|
||||
$schedule = &new SimpleCallSchedule();
|
||||
$schedule->registerAt(0, 'aMethod', false, new SimpleByReference($one));
|
||||
$schedule->registerAt(1, 'aMethod', false, new SimpleByReference($two));
|
||||
$this->assertReference($schedule->respond(0, 'aMethod', array()), $one);
|
||||
$this->assertReference($schedule->respond(1, 'aMethod', array()), $two);
|
||||
}
|
||||
|
||||
function testReturnsOverTimecanBeAlteredByTheArguments() {
|
||||
$one = '1';
|
||||
$two = '2';
|
||||
$two_a = '2a';
|
||||
$schedule = &new SimpleCallSchedule();
|
||||
$schedule->registerAt(0, 'aMethod', false, new SimpleByReference($one));
|
||||
$schedule->registerAt(1, 'aMethod', array('a'), new SimpleByReference($two_a));
|
||||
$schedule->registerAt(1, 'aMethod', false, new SimpleByReference($two));
|
||||
$this->assertReference($schedule->respond(0, 'aMethod', array()), $one);
|
||||
$this->assertReference($schedule->respond(1, 'aMethod', array()), $two);
|
||||
$this->assertReference($schedule->respond(1, 'aMethod', array('a')), $two_a);
|
||||
}
|
||||
|
||||
function testCanReturnByValue() {
|
||||
$a = 5;
|
||||
$schedule = &new SimpleCallSchedule();
|
||||
$schedule->register('aMethod', false, new SimpleByValue($a));
|
||||
$this->assertClone($schedule->respond(0, 'aMethod', array()), $a);
|
||||
}
|
||||
|
||||
function testCanThrowException() {
|
||||
if (version_compare(phpversion(), '5', '>=')) {
|
||||
$schedule = &new SimpleCallSchedule();
|
||||
$schedule->register('aMethod', false, new SimpleThrower(new Exception('Ouch')));
|
||||
$this->expectException(new Exception('Ouch'));
|
||||
$schedule->respond(0, 'aMethod', array());
|
||||
}
|
||||
}
|
||||
|
||||
function testCanEmitError() {
|
||||
$schedule = &new SimpleCallSchedule();
|
||||
$schedule->register('aMethod', false, new SimpleErrorThrower('Ouch', E_USER_WARNING));
|
||||
$this->expectError('Ouch');
|
||||
$schedule->respond(0, 'aMethod', array());
|
||||
}
|
||||
}
|
||||
|
||||
class Dummy {
|
||||
function Dummy() {
|
||||
}
|
||||
|
||||
function aMethod() {
|
||||
return true;
|
||||
}
|
||||
|
||||
function anotherMethod() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
Mock::generate('Dummy');
|
||||
Mock::generate('Dummy', 'AnotherMockDummy');
|
||||
Mock::generate('Dummy', 'MockDummyWithExtraMethods', array('extraMethod'));
|
||||
|
||||
class TestOfMockGeneration extends UnitTestCase {
|
||||
|
||||
function testCloning() {
|
||||
$mock = &new MockDummy();
|
||||
$this->assertTrue(method_exists($mock, "aMethod"));
|
||||
$this->assertNull($mock->aMethod());
|
||||
}
|
||||
|
||||
function testCloningWithExtraMethod() {
|
||||
$mock = &new MockDummyWithExtraMethods();
|
||||
$this->assertTrue(method_exists($mock, "extraMethod"));
|
||||
}
|
||||
|
||||
function testCloningWithChosenClassName() {
|
||||
$mock = &new AnotherMockDummy();
|
||||
$this->assertTrue(method_exists($mock, "aMethod"));
|
||||
}
|
||||
}
|
||||
|
||||
class TestOfMockReturns extends UnitTestCase {
|
||||
|
||||
function testDefaultReturn() {
|
||||
$mock = &new MockDummy();
|
||||
$mock->setReturnValue("aMethod", "aaa");
|
||||
$this->assertIdentical($mock->aMethod(), "aaa");
|
||||
$this->assertIdentical($mock->aMethod(), "aaa");
|
||||
}
|
||||
|
||||
function testParameteredReturn() {
|
||||
$mock = &new MockDummy();
|
||||
$mock->setReturnValue('aMethod', 'aaa', array(1, 2, 3));
|
||||
$this->assertNull($mock->aMethod());
|
||||
$this->assertIdentical($mock->aMethod(1, 2, 3), 'aaa');
|
||||
}
|
||||
|
||||
function testReferenceReturned() {
|
||||
$mock = &new MockDummy();
|
||||
$object = new Dummy();
|
||||
$mock->setReturnReference('aMethod', $object, array(1, 2, 3));
|
||||
$this->assertReference($zref = &$mock->aMethod(1, 2, 3), $object);
|
||||
}
|
||||
|
||||
function testPatternMatchReturn() {
|
||||
$mock = &new MockDummy();
|
||||
$mock->setReturnValue(
|
||||
"aMethod",
|
||||
"aaa",
|
||||
array(new PatternExpectation('/hello/i')));
|
||||
$this->assertIdentical($mock->aMethod('Hello'), "aaa");
|
||||
$this->assertNull($mock->aMethod('Goodbye'));
|
||||
}
|
||||
|
||||
function testMultipleMethods() {
|
||||
$mock = &new MockDummy();
|
||||
$mock->setReturnValue("aMethod", 100, array(1));
|
||||
$mock->setReturnValue("aMethod", 200, array(2));
|
||||
$mock->setReturnValue("anotherMethod", 10, array(1));
|
||||
$mock->setReturnValue("anotherMethod", 20, array(2));
|
||||
$this->assertIdentical($mock->aMethod(1), 100);
|
||||
$this->assertIdentical($mock->anotherMethod(1), 10);
|
||||
$this->assertIdentical($mock->aMethod(2), 200);
|
||||
$this->assertIdentical($mock->anotherMethod(2), 20);
|
||||
}
|
||||
|
||||
function testReturnSequence() {
|
||||
$mock = &new MockDummy();
|
||||
$mock->setReturnValueAt(0, "aMethod", "aaa");
|
||||
$mock->setReturnValueAt(1, "aMethod", "bbb");
|
||||
$mock->setReturnValueAt(3, "aMethod", "ddd");
|
||||
$this->assertIdentical($mock->aMethod(), "aaa");
|
||||
$this->assertIdentical($mock->aMethod(), "bbb");
|
||||
$this->assertNull($mock->aMethod());
|
||||
$this->assertIdentical($mock->aMethod(), "ddd");
|
||||
}
|
||||
|
||||
function testReturnReferenceSequence() {
|
||||
$mock = &new MockDummy();
|
||||
$object = new Dummy();
|
||||
$mock->setReturnReferenceAt(1, "aMethod", $object);
|
||||
$this->assertNull($mock->aMethod());
|
||||
$this->assertReference($zref =& $mock->aMethod(), $object);
|
||||
$this->assertNull($mock->aMethod());
|
||||
}
|
||||
|
||||
function testComplicatedReturnSequence() {
|
||||
$mock = &new MockDummy();
|
||||
$object = new Dummy();
|
||||
$mock->setReturnValueAt(1, "aMethod", "aaa", array("a"));
|
||||
$mock->setReturnValueAt(1, "aMethod", "bbb");
|
||||
$mock->setReturnReferenceAt(2, "aMethod", $object, array('*', 2));
|
||||
$mock->setReturnValueAt(2, "aMethod", "value", array('*', 3));
|
||||
$mock->setReturnValue("aMethod", 3, array(3));
|
||||
$this->assertNull($mock->aMethod());
|
||||
$this->assertEqual($mock->aMethod("a"), "aaa");
|
||||
$this->assertReference($zref =& $mock->aMethod(1, 2), $object);
|
||||
$this->assertEqual($mock->aMethod(3), 3);
|
||||
$this->assertNull($mock->aMethod());
|
||||
}
|
||||
|
||||
function testMultipleMethodSequences() {
|
||||
$mock = &new MockDummy();
|
||||
$mock->setReturnValueAt(0, "aMethod", "aaa");
|
||||
$mock->setReturnValueAt(1, "aMethod", "bbb");
|
||||
$mock->setReturnValueAt(0, "anotherMethod", "ccc");
|
||||
$mock->setReturnValueAt(1, "anotherMethod", "ddd");
|
||||
$this->assertIdentical($mock->aMethod(), "aaa");
|
||||
$this->assertIdentical($mock->anotherMethod(), "ccc");
|
||||
$this->assertIdentical($mock->aMethod(), "bbb");
|
||||
$this->assertIdentical($mock->anotherMethod(), "ddd");
|
||||
}
|
||||
|
||||
function testSequenceFallback() {
|
||||
$mock = &new MockDummy();
|
||||
$mock->setReturnValueAt(0, "aMethod", "aaa", array('a'));
|
||||
$mock->setReturnValueAt(1, "aMethod", "bbb", array('a'));
|
||||
$mock->setReturnValue("aMethod", "AAA");
|
||||
$this->assertIdentical($mock->aMethod('a'), "aaa");
|
||||
$this->assertIdentical($mock->aMethod('b'), "AAA");
|
||||
}
|
||||
|
||||
function testMethodInterference() {
|
||||
$mock = &new MockDummy();
|
||||
$mock->setReturnValueAt(0, "anotherMethod", "aaa");
|
||||
$mock->setReturnValue("aMethod", "AAA");
|
||||
$this->assertIdentical($mock->aMethod(), "AAA");
|
||||
$this->assertIdentical($mock->anotherMethod(), "aaa");
|
||||
}
|
||||
}
|
||||
|
||||
class TestOfMockExpectationsThatPass extends UnitTestCase {
|
||||
|
||||
function testAnyArgument() {
|
||||
$mock = &new MockDummy();
|
||||
$mock->expect('aMethod', array('*'));
|
||||
$mock->aMethod(1);
|
||||
$mock->aMethod('hello');
|
||||
}
|
||||
|
||||
function testAnyTwoArguments() {
|
||||
$mock = &new MockDummy();
|
||||
$mock->expect('aMethod', array('*', '*'));
|
||||
$mock->aMethod(1, 2);
|
||||
}
|
||||
|
||||
function testSpecificArgument() {
|
||||
$mock = &new MockDummy();
|
||||
$mock->expect('aMethod', array(1));
|
||||
$mock->aMethod(1);
|
||||
}
|
||||
|
||||
function testExpectation() {
|
||||
$mock = &new MockDummy();
|
||||
$mock->expect('aMethod', array(new IsAExpectation('Dummy')));
|
||||
$mock->aMethod(new Dummy());
|
||||
}
|
||||
|
||||
function testArgumentsInSequence() {
|
||||
$mock = &new MockDummy();
|
||||
$mock->expectAt(0, 'aMethod', array(1, 2));
|
||||
$mock->expectAt(1, 'aMethod', array(3, 4));
|
||||
$mock->aMethod(1, 2);
|
||||
$mock->aMethod(3, 4);
|
||||
}
|
||||
|
||||
function testAtLeastOnceSatisfiedByOneCall() {
|
||||
$mock = &new MockDummy();
|
||||
$mock->expectAtLeastOnce('aMethod');
|
||||
$mock->aMethod();
|
||||
}
|
||||
|
||||
function testAtLeastOnceSatisfiedByTwoCalls() {
|
||||
$mock = &new MockDummy();
|
||||
$mock->expectAtLeastOnce('aMethod');
|
||||
$mock->aMethod();
|
||||
$mock->aMethod();
|
||||
}
|
||||
|
||||
function testOnceSatisfiedByOneCall() {
|
||||
$mock = &new MockDummy();
|
||||
$mock->expectOnce('aMethod');
|
||||
$mock->aMethod();
|
||||
}
|
||||
|
||||
function testMinimumCallsSatisfiedByEnoughCalls() {
|
||||
$mock = &new MockDummy();
|
||||
$mock->expectMinimumCallCount('aMethod', 1);
|
||||
$mock->aMethod();
|
||||
}
|
||||
|
||||
function testMinimumCallsSatisfiedByTooManyCalls() {
|
||||
$mock = &new MockDummy();
|
||||
$mock->expectMinimumCallCount('aMethod', 3);
|
||||
$mock->aMethod();
|
||||
$mock->aMethod();
|
||||
$mock->aMethod();
|
||||
$mock->aMethod();
|
||||
}
|
||||
|
||||
function testMaximumCallsSatisfiedByEnoughCalls() {
|
||||
$mock = &new MockDummy();
|
||||
$mock->expectMaximumCallCount('aMethod', 1);
|
||||
$mock->aMethod();
|
||||
}
|
||||
|
||||
function testMaximumCallsSatisfiedByNoCalls() {
|
||||
$mock = &new MockDummy();
|
||||
$mock->expectMaximumCallCount('aMethod', 1);
|
||||
}
|
||||
}
|
||||
|
||||
class MockWithInjectedTestCase extends SimpleMock {
|
||||
function &_getCurrentTestCase() {
|
||||
$context = &SimpleTest::getContext();
|
||||
$test = &$context->getTest();
|
||||
return $test->getMockedTest();
|
||||
}
|
||||
}
|
||||
SimpleTest::setMockBaseClass('MockWithInjectedTestCase');
|
||||
Mock::generate('Dummy', 'MockDummyWithInjectedTestCase');
|
||||
SimpleTest::setMockBaseClass('SimpleMock');
|
||||
Mock::generate('SimpleTestCase');
|
||||
|
||||
class LikeExpectation extends IdenticalExpectation {
|
||||
function LikeExpectation($expectation) {
|
||||
$expectation->_message = '';
|
||||
$this->IdenticalExpectation($expectation);
|
||||
}
|
||||
|
||||
function test($compare) {
|
||||
$compare->_message = '';
|
||||
return parent::test($compare);
|
||||
}
|
||||
|
||||
function testMessage($compare) {
|
||||
$compare->_message = '';
|
||||
return parent::testMessage($compare);
|
||||
}
|
||||
}
|
||||
|
||||
class TestOfMockExpectations extends UnitTestCase {
|
||||
var $test;
|
||||
|
||||
function setUp() {
|
||||
$this->test = &new MockSimpleTestCase();
|
||||
}
|
||||
|
||||
function &getMockedTest() {
|
||||
return $this->test;
|
||||
}
|
||||
|
||||
function testSettingExpectationOnNonMethodThrowsError() {
|
||||
$mock = &new MockDummyWithInjectedTestCase();
|
||||
$mock->expectMaximumCallCount('aMissingMethod', 2);
|
||||
$this->assertError();
|
||||
}
|
||||
|
||||
function testMaxCallsDetectsOverrun() {
|
||||
$this->test->expectOnce('assert', array(
|
||||
new LikeExpectation(new MaximumCallCountExpectation('aMethod', 2)),
|
||||
3));
|
||||
$mock = &new MockDummyWithInjectedTestCase();
|
||||
$mock->expectMaximumCallCount('aMethod', 2);
|
||||
$mock->aMethod();
|
||||
$mock->aMethod();
|
||||
$mock->aMethod();
|
||||
$mock->_mock->atTestEnd('testSomething', $this->test);
|
||||
}
|
||||
|
||||
function testTallyOnMaxCallsSendsPassOnUnderrun() {
|
||||
$this->test->expectOnce('assert', array(
|
||||
new LikeExpectation(new MaximumCallCountExpectation('aMethod', 2)),
|
||||
2));
|
||||
$mock = &new MockDummyWithInjectedTestCase();
|
||||
$mock->expectMaximumCallCount("aMethod", 2);
|
||||
$mock->aMethod();
|
||||
$mock->aMethod();
|
||||
$mock->_mock->atTestEnd('testSomething', $this->test);
|
||||
}
|
||||
|
||||
function testExpectNeverDetectsOverrun() {
|
||||
$this->test->expectOnce('assert', array(
|
||||
new LikeExpectation(new MaximumCallCountExpectation('aMethod', 0)),
|
||||
1));
|
||||
$mock = &new MockDummyWithInjectedTestCase();
|
||||
$mock->expectNever('aMethod');
|
||||
$mock->aMethod();
|
||||
$mock->_mock->atTestEnd('testSomething', $this->test);
|
||||
}
|
||||
|
||||
function testTallyOnExpectNeverStillSendsPassOnUnderrun() {
|
||||
$this->test->expectOnce('assert', array(
|
||||
new LikeExpectation(new MaximumCallCountExpectation('aMethod', 0)),
|
||||
0));
|
||||
$mock = &new MockDummyWithInjectedTestCase();
|
||||
$mock->expectNever('aMethod');
|
||||
$mock->_mock->atTestEnd('testSomething', $this->test);
|
||||
}
|
||||
|
||||
function testMinCalls() {
|
||||
$this->test->expectOnce('assert', array(
|
||||
new LikeExpectation(new MinimumCallCountExpectation('aMethod', 2)),
|
||||
2));
|
||||
$mock = &new MockDummyWithInjectedTestCase();
|
||||
$mock->expectMinimumCallCount('aMethod', 2);
|
||||
$mock->aMethod();
|
||||
$mock->aMethod();
|
||||
$mock->_mock->atTestEnd('testSomething', $this->test);
|
||||
}
|
||||
|
||||
function testFailedNever() {
|
||||
$this->test->expectOnce('assert', array(
|
||||
new LikeExpectation(new MaximumCallCountExpectation('aMethod', 0)),
|
||||
1));
|
||||
$mock = &new MockDummyWithInjectedTestCase();
|
||||
$mock->expectNever('aMethod');
|
||||
$mock->aMethod();
|
||||
$mock->_mock->atTestEnd('testSomething', $this->test);
|
||||
}
|
||||
|
||||
function testUnderOnce() {
|
||||
$this->test->expectOnce('assert', array(
|
||||
new LikeExpectation(new CallCountExpectation('aMethod', 1)),
|
||||
0));
|
||||
$mock = &new MockDummyWithInjectedTestCase();
|
||||
$mock->expectOnce('aMethod');
|
||||
$mock->_mock->atTestEnd('testSomething', $this->test);
|
||||
}
|
||||
|
||||
function testOverOnce() {
|
||||
$this->test->expectOnce('assert', array(
|
||||
new LikeExpectation(new CallCountExpectation('aMethod', 1)),
|
||||
2));
|
||||
$mock = &new MockDummyWithInjectedTestCase();
|
||||
$mock->expectOnce('aMethod');
|
||||
$mock->aMethod();
|
||||
$mock->aMethod();
|
||||
$mock->_mock->atTestEnd('testSomething', $this->test);
|
||||
}
|
||||
|
||||
function testUnderAtLeastOnce() {
|
||||
$this->test->expectOnce('assert', array(
|
||||
new LikeExpectation(new MinimumCallCountExpectation('aMethod', 1)),
|
||||
0));
|
||||
$mock = &new MockDummyWithInjectedTestCase();
|
||||
$mock->expectAtLeastOnce("aMethod");
|
||||
$mock->_mock->atTestEnd('testSomething', $this->test);
|
||||
}
|
||||
|
||||
function testZeroArguments() {
|
||||
$this->test->expectOnce('assert', array(
|
||||
new LikeExpectation(new ParametersExpectation(array())),
|
||||
array(),
|
||||
'*'));
|
||||
$mock = &new MockDummyWithInjectedTestCase();
|
||||
$mock->expect("aMethod", array());
|
||||
$mock->aMethod();
|
||||
$mock->_mock->atTestEnd('testSomething', $this->test);
|
||||
}
|
||||
|
||||
function testExpectedArguments() {
|
||||
$this->test->expectOnce('assert', array(
|
||||
new LikeExpectation(new ParametersExpectation(array(1, 2, 3))),
|
||||
array(1, 2, 3),
|
||||
'*'));
|
||||
$mock = &new MockDummyWithInjectedTestCase();
|
||||
$mock->expect('aMethod', array(1, 2, 3));
|
||||
$mock->aMethod(1, 2, 3);
|
||||
$mock->_mock->atTestEnd('testSomething', $this->test);
|
||||
}
|
||||
|
||||
function testFailedArguments() {
|
||||
$this->test->expectOnce('assert', array(
|
||||
new LikeExpectation(new ParametersExpectation(array('this'))),
|
||||
array('that'),
|
||||
'*'));
|
||||
$mock = &new MockDummyWithInjectedTestCase();
|
||||
$mock->expect('aMethod', array('this'));
|
||||
$mock->aMethod('that');
|
||||
$mock->_mock->atTestEnd('testSomething', $this->test);
|
||||
}
|
||||
|
||||
function testWildcardsAreTranslatedToAnythingExpectations() {
|
||||
$this->test->expectOnce('assert', array(
|
||||
new LikeExpectation(new ParametersExpectation(array(
|
||||
new AnythingExpectation(), 123, new AnythingExpectation()))),
|
||||
array(100, 123, 101),
|
||||
'*'));
|
||||
$mock = &new MockDummyWithInjectedTestCase($this);
|
||||
$mock->expect("aMethod", array('*', 123, '*'));
|
||||
$mock->aMethod(100, 123, 101);
|
||||
$mock->_mock->atTestEnd('testSomething', $this->test);
|
||||
}
|
||||
|
||||
function testSpecificPassingSequence() {
|
||||
$this->test->expectAt(0, 'assert', array(
|
||||
new LikeExpectation(new ParametersExpectation(array(1, 2, 3))),
|
||||
array(1, 2, 3),
|
||||
'*'));
|
||||
$this->test->expectAt(1, 'assert', array(
|
||||
new LikeExpectation(new ParametersExpectation(array('Hello'))),
|
||||
array('Hello'),
|
||||
'*'));
|
||||
$mock = &new MockDummyWithInjectedTestCase();
|
||||
$mock->expectAt(1, 'aMethod', array(1, 2, 3));
|
||||
$mock->expectAt(2, 'aMethod', array('Hello'));
|
||||
$mock->aMethod();
|
||||
$mock->aMethod(1, 2, 3);
|
||||
$mock->aMethod('Hello');
|
||||
$mock->aMethod();
|
||||
$mock->_mock->atTestEnd('testSomething', $this->test);
|
||||
}
|
||||
|
||||
function testNonArrayForExpectedParametersGivesError() {
|
||||
$mock = &new MockDummyWithInjectedTestCase();
|
||||
$mock->expect("aMethod", "foo");
|
||||
$this->assertErrorPattern('/\$args.*not an array/i');
|
||||
$mock->aMethod();
|
||||
$mock->tally();
|
||||
$mock->_mock->atTestEnd('testSomething', $this->test);
|
||||
}
|
||||
}
|
||||
|
||||
class TestOfMockComparisons extends UnitTestCase {
|
||||
|
||||
function testEqualComparisonOfMocksDoesNotCrash() {
|
||||
$expectation = &new EqualExpectation(new MockDummy());
|
||||
$this->assertTrue($expectation->test(new MockDummy(), true));
|
||||
}
|
||||
|
||||
function testIdenticalComparisonOfMocksDoesNotCrash() {
|
||||
$expectation = &new IdenticalExpectation(new MockDummy());
|
||||
$this->assertTrue($expectation->test(new MockDummy()));
|
||||
}
|
||||
}
|
||||
|
||||
class ClassWithSpecialMethods {
|
||||
function __get($name) { }
|
||||
function __set($name, $value) { }
|
||||
function __isset($name) { }
|
||||
function __unset($name) { }
|
||||
function __call($method, $arguments) { }
|
||||
function __toString() { }
|
||||
}
|
||||
Mock::generate('ClassWithSpecialMethods');
|
||||
|
||||
class TestOfSpecialMethods extends UnitTestCase {
|
||||
function skip() {
|
||||
$this->skipIf(version_compare(phpversion(), '5', '<='), 'Overloading not tested unless PHP 5+');
|
||||
}
|
||||
|
||||
function testCanMockTheThingAtAll() {
|
||||
$mock = new MockClassWithSpecialMethods();
|
||||
}
|
||||
|
||||
function testReturnFromSpecialAccessor() {
|
||||
$mock = &new MockClassWithSpecialMethods();
|
||||
$mock->setReturnValue('__get', '1st Return', array('first'));
|
||||
$mock->setReturnValue('__get', '2nd Return', array('second'));
|
||||
$this->assertEqual($mock->first, '1st Return');
|
||||
$this->assertEqual($mock->second, '2nd Return');
|
||||
}
|
||||
|
||||
function testcanExpectTheSettingOfValue() {
|
||||
$mock = &new MockClassWithSpecialMethods();
|
||||
$mock->expectOnce('__set', array('a', 'A'));
|
||||
$mock->a = 'A';
|
||||
}
|
||||
|
||||
function testCanSimulateAnOverloadmethod() {
|
||||
$mock = &new MockClassWithSpecialMethods();
|
||||
$mock->expectOnce('__call', array('amOverloaded', array('A')));
|
||||
$mock->setReturnValue('__call', 'aaa');
|
||||
$this->assertIdentical($mock->amOverloaded('A'), 'aaa');
|
||||
}
|
||||
|
||||
function testCanEmulateIsset() {
|
||||
$mock = &new MockClassWithSpecialMethods();
|
||||
$mock->setReturnValue('__isset', true);
|
||||
$this->assertIdentical(isset($mock->a), true);
|
||||
}
|
||||
|
||||
function testCanExpectUnset() {
|
||||
$mock = &new MockClassWithSpecialMethods();
|
||||
$mock->expectOnce('__unset', array('a'));
|
||||
unset($mock->a);
|
||||
}
|
||||
|
||||
function testToStringMagic() {
|
||||
$mock = &new MockClassWithSpecialMethods();
|
||||
$mock->expectOnce('__toString');
|
||||
$mock->setReturnValue('__toString', 'AAA');
|
||||
ob_start();
|
||||
print $mock;
|
||||
$output = ob_get_contents();
|
||||
ob_end_clean();
|
||||
$this->assertEqual($output, 'AAA');
|
||||
}
|
||||
}
|
||||
|
||||
if (version_compare(phpversion(), '5', '>=')) {
|
||||
$class = 'class WithStaticMethod { ';
|
||||
$class .= ' static function aStaticMethod() { } ';
|
||||
$class .= '}';
|
||||
eval($class);
|
||||
}
|
||||
Mock::generate('WithStaticMethod');
|
||||
|
||||
class TestOfMockingClassesWithStaticMethods extends UnitTestCase {
|
||||
function skip() {
|
||||
$this->skipUnless(version_compare(phpversion(), '5', '>='), 'Static methods not tested unless PHP 5+');
|
||||
}
|
||||
|
||||
function testStaticMethodIsMockedAsStatic() {
|
||||
$mock = new WithStaticMethod();
|
||||
$reflection = new ReflectionClass($mock);
|
||||
$method = $reflection->getMethod('aStaticMethod');
|
||||
$this->assertTrue($method->isStatic());
|
||||
}
|
||||
}
|
||||
|
||||
if (version_compare(phpversion(), '5', '>=')) {
|
||||
class MockTestException extends Exception { }
|
||||
}
|
||||
|
||||
class TestOfThrowingExceptionsFromMocks extends UnitTestCase {
|
||||
function skip() {
|
||||
$this->skipUnless(version_compare(phpversion(), '5', '>='), 'Exception throwing not tested unless PHP 5+');
|
||||
}
|
||||
|
||||
function testCanThrowOnMethodCall() {
|
||||
$mock = new MockDummy();
|
||||
$mock->throwOn('aMethod');
|
||||
$this->expectException();
|
||||
$mock->aMethod();
|
||||
}
|
||||
|
||||
function testCanThrowSpecificExceptionOnMethodCall() {
|
||||
$mock = new MockDummy();
|
||||
$mock->throwOn('aMethod', new MockTestException());
|
||||
$this->expectException();
|
||||
$mock->aMethod();
|
||||
}
|
||||
|
||||
function testThrowsOnlyWhenCallSignatureMatches() {
|
||||
$mock = new MockDummy();
|
||||
$mock->throwOn('aMethod', new MockTestException(), array(3));
|
||||
$mock->aMethod(1);
|
||||
$mock->aMethod(2);
|
||||
$this->expectException();
|
||||
$mock->aMethod(3);
|
||||
}
|
||||
|
||||
function testCanThrowOnParticularInvocation() {
|
||||
$mock = new MockDummy();
|
||||
$mock->throwAt(2, 'aMethod', new MockTestException());
|
||||
$mock->aMethod();
|
||||
$mock->aMethod();
|
||||
$this->expectException();
|
||||
$mock->aMethod();
|
||||
}
|
||||
}
|
||||
|
||||
class TestOfThrowingErrorsFromMocks extends UnitTestCase {
|
||||
|
||||
function testCanGenerateErrorFromMethodCall() {
|
||||
$mock = new MockDummy();
|
||||
$mock->errorOn('aMethod', 'Ouch!');
|
||||
$this->expectError('Ouch!');
|
||||
$mock->aMethod();
|
||||
}
|
||||
|
||||
function testGeneratesErrorOnlyWhenCallSignatureMatches() {
|
||||
$mock = new MockDummy();
|
||||
$mock->errorOn('aMethod', 'Ouch!', array(3));
|
||||
$mock->aMethod(1);
|
||||
$mock->aMethod(2);
|
||||
$this->expectError();
|
||||
$mock->aMethod(3);
|
||||
}
|
||||
|
||||
function testCanGenerateErrorOnParticularInvocation() {
|
||||
$mock = new MockDummy();
|
||||
$mock->errorAt(2, 'aMethod', 'Ouch!');
|
||||
$mock->aMethod();
|
||||
$mock->aMethod();
|
||||
$this->expectError();
|
||||
$mock->aMethod();
|
||||
}
|
||||
}
|
||||
|
||||
Mock::generatePartial('Dummy', 'TestDummy', array('anotherMethod'));
|
||||
|
||||
class TestOfPartialMocks extends UnitTestCase {
|
||||
|
||||
function testMethodReplacementWithNoBehaviourReturnsNull() {
|
||||
$mock = &new TestDummy();
|
||||
$this->assertEqual($mock->aMethod(99), 99);
|
||||
$this->assertNull($mock->anotherMethod());
|
||||
}
|
||||
|
||||
function testSettingReturns() {
|
||||
$mock = &new TestDummy();
|
||||
$mock->setReturnValue('anotherMethod', 33, array(3));
|
||||
$mock->setReturnValue('anotherMethod', 22);
|
||||
$mock->setReturnValueAt(2, 'anotherMethod', 44, array(3));
|
||||
$this->assertEqual($mock->anotherMethod(), 22);
|
||||
$this->assertEqual($mock->anotherMethod(3), 33);
|
||||
$this->assertEqual($mock->anotherMethod(3), 44);
|
||||
}
|
||||
|
||||
function testReferences() {
|
||||
$mock = &new TestDummy();
|
||||
$object = new Dummy();
|
||||
$mock->setReturnReferenceAt(0, 'anotherMethod', $object, array(3));
|
||||
$this->assertReference($zref =& $mock->anotherMethod(3), $object);
|
||||
}
|
||||
|
||||
function testExpectations() {
|
||||
$mock = &new TestDummy();
|
||||
$mock->expectCallCount('anotherMethod', 2);
|
||||
$mock->expect('anotherMethod', array(77));
|
||||
$mock->expectAt(1, 'anotherMethod', array(66));
|
||||
$mock->anotherMethod(77);
|
||||
$mock->anotherMethod(66);
|
||||
}
|
||||
|
||||
function testSettingExpectationOnMissingMethodThrowsError() {
|
||||
$mock = &new TestDummy();
|
||||
$mock->expectCallCount('aMissingMethod', 2);
|
||||
$this->assertError();
|
||||
}
|
||||
}
|
||||
|
||||
class ConstructorSuperClass {
|
||||
function ConstructorSuperClass() { }
|
||||
}
|
||||
|
||||
class ConstructorSubClass extends ConstructorSuperClass {
|
||||
}
|
||||
|
||||
class TestOfPHP4StyleSuperClassConstruct extends UnitTestCase {
|
||||
/*
|
||||
* This addresses issue #1231401. Without the fix in place, this will
|
||||
* generate a fatal PHP error.
|
||||
*/
|
||||
function testBasicConstruct() {
|
||||
Mock::generate('ConstructorSubClass');
|
||||
$mock = &new MockConstructorSubClass();
|
||||
$this->assertIsA($mock, 'ConstructorSubClass');
|
||||
$this->assertTrue(method_exists($mock, 'ConstructorSuperClass'));
|
||||
}
|
||||
}
|
||||
|
||||
class TestOfPHP5StaticMethodMocking extends UnitTestCase {
|
||||
function skip() {
|
||||
$this->skipIf(version_compare(phpversion(), '5', '<='), 'Static methods not tested unless PHP 5+');
|
||||
}
|
||||
|
||||
function testCanCreateAMockObjectWithStaticMethodsWithoutError() {
|
||||
eval('
|
||||
class SimpleObjectContainingStaticMethod {
|
||||
static function someStatic() { }
|
||||
}
|
||||
');
|
||||
|
||||
Mock::generate('SimpleObjectContainingStaticMethod');
|
||||
$this->assertNoErrors();
|
||||
}
|
||||
}
|
||||
|
||||
class TestOfPHP5AbstractMethodMocking extends UnitTestCase {
|
||||
function skip() {
|
||||
$this->skipIf(version_compare(phpversion(), '5', '<='), 'Abstract class/methods not tested unless PHP 5+');
|
||||
}
|
||||
|
||||
function testCanCreateAMockObjectFromAnAbstractWithProperFunctionDeclarations() {
|
||||
eval('
|
||||
abstract class SimpleAbstractClassContainingAbstractMethods {
|
||||
abstract function anAbstract();
|
||||
abstract function anAbstractWithParameter($foo);
|
||||
abstract function anAbstractWithMultipleParameters($foo, $bar);
|
||||
}
|
||||
');
|
||||
|
||||
Mock::generate('SimpleAbstractClassContainingAbstractMethods');
|
||||
$this->assertNoErrors();
|
||||
|
||||
$this->assertTrue(
|
||||
method_exists(
|
||||
'MockSimpleAbstractClassContainingAbstractMethods',
|
||||
'anAbstract'
|
||||
)
|
||||
);
|
||||
$this->assertTrue(
|
||||
method_exists(
|
||||
'MockSimpleAbstractClassContainingAbstractMethods',
|
||||
'anAbstractWithParameter'
|
||||
)
|
||||
);
|
||||
$this->assertTrue(
|
||||
method_exists(
|
||||
'MockSimpleAbstractClassContainingAbstractMethods',
|
||||
'anAbstractWithMultipleParameters'
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
function testMethodsDefinedAsAbstractInParentShouldHaveFullSignature() {
|
||||
eval('
|
||||
abstract class SimpleParentAbstractClassContainingAbstractMethods {
|
||||
abstract function anAbstract();
|
||||
abstract function anAbstractWithParameter($foo);
|
||||
abstract function anAbstractWithMultipleParameters($foo, $bar);
|
||||
}
|
||||
|
||||
class SimpleChildAbstractClassContainingAbstractMethods extends SimpleParentAbstractClassContainingAbstractMethods {
|
||||
function anAbstract(){}
|
||||
function anAbstractWithParameter($foo){}
|
||||
function anAbstractWithMultipleParameters($foo, $bar){}
|
||||
}
|
||||
|
||||
class EvenDeeperEmptyChildClass extends SimpleChildAbstractClassContainingAbstractMethods {}
|
||||
');
|
||||
|
||||
Mock::generate('SimpleChildAbstractClassContainingAbstractMethods');
|
||||
$this->assertNoErrors();
|
||||
|
||||
$this->assertTrue(
|
||||
method_exists(
|
||||
'MockSimpleChildAbstractClassContainingAbstractMethods',
|
||||
'anAbstract'
|
||||
)
|
||||
);
|
||||
$this->assertTrue(
|
||||
method_exists(
|
||||
'MockSimpleChildAbstractClassContainingAbstractMethods',
|
||||
'anAbstractWithParameter'
|
||||
)
|
||||
);
|
||||
$this->assertTrue(
|
||||
method_exists(
|
||||
'MockSimpleChildAbstractClassContainingAbstractMethods',
|
||||
'anAbstractWithMultipleParameters'
|
||||
)
|
||||
);
|
||||
|
||||
Mock::generate('EvenDeeperEmptyChildClass');
|
||||
$this->assertNoErrors();
|
||||
|
||||
$this->assertTrue(
|
||||
method_exists(
|
||||
'MockEvenDeeperEmptyChildClass',
|
||||
'anAbstract'
|
||||
)
|
||||
);
|
||||
$this->assertTrue(
|
||||
method_exists(
|
||||
'MockEvenDeeperEmptyChildClass',
|
||||
'anAbstractWithParameter'
|
||||
)
|
||||
);
|
||||
$this->assertTrue(
|
||||
method_exists(
|
||||
'MockEvenDeeperEmptyChildClass',
|
||||
'anAbstractWithMultipleParameters'
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
903
tests/simpletest/test/page_test.php
Normal file
903
tests/simpletest/test/page_test.php
Normal file
|
|
@ -0,0 +1,903 @@
|
|||
<?php
|
||||
// $Id: page_test.php 1559 2007-07-16 18:13:24Z lastcraft $
|
||||
require_once(dirname(__FILE__) . '/../autorun.php');
|
||||
require_once(dirname(__FILE__) . '/../expectation.php');
|
||||
require_once(dirname(__FILE__) . '/../http.php');
|
||||
require_once(dirname(__FILE__) . '/../page.php');
|
||||
require_once(dirname(__FILE__) . '/../parser.php');
|
||||
Mock::generate('SimpleHtmlSaxParser');
|
||||
Mock::generate('SimplePage');
|
||||
Mock::generate('SimpleHttpResponse');
|
||||
Mock::generate('SimpleHttpHeaders');
|
||||
Mock::generate('SimplePageBuilder');
|
||||
Mock::generatePartial(
|
||||
'SimplePageBuilder',
|
||||
'PartialSimplePageBuilder',
|
||||
array('_createPage', '_createParser'));
|
||||
|
||||
class TestOfPageBuilder extends UnitTestCase {
|
||||
|
||||
function testLink() {
|
||||
$tag = &new SimpleAnchorTag(array('href' => 'http://somewhere'));
|
||||
$tag->addContent('Label');
|
||||
|
||||
$page = &new MockSimplePage();
|
||||
$page->expectArguments('acceptTag', array($tag));
|
||||
$page->expectCallCount('acceptTag', 1);
|
||||
|
||||
$builder = &new PartialSimplePageBuilder();
|
||||
$builder->setReturnReference('_createPage', $page);
|
||||
$builder->setReturnReference('_createParser', new MockSimpleHtmlSaxParser());
|
||||
$builder->SimplePageBuilder();
|
||||
|
||||
$builder->parse(new MockSimpleHttpResponse());
|
||||
$this->assertTrue($builder->startElement(
|
||||
'a',
|
||||
array('href' => 'http://somewhere')));
|
||||
$this->assertTrue($builder->addContent('Label'));
|
||||
$this->assertTrue($builder->endElement('a'));
|
||||
}
|
||||
|
||||
function testLinkWithId() {
|
||||
$tag = &new SimpleAnchorTag(array("href" => "http://somewhere", "id" => "44"));
|
||||
$tag->addContent("Label");
|
||||
|
||||
$page = &new MockSimplePage();
|
||||
$page->expectArguments("acceptTag", array($tag));
|
||||
$page->expectCallCount("acceptTag", 1);
|
||||
|
||||
$builder = &new PartialSimplePageBuilder();
|
||||
$builder->setReturnReference('_createPage', $page);
|
||||
$builder->setReturnReference('_createParser', new MockSimpleHtmlSaxParser());
|
||||
$builder->SimplePageBuilder();
|
||||
|
||||
$builder->parse(new MockSimpleHttpResponse());
|
||||
$this->assertTrue($builder->startElement(
|
||||
"a",
|
||||
array("href" => "http://somewhere", "id" => "44")));
|
||||
$this->assertTrue($builder->addContent("Label"));
|
||||
$this->assertTrue($builder->endElement("a"));
|
||||
}
|
||||
|
||||
function testLinkExtraction() {
|
||||
$tag = &new SimpleAnchorTag(array("href" => "http://somewhere"));
|
||||
$tag->addContent("Label");
|
||||
|
||||
$page = &new MockSimplePage();
|
||||
$page->expectArguments("acceptTag", array($tag));
|
||||
$page->expectCallCount("acceptTag", 1);
|
||||
|
||||
$builder = &new PartialSimplePageBuilder();
|
||||
$builder->setReturnReference('_createPage', $page);
|
||||
$builder->setReturnReference('_createParser', new MockSimpleHtmlSaxParser());
|
||||
$builder->SimplePageBuilder();
|
||||
|
||||
$builder->parse(new MockSimpleHttpResponse());
|
||||
$this->assertTrue($builder->addContent("Starting stuff"));
|
||||
$this->assertTrue($builder->startElement(
|
||||
"a",
|
||||
array("href" => "http://somewhere")));
|
||||
$this->assertTrue($builder->addContent("Label"));
|
||||
$this->assertTrue($builder->endElement("a"));
|
||||
$this->assertTrue($builder->addContent("Trailing stuff"));
|
||||
}
|
||||
|
||||
function testMultipleLinks() {
|
||||
$a1 = new SimpleAnchorTag(array("href" => "http://somewhere"));
|
||||
$a1->addContent("1");
|
||||
|
||||
$a2 = new SimpleAnchorTag(array("href" => "http://elsewhere"));
|
||||
$a2->addContent("2");
|
||||
|
||||
$page = &new MockSimplePage();
|
||||
$page->expectArgumentsAt(0, "acceptTag", array($a1));
|
||||
$page->expectArgumentsAt(1, "acceptTag", array($a2));
|
||||
$page->expectCallCount("acceptTag", 2);
|
||||
|
||||
$builder = &new PartialSimplePageBuilder();
|
||||
$builder->setReturnReference('_createPage', $page);
|
||||
$builder->setReturnReference('_createParser', new MockSimpleHtmlSaxParser());
|
||||
$builder->SimplePageBuilder();
|
||||
|
||||
$builder->parse(new MockSimpleHttpResponse());
|
||||
$builder->startElement("a", array("href" => "http://somewhere"));
|
||||
$builder->addContent("1");
|
||||
$builder->endElement("a");
|
||||
$builder->addContent("Padding");
|
||||
$builder->startElement("a", array("href" => "http://elsewhere"));
|
||||
$builder->addContent("2");
|
||||
$builder->endElement("a");
|
||||
}
|
||||
|
||||
function testTitle() {
|
||||
$tag = &new SimpleTitleTag(array());
|
||||
$tag->addContent("HereThere");
|
||||
|
||||
$page = &new MockSimplePage();
|
||||
$page->expectArguments("acceptTag", array($tag));
|
||||
$page->expectCallCount("acceptTag", 1);
|
||||
|
||||
$builder = &new PartialSimplePageBuilder();
|
||||
$builder->setReturnReference('_createPage', $page);
|
||||
$builder->setReturnReference('_createParser', new MockSimpleHtmlSaxParser());
|
||||
$builder->SimplePageBuilder();
|
||||
|
||||
$builder->parse(new MockSimpleHttpResponse());
|
||||
$builder->startElement("title", array());
|
||||
$builder->addContent("Here");
|
||||
$builder->addContent("There");
|
||||
$builder->endElement("title");
|
||||
}
|
||||
|
||||
function testForm() {
|
||||
$page = &new MockSimplePage();
|
||||
$page->expectOnce("acceptFormStart", array(new SimpleFormTag(array())));
|
||||
$page->expectOnce("acceptFormEnd", array());
|
||||
|
||||
$builder = &new PartialSimplePageBuilder();
|
||||
$builder->setReturnReference('_createPage', $page);
|
||||
$builder->setReturnReference('_createParser', new MockSimpleHtmlSaxParser());
|
||||
$builder->SimplePageBuilder();
|
||||
|
||||
$builder->parse(new MockSimpleHttpResponse());
|
||||
$builder->startElement("form", array());
|
||||
$builder->addContent("Stuff");
|
||||
$builder->endElement("form");
|
||||
}
|
||||
}
|
||||
|
||||
class TestOfPageParsing extends UnitTestCase {
|
||||
|
||||
function testParseMechanics() {
|
||||
$parser = &new MockSimpleHtmlSaxParser();
|
||||
$parser->expectOnce('parse', array('stuff'));
|
||||
|
||||
$page = &new MockSimplePage();
|
||||
$page->expectOnce('acceptPageEnd');
|
||||
|
||||
$builder = &new PartialSimplePageBuilder();
|
||||
$builder->setReturnReference('_createPage', $page);
|
||||
$builder->setReturnReference('_createParser', $parser);
|
||||
$builder->SimplePageBuilder();
|
||||
|
||||
$response = &new MockSimpleHttpResponse();
|
||||
$response->setReturnValue('getContent', 'stuff');
|
||||
$builder->parse($response);
|
||||
}
|
||||
}
|
||||
|
||||
class TestOfPageInterface extends UnitTestCase {
|
||||
|
||||
function testInterfaceOnEmptyPage() {
|
||||
$page = &new SimplePage();
|
||||
$this->assertEqual($page->getTransportError(), 'No page fetched yet');
|
||||
$this->assertIdentical($page->getRaw(), false);
|
||||
$this->assertIdentical($page->getHeaders(), false);
|
||||
$this->assertIdentical($page->getMimeType(), false);
|
||||
$this->assertIdentical($page->getResponseCode(), false);
|
||||
$this->assertIdentical($page->getAuthentication(), false);
|
||||
$this->assertIdentical($page->getRealm(), false);
|
||||
$this->assertFalse($page->hasFrames());
|
||||
$this->assertIdentical($page->getUrls(), array());
|
||||
$this->assertIdentical($page->getTitle(), false);
|
||||
}
|
||||
}
|
||||
|
||||
class TestOfPageHeaders extends UnitTestCase {
|
||||
|
||||
function testUrlAccessor() {
|
||||
$headers = &new MockSimpleHttpHeaders();
|
||||
|
||||
$response = &new MockSimpleHttpResponse();
|
||||
$response->setReturnValue('getHeaders', $headers);
|
||||
$response->setReturnValue('getMethod', 'POST');
|
||||
$response->setReturnValue('getUrl', new SimpleUrl('here'));
|
||||
$response->setReturnValue('getRequestData', array('a' => 'A'));
|
||||
|
||||
$page = &new SimplePage($response);
|
||||
$this->assertEqual($page->getMethod(), 'POST');
|
||||
$this->assertEqual($page->getUrl(), new SimpleUrl('here'));
|
||||
$this->assertEqual($page->getRequestData(), array('a' => 'A'));
|
||||
}
|
||||
|
||||
function testTransportError() {
|
||||
$response = &new MockSimpleHttpResponse();
|
||||
$response->setReturnValue('getError', 'Ouch');
|
||||
|
||||
$page = &new SimplePage($response);
|
||||
$this->assertEqual($page->getTransportError(), 'Ouch');
|
||||
}
|
||||
|
||||
function testHeadersAccessor() {
|
||||
$headers = &new MockSimpleHttpHeaders();
|
||||
$headers->setReturnValue('getRaw', 'My: Headers');
|
||||
|
||||
$response = &new MockSimpleHttpResponse();
|
||||
$response->setReturnValue('getHeaders', $headers);
|
||||
|
||||
$page = &new SimplePage($response);
|
||||
$this->assertEqual($page->getHeaders(), 'My: Headers');
|
||||
}
|
||||
|
||||
function testMimeAccessor() {
|
||||
$headers = &new MockSimpleHttpHeaders();
|
||||
$headers->setReturnValue('getMimeType', 'text/html');
|
||||
|
||||
$response = &new MockSimpleHttpResponse();
|
||||
$response->setReturnValue('getHeaders', $headers);
|
||||
|
||||
$page = &new SimplePage($response);
|
||||
$this->assertEqual($page->getMimeType(), 'text/html');
|
||||
}
|
||||
|
||||
function testResponseAccessor() {
|
||||
$headers = &new MockSimpleHttpHeaders();
|
||||
$headers->setReturnValue('getResponseCode', 301);
|
||||
|
||||
$response = &new MockSimpleHttpResponse();
|
||||
$response->setReturnValue('getHeaders', $headers);
|
||||
|
||||
$page = &new SimplePage($response);
|
||||
$this->assertIdentical($page->getResponseCode(), 301);
|
||||
}
|
||||
|
||||
function testAuthenticationAccessors() {
|
||||
$headers = &new MockSimpleHttpHeaders();
|
||||
$headers->setReturnValue('getAuthentication', 'Basic');
|
||||
$headers->setReturnValue('getRealm', 'Secret stuff');
|
||||
|
||||
$response = &new MockSimpleHttpResponse();
|
||||
$response->setReturnValue('getHeaders', $headers);
|
||||
|
||||
$page = &new SimplePage($response);
|
||||
$this->assertEqual($page->getAuthentication(), 'Basic');
|
||||
$this->assertEqual($page->getRealm(), 'Secret stuff');
|
||||
}
|
||||
}
|
||||
|
||||
class TestOfHtmlPage extends UnitTestCase {
|
||||
|
||||
function testRawAccessor() {
|
||||
$response = &new MockSimpleHttpResponse();
|
||||
$response->setReturnValue('getContent', 'Raw HTML');
|
||||
|
||||
$page = &new SimplePage($response);
|
||||
$this->assertEqual($page->getRaw(), 'Raw HTML');
|
||||
}
|
||||
|
||||
function testTextAccessor() {
|
||||
$response = &new MockSimpleHttpResponse();
|
||||
$response->setReturnValue('getContent', '<b>Some</b> "messy" HTML');
|
||||
|
||||
$page = &new SimplePage($response);
|
||||
$this->assertEqual($page->getText(), 'Some "messy" HTML');
|
||||
}
|
||||
|
||||
function testNoLinks() {
|
||||
$page = &new SimplePage(new MockSimpleHttpResponse());
|
||||
$this->assertIdentical($page->getUrls(), array());
|
||||
$this->assertIdentical($page->getUrlsByLabel('Label'), array());
|
||||
}
|
||||
|
||||
function testAddAbsoluteLink() {
|
||||
$link = &new SimpleAnchorTag(array('href' => 'http://somewhere.com'));
|
||||
$link->addContent('Label');
|
||||
$page = &new SimplePage(new MockSimpleHttpResponse());
|
||||
$page->AcceptTag($link);
|
||||
$this->assertEqual(
|
||||
$page->getUrlsByLabel('Label'),
|
||||
array(new SimpleUrl('http://somewhere.com')));
|
||||
}
|
||||
|
||||
function testAddStrictRelativeLink() {
|
||||
$link = &new SimpleAnchorTag(array('href' => './somewhere.php'));
|
||||
$link->addContent('Label');
|
||||
$response = &new MockSimpleHttpResponse();
|
||||
$response->setReturnValue('getUrl', new SimpleUrl('http://host/'));
|
||||
$page = &new SimplePage($response);
|
||||
$page->AcceptTag($link);
|
||||
$this->assertEqual(
|
||||
$page->getUrlsByLabel('Label'),
|
||||
array(new SimpleUrl('http://host/somewhere.php')));
|
||||
}
|
||||
|
||||
function testAddBareRelativeLink() {
|
||||
$response = &new MockSimpleHttpResponse();
|
||||
$response->setReturnValue('getUrl', new SimpleUrl('http://host/'));
|
||||
$page = &new SimplePage($response);
|
||||
$page->AcceptTag(new SimpleAnchorTag(array('href' => 'somewhere.php')));
|
||||
$this->assertIdentical($page->getUrls(), array('http://host/somewhere.php'));
|
||||
}
|
||||
|
||||
function testAddRelativeLinkWithBaseTag() {
|
||||
$link = &new SimpleAnchorTag(array('href' => 'somewhere.php'));
|
||||
$link->addContent('Label');
|
||||
$response = &new MockSimpleHttpResponse();
|
||||
$response->setReturnValue('getUrl', new SimpleUrl('http://host/'));
|
||||
$page = &new SimplePage($response);
|
||||
$page->AcceptTag($link);
|
||||
$base = &new SimpleBaseTag(array('href' => 'www.lastcraft.com/stuff/'));
|
||||
$page->AcceptTag($base);
|
||||
$this->assertEqual(
|
||||
$page->getUrlsByLabel('Label'),
|
||||
array(new SimpleUrl('www.lastcraft.com/stuff/somewhere.php')));
|
||||
}
|
||||
|
||||
function testAddAbsoluteLinkWithBaseTag() {
|
||||
$link = &new SimpleAnchorTag(array('href' => 'http://here.com/somewhere.php'));
|
||||
$link->addContent('Label');
|
||||
$response = &new MockSimpleHttpResponse();
|
||||
$response->setReturnValue('getUrl', new SimpleUrl('http://host/'));
|
||||
$page = &new SimplePage($response);
|
||||
$page->AcceptTag($link);
|
||||
$base = &new SimpleBaseTag(array('href' => 'www.lastcraft.com/stuff/'));
|
||||
$page->AcceptTag($base);
|
||||
$this->assertEqual(
|
||||
$page->getUrlsByLabel('Label'),
|
||||
array(new SimpleUrl('http://here.com/somewhere.php')));
|
||||
}
|
||||
|
||||
function testLinkIds() {
|
||||
$link = &new SimpleAnchorTag(array('href' => './somewhere.php', 'id' => 33));
|
||||
$link->addContent('Label');
|
||||
|
||||
$response = &new MockSimpleHttpResponse();
|
||||
$response->setReturnValue('getUrl', new SimpleUrl('http://host/'));
|
||||
|
||||
$page = &new SimplePage($response);
|
||||
$page->AcceptTag($link);
|
||||
|
||||
$this->assertEqual(
|
||||
$page->getUrlsByLabel('Label'),
|
||||
array(new SimpleUrl('http://host/somewhere.php')));
|
||||
$this->assertFalse($page->getUrlById(0));
|
||||
$this->assertEqual(
|
||||
$page->getUrlById(33),
|
||||
new SimpleUrl('http://host/somewhere.php'));
|
||||
}
|
||||
|
||||
function testFindLinkWithNormalisation() {
|
||||
$link = &new SimpleAnchorTag(array('href' => './somewhere.php', 'id' => 33));
|
||||
$link->addContent(' <em>Long & thin</em> ');
|
||||
|
||||
$response = &new MockSimpleHttpResponse();
|
||||
$response->setReturnValue('getUrl', new SimpleUrl('http://host/'));
|
||||
|
||||
$page = &new SimplePage($response);
|
||||
$page->AcceptTag($link);
|
||||
|
||||
$this->assertEqual(
|
||||
$page->getUrlsByLabel('Long & thin'),
|
||||
array(new SimpleUrl('http://host/somewhere.php')));
|
||||
}
|
||||
|
||||
function testFindLinkWithImage() {
|
||||
$link = &new SimpleAnchorTag(array('href' => './somewhere.php', 'id' => 33));
|
||||
$link->addContent('<img src="pic.jpg" alt="<A picture>">');
|
||||
|
||||
$response = &new MockSimpleHttpResponse();
|
||||
$response->setReturnValue('getUrl', new SimpleUrl('http://host/'));
|
||||
|
||||
$page = &new SimplePage($response);
|
||||
$page->AcceptTag($link);
|
||||
|
||||
$this->assertEqual(
|
||||
$page->getUrlsByLabel('<A picture>'),
|
||||
array(new SimpleUrl('http://host/somewhere.php')));
|
||||
}
|
||||
|
||||
function testTitleSetting() {
|
||||
$title = &new SimpleTitleTag(array());
|
||||
$title->addContent('Title');
|
||||
$page = &new SimplePage(new MockSimpleHttpResponse());
|
||||
$page->AcceptTag($title);
|
||||
$this->assertEqual($page->getTitle(), 'Title');
|
||||
}
|
||||
|
||||
function testFramesetAbsence() {
|
||||
$url = new SimpleUrl('here');
|
||||
$response = new MockSimpleHttpResponse();
|
||||
$response->setReturnValue('getUrl', $url);
|
||||
$page = &new SimplePage($response);
|
||||
$this->assertFalse($page->hasFrames());
|
||||
$this->assertIdentical($page->getFrameset(), false);
|
||||
}
|
||||
|
||||
function testHasEmptyFrameset() {
|
||||
$page = &new SimplePage(new MockSimpleHttpResponse());
|
||||
$page->acceptFramesetStart(new SimpleTag('frameset', array()));
|
||||
$page->acceptFramesetEnd();
|
||||
$this->assertTrue($page->hasFrames());
|
||||
$this->assertIdentical($page->getFrameset(), array());
|
||||
}
|
||||
|
||||
function testFramesInPage() {
|
||||
$response = &new MockSimpleHttpResponse();
|
||||
$response->setReturnValue('getUrl', new SimpleUrl('http://here'));
|
||||
|
||||
$page = &new SimplePage($response);
|
||||
$page->acceptFrame(new SimpleFrameTag(array('src' => '1.html')));
|
||||
$page->acceptFramesetStart(new SimpleTag('frameset', array()));
|
||||
$page->acceptFrame(new SimpleFrameTag(array('src' => '2.html')));
|
||||
$page->acceptFrame(new SimpleFrameTag(array('src' => '3.html')));
|
||||
$page->acceptFramesetEnd();
|
||||
$page->acceptFrame(new SimpleFrameTag(array('src' => '4.html')));
|
||||
|
||||
$this->assertTrue($page->hasFrames());
|
||||
$this->assertIdentical($page->getFrameset(), array(
|
||||
1 => new SimpleUrl('http://here/2.html'),
|
||||
2 => new SimpleUrl('http://here/3.html')));
|
||||
}
|
||||
|
||||
function testNamedFramesInPage() {
|
||||
$response = &new MockSimpleHttpResponse();
|
||||
$response->setReturnValue('getUrl', new SimpleUrl('http://here'));
|
||||
|
||||
$page = &new SimplePage($response);
|
||||
$page->acceptFramesetStart(new SimpleTag('frameset', array()));
|
||||
$page->acceptFrame(new SimpleFrameTag(array('src' => '1.html')));
|
||||
$page->acceptFrame(new SimpleFrameTag(array('src' => '2.html', 'name' => 'A')));
|
||||
$page->acceptFrame(new SimpleFrameTag(array('src' => '3.html', 'name' => 'B')));
|
||||
$page->acceptFrame(new SimpleFrameTag(array('src' => '4.html')));
|
||||
$page->acceptFramesetEnd();
|
||||
|
||||
$this->assertTrue($page->hasFrames());
|
||||
$this->assertIdentical($page->getFrameset(), array(
|
||||
1 => new SimpleUrl('http://here/1.html'),
|
||||
'A' => new SimpleUrl('http://here/2.html'),
|
||||
'B' => new SimpleUrl('http://here/3.html'),
|
||||
4 => new SimpleUrl('http://here/4.html')));
|
||||
}
|
||||
|
||||
function testRelativeFramesRespectBaseTag() {
|
||||
$response = &new MockSimpleHttpResponse();
|
||||
$response->setReturnValue('getUrl', new SimpleUrl('http://here.com/'));
|
||||
$page = &new SimplePage($response);
|
||||
|
||||
$base = &new SimpleBaseTag(array('href' => 'https://there.com/stuff/'));
|
||||
$page->AcceptTag($base);
|
||||
|
||||
$page->acceptFramesetStart(new SimpleTag('frameset', array()));
|
||||
$page->acceptFrame(new SimpleFrameTag(array('src' => '1.html')));
|
||||
$page->acceptFramesetEnd();
|
||||
$this->assertIdentical(
|
||||
$page->getFrameset(),
|
||||
array(1 => new SimpleUrl('https://there.com/stuff/1.html')));
|
||||
}
|
||||
}
|
||||
|
||||
class TestOfFormsCreatedFromEventStream extends UnitTestCase {
|
||||
|
||||
function testFormCanBeSubmitted() {
|
||||
$page = &new SimplePage(new MockSimpleHttpResponse());
|
||||
$page->acceptFormStart(
|
||||
new SimpleFormTag(array('method' => 'GET', 'action' => 'here.php')));
|
||||
$page->AcceptTag(
|
||||
new SimpleSubmitTag(array('type' => 'submit', 'name' => 's')));
|
||||
$page->acceptFormEnd();
|
||||
$form = &$page->getFormBySubmit(new SimpleByLabel('Submit'));
|
||||
$this->assertEqual(
|
||||
$form->submitButton(new SimpleByLabel('Submit')),
|
||||
new SimpleGetEncoding(array('s' => 'Submit')));
|
||||
}
|
||||
|
||||
function testInputFieldCanBeReadBack() {
|
||||
$page = &new SimplePage(new MockSimpleHttpResponse());
|
||||
$page->acceptFormStart(
|
||||
new SimpleFormTag(array("method" => "GET", "action" => "here.php")));
|
||||
$page->AcceptTag(
|
||||
new SimpleTextTag(array("type" => "text", "name" => "a", "value" => "A")));
|
||||
$page->AcceptTag(
|
||||
new SimpleSubmitTag(array("type" => "submit", "name" => "s")));
|
||||
$page->acceptFormEnd();
|
||||
$this->assertEqual($page->getField(new SimpleByName('a')), 'A');
|
||||
}
|
||||
|
||||
function testInputFieldCanBeReadBackByLabel() {
|
||||
$label = &new SimpleLabelTag(array());
|
||||
$page = &new SimplePage(new MockSimpleHttpResponse());
|
||||
$page->acceptFormStart(
|
||||
new SimpleFormTag(array("method" => "GET", "action" => "here.php")));
|
||||
$page->acceptLabelStart($label);
|
||||
$label->addContent('l');
|
||||
$page->AcceptTag(
|
||||
new SimpleTextTag(array("type" => "text", "name" => "a", "value" => "A")));
|
||||
$page->acceptLabelEnd();
|
||||
$page->AcceptTag(
|
||||
new SimpleSubmitTag(array("type" => "submit", "name" => "s")));
|
||||
$page->acceptFormEnd();
|
||||
$this->assertEqual($page->getField(new SimpleByLabel('l')), 'A');
|
||||
}
|
||||
}
|
||||
|
||||
class TestOfPageScraping extends UnitTestCase {
|
||||
|
||||
function &parse($response) {
|
||||
$builder = &new SimplePageBuilder();
|
||||
$page = &$builder->parse($response);
|
||||
return $page;
|
||||
}
|
||||
|
||||
function testEmptyPage() {
|
||||
$page = &new SimplePage(new MockSimpleHttpResponse());
|
||||
$this->assertIdentical($page->getUrls(), array());
|
||||
$this->assertIdentical($page->getTitle(), false);
|
||||
}
|
||||
|
||||
function testUninterestingPage() {
|
||||
$response = &new MockSimpleHttpResponse();
|
||||
$response->setReturnValue('getContent', '<html><body><p>Stuff</p></body></html>');
|
||||
$page = &$this->parse($response);
|
||||
$this->assertIdentical($page->getUrls(), array());
|
||||
}
|
||||
|
||||
function testLinksPage() {
|
||||
$raw = '<html>';
|
||||
$raw .= '<a href="there.html">There</a>';
|
||||
$raw .= '<a href="http://there.com/that.html" id="0">That page</a>';
|
||||
$raw .= '</html>';
|
||||
$response = &new MockSimpleHttpResponse();
|
||||
$response->setReturnValue('getContent', $raw);
|
||||
$response->setReturnValue('getUrl', new SimpleUrl('http://www.here.com/a/index.html'));
|
||||
|
||||
$page = &$this->parse($response);
|
||||
$this->assertIdentical(
|
||||
$page->getUrls(),
|
||||
array('http://www.here.com/a/there.html', 'http://there.com/that.html'));
|
||||
$this->assertIdentical(
|
||||
$page->getUrlsByLabel('There'),
|
||||
array(new SimpleUrl('http://www.here.com/a/there.html')));
|
||||
$this->assertEqual(
|
||||
$page->getUrlById('0'),
|
||||
new SimpleUrl('http://there.com/that.html'));
|
||||
}
|
||||
|
||||
function testTitle() {
|
||||
$response = &new MockSimpleHttpResponse();
|
||||
$response->setReturnValue('getContent', '<html><head><title>Me</title></head></html>');
|
||||
$page = &$this->parse($response);
|
||||
$this->assertEqual($page->getTitle(), 'Me');
|
||||
}
|
||||
|
||||
function testNastyTitle() {
|
||||
$response = &new MockSimpleHttpResponse();
|
||||
$response->setReturnValue(
|
||||
'getContent',
|
||||
'<html><head><Title> <b>Me&Me </TITLE></b></head></html>');
|
||||
$page = &$this->parse($response);
|
||||
$this->assertEqual($page->getTitle(), "Me&Me");
|
||||
}
|
||||
|
||||
function testCompleteForm() {
|
||||
$response = &new MockSimpleHttpResponse();
|
||||
$response->setReturnValue('getContent',
|
||||
'<html><head><form>' .
|
||||
'<input type="text" name="here" value="Hello">' .
|
||||
'</form></head></html>');
|
||||
$page = &$this->parse($response);
|
||||
$this->assertEqual($page->getField(new SimpleByName('here')), "Hello");
|
||||
}
|
||||
|
||||
function testUnclosedForm() {
|
||||
$response = &new MockSimpleHttpResponse();
|
||||
$response->setReturnValue('getContent',
|
||||
'<html><head><form>' .
|
||||
'<input type="text" name="here" value="Hello">' .
|
||||
'</head></html>');
|
||||
$page = &$this->parse($response);
|
||||
$this->assertEqual($page->getField(new SimpleByName('here')), "Hello");
|
||||
}
|
||||
|
||||
function testEmptyFrameset() {
|
||||
$response = &new MockSimpleHttpResponse();
|
||||
$response->setReturnValue(
|
||||
'getContent',
|
||||
'<html><frameset></frameset></html>');
|
||||
$page = &$this->parse($response);
|
||||
$this->assertTrue($page->hasFrames());
|
||||
$this->assertIdentical($page->getFrameset(), array());
|
||||
}
|
||||
|
||||
function testSingleFrame() {
|
||||
$response = &new MockSimpleHttpResponse();
|
||||
$response->setReturnValue(
|
||||
'getContent',
|
||||
'<html><frameset><frame src="a.html"></frameset></html>');
|
||||
$response->setReturnValue('getUrl', new SimpleUrl('http://host/'));
|
||||
|
||||
$page = &$this->parse($response);
|
||||
$this->assertTrue($page->hasFrames());
|
||||
$this->assertIdentical(
|
||||
$page->getFrameset(),
|
||||
array(1 => new SimpleUrl('http://host/a.html')));
|
||||
}
|
||||
|
||||
function testSingleFrameInNestedFrameset() {
|
||||
$response = &new MockSimpleHttpResponse();
|
||||
$response->setReturnValue('getContent',
|
||||
'<html><frameset><frameset>' .
|
||||
'<frame src="a.html">' .
|
||||
'</frameset></frameset></html>');
|
||||
$response->setReturnValue('getUrl', new SimpleUrl('http://host/'));
|
||||
|
||||
$page = &$this->parse($response);
|
||||
$this->assertTrue($page->hasFrames());
|
||||
$this->assertIdentical(
|
||||
$page->getFrameset(),
|
||||
array(1 => new SimpleUrl('http://host/a.html')));
|
||||
}
|
||||
|
||||
function testFrameWithNoSource() {
|
||||
$response = &new MockSimpleHttpResponse();
|
||||
$response->setReturnValue(
|
||||
'getContent',
|
||||
'<html><frameset><frame></frameset></html>');
|
||||
$page = &$this->parse($response);
|
||||
$this->assertTrue($page->hasFrames());
|
||||
$this->assertIdentical($page->getFrameset(), array());
|
||||
}
|
||||
|
||||
function testFramesCollectedWithNestedFramesetTags() {
|
||||
$response = &new MockSimpleHttpResponse();
|
||||
$response->setReturnValue('getContent',
|
||||
'<html><frameset>' .
|
||||
'<frame src="a.html">' .
|
||||
'<frameset><frame src="b.html"></frameset>' .
|
||||
'<frame src="c.html">' .
|
||||
'</frameset></html>');
|
||||
$response->setReturnValue('getUrl', new SimpleUrl('http://host/'));
|
||||
|
||||
$page = &$this->parse($response);
|
||||
$this->assertTrue($page->hasFrames());
|
||||
$this->assertIdentical($page->getFrameset(), array(
|
||||
1 => new SimpleUrl('http://host/a.html'),
|
||||
2 => new SimpleUrl('http://host/b.html'),
|
||||
3 => new SimpleUrl('http://host/c.html')));
|
||||
}
|
||||
|
||||
function testNamedFrames() {
|
||||
$response = &new MockSimpleHttpResponse();
|
||||
$response->setReturnValue('getContent',
|
||||
'<html><frameset>' .
|
||||
'<frame src="a.html">' .
|
||||
'<frame name="_one" src="b.html">' .
|
||||
'<frame src="c.html">' .
|
||||
'<frame src="d.html" name="_two">' .
|
||||
'</frameset></html>');
|
||||
$response->setReturnValue('getUrl', new SimpleUrl('http://host/'));
|
||||
|
||||
$page = &$this->parse($response);
|
||||
$this->assertTrue($page->hasFrames());
|
||||
$this->assertIdentical($page->getFrameset(), array(
|
||||
1 => new SimpleUrl('http://host/a.html'),
|
||||
'_one' => new SimpleUrl('http://host/b.html'),
|
||||
3 => new SimpleUrl('http://host/c.html'),
|
||||
'_two' => new SimpleUrl('http://host/d.html')));
|
||||
}
|
||||
|
||||
function testFindFormByLabel() {
|
||||
$response = &new MockSimpleHttpResponse();
|
||||
$response->setReturnValue(
|
||||
'getContent',
|
||||
'<html><head><form><input type="submit"></form></head></html>');
|
||||
$page = &$this->parse($response);
|
||||
$this->assertNull($page->getFormBySubmit(new SimpleByLabel('submit')));
|
||||
$this->assertNull($page->getFormBySubmit(new SimpleByName('submit')));
|
||||
$this->assertIsA(
|
||||
$page->getFormBySubmit(new SimpleByLabel('Submit')),
|
||||
'SimpleForm');
|
||||
}
|
||||
|
||||
function testConfirmSubmitAttributesAreCaseSensitive() {
|
||||
$response = &new MockSimpleHttpResponse();
|
||||
$response->setReturnValue(
|
||||
'getContent',
|
||||
'<html><head><FORM><INPUT TYPE="SUBMIT" NAME="S" VALUE="S"></FORM></head></html>');
|
||||
$page = &$this->parse($response);
|
||||
$this->assertIsA(
|
||||
$page->getFormBySubmit(new SimpleByName('S')),
|
||||
'SimpleForm');
|
||||
$this->assertIsA(
|
||||
$page->getFormBySubmit(new SimpleByLabel('S')),
|
||||
'SimpleForm');
|
||||
}
|
||||
|
||||
function testFindFormByImage() {
|
||||
$response = &new MockSimpleHttpResponse();
|
||||
$response->setReturnValue('getContent',
|
||||
'<html><head><form>' .
|
||||
'<input type="image" id=100 alt="Label" name="me">' .
|
||||
'</form></head></html>');
|
||||
$page = &$this->parse($response);
|
||||
$this->assertIsA(
|
||||
$page->getFormByImage(new SimpleByLabel('Label')),
|
||||
'SimpleForm');
|
||||
$this->assertIsA(
|
||||
$page->getFormByImage(new SimpleByName('me')),
|
||||
'SimpleForm');
|
||||
$this->assertIsA(
|
||||
$page->getFormByImage(new SimpleById(100)),
|
||||
'SimpleForm');
|
||||
}
|
||||
|
||||
function testFindFormByButtonTag() {
|
||||
$response = &new MockSimpleHttpResponse();
|
||||
$response->setReturnValue('getContent',
|
||||
'<html><head><form>' .
|
||||
'<button type="submit" name="b" value="B">BBB</button>' .
|
||||
'</form></head></html>');
|
||||
$page = &$this->parse($response);
|
||||
$this->assertNull($page->getFormBySubmit(new SimpleByLabel('b')));
|
||||
$this->assertNull($page->getFormBySubmit(new SimpleByLabel('B')));
|
||||
$this->assertIsA(
|
||||
$page->getFormBySubmit(new SimpleByName('b')),
|
||||
'SimpleForm');
|
||||
$this->assertIsA(
|
||||
$page->getFormBySubmit(new SimpleByLabel('BBB')),
|
||||
'SimpleForm');
|
||||
}
|
||||
|
||||
function testFindFormById() {
|
||||
$response = &new MockSimpleHttpResponse();
|
||||
$response->setReturnValue(
|
||||
'getContent',
|
||||
'<html><head><form id="55"><input type="submit"></form></head></html>');
|
||||
$page = &$this->parse($response);
|
||||
$this->assertNull($page->getFormById(54));
|
||||
$this->assertIsA($page->getFormById(55), 'SimpleForm');
|
||||
}
|
||||
|
||||
function testReadingTextField() {
|
||||
$response = &new MockSimpleHttpResponse();
|
||||
$response->setReturnValue('getContent',
|
||||
'<html><head><form>' .
|
||||
'<input type="text" name="a">' .
|
||||
'<input type="text" name="b" value="bbb" id=3>' .
|
||||
'</form></head></html>');
|
||||
$page = &$this->parse($response);
|
||||
$this->assertNull($page->getField(new SimpleByName('missing')));
|
||||
$this->assertIdentical($page->getField(new SimpleByName('a')), '');
|
||||
$this->assertIdentical($page->getField(new SimpleByName('b')), 'bbb');
|
||||
}
|
||||
|
||||
function testReadingTextFieldIsCaseInsensitive() {
|
||||
$response = &new MockSimpleHttpResponse();
|
||||
$response->setReturnValue('getContent',
|
||||
'<html><head><FORM>' .
|
||||
'<INPUT TYPE="TEXT" NAME="a">' .
|
||||
'<INPUT TYPE="TEXT" NAME="b" VALUE="bbb" id=3>' .
|
||||
'</FORM></head></html>');
|
||||
$page = &$this->parse($response);
|
||||
$this->assertNull($page->getField(new SimpleByName('missing')));
|
||||
$this->assertIdentical($page->getField(new SimpleByName('a')), '');
|
||||
$this->assertIdentical($page->getField(new SimpleByName('b')), 'bbb');
|
||||
}
|
||||
|
||||
function testSettingTextField() {
|
||||
$response = &new MockSimpleHttpResponse();
|
||||
$response->setReturnValue('getContent',
|
||||
'<html><head><form>' .
|
||||
'<input type="text" name="a">' .
|
||||
'<input type="text" name="b" id=3>' .
|
||||
'<input type="submit">' .
|
||||
'</form></head></html>');
|
||||
$page = &$this->parse($response);
|
||||
$this->assertTrue($page->setField(new SimpleByName('a'), 'aaa'));
|
||||
$this->assertEqual($page->getField(new SimpleByName('a')), 'aaa');
|
||||
$this->assertTrue($page->setField(new SimpleById(3), 'bbb'));
|
||||
$this->assertEqual($page->getField(new SimpleBYId(3)), 'bbb');
|
||||
$this->assertFalse($page->setField(new SimpleByName('z'), 'zzz'));
|
||||
$this->assertNull($page->getField(new SimpleByName('z')));
|
||||
}
|
||||
|
||||
function testSettingTextFieldByEnclosingLabel() {
|
||||
$response = &new MockSimpleHttpResponse();
|
||||
$response->setReturnValue('getContent',
|
||||
'<html><head><form>' .
|
||||
'<label>Stuff' .
|
||||
'<input type="text" name="a" value="A">' .
|
||||
'</label>' .
|
||||
'</form></head></html>');
|
||||
$page = &$this->parse($response);
|
||||
$this->assertEqual($page->getField(new SimpleByName('a')), 'A');
|
||||
$this->assertEqual($page->getField(new SimpleByLabel('Stuff')), 'A');
|
||||
$this->assertTrue($page->setField(new SimpleByLabel('Stuff'), 'aaa'));
|
||||
$this->assertEqual($page->getField(new SimpleByLabel('Stuff')), 'aaa');
|
||||
}
|
||||
|
||||
function testGettingTextFieldByEnclosingLabelWithConflictingOtherFields() {
|
||||
$response = &new MockSimpleHttpResponse();
|
||||
$response->setReturnValue('getContent',
|
||||
'<html><head><form>' .
|
||||
'<label>Stuff' .
|
||||
'<input type="text" name="a" value="A">' .
|
||||
'</label>' .
|
||||
'<input type="text" name="b" value="B">' .
|
||||
'</form></head></html>');
|
||||
$page = &$this->parse($response);
|
||||
$this->assertEqual($page->getField(new SimpleByName('a')), 'A');
|
||||
$this->assertEqual($page->getField(new SimpleByName('b')), 'B');
|
||||
$this->assertEqual($page->getField(new SimpleByLabel('Stuff')), 'A');
|
||||
}
|
||||
|
||||
function testSettingTextFieldByExternalLabel() {
|
||||
$response = &new MockSimpleHttpResponse();
|
||||
$response->setReturnValue('getContent',
|
||||
'<html><head><form>' .
|
||||
'<label for="aaa">Stuff</label>' .
|
||||
'<input id="aaa" type="text" name="a" value="A">' .
|
||||
'</form></head></html>');
|
||||
$page = &$this->parse($response);
|
||||
$this->assertEqual($page->getField(new SimpleByLabel('Stuff')), 'A');
|
||||
$this->assertTrue($page->setField(new SimpleByLabel('Stuff'), 'aaa'));
|
||||
$this->assertEqual($page->getField(new SimpleByLabel('Stuff')), 'aaa');
|
||||
}
|
||||
|
||||
function testReadingTextArea() {
|
||||
$response = &new MockSimpleHttpResponse();
|
||||
$response->setReturnValue('getContent',
|
||||
'<html><head><form>' .
|
||||
'<textarea name="a">aaa</textarea>' .
|
||||
'<input type="submit">' .
|
||||
'</form></head></html>');
|
||||
$page = &$this->parse($response);
|
||||
$this->assertEqual($page->getField(new SimpleByName('a')), 'aaa');
|
||||
}
|
||||
|
||||
function testSettingTextArea() {
|
||||
$response = &new MockSimpleHttpResponse();
|
||||
$response->setReturnValue('getContent',
|
||||
'<html><head><form>' .
|
||||
'<textarea name="a">aaa</textarea>' .
|
||||
'<input type="submit">' .
|
||||
'</form></head></html>');
|
||||
$page = &$this->parse($response);
|
||||
$this->assertTrue($page->setField(new SimpleByName('a'), 'AAA'));
|
||||
$this->assertEqual($page->getField(new SimpleByName('a')), 'AAA');
|
||||
}
|
||||
|
||||
function testSettingSelectionField() {
|
||||
$response = &new MockSimpleHttpResponse();
|
||||
$response->setReturnValue('getContent',
|
||||
'<html><head><form>' .
|
||||
'<select name="a">' .
|
||||
'<option>aaa</option>' .
|
||||
'<option selected>bbb</option>' .
|
||||
'</select>' .
|
||||
'<input type="submit">' .
|
||||
'</form></head></html>');
|
||||
$page = &$this->parse($response);
|
||||
$this->assertEqual($page->getField(new SimpleByName('a')), 'bbb');
|
||||
$this->assertFalse($page->setField(new SimpleByName('a'), 'ccc'));
|
||||
$this->assertTrue($page->setField(new SimpleByName('a'), 'aaa'));
|
||||
$this->assertEqual($page->getField(new SimpleByName('a')), 'aaa');
|
||||
}
|
||||
|
||||
function testSettingSelectionFieldByEnclosingLabel() {
|
||||
$response = &new MockSimpleHttpResponse();
|
||||
$response->setReturnValue('getContent',
|
||||
'<html><head><form>' .
|
||||
'<label>Stuff' .
|
||||
'<select name="a"><option selected>A</option><option>B</option></select>' .
|
||||
'</label>' .
|
||||
'</form></head></html>');
|
||||
$page = &$this->parse($response);
|
||||
$this->assertEqual($page->getField(new SimpleByLabel('Stuff')), 'A');
|
||||
$this->assertTrue($page->setField(new SimpleByLabel('Stuff'), 'B'));
|
||||
$this->assertEqual($page->getField(new SimpleByLabel('Stuff')), 'B');
|
||||
}
|
||||
|
||||
function testSettingRadioButtonByEnclosingLabel() {
|
||||
$response = &new MockSimpleHttpResponse();
|
||||
$response->setReturnValue('getContent',
|
||||
'<html><head><form>' .
|
||||
'<label>A<input type="radio" name="r" value="a" checked></label>' .
|
||||
'<label>B<input type="radio" name="r" value="b"></label>' .
|
||||
'</form></head></html>');
|
||||
$page = &$this->parse($response);
|
||||
$this->assertEqual($page->getField(new SimpleByLabel('A')), 'a');
|
||||
$this->assertTrue($page->setField(new SimpleBylabel('B'), 'b'));
|
||||
$this->assertEqual($page->getField(new SimpleByLabel('B')), 'b');
|
||||
}
|
||||
}
|
||||
?>
|
||||
9
tests/simpletest/test/parse_error_test.php
Normal file
9
tests/simpletest/test/parse_error_test.php
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
<?php
|
||||
// $Id: parse_error_test.php 1509 2007-05-08 22:11:49Z lastcraft $
|
||||
require_once('../unit_tester.php');
|
||||
require_once('../reporter.php');
|
||||
|
||||
$test = &new TestSuite('This should fail');
|
||||
$test->addFile('test_with_parse_error.php');
|
||||
$test->run(new HtmlReporter());
|
||||
?>
|
||||
551
tests/simpletest/test/parser_test.php
Normal file
551
tests/simpletest/test/parser_test.php
Normal file
|
|
@ -0,0 +1,551 @@
|
|||
<?php
|
||||
// $Id: parser_test.php 1608 2007-12-27 09:03:07Z pp11 $
|
||||
require_once(dirname(__FILE__) . '/../autorun.php');
|
||||
require_once(dirname(__FILE__) . '/../parser.php');
|
||||
Mock::generate('SimpleHtmlSaxParser');
|
||||
Mock::generate('SimpleSaxListener');
|
||||
|
||||
class TestOfParallelRegex extends UnitTestCase {
|
||||
|
||||
function testNoPatterns() {
|
||||
$regex = &new ParallelRegex(false);
|
||||
$this->assertFalse($regex->match("Hello", $match));
|
||||
$this->assertEqual($match, "");
|
||||
}
|
||||
|
||||
function testNoSubject() {
|
||||
$regex = &new ParallelRegex(false);
|
||||
$regex->addPattern(".*");
|
||||
$this->assertTrue($regex->match("", $match));
|
||||
$this->assertEqual($match, "");
|
||||
}
|
||||
|
||||
function testMatchAll() {
|
||||
$regex = &new ParallelRegex(false);
|
||||
$regex->addPattern(".*");
|
||||
$this->assertTrue($regex->match("Hello", $match));
|
||||
$this->assertEqual($match, "Hello");
|
||||
}
|
||||
|
||||
function testCaseSensitive() {
|
||||
$regex = &new ParallelRegex(true);
|
||||
$regex->addPattern("abc");
|
||||
$this->assertTrue($regex->match("abcdef", $match));
|
||||
$this->assertEqual($match, "abc");
|
||||
$this->assertTrue($regex->match("AAABCabcdef", $match));
|
||||
$this->assertEqual($match, "abc");
|
||||
}
|
||||
|
||||
function testCaseInsensitive() {
|
||||
$regex = &new ParallelRegex(false);
|
||||
$regex->addPattern("abc");
|
||||
$this->assertTrue($regex->match("abcdef", $match));
|
||||
$this->assertEqual($match, "abc");
|
||||
$this->assertTrue($regex->match("AAABCabcdef", $match));
|
||||
$this->assertEqual($match, "ABC");
|
||||
}
|
||||
|
||||
function testMatchMultiple() {
|
||||
$regex = &new ParallelRegex(true);
|
||||
$regex->addPattern("abc");
|
||||
$regex->addPattern("ABC");
|
||||
$this->assertTrue($regex->match("abcdef", $match));
|
||||
$this->assertEqual($match, "abc");
|
||||
$this->assertTrue($regex->match("AAABCabcdef", $match));
|
||||
$this->assertEqual($match, "ABC");
|
||||
$this->assertFalse($regex->match("Hello", $match));
|
||||
}
|
||||
|
||||
function testPatternLabels() {
|
||||
$regex = &new ParallelRegex(false);
|
||||
$regex->addPattern("abc", "letter");
|
||||
$regex->addPattern("123", "number");
|
||||
$this->assertIdentical($regex->match("abcdef", $match), "letter");
|
||||
$this->assertEqual($match, "abc");
|
||||
$this->assertIdentical($regex->match("0123456789", $match), "number");
|
||||
$this->assertEqual($match, "123");
|
||||
}
|
||||
}
|
||||
|
||||
class TestOfStateStack extends UnitTestCase {
|
||||
|
||||
function testStartState() {
|
||||
$stack = &new SimpleStateStack("one");
|
||||
$this->assertEqual($stack->getCurrent(), "one");
|
||||
}
|
||||
|
||||
function testExhaustion() {
|
||||
$stack = &new SimpleStateStack("one");
|
||||
$this->assertFalse($stack->leave());
|
||||
}
|
||||
|
||||
function testStateMoves() {
|
||||
$stack = &new SimpleStateStack("one");
|
||||
$stack->enter("two");
|
||||
$this->assertEqual($stack->getCurrent(), "two");
|
||||
$stack->enter("three");
|
||||
$this->assertEqual($stack->getCurrent(), "three");
|
||||
$this->assertTrue($stack->leave());
|
||||
$this->assertEqual($stack->getCurrent(), "two");
|
||||
$stack->enter("third");
|
||||
$this->assertEqual($stack->getCurrent(), "third");
|
||||
$this->assertTrue($stack->leave());
|
||||
$this->assertTrue($stack->leave());
|
||||
$this->assertEqual($stack->getCurrent(), "one");
|
||||
}
|
||||
}
|
||||
|
||||
class TestParser {
|
||||
|
||||
function accept() {
|
||||
}
|
||||
|
||||
function a() {
|
||||
}
|
||||
|
||||
function b() {
|
||||
}
|
||||
}
|
||||
Mock::generate('TestParser');
|
||||
|
||||
class TestOfLexer extends UnitTestCase {
|
||||
|
||||
function testEmptyPage() {
|
||||
$handler = &new MockTestParser();
|
||||
$handler->expectNever("accept");
|
||||
$handler->setReturnValue("accept", true);
|
||||
$handler->expectNever("accept");
|
||||
$handler->setReturnValue("accept", true);
|
||||
$lexer = &new SimpleLexer($handler);
|
||||
$lexer->addPattern("a+");
|
||||
$this->assertTrue($lexer->parse(""));
|
||||
}
|
||||
|
||||
function testSinglePattern() {
|
||||
$handler = &new MockTestParser();
|
||||
$handler->expectArgumentsAt(0, "accept", array("aaa", LEXER_MATCHED));
|
||||
$handler->expectArgumentsAt(1, "accept", array("x", LEXER_UNMATCHED));
|
||||
$handler->expectArgumentsAt(2, "accept", array("a", LEXER_MATCHED));
|
||||
$handler->expectArgumentsAt(3, "accept", array("yyy", LEXER_UNMATCHED));
|
||||
$handler->expectArgumentsAt(4, "accept", array("a", LEXER_MATCHED));
|
||||
$handler->expectArgumentsAt(5, "accept", array("x", LEXER_UNMATCHED));
|
||||
$handler->expectArgumentsAt(6, "accept", array("aaa", LEXER_MATCHED));
|
||||
$handler->expectArgumentsAt(7, "accept", array("z", LEXER_UNMATCHED));
|
||||
$handler->expectCallCount("accept", 8);
|
||||
$handler->setReturnValue("accept", true);
|
||||
$lexer = &new SimpleLexer($handler);
|
||||
$lexer->addPattern("a+");
|
||||
$this->assertTrue($lexer->parse("aaaxayyyaxaaaz"));
|
||||
}
|
||||
|
||||
function testMultiplePattern() {
|
||||
$handler = &new MockTestParser();
|
||||
$target = array("a", "b", "a", "bb", "x", "b", "a", "xxxxxx", "a", "x");
|
||||
for ($i = 0; $i < count($target); $i++) {
|
||||
$handler->expectArgumentsAt($i, "accept", array($target[$i], '*'));
|
||||
}
|
||||
$handler->expectCallCount("accept", count($target));
|
||||
$handler->setReturnValue("accept", true);
|
||||
$lexer = &new SimpleLexer($handler);
|
||||
$lexer->addPattern("a+");
|
||||
$lexer->addPattern("b+");
|
||||
$this->assertTrue($lexer->parse("ababbxbaxxxxxxax"));
|
||||
}
|
||||
}
|
||||
|
||||
class TestOfLexerModes extends UnitTestCase {
|
||||
|
||||
function testIsolatedPattern() {
|
||||
$handler = &new MockTestParser();
|
||||
$handler->expectArgumentsAt(0, "a", array("a", LEXER_MATCHED));
|
||||
$handler->expectArgumentsAt(1, "a", array("b", LEXER_UNMATCHED));
|
||||
$handler->expectArgumentsAt(2, "a", array("aa", LEXER_MATCHED));
|
||||
$handler->expectArgumentsAt(3, "a", array("bxb", LEXER_UNMATCHED));
|
||||
$handler->expectArgumentsAt(4, "a", array("aaa", LEXER_MATCHED));
|
||||
$handler->expectArgumentsAt(5, "a", array("x", LEXER_UNMATCHED));
|
||||
$handler->expectArgumentsAt(6, "a", array("aaaa", LEXER_MATCHED));
|
||||
$handler->expectArgumentsAt(7, "a", array("x", LEXER_UNMATCHED));
|
||||
$handler->expectCallCount("a", 8);
|
||||
$handler->setReturnValue("a", true);
|
||||
$lexer = &new SimpleLexer($handler, "a");
|
||||
$lexer->addPattern("a+", "a");
|
||||
$lexer->addPattern("b+", "b");
|
||||
$this->assertTrue($lexer->parse("abaabxbaaaxaaaax"));
|
||||
}
|
||||
|
||||
function testModeChange() {
|
||||
$handler = &new MockTestParser();
|
||||
$handler->expectArgumentsAt(0, "a", array("a", LEXER_MATCHED));
|
||||
$handler->expectArgumentsAt(1, "a", array("b", LEXER_UNMATCHED));
|
||||
$handler->expectArgumentsAt(2, "a", array("aa", LEXER_MATCHED));
|
||||
$handler->expectArgumentsAt(3, "a", array("b", LEXER_UNMATCHED));
|
||||
$handler->expectArgumentsAt(4, "a", array("aaa", LEXER_MATCHED));
|
||||
$handler->expectArgumentsAt(0, "b", array(":", LEXER_ENTER));
|
||||
$handler->expectArgumentsAt(1, "b", array("a", LEXER_UNMATCHED));
|
||||
$handler->expectArgumentsAt(2, "b", array("b", LEXER_MATCHED));
|
||||
$handler->expectArgumentsAt(3, "b", array("a", LEXER_UNMATCHED));
|
||||
$handler->expectArgumentsAt(4, "b", array("bb", LEXER_MATCHED));
|
||||
$handler->expectArgumentsAt(5, "b", array("a", LEXER_UNMATCHED));
|
||||
$handler->expectArgumentsAt(6, "b", array("bbb", LEXER_MATCHED));
|
||||
$handler->expectArgumentsAt(7, "b", array("a", LEXER_UNMATCHED));
|
||||
$handler->expectCallCount("a", 5);
|
||||
$handler->expectCallCount("b", 8);
|
||||
$handler->setReturnValue("a", true);
|
||||
$handler->setReturnValue("b", true);
|
||||
$lexer = &new SimpleLexer($handler, "a");
|
||||
$lexer->addPattern("a+", "a");
|
||||
$lexer->addEntryPattern(":", "a", "b");
|
||||
$lexer->addPattern("b+", "b");
|
||||
$this->assertTrue($lexer->parse("abaabaaa:ababbabbba"));
|
||||
}
|
||||
|
||||
function testNesting() {
|
||||
$handler = &new MockTestParser();
|
||||
$handler->setReturnValue("a", true);
|
||||
$handler->setReturnValue("b", true);
|
||||
$handler->expectArgumentsAt(0, "a", array("aa", LEXER_MATCHED));
|
||||
$handler->expectArgumentsAt(1, "a", array("b", LEXER_UNMATCHED));
|
||||
$handler->expectArgumentsAt(2, "a", array("aa", LEXER_MATCHED));
|
||||
$handler->expectArgumentsAt(3, "a", array("b", LEXER_UNMATCHED));
|
||||
$handler->expectArgumentsAt(0, "b", array("(", LEXER_ENTER));
|
||||
$handler->expectArgumentsAt(1, "b", array("bb", LEXER_MATCHED));
|
||||
$handler->expectArgumentsAt(2, "b", array("a", LEXER_UNMATCHED));
|
||||
$handler->expectArgumentsAt(3, "b", array("bb", LEXER_MATCHED));
|
||||
$handler->expectArgumentsAt(4, "b", array(")", LEXER_EXIT));
|
||||
$handler->expectArgumentsAt(4, "a", array("aa", LEXER_MATCHED));
|
||||
$handler->expectArgumentsAt(5, "a", array("b", LEXER_UNMATCHED));
|
||||
$handler->expectCallCount("a", 6);
|
||||
$handler->expectCallCount("b", 5);
|
||||
$lexer = &new SimpleLexer($handler, "a");
|
||||
$lexer->addPattern("a+", "a");
|
||||
$lexer->addEntryPattern("(", "a", "b");
|
||||
$lexer->addPattern("b+", "b");
|
||||
$lexer->addExitPattern(")", "b");
|
||||
$this->assertTrue($lexer->parse("aabaab(bbabb)aab"));
|
||||
}
|
||||
|
||||
function testSingular() {
|
||||
$handler = &new MockTestParser();
|
||||
$handler->setReturnValue("a", true);
|
||||
$handler->setReturnValue("b", true);
|
||||
$handler->expectArgumentsAt(0, "a", array("aa", LEXER_MATCHED));
|
||||
$handler->expectArgumentsAt(1, "a", array("aa", LEXER_MATCHED));
|
||||
$handler->expectArgumentsAt(2, "a", array("xx", LEXER_UNMATCHED));
|
||||
$handler->expectArgumentsAt(3, "a", array("xx", LEXER_UNMATCHED));
|
||||
$handler->expectArgumentsAt(0, "b", array("b", LEXER_SPECIAL));
|
||||
$handler->expectArgumentsAt(1, "b", array("bbb", LEXER_SPECIAL));
|
||||
$handler->expectCallCount("a", 4);
|
||||
$handler->expectCallCount("b", 2);
|
||||
$lexer = &new SimpleLexer($handler, "a");
|
||||
$lexer->addPattern("a+", "a");
|
||||
$lexer->addSpecialPattern("b+", "a", "b");
|
||||
$this->assertTrue($lexer->parse("aabaaxxbbbxx"));
|
||||
}
|
||||
|
||||
function testUnwindTooFar() {
|
||||
$handler = &new MockTestParser();
|
||||
$handler->setReturnValue("a", true);
|
||||
$handler->expectArgumentsAt(0, "a", array("aa", LEXER_MATCHED));
|
||||
$handler->expectArgumentsAt(1, "a", array(")", LEXER_EXIT));
|
||||
$handler->expectCallCount("a", 2);
|
||||
$lexer = &new SimpleLexer($handler, "a");
|
||||
$lexer->addPattern("a+", "a");
|
||||
$lexer->addExitPattern(")", "a");
|
||||
$this->assertFalse($lexer->parse("aa)aa"));
|
||||
}
|
||||
}
|
||||
|
||||
class TestOfLexerHandlers extends UnitTestCase {
|
||||
|
||||
function testModeMapping() {
|
||||
$handler = &new MockTestParser();
|
||||
$handler->setReturnValue("a", true);
|
||||
$handler->expectArgumentsAt(0, "a", array("aa", LEXER_MATCHED));
|
||||
$handler->expectArgumentsAt(1, "a", array("(", LEXER_ENTER));
|
||||
$handler->expectArgumentsAt(2, "a", array("bb", LEXER_MATCHED));
|
||||
$handler->expectArgumentsAt(3, "a", array("a", LEXER_UNMATCHED));
|
||||
$handler->expectArgumentsAt(4, "a", array("bb", LEXER_MATCHED));
|
||||
$handler->expectArgumentsAt(5, "a", array(")", LEXER_EXIT));
|
||||
$handler->expectArgumentsAt(6, "a", array("b", LEXER_UNMATCHED));
|
||||
$handler->expectCallCount("a", 7);
|
||||
$lexer = &new SimpleLexer($handler, "mode_a");
|
||||
$lexer->addPattern("a+", "mode_a");
|
||||
$lexer->addEntryPattern("(", "mode_a", "mode_b");
|
||||
$lexer->addPattern("b+", "mode_b");
|
||||
$lexer->addExitPattern(")", "mode_b");
|
||||
$lexer->mapHandler("mode_a", "a");
|
||||
$lexer->mapHandler("mode_b", "a");
|
||||
$this->assertTrue($lexer->parse("aa(bbabb)b"));
|
||||
}
|
||||
}
|
||||
|
||||
class TestOfSimpleHtmlLexer extends UnitTestCase {
|
||||
|
||||
function &createParser() {
|
||||
$parser = &new MockSimpleHtmlSaxParser();
|
||||
$parser->setReturnValue('acceptStartToken', true);
|
||||
$parser->setReturnValue('acceptEndToken', true);
|
||||
$parser->setReturnValue('acceptAttributeToken', true);
|
||||
$parser->setReturnValue('acceptEntityToken', true);
|
||||
$parser->setReturnValue('acceptTextToken', true);
|
||||
$parser->setReturnValue('ignore', true);
|
||||
return $parser;
|
||||
}
|
||||
|
||||
function testNoContent() {
|
||||
$parser = &$this->createParser();
|
||||
$parser->expectNever('acceptStartToken');
|
||||
$parser->expectNever('acceptEndToken');
|
||||
$parser->expectNever('acceptAttributeToken');
|
||||
$parser->expectNever('acceptEntityToken');
|
||||
$parser->expectNever('acceptTextToken');
|
||||
$lexer = &new SimpleHtmlLexer($parser);
|
||||
$this->assertTrue($lexer->parse(''));
|
||||
}
|
||||
|
||||
function testUninteresting() {
|
||||
$parser = &$this->createParser();
|
||||
$parser->expectOnce('acceptTextToken', array('<html></html>', '*'));
|
||||
$lexer = &new SimpleHtmlLexer($parser);
|
||||
$this->assertTrue($lexer->parse('<html></html>'));
|
||||
}
|
||||
|
||||
function testSkipCss() {
|
||||
$parser = &$this->createParser();
|
||||
$parser->expectNever('acceptTextToken');
|
||||
$parser->expectAtLeastOnce('ignore');
|
||||
$lexer = &new SimpleHtmlLexer($parser);
|
||||
$this->assertTrue($lexer->parse("<style>Lot's of styles</style>"));
|
||||
}
|
||||
|
||||
function testSkipJavaScript() {
|
||||
$parser = &$this->createParser();
|
||||
$parser->expectNever('acceptTextToken');
|
||||
$parser->expectAtLeastOnce('ignore');
|
||||
$lexer = &new SimpleHtmlLexer($parser);
|
||||
$this->assertTrue($lexer->parse("<SCRIPT>Javascript code {';:^%^%£$'@\"*(}</SCRIPT>"));
|
||||
}
|
||||
|
||||
function testSkipHtmlComments() {
|
||||
$parser = &$this->createParser();
|
||||
$parser->expectNever('acceptTextToken');
|
||||
$parser->expectAtLeastOnce('ignore');
|
||||
$lexer = &new SimpleHtmlLexer($parser);
|
||||
$this->assertTrue($lexer->parse("<!-- <title>title</title><style>styles</style> -->"));
|
||||
}
|
||||
|
||||
function testTagWithNoAttributes() {
|
||||
$parser = &$this->createParser();
|
||||
$parser->expectAt(0, 'acceptStartToken', array('<title', '*'));
|
||||
$parser->expectAt(1, 'acceptStartToken', array('>', '*'));
|
||||
$parser->expectCallCount('acceptStartToken', 2);
|
||||
$parser->expectOnce('acceptTextToken', array('Hello', '*'));
|
||||
$parser->expectOnce('acceptEndToken', array('</title>', '*'));
|
||||
$lexer = &new SimpleHtmlLexer($parser);
|
||||
$this->assertTrue($lexer->parse('<title>Hello</title>'));
|
||||
}
|
||||
|
||||
function testTagWithAttributes() {
|
||||
$parser = &$this->createParser();
|
||||
$parser->expectOnce('acceptTextToken', array('label', '*'));
|
||||
$parser->expectAt(0, 'acceptStartToken', array('<a', '*'));
|
||||
$parser->expectAt(1, 'acceptStartToken', array('href', '*'));
|
||||
$parser->expectAt(2, 'acceptStartToken', array('>', '*'));
|
||||
$parser->expectCallCount('acceptStartToken', 3);
|
||||
$parser->expectAt(0, 'acceptAttributeToken', array('= "', '*'));
|
||||
$parser->expectAt(1, 'acceptAttributeToken', array('here.html', '*'));
|
||||
$parser->expectAt(2, 'acceptAttributeToken', array('"', '*'));
|
||||
$parser->expectCallCount('acceptAttributeToken', 3);
|
||||
$parser->expectOnce('acceptEndToken', array('</a>', '*'));
|
||||
$lexer = &new SimpleHtmlLexer($parser);
|
||||
$this->assertTrue($lexer->parse('<a href = "here.html">label</a>'));
|
||||
}
|
||||
}
|
||||
|
||||
class TestOfHtmlSaxParser extends UnitTestCase {
|
||||
|
||||
function &createListener() {
|
||||
$listener = &new MockSimpleSaxListener();
|
||||
$listener->setReturnValue('startElement', true);
|
||||
$listener->setReturnValue('addContent', true);
|
||||
$listener->setReturnValue('endElement', true);
|
||||
return $listener;
|
||||
}
|
||||
|
||||
function testFramesetTag() {
|
||||
$listener = &$this->createListener();
|
||||
$listener->expectOnce('startElement', array('frameset', array()));
|
||||
$listener->expectOnce('addContent', array('Frames'));
|
||||
$listener->expectOnce('endElement', array('frameset'));
|
||||
$parser = &new SimpleHtmlSaxParser($listener);
|
||||
$this->assertTrue($parser->parse('<frameset>Frames</frameset>'));
|
||||
}
|
||||
|
||||
function testTagWithUnquotedAttributes() {
|
||||
$listener = &$this->createListener();
|
||||
$listener->expectOnce(
|
||||
'startElement',
|
||||
array('input', array('name' => 'a.b.c', 'value' => 'd')));
|
||||
$parser = &new SimpleHtmlSaxParser($listener);
|
||||
$this->assertTrue($parser->parse('<input name=a.b.c value = d>'));
|
||||
}
|
||||
|
||||
function testTagInsideContent() {
|
||||
$listener = &$this->createListener();
|
||||
$listener->expectOnce('startElement', array('a', array()));
|
||||
$listener->expectAt(0, 'addContent', array('<html>'));
|
||||
$listener->expectAt(1, 'addContent', array('</html>'));
|
||||
$parser = &new SimpleHtmlSaxParser($listener);
|
||||
$this->assertTrue($parser->parse('<html><a></a></html>'));
|
||||
}
|
||||
|
||||
function testTagWithInternalContent() {
|
||||
$listener = &$this->createListener();
|
||||
$listener->expectOnce('startElement', array('a', array()));
|
||||
$listener->expectOnce('addContent', array('label'));
|
||||
$listener->expectOnce('endElement', array('a'));
|
||||
$parser = &new SimpleHtmlSaxParser($listener);
|
||||
$this->assertTrue($parser->parse('<a>label</a>'));
|
||||
}
|
||||
|
||||
function testLinkAddress() {
|
||||
$listener = &$this->createListener();
|
||||
$listener->expectOnce('startElement', array('a', array('href' => 'here.html')));
|
||||
$listener->expectOnce('addContent', array('label'));
|
||||
$listener->expectOnce('endElement', array('a'));
|
||||
$parser = &new SimpleHtmlSaxParser($listener);
|
||||
$this->assertTrue($parser->parse("<a href = 'here.html'>label</a>"));
|
||||
}
|
||||
|
||||
function testEncodedAttribute() {
|
||||
$listener = &$this->createListener();
|
||||
$listener->expectOnce('startElement', array('a', array('href' => 'here&there.html')));
|
||||
$listener->expectOnce('addContent', array('label'));
|
||||
$listener->expectOnce('endElement', array('a'));
|
||||
$parser = &new SimpleHtmlSaxParser($listener);
|
||||
$this->assertTrue($parser->parse("<a href = 'here&there.html'>label</a>"));
|
||||
}
|
||||
|
||||
function testTagWithId() {
|
||||
$listener = &$this->createListener();
|
||||
$listener->expectOnce('startElement', array('a', array('id' => '0')));
|
||||
$listener->expectOnce('addContent', array('label'));
|
||||
$listener->expectOnce('endElement', array('a'));
|
||||
$parser = &new SimpleHtmlSaxParser($listener);
|
||||
$this->assertTrue($parser->parse('<a id="0">label</a>'));
|
||||
}
|
||||
|
||||
function testTagWithEmptyAttributes() {
|
||||
$listener = &$this->createListener();
|
||||
$listener->expectOnce(
|
||||
'startElement',
|
||||
array('option', array('value' => '', 'selected' => '')));
|
||||
$listener->expectOnce('addContent', array('label'));
|
||||
$listener->expectOnce('endElement', array('option'));
|
||||
$parser = &new SimpleHtmlSaxParser($listener);
|
||||
$this->assertTrue($parser->parse('<option value="" selected>label</option>'));
|
||||
}
|
||||
|
||||
function testComplexTagWithLotsOfCaseVariations() {
|
||||
$listener = &$this->createListener();
|
||||
$listener->expectOnce(
|
||||
'startElement',
|
||||
array('a', array('href' => 'here.html', 'style' => "'cool'")));
|
||||
$listener->expectOnce('addContent', array('label'));
|
||||
$listener->expectOnce('endElement', array('a'));
|
||||
$parser = &new SimpleHtmlSaxParser($listener);
|
||||
$this->assertTrue($parser->parse('<A HREF = \'here.html\' Style="\'cool\'">label</A>'));
|
||||
}
|
||||
|
||||
function testXhtmlSelfClosingTag() {
|
||||
$listener = &$this->createListener();
|
||||
$listener->expectOnce(
|
||||
'startElement',
|
||||
array('input', array('type' => 'submit', 'name' => 'N', 'value' => 'V')));
|
||||
$parser = &new SimpleHtmlSaxParser($listener);
|
||||
$this->assertTrue($parser->parse('<input type="submit" name="N" value="V" />'));
|
||||
}
|
||||
|
||||
function testNestedFrameInFrameset() {
|
||||
$listener = &$this->createListener();
|
||||
$listener->expectAt(0, 'startElement', array('frameset', array()));
|
||||
$listener->expectAt(1, 'startElement', array('frame', array('src' => 'frame.html')));
|
||||
$listener->expectCallCount('startElement', 2);
|
||||
$listener->expectOnce('addContent', array('<noframes>Hello</noframes>'));
|
||||
$listener->expectOnce('endElement', array('frameset'));
|
||||
$parser = &new SimpleHtmlSaxParser($listener);
|
||||
$this->assertTrue($parser->parse(
|
||||
'<frameset><frame src="frame.html"><noframes>Hello</noframes></frameset>'));
|
||||
}
|
||||
}
|
||||
|
||||
class TestOfTextExtraction extends UnitTestCase {
|
||||
|
||||
function testImageSuppressionWhileKeepingParagraphsAndAltText() {
|
||||
$this->assertEqual(
|
||||
SimpleHtmlSaxParser::normalise('<img src="foo.png" /><p>some text</p><img src="bar.png" alt="bar" />'),
|
||||
'some text bar');
|
||||
|
||||
}
|
||||
|
||||
function testSpaceNormalisation() {
|
||||
$this->assertEqual(
|
||||
SimpleHtmlSaxParser::normalise("\nOne\tTwo \nThree\t"),
|
||||
'One Two Three');
|
||||
}
|
||||
|
||||
function testMultilinesCommentSuppression() {
|
||||
$this->assertEqual(
|
||||
SimpleHtmlSaxParser::normalise('<!--\n Hello \n-->'),
|
||||
'');
|
||||
}
|
||||
|
||||
function testCommentSuppression() {
|
||||
$this->assertEqual(
|
||||
SimpleHtmlSaxParser::normalise('<!--Hello-->'),
|
||||
'');
|
||||
}
|
||||
|
||||
function testJavascriptSuppression() {
|
||||
$this->assertEqual(
|
||||
SimpleHtmlSaxParser::normalise('<script attribute="test">\nHello\n</script>'),
|
||||
'');
|
||||
$this->assertEqual(
|
||||
SimpleHtmlSaxParser::normalise('<script attribute="test">Hello</script>'),
|
||||
'');
|
||||
$this->assertEqual(
|
||||
SimpleHtmlSaxParser::normalise('<script>Hello</script>'),
|
||||
'');
|
||||
}
|
||||
|
||||
function testTagSuppression() {
|
||||
$this->assertEqual(
|
||||
SimpleHtmlSaxParser::normalise('<b>Hello</b>'),
|
||||
'Hello');
|
||||
}
|
||||
|
||||
function testAdjoiningTagSuppression() {
|
||||
$this->assertEqual(
|
||||
SimpleHtmlSaxParser::normalise('<b>Hello</b><em>Goodbye</em>'),
|
||||
'HelloGoodbye');
|
||||
}
|
||||
|
||||
function testExtractImageAltTextWithDifferentQuotes() {
|
||||
$this->assertEqual(
|
||||
SimpleHtmlSaxParser::normalise('<img alt="One"><img alt=\'Two\'><img alt=Three>'),
|
||||
'One Two Three');
|
||||
}
|
||||
|
||||
function testExtractImageAltTextMultipleTimes() {
|
||||
$this->assertEqual(
|
||||
SimpleHtmlSaxParser::normalise('<img alt="One"><img alt="Two"><img alt="Three">'),
|
||||
'One Two Three');
|
||||
}
|
||||
|
||||
function testHtmlEntityTranslation() {
|
||||
$this->assertEqual(
|
||||
SimpleHtmlSaxParser::normalise('<>"&''),
|
||||
'<>"&\'');
|
||||
}
|
||||
}
|
||||
?>
|
||||
61
tests/simpletest/test/reflection_php4_test.php
Normal file
61
tests/simpletest/test/reflection_php4_test.php
Normal file
|
|
@ -0,0 +1,61 @@
|
|||
<?php
|
||||
// $Id: reflection_php4_test.php 1505 2007-04-30 23:39:59Z lastcraft $
|
||||
require_once(dirname(__FILE__) . '/../autorun.php');
|
||||
|
||||
class AnyOldThing {
|
||||
function aMethod() {
|
||||
}
|
||||
}
|
||||
|
||||
class AnyOldChildThing extends AnyOldThing { }
|
||||
|
||||
class TestOfReflection extends UnitTestCase {
|
||||
|
||||
function testClassExistence() {
|
||||
$reflection = new SimpleReflection('AnyOldThing');
|
||||
$this->assertTrue($reflection->classOrInterfaceExists());
|
||||
$this->assertTrue($reflection->classOrInterfaceExistsSansAutoload());
|
||||
}
|
||||
|
||||
function testClassNonExistence() {
|
||||
$reflection = new SimpleReflection('UnknownThing');
|
||||
$this->assertFalse($reflection->classOrInterfaceExists());
|
||||
$this->assertFalse($reflection->classOrInterfaceExistsSansAutoload());
|
||||
}
|
||||
|
||||
function testDetectionOfInterfacesAlwaysFalse() {
|
||||
$reflection = new SimpleReflection('AnyOldThing');
|
||||
$this->assertFalse($reflection->isAbstract());
|
||||
$this->assertFalse($reflection->isInterface());
|
||||
}
|
||||
|
||||
function testFindingParentClass() {
|
||||
$reflection = new SimpleReflection('AnyOldChildThing');
|
||||
$this->assertEqual(strtolower($reflection->getParent()), 'anyoldthing');
|
||||
}
|
||||
|
||||
function testMethodsListFromClass() {
|
||||
$reflection = new SimpleReflection('AnyOldThing');
|
||||
$methods = $reflection->getMethods();
|
||||
$this->assertEqualIgnoringCase($methods[0], 'aMethod');
|
||||
}
|
||||
|
||||
function testNoInterfacesForPHP4() {
|
||||
$reflection = new SimpleReflection('AnyOldThing');
|
||||
$this->assertEqual(
|
||||
$reflection->getInterfaces(),
|
||||
array());
|
||||
}
|
||||
|
||||
function testMostGeneralPossibleSignature() {
|
||||
$reflection = new SimpleReflection('AnyOldThing');
|
||||
$this->assertEqualIgnoringCase(
|
||||
$reflection->getSignature('aMethod'),
|
||||
'function &aMethod()');
|
||||
}
|
||||
|
||||
function assertEqualIgnoringCase($a, $b) {
|
||||
return $this->assertEqual(strtolower($a), strtolower($b));
|
||||
}
|
||||
}
|
||||
?>
|
||||
271
tests/simpletest/test/reflection_php5_test.php
Normal file
271
tests/simpletest/test/reflection_php5_test.php
Normal file
|
|
@ -0,0 +1,271 @@
|
|||
<?php
|
||||
// $Id: reflection_php5_test.php 1541 2007-06-10 02:27:59Z tswicegood $
|
||||
require_once(dirname(__FILE__) . '/../autorun.php');
|
||||
require_once(dirname(__FILE__) . '/../reflection_php5.php');
|
||||
|
||||
class AnyOldLeafClass {
|
||||
function aMethod() { }
|
||||
}
|
||||
|
||||
abstract class AnyOldClass {
|
||||
function aMethod() { }
|
||||
}
|
||||
|
||||
class AnyOldLeafClassWithAFinal {
|
||||
final function aMethod() { }
|
||||
}
|
||||
|
||||
interface AnyOldInterface {
|
||||
function aMethod();
|
||||
}
|
||||
|
||||
interface AnyOldArgumentInterface {
|
||||
function aMethod(AnyOldInterface $argument);
|
||||
}
|
||||
|
||||
interface AnyDescendentInterface extends AnyOldInterface {
|
||||
}
|
||||
|
||||
class AnyOldImplementation implements AnyOldInterface {
|
||||
function aMethod() { }
|
||||
function extraMethod() { }
|
||||
}
|
||||
|
||||
abstract class AnyAbstractImplementation implements AnyOldInterface {
|
||||
}
|
||||
|
||||
abstract class AnotherOldAbstractClass {
|
||||
protected abstract function aMethod(AnyOldInterface $argument);
|
||||
}
|
||||
|
||||
class AnyOldSubclass extends AnyOldImplementation { }
|
||||
|
||||
class AnyOldArgumentClass {
|
||||
function aMethod($argument) { }
|
||||
}
|
||||
|
||||
class AnyOldArgumentImplementation implements AnyOldArgumentInterface {
|
||||
function aMethod(AnyOldInterface $argument) { }
|
||||
}
|
||||
|
||||
class AnyOldTypeHintedClass implements AnyOldArgumentInterface {
|
||||
function aMethod(AnyOldInterface $argument) { }
|
||||
}
|
||||
|
||||
class AnyDescendentImplementation implements AnyDescendentInterface {
|
||||
function aMethod() { }
|
||||
}
|
||||
|
||||
class AnyOldOverloadedClass {
|
||||
function __isset($key) { }
|
||||
function __unset($key) { }
|
||||
}
|
||||
|
||||
class AnyOldClassWithStaticMethods {
|
||||
static function aStatic() { }
|
||||
static function aStaticWithParameters($arg1, $arg2) { }
|
||||
}
|
||||
|
||||
abstract class AnyOldAbstractClassWithAbstractMethods {
|
||||
abstract function anAbstract();
|
||||
abstract function anAbstractWithParameter($foo);
|
||||
abstract function anAbstractWithMultipleParameters($foo, $bar);
|
||||
}
|
||||
|
||||
class TestOfReflection extends UnitTestCase {
|
||||
|
||||
function testClassExistence() {
|
||||
$reflection = new SimpleReflection('AnyOldLeafClass');
|
||||
$this->assertTrue($reflection->classOrInterfaceExists());
|
||||
$this->assertTrue($reflection->classOrInterfaceExistsSansAutoload());
|
||||
$this->assertFalse($reflection->isAbstract());
|
||||
$this->assertFalse($reflection->isInterface());
|
||||
}
|
||||
|
||||
function testClassNonExistence() {
|
||||
$reflection = new SimpleReflection('UnknownThing');
|
||||
$this->assertFalse($reflection->classOrInterfaceExists());
|
||||
$this->assertFalse($reflection->classOrInterfaceExistsSansAutoload());
|
||||
}
|
||||
|
||||
function testDetectionOfAbstractClass() {
|
||||
$reflection = new SimpleReflection('AnyOldClass');
|
||||
$this->assertTrue($reflection->isAbstract());
|
||||
}
|
||||
|
||||
function testDetectionOfFinalMethods() {
|
||||
$reflection = new SimpleReflection('AnyOldClass');
|
||||
$this->assertFalse($reflection->hasFinal());
|
||||
$reflection = new SimpleReflection('AnyOldLeafClassWithAFinal');
|
||||
$this->assertTrue($reflection->hasFinal());
|
||||
}
|
||||
|
||||
function testFindingParentClass() {
|
||||
$reflection = new SimpleReflection('AnyOldSubclass');
|
||||
$this->assertEqual($reflection->getParent(), 'AnyOldImplementation');
|
||||
}
|
||||
|
||||
function testInterfaceExistence() {
|
||||
$reflection = new SimpleReflection('AnyOldInterface');
|
||||
$this->assertTrue($reflection->classOrInterfaceExists());
|
||||
$this->assertTrue($reflection->classOrInterfaceExistsSansAutoload());
|
||||
$this->assertTrue($reflection->isInterface());
|
||||
}
|
||||
|
||||
function testMethodsListFromClass() {
|
||||
$reflection = new SimpleReflection('AnyOldClass');
|
||||
$this->assertIdentical($reflection->getMethods(), array('aMethod'));
|
||||
}
|
||||
|
||||
function testMethodsListFromInterface() {
|
||||
$reflection = new SimpleReflection('AnyOldInterface');
|
||||
$this->assertIdentical($reflection->getMethods(), array('aMethod'));
|
||||
$this->assertIdentical($reflection->getInterfaceMethods(), array('aMethod'));
|
||||
}
|
||||
|
||||
function testMethodsComeFromDescendentInterfacesASWell() {
|
||||
$reflection = new SimpleReflection('AnyDescendentInterface');
|
||||
$this->assertIdentical($reflection->getMethods(), array('aMethod'));
|
||||
}
|
||||
|
||||
function testCanSeparateInterfaceMethodsFromOthers() {
|
||||
$reflection = new SimpleReflection('AnyOldImplementation');
|
||||
$this->assertIdentical($reflection->getMethods(), array('aMethod', 'extraMethod'));
|
||||
$this->assertIdentical($reflection->getInterfaceMethods(), array('aMethod'));
|
||||
}
|
||||
|
||||
function testMethodsComeFromDescendentInterfacesInAbstractClass() {
|
||||
$reflection = new SimpleReflection('AnyAbstractImplementation');
|
||||
$this->assertIdentical($reflection->getMethods(), array('aMethod'));
|
||||
}
|
||||
|
||||
function testInterfaceHasOnlyItselfToImplement() {
|
||||
$reflection = new SimpleReflection('AnyOldInterface');
|
||||
$this->assertEqual(
|
||||
$reflection->getInterfaces(),
|
||||
array('AnyOldInterface'));
|
||||
}
|
||||
|
||||
function testInterfacesListedForClass() {
|
||||
$reflection = new SimpleReflection('AnyOldImplementation');
|
||||
$this->assertEqual(
|
||||
$reflection->getInterfaces(),
|
||||
array('AnyOldInterface'));
|
||||
}
|
||||
|
||||
function testInterfacesListedForSubclass() {
|
||||
$reflection = new SimpleReflection('AnyOldSubclass');
|
||||
$this->assertEqual(
|
||||
$reflection->getInterfaces(),
|
||||
array('AnyOldInterface'));
|
||||
}
|
||||
|
||||
function testNoParameterCreationWhenNoInterface() {
|
||||
$reflection = new SimpleReflection('AnyOldArgumentClass');
|
||||
$function = $reflection->getSignature('aMethod');
|
||||
if (version_compare(phpversion(), '5.0.2', '<=')) {
|
||||
$this->assertEqual('function amethod()', strtolower($function));
|
||||
} else {
|
||||
$this->assertEqual('function aMethod()', $function);
|
||||
}
|
||||
}
|
||||
|
||||
function testParameterCreationWithoutTypeHinting() {
|
||||
$reflection = new SimpleReflection('AnyOldArgumentImplementation');
|
||||
$function = $reflection->getSignature('aMethod');
|
||||
if (version_compare(phpversion(), '5.0.2', '<=')) {
|
||||
$this->assertEqual('function amethod(AnyOldInterface $argument)', $function);
|
||||
} else {
|
||||
$this->assertEqual('function aMethod(AnyOldInterface $argument)', $function);
|
||||
}
|
||||
}
|
||||
|
||||
function testParameterCreationForTypeHinting() {
|
||||
$reflection = new SimpleReflection('AnyOldTypeHintedClass');
|
||||
$function = $reflection->getSignature('aMethod');
|
||||
if (version_compare(phpversion(), '5.0.2', '<=')) {
|
||||
$this->assertEqual('function amethod(AnyOldInterface $argument)', $function);
|
||||
} else {
|
||||
$this->assertEqual('function aMethod(AnyOldInterface $argument)', $function);
|
||||
}
|
||||
}
|
||||
|
||||
function testIssetFunctionSignature() {
|
||||
$reflection = new SimpleReflection('AnyOldOverloadedClass');
|
||||
$function = $reflection->getSignature('__isset');
|
||||
if (version_compare(phpversion(), '5.1.0', '>=')) {
|
||||
$this->assertEqual('function __isset($key)', $function);
|
||||
} else {
|
||||
$this->assertEqual('function __isset()', $function);
|
||||
}
|
||||
}
|
||||
|
||||
function testUnsetFunctionSignature() {
|
||||
$reflection = new SimpleReflection('AnyOldOverloadedClass');
|
||||
$function = $reflection->getSignature('__unset');
|
||||
if (version_compare(phpversion(), '5.1.0', '>=')) {
|
||||
$this->assertEqual('function __unset($key)', $function);
|
||||
} else {
|
||||
$this->assertEqual('function __unset()', $function);
|
||||
}
|
||||
}
|
||||
|
||||
function testProperlyReflectsTheFinalInterfaceWhenObjectImplementsAnExtendedInterface() {
|
||||
$reflection = new SimpleReflection('AnyDescendentImplementation');
|
||||
$interfaces = $reflection->getInterfaces();
|
||||
$this->assertEqual(1, count($interfaces));
|
||||
$this->assertEqual('AnyDescendentInterface', array_shift($interfaces));
|
||||
}
|
||||
|
||||
function testCreatingSignatureForAbstractMethod() {
|
||||
$reflection = new SimpleReflection('AnotherOldAbstractClass');
|
||||
$this->assertEqual($reflection->getSignature('aMethod'), 'function aMethod(AnyOldInterface $argument)');
|
||||
}
|
||||
|
||||
function testCanProperlyGenerateStaticMethodSignatures() {
|
||||
$reflection = new SimpleReflection('AnyOldClassWithStaticMethods');
|
||||
$this->assertEqual('static function aStatic()', $reflection->getSignature('aStatic'));
|
||||
$this->assertEqual(
|
||||
'static function aStaticWithParameters($arg1, $arg2)',
|
||||
$reflection->getSignature('aStaticWithParameters')
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class TestOfReflectionWithTypeHints extends UnitTestCase {
|
||||
function skip() {
|
||||
$this->skipIf(version_compare(phpversion(), '5.1.0', '<'), 'Reflection with type hints only tested for PHP 5.1.0 and above');
|
||||
}
|
||||
|
||||
function testParameterCreationForTypeHintingWithArray() {
|
||||
eval('interface AnyOldArrayTypeHintedInterface {
|
||||
function amethod(array $argument);
|
||||
}
|
||||
class AnyOldArrayTypeHintedClass implements AnyOldArrayTypeHintedInterface {
|
||||
function amethod(array $argument) {}
|
||||
}');
|
||||
$reflection = new SimpleReflection('AnyOldArrayTypeHintedClass');
|
||||
$function = $reflection->getSignature('amethod');
|
||||
$this->assertEqual('function amethod(array $argument)', $function);
|
||||
}
|
||||
}
|
||||
|
||||
class TestOfAbstractsWithAbstractMethods extends UnitTestCase {
|
||||
function testCanProperlyGenerateAbstractMethods() {
|
||||
$reflection = new SimpleReflection('AnyOldAbstractClassWithAbstractMethods');
|
||||
$this->assertEqual(
|
||||
'function anAbstract()',
|
||||
$reflection->getSignature('anAbstract')
|
||||
);
|
||||
$this->assertEqual(
|
||||
'function anAbstractWithParameter($foo)',
|
||||
$reflection->getSignature('anAbstractWithParameter')
|
||||
);
|
||||
$this->assertEqual(
|
||||
'function anAbstractWithMultipleParameters($foo, $bar)',
|
||||
$reflection->getSignature('anAbstractWithMultipleParameters')
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
20
tests/simpletest/test/remote_test.php
Normal file
20
tests/simpletest/test/remote_test.php
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
<?php
|
||||
// $Id: remote_test.php 1505 2007-04-30 23:39:59Z lastcraft $
|
||||
require_once('../remote.php');
|
||||
require_once('../reporter.php');
|
||||
|
||||
// The following URL will depend on your own installation.
|
||||
if (isset($_SERVER['SCRIPT_URI'])) {
|
||||
$base_uri = $_SERVER['SCRIPT_URI'];
|
||||
} elseif (isset($_SERVER['HTTP_HOST']) && isset($_SERVER['PHP_SELF'])) {
|
||||
$base_uri = 'http://'. $_SERVER['HTTP_HOST'] . $_SERVER['PHP_SELF'];
|
||||
};
|
||||
$test_url = str_replace('remote_test.php', 'visual_test.php', $base_uri);
|
||||
|
||||
$test = &new TestSuite('Remote tests');
|
||||
$test->addTestCase(new RemoteTestCase($test_url . '?xml=yes', $test_url . '?xml=yes&dry=yes'));
|
||||
if (SimpleReporter::inCli()) {
|
||||
exit ($test->run(new TextReporter()) ? 0 : 1);
|
||||
}
|
||||
$test->run(new HtmlReporter());
|
||||
?>
|
||||
38
tests/simpletest/test/shell_test.php
Normal file
38
tests/simpletest/test/shell_test.php
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
<?php
|
||||
// $Id: shell_test.php 1529 2007-06-04 18:33:09Z lastcraft $
|
||||
require_once(dirname(__FILE__) . '/../autorun.php');
|
||||
require_once(dirname(__FILE__) . '/../shell_tester.php');
|
||||
|
||||
class TestOfShell extends UnitTestCase {
|
||||
|
||||
function testEcho() {
|
||||
$shell = &new SimpleShell();
|
||||
$this->assertIdentical($shell->execute('echo Hello'), 0);
|
||||
$this->assertPattern('/Hello/', $shell->getOutput());
|
||||
}
|
||||
|
||||
function testBadCommand() {
|
||||
$shell = &new SimpleShell();
|
||||
$this->assertNotEqual($ret = $shell->execute('blurgh! 2>&1'), 0);
|
||||
}
|
||||
}
|
||||
|
||||
class TestOfShellTesterAndShell extends ShellTestCase {
|
||||
|
||||
function testEcho() {
|
||||
$this->assertTrue($this->execute('echo Hello'));
|
||||
$this->assertExitCode(0);
|
||||
$this->assertoutput('Hello');
|
||||
}
|
||||
|
||||
function testFileExistence() {
|
||||
$this->assertFileExists(dirname(__FILE__) . '/all_tests.php');
|
||||
$this->assertFileNotExists('wibble');
|
||||
}
|
||||
|
||||
function testFilePatterns() {
|
||||
$this->assertFilePattern('/all[_ ]tests/i', dirname(__FILE__) . '/all_tests.php');
|
||||
$this->assertNoFilePattern('/sputnik/i', dirname(__FILE__) . '/all_tests.php');
|
||||
}
|
||||
}
|
||||
?>
|
||||
42
tests/simpletest/test/shell_tester_test.php
Normal file
42
tests/simpletest/test/shell_tester_test.php
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
<?php
|
||||
// $Id: shell_tester_test.php 1505 2007-04-30 23:39:59Z lastcraft $
|
||||
require_once(dirname(__FILE__) . '/../autorun.php');
|
||||
require_once(dirname(__FILE__) . '/../shell_tester.php');
|
||||
Mock::generate('SimpleShell');
|
||||
|
||||
class TestOfShellTestCase extends ShellTestCase {
|
||||
var $_mock_shell = false;
|
||||
|
||||
function &_getShell() {
|
||||
return $this->_mock_shell;
|
||||
}
|
||||
|
||||
function testGenericEquality() {
|
||||
$this->assertEqual('a', 'a');
|
||||
$this->assertNotEqual('a', 'A');
|
||||
}
|
||||
|
||||
function testExitCode() {
|
||||
$this->_mock_shell = &new MockSimpleShell();
|
||||
$this->_mock_shell->setReturnValue('execute', 0);
|
||||
$this->_mock_shell->expectOnce('execute', array('ls'));
|
||||
$this->assertTrue($this->execute('ls'));
|
||||
$this->assertExitCode(0);
|
||||
}
|
||||
|
||||
function testOutput() {
|
||||
$this->_mock_shell = &new MockSimpleShell();
|
||||
$this->_mock_shell->setReturnValue('execute', 0);
|
||||
$this->_mock_shell->setReturnValue('getOutput', "Line 1\nLine 2\n");
|
||||
$this->assertOutput("Line 1\nLine 2\n");
|
||||
}
|
||||
|
||||
function testOutputPatterns() {
|
||||
$this->_mock_shell = &new MockSimpleShell();
|
||||
$this->_mock_shell->setReturnValue('execute', 0);
|
||||
$this->_mock_shell->setReturnValue('getOutput', "Line 1\nLine 2\n");
|
||||
$this->assertOutputPattern('/line/i');
|
||||
$this->assertNoOutputPattern('/line 2/');
|
||||
}
|
||||
}
|
||||
?>
|
||||
58
tests/simpletest/test/simpletest_test.php
Normal file
58
tests/simpletest/test/simpletest_test.php
Normal file
|
|
@ -0,0 +1,58 @@
|
|||
<?php
|
||||
// $Id: simpletest_test.php 1505 2007-04-30 23:39:59Z lastcraft $
|
||||
require_once(dirname(__FILE__) . '/../autorun.php');
|
||||
require_once(dirname(__FILE__) . '/../simpletest.php');
|
||||
|
||||
SimpleTest::ignore('ShouldNeverBeRunEither');
|
||||
|
||||
class ShouldNeverBeRun extends UnitTestCase {
|
||||
function testWithNoChanceOfSuccess() {
|
||||
$this->fail('Should be ignored');
|
||||
}
|
||||
}
|
||||
|
||||
class ShouldNeverBeRunEither extends ShouldNeverBeRun { }
|
||||
|
||||
class TestOfStackTrace extends UnitTestCase {
|
||||
|
||||
function testCanFindAssertInTrace() {
|
||||
$trace = new SimpleStackTrace(array('assert'));
|
||||
$this->assertEqual(
|
||||
$trace->traceMethod(array(array(
|
||||
'file' => '/my_test.php',
|
||||
'line' => 24,
|
||||
'function' => 'assertSomething'))),
|
||||
' at [/my_test.php line 24]');
|
||||
}
|
||||
}
|
||||
|
||||
class DummyResource { }
|
||||
|
||||
class TestOfContext extends UnitTestCase {
|
||||
|
||||
function testCurrentContextIsUnique() {
|
||||
$this->assertReference(
|
||||
SimpleTest::getContext(),
|
||||
SimpleTest::getContext());
|
||||
}
|
||||
|
||||
function testContextHoldsCurrentTestCase() {
|
||||
$context = &SimpleTest::getContext();
|
||||
$this->assertReference($this, $context->getTest());
|
||||
}
|
||||
|
||||
function testResourceIsSingleInstanceWithContext() {
|
||||
$context = &new SimpleTestContext();
|
||||
$this->assertReference(
|
||||
$context->get('DummyResource'),
|
||||
$context->get('DummyResource'));
|
||||
}
|
||||
|
||||
function testClearingContextResetsResources() {
|
||||
$context = &new SimpleTestContext();
|
||||
$resource = &$context->get('DummyResource');
|
||||
$context->clear();
|
||||
$this->assertClone($resource, $context->get('DummyResource'));
|
||||
}
|
||||
}
|
||||
?>
|
||||
25
tests/simpletest/test/socket_test.php
Normal file
25
tests/simpletest/test/socket_test.php
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
<?php
|
||||
// $Id: socket_test.php 1509 2007-05-08 22:11:49Z lastcraft $
|
||||
require_once(dirname(__FILE__) . '/../autorun.php');
|
||||
require_once(dirname(__FILE__) . '/../socket.php');
|
||||
Mock::generate('SimpleSocket');
|
||||
|
||||
class TestOfSimpleStickyError extends UnitTestCase {
|
||||
|
||||
function testSettingError() {
|
||||
$error = new SimpleStickyError();
|
||||
$this->assertFalse($error->isError());
|
||||
$error->_setError('Ouch');
|
||||
$this->assertTrue($error->isError());
|
||||
$this->assertEqual($error->getError(), 'Ouch');
|
||||
}
|
||||
|
||||
function testClearingError() {
|
||||
$error = new SimpleStickyError();
|
||||
$error->_setError('Ouch');
|
||||
$this->assertTrue($error->isError());
|
||||
$error->_clearError();
|
||||
$this->assertFalse($error->isError());
|
||||
}
|
||||
}
|
||||
?>
|
||||
0
tests/simpletest/test/support/collector/collectable.1
Normal file
0
tests/simpletest/test/support/collector/collectable.1
Normal file
0
tests/simpletest/test/support/collector/collectable.2
Normal file
0
tests/simpletest/test/support/collector/collectable.2
Normal file
3
tests/simpletest/test/support/empty_test_file.php
Normal file
3
tests/simpletest/test/support/empty_test_file.php
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
<?php
|
||||
require_once(dirname(__FILE__) . '/../../autorun.php');
|
||||
?>
|
||||
1
tests/simpletest/test/support/latin1_sample
Normal file
1
tests/simpletest/test/support/latin1_sample
Normal file
|
|
@ -0,0 +1 @@
|
|||
ㄨ眾播輥奧禆蛺姣6
|
||||
15
tests/simpletest/test/support/spl_examples.php
Normal file
15
tests/simpletest/test/support/spl_examples.php
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
<?php
|
||||
// $Id: spl_examples.php 1262 2006-02-05 19:35:31Z lastcraft $
|
||||
|
||||
class IteratorImplementation implements Iterator {
|
||||
function current() { }
|
||||
function next() { }
|
||||
function key() { }
|
||||
function valid() { }
|
||||
function rewind() { }
|
||||
}
|
||||
|
||||
class IteratorAggregateImplementation implements IteratorAggregate {
|
||||
function getIterator() { }
|
||||
}
|
||||
?>
|
||||
|
|
@ -0,0 +1 @@
|
|||
Some more text content
|
||||
7
tests/simpletest/test/support/test1.php
Normal file
7
tests/simpletest/test/support/test1.php
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
<?php
|
||||
class test1 extends UnitTestCase {
|
||||
function test_pass(){
|
||||
$this->assertEqual(3,1+2, "pass1");
|
||||
}
|
||||
}
|
||||
?>
|
||||
1
tests/simpletest/test/support/upload_sample.txt
Normal file
1
tests/simpletest/test/support/upload_sample.txt
Normal file
|
|
@ -0,0 +1 @@
|
|||
Sample for testing file upload
|
||||
554
tests/simpletest/test/tag_test.php
Normal file
554
tests/simpletest/test/tag_test.php
Normal file
|
|
@ -0,0 +1,554 @@
|
|||
<?php
|
||||
// $Id: tag_test.php 1509 2007-05-08 22:11:49Z lastcraft $
|
||||
require_once(dirname(__FILE__) . '/../autorun.php');
|
||||
require_once(dirname(__FILE__) . '/../tag.php');
|
||||
require_once(dirname(__FILE__) . '/../encoding.php');
|
||||
Mock::generate('SimpleMultipartEncoding');
|
||||
|
||||
class TestOfTag extends UnitTestCase {
|
||||
|
||||
function testStartValuesWithoutAdditionalContent() {
|
||||
$tag = new SimpleTitleTag(array('a' => '1', 'b' => ''));
|
||||
$this->assertEqual($tag->getTagName(), 'title');
|
||||
$this->assertIdentical($tag->getAttribute('a'), '1');
|
||||
$this->assertIdentical($tag->getAttribute('b'), '');
|
||||
$this->assertIdentical($tag->getAttribute('c'), false);
|
||||
$this->assertIdentical($tag->getContent(), '');
|
||||
}
|
||||
|
||||
function testTitleContent() {
|
||||
$tag = &new SimpleTitleTag(array());
|
||||
$this->assertTrue($tag->expectEndTag());
|
||||
$tag->addContent('Hello');
|
||||
$tag->addContent('World');
|
||||
$this->assertEqual($tag->getText(), 'HelloWorld');
|
||||
}
|
||||
|
||||
function testMessyTitleContent() {
|
||||
$tag = &new SimpleTitleTag(array());
|
||||
$this->assertTrue($tag->expectEndTag());
|
||||
$tag->addContent('<b>Hello</b>');
|
||||
$tag->addContent('<em>World</em>');
|
||||
$this->assertEqual($tag->getText(), 'HelloWorld');
|
||||
}
|
||||
|
||||
function testTagWithNoEnd() {
|
||||
$tag = &new SimpleTextTag(array());
|
||||
$this->assertFalse($tag->expectEndTag());
|
||||
}
|
||||
|
||||
function testAnchorHref() {
|
||||
$tag = &new SimpleAnchorTag(array('href' => 'http://here/'));
|
||||
$this->assertEqual($tag->getHref(), 'http://here/');
|
||||
|
||||
$tag = &new SimpleAnchorTag(array('href' => ''));
|
||||
$this->assertIdentical($tag->getAttribute('href'), '');
|
||||
$this->assertIdentical($tag->getHref(), '');
|
||||
|
||||
$tag = &new SimpleAnchorTag(array());
|
||||
$this->assertIdentical($tag->getAttribute('href'), false);
|
||||
$this->assertIdentical($tag->getHref(), '');
|
||||
}
|
||||
|
||||
function testIsIdMatchesIdAttribute() {
|
||||
$tag = &new SimpleAnchorTag(array('href' => 'http://here/', 'id' => 7));
|
||||
$this->assertIdentical($tag->getAttribute('id'), '7');
|
||||
$this->assertTrue($tag->isId(7));
|
||||
}
|
||||
}
|
||||
|
||||
class TestOfWidget extends UnitTestCase {
|
||||
|
||||
function testTextEmptyDefault() {
|
||||
$tag = &new SimpleTextTag(array('type' => 'text'));
|
||||
$this->assertIdentical($tag->getDefault(), '');
|
||||
$this->assertIdentical($tag->getValue(), '');
|
||||
}
|
||||
|
||||
function testSettingOfExternalLabel() {
|
||||
$tag = &new SimpleTextTag(array('type' => 'text'));
|
||||
$tag->setLabel('it');
|
||||
$this->assertTrue($tag->isLabel('it'));
|
||||
}
|
||||
|
||||
function testTextDefault() {
|
||||
$tag = &new SimpleTextTag(array('value' => 'aaa'));
|
||||
$this->assertEqual($tag->getDefault(), 'aaa');
|
||||
$this->assertEqual($tag->getValue(), 'aaa');
|
||||
}
|
||||
|
||||
function testSettingTextValue() {
|
||||
$tag = &new SimpleTextTag(array('value' => 'aaa'));
|
||||
$tag->setValue('bbb');
|
||||
$this->assertEqual($tag->getValue(), 'bbb');
|
||||
$tag->resetValue();
|
||||
$this->assertEqual($tag->getValue(), 'aaa');
|
||||
}
|
||||
|
||||
function testFailToSetHiddenValue() {
|
||||
$tag = &new SimpleTextTag(array('value' => 'aaa', 'type' => 'hidden'));
|
||||
$this->assertFalse($tag->setValue('bbb'));
|
||||
$this->assertEqual($tag->getValue(), 'aaa');
|
||||
}
|
||||
|
||||
function testSubmitDefaults() {
|
||||
$tag = &new SimpleSubmitTag(array('type' => 'submit'));
|
||||
$this->assertIdentical($tag->getName(), false);
|
||||
$this->assertEqual($tag->getValue(), 'Submit');
|
||||
$this->assertFalse($tag->setValue('Cannot set this'));
|
||||
$this->assertEqual($tag->getValue(), 'Submit');
|
||||
$this->assertEqual($tag->getLabel(), 'Submit');
|
||||
|
||||
$encoding = &new MockSimpleMultipartEncoding();
|
||||
$encoding->expectNever('add');
|
||||
$tag->write($encoding);
|
||||
}
|
||||
|
||||
function testPopulatedSubmit() {
|
||||
$tag = &new SimpleSubmitTag(
|
||||
array('type' => 'submit', 'name' => 's', 'value' => 'Ok!'));
|
||||
$this->assertEqual($tag->getName(), 's');
|
||||
$this->assertEqual($tag->getValue(), 'Ok!');
|
||||
$this->assertEqual($tag->getLabel(), 'Ok!');
|
||||
|
||||
$encoding = &new MockSimpleMultipartEncoding();
|
||||
$encoding->expectOnce('add', array('s', 'Ok!'));
|
||||
$tag->write($encoding);
|
||||
}
|
||||
|
||||
function testImageSubmit() {
|
||||
$tag = &new SimpleImageSubmitTag(
|
||||
array('type' => 'image', 'name' => 's', 'alt' => 'Label'));
|
||||
$this->assertEqual($tag->getName(), 's');
|
||||
$this->assertEqual($tag->getLabel(), 'Label');
|
||||
|
||||
$encoding = &new MockSimpleMultipartEncoding();
|
||||
$encoding->expectAt(0, 'add', array('s.x', 20));
|
||||
$encoding->expectAt(1, 'add', array('s.y', 30));
|
||||
$tag->write($encoding, 20, 30);
|
||||
}
|
||||
|
||||
function testImageSubmitTitlePreferredOverAltForLabel() {
|
||||
$tag = &new SimpleImageSubmitTag(
|
||||
array('type' => 'image', 'name' => 's', 'alt' => 'Label', 'title' => 'Title'));
|
||||
$this->assertEqual($tag->getLabel(), 'Title');
|
||||
}
|
||||
|
||||
function testButton() {
|
||||
$tag = &new SimpleButtonTag(
|
||||
array('type' => 'submit', 'name' => 's', 'value' => 'do'));
|
||||
$tag->addContent('I am a button');
|
||||
$this->assertEqual($tag->getName(), 's');
|
||||
$this->assertEqual($tag->getValue(), 'do');
|
||||
$this->assertEqual($tag->getLabel(), 'I am a button');
|
||||
|
||||
$encoding = &new MockSimpleMultipartEncoding();
|
||||
$encoding->expectOnce('add', array('s', 'do'));
|
||||
$tag->write($encoding);
|
||||
}
|
||||
}
|
||||
|
||||
class TestOfTextArea extends UnitTestCase {
|
||||
|
||||
function testDefault() {
|
||||
$tag = &new SimpleTextAreaTag(array('name' => 'a'));
|
||||
$tag->addContent('Some text');
|
||||
$this->assertEqual($tag->getName(), 'a');
|
||||
$this->assertEqual($tag->getDefault(), 'Some text');
|
||||
}
|
||||
|
||||
function testWrapping() {
|
||||
$tag = &new SimpleTextAreaTag(array('cols' => '10', 'wrap' => 'physical'));
|
||||
$tag->addContent("Lot's of text that should be wrapped");
|
||||
$this->assertEqual(
|
||||
$tag->getDefault(),
|
||||
"Lot's of\r\ntext that\r\nshould be\r\nwrapped");
|
||||
$tag->setValue("New long text\r\nwith two lines");
|
||||
$this->assertEqual(
|
||||
$tag->getValue(),
|
||||
"New long\r\ntext\r\nwith two\r\nlines");
|
||||
}
|
||||
|
||||
function testWrappingRemovesLeadingcariageReturn() {
|
||||
$tag = &new SimpleTextAreaTag(array('cols' => '20', 'wrap' => 'physical'));
|
||||
$tag->addContent("\rStuff");
|
||||
$this->assertEqual($tag->getDefault(), 'Stuff');
|
||||
$tag->setValue("\nNew stuff\n");
|
||||
$this->assertEqual($tag->getValue(), "New stuff\r\n");
|
||||
}
|
||||
|
||||
function testBreaksAreNewlineAndCarriageReturn() {
|
||||
$tag = &new SimpleTextAreaTag(array('cols' => '10'));
|
||||
$tag->addContent("Some\nText\rwith\r\nbreaks");
|
||||
$this->assertEqual($tag->getValue(), "Some\r\nText\r\nwith\r\nbreaks");
|
||||
}
|
||||
}
|
||||
|
||||
class TestOfCheckbox extends UnitTestCase {
|
||||
|
||||
function testCanSetCheckboxToNamedValueWithBooleanTrue() {
|
||||
$tag = &new SimpleCheckboxTag(array('name' => 'a', 'value' => 'A'));
|
||||
$this->assertEqual($tag->getValue(), false);
|
||||
$tag->setValue(true);
|
||||
$this->assertIdentical($tag->getValue(), 'A');
|
||||
}
|
||||
}
|
||||
|
||||
class TestOfSelection extends UnitTestCase {
|
||||
|
||||
function testEmpty() {
|
||||
$tag = &new SimpleSelectionTag(array('name' => 'a'));
|
||||
$this->assertIdentical($tag->getValue(), '');
|
||||
}
|
||||
|
||||
function testSingle() {
|
||||
$tag = &new SimpleSelectionTag(array('name' => 'a'));
|
||||
$option = &new SimpleOptionTag(array());
|
||||
$option->addContent('AAA');
|
||||
$tag->addTag($option);
|
||||
$this->assertEqual($tag->getValue(), 'AAA');
|
||||
}
|
||||
|
||||
function testSingleDefault() {
|
||||
$tag = &new SimpleSelectionTag(array('name' => 'a'));
|
||||
$option = &new SimpleOptionTag(array('selected' => ''));
|
||||
$option->addContent('AAA');
|
||||
$tag->addTag($option);
|
||||
$this->assertEqual($tag->getValue(), 'AAA');
|
||||
}
|
||||
|
||||
function testSingleMappedDefault() {
|
||||
$tag = &new SimpleSelectionTag(array('name' => 'a'));
|
||||
$option = &new SimpleOptionTag(array('selected' => '', 'value' => 'aaa'));
|
||||
$option->addContent('AAA');
|
||||
$tag->addTag($option);
|
||||
$this->assertEqual($tag->getValue(), 'aaa');
|
||||
}
|
||||
|
||||
function testStartsWithDefault() {
|
||||
$tag = &new SimpleSelectionTag(array('name' => 'a'));
|
||||
$a = &new SimpleOptionTag(array());
|
||||
$a->addContent('AAA');
|
||||
$tag->addTag($a);
|
||||
$b = &new SimpleOptionTag(array('selected' => ''));
|
||||
$b->addContent('BBB');
|
||||
$tag->addTag($b);
|
||||
$c = &new SimpleOptionTag(array());
|
||||
$c->addContent('CCC');
|
||||
$tag->addTag($c);
|
||||
$this->assertEqual($tag->getValue(), 'BBB');
|
||||
}
|
||||
|
||||
function testSettingOption() {
|
||||
$tag = &new SimpleSelectionTag(array('name' => 'a'));
|
||||
$a = &new SimpleOptionTag(array());
|
||||
$a->addContent('AAA');
|
||||
$tag->addTag($a);
|
||||
$b = &new SimpleOptionTag(array('selected' => ''));
|
||||
$b->addContent('BBB');
|
||||
$tag->addTag($b);
|
||||
$c = &new SimpleOptionTag(array());
|
||||
$c->addContent('CCC');
|
||||
$tag->setValue('AAA');
|
||||
$this->assertEqual($tag->getValue(), 'AAA');
|
||||
}
|
||||
|
||||
function testSettingMappedOption() {
|
||||
$tag = &new SimpleSelectionTag(array('name' => 'a'));
|
||||
$a = &new SimpleOptionTag(array('value' => 'aaa'));
|
||||
$a->addContent('AAA');
|
||||
$tag->addTag($a);
|
||||
$b = &new SimpleOptionTag(array('value' => 'bbb', 'selected' => ''));
|
||||
$b->addContent('BBB');
|
||||
$tag->addTag($b);
|
||||
$c = &new SimpleOptionTag(array('value' => 'ccc'));
|
||||
$c->addContent('CCC');
|
||||
$tag->addTag($c);
|
||||
$tag->setValue('AAA');
|
||||
$this->assertEqual($tag->getValue(), 'aaa');
|
||||
$tag->setValue('ccc');
|
||||
$this->assertEqual($tag->getValue(), 'ccc');
|
||||
}
|
||||
|
||||
function testSelectionDespiteSpuriousWhitespace() {
|
||||
$tag = &new SimpleSelectionTag(array('name' => 'a'));
|
||||
$a = &new SimpleOptionTag(array());
|
||||
$a->addContent(' AAA ');
|
||||
$tag->addTag($a);
|
||||
$b = &new SimpleOptionTag(array('selected' => ''));
|
||||
$b->addContent(' BBB ');
|
||||
$tag->addTag($b);
|
||||
$c = &new SimpleOptionTag(array());
|
||||
$c->addContent(' CCC ');
|
||||
$tag->addTag($c);
|
||||
$this->assertEqual($tag->getValue(), ' BBB ');
|
||||
$tag->setValue('AAA');
|
||||
$this->assertEqual($tag->getValue(), ' AAA ');
|
||||
}
|
||||
|
||||
function testFailToSetIllegalOption() {
|
||||
$tag = &new SimpleSelectionTag(array('name' => 'a'));
|
||||
$a = &new SimpleOptionTag(array());
|
||||
$a->addContent('AAA');
|
||||
$tag->addTag($a);
|
||||
$b = &new SimpleOptionTag(array('selected' => ''));
|
||||
$b->addContent('BBB');
|
||||
$tag->addTag($b);
|
||||
$c = &new SimpleOptionTag(array());
|
||||
$c->addContent('CCC');
|
||||
$tag->addTag($c);
|
||||
$this->assertFalse($tag->setValue('Not present'));
|
||||
$this->assertEqual($tag->getValue(), 'BBB');
|
||||
}
|
||||
|
||||
function testNastyOptionValuesThatLookLikeFalse() {
|
||||
$tag = &new SimpleSelectionTag(array('name' => 'a'));
|
||||
$a = &new SimpleOptionTag(array('value' => '1'));
|
||||
$a->addContent('One');
|
||||
$tag->addTag($a);
|
||||
$b = &new SimpleOptionTag(array('value' => '0'));
|
||||
$b->addContent('Zero');
|
||||
$tag->addTag($b);
|
||||
$this->assertIdentical($tag->getValue(), '1');
|
||||
$tag->setValue('Zero');
|
||||
$this->assertIdentical($tag->getValue(), '0');
|
||||
}
|
||||
|
||||
function testBlankOption() {
|
||||
$tag = &new SimpleSelectionTag(array('name' => 'A'));
|
||||
$a = &new SimpleOptionTag(array());
|
||||
$tag->addTag($a);
|
||||
$b = &new SimpleOptionTag(array());
|
||||
$b->addContent('b');
|
||||
$tag->addTag($b);
|
||||
$this->assertIdentical($tag->getValue(), '');
|
||||
$tag->setValue('b');
|
||||
$this->assertIdentical($tag->getValue(), 'b');
|
||||
$tag->setValue('');
|
||||
$this->assertIdentical($tag->getValue(), '');
|
||||
}
|
||||
|
||||
function testMultipleDefaultWithNoSelections() {
|
||||
$tag = &new MultipleSelectionTag(array('name' => 'a', 'multiple' => ''));
|
||||
$a = &new SimpleOptionTag(array());
|
||||
$a->addContent('AAA');
|
||||
$tag->addTag($a);
|
||||
$b = &new SimpleOptionTag(array());
|
||||
$b->addContent('BBB');
|
||||
$tag->addTag($b);
|
||||
$this->assertIdentical($tag->getDefault(), array());
|
||||
$this->assertIdentical($tag->getValue(), array());
|
||||
}
|
||||
|
||||
function testMultipleDefaultWithSelections() {
|
||||
$tag = &new MultipleSelectionTag(array('name' => 'a', 'multiple' => ''));
|
||||
$a = &new SimpleOptionTag(array('selected' => ''));
|
||||
$a->addContent('AAA');
|
||||
$tag->addTag($a);
|
||||
$b = &new SimpleOptionTag(array('selected' => ''));
|
||||
$b->addContent('BBB');
|
||||
$tag->addTag($b);
|
||||
$this->assertIdentical($tag->getDefault(), array('AAA', 'BBB'));
|
||||
$this->assertIdentical($tag->getValue(), array('AAA', 'BBB'));
|
||||
}
|
||||
|
||||
function testSettingMultiple() {
|
||||
$tag = &new MultipleSelectionTag(array('name' => 'a', 'multiple' => ''));
|
||||
$a = &new SimpleOptionTag(array('selected' => ''));
|
||||
$a->addContent('AAA');
|
||||
$tag->addTag($a);
|
||||
$b = &new SimpleOptionTag(array());
|
||||
$b->addContent('BBB');
|
||||
$tag->addTag($b);
|
||||
$c = &new SimpleOptionTag(array('selected' => '', 'value' => 'ccc'));
|
||||
$c->addContent('CCC');
|
||||
$tag->addTag($c);
|
||||
$this->assertIdentical($tag->getDefault(), array('AAA', 'ccc'));
|
||||
$this->assertTrue($tag->setValue(array('BBB', 'ccc')));
|
||||
$this->assertIdentical($tag->getValue(), array('BBB', 'ccc'));
|
||||
$this->assertTrue($tag->setValue(array()));
|
||||
$this->assertIdentical($tag->getValue(), array());
|
||||
}
|
||||
|
||||
function testFailToSetIllegalOptionsInMultiple() {
|
||||
$tag = &new MultipleSelectionTag(array('name' => 'a', 'multiple' => ''));
|
||||
$a = &new SimpleOptionTag(array('selected' => ''));
|
||||
$a->addContent('AAA');
|
||||
$tag->addTag($a);
|
||||
$b = &new SimpleOptionTag(array());
|
||||
$b->addContent('BBB');
|
||||
$tag->addTag($b);
|
||||
$this->assertFalse($tag->setValue(array('CCC')));
|
||||
$this->assertTrue($tag->setValue(array('AAA', 'BBB')));
|
||||
$this->assertFalse($tag->setValue(array('AAA', 'CCC')));
|
||||
}
|
||||
}
|
||||
|
||||
class TestOfRadioGroup extends UnitTestCase {
|
||||
|
||||
function testEmptyGroup() {
|
||||
$group = &new SimpleRadioGroup();
|
||||
$this->assertIdentical($group->getDefault(), false);
|
||||
$this->assertIdentical($group->getValue(), false);
|
||||
$this->assertFalse($group->setValue('a'));
|
||||
}
|
||||
|
||||
function testReadingSingleButtonGroup() {
|
||||
$group = &new SimpleRadioGroup();
|
||||
$group->addWidget(new SimpleRadioButtonTag(
|
||||
array('value' => 'A', 'checked' => '')));
|
||||
$this->assertIdentical($group->getDefault(), 'A');
|
||||
$this->assertIdentical($group->getValue(), 'A');
|
||||
}
|
||||
|
||||
function testReadingMultipleButtonGroup() {
|
||||
$group = &new SimpleRadioGroup();
|
||||
$group->addWidget(new SimpleRadioButtonTag(
|
||||
array('value' => 'A')));
|
||||
$group->addWidget(new SimpleRadioButtonTag(
|
||||
array('value' => 'B', 'checked' => '')));
|
||||
$this->assertIdentical($group->getDefault(), 'B');
|
||||
$this->assertIdentical($group->getValue(), 'B');
|
||||
}
|
||||
|
||||
function testFailToSetUnlistedValue() {
|
||||
$group = &new SimpleRadioGroup();
|
||||
$group->addWidget(new SimpleRadioButtonTag(array('value' => 'z')));
|
||||
$this->assertFalse($group->setValue('a'));
|
||||
$this->assertIdentical($group->getValue(), false);
|
||||
}
|
||||
|
||||
function testSettingNewValueClearsTheOldOne() {
|
||||
$group = &new SimpleRadioGroup();
|
||||
$group->addWidget(new SimpleRadioButtonTag(
|
||||
array('value' => 'A')));
|
||||
$group->addWidget(new SimpleRadioButtonTag(
|
||||
array('value' => 'B', 'checked' => '')));
|
||||
$this->assertTrue($group->setValue('A'));
|
||||
$this->assertIdentical($group->getValue(), 'A');
|
||||
}
|
||||
|
||||
function testIsIdMatchesAnyWidgetInSet() {
|
||||
$group = &new SimpleRadioGroup();
|
||||
$group->addWidget(new SimpleRadioButtonTag(
|
||||
array('value' => 'A', 'id' => 'i1')));
|
||||
$group->addWidget(new SimpleRadioButtonTag(
|
||||
array('value' => 'B', 'id' => 'i2')));
|
||||
$this->assertFalse($group->isId('i0'));
|
||||
$this->assertTrue($group->isId('i1'));
|
||||
$this->assertTrue($group->isId('i2'));
|
||||
}
|
||||
|
||||
function testIsLabelMatchesAnyWidgetInSet() {
|
||||
$group = &new SimpleRadioGroup();
|
||||
$button1 = &new SimpleRadioButtonTag(array('value' => 'A'));
|
||||
$button1->setLabel('one');
|
||||
$group->addWidget($button1);
|
||||
$button2 = &new SimpleRadioButtonTag(array('value' => 'B'));
|
||||
$button2->setLabel('two');
|
||||
$group->addWidget($button2);
|
||||
$this->assertFalse($group->isLabel('three'));
|
||||
$this->assertTrue($group->isLabel('one'));
|
||||
$this->assertTrue($group->isLabel('two'));
|
||||
}
|
||||
}
|
||||
|
||||
class TestOfTagGroup extends UnitTestCase {
|
||||
|
||||
function testReadingMultipleCheckboxGroup() {
|
||||
$group = &new SimpleCheckboxGroup();
|
||||
$group->addWidget(new SimpleCheckboxTag(array('value' => 'A')));
|
||||
$group->addWidget(new SimpleCheckboxTag(
|
||||
array('value' => 'B', 'checked' => '')));
|
||||
$this->assertIdentical($group->getDefault(), 'B');
|
||||
$this->assertIdentical($group->getValue(), 'B');
|
||||
}
|
||||
|
||||
function testReadingMultipleUncheckedItems() {
|
||||
$group = &new SimpleCheckboxGroup();
|
||||
$group->addWidget(new SimpleCheckboxTag(array('value' => 'A')));
|
||||
$group->addWidget(new SimpleCheckboxTag(array('value' => 'B')));
|
||||
$this->assertIdentical($group->getDefault(), false);
|
||||
$this->assertIdentical($group->getValue(), false);
|
||||
}
|
||||
|
||||
function testReadingMultipleCheckedItems() {
|
||||
$group = &new SimpleCheckboxGroup();
|
||||
$group->addWidget(new SimpleCheckboxTag(
|
||||
array('value' => 'A', 'checked' => '')));
|
||||
$group->addWidget(new SimpleCheckboxTag(
|
||||
array('value' => 'B', 'checked' => '')));
|
||||
$this->assertIdentical($group->getDefault(), array('A', 'B'));
|
||||
$this->assertIdentical($group->getValue(), array('A', 'B'));
|
||||
}
|
||||
|
||||
function testSettingSingleValue() {
|
||||
$group = &new SimpleCheckboxGroup();
|
||||
$group->addWidget(new SimpleCheckboxTag(array('value' => 'A')));
|
||||
$group->addWidget(new SimpleCheckboxTag(array('value' => 'B')));
|
||||
$this->assertTrue($group->setValue('A'));
|
||||
$this->assertIdentical($group->getValue(), 'A');
|
||||
$this->assertTrue($group->setValue('B'));
|
||||
$this->assertIdentical($group->getValue(), 'B');
|
||||
}
|
||||
|
||||
function testSettingMultipleValues() {
|
||||
$group = &new SimpleCheckboxGroup();
|
||||
$group->addWidget(new SimpleCheckboxTag(array('value' => 'A')));
|
||||
$group->addWidget(new SimpleCheckboxTag(array('value' => 'B')));
|
||||
$this->assertTrue($group->setValue(array('A', 'B')));
|
||||
$this->assertIdentical($group->getValue(), array('A', 'B'));
|
||||
}
|
||||
|
||||
function testSettingNoValue() {
|
||||
$group = &new SimpleCheckboxGroup();
|
||||
$group->addWidget(new SimpleCheckboxTag(array('value' => 'A')));
|
||||
$group->addWidget(new SimpleCheckboxTag(array('value' => 'B')));
|
||||
$this->assertTrue($group->setValue(false));
|
||||
$this->assertIdentical($group->getValue(), false);
|
||||
}
|
||||
|
||||
function testIsIdMatchesAnyIdInSet() {
|
||||
$group = &new SimpleCheckboxGroup();
|
||||
$group->addWidget(new SimpleCheckboxTag(array('id' => 1, 'value' => 'A')));
|
||||
$group->addWidget(new SimpleCheckboxTag(array('id' => 2, 'value' => 'B')));
|
||||
$this->assertFalse($group->isId(0));
|
||||
$this->assertTrue($group->isId(1));
|
||||
$this->assertTrue($group->isId(2));
|
||||
}
|
||||
}
|
||||
|
||||
class TestOfUploadWidget extends UnitTestCase {
|
||||
|
||||
function testValueIsFilePath() {
|
||||
$upload = &new SimpleUploadTag(array('name' => 'a'));
|
||||
$upload->setValue(dirname(__FILE__) . '/support/upload_sample.txt');
|
||||
$this->assertEqual($upload->getValue(), dirname(__FILE__) . '/support/upload_sample.txt');
|
||||
}
|
||||
|
||||
function testSubmitsFileContents() {
|
||||
$encoding = &new MockSimpleMultipartEncoding();
|
||||
$encoding->expectOnce('attach', array(
|
||||
'a',
|
||||
'Sample for testing file upload',
|
||||
'upload_sample.txt'));
|
||||
$upload = &new SimpleUploadTag(array('name' => 'a'));
|
||||
$upload->setValue(dirname(__FILE__) . '/support/upload_sample.txt');
|
||||
$upload->write($encoding);
|
||||
}
|
||||
}
|
||||
|
||||
class TestOfLabelTag extends UnitTestCase {
|
||||
|
||||
function testLabelShouldHaveAnEndTag() {
|
||||
$label = &new SimpleLabelTag(array());
|
||||
$this->assertTrue($label->expectEndTag());
|
||||
}
|
||||
|
||||
function testContentIsTextOnly() {
|
||||
$label = &new SimpleLabelTag(array());
|
||||
$label->addContent('Here <tag>are</tag> words');
|
||||
$this->assertEqual($label->getText(), 'Here are words');
|
||||
}
|
||||
}
|
||||
?>
|
||||
8
tests/simpletest/test/test_with_parse_error.php
Normal file
8
tests/simpletest/test/test_with_parse_error.php
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
<?php
|
||||
// $Id: test_with_parse_error.php 901 2005-01-24 00:32:14Z lastcraft $
|
||||
|
||||
class TestCaseWithParseError extends UnitTestCase {
|
||||
wibble
|
||||
}
|
||||
|
||||
?>
|
||||
55
tests/simpletest/test/unit_tester_test.php
Normal file
55
tests/simpletest/test/unit_tester_test.php
Normal file
|
|
@ -0,0 +1,55 @@
|
|||
<?php
|
||||
// $Id: unit_tester_test.php 1509 2007-05-08 22:11:49Z lastcraft $
|
||||
require_once(dirname(__FILE__) . '/../autorun.php');
|
||||
|
||||
class ReferenceForTesting {
|
||||
}
|
||||
|
||||
class TestOfUnitTester extends UnitTestCase {
|
||||
|
||||
function testAssertTrueReturnsAssertionAsBoolean() {
|
||||
$this->assertTrue($this->assertTrue(true));
|
||||
}
|
||||
|
||||
function testAssertFalseReturnsAssertionAsBoolean() {
|
||||
$this->assertTrue($this->assertFalse(false));
|
||||
}
|
||||
|
||||
function testAssertEqualReturnsAssertionAsBoolean() {
|
||||
$this->assertTrue($this->assertEqual(5, 5));
|
||||
}
|
||||
|
||||
function testAssertIdenticalReturnsAssertionAsBoolean() {
|
||||
$this->assertTrue($this->assertIdentical(5, 5));
|
||||
}
|
||||
|
||||
function testCoreAssertionsDoNotThrowErrors() {
|
||||
$this->assertIsA($this, 'UnitTestCase');
|
||||
$this->assertNotA($this, 'WebTestCase');
|
||||
}
|
||||
|
||||
function testReferenceAssertionOnObjects() {
|
||||
$a = &new ReferenceForTesting();
|
||||
$b = &$a;
|
||||
$this->assertReference($a, $b);
|
||||
}
|
||||
|
||||
function testReferenceAssertionOnScalars() {
|
||||
$a = 25;
|
||||
$b = &$a;
|
||||
$this->assertReference($a, $b);
|
||||
}
|
||||
|
||||
function testCloneOnObjects() {
|
||||
$a = &new ReferenceForTesting();
|
||||
$b = &new ReferenceForTesting();
|
||||
$this->assertClone($a, $b);
|
||||
}
|
||||
|
||||
function testCloneOnScalars() {
|
||||
$a = 25;
|
||||
$b = 25;
|
||||
$this->assertClone($a, $b);
|
||||
}
|
||||
}
|
||||
?>
|
||||
55
tests/simpletest/test/unit_tests.php
Normal file
55
tests/simpletest/test/unit_tests.php
Normal file
|
|
@ -0,0 +1,55 @@
|
|||
<?php
|
||||
// $Id: unit_tests.php 1661 2008-02-26 21:04:31Z pp11 $
|
||||
require_once(dirname(__FILE__) . '/../autorun.php');
|
||||
require_once(dirname(__FILE__) . '/../unit_tester.php');
|
||||
require_once(dirname(__FILE__) . '/../shell_tester.php');
|
||||
require_once(dirname(__FILE__) . '/../mock_objects.php');
|
||||
require_once(dirname(__FILE__) . '/../web_tester.php');
|
||||
require_once(dirname(__FILE__) . '/../extensions/pear_test_case.php');
|
||||
require_once(dirname(__FILE__) . '/../extensions/phpunit_test_case.php');
|
||||
|
||||
class UnitTests extends TestSuite {
|
||||
function UnitTests() {
|
||||
$this->TestSuite('Unit tests');
|
||||
$path = dirname(__FILE__);
|
||||
$this->addFile($path . '/errors_test.php');
|
||||
if (version_compare(phpversion(), '5') >= 0) {
|
||||
$this->addFile($path . '/exceptions_test.php');
|
||||
}
|
||||
$this->addFile($path . '/autorun_test.php');
|
||||
$this->addFile($path . '/compatibility_test.php');
|
||||
$this->addFile($path . '/simpletest_test.php');
|
||||
$this->addFile($path . '/dumper_test.php');
|
||||
$this->addFile($path . '/expectation_test.php');
|
||||
$this->addFile($path . '/unit_tester_test.php');
|
||||
if (version_compare(phpversion(), '5', '>=')) {
|
||||
$this->addFile($path . '/reflection_php5_test.php');
|
||||
} else {
|
||||
$this->addFile($path . '/reflection_php4_test.php');
|
||||
}
|
||||
$this->addFile($path . '/mock_objects_test.php');
|
||||
if (version_compare(phpversion(), '5', '>=')) {
|
||||
$this->addFile($path . '/interfaces_test.php');
|
||||
}
|
||||
$this->addFile($path . '/collector_test.php');
|
||||
$this->addFile($path . '/adapter_test.php');
|
||||
$this->addFile($path . '/socket_test.php');
|
||||
$this->addFile($path . '/encoding_test.php');
|
||||
$this->addFile($path . '/url_test.php');
|
||||
$this->addFile($path . '/cookies_test.php');
|
||||
$this->addFile($path . '/http_test.php');
|
||||
$this->addFile($path . '/authentication_test.php');
|
||||
$this->addFile($path . '/user_agent_test.php');
|
||||
$this->addFile($path . '/parser_test.php');
|
||||
$this->addFile($path . '/tag_test.php');
|
||||
$this->addFile($path . '/form_test.php');
|
||||
$this->addFile($path . '/page_test.php');
|
||||
$this->addFile($path . '/frames_test.php');
|
||||
$this->addFile($path . '/browser_test.php');
|
||||
$this->addFile($path . '/web_tester_test.php');
|
||||
$this->addFile($path . '/shell_tester_test.php');
|
||||
$this->addFile($path . '/xml_test.php');
|
||||
$this->addFile($path . '/../extensions/testdox/test.php');
|
||||
}
|
||||
}
|
||||
?>
|
||||
443
tests/simpletest/test/url_test.php
Normal file
443
tests/simpletest/test/url_test.php
Normal file
|
|
@ -0,0 +1,443 @@
|
|||
<?php
|
||||
// $Id: url_test.php 1598 2007-12-24 10:44:09Z pp11 $
|
||||
require_once(dirname(__FILE__) . '/../autorun.php');
|
||||
require_once(dirname(__FILE__) . '/../url.php');
|
||||
|
||||
class TestOfUrl extends UnitTestCase {
|
||||
|
||||
function testDefaultUrl() {
|
||||
$url = new SimpleUrl('');
|
||||
$this->assertEqual($url->getScheme(), '');
|
||||
$this->assertEqual($url->getHost(), '');
|
||||
$this->assertEqual($url->getScheme('http'), 'http');
|
||||
$this->assertEqual($url->getHost('localhost'), 'localhost');
|
||||
$this->assertEqual($url->getPath(), '');
|
||||
}
|
||||
|
||||
function testBasicParsing() {
|
||||
$url = new SimpleUrl('https://www.lastcraft.com/test/');
|
||||
$this->assertEqual($url->getScheme(), 'https');
|
||||
$this->assertEqual($url->getHost(), 'www.lastcraft.com');
|
||||
$this->assertEqual($url->getPath(), '/test/');
|
||||
}
|
||||
|
||||
function testRelativeUrls() {
|
||||
$url = new SimpleUrl('../somewhere.php');
|
||||
$this->assertEqual($url->getScheme(), false);
|
||||
$this->assertEqual($url->getHost(), false);
|
||||
$this->assertEqual($url->getPath(), '../somewhere.php');
|
||||
}
|
||||
|
||||
function testParseBareParameter() {
|
||||
$url = new SimpleUrl('?a');
|
||||
$this->assertEqual($url->getPath(), '');
|
||||
$this->assertEqual($url->getEncodedRequest(), '?a');
|
||||
$url->addRequestParameter('x', 'X');
|
||||
$this->assertEqual($url->getEncodedRequest(), '?a=&x=X');
|
||||
}
|
||||
|
||||
function testParseEmptyParameter() {
|
||||
$url = new SimpleUrl('?a=');
|
||||
$this->assertEqual($url->getPath(), '');
|
||||
$this->assertEqual($url->getEncodedRequest(), '?a=');
|
||||
$url->addRequestParameter('x', 'X');
|
||||
$this->assertEqual($url->getEncodedRequest(), '?a=&x=X');
|
||||
}
|
||||
|
||||
function testParseParameterPair() {
|
||||
$url = new SimpleUrl('?a=A');
|
||||
$this->assertEqual($url->getPath(), '');
|
||||
$this->assertEqual($url->getEncodedRequest(), '?a=A');
|
||||
$url->addRequestParameter('x', 'X');
|
||||
$this->assertEqual($url->getEncodedRequest(), '?a=A&x=X');
|
||||
}
|
||||
|
||||
function testParseMultipleParameters() {
|
||||
$url = new SimpleUrl('?a=A&b=B');
|
||||
$this->assertEqual($url->getEncodedRequest(), '?a=A&b=B');
|
||||
$url->addRequestParameter('x', 'X');
|
||||
$this->assertEqual($url->getEncodedRequest(), '?a=A&b=B&x=X');
|
||||
}
|
||||
|
||||
function testParsingParameterMixture() {
|
||||
$url = new SimpleUrl('?a=A&b=&c');
|
||||
$this->assertEqual($url->getEncodedRequest(), '?a=A&b=&c');
|
||||
$url->addRequestParameter('x', 'X');
|
||||
$this->assertEqual($url->getEncodedRequest(), '?a=A&b=&c=&x=X');
|
||||
}
|
||||
|
||||
function testAddParametersFromScratch() {
|
||||
$url = new SimpleUrl('');
|
||||
$url->addRequestParameter('a', 'A');
|
||||
$this->assertEqual($url->getEncodedRequest(), '?a=A');
|
||||
$url->addRequestParameter('b', 'B');
|
||||
$this->assertEqual($url->getEncodedRequest(), '?a=A&b=B');
|
||||
$url->addRequestParameter('a', 'aaa');
|
||||
$this->assertEqual($url->getEncodedRequest(), '?a=A&b=B&a=aaa');
|
||||
}
|
||||
|
||||
function testClearingParameters() {
|
||||
$url = new SimpleUrl('');
|
||||
$url->addRequestParameter('a', 'A');
|
||||
$url->clearRequest();
|
||||
$this->assertIdentical($url->getEncodedRequest(), '');
|
||||
}
|
||||
|
||||
function testEncodingParameters() {
|
||||
$url = new SimpleUrl('');
|
||||
$url->addRequestParameter('a', '?!"\'#~@[]{}:;<>,./|£$%^&*()_+-=');
|
||||
$this->assertIdentical(
|
||||
$request = $url->getEncodedRequest(),
|
||||
'?a=%3F%21%22%27%23%7E%40%5B%5D%7B%7D%3A%3B%3C%3E%2C.%2F%7C%A3%24%25%5E%26%2A%28%29_%2B-%3D');
|
||||
}
|
||||
|
||||
function testDecodingParameters() {
|
||||
$url = new SimpleUrl('?a=%3F%21%22%27%23%7E%40%5B%5D%7B%7D%3A%3B%3C%3E%2C.%2F%7C%A3%24%25%5E%26%2A%28%29_%2B-%3D');
|
||||
$this->assertEqual(
|
||||
$url->getEncodedRequest(),
|
||||
'?a=' . urlencode('?!"\'#~@[]{}:;<>,./|£$%^&*()_+-='));
|
||||
}
|
||||
|
||||
function testUrlInQueryDoesNotConfuseParsing() {
|
||||
$url = new SimpleUrl('wibble/login.php?url=http://www.google.com/moo/');
|
||||
$this->assertFalse($url->getScheme());
|
||||
$this->assertFalse($url->getHost());
|
||||
$this->assertEqual($url->getPath(), 'wibble/login.php');
|
||||
$this->assertEqual($url->getEncodedRequest(), '?url=http://www.google.com/moo/');
|
||||
}
|
||||
|
||||
function testSettingCordinates() {
|
||||
$url = new SimpleUrl('');
|
||||
$url->setCoordinates('32', '45');
|
||||
$this->assertIdentical($url->getX(), 32);
|
||||
$this->assertIdentical($url->getY(), 45);
|
||||
$this->assertEqual($url->getEncodedRequest(), '');
|
||||
}
|
||||
|
||||
function testParseCordinates() {
|
||||
$url = new SimpleUrl('?32,45');
|
||||
$this->assertIdentical($url->getX(), 32);
|
||||
$this->assertIdentical($url->getY(), 45);
|
||||
}
|
||||
|
||||
function testClearingCordinates() {
|
||||
$url = new SimpleUrl('?32,45');
|
||||
$url->setCoordinates();
|
||||
$this->assertIdentical($url->getX(), false);
|
||||
$this->assertIdentical($url->getY(), false);
|
||||
}
|
||||
|
||||
function testParsingParameterCordinateMixture() {
|
||||
$url = new SimpleUrl('?a=A&b=&c?32,45');
|
||||
$this->assertIdentical($url->getX(), 32);
|
||||
$this->assertIdentical($url->getY(), 45);
|
||||
$this->assertEqual($url->getEncodedRequest(), '?a=A&b=&c');
|
||||
}
|
||||
|
||||
function testParsingParameterWithBadCordinates() {
|
||||
$url = new SimpleUrl('?a=A&b=&c?32');
|
||||
$this->assertIdentical($url->getX(), false);
|
||||
$this->assertIdentical($url->getY(), false);
|
||||
$this->assertEqual($url->getEncodedRequest(), '?a=A&b=&c?32');
|
||||
}
|
||||
|
||||
function testPageSplitting() {
|
||||
$url = new SimpleUrl('./here/../there/somewhere.php');
|
||||
$this->assertEqual($url->getPath(), './here/../there/somewhere.php');
|
||||
$this->assertEqual($url->getPage(), 'somewhere.php');
|
||||
$this->assertEqual($url->getBasePath(), './here/../there/');
|
||||
}
|
||||
|
||||
function testAbsolutePathPageSplitting() {
|
||||
$url = new SimpleUrl("http://host.com/here/there/somewhere.php");
|
||||
$this->assertEqual($url->getPath(), "/here/there/somewhere.php");
|
||||
$this->assertEqual($url->getPage(), "somewhere.php");
|
||||
$this->assertEqual($url->getBasePath(), "/here/there/");
|
||||
}
|
||||
|
||||
function testSplittingUrlWithNoPageGivesEmptyPage() {
|
||||
$url = new SimpleUrl('/here/there/');
|
||||
$this->assertEqual($url->getPath(), '/here/there/');
|
||||
$this->assertEqual($url->getPage(), '');
|
||||
$this->assertEqual($url->getBasePath(), '/here/there/');
|
||||
}
|
||||
|
||||
function testPathNormalisation() {
|
||||
$this->assertEqual(
|
||||
SimpleUrl::normalisePath('https://host.com/I/am/here/../there/somewhere.php'),
|
||||
'https://host.com/I/am/there/somewhere.php');
|
||||
}
|
||||
|
||||
// regression test for #1535407
|
||||
function testPathNormalisationWithSinglePeriod() {
|
||||
$this->assertEqual(
|
||||
SimpleUrl::normalisePath('https://host.com/I/am/here/./../there/somewhere.php'),
|
||||
'https://host.com/I/am/there/somewhere.php');
|
||||
}
|
||||
|
||||
// regression test for #1852413
|
||||
function testHostnameExtractedFromUContainingAtSign() {
|
||||
$url = new SimpleUrl("http://localhost/name@example.com");
|
||||
$this->assertEqual($url->getScheme(), "http");
|
||||
$this->assertEqual($url->getUsername(), "");
|
||||
$this->assertEqual($url->getPassword(), "");
|
||||
$this->assertEqual($url->getHost(), "localhost");
|
||||
$this->assertEqual($url->getPath(), "/name@example.com");
|
||||
}
|
||||
|
||||
function testHostnameInLocalhost() {
|
||||
$url = new SimpleUrl("http://localhost/name/example.com");
|
||||
$this->assertEqual($url->getScheme(), "http");
|
||||
$this->assertEqual($url->getUsername(), "");
|
||||
$this->assertEqual($url->getPassword(), "");
|
||||
$this->assertEqual($url->getHost(), "localhost");
|
||||
$this->assertEqual($url->getPath(), "/name/example.com");
|
||||
}
|
||||
|
||||
function testUsernameAndPasswordAreUrlDecoded() {
|
||||
$url = new SimpleUrl('http://' . urlencode('test@test') .
|
||||
':' . urlencode('$!£@*&%') . '@www.lastcraft.com');
|
||||
$this->assertEqual($url->getUsername(), 'test@test');
|
||||
$this->assertEqual($url->getPassword(), '$!£@*&%');
|
||||
}
|
||||
|
||||
function testBlitz() {
|
||||
$this->assertUrl(
|
||||
"https://username:password@www.somewhere.com:243/this/that/here.php?a=1&b=2#anchor",
|
||||
array("https", "username", "password", "www.somewhere.com", 243, "/this/that/here.php", "com", "?a=1&b=2", "anchor"),
|
||||
array("a" => "1", "b" => "2"));
|
||||
$this->assertUrl(
|
||||
"username:password@www.somewhere.com/this/that/here.php?a=1",
|
||||
array(false, "username", "password", "www.somewhere.com", false, "/this/that/here.php", "com", "?a=1", false),
|
||||
array("a" => "1"));
|
||||
$this->assertUrl(
|
||||
"username:password@somewhere.com:243?1,2",
|
||||
array(false, "username", "password", "somewhere.com", 243, "/", "com", "", false),
|
||||
array(),
|
||||
array(1, 2));
|
||||
$this->assertUrl(
|
||||
"https://www.somewhere.com",
|
||||
array("https", false, false, "www.somewhere.com", false, "/", "com", "", false));
|
||||
$this->assertUrl(
|
||||
"username@www.somewhere.com:243#anchor",
|
||||
array(false, "username", false, "www.somewhere.com", 243, "/", "com", "", "anchor"));
|
||||
$this->assertUrl(
|
||||
"/this/that/here.php?a=1&b=2?3,4",
|
||||
array(false, false, false, false, false, "/this/that/here.php", false, "?a=1&b=2", false),
|
||||
array("a" => "1", "b" => "2"),
|
||||
array(3, 4));
|
||||
$this->assertUrl(
|
||||
"username@/here.php?a=1&b=2",
|
||||
array(false, "username", false, false, false, "/here.php", false, "?a=1&b=2", false),
|
||||
array("a" => "1", "b" => "2"));
|
||||
}
|
||||
|
||||
function testAmbiguousHosts() {
|
||||
$this->assertUrl(
|
||||
"tigger",
|
||||
array(false, false, false, false, false, "tigger", false, "", false));
|
||||
$this->assertUrl(
|
||||
"/tigger",
|
||||
array(false, false, false, false, false, "/tigger", false, "", false));
|
||||
$this->assertUrl(
|
||||
"//tigger",
|
||||
array(false, false, false, "tigger", false, "/", false, "", false));
|
||||
$this->assertUrl(
|
||||
"//tigger/",
|
||||
array(false, false, false, "tigger", false, "/", false, "", false));
|
||||
$this->assertUrl(
|
||||
"tigger.com",
|
||||
array(false, false, false, "tigger.com", false, "/", "com", "", false));
|
||||
$this->assertUrl(
|
||||
"me.net/tigger",
|
||||
array(false, false, false, "me.net", false, "/tigger", "net", "", false));
|
||||
}
|
||||
|
||||
function testAsString() {
|
||||
$this->assertPreserved('https://www.here.com');
|
||||
$this->assertPreserved('http://me:secret@www.here.com');
|
||||
$this->assertPreserved('http://here/there');
|
||||
$this->assertPreserved('http://here/there?a=A&b=B');
|
||||
$this->assertPreserved('http://here/there?a=1&a=2');
|
||||
$this->assertPreserved('http://here/there?a=1&a=2?9,8');
|
||||
$this->assertPreserved('http://host?a=1&a=2');
|
||||
$this->assertPreserved('http://host#stuff');
|
||||
$this->assertPreserved('http://me:secret@www.here.com/a/b/c/here.html?a=A?7,6');
|
||||
$this->assertPreserved('http://www.here.com/?a=A__b=B');
|
||||
}
|
||||
|
||||
function assertUrl($raw, $parts, $params = false, $coords = false) {
|
||||
if (! is_array($params)) {
|
||||
$params = array();
|
||||
}
|
||||
$url = new SimpleUrl($raw);
|
||||
$this->assertIdentical($url->getScheme(), $parts[0], "[$raw] scheme -> %s");
|
||||
$this->assertIdentical($url->getUsername(), $parts[1], "[$raw] username -> %s");
|
||||
$this->assertIdentical($url->getPassword(), $parts[2], "[$raw] password -> %s");
|
||||
$this->assertIdentical($url->getHost(), $parts[3], "[$raw] host -> %s");
|
||||
$this->assertIdentical($url->getPort(), $parts[4], "[$raw] port -> %s");
|
||||
$this->assertIdentical($url->getPath(), $parts[5], "[$raw] path -> %s");
|
||||
$this->assertIdentical($url->getTld(), $parts[6], "[$raw] tld -> %s");
|
||||
$this->assertIdentical($url->getEncodedRequest(), $parts[7], "[$raw] encoded -> %s");
|
||||
$this->assertIdentical($url->getFragment(), $parts[8], "[$raw] fragment -> %s");
|
||||
if ($coords) {
|
||||
$this->assertIdentical($url->getX(), $coords[0], "[$raw] x -> %s");
|
||||
$this->assertIdentical($url->getY(), $coords[1], "[$raw] y -> %s");
|
||||
}
|
||||
}
|
||||
|
||||
function testUrlWithTwoSlashesInPath() {
|
||||
$url = new SimpleUrl('/article/categoryedit/insert//');
|
||||
$this->assertEqual($url->getPath(), '/article/categoryedit/insert//');
|
||||
}
|
||||
|
||||
function assertPreserved($string) {
|
||||
$url = new SimpleUrl($string);
|
||||
$this->assertEqual($url->asString(), $string);
|
||||
}
|
||||
}
|
||||
|
||||
class TestOfAbsoluteUrls extends UnitTestCase {
|
||||
|
||||
function testDirectoriesAfterFilename() {
|
||||
$string = '../../index.php/foo/bar';
|
||||
$url = new SimpleUrl($string);
|
||||
$this->assertEqual($url->asString(), $string);
|
||||
|
||||
$absolute = $url->makeAbsolute('http://www.domain.com/some/path/');
|
||||
$this->assertEqual($absolute->asString(), 'http://www.domain.com/index.php/foo/bar');
|
||||
}
|
||||
|
||||
function testMakingAbsolute() {
|
||||
$url = new SimpleUrl('../there/somewhere.php');
|
||||
$this->assertEqual($url->getPath(), '../there/somewhere.php');
|
||||
$absolute = $url->makeAbsolute('https://host.com:1234/I/am/here/');
|
||||
$this->assertEqual($absolute->getScheme(), 'https');
|
||||
$this->assertEqual($absolute->getHost(), 'host.com');
|
||||
$this->assertEqual($absolute->getPort(), 1234);
|
||||
$this->assertEqual($absolute->getPath(), '/I/am/there/somewhere.php');
|
||||
}
|
||||
|
||||
function testMakingAnEmptyUrlAbsolute() {
|
||||
$url = new SimpleUrl('');
|
||||
$this->assertEqual($url->getPath(), '');
|
||||
$absolute = $url->makeAbsolute('http://host.com/I/am/here/page.html');
|
||||
$this->assertEqual($absolute->getScheme(), 'http');
|
||||
$this->assertEqual($absolute->getHost(), 'host.com');
|
||||
$this->assertEqual($absolute->getPath(), '/I/am/here/page.html');
|
||||
}
|
||||
|
||||
function testMakingAnEmptyUrlAbsoluteWithMissingPageName() {
|
||||
$url = new SimpleUrl('');
|
||||
$this->assertEqual($url->getPath(), '');
|
||||
$absolute = $url->makeAbsolute('http://host.com/I/am/here/');
|
||||
$this->assertEqual($absolute->getScheme(), 'http');
|
||||
$this->assertEqual($absolute->getHost(), 'host.com');
|
||||
$this->assertEqual($absolute->getPath(), '/I/am/here/');
|
||||
}
|
||||
|
||||
function testMakingAShortQueryUrlAbsolute() {
|
||||
$url = new SimpleUrl('?a#b');
|
||||
$this->assertEqual($url->getPath(), '');
|
||||
$absolute = $url->makeAbsolute('http://host.com/I/am/here/');
|
||||
$this->assertEqual($absolute->getScheme(), 'http');
|
||||
$this->assertEqual($absolute->getHost(), 'host.com');
|
||||
$this->assertEqual($absolute->getPath(), '/I/am/here/');
|
||||
$this->assertEqual($absolute->getEncodedRequest(), '?a');
|
||||
$this->assertEqual($absolute->getFragment(), 'b');
|
||||
}
|
||||
|
||||
function testMakingADirectoryUrlAbsolute() {
|
||||
$url = new SimpleUrl('hello/');
|
||||
$this->assertEqual($url->getPath(), 'hello/');
|
||||
$this->assertEqual($url->getBasePath(), 'hello/');
|
||||
$this->assertEqual($url->getPage(), '');
|
||||
$absolute = $url->makeAbsolute('http://host.com/I/am/here/page.html');
|
||||
$this->assertEqual($absolute->getPath(), '/I/am/here/hello/');
|
||||
}
|
||||
|
||||
function testMakingARootUrlAbsolute() {
|
||||
$url = new SimpleUrl('/');
|
||||
$this->assertEqual($url->getPath(), '/');
|
||||
$absolute = $url->makeAbsolute('http://host.com/I/am/here/page.html');
|
||||
$this->assertEqual($absolute->getPath(), '/');
|
||||
}
|
||||
|
||||
function testMakingARootPageUrlAbsolute() {
|
||||
$url = new SimpleUrl('/here.html');
|
||||
$absolute = $url->makeAbsolute('http://host.com/I/am/here/page.html');
|
||||
$this->assertEqual($absolute->getPath(), '/here.html');
|
||||
}
|
||||
|
||||
function testCarryAuthenticationFromRootPage() {
|
||||
$url = new SimpleUrl('here.html');
|
||||
$absolute = $url->makeAbsolute('http://test:secret@host.com/');
|
||||
$this->assertEqual($absolute->getPath(), '/here.html');
|
||||
$this->assertEqual($absolute->getUsername(), 'test');
|
||||
$this->assertEqual($absolute->getPassword(), 'secret');
|
||||
}
|
||||
|
||||
function testMakingCoordinateUrlAbsolute() {
|
||||
$url = new SimpleUrl('?1,2');
|
||||
$this->assertEqual($url->getPath(), '');
|
||||
$absolute = $url->makeAbsolute('http://host.com/I/am/here/');
|
||||
$this->assertEqual($absolute->getScheme(), 'http');
|
||||
$this->assertEqual($absolute->getHost(), 'host.com');
|
||||
$this->assertEqual($absolute->getPath(), '/I/am/here/');
|
||||
$this->assertEqual($absolute->getX(), 1);
|
||||
$this->assertEqual($absolute->getY(), 2);
|
||||
}
|
||||
|
||||
function testMakingAbsoluteAppendedPath() {
|
||||
$url = new SimpleUrl('./there/somewhere.php');
|
||||
$absolute = $url->makeAbsolute('https://host.com/here/');
|
||||
$this->assertEqual($absolute->getPath(), '/here/there/somewhere.php');
|
||||
}
|
||||
|
||||
function testMakingAbsoluteBadlyFormedAppendedPath() {
|
||||
$url = new SimpleUrl('there/somewhere.php');
|
||||
$absolute = $url->makeAbsolute('https://host.com/here/');
|
||||
$this->assertEqual($absolute->getPath(), '/here/there/somewhere.php');
|
||||
}
|
||||
|
||||
function testMakingAbsoluteHasNoEffectWhenAlreadyAbsolute() {
|
||||
$url = new SimpleUrl('https://test:secret@www.lastcraft.com:321/stuff/?a=1#f');
|
||||
$absolute = $url->makeAbsolute('http://host.com/here/');
|
||||
$this->assertEqual($absolute->getScheme(), 'https');
|
||||
$this->assertEqual($absolute->getUsername(), 'test');
|
||||
$this->assertEqual($absolute->getPassword(), 'secret');
|
||||
$this->assertEqual($absolute->getHost(), 'www.lastcraft.com');
|
||||
$this->assertEqual($absolute->getPort(), 321);
|
||||
$this->assertEqual($absolute->getPath(), '/stuff/');
|
||||
$this->assertEqual($absolute->getEncodedRequest(), '?a=1');
|
||||
$this->assertEqual($absolute->getFragment(), 'f');
|
||||
}
|
||||
|
||||
function testMakingAbsoluteCarriesAuthenticationWhenAlreadyAbsolute() {
|
||||
$url = new SimpleUrl('https://www.lastcraft.com');
|
||||
$absolute = $url->makeAbsolute('http://test:secret@host.com/here/');
|
||||
$this->assertEqual($absolute->getHost(), 'www.lastcraft.com');
|
||||
$this->assertEqual($absolute->getUsername(), 'test');
|
||||
$this->assertEqual($absolute->getPassword(), 'secret');
|
||||
}
|
||||
|
||||
function testMakingHostOnlyAbsoluteDoesNotCarryAnyOtherInformation() {
|
||||
$url = new SimpleUrl('http://www.lastcraft.com');
|
||||
$absolute = $url->makeAbsolute('https://host.com:81/here/');
|
||||
$this->assertEqual($absolute->getScheme(), 'http');
|
||||
$this->assertEqual($absolute->getHost(), 'www.lastcraft.com');
|
||||
$this->assertIdentical($absolute->getPort(), false);
|
||||
$this->assertEqual($absolute->getPath(), '/');
|
||||
}
|
||||
}
|
||||
|
||||
class TestOfFrameUrl extends UnitTestCase {
|
||||
|
||||
function testTargetAttachment() {
|
||||
$url = new SimpleUrl('http://www.site.com/home.html');
|
||||
$this->assertIdentical($url->getTarget(), false);
|
||||
$url->setTarget('A frame');
|
||||
$this->assertIdentical($url->getTarget(), 'A frame');
|
||||
}
|
||||
}
|
||||
?>
|
||||
358
tests/simpletest/test/user_agent_test.php
Normal file
358
tests/simpletest/test/user_agent_test.php
Normal file
|
|
@ -0,0 +1,358 @@
|
|||
<?php
|
||||
// $Id: user_agent_test.php 1509 2007-05-08 22:11:49Z lastcraft $
|
||||
require_once(dirname(__FILE__) . '/../autorun.php');
|
||||
require_once(dirname(__FILE__) . '/../user_agent.php');
|
||||
require_once(dirname(__FILE__) . '/../authentication.php');
|
||||
require_once(dirname(__FILE__) . '/../http.php');
|
||||
require_once(dirname(__FILE__) . '/../encoding.php');
|
||||
Mock::generate('SimpleHttpRequest');
|
||||
Mock::generate('SimpleHttpResponse');
|
||||
Mock::generate('SimpleHttpHeaders');
|
||||
Mock::generatePartial('SimpleUserAgent', 'MockRequestUserAgent', array('_createHttpRequest'));
|
||||
|
||||
class TestOfFetchingUrlParameters extends UnitTestCase {
|
||||
|
||||
function setUp() {
|
||||
$this->_headers = &new MockSimpleHttpHeaders();
|
||||
|
||||
$this->_response = &new MockSimpleHttpResponse();
|
||||
$this->_response->setReturnValue('isError', false);
|
||||
$this->_response->setReturnReference('getHeaders', new MockSimpleHttpHeaders());
|
||||
|
||||
$this->_request = &new MockSimpleHttpRequest();
|
||||
$this->_request->setReturnReference('fetch', $this->_response);
|
||||
}
|
||||
|
||||
function testGetRequestWithoutIncidentGivesNoErrors() {
|
||||
$url = new SimpleUrl('http://test:secret@this.com/page.html');
|
||||
$url->addRequestParameters(array('a' => 'A', 'b' => 'B'));
|
||||
|
||||
$agent = &new MockRequestUserAgent();
|
||||
$agent->setReturnReference('_createHttpRequest', $this->_request);
|
||||
$agent->SimpleUserAgent();
|
||||
|
||||
$response = &$agent->fetchResponse(
|
||||
new SimpleUrl('http://test:secret@this.com/page.html'),
|
||||
new SimpleGetEncoding(array('a' => 'A', 'b' => 'B')));
|
||||
$this->assertFalse($response->isError());
|
||||
}
|
||||
}
|
||||
|
||||
class TestOfAdditionalHeaders extends UnitTestCase {
|
||||
|
||||
function testAdditionalHeaderAddedToRequest() {
|
||||
$response = &new MockSimpleHttpResponse();
|
||||
$response->setReturnReference('getHeaders', new MockSimpleHttpHeaders());
|
||||
|
||||
$request = &new MockSimpleHttpRequest();
|
||||
$request->setReturnReference('fetch', $response);
|
||||
$request->expectOnce(
|
||||
'addHeaderLine',
|
||||
array('User-Agent: SimpleTest'));
|
||||
|
||||
$agent = &new MockRequestUserAgent();
|
||||
$agent->setReturnReference('_createHttpRequest', $request);
|
||||
$agent->SimpleUserAgent();
|
||||
$agent->addHeader('User-Agent: SimpleTest');
|
||||
$response = &$agent->fetchResponse(new SimpleUrl('http://this.host/'), new SimpleGetEncoding());
|
||||
}
|
||||
}
|
||||
|
||||
class TestOfBrowserCookies extends UnitTestCase {
|
||||
|
||||
function &_createStandardResponse() {
|
||||
$response = &new MockSimpleHttpResponse();
|
||||
$response->setReturnValue("isError", false);
|
||||
$response->setReturnValue("getContent", "stuff");
|
||||
$response->setReturnReference("getHeaders", new MockSimpleHttpHeaders());
|
||||
return $response;
|
||||
}
|
||||
|
||||
function &_createCookieSite($header_lines) {
|
||||
$headers = &new SimpleHttpHeaders($header_lines);
|
||||
|
||||
$response = &new MockSimpleHttpResponse();
|
||||
$response->setReturnValue("isError", false);
|
||||
$response->setReturnReference("getHeaders", $headers);
|
||||
$response->setReturnValue("getContent", "stuff");
|
||||
|
||||
$request = &new MockSimpleHttpRequest();
|
||||
$request->setReturnReference("fetch", $response);
|
||||
return $request;
|
||||
}
|
||||
|
||||
function &_createMockedRequestUserAgent(&$request) {
|
||||
$agent = &new MockRequestUserAgent();
|
||||
$agent->setReturnReference('_createHttpRequest', $request);
|
||||
$agent->SimpleUserAgent();
|
||||
return $agent;
|
||||
}
|
||||
|
||||
function testCookieJarIsSentToRequest() {
|
||||
$jar = new SimpleCookieJar();
|
||||
$jar->setCookie('a', 'A');
|
||||
|
||||
$request = &new MockSimpleHttpRequest();
|
||||
$request->setReturnReference('fetch', $this->_createStandardResponse());
|
||||
$request->expectOnce('readCookiesFromJar', array($jar, '*'));
|
||||
|
||||
$agent = &$this->_createMockedRequestUserAgent($request);
|
||||
$agent->setCookie('a', 'A');
|
||||
$agent->fetchResponse(
|
||||
new SimpleUrl('http://this.com/this/path/page.html'),
|
||||
new SimpleGetEncoding());
|
||||
}
|
||||
|
||||
function testNoCookieJarIsSentToRequestWhenCookiesAreDisabled() {
|
||||
$request = &new MockSimpleHttpRequest();
|
||||
$request->setReturnReference('fetch', $this->_createStandardResponse());
|
||||
$request->expectNever('readCookiesFromJar');
|
||||
|
||||
$agent = &$this->_createMockedRequestUserAgent($request);
|
||||
$agent->setCookie('a', 'A');
|
||||
$agent->ignoreCookies();
|
||||
$agent->fetchResponse(
|
||||
new SimpleUrl('http://this.com/this/path/page.html'),
|
||||
new SimpleGetEncoding());
|
||||
}
|
||||
|
||||
function testReadingNewCookie() {
|
||||
$request = &$this->_createCookieSite('Set-cookie: a=AAAA');
|
||||
$agent = &$this->_createMockedRequestUserAgent($request);
|
||||
$agent->fetchResponse(
|
||||
new SimpleUrl('http://this.com/this/path/page.html'),
|
||||
new SimpleGetEncoding());
|
||||
$this->assertEqual($agent->getCookieValue("this.com", "this/path/", "a"), "AAAA");
|
||||
}
|
||||
|
||||
function testIgnoringNewCookieWhenCookiesDisabled() {
|
||||
$request = &$this->_createCookieSite('Set-cookie: a=AAAA');
|
||||
$agent = &$this->_createMockedRequestUserAgent($request);
|
||||
$agent->ignoreCookies();
|
||||
$agent->fetchResponse(
|
||||
new SimpleUrl('http://this.com/this/path/page.html'),
|
||||
new SimpleGetEncoding());
|
||||
$this->assertIdentical($agent->getCookieValue("this.com", "this/path/", "a"), false);
|
||||
}
|
||||
|
||||
function testOverwriteCookieThatAlreadyExists() {
|
||||
$request = &$this->_createCookieSite('Set-cookie: a=AAAA');
|
||||
$agent = &$this->_createMockedRequestUserAgent($request);
|
||||
$agent->setCookie('a', 'A');
|
||||
$agent->fetchResponse(
|
||||
new SimpleUrl('http://this.com/this/path/page.html'),
|
||||
new SimpleGetEncoding());
|
||||
$this->assertEqual($agent->getCookieValue("this.com", "this/path/", "a"), "AAAA");
|
||||
}
|
||||
|
||||
function testClearCookieBySettingExpiry() {
|
||||
$request = &$this->_createCookieSite('Set-cookie: a=b');
|
||||
$agent = &$this->_createMockedRequestUserAgent($request);
|
||||
|
||||
$agent->setCookie("a", "A", "this/path/", "Wed, 25-Dec-02 04:24:21 GMT");
|
||||
$agent->fetchResponse(
|
||||
new SimpleUrl('http://this.com/this/path/page.html'),
|
||||
new SimpleGetEncoding());
|
||||
$this->assertIdentical(
|
||||
$agent->getCookieValue("this.com", "this/path/", "a"),
|
||||
"b");
|
||||
$agent->restart("Wed, 25-Dec-02 04:24:20 GMT");
|
||||
$this->assertIdentical(
|
||||
$agent->getCookieValue("this.com", "this/path/", "a"),
|
||||
false);
|
||||
}
|
||||
|
||||
function testAgeingAndClearing() {
|
||||
$request = &$this->_createCookieSite('Set-cookie: a=A; expires=Wed, 25-Dec-02 04:24:21 GMT; path=/this/path');
|
||||
$agent = &$this->_createMockedRequestUserAgent($request);
|
||||
|
||||
$agent->fetchResponse(
|
||||
new SimpleUrl('http://this.com/this/path/page.html'),
|
||||
new SimpleGetEncoding());
|
||||
$agent->restart("Wed, 25-Dec-02 04:24:20 GMT");
|
||||
$this->assertIdentical(
|
||||
$agent->getCookieValue("this.com", "this/path/", "a"),
|
||||
"A");
|
||||
$agent->ageCookies(2);
|
||||
$agent->restart("Wed, 25-Dec-02 04:24:20 GMT");
|
||||
$this->assertIdentical(
|
||||
$agent->getCookieValue("this.com", "this/path/", "a"),
|
||||
false);
|
||||
}
|
||||
|
||||
function testReadingIncomingAndSettingNewCookies() {
|
||||
$request = &$this->_createCookieSite('Set-cookie: a=AAA');
|
||||
$agent = &$this->_createMockedRequestUserAgent($request);
|
||||
|
||||
$this->assertNull($agent->getBaseCookieValue("a", false));
|
||||
$agent->fetchResponse(
|
||||
new SimpleUrl('http://this.com/this/path/page.html'),
|
||||
new SimpleGetEncoding());
|
||||
$agent->setCookie("b", "BBB", "this.com", "this/path/");
|
||||
$this->assertEqual(
|
||||
$agent->getBaseCookieValue("a", new SimpleUrl('http://this.com/this/path/page.html')),
|
||||
"AAA");
|
||||
$this->assertEqual(
|
||||
$agent->getBaseCookieValue("b", new SimpleUrl('http://this.com/this/path/page.html')),
|
||||
"BBB");
|
||||
}
|
||||
}
|
||||
|
||||
class TestOfHttpRedirects extends UnitTestCase {
|
||||
|
||||
function &createRedirect($content, $redirect) {
|
||||
$headers = &new MockSimpleHttpHeaders();
|
||||
$headers->setReturnValue('isRedirect', (boolean)$redirect);
|
||||
$headers->setReturnValue('getLocation', $redirect);
|
||||
|
||||
$response = &new MockSimpleHttpResponse();
|
||||
$response->setReturnValue('getContent', $content);
|
||||
$response->setReturnReference('getHeaders', $headers);
|
||||
|
||||
$request = &new MockSimpleHttpRequest();
|
||||
$request->setReturnReference('fetch', $response);
|
||||
return $request;
|
||||
}
|
||||
|
||||
function testDisabledRedirects() {
|
||||
$agent = &new MockRequestUserAgent();
|
||||
$agent->setReturnReference(
|
||||
'_createHttpRequest',
|
||||
$this->createRedirect('stuff', 'there.html'));
|
||||
$agent->expectOnce('_createHttpRequest');
|
||||
$agent->SimpleUserAgent();
|
||||
|
||||
$agent->setMaximumRedirects(0);
|
||||
$response = &$agent->fetchResponse(new SimpleUrl('here.html'), new SimpleGetEncoding());
|
||||
$this->assertEqual($response->getContent(), 'stuff');
|
||||
}
|
||||
|
||||
function testSingleRedirect() {
|
||||
$agent = &new MockRequestUserAgent();
|
||||
$agent->setReturnReferenceAt(
|
||||
0,
|
||||
'_createHttpRequest',
|
||||
$this->createRedirect('first', 'two.html'));
|
||||
$agent->setReturnReferenceAt(
|
||||
1,
|
||||
'_createHttpRequest',
|
||||
$this->createRedirect('second', 'three.html'));
|
||||
$agent->expectCallCount('_createHttpRequest', 2);
|
||||
$agent->SimpleUserAgent();
|
||||
|
||||
$agent->setMaximumRedirects(1);
|
||||
$response = &$agent->fetchResponse(new SimpleUrl('one.html'), new SimpleGetEncoding());
|
||||
$this->assertEqual($response->getContent(), 'second');
|
||||
}
|
||||
|
||||
function testDoubleRedirect() {
|
||||
$agent = &new MockRequestUserAgent();
|
||||
$agent->setReturnReferenceAt(
|
||||
0,
|
||||
'_createHttpRequest',
|
||||
$this->createRedirect('first', 'two.html'));
|
||||
$agent->setReturnReferenceAt(
|
||||
1,
|
||||
'_createHttpRequest',
|
||||
$this->createRedirect('second', 'three.html'));
|
||||
$agent->setReturnReferenceAt(
|
||||
2,
|
||||
'_createHttpRequest',
|
||||
$this->createRedirect('third', 'four.html'));
|
||||
$agent->expectCallCount('_createHttpRequest', 3);
|
||||
$agent->SimpleUserAgent();
|
||||
|
||||
$agent->setMaximumRedirects(2);
|
||||
$response = &$agent->fetchResponse(new SimpleUrl('one.html'), new SimpleGetEncoding());
|
||||
$this->assertEqual($response->getContent(), 'third');
|
||||
}
|
||||
|
||||
function testSuccessAfterRedirect() {
|
||||
$agent = &new MockRequestUserAgent();
|
||||
$agent->setReturnReferenceAt(
|
||||
0,
|
||||
'_createHttpRequest',
|
||||
$this->createRedirect('first', 'two.html'));
|
||||
$agent->setReturnReferenceAt(
|
||||
1,
|
||||
'_createHttpRequest',
|
||||
$this->createRedirect('second', false));
|
||||
$agent->setReturnReferenceAt(
|
||||
2,
|
||||
'_createHttpRequest',
|
||||
$this->createRedirect('third', 'four.html'));
|
||||
$agent->expectCallCount('_createHttpRequest', 2);
|
||||
$agent->SimpleUserAgent();
|
||||
|
||||
$agent->setMaximumRedirects(2);
|
||||
$response = &$agent->fetchResponse(new SimpleUrl('one.html'), new SimpleGetEncoding());
|
||||
$this->assertEqual($response->getContent(), 'second');
|
||||
}
|
||||
|
||||
function testRedirectChangesPostToGet() {
|
||||
$agent = &new MockRequestUserAgent();
|
||||
$agent->setReturnReferenceAt(
|
||||
0,
|
||||
'_createHttpRequest',
|
||||
$this->createRedirect('first', 'two.html'));
|
||||
$agent->expectArgumentsAt(0, '_createHttpRequest', array('*', new IsAExpectation('SimplePostEncoding')));
|
||||
$agent->setReturnReferenceAt(
|
||||
1,
|
||||
'_createHttpRequest',
|
||||
$this->createRedirect('second', 'three.html'));
|
||||
$agent->expectArgumentsAt(1, '_createHttpRequest', array('*', new IsAExpectation('SimpleGetEncoding')));
|
||||
$agent->expectCallCount('_createHttpRequest', 2);
|
||||
$agent->SimpleUserAgent();
|
||||
$agent->setMaximumRedirects(1);
|
||||
$response = &$agent->fetchResponse(new SimpleUrl('one.html'), new SimplePostEncoding());
|
||||
}
|
||||
}
|
||||
|
||||
class TestOfBadHosts extends UnitTestCase {
|
||||
|
||||
function &_createSimulatedBadHost() {
|
||||
$response = &new MockSimpleHttpResponse();
|
||||
$response->setReturnValue('isError', true);
|
||||
$response->setReturnValue('getError', 'Bad socket');
|
||||
$response->setReturnValue('getContent', false);
|
||||
|
||||
$request = &new MockSimpleHttpRequest();
|
||||
$request->setReturnReference('fetch', $response);
|
||||
return $request;
|
||||
}
|
||||
|
||||
function testUntestedHost() {
|
||||
$request = &$this->_createSimulatedBadHost();
|
||||
|
||||
$agent = &new MockRequestUserAgent();
|
||||
$agent->setReturnReference('_createHttpRequest', $request);
|
||||
$agent->SimpleUserAgent();
|
||||
|
||||
$response = &$agent->fetchResponse(
|
||||
new SimpleUrl('http://this.host/this/path/page.html'),
|
||||
new SimpleGetEncoding());
|
||||
$this->assertTrue($response->isError());
|
||||
}
|
||||
}
|
||||
|
||||
class TestOfAuthorisation extends UnitTestCase {
|
||||
|
||||
function testAuthenticateHeaderAdded() {
|
||||
$response = &new MockSimpleHttpResponse();
|
||||
$response->setReturnReference('getHeaders', new MockSimpleHttpHeaders());
|
||||
|
||||
$request = &new MockSimpleHttpRequest();
|
||||
$request->setReturnReference('fetch', $response);
|
||||
$request->expectOnce(
|
||||
'addHeaderLine',
|
||||
array('Authorization: Basic ' . base64_encode('test:secret')));
|
||||
|
||||
$agent = &new MockRequestUserAgent();
|
||||
$agent->setReturnReference('_createHttpRequest', $request);
|
||||
$agent->SimpleUserAgent();
|
||||
$response = &$agent->fetchResponse(
|
||||
new SimpleUrl('http://test:secret@this.host'),
|
||||
new SimpleGetEncoding());
|
||||
}
|
||||
}
|
||||
?>
|
||||
495
tests/simpletest/test/visual_test.php
Normal file
495
tests/simpletest/test/visual_test.php
Normal file
|
|
@ -0,0 +1,495 @@
|
|||
<?php
|
||||
// $Id: visual_test.php 1547 2007-07-04 00:42:05Z lastcraft $
|
||||
|
||||
// NOTE:
|
||||
// Some of these tests are designed to fail! Do not be alarmed.
|
||||
// ----------------
|
||||
|
||||
// The following tests are a bit hacky. Whilst Kent Beck tried to
|
||||
// build a unit tester with a unit tester, I am not that brave.
|
||||
// Instead I have just hacked together odd test scripts until
|
||||
// I have enough of a tester to procede more formally.
|
||||
//
|
||||
// The proper tests start in all_tests.php
|
||||
require_once('../unit_tester.php');
|
||||
require_once('../shell_tester.php');
|
||||
require_once('../mock_objects.php');
|
||||
require_once('../reporter.php');
|
||||
require_once('../xml.php');
|
||||
|
||||
class TestDisplayClass {
|
||||
var $_a;
|
||||
|
||||
function TestDisplayClass($a) {
|
||||
$this->_a = $a;
|
||||
}
|
||||
}
|
||||
|
||||
class PassingUnitTestCaseOutput extends UnitTestCase {
|
||||
|
||||
function testOfResults() {
|
||||
$this->pass('Pass');
|
||||
}
|
||||
|
||||
function testTrue() {
|
||||
$this->assertTrue(true);
|
||||
}
|
||||
|
||||
function testFalse() {
|
||||
$this->assertFalse(false);
|
||||
}
|
||||
|
||||
function testExpectation() {
|
||||
$expectation = &new EqualExpectation(25, 'My expectation message: %s');
|
||||
$this->assert($expectation, 25, 'My assert message : %s');
|
||||
}
|
||||
|
||||
function testNull() {
|
||||
$this->assertNull(null, "%s -> Pass");
|
||||
$this->assertNotNull(false, "%s -> Pass");
|
||||
}
|
||||
|
||||
function testType() {
|
||||
$this->assertIsA("hello", "string", "%s -> Pass");
|
||||
$this->assertIsA($this, "PassingUnitTestCaseOutput", "%s -> Pass");
|
||||
$this->assertIsA($this, "UnitTestCase", "%s -> Pass");
|
||||
}
|
||||
|
||||
function testTypeEquality() {
|
||||
$this->assertEqual("0", 0, "%s -> Pass");
|
||||
}
|
||||
|
||||
function testNullEquality() {
|
||||
$this->assertNotEqual(null, 1, "%s -> Pass");
|
||||
$this->assertNotEqual(1, null, "%s -> Pass");
|
||||
}
|
||||
|
||||
function testIntegerEquality() {
|
||||
$this->assertNotEqual(1, 2, "%s -> Pass");
|
||||
}
|
||||
|
||||
function testStringEquality() {
|
||||
$this->assertEqual("a", "a", "%s -> Pass");
|
||||
$this->assertNotEqual("aa", "ab", "%s -> Pass");
|
||||
}
|
||||
|
||||
function testHashEquality() {
|
||||
$this->assertEqual(array("a" => "A", "b" => "B"), array("b" => "B", "a" => "A"), "%s -> Pass");
|
||||
}
|
||||
|
||||
function testWithin() {
|
||||
$this->assertWithinMargin(5, 5.4, 0.5, "%s -> Pass");
|
||||
}
|
||||
|
||||
function testOutside() {
|
||||
$this->assertOutsideMargin(5, 5.6, 0.5, "%s -> Pass");
|
||||
}
|
||||
|
||||
function testStringIdentity() {
|
||||
$a = "fred";
|
||||
$b = $a;
|
||||
$this->assertIdentical($a, $b, "%s -> Pass");
|
||||
}
|
||||
|
||||
function testTypeIdentity() {
|
||||
$a = "0";
|
||||
$b = 0;
|
||||
$this->assertNotIdentical($a, $b, "%s -> Pass");
|
||||
}
|
||||
|
||||
function testNullIdentity() {
|
||||
$this->assertNotIdentical(null, 1, "%s -> Pass");
|
||||
$this->assertNotIdentical(1, null, "%s -> Pass");
|
||||
}
|
||||
|
||||
function testHashIdentity() {
|
||||
}
|
||||
|
||||
function testObjectEquality() {
|
||||
$this->assertEqual(new TestDisplayClass(4), new TestDisplayClass(4), "%s -> Pass");
|
||||
$this->assertNotEqual(new TestDisplayClass(4), new TestDisplayClass(5), "%s -> Pass");
|
||||
}
|
||||
|
||||
function testObjectIndentity() {
|
||||
$this->assertIdentical(new TestDisplayClass(false), new TestDisplayClass(false), "%s -> Pass");
|
||||
$this->assertNotIdentical(new TestDisplayClass(false), new TestDisplayClass(0), "%s -> Pass");
|
||||
}
|
||||
|
||||
function testReference() {
|
||||
$a = "fred";
|
||||
$b = &$a;
|
||||
$this->assertReference($a, $b, "%s -> Pass");
|
||||
}
|
||||
|
||||
function testCloneOnDifferentObjects() {
|
||||
$a = "fred";
|
||||
$b = $a;
|
||||
$c = "Hello";
|
||||
$this->assertClone($a, $b, "%s -> Pass");
|
||||
}
|
||||
|
||||
function testPatterns() {
|
||||
$this->assertPattern('/hello/i', "Hello there", "%s -> Pass");
|
||||
$this->assertNoPattern('/hello/', "Hello there", "%s -> Pass");
|
||||
}
|
||||
|
||||
function testLongStrings() {
|
||||
$text = "";
|
||||
for ($i = 0; $i < 10; $i++) {
|
||||
$text .= "0123456789";
|
||||
}
|
||||
$this->assertEqual($text, $text);
|
||||
}
|
||||
}
|
||||
|
||||
class FailingUnitTestCaseOutput extends UnitTestCase {
|
||||
|
||||
function testOfResults() {
|
||||
$this->fail('Fail'); // Fail.
|
||||
}
|
||||
|
||||
function testTrue() {
|
||||
$this->assertTrue(false); // Fail.
|
||||
}
|
||||
|
||||
function testFalse() {
|
||||
$this->assertFalse(true); // Fail.
|
||||
}
|
||||
|
||||
function testExpectation() {
|
||||
$expectation = &new EqualExpectation(25, 'My expectation message: %s');
|
||||
$this->assert($expectation, 24, 'My assert message : %s'); // Fail.
|
||||
}
|
||||
|
||||
function testNull() {
|
||||
$this->assertNull(false, "%s -> Fail"); // Fail.
|
||||
$this->assertNotNull(null, "%s -> Fail"); // Fail.
|
||||
}
|
||||
|
||||
function testType() {
|
||||
$this->assertIsA(14, "string", "%s -> Fail"); // Fail.
|
||||
$this->assertIsA(14, "TestOfUnitTestCaseOutput", "%s -> Fail"); // Fail.
|
||||
$this->assertIsA($this, "TestReporter", "%s -> Fail"); // Fail.
|
||||
}
|
||||
|
||||
function testTypeEquality() {
|
||||
$this->assertNotEqual("0", 0, "%s -> Fail"); // Fail.
|
||||
}
|
||||
|
||||
function testNullEquality() {
|
||||
$this->assertEqual(null, 1, "%s -> Fail"); // Fail.
|
||||
$this->assertEqual(1, null, "%s -> Fail"); // Fail.
|
||||
}
|
||||
|
||||
function testIntegerEquality() {
|
||||
$this->assertEqual(1, 2, "%s -> Fail"); // Fail.
|
||||
}
|
||||
|
||||
function testStringEquality() {
|
||||
$this->assertNotEqual("a", "a", "%s -> Fail"); // Fail.
|
||||
$this->assertEqual("aa", "ab", "%s -> Fail"); // Fail.
|
||||
}
|
||||
|
||||
function testHashEquality() {
|
||||
$this->assertEqual(array("a" => "A", "b" => "B"), array("b" => "B", "a" => "Z"), "%s -> Fail");
|
||||
}
|
||||
|
||||
function testWithin() {
|
||||
$this->assertWithinMargin(5, 5.6, 0.5, "%s -> Fail"); // Fail.
|
||||
}
|
||||
|
||||
function testOutside() {
|
||||
$this->assertOutsideMargin(5, 5.4, 0.5, "%s -> Fail"); // Fail.
|
||||
}
|
||||
|
||||
function testStringIdentity() {
|
||||
$a = "fred";
|
||||
$b = $a;
|
||||
$this->assertNotIdentical($a, $b, "%s -> Fail"); // Fail.
|
||||
}
|
||||
|
||||
function testTypeIdentity() {
|
||||
$a = "0";
|
||||
$b = 0;
|
||||
$this->assertIdentical($a, $b, "%s -> Fail"); // Fail.
|
||||
}
|
||||
|
||||
function testNullIdentity() {
|
||||
$this->assertIdentical(null, 1, "%s -> Fail"); // Fail.
|
||||
$this->assertIdentical(1, null, "%s -> Fail"); // Fail.
|
||||
}
|
||||
|
||||
function testHashIdentity() {
|
||||
$this->assertIdentical(array("a" => "A", "b" => "B"), array("b" => "B", "a" => "A"), "%s -> fail"); // Fail.
|
||||
}
|
||||
|
||||
function testObjectEquality() {
|
||||
$this->assertNotEqual(new TestDisplayClass(4), new TestDisplayClass(4), "%s -> Fail"); // Fail.
|
||||
$this->assertEqual(new TestDisplayClass(4), new TestDisplayClass(5), "%s -> Fail"); // Fail.
|
||||
}
|
||||
|
||||
function testObjectIndentity() {
|
||||
$this->assertNotIdentical(new TestDisplayClass(false), new TestDisplayClass(false), "%s -> Fail"); // Fail.
|
||||
$this->assertIdentical(new TestDisplayClass(false), new TestDisplayClass(0), "%s -> Fail"); // Fail.
|
||||
}
|
||||
|
||||
function testReference() {
|
||||
$a = "fred";
|
||||
$b = &$a;
|
||||
$this->assertClone($a, $b, "%s -> Fail"); // Fail.
|
||||
}
|
||||
|
||||
function testCloneOnDifferentObjects() {
|
||||
$a = "fred";
|
||||
$b = $a;
|
||||
$c = "Hello";
|
||||
$this->assertClone($a, $c, "%s -> Fail"); // Fail.
|
||||
}
|
||||
|
||||
function testPatterns() {
|
||||
$this->assertPattern('/hello/', "Hello there", "%s -> Fail"); // Fail.
|
||||
$this->assertNoPattern('/hello/i', "Hello there", "%s -> Fail"); // Fail.
|
||||
}
|
||||
|
||||
function testLongStrings() {
|
||||
$text = "";
|
||||
for ($i = 0; $i < 10; $i++) {
|
||||
$text .= "0123456789";
|
||||
}
|
||||
$this->assertEqual($text . $text, $text . "a" . $text); // Fail.
|
||||
}
|
||||
}
|
||||
|
||||
class Dummy {
|
||||
function Dummy() {
|
||||
}
|
||||
|
||||
function a() {
|
||||
}
|
||||
}
|
||||
Mock::generate('Dummy');
|
||||
|
||||
class TestOfMockObjectsOutput extends UnitTestCase {
|
||||
|
||||
function testCallCounts() {
|
||||
$dummy = &new MockDummy();
|
||||
$dummy->expectCallCount('a', 1, 'My message: %s');
|
||||
$dummy->a();
|
||||
$dummy->a();
|
||||
}
|
||||
|
||||
function testMinimumCallCounts() {
|
||||
$dummy = &new MockDummy();
|
||||
$dummy->expectMinimumCallCount('a', 2, 'My message: %s');
|
||||
$dummy->a();
|
||||
$dummy->a();
|
||||
}
|
||||
|
||||
function testEmptyMatching() {
|
||||
$dummy = &new MockDummy();
|
||||
$dummy->expectArguments('a', array());
|
||||
$dummy->a();
|
||||
$dummy->a(null); // Fail.
|
||||
}
|
||||
|
||||
function testEmptyMatchingWithCustomMessage() {
|
||||
$dummy = &new MockDummy();
|
||||
$dummy->expectArguments('a', array(), 'My expectation message: %s');
|
||||
$dummy->a();
|
||||
$dummy->a(null); // Fail.
|
||||
}
|
||||
|
||||
function testNullMatching() {
|
||||
$dummy = &new MockDummy();
|
||||
$dummy->expectArguments('a', array(null));
|
||||
$dummy->a(null);
|
||||
$dummy->a(); // Fail.
|
||||
}
|
||||
|
||||
function testBooleanMatching() {
|
||||
$dummy = &new MockDummy();
|
||||
$dummy->expectArguments('a', array(true, false));
|
||||
$dummy->a(true, false);
|
||||
$dummy->a(true, true); // Fail.
|
||||
}
|
||||
|
||||
function testIntegerMatching() {
|
||||
$dummy = &new MockDummy();
|
||||
$dummy->expectArguments('a', array(32, 33));
|
||||
$dummy->a(32, 33);
|
||||
$dummy->a(32, 34); // Fail.
|
||||
}
|
||||
|
||||
function testFloatMatching() {
|
||||
$dummy = &new MockDummy();
|
||||
$dummy->expectArguments('a', array(3.2, 3.3));
|
||||
$dummy->a(3.2, 3.3);
|
||||
$dummy->a(3.2, 3.4); // Fail.
|
||||
}
|
||||
|
||||
function testStringMatching() {
|
||||
$dummy = &new MockDummy();
|
||||
$dummy->expectArguments('a', array('32', '33'));
|
||||
$dummy->a('32', '33');
|
||||
$dummy->a('32', '34'); // Fail.
|
||||
}
|
||||
|
||||
function testEmptyMatchingWithCustomExpectationMessage() {
|
||||
$dummy = &new MockDummy();
|
||||
$dummy->expectArguments(
|
||||
'a',
|
||||
array(new EqualExpectation('A', 'My part expectation message: %s')),
|
||||
'My expectation message: %s');
|
||||
$dummy->a('A');
|
||||
$dummy->a('B'); // Fail.
|
||||
}
|
||||
|
||||
function testArrayMatching() {
|
||||
$dummy = &new MockDummy();
|
||||
$dummy->expectArguments('a', array(array(32), array(33)));
|
||||
$dummy->a(array(32), array(33));
|
||||
$dummy->a(array(32), array('33')); // Fail.
|
||||
}
|
||||
|
||||
function testObjectMatching() {
|
||||
$a = new Dummy();
|
||||
$a->a = 'a';
|
||||
$b = new Dummy();
|
||||
$b->b = 'b';
|
||||
$dummy = &new MockDummy();
|
||||
$dummy->expectArguments('a', array($a, $b));
|
||||
$dummy->a($a, $b);
|
||||
$dummy->a($a, $a); // Fail.
|
||||
}
|
||||
|
||||
function testBigList() {
|
||||
$dummy = &new MockDummy();
|
||||
$dummy->expectArguments('a', array(false, 0, 1, 1.0));
|
||||
$dummy->a(false, 0, 1, 1.0);
|
||||
$dummy->a(true, false, 2, 2.0); // Fail.
|
||||
}
|
||||
}
|
||||
|
||||
class TestOfPastBugs extends UnitTestCase {
|
||||
|
||||
function testMixedTypes() {
|
||||
$this->assertEqual(array(), null, "%s -> Pass");
|
||||
$this->assertIdentical(array(), null, "%s -> Fail"); // Fail.
|
||||
}
|
||||
|
||||
function testMockWildcards() {
|
||||
$dummy = &new MockDummy();
|
||||
$dummy->expectArguments('a', array('*', array(33)));
|
||||
$dummy->a(array(32), array(33));
|
||||
$dummy->a(array(32), array('33')); // Fail.
|
||||
}
|
||||
}
|
||||
|
||||
class TestOfVisualShell extends ShellTestCase {
|
||||
|
||||
function testDump() {
|
||||
$this->execute('ls');
|
||||
$this->dumpOutput();
|
||||
$this->execute('dir');
|
||||
$this->dumpOutput();
|
||||
}
|
||||
|
||||
function testDumpOfList() {
|
||||
$this->execute('ls');
|
||||
$this->dump($this->getOutputAsList());
|
||||
}
|
||||
}
|
||||
|
||||
class PassesAsWellReporter extends HtmlReporter {
|
||||
|
||||
function _getCss() {
|
||||
return parent::_getCss() . ' .pass { color: darkgreen; }';
|
||||
}
|
||||
|
||||
function paintPass($message) {
|
||||
parent::paintPass($message);
|
||||
print "<span class=\"pass\">Pass</span>: ";
|
||||
$breadcrumb = $this->getTestList();
|
||||
array_shift($breadcrumb);
|
||||
print implode(" -> ", $breadcrumb);
|
||||
print " -> " . htmlentities($message) . "<br />\n";
|
||||
}
|
||||
|
||||
function paintSignal($type, &$payload) {
|
||||
print "<span class=\"fail\">$type</span>: ";
|
||||
$breadcrumb = $this->getTestList();
|
||||
array_shift($breadcrumb);
|
||||
print implode(" -> ", $breadcrumb);
|
||||
print " -> " . htmlentities(serialize($payload)) . "<br />\n";
|
||||
}
|
||||
}
|
||||
|
||||
class TestOfSkippingNoMatterWhat extends UnitTestCase {
|
||||
function skip() {
|
||||
$this->skipIf(true, 'Always skipped -> %s');
|
||||
}
|
||||
|
||||
function testFail() {
|
||||
$this->fail('This really shouldn\'t have happened');
|
||||
}
|
||||
}
|
||||
|
||||
class TestOfSkippingOrElse extends UnitTestCase {
|
||||
function skip() {
|
||||
$this->skipUnless(false, 'Always skipped -> %s');
|
||||
}
|
||||
|
||||
function testFail() {
|
||||
$this->fail('This really shouldn\'t have happened');
|
||||
}
|
||||
}
|
||||
|
||||
class TestOfSkippingTwiceOver extends UnitTestCase {
|
||||
function skip() {
|
||||
$this->skipIf(true, 'First reason -> %s');
|
||||
$this->skipIf(true, 'Second reason -> %s');
|
||||
}
|
||||
|
||||
function testFail() {
|
||||
$this->fail('This really shouldn\'t have happened');
|
||||
}
|
||||
}
|
||||
|
||||
class TestThatShouldNotBeSkipped extends UnitTestCase {
|
||||
function skip() {
|
||||
$this->skipIf(false);
|
||||
$this->skipUnless(true);
|
||||
}
|
||||
|
||||
function testFail() {
|
||||
$this->fail('We should see this message');
|
||||
}
|
||||
|
||||
function testPass() {
|
||||
$this->pass('We should see this message');
|
||||
}
|
||||
}
|
||||
|
||||
$test = &new TestSuite('Visual test with 46 passes, 47 fails and 0 exceptions');
|
||||
$test->addTestCase(new PassingUnitTestCaseOutput());
|
||||
$test->addTestCase(new FailingUnitTestCaseOutput());
|
||||
$test->addTestCase(new TestOfMockObjectsOutput());
|
||||
$test->addTestCase(new TestOfPastBugs());
|
||||
$test->addTestCase(new TestOfVisualShell());
|
||||
$test->addTestCase(new TestOfSkippingNoMatterWhat());
|
||||
$test->addTestCase(new TestOfSkippingOrElse());
|
||||
$test->addTestCase(new TestOfSkippingTwiceOver());
|
||||
$test->addTestCase(new TestThatShouldNotBeSkipped());
|
||||
|
||||
if (isset($_GET['xml']) || in_array('xml', (isset($argv) ? $argv : array()))) {
|
||||
$reporter = &new XmlReporter();
|
||||
} elseif (TextReporter::inCli()) {
|
||||
$reporter = &new TextReporter();
|
||||
} else {
|
||||
$reporter = &new PassesAsWellReporter();
|
||||
}
|
||||
if (isset($_GET['dry']) || in_array('dry', (isset($argv) ? $argv : array()))) {
|
||||
$reporter->makeDry();
|
||||
}
|
||||
exit ($test->run($reporter) ? 0 : 1);
|
||||
?>
|
||||
156
tests/simpletest/test/web_tester_test.php
Normal file
156
tests/simpletest/test/web_tester_test.php
Normal file
|
|
@ -0,0 +1,156 @@
|
|||
<?php
|
||||
// $Id: web_tester_test.php 1509 2007-05-08 22:11:49Z lastcraft $
|
||||
require_once(dirname(__FILE__) . '/../autorun.php');
|
||||
require_once(dirname(__FILE__) . '/../web_tester.php');
|
||||
|
||||
class TestOfFieldExpectation extends UnitTestCase {
|
||||
|
||||
function testStringMatchingIsCaseSensitive() {
|
||||
$expectation = new FieldExpectation('a');
|
||||
$this->assertTrue($expectation->test('a'));
|
||||
$this->assertTrue($expectation->test(array('a')));
|
||||
$this->assertFalse($expectation->test('A'));
|
||||
}
|
||||
|
||||
function testMatchesInteger() {
|
||||
$expectation = new FieldExpectation('1');
|
||||
$this->assertTrue($expectation->test('1'));
|
||||
$this->assertTrue($expectation->test(1));
|
||||
$this->assertTrue($expectation->test(array('1')));
|
||||
$this->assertTrue($expectation->test(array(1)));
|
||||
}
|
||||
|
||||
function testNonStringFailsExpectation() {
|
||||
$expectation = new FieldExpectation('a');
|
||||
$this->assertFalse($expectation->test(null));
|
||||
}
|
||||
|
||||
function testUnsetFieldCanBeTestedFor() {
|
||||
$expectation = new FieldExpectation(false);
|
||||
$this->assertTrue($expectation->test(false));
|
||||
}
|
||||
|
||||
function testMultipleValuesCanBeInAnyOrder() {
|
||||
$expectation = new FieldExpectation(array('a', 'b'));
|
||||
$this->assertTrue($expectation->test(array('a', 'b')));
|
||||
$this->assertTrue($expectation->test(array('b', 'a')));
|
||||
$this->assertFalse($expectation->test(array('a', 'a')));
|
||||
$this->assertFalse($expectation->test('a'));
|
||||
}
|
||||
|
||||
function testSingleItemCanBeArrayOrString() {
|
||||
$expectation = new FieldExpectation(array('a'));
|
||||
$this->assertTrue($expectation->test(array('a')));
|
||||
$this->assertTrue($expectation->test('a'));
|
||||
}
|
||||
}
|
||||
|
||||
class TestOfHeaderExpectations extends UnitTestCase {
|
||||
|
||||
function testExpectingOnlyTheHeaderName() {
|
||||
$expectation = new HttpHeaderExpectation('a');
|
||||
$this->assertIdentical($expectation->test(false), false);
|
||||
$this->assertIdentical($expectation->test('a: A'), true);
|
||||
$this->assertIdentical($expectation->test('A: A'), true);
|
||||
$this->assertIdentical($expectation->test('a: B'), true);
|
||||
$this->assertIdentical($expectation->test(' a : A '), true);
|
||||
}
|
||||
|
||||
function testHeaderValueAsWell() {
|
||||
$expectation = new HttpHeaderExpectation('a', 'A');
|
||||
$this->assertIdentical($expectation->test(false), false);
|
||||
$this->assertIdentical($expectation->test('a: A'), true);
|
||||
$this->assertIdentical($expectation->test('A: A'), true);
|
||||
$this->assertIdentical($expectation->test('A: a'), false);
|
||||
$this->assertIdentical($expectation->test('a: B'), false);
|
||||
$this->assertIdentical($expectation->test(' a : A '), true);
|
||||
$this->assertIdentical($expectation->test(' a : AB '), false);
|
||||
}
|
||||
|
||||
function testHeaderValueWithColons() {
|
||||
$expectation = new HttpHeaderExpectation('a', 'A:B:C');
|
||||
$this->assertIdentical($expectation->test('a: A'), false);
|
||||
$this->assertIdentical($expectation->test('a: A:B'), false);
|
||||
$this->assertIdentical($expectation->test('a: A:B:C'), true);
|
||||
$this->assertIdentical($expectation->test('a: A:B:C:D'), false);
|
||||
}
|
||||
|
||||
function testMultilineSearch() {
|
||||
$expectation = new HttpHeaderExpectation('a', 'A');
|
||||
$this->assertIdentical($expectation->test("aa: A\r\nb: B\r\nc: C"), false);
|
||||
$this->assertIdentical($expectation->test("aa: A\r\na: A\r\nb: B"), true);
|
||||
}
|
||||
|
||||
function testMultilineSearchWithPadding() {
|
||||
$expectation = new HttpHeaderExpectation('a', ' A ');
|
||||
$this->assertIdentical($expectation->test("aa:A\r\nb:B\r\nc:C"), false);
|
||||
$this->assertIdentical($expectation->test("aa:A\r\na:A\r\nb:B"), true);
|
||||
}
|
||||
|
||||
function testPatternMatching() {
|
||||
$expectation = new HttpHeaderExpectation('a', new PatternExpectation('/A/'));
|
||||
$this->assertIdentical($expectation->test('a: A'), true);
|
||||
$this->assertIdentical($expectation->test('A: A'), true);
|
||||
$this->assertIdentical($expectation->test('A: a'), false);
|
||||
$this->assertIdentical($expectation->test('a: B'), false);
|
||||
$this->assertIdentical($expectation->test(' a : A '), true);
|
||||
$this->assertIdentical($expectation->test(' a : AB '), true);
|
||||
}
|
||||
|
||||
function testCaseInsensitivePatternMatching() {
|
||||
$expectation = new HttpHeaderExpectation('a', new PatternExpectation('/A/i'));
|
||||
$this->assertIdentical($expectation->test('a: a'), true);
|
||||
$this->assertIdentical($expectation->test('a: B'), false);
|
||||
$this->assertIdentical($expectation->test(' a : A '), true);
|
||||
$this->assertIdentical($expectation->test(' a : BAB '), true);
|
||||
$this->assertIdentical($expectation->test(' a : bab '), true);
|
||||
}
|
||||
|
||||
function testUnwantedHeader() {
|
||||
$expectation = new NoHttpHeaderExpectation('a');
|
||||
$this->assertIdentical($expectation->test(''), true);
|
||||
$this->assertIdentical($expectation->test('stuff'), true);
|
||||
$this->assertIdentical($expectation->test('b: B'), true);
|
||||
$this->assertIdentical($expectation->test('a: A'), false);
|
||||
$this->assertIdentical($expectation->test('A: A'), false);
|
||||
}
|
||||
|
||||
function testMultilineUnwantedSearch() {
|
||||
$expectation = new NoHttpHeaderExpectation('a');
|
||||
$this->assertIdentical($expectation->test("aa:A\r\nb:B\r\nc:C"), true);
|
||||
$this->assertIdentical($expectation->test("aa:A\r\na:A\r\nb:B"), false);
|
||||
}
|
||||
|
||||
function testLocationHeaderSplitsCorrectly() {
|
||||
$expectation = new HttpHeaderExpectation('Location', 'http://here/');
|
||||
$this->assertIdentical($expectation->test('Location: http://here/'), true);
|
||||
}
|
||||
}
|
||||
|
||||
class TestOfTextExpectations extends UnitTestCase {
|
||||
|
||||
function testMatchingSubString() {
|
||||
$expectation = new TextExpectation('wanted');
|
||||
$this->assertIdentical($expectation->test(''), false);
|
||||
$this->assertIdentical($expectation->test('Wanted'), false);
|
||||
$this->assertIdentical($expectation->test('wanted'), true);
|
||||
$this->assertIdentical($expectation->test('the wanted text is here'), true);
|
||||
}
|
||||
|
||||
function testNotMatchingSubString() {
|
||||
$expectation = new NoTextExpectation('wanted');
|
||||
$this->assertIdentical($expectation->test(''), true);
|
||||
$this->assertIdentical($expectation->test('Wanted'), true);
|
||||
$this->assertIdentical($expectation->test('wanted'), false);
|
||||
$this->assertIdentical($expectation->test('the wanted text is here'), false);
|
||||
}
|
||||
}
|
||||
|
||||
class TestOfGenericAssertionsInWebTester extends WebTestCase {
|
||||
|
||||
function testEquality() {
|
||||
$this->assertEqual('a', 'a');
|
||||
$this->assertNotEqual('a', 'A');
|
||||
}
|
||||
}
|
||||
?>
|
||||
187
tests/simpletest/test/xml_test.php
Normal file
187
tests/simpletest/test/xml_test.php
Normal file
|
|
@ -0,0 +1,187 @@
|
|||
<?php
|
||||
// $Id: xml_test.php 1509 2007-05-08 22:11:49Z lastcraft $
|
||||
require_once(dirname(__FILE__) . '/../autorun.php');
|
||||
require_once(dirname(__FILE__) . '/../xml.php');
|
||||
Mock::generate('SimpleScorer');
|
||||
|
||||
if (! function_exists('xml_parser_create')) {
|
||||
SimpleTest::ignore('TestOfXmlStructureParsing');
|
||||
SimpleTest::ignore('TestOfXmlResultsParsing');
|
||||
}
|
||||
|
||||
class TestOfNestingTags extends UnitTestCase {
|
||||
function testGroupSize() {
|
||||
$nesting = new NestingGroupTag(array('SIZE' => 2));
|
||||
$this->assertEqual($nesting->getSize(), 2);
|
||||
}
|
||||
}
|
||||
|
||||
class TestOfXmlStructureParsing extends UnitTestCase {
|
||||
function testValidXml() {
|
||||
$listener = &new MockSimpleScorer();
|
||||
$listener->expectNever('paintGroupStart');
|
||||
$listener->expectNever('paintGroupEnd');
|
||||
$listener->expectNever('paintCaseStart');
|
||||
$listener->expectNever('paintCaseEnd');
|
||||
$parser = &new SimpleTestXmlParser($listener);
|
||||
$this->assertTrue($parser->parse("<?xml version=\"1.0\"?>\n"));
|
||||
$this->assertTrue($parser->parse("<run>\n"));
|
||||
$this->assertTrue($parser->parse("</run>\n"));
|
||||
}
|
||||
|
||||
function testEmptyGroup() {
|
||||
$listener = &new MockSimpleScorer();
|
||||
$listener->expectOnce('paintGroupStart', array('a_group', 7));
|
||||
$listener->expectOnce('paintGroupEnd', array('a_group'));
|
||||
$parser = &new SimpleTestXmlParser($listener);
|
||||
$parser->parse("<?xml version=\"1.0\"?>\n");
|
||||
$parser->parse("<run>\n");
|
||||
$this->assertTrue($parser->parse("<group size=\"7\">\n"));
|
||||
$this->assertTrue($parser->parse("<name>a_group</name>\n"));
|
||||
$this->assertTrue($parser->parse("</group>\n"));
|
||||
$parser->parse("</run>\n");
|
||||
}
|
||||
|
||||
function testEmptyCase() {
|
||||
$listener = &new MockSimpleScorer();
|
||||
$listener->expectOnce('paintCaseStart', array('a_case'));
|
||||
$listener->expectOnce('paintCaseEnd', array('a_case'));
|
||||
$parser = &new SimpleTestXmlParser($listener);
|
||||
$parser->parse("<?xml version=\"1.0\"?>\n");
|
||||
$parser->parse("<run>\n");
|
||||
$this->assertTrue($parser->parse("<case>\n"));
|
||||
$this->assertTrue($parser->parse("<name>a_case</name>\n"));
|
||||
$this->assertTrue($parser->parse("</case>\n"));
|
||||
$parser->parse("</run>\n");
|
||||
}
|
||||
|
||||
function testEmptyMethod() {
|
||||
$listener = &new MockSimpleScorer();
|
||||
$listener->expectOnce('paintCaseStart', array('a_case'));
|
||||
$listener->expectOnce('paintCaseEnd', array('a_case'));
|
||||
$listener->expectOnce('paintMethodStart', array('a_method'));
|
||||
$listener->expectOnce('paintMethodEnd', array('a_method'));
|
||||
$parser = &new SimpleTestXmlParser($listener);
|
||||
$parser->parse("<?xml version=\"1.0\"?>\n");
|
||||
$parser->parse("<run>\n");
|
||||
$parser->parse("<case>\n");
|
||||
$parser->parse("<name>a_case</name>\n");
|
||||
$this->assertTrue($parser->parse("<test>\n"));
|
||||
$this->assertTrue($parser->parse("<name>a_method</name>\n"));
|
||||
$this->assertTrue($parser->parse("</test>\n"));
|
||||
$parser->parse("</case>\n");
|
||||
$parser->parse("</run>\n");
|
||||
}
|
||||
|
||||
function testNestedGroup() {
|
||||
$listener = &new MockSimpleScorer();
|
||||
$listener->expectArgumentsAt(0, 'paintGroupStart', array('a_group', 7));
|
||||
$listener->expectArgumentsAt(1, 'paintGroupStart', array('b_group', 3));
|
||||
$listener->expectCallCount('paintGroupStart', 2);
|
||||
$listener->expectArgumentsAt(0, 'paintGroupEnd', array('b_group'));
|
||||
$listener->expectArgumentsAt(1, 'paintGroupEnd', array('a_group'));
|
||||
$listener->expectCallCount('paintGroupEnd', 2);
|
||||
|
||||
$parser = &new SimpleTestXmlParser($listener);
|
||||
$parser->parse("<?xml version=\"1.0\"?>\n");
|
||||
$parser->parse("<run>\n");
|
||||
|
||||
$this->assertTrue($parser->parse("<group size=\"7\">\n"));
|
||||
$this->assertTrue($parser->parse("<name>a_group</name>\n"));
|
||||
$this->assertTrue($parser->parse("<group size=\"3\">\n"));
|
||||
$this->assertTrue($parser->parse("<name>b_group</name>\n"));
|
||||
$this->assertTrue($parser->parse("</group>\n"));
|
||||
$this->assertTrue($parser->parse("</group>\n"));
|
||||
$parser->parse("</run>\n");
|
||||
}
|
||||
}
|
||||
|
||||
class AnyOldSignal {
|
||||
var $stuff = true;
|
||||
}
|
||||
|
||||
class TestOfXmlResultsParsing extends UnitTestCase {
|
||||
|
||||
function sendValidStart(&$parser) {
|
||||
$parser->parse("<?xml version=\"1.0\"?>\n");
|
||||
$parser->parse("<run>\n");
|
||||
$parser->parse("<case>\n");
|
||||
$parser->parse("<name>a_case</name>\n");
|
||||
$parser->parse("<test>\n");
|
||||
$parser->parse("<name>a_method</name>\n");
|
||||
}
|
||||
|
||||
function sendValidEnd(&$parser) {
|
||||
$parser->parse("</test>\n");
|
||||
$parser->parse("</case>\n");
|
||||
$parser->parse("</run>\n");
|
||||
}
|
||||
|
||||
function testPass() {
|
||||
$listener = &new MockSimpleScorer();
|
||||
$listener->expectOnce('paintPass', array('a_message'));
|
||||
$parser = &new SimpleTestXmlParser($listener);
|
||||
$this->sendValidStart($parser);
|
||||
$this->assertTrue($parser->parse("<pass>a_message</pass>\n"));
|
||||
$this->sendValidEnd($parser);
|
||||
}
|
||||
|
||||
function testFail() {
|
||||
$listener = &new MockSimpleScorer();
|
||||
$listener->expectOnce('paintFail', array('a_message'));
|
||||
$parser = &new SimpleTestXmlParser($listener);
|
||||
$this->sendValidStart($parser);
|
||||
$this->assertTrue($parser->parse("<fail>a_message</fail>\n"));
|
||||
$this->sendValidEnd($parser);
|
||||
}
|
||||
|
||||
function testException() {
|
||||
$listener = &new MockSimpleScorer();
|
||||
$listener->expectOnce('paintError', array('a_message'));
|
||||
$parser = &new SimpleTestXmlParser($listener);
|
||||
$this->sendValidStart($parser);
|
||||
$this->assertTrue($parser->parse("<exception>a_message</exception>\n"));
|
||||
$this->sendValidEnd($parser);
|
||||
}
|
||||
|
||||
function testSkip() {
|
||||
$listener = &new MockSimpleScorer();
|
||||
$listener->expectOnce('paintSkip', array('a_message'));
|
||||
$parser = &new SimpleTestXmlParser($listener);
|
||||
$this->sendValidStart($parser);
|
||||
$this->assertTrue($parser->parse("<skip>a_message</skip>\n"));
|
||||
$this->sendValidEnd($parser);
|
||||
}
|
||||
|
||||
function testSignal() {
|
||||
$signal = new AnyOldSignal();
|
||||
$signal->stuff = "Hello";
|
||||
$listener = &new MockSimpleScorer();
|
||||
$listener->expectOnce('paintSignal', array('a_signal', $signal));
|
||||
$parser = &new SimpleTestXmlParser($listener);
|
||||
$this->sendValidStart($parser);
|
||||
$this->assertTrue($parser->parse(
|
||||
"<signal type=\"a_signal\"><![CDATA[" .
|
||||
serialize($signal) . "]]></signal>\n"));
|
||||
$this->sendValidEnd($parser);
|
||||
}
|
||||
|
||||
function testMessage() {
|
||||
$listener = &new MockSimpleScorer();
|
||||
$listener->expectOnce('paintMessage', array('a_message'));
|
||||
$parser = &new SimpleTestXmlParser($listener);
|
||||
$this->sendValidStart($parser);
|
||||
$this->assertTrue($parser->parse("<message>a_message</message>\n"));
|
||||
$this->sendValidEnd($parser);
|
||||
}
|
||||
|
||||
function testFormattedMessage() {
|
||||
$listener = &new MockSimpleScorer();
|
||||
$listener->expectOnce('paintFormattedMessage', array("\na\tmessage\n"));
|
||||
$parser = &new SimpleTestXmlParser($listener);
|
||||
$this->sendValidStart($parser);
|
||||
$this->assertTrue($parser->parse("<formatted><![CDATA[\na\tmessage\n]]></formatted>\n"));
|
||||
$this->sendValidEnd($parser);
|
||||
}
|
||||
}
|
||||
?>
|
||||
708
tests/simpletest/test_case.php
Normal file
708
tests/simpletest/test_case.php
Normal file
|
|
@ -0,0 +1,708 @@
|
|||
<?php
|
||||
/**
|
||||
* Base include file for SimpleTest
|
||||
* @package SimpleTest
|
||||
* @subpackage UnitTester
|
||||
* @version $Id: test_case.php 1726 2008-04-08 01:20:10Z lastcraft $
|
||||
*/
|
||||
|
||||
/**#@+
|
||||
* Includes SimpleTest files and defined the root constant
|
||||
* for dependent libraries.
|
||||
*/
|
||||
require_once(dirname(__FILE__) . '/invoker.php');
|
||||
require_once(dirname(__FILE__) . '/errors.php');
|
||||
require_once(dirname(__FILE__) . '/compatibility.php');
|
||||
require_once(dirname(__FILE__) . '/scorer.php');
|
||||
require_once(dirname(__FILE__) . '/expectation.php');
|
||||
require_once(dirname(__FILE__) . '/dumper.php');
|
||||
require_once(dirname(__FILE__) . '/simpletest.php');
|
||||
if (version_compare(phpversion(), '5') >= 0) {
|
||||
require_once(dirname(__FILE__) . '/exceptions.php');
|
||||
require_once(dirname(__FILE__) . '/reflection_php5.php');
|
||||
} else {
|
||||
require_once(dirname(__FILE__) . '/reflection_php4.php');
|
||||
}
|
||||
if (! defined('SIMPLE_TEST')) {
|
||||
/**
|
||||
* @ignore
|
||||
*/
|
||||
define('SIMPLE_TEST', dirname(__FILE__) . DIRECTORY_SEPARATOR);
|
||||
}
|
||||
/**#@-*/
|
||||
|
||||
/**
|
||||
* Basic test case. This is the smallest unit of a test
|
||||
* suite. It searches for
|
||||
* all methods that start with the the string "test" and
|
||||
* runs them. Working test cases extend this class.
|
||||
* @package SimpleTest
|
||||
* @subpackage UnitTester
|
||||
*/
|
||||
class SimpleTestCase {
|
||||
var $_label = false;
|
||||
var $_reporter;
|
||||
var $_observers;
|
||||
var $_should_skip = false;
|
||||
|
||||
/**
|
||||
* Sets up the test with no display.
|
||||
* @param string $label If no test name is given then
|
||||
* the class name is used.
|
||||
* @access public
|
||||
*/
|
||||
function SimpleTestCase($label = false) {
|
||||
if ($label) {
|
||||
$this->_label = $label;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for the test name for subclasses.
|
||||
* @return string Name of the test.
|
||||
* @access public
|
||||
*/
|
||||
function getLabel() {
|
||||
return $this->_label ? $this->_label : get_class($this);
|
||||
}
|
||||
|
||||
/**
|
||||
* This is a placeholder for skipping tests. In this
|
||||
* method you place skipIf() and skipUnless() calls to
|
||||
* set the skipping state.
|
||||
* @access public
|
||||
*/
|
||||
function skip() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Will issue a message to the reporter and tell the test
|
||||
* case to skip if the incoming flag is true.
|
||||
* @param string $should_skip Condition causing the tests to be skipped.
|
||||
* @param string $message Text of skip condition.
|
||||
* @access public
|
||||
*/
|
||||
function skipIf($should_skip, $message = '%s') {
|
||||
if ($should_skip && ! $this->_should_skip) {
|
||||
$this->_should_skip = true;
|
||||
$message = sprintf($message, 'Skipping [' . get_class($this) . ']');
|
||||
$this->_reporter->paintSkip($message . $this->getAssertionLine());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Will issue a message to the reporter and tell the test
|
||||
* case to skip if the incoming flag is false.
|
||||
* @param string $shouldnt_skip Condition causing the tests to be run.
|
||||
* @param string $message Text of skip condition.
|
||||
* @access public
|
||||
*/
|
||||
function skipUnless($shouldnt_skip, $message = false) {
|
||||
$this->skipIf(! $shouldnt_skip, $message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Used to invoke the single tests.
|
||||
* @return SimpleInvoker Individual test runner.
|
||||
* @access public
|
||||
*/
|
||||
function &createInvoker() {
|
||||
$invoker = &new SimpleErrorTrappingInvoker(new SimpleInvoker($this));
|
||||
if (version_compare(phpversion(), '5') >= 0) {
|
||||
$invoker = &new SimpleExceptionTrappingInvoker($invoker);
|
||||
}
|
||||
return $invoker;
|
||||
}
|
||||
|
||||
/**
|
||||
* Uses reflection to run every method within itself
|
||||
* starting with the string "test" unless a method
|
||||
* is specified.
|
||||
* @param SimpleReporter $reporter Current test reporter.
|
||||
* @return boolean True if all tests passed.
|
||||
* @access public
|
||||
*/
|
||||
function run(&$reporter) {
|
||||
$context = &SimpleTest::getContext();
|
||||
$context->setTest($this);
|
||||
$context->setReporter($reporter);
|
||||
$this->_reporter = &$reporter;
|
||||
$started = false;
|
||||
foreach ($this->getTests() as $method) {
|
||||
if ($reporter->shouldInvoke($this->getLabel(), $method)) {
|
||||
$this->skip();
|
||||
if ($this->_should_skip) {
|
||||
break;
|
||||
}
|
||||
if (! $started) {
|
||||
$reporter->paintCaseStart($this->getLabel());
|
||||
$started = true;
|
||||
}
|
||||
$invoker = &$this->_reporter->createInvoker($this->createInvoker());
|
||||
$invoker->before($method);
|
||||
$invoker->invoke($method);
|
||||
$invoker->after($method);
|
||||
}
|
||||
}
|
||||
if ($started) {
|
||||
$reporter->paintCaseEnd($this->getLabel());
|
||||
}
|
||||
unset($this->_reporter);
|
||||
return $reporter->getStatus();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a list of test names. Normally that will
|
||||
* be all internal methods that start with the
|
||||
* name "test". This method should be overridden
|
||||
* if you want a different rule.
|
||||
* @return array List of test names.
|
||||
* @access public
|
||||
*/
|
||||
function getTests() {
|
||||
$methods = array();
|
||||
foreach (get_class_methods(get_class($this)) as $method) {
|
||||
if ($this->_isTest($method)) {
|
||||
$methods[] = $method;
|
||||
}
|
||||
}
|
||||
return $methods;
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests to see if the method is a test that should
|
||||
* be run. Currently any method that starts with 'test'
|
||||
* is a candidate unless it is the constructor.
|
||||
* @param string $method Method name to try.
|
||||
* @return boolean True if test method.
|
||||
* @access protected
|
||||
*/
|
||||
function _isTest($method) {
|
||||
if (strtolower(substr($method, 0, 4)) == 'test') {
|
||||
return ! SimpleTestCompatibility::isA($this, strtolower($method));
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Announces the start of the test.
|
||||
* @param string $method Test method just started.
|
||||
* @access public
|
||||
*/
|
||||
function before($method) {
|
||||
$this->_reporter->paintMethodStart($method);
|
||||
$this->_observers = array();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets up unit test wide variables at the start
|
||||
* of each test method. To be overridden in
|
||||
* actual user test cases.
|
||||
* @access public
|
||||
*/
|
||||
function setUp() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Clears the data set in the setUp() method call.
|
||||
* To be overridden by the user in actual user test cases.
|
||||
* @access public
|
||||
*/
|
||||
function tearDown() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Announces the end of the test. Includes private clean up.
|
||||
* @param string $method Test method just finished.
|
||||
* @access public
|
||||
*/
|
||||
function after($method) {
|
||||
for ($i = 0; $i < count($this->_observers); $i++) {
|
||||
$this->_observers[$i]->atTestEnd($method, $this);
|
||||
}
|
||||
$this->_reporter->paintMethodEnd($method);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets up an observer for the test end.
|
||||
* @param object $observer Must have atTestEnd()
|
||||
* method.
|
||||
* @access public
|
||||
*/
|
||||
function tell(&$observer) {
|
||||
$this->_observers[] = &$observer;
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
*/
|
||||
function pass($message = "Pass") {
|
||||
if (! isset($this->_reporter)) {
|
||||
trigger_error('Can only make assertions within test methods');
|
||||
}
|
||||
$this->_reporter->paintPass(
|
||||
$message . $this->getAssertionLine());
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends a fail event with a message.
|
||||
* @param string $message Message to send.
|
||||
* @access public
|
||||
*/
|
||||
function fail($message = "Fail") {
|
||||
if (! isset($this->_reporter)) {
|
||||
trigger_error('Can only make assertions within test methods');
|
||||
}
|
||||
$this->_reporter->paintFail(
|
||||
$message . $this->getAssertionLine());
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Formats a PHP error and dispatches it to the
|
||||
* reporter.
|
||||
* @param integer $severity PHP error code.
|
||||
* @param string $message Text of error.
|
||||
* @param string $file File error occoured in.
|
||||
* @param integer $line Line number of error.
|
||||
* @access public
|
||||
*/
|
||||
function error($severity, $message, $file, $line) {
|
||||
if (! isset($this->_reporter)) {
|
||||
trigger_error('Can only make assertions within test methods');
|
||||
}
|
||||
$this->_reporter->paintError(
|
||||
"Unexpected PHP error [$message] severity [$severity] in [$file line $line]");
|
||||
}
|
||||
|
||||
/**
|
||||
* Formats an exception and dispatches it to the
|
||||
* reporter.
|
||||
* @param Exception $exception Object thrown.
|
||||
* @access public
|
||||
*/
|
||||
function exception($exception) {
|
||||
$this->_reporter->paintException($exception);
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
*/
|
||||
function signal($type, &$payload) {
|
||||
if (! isset($this->_reporter)) {
|
||||
trigger_error('Can only make assertions within test methods');
|
||||
}
|
||||
$this->_reporter->paintSignal($type, $payload);
|
||||
}
|
||||
|
||||
/**
|
||||
* Runs an expectation directly, for extending the
|
||||
* tests with new expectation classes.
|
||||
* @param SimpleExpectation $expectation Expectation subclass.
|
||||
* @param mixed $compare Value to compare.
|
||||
* @param string $message Message to display.
|
||||
* @return boolean True on pass
|
||||
* @access public
|
||||
*/
|
||||
function assert(&$expectation, $compare, $message = '%s') {
|
||||
if ($expectation->test($compare)) {
|
||||
return $this->pass(sprintf(
|
||||
$message,
|
||||
$expectation->overlayMessage($compare, $this->_reporter->getDumper())));
|
||||
} else {
|
||||
return $this->fail(sprintf(
|
||||
$message,
|
||||
$expectation->overlayMessage($compare, $this->_reporter->getDumper())));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
*/
|
||||
function assertExpectation(&$expectation, $compare, $message = '%s') {
|
||||
return $this->assert($expectation, $compare, $message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Uses a stack trace to find the line of an assertion.
|
||||
* @return string Line number of first assert*
|
||||
* method embedded in format string.
|
||||
* @access public
|
||||
*/
|
||||
function getAssertionLine() {
|
||||
$trace = new SimpleStackTrace(array('assert', 'expect', 'pass', 'fail', 'skip'));
|
||||
return $trace->traceMethod();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends a formatted dump of a variable to the
|
||||
* test suite for those emergency debugging
|
||||
* situations.
|
||||
* @param mixed $variable Variable to display.
|
||||
* @param string $message Message to display.
|
||||
* @return mixed The original variable.
|
||||
* @access public
|
||||
*/
|
||||
function dump($variable, $message = false) {
|
||||
$dumper = $this->_reporter->getDumper();
|
||||
$formatted = $dumper->dump($variable);
|
||||
if ($message) {
|
||||
$formatted = $message . "\n" . $formatted;
|
||||
}
|
||||
$this->_reporter->paintFormattedMessage($formatted);
|
||||
return $variable;
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
*/
|
||||
function sendMessage($message) {
|
||||
$this->_reporter->PaintMessage($message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for the number of subtests including myelf.
|
||||
* @return integer Number of test cases.
|
||||
* @access public
|
||||
* @static
|
||||
*/
|
||||
function getSize() {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Helps to extract test cases automatically from a file.
|
||||
*/
|
||||
class SimpleFileLoader {
|
||||
|
||||
/**
|
||||
* Builds a test suite from a library of test cases.
|
||||
* The new suite is composed into this one.
|
||||
* @param string $test_file File name of library with
|
||||
* test case classes.
|
||||
* @return TestSuite The new test suite.
|
||||
* @access public
|
||||
*/
|
||||
function &load($test_file) {
|
||||
$existing_classes = get_declared_classes();
|
||||
$existing_globals = get_defined_vars();
|
||||
include_once($test_file);
|
||||
$new_globals = get_defined_vars();
|
||||
$this->_makeFileVariablesGlobal($existing_globals, $new_globals);
|
||||
$new_classes = array_diff(get_declared_classes(), $existing_classes);
|
||||
if (empty($new_classes)) {
|
||||
$new_classes = $this->_scrapeClassesFromFile($test_file);
|
||||
}
|
||||
$classes = $this->selectRunnableTests($new_classes);
|
||||
$suite = &$this->createSuiteFromClasses($test_file, $classes);
|
||||
return $suite;
|
||||
}
|
||||
|
||||
/**
|
||||
* Imports new variables into the global namespace.
|
||||
* @param hash $existing Variables before the file was loaded.
|
||||
* @param hash $new Variables after the file was loaded.
|
||||
* @access private
|
||||
*/
|
||||
function _makeFileVariablesGlobal($existing, $new) {
|
||||
$globals = array_diff(array_keys($new), array_keys($existing));
|
||||
foreach ($globals as $global) {
|
||||
$_GLOBALS[$global] = $new[$global];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Lookup classnames from file contents, in case the
|
||||
* file may have been included before.
|
||||
* Note: This is probably too clever by half. Figuring this
|
||||
* out after a failed test case is going to be tricky for us,
|
||||
* never mind the user. A test case should not be included
|
||||
* twice anyway.
|
||||
* @param string $test_file File name with classes.
|
||||
* @access private
|
||||
*/
|
||||
function _scrapeClassesFromFile($test_file) {
|
||||
preg_match_all('~^\s*class\s+(\w+)(\s+(extends|implements)\s+\w+)*\s*\{~mi',
|
||||
file_get_contents($test_file),
|
||||
$matches );
|
||||
return $matches[1];
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates the incoming test cases. Skips abstract
|
||||
* and ignored classes.
|
||||
* @param array $candidates Candidate classes.
|
||||
* @return array New classes which are test
|
||||
* cases that shouldn't be ignored.
|
||||
* @access public
|
||||
*/
|
||||
function selectRunnableTests($candidates) {
|
||||
$classes = array();
|
||||
foreach ($candidates as $class) {
|
||||
if (TestSuite::getBaseTestCase($class)) {
|
||||
$reflection = new SimpleReflection($class);
|
||||
if ($reflection->isAbstract()) {
|
||||
SimpleTest::ignore($class);
|
||||
} else {
|
||||
$classes[] = $class;
|
||||
}
|
||||
}
|
||||
}
|
||||
return $classes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds a test suite from a class list.
|
||||
* @param string $title Title of new group.
|
||||
* @param array $classes Test classes.
|
||||
* @return TestSuite Group loaded with the new
|
||||
* test cases.
|
||||
* @access public
|
||||
*/
|
||||
function &createSuiteFromClasses($title, $classes) {
|
||||
if (count($classes) == 0) {
|
||||
$suite = &new BadTestSuite($title, "No runnable test cases in [$title]");
|
||||
return $suite;
|
||||
}
|
||||
SimpleTest::ignoreParentsIfIgnored($classes);
|
||||
$suite = &new TestSuite($title);
|
||||
foreach ($classes as $class) {
|
||||
if (! SimpleTest::isIgnored($class)) {
|
||||
$suite->addTestClass($class);
|
||||
}
|
||||
}
|
||||
return $suite;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This is a composite test class for combining
|
||||
* test cases and other RunnableTest classes into
|
||||
* a group test.
|
||||
* @package SimpleTest
|
||||
* @subpackage UnitTester
|
||||
*/
|
||||
class TestSuite {
|
||||
var $_label;
|
||||
var $_test_cases;
|
||||
|
||||
/**
|
||||
* Sets the name of the test suite.
|
||||
* @param string $label Name sent at the start and end
|
||||
* of the test.
|
||||
* @access public
|
||||
*/
|
||||
function TestSuite($label = false) {
|
||||
$this->_label = $label;
|
||||
$this->_test_cases = array();
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for the test name for subclasses. If the suite
|
||||
* wraps a single test case the label defaults to the name of that test.
|
||||
* @return string Name of the test.
|
||||
* @access public
|
||||
*/
|
||||
function getLabel() {
|
||||
if (! $this->_label) {
|
||||
return ($this->getSize() == 1) ?
|
||||
get_class($this->_test_cases[0]) : get_class($this);
|
||||
} else {
|
||||
return $this->_label;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
*/
|
||||
function addTestCase(&$test_case) {
|
||||
$this->_test_cases[] = &$test_case;
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
*/
|
||||
function addTestClass($class) {
|
||||
if (TestSuite::getBaseTestCase($class) == 'testsuite') {
|
||||
$this->_test_cases[] = &new $class();
|
||||
} else {
|
||||
$this->_test_cases[] = $class;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a test into the suite by instance or class. The class will
|
||||
* be instantiated if it's a test suite.
|
||||
* @param SimpleTestCase $test_case Suite or individual test
|
||||
* case implementing the
|
||||
* runnable test interface.
|
||||
* @access public
|
||||
*/
|
||||
function add(&$test_case) {
|
||||
if (! is_string($test_case)) {
|
||||
$this->_test_cases[] = &$test_case;
|
||||
} elseif (TestSuite::getBaseTestCase($class) == 'testsuite') {
|
||||
$this->_test_cases[] = &new $class();
|
||||
} else {
|
||||
$this->_test_cases[] = $class;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
*/
|
||||
function addTestFile($test_file) {
|
||||
$this->addFile($test_file);
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds a test suite from a library of test cases.
|
||||
* The new suite is composed into this one.
|
||||
* @param string $test_file File name of library with
|
||||
* test case classes.
|
||||
* @access public
|
||||
*/
|
||||
function addFile($test_file) {
|
||||
$extractor = new SimpleFileLoader();
|
||||
$this->add($extractor->load($test_file));
|
||||
}
|
||||
|
||||
/**
|
||||
* Delegates to a visiting collector to add test
|
||||
* files.
|
||||
* @param string $path Path to scan from.
|
||||
* @param SimpleCollector $collector Directory scanner.
|
||||
* @access public
|
||||
*/
|
||||
function collect($path, &$collector) {
|
||||
$collector->collect($this, $path);
|
||||
}
|
||||
|
||||
/**
|
||||
* Invokes run() on all of the held test cases, instantiating
|
||||
* them if necessary.
|
||||
* @param SimpleReporter $reporter Current test reporter.
|
||||
* @access public
|
||||
*/
|
||||
function run(&$reporter) {
|
||||
$reporter->paintGroupStart($this->getLabel(), $this->getSize());
|
||||
for ($i = 0, $count = count($this->_test_cases); $i < $count; $i++) {
|
||||
if (is_string($this->_test_cases[$i])) {
|
||||
$class = $this->_test_cases[$i];
|
||||
$test = &new $class();
|
||||
$test->run($reporter);
|
||||
unset($test);
|
||||
} else {
|
||||
$this->_test_cases[$i]->run($reporter);
|
||||
}
|
||||
}
|
||||
$reporter->paintGroupEnd($this->getLabel());
|
||||
return $reporter->getStatus();
|
||||
}
|
||||
|
||||
/**
|
||||
* Number of contained test cases.
|
||||
* @return integer Total count of cases in the group.
|
||||
* @access public
|
||||
*/
|
||||
function getSize() {
|
||||
$count = 0;
|
||||
foreach ($this->_test_cases as $case) {
|
||||
if (is_string($case)) {
|
||||
if (! SimpleTest::isIgnored($case)) {
|
||||
$count++;
|
||||
}
|
||||
} else {
|
||||
$count += $case->getSize();
|
||||
}
|
||||
}
|
||||
return $count;
|
||||
}
|
||||
|
||||
/**
|
||||
* Test to see if a class is derived from the
|
||||
* SimpleTestCase class.
|
||||
* @param string $class Class name.
|
||||
* @access public
|
||||
* @static
|
||||
*/
|
||||
function getBaseTestCase($class) {
|
||||
while ($class = get_parent_class($class)) {
|
||||
$class = strtolower($class);
|
||||
if ($class == 'simpletestcase' || $class == 'testsuite') {
|
||||
return $class;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @package SimpleTest
|
||||
* @subpackage UnitTester
|
||||
* @deprecated
|
||||
*/
|
||||
class GroupTest extends TestSuite { }
|
||||
|
||||
/**
|
||||
* This is a failing group test for when a test suite hasn't
|
||||
* loaded properly.
|
||||
* @package SimpleTest
|
||||
* @subpackage UnitTester
|
||||
*/
|
||||
class BadTestSuite {
|
||||
var $_label;
|
||||
var $_error;
|
||||
|
||||
/**
|
||||
* Sets the name of the test suite and error message.
|
||||
* @param string $label Name sent at the start and end
|
||||
* of the test.
|
||||
* @access public
|
||||
*/
|
||||
function BadTestSuite($label, $error) {
|
||||
$this->_label = $label;
|
||||
$this->_error = $error;
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for the test name for subclasses.
|
||||
* @return string Name of the test.
|
||||
* @access public
|
||||
*/
|
||||
function getLabel() {
|
||||
return $this->_label;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends a single error to the reporter.
|
||||
* @param SimpleReporter $reporter Current test reporter.
|
||||
* @access public
|
||||
*/
|
||||
function run(&$reporter) {
|
||||
$reporter->paintGroupStart($this->getLabel(), $this->getSize());
|
||||
$reporter->paintFail('Bad TestSuite [' . $this->getLabel() .
|
||||
'] with error [' . $this->_error . ']');
|
||||
$reporter->paintGroupEnd($this->getLabel());
|
||||
return $reporter->getStatus();
|
||||
}
|
||||
|
||||
/**
|
||||
* Number of contained test cases. Always zero.
|
||||
* @return integer Total count of cases in the group.
|
||||
* @access public
|
||||
*/
|
||||
function getSize() {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @package SimpleTest
|
||||
* @subpackage UnitTester
|
||||
* @deprecated
|
||||
*/
|
||||
class BadGroupTest extends BadTestSuite { }
|
||||
?>
|
||||
420
tests/simpletest/unit_tester.php
Normal file
420
tests/simpletest/unit_tester.php
Normal file
|
|
@ -0,0 +1,420 @@
|
|||
<?php
|
||||
/**
|
||||
* base include file for SimpleTest
|
||||
* @package SimpleTest
|
||||
* @subpackage UnitTester
|
||||
* @version $Id: unit_tester.php 1723 2008-04-08 00:34:10Z lastcraft $
|
||||
*/
|
||||
|
||||
/**#@+
|
||||
* include other SimpleTest class files
|
||||
*/
|
||||
require_once(dirname(__FILE__) . '/test_case.php');
|
||||
require_once(dirname(__FILE__) . '/dumper.php');
|
||||
/**#@-*/
|
||||
|
||||
/**
|
||||
* Standard unit test class for day to day testing
|
||||
* of PHP code XP style. Adds some useful standard
|
||||
* assertions.
|
||||
* @package SimpleTest
|
||||
* @subpackage UnitTester
|
||||
*/
|
||||
class UnitTestCase extends SimpleTestCase {
|
||||
|
||||
/**
|
||||
* Creates an empty test case. Should be subclassed
|
||||
* with test methods for a functional test case.
|
||||
* @param string $label Name of test case. Will use
|
||||
* the class name if none specified.
|
||||
* @access public
|
||||
*/
|
||||
function UnitTestCase($label = false) {
|
||||
if (! $label) {
|
||||
$label = get_class($this);
|
||||
}
|
||||
$this->SimpleTestCase($label);
|
||||
}
|
||||
|
||||
/**
|
||||
* Called from within the test methods to register
|
||||
* passes and failures.
|
||||
* @param boolean $result Pass on true.
|
||||
* @param string $message Message to display describing
|
||||
* the test state.
|
||||
* @return boolean True on pass
|
||||
* @access public
|
||||
*/
|
||||
function assertTrue($result, $message = false) {
|
||||
return $this->assert(new TrueExpectation(), $result, $message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Will be true on false and vice versa. False
|
||||
* is the PHP definition of false, so that null,
|
||||
* empty strings, zero and an empty array all count
|
||||
* as false.
|
||||
* @param boolean $result Pass on false.
|
||||
* @param string $message Message to display.
|
||||
* @return boolean True on pass
|
||||
* @access public
|
||||
*/
|
||||
function assertFalse($result, $message = '%s') {
|
||||
return $this->assert(new FalseExpectation(), $result, $message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Will be true if the value is null.
|
||||
* @param null $value Supposedly null value.
|
||||
* @param string $message Message to display.
|
||||
* @return boolean True on pass
|
||||
* @access public
|
||||
*/
|
||||
function assertNull($value, $message = '%s') {
|
||||
$dumper = &new SimpleDumper();
|
||||
$message = sprintf(
|
||||
$message,
|
||||
'[' . $dumper->describeValue($value) . '] should be null');
|
||||
return $this->assertTrue(! isset($value), $message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Will be true if the value is set.
|
||||
* @param mixed $value Supposedly set value.
|
||||
* @param string $message Message to display.
|
||||
* @return boolean True on pass.
|
||||
* @access public
|
||||
*/
|
||||
function assertNotNull($value, $message = '%s') {
|
||||
$dumper = &new SimpleDumper();
|
||||
$message = sprintf(
|
||||
$message,
|
||||
'[' . $dumper->describeValue($value) . '] should not be null');
|
||||
return $this->assertTrue(isset($value), $message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Type and class test. Will pass if class
|
||||
* matches the type name or is a subclass or
|
||||
* if not an object, but the type is correct.
|
||||
* @param mixed $object Object to test.
|
||||
* @param string $type Type name as string.
|
||||
* @param string $message Message to display.
|
||||
* @return boolean True on pass.
|
||||
* @access public
|
||||
*/
|
||||
function assertIsA($object, $type, $message = '%s') {
|
||||
return $this->assert(
|
||||
new IsAExpectation($type),
|
||||
$object,
|
||||
$message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Type and class mismatch test. Will pass if class
|
||||
* name or underling type does not match the one
|
||||
* specified.
|
||||
* @param mixed $object Object to test.
|
||||
* @param string $type Type name as string.
|
||||
* @param string $message Message to display.
|
||||
* @return boolean True on pass.
|
||||
* @access public
|
||||
*/
|
||||
function assertNotA($object, $type, $message = '%s') {
|
||||
return $this->assert(
|
||||
new NotAExpectation($type),
|
||||
$object,
|
||||
$message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Will trigger a pass if the two parameters have
|
||||
* the same value only. Otherwise a fail.
|
||||
* @param mixed $first Value to compare.
|
||||
* @param mixed $second Value to compare.
|
||||
* @param string $message Message to display.
|
||||
* @return boolean True on pass
|
||||
* @access public
|
||||
*/
|
||||
function assertEqual($first, $second, $message = '%s') {
|
||||
return $this->assert(
|
||||
new EqualExpectation($first),
|
||||
$second,
|
||||
$message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Will trigger a pass if the two parameters have
|
||||
* a different value. Otherwise a fail.
|
||||
* @param mixed $first Value to compare.
|
||||
* @param mixed $second Value to compare.
|
||||
* @param string $message Message to display.
|
||||
* @return boolean True on pass
|
||||
* @access public
|
||||
*/
|
||||
function assertNotEqual($first, $second, $message = '%s') {
|
||||
return $this->assert(
|
||||
new NotEqualExpectation($first),
|
||||
$second,
|
||||
$message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Will trigger a pass if the if the first parameter
|
||||
* is near enough to the second by the margin.
|
||||
* @param mixed $first Value to compare.
|
||||
* @param mixed $second Value to compare.
|
||||
* @param mixed $margin Fuzziness of match.
|
||||
* @param string $message Message to display.
|
||||
* @return boolean True on pass
|
||||
* @access public
|
||||
*/
|
||||
function assertWithinMargin($first, $second, $margin, $message = '%s') {
|
||||
return $this->assert(
|
||||
new WithinMarginExpectation($first, $margin),
|
||||
$second,
|
||||
$message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Will trigger a pass if the two parameters differ
|
||||
* by more than the margin.
|
||||
* @param mixed $first Value to compare.
|
||||
* @param mixed $second Value to compare.
|
||||
* @param mixed $margin Fuzziness of match.
|
||||
* @param string $message Message to display.
|
||||
* @return boolean True on pass
|
||||
* @access public
|
||||
*/
|
||||
function assertOutsideMargin($first, $second, $margin, $message = '%s') {
|
||||
return $this->assert(
|
||||
new OutsideMarginExpectation($first, $margin),
|
||||
$second,
|
||||
$message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Will trigger a pass if the two parameters have
|
||||
* the same value and same type. Otherwise a fail.
|
||||
* @param mixed $first Value to compare.
|
||||
* @param mixed $second Value to compare.
|
||||
* @param string $message Message to display.
|
||||
* @return boolean True on pass
|
||||
* @access public
|
||||
*/
|
||||
function assertIdentical($first, $second, $message = '%s') {
|
||||
return $this->assert(
|
||||
new IdenticalExpectation($first),
|
||||
$second,
|
||||
$message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Will trigger a pass if the two parameters have
|
||||
* the different value or different type.
|
||||
* @param mixed $first Value to compare.
|
||||
* @param mixed $second Value to compare.
|
||||
* @param string $message Message to display.
|
||||
* @return boolean True on pass
|
||||
* @access public
|
||||
*/
|
||||
function assertNotIdentical($first, $second, $message = '%s') {
|
||||
return $this->assert(
|
||||
new NotIdenticalExpectation($first),
|
||||
$second,
|
||||
$message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Will trigger a pass if both parameters refer
|
||||
* to the same object. Fail otherwise.
|
||||
* @param mixed $first Object reference to check.
|
||||
* @param mixed $second Hopefully the same object.
|
||||
* @param string $message Message to display.
|
||||
* @return boolean True on pass
|
||||
* @access public
|
||||
*/
|
||||
function assertReference(&$first, &$second, $message = '%s') {
|
||||
$dumper = &new SimpleDumper();
|
||||
$message = sprintf(
|
||||
$message,
|
||||
'[' . $dumper->describeValue($first) .
|
||||
'] and [' . $dumper->describeValue($second) .
|
||||
'] should reference the same object');
|
||||
return $this->assertTrue(
|
||||
SimpleTestCompatibility::isReference($first, $second),
|
||||
$message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Will trigger a pass if both parameters refer
|
||||
* to different objects. Fail otherwise. The objects
|
||||
* have to be identical though.
|
||||
* @param mixed $first Object reference to check.
|
||||
* @param mixed $second Hopefully not the same object.
|
||||
* @param string $message Message to display.
|
||||
* @return boolean True on pass
|
||||
* @access public
|
||||
*/
|
||||
function assertClone(&$first, &$second, $message = '%s') {
|
||||
$dumper = &new SimpleDumper();
|
||||
$message = sprintf(
|
||||
$message,
|
||||
'[' . $dumper->describeValue($first) .
|
||||
'] and [' . $dumper->describeValue($second) .
|
||||
'] should not be the same object');
|
||||
$identical = &new IdenticalExpectation($first);
|
||||
return $this->assertTrue(
|
||||
$identical->test($second) &&
|
||||
! SimpleTestCompatibility::isReference($first, $second),
|
||||
$message);
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
*/
|
||||
function assertCopy(&$first, &$second, $message = "%s") {
|
||||
$dumper = &new SimpleDumper();
|
||||
$message = sprintf(
|
||||
$message,
|
||||
"[" . $dumper->describeValue($first) .
|
||||
"] and [" . $dumper->describeValue($second) .
|
||||
"] should not be the same object");
|
||||
return $this->assertFalse(
|
||||
SimpleTestCompatibility::isReference($first, $second),
|
||||
$message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Will trigger a pass if the Perl regex pattern
|
||||
* is found in the subject. Fail otherwise.
|
||||
* @param string $pattern Perl regex to look for including
|
||||
* the regex delimiters.
|
||||
* @param string $subject String to search in.
|
||||
* @param string $message Message to display.
|
||||
* @return boolean True on pass
|
||||
* @access public
|
||||
*/
|
||||
function assertPattern($pattern, $subject, $message = '%s') {
|
||||
return $this->assert(
|
||||
new PatternExpectation($pattern),
|
||||
$subject,
|
||||
$message);
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
*/
|
||||
function assertWantedPattern($pattern, $subject, $message = '%s') {
|
||||
return $this->assertPattern($pattern, $subject, $message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Will trigger a pass if the perl regex pattern
|
||||
* is not present in subject. Fail if found.
|
||||
* @param string $pattern Perl regex to look for including
|
||||
* the regex delimiters.
|
||||
* @param string $subject String to search in.
|
||||
* @param string $message Message to display.
|
||||
* @return boolean True on pass
|
||||
* @access public
|
||||
*/
|
||||
function assertNoPattern($pattern, $subject, $message = '%s') {
|
||||
return $this->assert(
|
||||
new NoPatternExpectation($pattern),
|
||||
$subject,
|
||||
$message);
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
*/
|
||||
function assertNoUnwantedPattern($pattern, $subject, $message = '%s') {
|
||||
return $this->assertNoPattern($pattern, $subject, $message);
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
*/
|
||||
function swallowErrors() {
|
||||
$context = &SimpleTest::getContext();
|
||||
$queue = &$context->get('SimpleErrorQueue');
|
||||
$queue->clear();
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
*/
|
||||
function assertNoErrors($message = '%s') {
|
||||
$context = &SimpleTest::getContext();
|
||||
$queue = &$context->get('SimpleErrorQueue');
|
||||
return $queue->assertNoErrors($message);
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
*/
|
||||
function assertError($expected = false, $message = '%s') {
|
||||
$context = &SimpleTest::getContext();
|
||||
$queue = &$context->get('SimpleErrorQueue');
|
||||
return $queue->assertError($this->_coerceExpectation($expected), $message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepares for an error. If the error mismatches it
|
||||
* passes through, otherwise it is swallowed. Any
|
||||
* left over errors trigger failures.
|
||||
* @param SimpleExpectation/string $expected The error to match.
|
||||
* @param string $message Message on failure.
|
||||
* @access public
|
||||
*/
|
||||
function expectError($expected = false, $message = '%s') {
|
||||
$context = &SimpleTest::getContext();
|
||||
$queue = &$context->get('SimpleErrorQueue');
|
||||
$queue->expectError($this->_coerceExpectation($expected), $message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepares for an exception. If the error mismatches it
|
||||
* passes through, otherwise it is swallowed. Any
|
||||
* left over errors trigger failures.
|
||||
* @param SimpleExpectation/Exception $expected The error to match.
|
||||
* @param string $message Message on failure.
|
||||
* @access public
|
||||
*/
|
||||
function expectException($expected = false, $message = '%s') {
|
||||
$context = &SimpleTest::getContext();
|
||||
$queue = &$context->get('SimpleExceptionTrap');
|
||||
// :HACK: Directly substituting in seems to cause a segfault with
|
||||
// Zend Optimizer on some systems
|
||||
$line = $this->getAssertionLine();
|
||||
$queue->expectException($expected, $message . $line);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an equality expectation if the
|
||||
* object/value is not already some type
|
||||
* of expectation.
|
||||
* @param mixed $expected Expected value.
|
||||
* @return SimpleExpectation Expectation object.
|
||||
* @access private
|
||||
*/
|
||||
function _coerceExpectation($expected) {
|
||||
if ($expected == false) {
|
||||
return new TrueExpectation();
|
||||
}
|
||||
if (SimpleTestCompatibility::isA($expected, 'SimpleExpectation')) {
|
||||
return $expected;
|
||||
}
|
||||
return new EqualExpectation(
|
||||
is_string($expected) ? str_replace('%', '%%', $expected) : $expected);
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
*/
|
||||
function assertErrorPattern($pattern, $message = '%s') {
|
||||
return $this->assertError(new PatternExpectation($pattern), $message);
|
||||
}
|
||||
}
|
||||
?>
|
||||
528
tests/simpletest/url.php
Normal file
528
tests/simpletest/url.php
Normal file
|
|
@ -0,0 +1,528 @@
|
|||
<?php
|
||||
/**
|
||||
* base include file for SimpleTest
|
||||
* @package SimpleTest
|
||||
* @subpackage WebTester
|
||||
* @version $Id: url.php 1723 2008-04-08 00:34:10Z lastcraft $
|
||||
*/
|
||||
|
||||
/**#@+
|
||||
* include other SimpleTest class files
|
||||
*/
|
||||
require_once(dirname(__FILE__) . '/encoding.php');
|
||||
/**#@-*/
|
||||
|
||||
/**
|
||||
* URL parser to replace parse_url() PHP function which
|
||||
* got broken in PHP 4.3.0. Adds some browser specific
|
||||
* functionality such as expandomatics.
|
||||
* Guesses a bit trying to separate the host from
|
||||
* the path and tries to keep a raw, possibly unparsable,
|
||||
* request string as long as possible.
|
||||
* @package SimpleTest
|
||||
* @subpackage WebTester
|
||||
*/
|
||||
class SimpleUrl {
|
||||
var $_scheme;
|
||||
var $_username;
|
||||
var $_password;
|
||||
var $_host;
|
||||
var $_port;
|
||||
var $_path;
|
||||
var $_request;
|
||||
var $_fragment;
|
||||
var $_x;
|
||||
var $_y;
|
||||
var $_target;
|
||||
var $_raw = false;
|
||||
|
||||
/**
|
||||
* Constructor. Parses URL into sections.
|
||||
* @param string $url Incoming URL.
|
||||
* @access public
|
||||
*/
|
||||
function SimpleUrl($url = '') {
|
||||
list($x, $y) = $this->_chompCoordinates($url);
|
||||
$this->setCoordinates($x, $y);
|
||||
$this->_scheme = $this->_chompScheme($url);
|
||||
list($this->_username, $this->_password) = $this->_chompLogin($url);
|
||||
$this->_host = $this->_chompHost($url);
|
||||
$this->_port = false;
|
||||
if (preg_match('/(.*?):(.*)/', $this->_host, $host_parts)) {
|
||||
$this->_host = $host_parts[1];
|
||||
$this->_port = (integer)$host_parts[2];
|
||||
}
|
||||
$this->_path = $this->_chompPath($url);
|
||||
$this->_request = $this->_parseRequest($this->_chompRequest($url));
|
||||
$this->_fragment = (strncmp($url, "#", 1) == 0 ? substr($url, 1) : false);
|
||||
$this->_target = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Extracts the X, Y coordinate pair from an image map.
|
||||
* @param string $url URL so far. The coordinates will be
|
||||
* removed.
|
||||
* @return array X, Y as a pair of integers.
|
||||
* @access private
|
||||
*/
|
||||
function _chompCoordinates(&$url) {
|
||||
if (preg_match('/(.*)\?(\d+),(\d+)$/', $url, $matches)) {
|
||||
$url = $matches[1];
|
||||
return array((integer)$matches[2], (integer)$matches[3]);
|
||||
}
|
||||
return array(false, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Extracts the scheme part of an incoming URL.
|
||||
* @param string $url URL so far. The scheme will be
|
||||
* removed.
|
||||
* @return string Scheme part or false.
|
||||
* @access private
|
||||
*/
|
||||
function _chompScheme(&$url) {
|
||||
if (preg_match('/^([^\/:]*):(\/\/)(.*)/', $url, $matches)) {
|
||||
$url = $matches[2] . $matches[3];
|
||||
return $matches[1];
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Extracts the username and password from the
|
||||
* incoming URL. The // prefix will be reattached
|
||||
* to the URL after the doublet is extracted.
|
||||
* @param string $url URL so far. The username and
|
||||
* password are removed.
|
||||
* @return array Two item list of username and
|
||||
* password. Will urldecode() them.
|
||||
* @access private
|
||||
*/
|
||||
function _chompLogin(&$url) {
|
||||
$prefix = '';
|
||||
if (preg_match('/^(\/\/)(.*)/', $url, $matches)) {
|
||||
$prefix = $matches[1];
|
||||
$url = $matches[2];
|
||||
}
|
||||
if (preg_match('/^([^\/]*)@(.*)/', $url, $matches)) {
|
||||
$url = $prefix . $matches[2];
|
||||
$parts = split(":", $matches[1]);
|
||||
return array(
|
||||
urldecode($parts[0]),
|
||||
isset($parts[1]) ? urldecode($parts[1]) : false);
|
||||
}
|
||||
$url = $prefix . $url;
|
||||
return array(false, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Extracts the host part of an incoming URL.
|
||||
* Includes the port number part. Will extract
|
||||
* the host if it starts with // or it has
|
||||
* a top level domain or it has at least two
|
||||
* dots.
|
||||
* @param string $url URL so far. The host will be
|
||||
* removed.
|
||||
* @return string Host part guess or false.
|
||||
* @access private
|
||||
*/
|
||||
function _chompHost(&$url) {
|
||||
if (preg_match('/^(\/\/)(.*?)(\/.*|\?.*|#.*|$)/', $url, $matches)) {
|
||||
$url = $matches[3];
|
||||
return $matches[2];
|
||||
}
|
||||
if (preg_match('/(.*?)(\.\.\/|\.\/|\/|\?|#|$)(.*)/', $url, $matches)) {
|
||||
$tlds = SimpleUrl::getAllTopLevelDomains();
|
||||
if (preg_match('/[a-z0-9\-]+\.(' . $tlds . ')/i', $matches[1])) {
|
||||
$url = $matches[2] . $matches[3];
|
||||
return $matches[1];
|
||||
} elseif (preg_match('/[a-z0-9\-]+\.[a-z0-9\-]+\.[a-z0-9\-]+/i', $matches[1])) {
|
||||
$url = $matches[2] . $matches[3];
|
||||
return $matches[1];
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Extracts the path information from the incoming
|
||||
* URL. Strips this path from the URL.
|
||||
* @param string $url URL so far. The host will be
|
||||
* removed.
|
||||
* @return string Path part or '/'.
|
||||
* @access private
|
||||
*/
|
||||
function _chompPath(&$url) {
|
||||
if (preg_match('/(.*?)(\?|#|$)(.*)/', $url, $matches)) {
|
||||
$url = $matches[2] . $matches[3];
|
||||
return ($matches[1] ? $matches[1] : '');
|
||||
}
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Strips off the request data.
|
||||
* @param string $url URL so far. The request will be
|
||||
* removed.
|
||||
* @return string Raw request part.
|
||||
* @access private
|
||||
*/
|
||||
function _chompRequest(&$url) {
|
||||
if (preg_match('/\?(.*?)(#|$)(.*)/', $url, $matches)) {
|
||||
$url = $matches[2] . $matches[3];
|
||||
return $matches[1];
|
||||
}
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Breaks the request down into an object.
|
||||
* @param string $raw Raw request.
|
||||
* @return SimpleFormEncoding Parsed data.
|
||||
* @access private
|
||||
*/
|
||||
function _parseRequest($raw) {
|
||||
$this->_raw = $raw;
|
||||
$request = new SimpleGetEncoding();
|
||||
foreach (split("&", $raw) as $pair) {
|
||||
if (preg_match('/(.*?)=(.*)/', $pair, $matches)) {
|
||||
$request->add($matches[1], urldecode($matches[2]));
|
||||
} elseif ($pair) {
|
||||
$request->add($pair, '');
|
||||
}
|
||||
}
|
||||
return $request;
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for protocol part.
|
||||
* @param string $default Value to use if not present.
|
||||
* @return string Scheme name, e.g "http".
|
||||
* @access public
|
||||
*/
|
||||
function getScheme($default = false) {
|
||||
return $this->_scheme ? $this->_scheme : $default;
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for user name.
|
||||
* @return string Username preceding host.
|
||||
* @access public
|
||||
*/
|
||||
function getUsername() {
|
||||
return $this->_username;
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for password.
|
||||
* @return string Password preceding host.
|
||||
* @access public
|
||||
*/
|
||||
function getPassword() {
|
||||
return $this->_password;
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for hostname and port.
|
||||
* @param string $default Value to use if not present.
|
||||
* @return string Hostname only.
|
||||
* @access public
|
||||
*/
|
||||
function getHost($default = false) {
|
||||
return $this->_host ? $this->_host : $default;
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for top level domain.
|
||||
* @return string Last part of host.
|
||||
* @access public
|
||||
*/
|
||||
function getTld() {
|
||||
$path_parts = pathinfo($this->getHost());
|
||||
return (isset($path_parts['extension']) ? $path_parts['extension'] : false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for port number.
|
||||
* @return integer TCP/IP port number.
|
||||
* @access public
|
||||
*/
|
||||
function getPort() {
|
||||
return $this->_port;
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for path.
|
||||
* @return string Full path including leading slash if implied.
|
||||
* @access public
|
||||
*/
|
||||
function getPath() {
|
||||
if (! $this->_path && $this->_host) {
|
||||
return '/';
|
||||
}
|
||||
return $this->_path;
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for page if any. This may be a
|
||||
* directory name if ambiguious.
|
||||
* @return Page name.
|
||||
* @access public
|
||||
*/
|
||||
function getPage() {
|
||||
if (! preg_match('/([^\/]*?)$/', $this->getPath(), $matches)) {
|
||||
return false;
|
||||
}
|
||||
return $matches[1];
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the path to the page.
|
||||
* @return string Path less the page.
|
||||
* @access public
|
||||
*/
|
||||
function getBasePath() {
|
||||
if (! preg_match('/(.*\/)[^\/]*?$/', $this->getPath(), $matches)) {
|
||||
return false;
|
||||
}
|
||||
return $matches[1];
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for fragment at end of URL after the "#".
|
||||
* @return string Part after "#".
|
||||
* @access public
|
||||
*/
|
||||
function getFragment() {
|
||||
return $this->_fragment;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets image coordinates. Set to false to clear
|
||||
* them.
|
||||
* @param integer $x Horizontal position.
|
||||
* @param integer $y Vertical position.
|
||||
* @access public
|
||||
*/
|
||||
function setCoordinates($x = false, $y = false) {
|
||||
if (($x === false) || ($y === false)) {
|
||||
$this->_x = $this->_y = false;
|
||||
return;
|
||||
}
|
||||
$this->_x = (integer)$x;
|
||||
$this->_y = (integer)$y;
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for horizontal image coordinate.
|
||||
* @return integer X value.
|
||||
* @access public
|
||||
*/
|
||||
function getX() {
|
||||
return $this->_x;
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for vertical image coordinate.
|
||||
* @return integer Y value.
|
||||
* @access public
|
||||
*/
|
||||
function getY() {
|
||||
return $this->_y;
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for current request parameters
|
||||
* in URL string form. Will return teh original request
|
||||
* if at all possible even if it doesn't make much
|
||||
* sense.
|
||||
* @return string Form is string "?a=1&b=2", etc.
|
||||
* @access public
|
||||
*/
|
||||
function getEncodedRequest() {
|
||||
if ($this->_raw) {
|
||||
$encoded = $this->_raw;
|
||||
} else {
|
||||
$encoded = $this->_request->asUrlRequest();
|
||||
}
|
||||
if ($encoded) {
|
||||
return '?' . preg_replace('/^\?/', '', $encoded);
|
||||
}
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds an additional parameter to the request.
|
||||
* @param string $key Name of parameter.
|
||||
* @param string $value Value as string.
|
||||
* @access public
|
||||
*/
|
||||
function addRequestParameter($key, $value) {
|
||||
$this->_raw = false;
|
||||
$this->_request->add($key, $value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds additional parameters to the request.
|
||||
* @param hash/SimpleFormEncoding $parameters Additional
|
||||
* parameters.
|
||||
* @access public
|
||||
*/
|
||||
function addRequestParameters($parameters) {
|
||||
$this->_raw = false;
|
||||
$this->_request->merge($parameters);
|
||||
}
|
||||
|
||||
/**
|
||||
* Clears down all parameters.
|
||||
* @access public
|
||||
*/
|
||||
function clearRequest() {
|
||||
$this->_raw = false;
|
||||
$this->_request = &new SimpleGetEncoding();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the frame target if present. Although
|
||||
* not strictly part of the URL specification it
|
||||
* acts as similarily to the browser.
|
||||
* @return boolean/string Frame name or false if none.
|
||||
* @access public
|
||||
*/
|
||||
function getTarget() {
|
||||
return $this->_target;
|
||||
}
|
||||
|
||||
/**
|
||||
* Attaches a frame target.
|
||||
* @param string $frame Name of frame.
|
||||
* @access public
|
||||
*/
|
||||
function setTarget($frame) {
|
||||
$this->_raw = false;
|
||||
$this->_target = $frame;
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders the URL back into a string.
|
||||
* @return string URL in canonical form.
|
||||
* @access public
|
||||
*/
|
||||
function asString() {
|
||||
$path = $this->_path;
|
||||
$scheme = $identity = $host = $encoded = $fragment = '';
|
||||
if ($this->_username && $this->_password) {
|
||||
$identity = $this->_username . ':' . $this->_password . '@';
|
||||
}
|
||||
if ($this->getHost()) {
|
||||
$scheme = $this->getScheme() ? $this->getScheme() : 'http';
|
||||
$scheme .= "://";
|
||||
$host = $this->getHost();
|
||||
}
|
||||
if (substr($this->_path, 0, 1) == '/') {
|
||||
$path = $this->normalisePath($this->_path);
|
||||
}
|
||||
$encoded = $this->getEncodedRequest();
|
||||
$fragment = $this->getFragment() ? '#'. $this->getFragment() : '';
|
||||
$coords = $this->getX() === false ? '' : '?' . $this->getX() . ',' . $this->getY();
|
||||
return "$scheme$identity$host$path$encoded$fragment$coords";
|
||||
}
|
||||
|
||||
/**
|
||||
* Replaces unknown sections to turn a relative
|
||||
* URL into an absolute one. The base URL can
|
||||
* be either a string or a SimpleUrl object.
|
||||
* @param string/SimpleUrl $base Base URL.
|
||||
* @access public
|
||||
*/
|
||||
function makeAbsolute($base) {
|
||||
if (! is_object($base)) {
|
||||
$base = new SimpleUrl($base);
|
||||
}
|
||||
if ($this->getHost()) {
|
||||
$scheme = $this->getScheme();
|
||||
$host = $this->getHost();
|
||||
$port = $this->getPort() ? ':' . $this->getPort() : '';
|
||||
$identity = $this->getIdentity() ? $this->getIdentity() . '@' : '';
|
||||
if (! $identity) {
|
||||
$identity = $base->getIdentity() ? $base->getIdentity() . '@' : '';
|
||||
}
|
||||
} else {
|
||||
$scheme = $base->getScheme();
|
||||
$host = $base->getHost();
|
||||
$port = $base->getPort() ? ':' . $base->getPort() : '';
|
||||
$identity = $base->getIdentity() ? $base->getIdentity() . '@' : '';
|
||||
}
|
||||
$path = $this->normalisePath($this->_extractAbsolutePath($base));
|
||||
$encoded = $this->getEncodedRequest();
|
||||
$fragment = $this->getFragment() ? '#'. $this->getFragment() : '';
|
||||
$coords = $this->getX() === false ? '' : '?' . $this->getX() . ',' . $this->getY();
|
||||
return new SimpleUrl("$scheme://$identity$host$port$path$encoded$fragment$coords");
|
||||
}
|
||||
|
||||
/**
|
||||
* Replaces unknown sections of the path with base parts
|
||||
* to return a complete absolute one.
|
||||
* @param string/SimpleUrl $base Base URL.
|
||||
* @param string Absolute path.
|
||||
* @access private
|
||||
*/
|
||||
function _extractAbsolutePath($base) {
|
||||
if ($this->getHost()) {
|
||||
return $this->_path;
|
||||
}
|
||||
if (! $this->_isRelativePath($this->_path)) {
|
||||
return $this->_path;
|
||||
}
|
||||
if ($this->_path) {
|
||||
return $base->getBasePath() . $this->_path;
|
||||
}
|
||||
return $base->getPath();
|
||||
}
|
||||
|
||||
/**
|
||||
* Simple test to see if a path part is relative.
|
||||
* @param string $path Path to test.
|
||||
* @return boolean True if starts with a "/".
|
||||
* @access private
|
||||
*/
|
||||
function _isRelativePath($path) {
|
||||
return (substr($path, 0, 1) != '/');
|
||||
}
|
||||
|
||||
/**
|
||||
* Extracts the username and password for use in rendering
|
||||
* a URL.
|
||||
* @return string/boolean Form of username:password or false.
|
||||
* @access public
|
||||
*/
|
||||
function getIdentity() {
|
||||
if ($this->_username && $this->_password) {
|
||||
return $this->_username . ':' . $this->_password;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Replaces . and .. sections of the path.
|
||||
* @param string $path Unoptimised path.
|
||||
* @return string Path with dots removed if possible.
|
||||
* @access public
|
||||
*/
|
||||
function normalisePath($path) {
|
||||
$path = preg_replace('|/\./|', '/', $path);
|
||||
return preg_replace('|/[^/]+/\.\./|', '/', $path);
|
||||
}
|
||||
|
||||
/**
|
||||
* A pipe seperated list of all TLDs that result in two part
|
||||
* domain names.
|
||||
* @return string Pipe separated list.
|
||||
* @access public
|
||||
* @static
|
||||
*/
|
||||
function getAllTopLevelDomains() {
|
||||
return 'com|edu|net|org|gov|mil|int|biz|info|name|pro|aero|coop|museum';
|
||||
}
|
||||
}
|
||||
?>
|
||||
332
tests/simpletest/user_agent.php
Normal file
332
tests/simpletest/user_agent.php
Normal file
|
|
@ -0,0 +1,332 @@
|
|||
<?php
|
||||
/**
|
||||
* Base include file for SimpleTest
|
||||
* @package SimpleTest
|
||||
* @subpackage WebTester
|
||||
* @version $Id: user_agent.php 1723 2008-04-08 00:34:10Z lastcraft $
|
||||
*/
|
||||
|
||||
/**#@+
|
||||
* include other SimpleTest class files
|
||||
*/
|
||||
require_once(dirname(__FILE__) . '/cookies.php');
|
||||
require_once(dirname(__FILE__) . '/http.php');
|
||||
require_once(dirname(__FILE__) . '/encoding.php');
|
||||
require_once(dirname(__FILE__) . '/authentication.php');
|
||||
/**#@-*/
|
||||
|
||||
if (! defined('DEFAULT_MAX_REDIRECTS')) {
|
||||
define('DEFAULT_MAX_REDIRECTS', 3);
|
||||
}
|
||||
if (! defined('DEFAULT_CONNECTION_TIMEOUT')) {
|
||||
define('DEFAULT_CONNECTION_TIMEOUT', 15);
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetches web pages whilst keeping track of
|
||||
* cookies and authentication.
|
||||
* @package SimpleTest
|
||||
* @subpackage WebTester
|
||||
*/
|
||||
class SimpleUserAgent {
|
||||
var $_cookie_jar;
|
||||
var $_cookies_enabled = true;
|
||||
var $_authenticator;
|
||||
var $_max_redirects = DEFAULT_MAX_REDIRECTS;
|
||||
var $_proxy = false;
|
||||
var $_proxy_username = false;
|
||||
var $_proxy_password = false;
|
||||
var $_connection_timeout = DEFAULT_CONNECTION_TIMEOUT;
|
||||
var $_additional_headers = array();
|
||||
|
||||
/**
|
||||
* Starts with no cookies, realms or proxies.
|
||||
* @access public
|
||||
*/
|
||||
function SimpleUserAgent() {
|
||||
$this->_cookie_jar = &new SimpleCookieJar();
|
||||
$this->_authenticator = &new SimpleAuthenticator();
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes expired and temporary cookies as if
|
||||
* the browser was closed and re-opened. Authorisation
|
||||
* has to be obtained again as well.
|
||||
* @param string/integer $date Time when session restarted.
|
||||
* If omitted then all persistent
|
||||
* cookies are kept.
|
||||
* @access public
|
||||
*/
|
||||
function restart($date = false) {
|
||||
$this->_cookie_jar->restartSession($date);
|
||||
$this->_authenticator->restartSession();
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a header to every fetch.
|
||||
* @param string $header Header line to add to every
|
||||
* request until cleared.
|
||||
* @access public
|
||||
*/
|
||||
function addHeader($header) {
|
||||
$this->_additional_headers[] = $header;
|
||||
}
|
||||
|
||||
/**
|
||||
* Ages the cookies by the specified time.
|
||||
* @param integer $interval Amount in seconds.
|
||||
* @access public
|
||||
*/
|
||||
function ageCookies($interval) {
|
||||
$this->_cookie_jar->agePrematurely($interval);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets an additional cookie. If a cookie has
|
||||
* the same name and path it is replaced.
|
||||
* @param string $name Cookie key.
|
||||
* @param string $value Value of cookie.
|
||||
* @param string $host Host upon which the cookie is valid.
|
||||
* @param string $path Cookie path if not host wide.
|
||||
* @param string $expiry Expiry date.
|
||||
* @access public
|
||||
*/
|
||||
function setCookie($name, $value, $host = false, $path = '/', $expiry = false) {
|
||||
$this->_cookie_jar->setCookie($name, $value, $host, $path, $expiry);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads the most specific cookie value from the
|
||||
* browser cookies.
|
||||
* @param string $host Host to search.
|
||||
* @param string $path Applicable path.
|
||||
* @param string $name Name of cookie to read.
|
||||
* @return string False if not present, else the
|
||||
* value as a string.
|
||||
* @access public
|
||||
*/
|
||||
function getCookieValue($host, $path, $name) {
|
||||
return $this->_cookie_jar->getCookieValue($host, $path, $name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads the current cookies within the base URL.
|
||||
* @param string $name Key of cookie to find.
|
||||
* @param SimpleUrl $base Base URL to search from.
|
||||
* @return string/boolean Null if there is no base URL, false
|
||||
* if the cookie is not set.
|
||||
* @access public
|
||||
*/
|
||||
function getBaseCookieValue($name, $base) {
|
||||
if (! $base) {
|
||||
return null;
|
||||
}
|
||||
return $this->getCookieValue($base->getHost(), $base->getPath(), $name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Switches off cookie sending and recieving.
|
||||
* @access public
|
||||
*/
|
||||
function ignoreCookies() {
|
||||
$this->_cookies_enabled = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Switches back on the cookie sending and recieving.
|
||||
* @access public
|
||||
*/
|
||||
function useCookies() {
|
||||
$this->_cookies_enabled = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the socket timeout for opening a connection.
|
||||
* @param integer $timeout Maximum time in seconds.
|
||||
* @access public
|
||||
*/
|
||||
function setConnectionTimeout($timeout) {
|
||||
$this->_connection_timeout = $timeout;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the maximum number of redirects before
|
||||
* a page will be loaded anyway.
|
||||
* @param integer $max Most hops allowed.
|
||||
* @access public
|
||||
*/
|
||||
function setMaximumRedirects($max) {
|
||||
$this->_max_redirects = $max;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets proxy to use on all requests for when
|
||||
* testing from behind a firewall. Set URL
|
||||
* to false to disable.
|
||||
* @param string $proxy Proxy URL.
|
||||
* @param string $username Proxy username for authentication.
|
||||
* @param string $password Proxy password for authentication.
|
||||
* @access public
|
||||
*/
|
||||
function useProxy($proxy, $username, $password) {
|
||||
if (! $proxy) {
|
||||
$this->_proxy = false;
|
||||
return;
|
||||
}
|
||||
if ((strncmp($proxy, 'http://', 7) != 0) && (strncmp($proxy, 'https://', 8) != 0)) {
|
||||
$proxy = 'http://'. $proxy;
|
||||
}
|
||||
$this->_proxy = &new SimpleUrl($proxy);
|
||||
$this->_proxy_username = $username;
|
||||
$this->_proxy_password = $password;
|
||||
}
|
||||
|
||||
/**
|
||||
* Test to see if the redirect limit is passed.
|
||||
* @param integer $redirects Count so far.
|
||||
* @return boolean True if over.
|
||||
* @access private
|
||||
*/
|
||||
function _isTooManyRedirects($redirects) {
|
||||
return ($redirects > $this->_max_redirects);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the identity for the current realm.
|
||||
* @param string $host Host to which realm applies.
|
||||
* @param string $realm Full name of realm.
|
||||
* @param string $username Username for realm.
|
||||
* @param string $password Password for realm.
|
||||
* @access public
|
||||
*/
|
||||
function setIdentity($host, $realm, $username, $password) {
|
||||
$this->_authenticator->setIdentityForRealm($host, $realm, $username, $password);
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetches a URL as a response object. Will keep trying if redirected.
|
||||
* It will also collect authentication realm information.
|
||||
* @param string/SimpleUrl $url Target to fetch.
|
||||
* @param SimpleEncoding $encoding Additional parameters for request.
|
||||
* @return SimpleHttpResponse Hopefully the target page.
|
||||
* @access public
|
||||
*/
|
||||
function &fetchResponse($url, $encoding) {
|
||||
if ($encoding->getMethod() != 'POST') {
|
||||
$url->addRequestParameters($encoding);
|
||||
$encoding->clear();
|
||||
}
|
||||
$response = &$this->_fetchWhileRedirected($url, $encoding);
|
||||
if ($headers = $response->getHeaders()) {
|
||||
if ($headers->isChallenge()) {
|
||||
$this->_authenticator->addRealm(
|
||||
$url,
|
||||
$headers->getAuthentication(),
|
||||
$headers->getRealm());
|
||||
}
|
||||
}
|
||||
return $response;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetches the page until no longer redirected or
|
||||
* until the redirect limit runs out.
|
||||
* @param SimpleUrl $url Target to fetch.
|
||||
* @param SimpelFormEncoding $encoding Additional parameters for request.
|
||||
* @return SimpleHttpResponse Hopefully the target page.
|
||||
* @access private
|
||||
*/
|
||||
function &_fetchWhileRedirected($url, $encoding) {
|
||||
$redirects = 0;
|
||||
do {
|
||||
$response = &$this->_fetch($url, $encoding);
|
||||
if ($response->isError()) {
|
||||
return $response;
|
||||
}
|
||||
$headers = $response->getHeaders();
|
||||
$location = new SimpleUrl($headers->getLocation());
|
||||
$url = $location->makeAbsolute($url);
|
||||
if ($this->_cookies_enabled) {
|
||||
$headers->writeCookiesToJar($this->_cookie_jar, $url);
|
||||
}
|
||||
if (! $headers->isRedirect()) {
|
||||
break;
|
||||
}
|
||||
$encoding = new SimpleGetEncoding();
|
||||
} while (! $this->_isTooManyRedirects(++$redirects));
|
||||
return $response;
|
||||
}
|
||||
|
||||
/**
|
||||
* Actually make the web request.
|
||||
* @param SimpleUrl $url Target to fetch.
|
||||
* @param SimpleFormEncoding $encoding Additional parameters for request.
|
||||
* @return SimpleHttpResponse Headers and hopefully content.
|
||||
* @access protected
|
||||
*/
|
||||
function &_fetch($url, $encoding) {
|
||||
$request = &$this->_createRequest($url, $encoding);
|
||||
$response = &$request->fetch($this->_connection_timeout);
|
||||
return $response;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a full page request.
|
||||
* @param SimpleUrl $url Target to fetch as url object.
|
||||
* @param SimpleFormEncoding $encoding POST/GET parameters.
|
||||
* @return SimpleHttpRequest New request.
|
||||
* @access private
|
||||
*/
|
||||
function &_createRequest($url, $encoding) {
|
||||
$request = &$this->_createHttpRequest($url, $encoding);
|
||||
$this->_addAdditionalHeaders($request);
|
||||
if ($this->_cookies_enabled) {
|
||||
$request->readCookiesFromJar($this->_cookie_jar, $url);
|
||||
}
|
||||
$this->_authenticator->addHeaders($request, $url);
|
||||
return $request;
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds the appropriate HTTP request object.
|
||||
* @param SimpleUrl $url Target to fetch as url object.
|
||||
* @param SimpleFormEncoding $parameters POST/GET parameters.
|
||||
* @return SimpleHttpRequest New request object.
|
||||
* @access protected
|
||||
*/
|
||||
function &_createHttpRequest($url, $encoding) {
|
||||
$request = &new SimpleHttpRequest($this->_createRoute($url), $encoding);
|
||||
return $request;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets up either a direct route or via a proxy.
|
||||
* @param SimpleUrl $url Target to fetch as url object.
|
||||
* @return SimpleRoute Route to take to fetch URL.
|
||||
* @access protected
|
||||
*/
|
||||
function &_createRoute($url) {
|
||||
if ($this->_proxy) {
|
||||
$route = &new SimpleProxyRoute(
|
||||
$url,
|
||||
$this->_proxy,
|
||||
$this->_proxy_username,
|
||||
$this->_proxy_password);
|
||||
} else {
|
||||
$route = &new SimpleRoute($url);
|
||||
}
|
||||
return $route;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds additional manual headers.
|
||||
* @param SimpleHttpRequest $request Outgoing request.
|
||||
* @access private
|
||||
*/
|
||||
function _addAdditionalHeaders(&$request) {
|
||||
foreach ($this->_additional_headers as $header) {
|
||||
$request->addHeaderLine($header);
|
||||
}
|
||||
}
|
||||
}
|
||||
?>
|
||||
1541
tests/simpletest/web_tester.php
Normal file
1541
tests/simpletest/web_tester.php
Normal file
File diff suppressed because it is too large
Load diff
647
tests/simpletest/xml.php
Normal file
647
tests/simpletest/xml.php
Normal file
|
|
@ -0,0 +1,647 @@
|
|||
<?php
|
||||
/**
|
||||
* base include file for SimpleTest
|
||||
* @package SimpleTest
|
||||
* @subpackage UnitTester
|
||||
* @version $Id: xml.php 1723 2008-04-08 00:34:10Z lastcraft $
|
||||
*/
|
||||
|
||||
/**#@+
|
||||
* include other SimpleTest class files
|
||||
*/
|
||||
require_once(dirname(__FILE__) . '/scorer.php');
|
||||
/**#@-*/
|
||||
|
||||
/**
|
||||
* Creates the XML needed for remote communication
|
||||
* by SimpleTest.
|
||||
* @package SimpleTest
|
||||
* @subpackage UnitTester
|
||||
*/
|
||||
class XmlReporter extends SimpleReporter {
|
||||
var $_indent;
|
||||
var $_namespace;
|
||||
|
||||
/**
|
||||
* Sets up indentation and namespace.
|
||||
* @param string $namespace Namespace to add to each tag.
|
||||
* @param string $indent Indenting to add on each nesting.
|
||||
* @access public
|
||||
*/
|
||||
function XmlReporter($namespace = false, $indent = ' ') {
|
||||
$this->SimpleReporter();
|
||||
$this->_namespace = ($namespace ? $namespace . ':' : '');
|
||||
$this->_indent = $indent;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates the pretty printing indent level
|
||||
* from the current level of nesting.
|
||||
* @param integer $offset Extra indenting level.
|
||||
* @return string Leading space.
|
||||
* @access protected
|
||||
*/
|
||||
function _getIndent($offset = 0) {
|
||||
return str_repeat(
|
||||
$this->_indent,
|
||||
count($this->getTestList()) + $offset);
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts character string to parsed XML
|
||||
* entities string.
|
||||
* @param string text Unparsed character data.
|
||||
* @return string Parsed character data.
|
||||
* @access public
|
||||
*/
|
||||
function toParsedXml($text) {
|
||||
return str_replace(
|
||||
array('&', '<', '>', '"', '\''),
|
||||
array('&', '<', '>', '"', '''),
|
||||
$text);
|
||||
}
|
||||
|
||||
/**
|
||||
* Paints the start of a group test.
|
||||
* @param string $test_name Name of test that is starting.
|
||||
* @param integer $size Number of test cases starting.
|
||||
* @access public
|
||||
*/
|
||||
function paintGroupStart($test_name, $size) {
|
||||
parent::paintGroupStart($test_name, $size);
|
||||
print $this->_getIndent();
|
||||
print "<" . $this->_namespace . "group size=\"$size\">\n";
|
||||
print $this->_getIndent(1);
|
||||
print "<" . $this->_namespace . "name>" .
|
||||
$this->toParsedXml($test_name) .
|
||||
"</" . $this->_namespace . "name>\n";
|
||||
}
|
||||
|
||||
/**
|
||||
* Paints the end of a group test.
|
||||
* @param string $test_name Name of test that is ending.
|
||||
* @access public
|
||||
*/
|
||||
function paintGroupEnd($test_name) {
|
||||
print $this->_getIndent();
|
||||
print "</" . $this->_namespace . "group>\n";
|
||||
parent::paintGroupEnd($test_name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Paints the start of a test case.
|
||||
* @param string $test_name Name of test that is starting.
|
||||
* @access public
|
||||
*/
|
||||
function paintCaseStart($test_name) {
|
||||
parent::paintCaseStart($test_name);
|
||||
print $this->_getIndent();
|
||||
print "<" . $this->_namespace . "case>\n";
|
||||
print $this->_getIndent(1);
|
||||
print "<" . $this->_namespace . "name>" .
|
||||
$this->toParsedXml($test_name) .
|
||||
"</" . $this->_namespace . "name>\n";
|
||||
}
|
||||
|
||||
/**
|
||||
* Paints the end of a test case.
|
||||
* @param string $test_name Name of test that is ending.
|
||||
* @access public
|
||||
*/
|
||||
function paintCaseEnd($test_name) {
|
||||
print $this->_getIndent();
|
||||
print "</" . $this->_namespace . "case>\n";
|
||||
parent::paintCaseEnd($test_name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Paints the start of a test method.
|
||||
* @param string $test_name Name of test that is starting.
|
||||
* @access public
|
||||
*/
|
||||
function paintMethodStart($test_name) {
|
||||
parent::paintMethodStart($test_name);
|
||||
print $this->_getIndent();
|
||||
print "<" . $this->_namespace . "test>\n";
|
||||
print $this->_getIndent(1);
|
||||
print "<" . $this->_namespace . "name>" .
|
||||
$this->toParsedXml($test_name) .
|
||||
"</" . $this->_namespace . "name>\n";
|
||||
}
|
||||
|
||||
/**
|
||||
* Paints the end of a test method.
|
||||
* @param string $test_name Name of test that is ending.
|
||||
* @param integer $progress Number of test cases ending.
|
||||
* @access public
|
||||
*/
|
||||
function paintMethodEnd($test_name) {
|
||||
print $this->_getIndent();
|
||||
print "</" . $this->_namespace . "test>\n";
|
||||
parent::paintMethodEnd($test_name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Paints pass as XML.
|
||||
* @param string $message Message to encode.
|
||||
* @access public
|
||||
*/
|
||||
function paintPass($message) {
|
||||
parent::paintPass($message);
|
||||
print $this->_getIndent(1);
|
||||
print "<" . $this->_namespace . "pass>";
|
||||
print $this->toParsedXml($message);
|
||||
print "</" . $this->_namespace . "pass>\n";
|
||||
}
|
||||
|
||||
/**
|
||||
* Paints failure as XML.
|
||||
* @param string $message Message to encode.
|
||||
* @access public
|
||||
*/
|
||||
function paintFail($message) {
|
||||
parent::paintFail($message);
|
||||
print $this->_getIndent(1);
|
||||
print "<" . $this->_namespace . "fail>";
|
||||
print $this->toParsedXml($message);
|
||||
print "</" . $this->_namespace . "fail>\n";
|
||||
}
|
||||
|
||||
/**
|
||||
* Paints error as XML.
|
||||
* @param string $message Message to encode.
|
||||
* @access public
|
||||
*/
|
||||
function paintError($message) {
|
||||
parent::paintError($message);
|
||||
print $this->_getIndent(1);
|
||||
print "<" . $this->_namespace . "exception>";
|
||||
print $this->toParsedXml($message);
|
||||
print "</" . $this->_namespace . "exception>\n";
|
||||
}
|
||||
|
||||
/**
|
||||
* Paints exception as XML.
|
||||
* @param Exception $exception Exception to encode.
|
||||
* @access public
|
||||
*/
|
||||
function paintException($exception) {
|
||||
parent::paintException($exception);
|
||||
print $this->_getIndent(1);
|
||||
print "<" . $this->_namespace . "exception>";
|
||||
$message = 'Unexpected exception of type [' . get_class($exception) .
|
||||
'] with message ['. $exception->getMessage() .
|
||||
'] in ['. $exception->getFile() .
|
||||
' line ' . $exception->getLine() . ']';
|
||||
print $this->toParsedXml($message);
|
||||
print "</" . $this->_namespace . "exception>\n";
|
||||
}
|
||||
|
||||
/**
|
||||
* Paints the skipping message and tag.
|
||||
* @param string $message Text to display in skip tag.
|
||||
* @access public
|
||||
*/
|
||||
function paintSkip($message) {
|
||||
parent::paintSkip($message);
|
||||
print $this->_getIndent(1);
|
||||
print "<" . $this->_namespace . "skip>";
|
||||
print $this->toParsedXml($message);
|
||||
print "</" . $this->_namespace . "skip>\n";
|
||||
}
|
||||
|
||||
/**
|
||||
* Paints a simple supplementary message.
|
||||
* @param string $message Text to display.
|
||||
* @access public
|
||||
*/
|
||||
function paintMessage($message) {
|
||||
parent::paintMessage($message);
|
||||
print $this->_getIndent(1);
|
||||
print "<" . $this->_namespace . "message>";
|
||||
print $this->toParsedXml($message);
|
||||
print "</" . $this->_namespace . "message>\n";
|
||||
}
|
||||
|
||||
/**
|
||||
* Paints a formatted ASCII message such as a
|
||||
* variable dump.
|
||||
* @param string $message Text to display.
|
||||
* @access public
|
||||
*/
|
||||
function paintFormattedMessage($message) {
|
||||
parent::paintFormattedMessage($message);
|
||||
print $this->_getIndent(1);
|
||||
print "<" . $this->_namespace . "formatted>";
|
||||
print "<![CDATA[$message]]>";
|
||||
print "</" . $this->_namespace . "formatted>\n";
|
||||
}
|
||||
|
||||
/**
|
||||
* Serialises the event object.
|
||||
* @param string $type Event type as text.
|
||||
* @param mixed $payload Message or object.
|
||||
* @access public
|
||||
*/
|
||||
function paintSignal($type, $payload) {
|
||||
parent::paintSignal($type, $payload);
|
||||
print $this->_getIndent(1);
|
||||
print "<" . $this->_namespace . "signal type=\"$type\">";
|
||||
print "<![CDATA[" . serialize($payload) . "]]>";
|
||||
print "</" . $this->_namespace . "signal>\n";
|
||||
}
|
||||
|
||||
/**
|
||||
* Paints the test document header.
|
||||
* @param string $test_name First test top level
|
||||
* to start.
|
||||
* @access public
|
||||
* @abstract
|
||||
*/
|
||||
function paintHeader($test_name) {
|
||||
if (! SimpleReporter::inCli()) {
|
||||
header('Content-type: text/xml');
|
||||
}
|
||||
print "<?xml version=\"1.0\"";
|
||||
if ($this->_namespace) {
|
||||
print " xmlns:" . $this->_namespace .
|
||||
"=\"www.lastcraft.com/SimpleTest/Beta3/Report\"";
|
||||
}
|
||||
print "?>\n";
|
||||
print "<" . $this->_namespace . "run>\n";
|
||||
}
|
||||
|
||||
/**
|
||||
* Paints the test document footer.
|
||||
* @param string $test_name The top level test.
|
||||
* @access public
|
||||
* @abstract
|
||||
*/
|
||||
function paintFooter($test_name) {
|
||||
print "</" . $this->_namespace . "run>\n";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Accumulator for incoming tag. Holds the
|
||||
* incoming test structure information for
|
||||
* later dispatch to the reporter.
|
||||
* @package SimpleTest
|
||||
* @subpackage UnitTester
|
||||
*/
|
||||
class NestingXmlTag {
|
||||
var $_name;
|
||||
var $_attributes;
|
||||
|
||||
/**
|
||||
* Sets the basic test information except
|
||||
* the name.
|
||||
* @param hash $attributes Name value pairs.
|
||||
* @access public
|
||||
*/
|
||||
function NestingXmlTag($attributes) {
|
||||
$this->_name = false;
|
||||
$this->_attributes = $attributes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the test case/method name.
|
||||
* @param string $name Name of test.
|
||||
* @access public
|
||||
*/
|
||||
function setName($name) {
|
||||
$this->_name = $name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for name.
|
||||
* @return string Name of test.
|
||||
* @access public
|
||||
*/
|
||||
function getName() {
|
||||
return $this->_name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for attributes.
|
||||
* @return hash All attributes.
|
||||
* @access protected
|
||||
*/
|
||||
function _getAttributes() {
|
||||
return $this->_attributes;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Accumulator for incoming method tag. Holds the
|
||||
* incoming test structure information for
|
||||
* later dispatch to the reporter.
|
||||
* @package SimpleTest
|
||||
* @subpackage UnitTester
|
||||
*/
|
||||
class NestingMethodTag extends NestingXmlTag {
|
||||
|
||||
/**
|
||||
* Sets the basic test information except
|
||||
* the name.
|
||||
* @param hash $attributes Name value pairs.
|
||||
* @access public
|
||||
*/
|
||||
function NestingMethodTag($attributes) {
|
||||
$this->NestingXmlTag($attributes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Signals the appropriate start event on the
|
||||
* listener.
|
||||
* @param SimpleReporter $listener Target for events.
|
||||
* @access public
|
||||
*/
|
||||
function paintStart(&$listener) {
|
||||
$listener->paintMethodStart($this->getName());
|
||||
}
|
||||
|
||||
/**
|
||||
* Signals the appropriate end event on the
|
||||
* listener.
|
||||
* @param SimpleReporter $listener Target for events.
|
||||
* @access public
|
||||
*/
|
||||
function paintEnd(&$listener) {
|
||||
$listener->paintMethodEnd($this->getName());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Accumulator for incoming case tag. Holds the
|
||||
* incoming test structure information for
|
||||
* later dispatch to the reporter.
|
||||
* @package SimpleTest
|
||||
* @subpackage UnitTester
|
||||
*/
|
||||
class NestingCaseTag extends NestingXmlTag {
|
||||
|
||||
/**
|
||||
* Sets the basic test information except
|
||||
* the name.
|
||||
* @param hash $attributes Name value pairs.
|
||||
* @access public
|
||||
*/
|
||||
function NestingCaseTag($attributes) {
|
||||
$this->NestingXmlTag($attributes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Signals the appropriate start event on the
|
||||
* listener.
|
||||
* @param SimpleReporter $listener Target for events.
|
||||
* @access public
|
||||
*/
|
||||
function paintStart(&$listener) {
|
||||
$listener->paintCaseStart($this->getName());
|
||||
}
|
||||
|
||||
/**
|
||||
* Signals the appropriate end event on the
|
||||
* listener.
|
||||
* @param SimpleReporter $listener Target for events.
|
||||
* @access public
|
||||
*/
|
||||
function paintEnd(&$listener) {
|
||||
$listener->paintCaseEnd($this->getName());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Accumulator for incoming group tag. Holds the
|
||||
* incoming test structure information for
|
||||
* later dispatch to the reporter.
|
||||
* @package SimpleTest
|
||||
* @subpackage UnitTester
|
||||
*/
|
||||
class NestingGroupTag extends NestingXmlTag {
|
||||
|
||||
/**
|
||||
* Sets the basic test information except
|
||||
* the name.
|
||||
* @param hash $attributes Name value pairs.
|
||||
* @access public
|
||||
*/
|
||||
function NestingGroupTag($attributes) {
|
||||
$this->NestingXmlTag($attributes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Signals the appropriate start event on the
|
||||
* listener.
|
||||
* @param SimpleReporter $listener Target for events.
|
||||
* @access public
|
||||
*/
|
||||
function paintStart(&$listener) {
|
||||
$listener->paintGroupStart($this->getName(), $this->getSize());
|
||||
}
|
||||
|
||||
/**
|
||||
* Signals the appropriate end event on the
|
||||
* listener.
|
||||
* @param SimpleReporter $listener Target for events.
|
||||
* @access public
|
||||
*/
|
||||
function paintEnd(&$listener) {
|
||||
$listener->paintGroupEnd($this->getName());
|
||||
}
|
||||
|
||||
/**
|
||||
* The size in the attributes.
|
||||
* @return integer Value of size attribute or zero.
|
||||
* @access public
|
||||
*/
|
||||
function getSize() {
|
||||
$attributes = $this->_getAttributes();
|
||||
if (isset($attributes['SIZE'])) {
|
||||
return (integer)$attributes['SIZE'];
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Parser for importing the output of the XmlReporter.
|
||||
* Dispatches that output to another reporter.
|
||||
* @package SimpleTest
|
||||
* @subpackage UnitTester
|
||||
*/
|
||||
class SimpleTestXmlParser {
|
||||
var $_listener;
|
||||
var $_expat;
|
||||
var $_tag_stack;
|
||||
var $_in_content_tag;
|
||||
var $_content;
|
||||
var $_attributes;
|
||||
|
||||
/**
|
||||
* Loads a listener with the SimpleReporter
|
||||
* interface.
|
||||
* @param SimpleReporter $listener Listener of tag events.
|
||||
* @access public
|
||||
*/
|
||||
function SimpleTestXmlParser(&$listener) {
|
||||
$this->_listener = &$listener;
|
||||
$this->_expat = &$this->_createParser();
|
||||
$this->_tag_stack = array();
|
||||
$this->_in_content_tag = false;
|
||||
$this->_content = '';
|
||||
$this->_attributes = array();
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses a block of XML sending the results to
|
||||
* the listener.
|
||||
* @param string $chunk Block of text to read.
|
||||
* @return boolean True if valid XML.
|
||||
* @access public
|
||||
*/
|
||||
function parse($chunk) {
|
||||
if (! xml_parse($this->_expat, $chunk)) {
|
||||
trigger_error('XML parse error with ' .
|
||||
xml_error_string(xml_get_error_code($this->_expat)));
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets up expat as the XML parser.
|
||||
* @return resource Expat handle.
|
||||
* @access protected
|
||||
*/
|
||||
function &_createParser() {
|
||||
$expat = xml_parser_create();
|
||||
xml_set_object($expat, $this);
|
||||
xml_set_element_handler($expat, '_startElement', '_endElement');
|
||||
xml_set_character_data_handler($expat, '_addContent');
|
||||
xml_set_default_handler($expat, '_default');
|
||||
return $expat;
|
||||
}
|
||||
|
||||
/**
|
||||
* Opens a new test nesting level.
|
||||
* @return NestedXmlTag The group, case or method tag
|
||||
* to start.
|
||||
* @access private
|
||||
*/
|
||||
function _pushNestingTag($nested) {
|
||||
array_unshift($this->_tag_stack, $nested);
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for current test structure tag.
|
||||
* @return NestedXmlTag The group, case or method tag
|
||||
* being parsed.
|
||||
* @access private
|
||||
*/
|
||||
function &_getCurrentNestingTag() {
|
||||
return $this->_tag_stack[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* Ends a nesting tag.
|
||||
* @return NestedXmlTag The group, case or method tag
|
||||
* just finished.
|
||||
* @access private
|
||||
*/
|
||||
function _popNestingTag() {
|
||||
return array_shift($this->_tag_stack);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test if tag is a leaf node with only text content.
|
||||
* @param string $tag XML tag name.
|
||||
* @return @boolean True if leaf, false if nesting.
|
||||
* @private
|
||||
*/
|
||||
function _isLeaf($tag) {
|
||||
return in_array($tag, array(
|
||||
'NAME', 'PASS', 'FAIL', 'EXCEPTION', 'SKIP', 'MESSAGE', 'FORMATTED', 'SIGNAL'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Handler for start of event element.
|
||||
* @param resource $expat Parser handle.
|
||||
* @param string $tag Element name.
|
||||
* @param hash $attributes Name value pairs.
|
||||
* Attributes without content
|
||||
* are marked as true.
|
||||
* @access protected
|
||||
*/
|
||||
function _startElement($expat, $tag, $attributes) {
|
||||
$this->_attributes = $attributes;
|
||||
if ($tag == 'GROUP') {
|
||||
$this->_pushNestingTag(new NestingGroupTag($attributes));
|
||||
} elseif ($tag == 'CASE') {
|
||||
$this->_pushNestingTag(new NestingCaseTag($attributes));
|
||||
} elseif ($tag == 'TEST') {
|
||||
$this->_pushNestingTag(new NestingMethodTag($attributes));
|
||||
} elseif ($this->_isLeaf($tag)) {
|
||||
$this->_in_content_tag = true;
|
||||
$this->_content = '';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* End of element event.
|
||||
* @param resource $expat Parser handle.
|
||||
* @param string $tag Element name.
|
||||
* @access protected
|
||||
*/
|
||||
function _endElement($expat, $tag) {
|
||||
$this->_in_content_tag = false;
|
||||
if (in_array($tag, array('GROUP', 'CASE', 'TEST'))) {
|
||||
$nesting_tag = $this->_popNestingTag();
|
||||
$nesting_tag->paintEnd($this->_listener);
|
||||
} elseif ($tag == 'NAME') {
|
||||
$nesting_tag = &$this->_getCurrentNestingTag();
|
||||
$nesting_tag->setName($this->_content);
|
||||
$nesting_tag->paintStart($this->_listener);
|
||||
} elseif ($tag == 'PASS') {
|
||||
$this->_listener->paintPass($this->_content);
|
||||
} elseif ($tag == 'FAIL') {
|
||||
$this->_listener->paintFail($this->_content);
|
||||
} elseif ($tag == 'EXCEPTION') {
|
||||
$this->_listener->paintError($this->_content);
|
||||
} elseif ($tag == 'SKIP') {
|
||||
$this->_listener->paintSkip($this->_content);
|
||||
} elseif ($tag == 'SIGNAL') {
|
||||
$this->_listener->paintSignal(
|
||||
$this->_attributes['TYPE'],
|
||||
unserialize($this->_content));
|
||||
} elseif ($tag == 'MESSAGE') {
|
||||
$this->_listener->paintMessage($this->_content);
|
||||
} elseif ($tag == 'FORMATTED') {
|
||||
$this->_listener->paintFormattedMessage($this->_content);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Content between start and end elements.
|
||||
* @param resource $expat Parser handle.
|
||||
* @param string $text Usually output messages.
|
||||
* @access protected
|
||||
*/
|
||||
function _addContent($expat, $text) {
|
||||
if ($this->_in_content_tag) {
|
||||
$this->_content .= $text;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* XML and Doctype handler. Discards all such content.
|
||||
* @param resource $expat Parser handle.
|
||||
* @param string $default Text of default content.
|
||||
* @access protected
|
||||
*/
|
||||
function _default($expat, $default) {
|
||||
}
|
||||
}
|
||||
?>
|
||||
Loading…
Add table
Add a link
Reference in a new issue