Skip to content

Commit e0d48a4

Browse files
authored
Merge pull request #1977 from jim-parry/test/featuretestcase
Test/featuretestcase
2 parents e5be1f1 + 8457385 commit e0d48a4

6 files changed

Lines changed: 126 additions & 28 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: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,4 +55,23 @@ public function index3()
5555
return $response;
5656
}
5757

58+
public function canyon()
59+
{
60+
echo 'Hello-o-o';
61+
}
62+
63+
public function cat()
64+
{
65+
}
66+
67+
public function json()
68+
{
69+
$this->responsd(['answer' => 42]);
70+
}
71+
72+
public function xml()
73+
{
74+
$this->respond('<my><pet>cat</pet></my>');
75+
}
76+
5877
}

tests/system/Test/FeatureTestCaseTest.php

Lines changed: 54 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,9 @@
44
use CodeIgniter\Test\FeatureResponse;
55

66
/**
7-
* @group DatabaseLive
7+
* @group DatabaseLive
8+
* @runTestsInSeparateProcesses
9+
* @preserveGlobalState disabled
810
*/
911
class FeatureTestCaseTest extends FeatureTestCase
1012
{
@@ -14,7 +16,6 @@ protected function setUp()
1416
parent::setUp();
1517

1618
$this->skipEvents();
17-
$this->clean = false;
1819
}
1920

2021
public function testCallGet()
@@ -30,9 +31,6 @@ function () {
3031
]);
3132
$response = $this->get('home');
3233

33-
// close open buffer
34-
ob_end_clean();
35-
3634
$response->assertSee('Hello World');
3735
$response->assertDontSee('Again');
3836
}
@@ -44,7 +42,7 @@ public function testCallSimpleGet()
4442
'add',
4543
'home',
4644
function () {
47-
return 'Hello World';
45+
return 'Hello Earth';
4846
},
4947
],
5048
]);
@@ -53,7 +51,7 @@ function () {
5351
$this->assertInstanceOf(FeatureResponse::class, $response);
5452
$this->assertInstanceOf(\CodeIgniter\HTTP\Response::class, $response->response);
5553
$this->assertTrue($response->isOK());
56-
$this->assertEquals('Hello World', $response->response->getBody());
54+
$this->assertEquals('Hello Earth', $response->response->getBody());
5755
$this->assertEquals(200, $response->response->getStatusCode());
5856
}
5957

@@ -64,13 +62,13 @@ public function testCallPost()
6462
'post',
6563
'home',
6664
function () {
67-
return 'Hello World';
65+
return 'Hello Mars';
6866
},
6967
],
7068
]);
7169
$response = $this->post('home');
7270

73-
$response->assertSee('Hello World');
71+
$response->assertSee('Hello Mars');
7472
}
7573

7674
public function testCallPut()
@@ -80,13 +78,13 @@ public function testCallPut()
8078
'put',
8179
'home',
8280
function () {
83-
return 'Hello World';
81+
return 'Hello Pluto';
8482
},
8583
],
8684
]);
8785
$response = $this->put('home');
8886

89-
$response->assertSee('Hello World');
87+
$response->assertSee('Hello Pluto');
9088
}
9189

9290
public function testCallPatch()
@@ -96,13 +94,13 @@ public function testCallPatch()
9694
'patch',
9795
'home',
9896
function () {
99-
return 'Hello World';
97+
return 'Hello Jupiter';
10098
},
10199
],
102100
]);
103101
$response = $this->patch('home');
104102

105-
$response->assertSee('Hello World');
103+
$response->assertSee('Hello Jupiter');
106104
}
107105

108106
public function testCallOptions()
@@ -112,13 +110,13 @@ public function testCallOptions()
112110
'options',
113111
'home',
114112
function () {
115-
return 'Hello World';
113+
return 'Hello George';
116114
},
117115
],
118116
]);
119117
$response = $this->options('home');
120118

121-
$response->assertSee('Hello World');
119+
$response->assertSee('Hello George');
122120
}
123121

124122
public function testCallDelete()
@@ -128,13 +126,13 @@ public function testCallDelete()
128126
'delete',
129127
'home',
130128
function () {
131-
return 'Hello World';
129+
return 'Hello Wonka';
132130
},
133131
],
134132
]);
135133
$response = $this->delete('home');
136134

137-
$response->assertSee('Hello World');
135+
$response->assertSee('Hello Wonka');
138136
}
139137

140138
public function testSession()
@@ -148,4 +146,43 @@ public function testSession()
148146
$response->assertSessionMissing('popcorn');
149147
}
150148

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+
151188
}

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)