3 require_once dirname( __FILE__
) . "/../../../maintenance/fetchText.php";
6 * Mock for the input/output of FetchText
8 * FetchText internally tries to access stdin and stdout. We mock those aspects
11 class SemiMockedFetchText
extends FetchText
{
14 * @var String|null Text to pass as stdin
16 private $mockStdinText = null;
19 * @var bool Whether or not a text for stdin has been provided
21 private $mockSetUp = False;
24 * @var Array Invocation counters for the mocked aspects
26 private $mockInvocations = array( 'getStdin' => 0 );
31 * Data for the fake stdin
33 * @param $stdin String The string to be used instead of stdin
35 function mockStdin( $stdin )
37 $this->mockStdinText
= $stdin;
38 $this->mockSetUp
= True;
42 * Gets invocation counters for mocked methods.
44 * @return Array An array, whose keys are function names. The corresponding values
45 * denote the number of times the function has been invoked.
47 function mockGetInvocations()
49 return $this->mockInvocations
;
52 // -----------------------------------------------------------------
53 // Mocked functions from FetchText follow.
55 function getStdin( $len = null )
57 $this->mockInvocations
['getStdin']++
;
58 if ( $len !== null ) {
59 throw new PHPUnit_Framework_ExpectationFailedException(
60 "Tried to get stdin with non null parameter" );
63 if ( ! $this->mockSetUp
) {
64 throw new PHPUnit_Framework_ExpectationFailedException(
65 "Tried to get stdin before setting up rerouting" );
68 return fopen( 'data://text/plain,' . $this->mockStdinText
, 'r' );
74 * TestCase for FetchText
79 class FetchTextTest
extends MediaWikiTestCase
{
81 // We add 5 Revisions for this test. Their corresponding text id's
82 // are stored in the following 5 variables.
91 * @var Exception|null As the current MediaWikiTestCase::run is not
92 * robust enough to recover from thrown exceptions directly, we cannot
93 * throw frow within addDBData, although it would be appropriate. Hence,
94 * we catch the exception and store it until we are in setUp and may
95 * finally rethrow the exception without crashing the test suite.
97 private $exceptionFromAddDBData;
100 * @var FetchText the (mocked) FetchText that is to test
105 * Adds a revision to a page, while returning the resuting text's id
107 * @param $page WikiPage The page to add the revision to
108 * @param $text String The revisions text
109 * @param $text String The revisions summare
113 private function addRevision( $page, $text, $summary ) {
114 $status = $page->doEdit( $text, $summary );
115 if ( $status->isGood() ) {
116 $value = $status->getValue();
117 $revision = $value['revision'];
118 $id = $revision->getTextId();
123 throw new MWException( "Could not determine text id" );
127 function addDBData() {
128 $this->tablesUsed
[] = 'page';
129 $this->tablesUsed
[] = 'revision';
130 $this->tablesUsed
[] = 'text';
133 $title = Title
::newFromText( 'FetchTextTestPage1' );
134 $page = WikiPage
::factory( $title );
135 $this->textId1
= $this->addRevision( $page, "FetchTextTestPage1Text1", "FetchTextTestPage1Summary1" );
137 $title = Title
::newFromText( 'FetchTextTestPage2' );
138 $page = WikiPage
::factory( $title );
139 $this->textId2
= $this->addRevision( $page, "FetchTextTestPage2Text1", "FetchTextTestPage2Summary1" );
140 $this->textId3
= $this->addRevision( $page, "FetchTextTestPage2Text2", "FetchTextTestPage2Summary2" );
141 $this->textId4
= $this->addRevision( $page, "FetchTextTestPage2Text3", "FetchTextTestPage2Summary3" );
142 $this->textId5
= $this->addRevision( $page, "FetchTextTestPage2Text4 some additional Text ", "FetchTextTestPage2Summary4 extra " );
143 } catch ( Exception
$e ) {
144 // We'd love to pass $e directly. However, ... see
145 // documentation of exceptionFromAddDBData
146 $this->exceptionFromAddDBData
= $e;
151 protected function setUp() {
154 // Check if any Exception is stored for rethrowing from addDBData
155 if ( $this->exceptionFromAddDBData
!== null ) {
156 throw $this->exceptionFromAddDBData
;
159 $this->fetchText
= new SemiMockedFetchText();
164 * Helper to relate FetchText's input and output
166 private function assertFilter( $input, $expectedOutput ) {
167 $this->fetchText
->mockStdin( $input );
168 $this->fetchText
->execute();
169 $invocations = $this->fetchText
->mockGetInvocations();
170 $this->assertEquals( 1, $invocations['getStdin'],
171 "getStdin invocation counter" );
172 $this->expectOutputString( $expectedOutput );
177 // Instead of the following functions, a data provider would be great.
178 // However, as data providers are evaluated /before/ addDBData, a data
179 // provider would not know the required ids.
181 function testExistingSimple() {
182 $this->assertFilter( $this->textId2
,
183 $this->textId2
. "\n23\nFetchTextTestPage2Text1" );
186 function testExistingSimpleWithNewline() {
187 $this->assertFilter( $this->textId2
. "\n",
188 $this->textId2
. "\n23\nFetchTextTestPage2Text1" );
191 function testExistingSeveral() {
192 $this->assertFilter( "$this->textId1\n$this->textId5\n"
193 . "$this->textId3\n$this->textId3",
195 $this->textId1
. "\n23\nFetchTextTestPage1Text1",
196 $this->textId5
. "\n44\nFetchTextTestPage2Text4 "
197 . "some additional Text",
198 $this->textId3
. "\n23\nFetchTextTestPage2Text2",
199 $this->textId3
. "\n23\nFetchTextTestPage2Text2"
203 function testEmpty() {
204 $this->assertFilter( "", null );
207 function testNonExisting() {
208 $this->assertFilter( $this->textId5 +
10, ( $this->textId5 +
10 ) . "\n-1\n" );
211 function testNegativeInteger() {
212 $this->assertFilter( "-42", "-42\n-1\n" );
215 function testFloatingPointNumberExisting() {
216 // float -> int -> revision
217 $this->assertFilter( $this->textId3 +
0.14159,
218 $this->textId3
. "\n23\nFetchTextTestPage2Text2" );
221 function testFloatingPointNumberNonExisting() {
222 $this->assertFilter( $this->textId5 +
3.14159,
223 ( $this->textId5 +
3 ) . "\n-1\n" );
226 function testCharacters() {
227 $this->assertFilter( "abc", "0\n-1\n" );
231 $this->assertFilter( "ab\n" . $this->textId4
. ".5cd\n\nefg\n" . $this->textId2
232 . "\n" . $this->textId3
,
235 $this->textId4
. "\n23\nFetchTextTestPage2Text3",
238 $this->textId2
. "\n23\nFetchTextTestPage2Text1",
239 $this->textId3
. "\n23\nFetchTextTestPage2Text2"