Skip to content

Commit 33b1f5a

Browse files
committed
Improve FeatureTestCase
1 parent e5fd33d commit 33b1f5a

6 files changed

Lines changed: 108 additions & 24 deletions

File tree

system/Router/RouteCollection.php

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -619,9 +619,9 @@ public function map(array $routes = [], array $options = null): RouteCollectionI
619619
* Example:
620620
* $routes->add('news', 'Posts::index');
621621
*
622-
* @param string $from
623-
* @param array|string $to
624-
* @param array $options
622+
* @param string $from
623+
* @param array|string $to
624+
* @param array $options
625625
*
626626
* @return RouteCollectionInterface
627627
*/
@@ -1432,4 +1432,18 @@ private function determineCurrentSubdomain()
14321432
}
14331433

14341434
//--------------------------------------------------------------------
1435+
1436+
/**
1437+
* Reset the routes, so that a FeatureTestCase can provide the
1438+
* explicit ones needed for it.
1439+
*/
1440+
public function resetRoutes()
1441+
{
1442+
$this->routes = ['*' => []];
1443+
foreach ($this->defaultHTTPMethods as $verb)
1444+
{
1445+
$this->routes[$verb] = [];
1446+
}
1447+
}
1448+
14351449
}

system/Test/FeatureResponse.php

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@
4747
*/
4848
class FeatureResponse extends TestCase
4949
{
50+
5051
/**
5152
* @var \CodeIgniter\HTTP\Response
5253
*/
@@ -61,9 +62,10 @@ public function __construct(Response $response = null)
6162
{
6263
$this->response = $response;
6364

64-
if (is_string($this->response->getBody()))
65+
$body = $response->getBody();
66+
if (! empty($body) && is_string($body))
6567
{
66-
$this->domParser = (new DOMParser())->withString($this->response->getBody());
68+
$this->domParser = (new DOMParser())->withString($body);
6769
}
6870
}
6971

@@ -124,7 +126,7 @@ public function assertRedirect()
124126
*/
125127
public function assertStatus(int $code)
126128
{
127-
$this->assertEquals($code, (int)$this->response->getStatusCode());
129+
$this->assertEquals($code, (int) $this->response->getStatusCode());
128130
}
129131

130132
/**
@@ -397,4 +399,5 @@ public function getXML()
397399
{
398400
return $this->response->getXML();
399401
}
402+
400403
}

system/Test/FeatureTestCase.php

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@
5555
*/
5656
class FeatureTestCase extends CIDatabaseTestCase
5757
{
58+
5859
/**
5960
* If present, will override application
6061
* routes when using call().
@@ -82,6 +83,11 @@ class FeatureTestCase extends CIDatabaseTestCase
8283
* Sets a RouteCollection that will override
8384
* the application's route collection.
8485
*
86+
* Example routes:
87+
* [
88+
* ['get', 'home', 'Home::index']
89+
* ]
90+
*
8591
* @param array $routes
8692
*
8793
* @return $this
@@ -92,6 +98,7 @@ protected function withRoutes(array $routes = null)
9298

9399
if ($routes)
94100
{
101+
$collection->resetRoutes();
95102
foreach ($routes as $route)
96103
{
97104
$collection->{$route[0]}($route[1], $route[2]);
@@ -149,18 +156,31 @@ public function call(string $method, string $path, array $params = null)
149156
$request = $this->setupRequest($method, $path, $params);
150157
$request = $this->populateGlobals($method, $request, $params);
151158

159+
// Make sure the RouteCollection knows what method we're using...
160+
if (! empty($this->routes))
161+
{
162+
$this->routes->setHTTPVerb($method);
163+
}
164+
152165
// Make sure any other classes that might call the request
153166
// instance get the right one.
154167
Services::injectMock('request', $request);
155168
$_SERVER['REQUEST_METHOD'] = $method;
156169

157170
$response = $this->app
158-
->setRequest($request)
159-
->run($this->routes, true);
171+
->setRequest($request)
172+
->run($this->routes, true);
173+
174+
$output = ob_get_contents();
175+
if (empty($response->getBody()) && ! empty($output))
176+
{
177+
$response->setBody($output);
178+
}
160179

161180
// Clean up any open output buffers
162181
// not relevant to unit testing
163182
// @codeCoverageIgnoreStart
183+
164184
if (ob_get_level() > 0 && $this->clean)
165185
{
166186
ob_end_clean();
@@ -311,4 +331,5 @@ protected function populateGlobals(string $method, Request $request, array $para
311331

312332
return $request;
313333
}
334+
314335
}

tests/_support/Controllers/Popcorn.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,10 @@ public function canyon()
6060
echo 'Hello-o-o';
6161
}
6262

63+
public function cat()
64+
{
65+
}
66+
6367
public function json()
6468
{
6569
$this->responsd(['answer' => 42]);

tests/system/Test/FeatureTestCaseTest.php

Lines changed: 51 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@ protected function setUp()
1616
parent::setUp();
1717

1818
$this->skipEvents();
19-
$this->clean = false;
2019
}
2120

2221
public function testCallGet()
@@ -43,7 +42,7 @@ public function testCallSimpleGet()
4342
'add',
4443
'home',
4544
function () {
46-
return 'Hello World';
45+
return 'Hello Earth';
4746
},
4847
],
4948
]);
@@ -52,7 +51,7 @@ function () {
5251
$this->assertInstanceOf(FeatureResponse::class, $response);
5352
$this->assertInstanceOf(\CodeIgniter\HTTP\Response::class, $response->response);
5453
$this->assertTrue($response->isOK());
55-
$this->assertEquals('Hello World', $response->response->getBody());
54+
$this->assertEquals('Hello Earth', $response->response->getBody());
5655
$this->assertEquals(200, $response->response->getStatusCode());
5756
}
5857

@@ -63,13 +62,13 @@ public function testCallPost()
6362
'post',
6463
'home',
6564
function () {
66-
return 'Hello World';
65+
return 'Hello Mars';
6766
},
6867
],
6968
]);
7069
$response = $this->post('home');
7170

72-
$response->assertSee('Hello World');
71+
$response->assertSee('Hello Mars');
7372
}
7473

7574
public function testCallPut()
@@ -79,13 +78,13 @@ public function testCallPut()
7978
'put',
8079
'home',
8180
function () {
82-
return 'Hello World';
81+
return 'Hello Pluto';
8382
},
8483
],
8584
]);
8685
$response = $this->put('home');
8786

88-
$response->assertSee('Hello World');
87+
$response->assertSee('Hello Pluto');
8988
}
9089

9190
public function testCallPatch()
@@ -95,13 +94,13 @@ public function testCallPatch()
9594
'patch',
9695
'home',
9796
function () {
98-
return 'Hello World';
97+
return 'Hello Jupiter';
9998
},
10099
],
101100
]);
102101
$response = $this->patch('home');
103102

104-
$response->assertSee('Hello World');
103+
$response->assertSee('Hello Jupiter');
105104
}
106105

107106
public function testCallOptions()
@@ -111,13 +110,13 @@ public function testCallOptions()
111110
'options',
112111
'home',
113112
function () {
114-
return 'Hello World';
113+
return 'Hello George';
115114
},
116115
],
117116
]);
118117
$response = $this->options('home');
119118

120-
$response->assertSee('Hello World');
119+
$response->assertSee('Hello George');
121120
}
122121

123122
public function testCallDelete()
@@ -127,13 +126,13 @@ public function testCallDelete()
127126
'delete',
128127
'home',
129128
function () {
130-
return 'Hello World';
129+
return 'Hello Wonka';
131130
},
132131
],
133132
]);
134133
$response = $this->delete('home');
135134

136-
$response->assertSee('Hello World');
135+
$response->assertSee('Hello Wonka');
137136
}
138137

139138
public function testSession()
@@ -147,4 +146,43 @@ public function testSession()
147146
$response->assertSessionMissing('popcorn');
148147
}
149148

149+
public function testReturns()
150+
{
151+
$this->withRoutes([
152+
[
153+
'get',
154+
'home',
155+
'Tests\Support\Controllers\Popcorn::index',
156+
],
157+
]);
158+
$response = $this->get('home');
159+
$response->assertSee('Hi');
160+
}
161+
162+
public function testIgnores()
163+
{
164+
$this->withRoutes([
165+
[
166+
'get',
167+
'home',
168+
'Tests\Support\Controllers\Popcorn::cat',
169+
],
170+
]);
171+
$response = $this->get('home');
172+
$response->assertEmpty($response->response->getBody());
173+
}
174+
175+
public function testEchoes()
176+
{
177+
$this->withRoutes([
178+
[
179+
'get',
180+
'home',
181+
'Tests\Support\Controllers\Popcorn::canyon',
182+
],
183+
]);
184+
$response = $this->get('home');
185+
$response->assertSee('Hello-o-o');
186+
}
187+
150188
}

user_guide_src/source/testing/feature.rst

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -69,16 +69,20 @@ Shorthand methods for each of the HTTP verbs exist to ease typing and make thing
6969
Setting Different Routes
7070
------------------------
7171

72-
You can use a custom collection of routes by passing an array of routes into the ``withRoutes()`` method. This will
72+
You can use a custom collection of routes by passing an array of "routes" into the ``withRoutes()`` method. This will
7373
override any existing routes in the system::
7474

7575
$routes = [
76-
'users' => 'UserController::list'
77-
];
76+
[ 'get', 'users', 'UserController::list' ]
77+
];
7878

7979
$result = $this->withRoutes($routes)
8080
->get('users');
8181

82+
Each of the "routes" is a 3 element array containing the HTTP verb (or "add" for all),
83+
the URI to match, and the routing destination.
84+
85+
8286
Setting Session Values
8387
----------------------
8488

0 commit comments

Comments
 (0)