PageRenderTime 55ms CodeModel.GetById 15ms RepoModel.GetById 1ms app.codeStats 0ms

/slim/tests/SlimTest.php

http://github.com/eryx/php-framework-benchmark
PHP | 1759 lines | 744 code | 95 blank | 920 comment | 2 complexity | 6eee421e580c9e23f982da04e181d1bc MD5 | raw file
Possible License(s): MIT, BSD-3-Clause, Apache-2.0, LGPL-2.1, LGPL-3.0, BSD-2-Clause

Large files files are truncated, but you can click here to view the full file

  1. <?php
  2. /**
  3. * Slim - a micro PHP 5 framework
  4. *
  5. * @author Josh Lockhart <info@joshlockhart.com>
  6. * @copyright 2011 Josh Lockhart
  7. * @link http://www.slimframework.com
  8. * @license http://www.slimframework.com/license
  9. * @version 1.5.0
  10. *
  11. * MIT LICENSE
  12. *
  13. * Permission is hereby granted, free of charge, to any person obtaining
  14. * a copy of this software and associated documentation files (the
  15. * "Software"), to deal in the Software without restriction, including
  16. * without limitation the rights to use, copy, modify, merge, publish,
  17. * distribute, sublicense, and/or sell copies of the Software, and to
  18. * permit persons to whom the Software is furnished to do so, subject to
  19. * the following conditions:
  20. *
  21. * The above copyright notice and this permission notice shall be
  22. * included in all copies or substantial portions of the Software.
  23. *
  24. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  25. * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  26. * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  27. * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
  28. * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
  29. * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
  30. * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  31. */
  32. set_include_path(dirname(__FILE__) . '/../' . PATH_SEPARATOR . get_include_path());
  33. //Start session before PHPUnit sends output. This only prevents us from using
  34. //the default Slim Session cookie store.
  35. session_start();
  36. require_once 'Slim/Slim.php';
  37. //Prepare mock HTTP request
  38. $_SERVER['REDIRECT_STATUS'] = "200";
  39. $_SERVER['HTTP_HOST'] = "slim";
  40. $_SERVER['HTTP_CONNECTION'] = "keep-alive";
  41. $_SERVER['HTTP_CACHE_CONTROL'] = "max-age=0";
  42. $_SERVER['HTTP_ACCEPT'] = "application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5";
  43. $_SERVER['HTTP_USER_AGENT'] = "Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_4; en-US) AppleWebKit/534.3 (KHTML, like Gecko) Chrome/6.0.472.63 Safari/534.3";
  44. $_SERVER['HTTP_ACCEPT_ENCODING'] = "gzip,deflate,sdch";
  45. $_SERVER['HTTP_ACCEPT_LANGUAGE'] = "en-US,en;q=0.8";
  46. $_SERVER['HTTP_ACCEPT_CHARSET'] = "ISO-8859-1,utf-8;q=0.7,*;q=0.3";
  47. $_SERVER['HTTP_IF_MODIFIED_SINCE'] = "Sun, 03 Oct 2010 17:00:52 -0400";
  48. $_SERVER['HTTP_IF_NONE_MATCH'] = '"abc123"';
  49. $_SERVER['HTTP_COOKIE'] = 'foo=bar; foo2=bar2';
  50. $_SERVER['PATH'] = "/usr/bin:/bin:/usr/sbin:/sbin";
  51. $_SERVER['SERVER_SIGNATURE'] = "";
  52. $_SERVER['SERVER_SOFTWARE'] = "Apache";
  53. $_SERVER['SERVER_NAME'] = "slim";
  54. $_SERVER['SERVER_ADDR'] = "127.0.0.1";
  55. $_SERVER['SERVER_PORT'] = "80";
  56. $_SERVER['REMOTE_ADDR'] = "127.0.0.1";
  57. $_SERVER['DOCUMENT_ROOT'] = '/home/account/public';
  58. $_SERVER['SERVER_ADMIN'] = "you@example.com";
  59. $_SERVER['SCRIPT_FILENAME'] = __FILE__;
  60. $_SERVER['REMOTE_PORT'] = "55426";
  61. $_SERVER['REDIRECT_URL'] = "/";
  62. $_SERVER['GATEWAY_INTERFACE'] = "CGI/1.1";
  63. $_SERVER['SERVER_PROTOCOL'] = "HTTP/1.1";
  64. $_SERVER['REQUEST_METHOD'] = "GET";
  65. $_SERVER['QUERY_STRING'] = "";
  66. $_SERVER['REQUEST_URI'] = "/";
  67. $_SERVER['SCRIPT_NAME'] = '/bootstrap.php';
  68. $_SERVER['PHP_SELF'] = '/bootstrap.php';
  69. $_SERVER['REQUEST_TIME'] = "1285647051";
  70. $_SERVER['argv'] = array();
  71. $_SERVER['argc'] = 0;
  72. //Register non-Slim autoloader
  73. function customAutoLoader( $class ) {
  74. $file = rtrim(dirname(__FILE__), '/') . '/' . $class . '.php';
  75. if ( file_exists($file) ) {
  76. require $file;
  77. } else {
  78. return;
  79. }
  80. }
  81. spl_autoload_register('customAutoLoader');
  82. //Mock custom view
  83. class CustomView extends Slim_View {
  84. function render($template) { echo "Custom view"; }
  85. }
  86. //Mock custom Logger
  87. class CustomLogger{
  88. public function debug( $var ) {
  89. print_r($var);
  90. }
  91. public function info( $var ) {
  92. print_r($var);
  93. }
  94. public function warn( $var ) {
  95. print_r($var);
  96. }
  97. public function error( $var ) {
  98. print_r($var);
  99. }
  100. public function fatal( $var ) {
  101. print_r($var);
  102. }
  103. }
  104. class SlimTest extends PHPUnit_Extensions_OutputTestCase {
  105. public function setUp() {
  106. $_SERVER['REQUEST_METHOD'] = "GET";
  107. $_ENV['SLIM_MODE'] = null;
  108. $_COOKIE['foo'] = 'bar';
  109. $_COOKIE['foo2'] = 'bar2';
  110. $_SERVER['REQUEST_URI'] = "/";
  111. }
  112. /************************************************
  113. * SLIM INITIALIZATION
  114. ************************************************/
  115. /**
  116. * Test Slim default View
  117. *
  118. * Pre-conditions:
  119. * Slim app instantiated with default View;
  120. *
  121. * Post-conditions:
  122. * Slim app has default View of class Slim_View;
  123. */
  124. public function testSlimDefaultView() {
  125. $app = new Slim();
  126. $this->assertTrue($app->view() instanceof Slim_View);
  127. }
  128. /**
  129. * Test Slim custom View
  130. *
  131. * Pre-conditions:
  132. * Case A: Slim app instantiated with View setting as string;
  133. * Case B: Slim app instantiated with View as instance;
  134. *
  135. * Post-conditions:
  136. * Case A: View is instance of CustomView
  137. * Case B: View is instance of CustomView
  138. */
  139. public function testSlimInitWithCustomView(){
  140. //Case A
  141. $app1 = new Slim(array('view' => 'CustomView'));
  142. $this->assertTrue($app1->view() instanceof CustomView);
  143. //Case B
  144. $app2 = new Slim(array('view' => new CustomView()));
  145. $this->assertTrue($app2->view() instanceOf CustomView);
  146. }
  147. /**
  148. * Test Slim default Logger
  149. *
  150. * Pre-conditions:
  151. * Slim app instantiated;
  152. * Logging enabled;
  153. * Default Logger used;
  154. *
  155. * Post-conditions:
  156. * Slim app has default Logger of class Slim_Logger;
  157. */
  158. public function testSlimInitWithDefaultLogger() {
  159. $app = new Slim(array(
  160. 'log.path' => dirname(__FILE__) . '/logs',
  161. 'log.enable' => true
  162. ));
  163. $this->assertTrue($app->getLog()->getLogger() instanceof Slim_Logger);
  164. }
  165. /**
  166. * Test Slim custom Logger
  167. *
  168. * Pre-conditions:
  169. * Slim app instantiated;
  170. * Logging enabled;
  171. * Custom Logger used;
  172. *
  173. * Post-conditions:
  174. * Slim app has custom Logger of class CustomLogger;
  175. */
  176. public function testSlimInitWithCustomLogger() {
  177. $app = new Slim(array(
  178. 'log.enable' => true,
  179. 'log.logger' => new CustomLogger()
  180. ));
  181. $this->assertTrue($app->getLog()->getLogger() instanceof CustomLogger);
  182. }
  183. /**
  184. * Test Slim autoloader ignores non-Slim classes
  185. *
  186. * Pre-conditions:
  187. * Instantiate a non-Slim class;
  188. *
  189. * Post-conditions:
  190. * Slim autoloader returns without requiring a class file;
  191. */
  192. public function testSlimAutoloaderIgnoresNonSlimClass() {
  193. $foo = new Foo();
  194. }
  195. /**
  196. * Test Slim get instance
  197. *
  198. * Pre-conditions:
  199. * Slim app instantiated;
  200. * Set app name;
  201. *
  202. * Post-conditions:
  203. * A default app exists;
  204. * The instantiated app is returned by the name assigned to it;
  205. */
  206. public function testGetInstance() {
  207. $app = new Slim();
  208. $app->setName('foo');
  209. $this->assertTrue(Slim::getInstance() instanceof Slim);
  210. $this->assertEquals('foo', $app->getName());
  211. $this->assertSame($app, Slim::getInstance('foo'));
  212. }
  213. /**
  214. * Test Slim does not affect default Response HTTP status
  215. *
  216. * Pre-conditions:
  217. * Slim app instantiated;
  218. * Case A: Use default settings;
  219. * Case B: Set to "1.0";
  220. *
  221. * Post-conditions:
  222. * Case A: Response HTTP version is "1.1";
  223. * Case B: Response HTTP version is "1.0";
  224. */
  225. public function testSlimSetsResponseHttpVersion() {
  226. $app1 = new Slim();
  227. $app2 = new Slim(array(
  228. 'http.version' => '1.0'
  229. ));
  230. $this->assertEquals('1.1', $app1->response()->httpVersion());
  231. $this->assertEquals('1.0', $app2->response()->httpVersion());
  232. }
  233. /************************************************
  234. * SLIM SETTINGS
  235. ************************************************/
  236. /**
  237. * Test Slim mode with ENV[SLIM_MODE]
  238. *
  239. * Pre-conditions:
  240. * SLIM_MODE environment variable set;
  241. * Slim app instantiated with config mode;
  242. *
  243. * Post-conditions:
  244. * Only the production configuration is called;
  245. */
  246. public function testSlimModeEnvironment() {
  247. $this->expectOutputString('production mode');
  248. $_ENV['SLIM_MODE'] = 'production';
  249. $app = new Slim(array(
  250. 'mode' => 'test'
  251. ));
  252. $app->configureMode('test', function () {
  253. echo "test mode";
  254. });
  255. $app->configureMode('production', function () {
  256. echo "production mode";
  257. });
  258. }
  259. /**
  260. * Test Slim mode with Config
  261. *
  262. * Pre-conditions:
  263. * ENV[SLIM_MODE] not set;
  264. * Slim app instantiated with config mode;
  265. *
  266. * Post-conditions:
  267. * Only the test configuration is called;
  268. */
  269. public function testSlimModeConfig() {
  270. $this->expectOutputString('test mode');
  271. $app = new Slim(array(
  272. 'mode' => 'test'
  273. ));
  274. $app->configureMode('test', function () {
  275. echo "test mode";
  276. });
  277. $app->configureMode('production', function () {
  278. echo "production mode";
  279. });
  280. }
  281. /**
  282. * Test Slim mode with default
  283. *
  284. * Pre-conditions:
  285. * ENV[SLIM_MODE] not set;
  286. * Slim app instantiated without config mode;
  287. *
  288. * Post-conditions:
  289. * Only the development configuration is called;
  290. */
  291. public function testSlimModeDefault() {
  292. $this->expectOutputString('dev mode');
  293. $app = new Slim();
  294. $app->configureMode('development', function () {
  295. echo "dev mode";
  296. });
  297. $app->configureMode('production', function () {
  298. echo "production mode";
  299. });
  300. }
  301. /**
  302. * Test Slim Logging for given mode
  303. *
  304. * Pre-conditions:
  305. * Slim app instantiated;
  306. * Set custom Logger for current app mode;
  307. *
  308. * Post-conditions:
  309. * Slim app Logger correct based on mode;
  310. */
  311. public function testSlimLoggerInMode() {
  312. $app = new Slim(array(
  313. 'mode' => 'test'
  314. ));
  315. $app->configureMode('test', function () use ($app) {
  316. $app->config(array(
  317. 'log.enable' => true,
  318. 'log.logger' => new CustomLogger()
  319. ));
  320. });
  321. $app->configureMode('development', function () use ($app) {
  322. $app->config(array(
  323. 'log.enable' => true
  324. ));
  325. });
  326. $this->assertTrue($app->getLog()->getLogger() instanceof CustomLogger);
  327. }
  328. /**
  329. * Test Slim defines one application setting
  330. *
  331. * Pre-conditions:
  332. * Slim app instantiated;
  333. * One configuration setting is set;
  334. *
  335. * Post-conditions:
  336. * Configuration setting `foo` === `bar`;
  337. */
  338. public function testSlimConfigSetsOneSetting(){
  339. $app = new Slim();
  340. $app->config('foo', 'bar');
  341. $this->assertEquals('bar', $app->config('foo'));
  342. }
  343. /**
  344. * Test Slim setting is NULL if non-existant
  345. *
  346. * Pre-conditions:
  347. * Slim app instantiated;
  348. * Fetch non-existing configuration setting;
  349. *
  350. * Post-conditions:
  351. * NULL is returned for the value of the setting;
  352. */
  353. public function testSlimConfigIfSettingDoesNotExist(){
  354. $app = new Slim();
  355. $this->assertNull($app->config('foo'));
  356. }
  357. /**
  358. * Test Slim defines multiple settings with array
  359. *
  360. * Pre-conditions:
  361. * Slim app instantiated;
  362. * Batch-define multiple configuration settings with associative array;
  363. *
  364. * Post-conditions:
  365. * Multiple settings are set correctly;
  366. */
  367. public function testSlimCongfigurationWithArray(){
  368. $app = new Slim();
  369. $app->config(array(
  370. 'one' => 'A',
  371. 'two' => 'B',
  372. 'three' => 'C'
  373. ));
  374. $this->assertEquals('A', $app->config('one'));
  375. $this->assertEquals('B', $app->config('two'));
  376. $this->assertEquals('C', $app->config('three'));
  377. }
  378. /************************************************
  379. * SLIM ROUTING
  380. ************************************************/
  381. /**
  382. * Test Slim GET route
  383. *
  384. * Pre-conditions:
  385. * Slim app instantiated;
  386. * One GET route defined;
  387. *
  388. * Post-conditions:
  389. * The GET route is returned;
  390. * The GET route's pattern and callable are set correctly;
  391. */
  392. public function testSlimGetRoute(){
  393. $app = new Slim();
  394. $callable = function () { echo "foo"; };
  395. $route = $app->get('/foo/bar', $callable);
  396. $this->assertEquals('/foo/bar', $route->getPattern());
  397. $this->assertSame($callable, $route->getCallable());
  398. }
  399. /**
  400. * Test Slim GET route with middleware
  401. *
  402. * Pre-conditions:
  403. * Slim app instantiated and run;
  404. * One GET route defined with middleware;
  405. *
  406. * Post-conditions:
  407. * The GET route and its middleware are invoked in sequence;
  408. */
  409. public function testSlimGetRouteWithMiddleware(){
  410. $app = new Slim();
  411. $mw1 = function () { echo "foo"; };
  412. $mw2 = function () { echo "bar"; };
  413. $callable = function () { echo "foo"; };
  414. $app->get('/', $mw1, $mw2, $callable);
  415. $this->expectOutputString('foobarfoo');
  416. $app->run();
  417. }
  418. /**
  419. * Test Slim sets POST route
  420. *
  421. * Pre-conditions:
  422. * Slim app instantiated;
  423. * One POST route defined;
  424. *
  425. * Post-conditions:
  426. * The POST route is returned;
  427. * The POST route's pattern and callable are set correctly;
  428. */
  429. public function testSlimPostRoute(){
  430. $app = new Slim();
  431. $callable = function () { echo "foo"; };
  432. $route = $app->post('/foo/bar', $callable);
  433. $this->assertEquals('/foo/bar', $route->getPattern());
  434. $this->assertSame($callable, $route->getCallable());
  435. }
  436. /**
  437. * Test Slim POST route with middleware
  438. *
  439. * Pre-conditions:
  440. * Slim app instantiated and run;
  441. * One POST route defined with middleware;
  442. *
  443. * Post-conditions:
  444. * The POST route and its middleware are invoked in sequence;
  445. */
  446. public function testSlimPostRouteWithMiddleware(){
  447. $_SERVER['REQUEST_METHOD'] = 'POST';
  448. $app = new Slim();
  449. $mw1 = function () { echo "foo"; };
  450. $mw2 = function () { echo "bar"; };
  451. $callable = function () { echo "foo"; };
  452. $route = $app->post('/', $mw1, $mw2, $callable);
  453. $this->expectOutputString('foobarfoo');
  454. $app->run();
  455. }
  456. /**
  457. * Test Slim sets PUT route
  458. *
  459. * Pre-conditions:
  460. * Slim app instantiated;
  461. * One PUT request defined;
  462. *
  463. * Post-conditions:
  464. * The PUT route is returned;
  465. * The PUT route's pattern and callable are set correctly;
  466. */
  467. public function testSlimPutRoute(){
  468. $app = new Slim();
  469. $callable = function () { echo "foo"; };
  470. $route = $app->put('/foo/bar', $callable);
  471. $this->assertEquals('/foo/bar', $route->getPattern());
  472. $this->assertSame($callable, $route->getCallable());
  473. }
  474. /**
  475. * Test Slim PUT route with middleware
  476. *
  477. * Pre-conditions:
  478. * Slim app instantiated and run;
  479. * One PUT request defined with middleware;
  480. *
  481. * Post-conditions:
  482. * The PUT route and its middleware are invoked in sequence;
  483. */
  484. public function testSlimPutRouteWithMiddleware(){
  485. $_SERVER['REQUEST_METHOD'] = 'PUT';
  486. $app = new Slim();
  487. $mw1 = function () { echo "foo"; };
  488. $mw2 = function () { echo "bar"; };
  489. $callable = function () { echo "foo"; };
  490. $route = $app->put('/', $mw1, $mw2, $callable);
  491. $this->expectOutputString('foobarfoo');
  492. $app->run();
  493. }
  494. /**
  495. * Test Slim sets DELETE route
  496. *
  497. * Pre-conditions:
  498. * Slim app instantiated;
  499. * One DELETE route defined;
  500. *
  501. * Post-conditions:
  502. * The DELETE route is returned;
  503. * The DELETE route's pattern and callable are set correctly;
  504. */
  505. public function testSlimDeleteRoute(){
  506. $app = new Slim();
  507. $callable = function () { echo "foo"; };
  508. $route = $app->delete('/foo/bar', $callable);
  509. $this->assertEquals('/foo/bar', $route->getPattern());
  510. $this->assertSame($callable, $route->getCallable());
  511. }
  512. /**
  513. * Test Slim DELETE route with middleware
  514. *
  515. * Pre-conditions:
  516. * Slim app instatiated and run;
  517. * One DELETE route defined with middleware;
  518. *
  519. * Post-conditions:
  520. * The DELETE route and its middleware are invoked in sequence;
  521. */
  522. public function testSlimDeleteRouteWithMiddleware(){
  523. $_SERVER['REQUEST_METHOD'] = 'DELETE';
  524. $app = new Slim();
  525. $mw1 = function () { echo "foo"; };
  526. $mw2 = function () { echo "bar"; };
  527. $callable = function () { echo "foo"; };
  528. $route = $app->delete('/', $mw1, $mw2, $callable);
  529. $this->expectOutputString('foobarfoo');
  530. $app->run();
  531. }
  532. /**
  533. * Test Slim sets DELETE route
  534. *
  535. * Pre-conditions:
  536. * Slim app instantiated;
  537. * One OPTIONS route defined;
  538. *
  539. * Post-conditions:
  540. * The OPTIONS route is returned;
  541. * The OPTIONS route's pattern and callable are set correctly;
  542. */
  543. public function testSlimOptionsRoute(){
  544. $app = new Slim();
  545. $callable = function () { echo "foo"; };
  546. $route = $app->options('/foo/bar', $callable);
  547. $this->assertEquals('/foo/bar', $route->getPattern());
  548. $this->assertSame($callable, $route->getCallable());
  549. }
  550. /**
  551. * Test Slim DELETE route with middleware
  552. *
  553. * Pre-conditions:
  554. * Slim app instatiated and run;
  555. * One OPTIONS route defined with middleware;
  556. *
  557. * Post-conditions:
  558. * The OPTIONS route and its middleware are invoked in sequence;
  559. */
  560. public function testSlimOptionsRouteWithMiddleware(){
  561. $_SERVER['REQUEST_METHOD'] = 'OPTIONS';
  562. $app = new Slim();
  563. $mw1 = function () { echo "foo"; };
  564. $mw2 = function () { echo "bar"; };
  565. $callable = function () { echo "foo"; };
  566. $route = $app->options('/', $mw1, $mw2, $callable);
  567. $this->expectOutputString('foobarfoo');
  568. $app->run();
  569. }
  570. /**
  571. * Test Slim routing and trailing slashes
  572. *
  573. * Pre-conditions:
  574. * A route is defined that expects a trailing slash, but
  575. * the resource URI does not have a trailing slash - but
  576. * otherwise matches the route pattern.
  577. *
  578. * Post-conditions:
  579. * Slim will send a 301 redirect response to the same
  580. * resource URI but with a trailing slash.
  581. */
  582. public function testRouteWithSlashAndUrlWithout() {
  583. $_SERVER['REQUEST_URI'] = '/foo/bar/bob';
  584. $app = new Slim();
  585. $app->get('/foo/bar/:name/', function ($name) {});
  586. $app->run();
  587. $this->assertEquals(301, $app->response()->status());
  588. $this->assertEquals('/foo/bar/bob/', $app->response()->header('Location'));
  589. }
  590. /**
  591. * Test Slim routing and trailing slashes
  592. *
  593. * Pre-conditions:
  594. * Slim app instantiated;
  595. * Route defined that matches current HTTP request;
  596. * Route does NOT expect trailing slash;
  597. * HTTP request DOES have trailing slash;
  598. *
  599. * Post-conditions:
  600. * Slim response status is 404;
  601. */
  602. public function testRouteWithoutSlashAndUrlWith() {
  603. $_SERVER['REQUEST_URI'] = '/foo/bar/bob/';
  604. $app = new Slim();
  605. $app->get('/foo/bar/:name', function ($name) {});
  606. $app->run();
  607. $this->assertEquals(404, $app->response()->status());
  608. }
  609. /**
  610. * Test Slim routing with URL encoded characters
  611. *
  612. * Pre-conditions:
  613. * Slim initialized;
  614. * Route defined and matches current request;
  615. * URL encoded spaces in URL;
  616. *
  617. * Post-conditions:
  618. * Route matched;
  619. * Route callable invoked;
  620. * Route callable arguments are URL decoded;
  621. */
  622. public function testRouteWithUrlEncodedParameters() {
  623. $_SERVER['REQUEST_URI'] = '/foo/jo%20hn/smi%20th';
  624. $app = new Slim();
  625. $app->get('/foo/:one/:two', function ($one, $two) {
  626. echo "$one and $two";
  627. });
  628. $app->run();
  629. $this->expectOutputString('jo hn and smi th');
  630. }
  631. /************************************************
  632. * SLIM ACCESSORS
  633. ************************************************/
  634. public function testSlimAccessors() {
  635. $app = new Slim();
  636. $this->assertTrue($app->request() instanceof Slim_Http_Request);
  637. $this->assertTrue($app->response() instanceof Slim_Http_Response);
  638. $this->assertTrue($app->router() instanceof Slim_Router);
  639. }
  640. /************************************************
  641. * SLIM VIEW
  642. ************************************************/
  643. /**
  644. * Test Slim copies data from old View to new View
  645. *
  646. * Pre-conditions:
  647. * Slim app instantiated;
  648. * Data set in default View;
  649. * New View is defined;
  650. *
  651. * Post-conditions:
  652. * The data from the original View is accessible in the new View;
  653. */
  654. public function testSlimCopiesViewData(){
  655. $data = array('foo' => 'bar');
  656. $app = new Slim();
  657. $app->view()->setData($data);
  658. $this->assertTrue($app->view() instanceof Slim_View);
  659. $this->assertEquals($data, $app->view()->getData());
  660. $app->view('CustomView');
  661. $this->assertTrue($app->view() instanceof CustomView);
  662. $this->assertEquals($data, $app->view()->getData());
  663. }
  664. /************************************************
  665. * SLIM RENDERING
  666. ************************************************/
  667. /**
  668. * Test Slim rendering with custom status
  669. *
  670. * Pre-conditions:
  671. * Slim app instantiated;
  672. * Render an existing template with custom data and status;
  673. *
  674. * Post-conditions:
  675. * The response status is 404;
  676. * The response body is correct;
  677. */
  678. public function testSlimRenderSetsResponseStatusOk(){
  679. $this->expectOutputString('test output bar');
  680. $app = new Slim(array(
  681. 'templates.path' => null,
  682. 'templates_dir' => dirname(__FILE__) . '/templates'
  683. ));
  684. $app->render('test.php', array('foo' => 'bar'), 404);
  685. $this->assertEquals(404, $app->response()->status());
  686. }
  687. /**
  688. * Test Slim rendering
  689. *
  690. * Pre-conditions:
  691. * Slim app instantiated;
  692. * Render an existing template with custom data;
  693. *
  694. * Post-conditions:
  695. * The response body is correct;
  696. */
  697. public function testSlimRender(){
  698. $this->expectOutputString('test output bar');
  699. $app = new Slim(array(
  700. 'templates.path' => dirname(__FILE__) . '/templates'
  701. ));
  702. $app->render('test.php', array('foo' => 'bar'));
  703. }
  704. /************************************************
  705. * SLIM HTTP CACHING
  706. ************************************************/
  707. /**
  708. * Test Slim HTTP caching if ETag match
  709. *
  710. * Pre-conditions:
  711. * Slim app instantiated;
  712. * Define route that matches current HTTP request;
  713. * Route sets ETag header, matches request's `If-None-Match` header;
  714. *
  715. * Post-conditions:
  716. * Slim app response status is 304;
  717. */
  718. public function testSlimEtagMatches(){
  719. $app = new Slim();
  720. $app->get('/', function () use ($app) {
  721. $app->etag('abc123');
  722. });
  723. $app->run();
  724. $this->assertEquals(304, $app->response()->status());
  725. }
  726. /**
  727. * Test Slim HTTP caching if ETag does not match
  728. *
  729. * Pre-conditions:
  730. * Slim app instantiated;
  731. * Define route that matches current HTTP request;
  732. * Route sets ETag header, does not match request's `If-None-Match` header;
  733. *
  734. * Post-conditions:
  735. * Slim app response status is 200;
  736. */
  737. public function testSlimEtagDoesNotMatch(){
  738. $app = new Slim();
  739. $app->get('/', function () use ($app) {
  740. $app->etag('xyz789');
  741. });
  742. $app->run();
  743. $this->assertEquals(200, $app->response()->status());
  744. }
  745. /**
  746. * Test Slim::etag only accepts 'strong' or 'weak' types
  747. *
  748. * Pre-conditions:
  749. * Slim app instantiated;
  750. * Define route that matches current HTTP request;
  751. * Route sets ETag header with an invalid argument;
  752. *
  753. * Post-conditions:
  754. * Slim app response status is 500;
  755. */
  756. public function testSlimETagThrowsExceptionForInvalidType(){
  757. $app = new Slim();
  758. $app->get('/', function () use ($app) {
  759. $app->etag('123','foo');
  760. });
  761. $app->run();
  762. $this->assertEquals(500, $app->response()->status());
  763. }
  764. /**
  765. * Test Slim HTTP caching with Last Modified match
  766. *
  767. * Pre-conditions:
  768. * Slim app instantiated;
  769. * Define route that matches current HTTP request;
  770. * Route correctly sets a Last-Modified header;
  771. *
  772. * Post-conditions:
  773. * Slim app response status is 304 Not Modified;
  774. */
  775. public function testSlimLastModifiedDateMatches(){
  776. $app = new Slim();
  777. $app->get('/', function () use ($app) {
  778. $app->lastModified(1286139652);
  779. });
  780. $app->run();
  781. $this->assertEquals(304, $app->response()->status());
  782. }
  783. /**
  784. * Test Slim HTTP caching if Last Modified does not match
  785. *
  786. * Pre-conditions:
  787. * Slim app instantiated;
  788. * Define route that matches current HTTP request;
  789. * Route sets `Last-Modified` header;
  790. * The HTTP `If-Modified-Since` header does not match the `Last-Modified` date;
  791. *
  792. * Post-conditions:
  793. * Slim app response status is 200;
  794. */
  795. public function testSlimLastModifiedDateDoesNotMatch(){
  796. $app = new Slim();
  797. $app->get('/', function () use ($app) {
  798. $app->lastModified(1286139250);
  799. });
  800. $app->run();
  801. $this->assertEquals(200, $app->response()->status());
  802. }
  803. /**
  804. * Test Slim Last Modified only accepts integer values
  805. *
  806. * Pre-conditions:
  807. * Slim app instantiated;
  808. * Define route that matches current HTTP request;
  809. * Route sets LastModified header value incorrectly;
  810. *
  811. * Post-conditions:
  812. * Slim app response status is 500;
  813. */
  814. public function testSlimLastModifiedOnlyAcceptsIntegers(){
  815. $app = new Slim();
  816. $app->get('/', function () use ($app) {
  817. $app->lastModified('Test');
  818. });
  819. $app->run();
  820. $this->assertEquals(500, $app->response()->status());
  821. }
  822. /************************************************
  823. * SLIM COOKIES
  824. ************************************************/
  825. /**
  826. * Test Slim gets cookie
  827. *
  828. * Pre-conditions:
  829. * Slim app instantiated;
  830. * Case A: Cookie `foo` exists, available in HTTP request;
  831. * Case B: Cookie `bad` does not exist;
  832. *
  833. * Post-conditions:
  834. * Case A: Cookie `foo` value is "bar";
  835. * Case B: Cooke `bad` value is NULL;
  836. */
  837. public function testSlimGetsCookie() {
  838. $app = new Slim();
  839. //Case A
  840. $this->assertEquals('bar', $app->getCookie('foo'));
  841. //Case B
  842. $this->assertNull($app->getCookie('doesNotExist'));
  843. }
  844. /**
  845. * Test Slim sets cookie with default time
  846. *
  847. * Pre-conditions:
  848. * Slim app instantiated;
  849. * Case A: Cookie time not set;
  850. * Case B: Cookie time set as seconds from now (integer);
  851. * Case C: Cookie time set as string;
  852. * Case D: Cookie time is set to 0;
  853. *
  854. * Post-conditions:
  855. * Cookie available in response;
  856. * Case A: Cookie time set using default value;
  857. * Case C: Cookie time set using `strtotime()`;
  858. * Case D: Cookie time is 0;
  859. */
  860. public function testSlimSetsCookie() {
  861. $app = new Slim();
  862. $cj = $app->response()->getCookieJar();
  863. //Case A
  864. $timeA = time();
  865. $app->setCookie('myCookie1', 'myValue1');
  866. $cookieA = $cj->getResponseCookie('myCookie1');
  867. $this->assertEquals('myCookie1', $cookieA->getName());
  868. $this->assertEquals('myValue1', $cookieA->getValue());
  869. $this->assertEquals($timeA + 1200, $cookieA->getExpires()); //default duration is 20 minutes
  870. $this->assertEquals('/', $cookieA->getPath());
  871. $this->assertEquals('', $cookieA->getDomain());
  872. $this->assertFalse($cookieA->getSecure());
  873. $this->assertFalse($cookieA->getHttpOnly());
  874. //Case C
  875. $timeC = time();
  876. $app->setCookie('myCookie3', 'myValue3', '1 hour');
  877. $cookieC = $cj->getResponseCookie('myCookie3');
  878. $this->assertEquals($timeC + 3600, $cookieC->getExpires());
  879. //Case D
  880. $timeD = time();
  881. $app->setCookie('myCookie4', 'myValue4', 0);
  882. $cookieD = $cj->getResponseCookie('myCookie4');
  883. $this->assertEquals(0, $cookieD->getExpires());
  884. }
  885. /**
  886. * Test Slim sets encrypted cookie
  887. *
  888. * Pre-conditions:
  889. * Slim app instantiated;
  890. * Case A: Cookie time not set;
  891. * Case B: Cookie time set as seconds from now (integer);
  892. * Case C: Cookie time set as string;
  893. * Case D: Cookie time is set to 0;
  894. *
  895. * Post-conditions:
  896. * Cookie available in response;
  897. * Case A: Cookie time set using default value;
  898. * Case C: Cookie time set using `strtotime()`;
  899. * Case D: Cookie time is 0;
  900. */
  901. public function testSlimSetsEncryptedCookie() {
  902. $app = new Slim();
  903. $cj = $app->response()->getCookieJar();
  904. //Case A
  905. $timeA = time();
  906. $app->setEncryptedCookie('myCookie1', 'myValue1');
  907. $cookieA = $cj->getResponseCookie('myCookie1');
  908. $this->assertEquals('myCookie1', $cookieA->getName());
  909. $this->assertEquals($timeA + 1200, $cookieA->getExpires()); //default duration is 20 minutes
  910. $this->assertEquals('/', $cookieA->getPath());
  911. $this->assertEquals('', $cookieA->getDomain());
  912. $this->assertFalse($cookieA->getSecure());
  913. $this->assertFalse($cookieA->getHttpOnly());
  914. //Case C
  915. $timeC = time();
  916. $app->setEncryptedCookie('myCookie3', 'myValue3', '1 hour');
  917. $cookieC = $cj->getResponseCookie('myCookie3');
  918. $this->assertEquals($timeC + 3600, $cookieC->getExpires());
  919. //Case D
  920. $timeD = time();
  921. $app->setEncryptedCookie('myCookie4', 'myValue4', 0);
  922. $cookieD = $cj->getResponseCookie('myCookie4');
  923. $this->assertEquals(0, $cookieD->getExpires());
  924. }
  925. /**
  926. * Test Slim deletes cookies
  927. *
  928. * Pre-conditions:
  929. * Case A: Classic cookie
  930. * Case B: Encrypted cookie
  931. *
  932. * Post-conditions:
  933. * Response Cookies replaced with empty, auto-expiring Cookies
  934. */
  935. public function testSlimDeletesCookies() {
  936. $app = new Slim();
  937. $cj = $app->response()->getCookieJar();
  938. //Case A
  939. $app->setCookie('foo1', 'bar1');
  940. $this->assertEquals('bar1', $cj->getResponseCookie('foo1')->getValue());
  941. $this->assertTrue($cj->getResponseCookie('foo1')->getExpires() > time());
  942. $app->deleteCookie('foo1');
  943. $this->assertEquals('', $app->getCookie('foo1'));
  944. $this->assertTrue($cj->getResponseCookie('foo1')->getExpires() < time());
  945. //Case B
  946. $app->setEncryptedCookie('foo2', 'bar2');
  947. $this->assertTrue(strlen($cj->getResponseCookie('foo2')->getValue()) > 0);
  948. $this->assertTrue($cj->getResponseCookie('foo2')->getExpires() > time());
  949. $app->deleteCookie('foo2');
  950. $this->assertEquals('', $cj->getResponseCookie('foo2')->getValue());
  951. $this->assertTrue($cj->getResponseCookie('foo2')->getExpires() < time());
  952. }
  953. /************************************************
  954. * SLIM HELPERS
  955. ************************************************/
  956. /**
  957. * Test Slim Root
  958. *
  959. * Pre-conditions:
  960. * Slim app instantiated;
  961. * Slim app installed in document root directory;
  962. *
  963. * Post-conditions:
  964. * Slim correctly reports root path;
  965. */
  966. public function testRootPathInBaseDirectory() {
  967. $rootPath = rtrim($_SERVER['DOCUMENT_ROOT'], '/') . '/';
  968. $app = new Slim();
  969. $this->assertEquals($rootPath, $app->root());
  970. }
  971. /**
  972. * Test Slim Root From Subdirectory
  973. *
  974. * Pre-conditions:
  975. * Slim app instantiated;
  976. * Slim app installed in a physical, public subdirectory of document root;
  977. *
  978. * Post-conditions:
  979. * Slim correctly reports root path;
  980. */
  981. public function testRootPathInSubDirectory() {
  982. $_SERVER['REQUEST_URI'] = '/foo/bar';
  983. $_SERVER['SCRIPT_NAME'] = '/foo/bootstrap.php';
  984. $_SERVER['PHP_SELF'] = '/foo/bootstrap.php';
  985. $rootPath = rtrim($_SERVER['DOCUMENT_ROOT'], '/') . '/foo/';
  986. $app = new Slim();
  987. $this->assertEquals($rootPath, $app->root());
  988. }
  989. /**
  990. * Test Slim Stop
  991. *
  992. * Pre-conditions:
  993. * Slim app instantiated;
  994. * Slim app stopped while route invocation in process;
  995. *
  996. * Post-conditions:
  997. * Slim ignores output after `stop()` is invoked;
  998. */
  999. public function testSlimStop() {
  1000. $app = new Slim();
  1001. $app->get('/', function () use ($app) {
  1002. try {
  1003. echo "foo";
  1004. $app->stop();
  1005. echo "bar";
  1006. } catch ( Slim_Exception_Stop $e ) {}
  1007. });
  1008. $app->run();
  1009. $this->assertEquals('foo', $app->response()->body());
  1010. }
  1011. /**
  1012. * Test Slim Halt inside route callback
  1013. *
  1014. * Pre-conditions:
  1015. * Slim app instantiated;
  1016. * Define route that matches current HTTP request;
  1017. * Halt app from within invoked route;
  1018. *
  1019. * Post-conditions:
  1020. * Slim app response status is 404;
  1021. * Slim app response body is 'Halt not found';
  1022. */
  1023. public function testSlimHaltInsideCallback() {
  1024. $app = new Slim();
  1025. $app->get('/', function () use ($app) {
  1026. echo 'foo';
  1027. $app->halt(404, 'Halt not found');
  1028. echo 'bar';
  1029. });
  1030. $app->run();
  1031. $this->assertEquals(404, $app->response()->status());
  1032. $this->assertEquals('Halt not found', $app->response()->body());
  1033. }
  1034. /**
  1035. * Test Slim Halt outside route callback
  1036. *
  1037. * Pre-conditions:
  1038. * Slim app instantiated;
  1039. * Slim::halt is invoked outside of a route callback;
  1040. *
  1041. * Post-conditions:
  1042. * The new response should be returned with the expected
  1043. * status code and body, regardless of the current route
  1044. * callback's expected output.
  1045. */
  1046. public function testSlimHaltOutsideCallback() {
  1047. $this->setExpectedException('Slim_Exception_Stop');
  1048. $app = new Slim();
  1049. $app->halt(500, 'External error');
  1050. $app->get('/', function () {
  1051. echo "foo";
  1052. });
  1053. $app->run();
  1054. $this->assertEquals(500, $app->response()->status());
  1055. $this->assertEquals('External error', $app->response()->body());
  1056. }
  1057. /**
  1058. * Test Slim Pass continues to next matching route
  1059. *
  1060. * Pre-conditions:
  1061. * Slim app instantiated with two routes;
  1062. * First route is most specific, invokes `pass()`;
  1063. * Second route is next matching route;
  1064. *
  1065. * Post-conditions:
  1066. * The response body is set by the second matching route;
  1067. */
  1068. public function testSlimPassWithFallbackRoute() {
  1069. $_SERVER['REQUEST_URI'] = "/name/Frank";
  1070. $app = new Slim();
  1071. $app->get('/name/Frank', function () use ($app) {
  1072. echo "Your name is Frank";
  1073. $app->pass();
  1074. });
  1075. $app->get('/name/:name', function ($name) {
  1076. echo "I think your name is $name";
  1077. });
  1078. $app->run();
  1079. $this->assertEquals('I think your name is Frank', $app->response()->body());
  1080. }
  1081. /**
  1082. * Test Slim Pass continues, but next matching route not found
  1083. *
  1084. * Pre-conditions:
  1085. * Slim app initiated;
  1086. * Define route that matches current HTTP request;
  1087. * Route passes;
  1088. * No subsequent routes available;
  1089. *
  1090. * Post-conditions:
  1091. * Slim app response status is 404;
  1092. */
  1093. public function testSlimPassWithoutFallbackRoute() {
  1094. $_SERVER['REQUEST_URI'] = '/name/Frank';
  1095. $app = new Slim();
  1096. $app->get('/name/Frank', function () use ($app) {
  1097. echo 'Your name is Frank';
  1098. $app->pass();
  1099. });
  1100. $app->run();
  1101. $this->assertEquals(404, $app->response()->status());
  1102. }
  1103. /**
  1104. * Test Slim::contentType
  1105. *
  1106. * Pre-conditions:
  1107. * Slim app instantiated;
  1108. * Content-Type header is set using helper method;
  1109. *
  1110. * Post-conditions:
  1111. * The Response content type header is set correctly;
  1112. */
  1113. public function testSlimContentType(){
  1114. $app = new Slim();
  1115. $app->contentType('image/jpeg');
  1116. $this->assertEquals('image/jpeg', $app->response()->header('Content-Type'));
  1117. }
  1118. /**
  1119. * Test Slim::status
  1120. *
  1121. * Pre-conditions:
  1122. * Slim app instantiated;
  1123. * Case A: Valid HTTP status is set using helper method;
  1124. * Case B: Invalid HTTP status is set using helper method;
  1125. *
  1126. * Post-conditions:
  1127. * Case A: The Response status code is set correctly;
  1128. * Case B: InvalidArgumentException is thrown;
  1129. */
  1130. public function testSlimStatus(){
  1131. $app1 = new Slim();
  1132. //Case A
  1133. $app1->status(302);
  1134. $this->assertSame($app1->response()->status(), 302);
  1135. //Case B
  1136. $this->setExpectedException('InvalidArgumentException');
  1137. $app2 = new Slim();
  1138. $app2->status(900);
  1139. }
  1140. /**
  1141. * Test Slim URL For
  1142. *
  1143. * Pre-conditions:
  1144. * Slim app instantiatd with named route;
  1145. *
  1146. * Post-conditions:
  1147. * Slim returns an accurate URL for the named route;
  1148. */
  1149. public function testSlimUrlFor(){
  1150. $app = new Slim();
  1151. $app->get('/hello/:name', function () {})->name('hello');
  1152. $this->assertEquals('/hello/Josh', $app->urlFor('hello', array('name' => 'Josh')));
  1153. }
  1154. /**
  1155. * Test Slim::redirect
  1156. *
  1157. * Pre-conditions:
  1158. * Case A: Status code is less than 300
  1159. * Case B: Status code is greater than 307
  1160. * Case C: Status code is 300
  1161. * Case D: Status code is 302 (between 300 and 307)
  1162. * Case E: Status code is 307
  1163. *
  1164. * Post-conditions:
  1165. * Case A: Response code is 500 (due to invalid redirect status)
  1166. * Case B: Response code is 500 (due to invalid redirect status)
  1167. * Case C: Response code is 300
  1168. * Case D: Response code is 302
  1169. * Case E: Response code is 307
  1170. */
  1171. public function testSlimRedirect() {
  1172. //Case A
  1173. $app1 = new Slim();
  1174. $app1->get('/', function () use ($app1) {
  1175. $app1->redirect('/foo', 200);
  1176. });
  1177. ob_start();
  1178. $app1->run();
  1179. $app1Out = ob_get_clean();
  1180. $this->assertEquals(500, $app1->response()->status());
  1181. //Case B
  1182. $app2 = new Slim();
  1183. $app2->get('/', function () use ($app2) {
  1184. $app2->redirect('/foo', 308);
  1185. });
  1186. ob_start();
  1187. $app2->run();
  1188. $app2Out = ob_get_clean();
  1189. $this->assertEquals(500, $app2->response()->status());
  1190. //Case C
  1191. $app3 = new Slim();
  1192. $app3->get('/', function () use ($app3) {
  1193. $app3->redirect('/foo', 300);
  1194. });
  1195. $app3->run();
  1196. $this->assertEquals(300, $app3->response()->status());
  1197. //Case D
  1198. $app4 = new Slim();
  1199. $app4->get('/', function () use ($app4) {
  1200. $app4->redirect('/foo', 302);
  1201. });
  1202. $app4->run();
  1203. $this->assertEquals(302, $app4->response()->status());
  1204. //Case E
  1205. $app5 = new Slim();
  1206. $app5->get('/', function () use ($app5) {
  1207. $app5->redirect('/foo', 307);
  1208. });
  1209. $app5->run();
  1210. $this->assertEquals(307, $app5->response()->status());
  1211. }
  1212. /************************************************
  1213. * SLIM FLASH MESSAGING
  1214. ************************************************/
  1215. /**
  1216. * Slim Flash
  1217. *
  1218. * Pre-conditions:
  1219. * Slim app sets Flash message for next request;
  1220. *
  1221. * Post-conditions:
  1222. * Message is persisted to $_SESSION after app is run;
  1223. */
  1224. public function testSlimFlash() {
  1225. $app = new Slim();
  1226. $app->get('/', function () use ($app) {
  1227. $app->flash('info', 'Foo');
  1228. });
  1229. $app->run();
  1230. $this->assertArrayHasKey('info', $_SESSION['flash']);
  1231. $this->assertEquals('Foo', $_SESSION['flash']['info']);
  1232. }
  1233. /**
  1234. * Slim Flash with Redirect
  1235. *
  1236. * Pre-conditions:
  1237. * Slim app sets Flash message for next request;
  1238. * Slim app halts with 302 redirect
  1239. *
  1240. * Post-conditions:
  1241. * Message is persisted to $_SESSION after app is run;
  1242. */
  1243. public function testSlimFlashWithRedirect() {
  1244. $app = new Slim();
  1245. $app->get('/', function () use ($app) {
  1246. $app->flash('info', 'Foo redirect');
  1247. $app->redirect('/foo');
  1248. });
  1249. $app->run();
  1250. $this->assertArrayHasKey('info', $_SESSION['flash']);
  1251. $this->assertEquals('Foo redirect', $_SESSION['flash']['info']);
  1252. }
  1253. /**
  1254. * Slim Flash Now
  1255. *
  1256. * Pre-conditions:
  1257. * Slim app sets Flash message for current request;
  1258. *
  1259. * Post-conditions:
  1260. * Message is persisted to View data;
  1261. */
  1262. public function testSlimFlashNow() {
  1263. $app = new Slim();
  1264. $app->get('/', function () use ($app) {
  1265. $app->flashNow('info', 'Foo');
  1266. });
  1267. $app->run();
  1268. $flash = $app->view()->getData('flash');
  1269. $this->assertEquals('Foo', $flash['info']);
  1270. }
  1271. /**
  1272. * Slim Keep Flash
  1273. *
  1274. * Pre-conditions:
  1275. * Slim app receives existing Flash message from $_SESSION;
  1276. *
  1277. * Post-conditions:
  1278. * Message is re-persisted to $_SESSION after app is run;
  1279. */
  1280. public function testSlimFlashKeep() {
  1281. $_SESSION['flash'] = array('info' => 'Foo');
  1282. $app = new Slim();
  1283. $app->get('/', function () use ($app) {
  1284. $app->flashKeep();
  1285. });
  1286. $app->run();
  1287. $this->assertArrayHasKey('info', $_SESSION['flash']);
  1288. $this->assertEquals('Foo', $_SESSION['flash']['info']);
  1289. }
  1290. /************************************************
  1291. * SLIM ERROR AND EXCEPTION HANDLING
  1292. ************************************************/
  1293. /**
  1294. * Test default and custom error handlers
  1295. *
  1296. * Pre-conditions:
  1297. * Invoked app route calls default error handler;
  1298. *
  1299. * Post-conditions:
  1300. * Response status code is 500;
  1301. */
  1302. public function testSlimError() {
  1303. $app = new Slim();
  1304. $app->get('/', function () use ($app) {
  1305. $app->error();
  1306. });
  1307. $app->run();
  1308. $this->assertEquals(500, $app->response()->status());
  1309. }
  1310. /**
  1311. * Test triggered errors are converted to ErrorExceptions
  1312. *
  1313. * Pre-conditions:
  1314. * Custom error handler defined;
  1315. * Invoked app route triggers error;
  1316. *
  1317. * Post-conditions:
  1318. * Response status is 500;
  1319. * Response body is equal to triggered error message;
  1320. * Error handler's argument is ErrorException instance;
  1321. */
  1322. public function testTriggeredErrorsAreConvertedToErrorExceptions() {
  1323. $app = new Slim(array(
  1324. 'debug' => false
  1325. ));
  1326. $app->error(function ( $e ) {
  1327. if ( $e instanceof ErrorException ) {
  1328. echo $e->getMessage();
  1329. }
  1330. });
  1331. $app->get('/', function () {
  1332. trigger_error('Foo I say!');
  1333. });
  1334. $app->run();
  1335. $this->assertEquals('Foo I say!', $app->response()->body());
  1336. $this->assertEquals(500, $app->response()->status());
  1337. }
  1338. /**
  1339. * Test error handler receives Exception as argument
  1340. *
  1341. * Pre-conditions:
  1342. * Custom error handler defined;
  1343. * Invoked app route throws Exception;
  1344. *
  1345. * Post-conditions:
  1346. * Response status is 500;
  1347. * Error handler's argument is the thrown Exception
  1348. */
  1349. public function testErrorHandlerReceivesException() {
  1350. $this->expectOutputString('ErrorException');
  1351. $app = new Slim(array(
  1352. 'debug' => false
  1353. ));
  1354. $app->error(function ( $e ) {
  1355. if ( $e instanceof Exception ) {
  1356. echo get_class($e);
  1357. }
  1358. });
  1359. $app->get('/', function () {
  1360. $result = 1 / 0;
  1361. });
  1362. $app->run();
  1363. $this->assertEquals(500, $app->response()->status());
  1364. }
  1365. /**
  1366. * Test error triggered with multiple applications
  1367. *
  1368. * Pre-conditions:
  1369. * Multiple Slim apps are instantiated;
  1370. * Both apps are run;
  1371. * One app returns 200 OK;
  1372. * One app triggers an error;
  1373. *
  1374. * Post-conditions:
  1375. * One app returns 200 OK with no Exceptions;
  1376. * One app returns 500 Error;
  1377. * Error triggered does not affect other app;
  1378. */
  1379. public function testErrorWithMultipleApps() {
  1380. $app1 = new Slim();
  1381. $app2 = new Slim();
  1382. $app1->get('/', function () {
  1383. trigger_error('error');
  1384. });
  1385. $app2->get('/', function () {
  1386. echo 'success';
  1387. });
  1388. $app1->run();
  1389. $app2->run();
  1390. $this->assertEquals(500, $app1->response()->status());
  1391. $this->assertEquals(200, $app2->response()->status());
  1392. }
  1393. /**
  1394. * Test Slim Not Found handler
  1395. *
  1396. * Pre-conditions:
  1397. * Initialize one Slim app without custom Not Found handler;
  1398. * Initialize one Slim app with custom Not Found Handler;
  1399. * Both app's routes do not match HTTP request;
  1400. *
  1401. * Post-conditions:
  1402. * Both Slim apps' response status is 404;
  1403. * Custom Not Found handler is invoked if specified;
  1404. */
  1405. public function testSlimRouteNotFound() {
  1406. $app1 = new Slim();
  1407. $app1->get('/foo', function () {});
  1408. ob_start();
  1409. $app1->run();
  1410. $app1Out = ob_get_clean();
  1411. $app2 = new Slim();
  1412. $app2->notFound(function () {
  1413. echo 'Not Found';
  1414. });
  1415. $app2->get('/bar', function () {});
  1416. ob_start();
  1417. $app2->run();
  1418. $app2Out = ob_get_clean();
  1419. $this->assertEquals(404, $app1->response()->status());
  1420. $this->assertEquals(404, $app2->response()->status());
  1421. $this->assertEquals('Not Found', $app2->response()->body());
  1422. }
  1423. /**
  1424. * Test Slim app without errors
  1425. *
  1426. * Pre-conditions:
  1427. * Slim app does not have Errors and Exceptions;
  1428. *
  1429. * Post-conditions:
  1430. * Slim app response status is 200;
  1431. */
  1432. public function testSlimOkResponse() {
  1433. $app = new Slim();
  1434. $app->get('/', function () {
  1435. echo 'Ok';
  1436. });
  1437. $app->run();
  1438. $this->assertEquals(200, $app->response()->status());
  1439. $this->assertEquals('Ok', $app->response()->body());
  1440. }
  1441. /************************************************
  1442. * SLIM HOOKS
  1443. ************************************************/
  1444. /**
  1445. * Test hook listener
  1446. *
  1447. * Pre-conditions:
  1448. * Slim app instantiated;
  1449. * Hook name does not exist;
  1450. * Listeners are callable objects;
  1451. *
  1452. * Post-conditions:
  1453. * Callables are invoked in expected order;
  1454. */
  1455. public function testRegistersAndCallsHooksByPriority() {
  1456. $this->expectOutputString('barfoo');
  1457. $app = new Slim();
  1458. $callable1 = function () { echo "foo"; };
  1459. $callable2 = function () { echo "bar"; };
  1460. $app->hook('test.hook.one', $callable1); //default is 10
  1461. $app->hook('test.hook.one', $callable2, 8);
  1462. $hooks = $app->getHooks();
  1463. $this->assertEquals(7, count($hooks)); //6 default, 1 custom
  1464. $app->applyHook('test.hook.one');
  1465. }
  1466. /**
  1467. * Test hook listener if listener is not callable
  1468. *
  1469. * Pre-conditions:
  1470. * Slim app instantiated;
  1471. * Hook name does not exist;
  1472. * Listener is NOT a callable object;
  1473. *
  1474. * Post-conditions:
  1475. * Hook is created;
  1476. * Callable is NOT assigned to hook;
  1477. */
  1478. public function testHookInvalidCallable() {
  1479. $app = new Slim();
  1480. $callable = 'test'; //NOT callable
  1481. $app->hook('test.hook.one', $callable);
  1482. $this->assertEquals(array(array()), $app->getHooks('test.hook.one'));
  1483. }
  1484. /**
  1485. * Test hook invocation if hook does not exist
  1486. *
  1487. * Pre-conditions:
  1488. * Slim app instantiated;
  1489. * Hook name does not exist;
  1490. *
  1491. * Post-conditions:
  1492. * Hook is created;
  1493. * Hook initialized with empty array;
  1494. */
  1495. public function testHookInvocationIfNotExists() {
  1496. $app = new Slim();
  1497. $app->applyHook('test.hook.one');
  1498. $this->assertEquals(array(array()), $app->getHooks('test.hook.one'));
  1499. }
  1500. /**
  1501. * Test clear hooks
  1502. *
  1503. * Pre-conditions:
  1504. * Slim app instantiated;
  1505. * Two hooks exist, each with one listener;
  1506. *
  1507. * Post-conditions:
  1508. * Case A: Listeners for 'test.hook.one' are cleared;
  1509. * Case B: Listeners for all hooks are cleared;
  1510. */
  1511. public function testHookClear() {
  1512. $app = new Slim();
  1513. $app->hook('test.hook.one', function () {});
  1514. $app->hook('test.hook.two', function () {});
  1515. $app->clearHooks('test.hook.two');
  1516. $this->assertEquals(array(array()), $app->getHooks('test.hook.two'));
  1517. $hookOne = $

Large files files are truncated, but you can click here to view the full file