blob: dac1a5c7e2daa8c9478689506470fc00760a88d3 [file] [log] [blame]
Andrey Andreev2a27d312011-12-25 17:08:24 +02001<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
Derek Allard2067d1a2008-11-13 22:59:24 +00002/**
3 * CodeIgniter
4 *
Greg Aker741de1c2010-11-10 14:52:57 -06005 * An open source application development framework for PHP 5.1.6 or newer
Derek Allard2067d1a2008-11-13 22:59:24 +00006 *
Derek Jonesf4a4bd82011-10-20 12:18:42 -05007 * NOTICE OF LICENSE
Andrey Andreev2a27d312011-12-25 17:08:24 +02008 *
Derek Jonesf4a4bd82011-10-20 12:18:42 -05009 * Licensed under the Open Software License version 3.0
Andrey Andreev2a27d312011-12-25 17:08:24 +020010 *
Derek Jonesf4a4bd82011-10-20 12:18:42 -050011 * This source file is subject to the Open Software License (OSL 3.0) that is
12 * bundled with this package in the files license.txt / license.rst. It is
13 * also available through the world wide web at this URL:
14 * http://opensource.org/licenses/OSL-3.0
15 * If you did not receive a copy of the license and are unable to obtain it
16 * through the world wide web, please send an email to
17 * licensing@ellislab.com so we can send you a copy immediately.
18 *
Derek Allard2067d1a2008-11-13 22:59:24 +000019 * @package CodeIgniter
Derek Jonesf4a4bd82011-10-20 12:18:42 -050020 * @author EllisLab Dev Team
21 * @copyright Copyright (c) 2008 - 2011, EllisLab, Inc. (http://ellislab.com/)
22 * @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
Derek Allard2067d1a2008-11-13 22:59:24 +000023 * @link http://codeigniter.com
24 * @since Version 1.3.1
25 * @filesource
26 */
27
28// ------------------------------------------------------------------------
29
30/**
31 * Unit Testing Class
32 *
33 * Simple testing class
34 *
35 * @package CodeIgniter
36 * @subpackage Libraries
37 * @category UnitTesting
Derek Jonesf4a4bd82011-10-20 12:18:42 -050038 * @author EllisLab Dev Team
Gerry33c9c3f2011-09-25 00:32:38 +080039 * @link http://codeigniter.com/user_guide/libraries/unit_testing.html
Derek Allard2067d1a2008-11-13 22:59:24 +000040 */
41class CI_Unit_test {
42
Andrey Andreev2a27d312011-12-25 17:08:24 +020043 public $active = TRUE;
44 public $results = array();
45 public $strict = FALSE;
46 private $_template = NULL;
47 private $_template_rows = NULL;
48 private $_test_items_visible = array();
Derek Allard2067d1a2008-11-13 22:59:24 +000049
Greg Akera9263282010-11-10 15:26:43 -060050 public function __construct()
Derek Allard2067d1a2008-11-13 22:59:24 +000051 {
Derek Allard0ce73ef2010-01-18 15:48:25 +000052 // These are the default items visible when a test is run.
53 $this->_test_items_visible = array (
54 'test_name',
55 'test_datatype',
56 'res_datatype',
57 'result',
58 'file',
59 'line',
60 'notes'
61 );
62
Derek Allard2067d1a2008-11-13 22:59:24 +000063 log_message('debug', "Unit Testing Class Initialized");
Derek Allard0ce73ef2010-01-18 15:48:25 +000064 }
Derek Allard2067d1a2008-11-13 22:59:24 +000065
66 // --------------------------------------------------------------------
Derek Allard0ce73ef2010-01-18 15:48:25 +000067
68 /**
69 * Run the tests
70 *
71 * Runs the supplied tests
72 *
73 * @access public
74 * @param array
75 * @return void
76 */
Andrey Andreev2a27d312011-12-25 17:08:24 +020077 public function set_test_items($items = array())
Derek Allard0ce73ef2010-01-18 15:48:25 +000078 {
79 if ( ! empty($items) AND is_array($items))
80 {
81 $this->_test_items_visible = $items;
82 }
83 }
84
85 // --------------------------------------------------------------------
86
Derek Allard2067d1a2008-11-13 22:59:24 +000087 /**
88 * Run the tests
89 *
90 * Runs the supplied tests
91 *
92 * @access public
93 * @param mixed
94 * @param mixed
95 * @param string
96 * @return string
Barry Mienydd671972010-10-04 16:33:58 +020097 */
Andrey Andreev2a27d312011-12-25 17:08:24 +020098 public function run($test, $expected = TRUE, $test_name = 'undefined', $notes = '')
Derek Allard2067d1a2008-11-13 22:59:24 +000099 {
100 if ($this->active == FALSE)
101 {
102 return FALSE;
103 }
Barry Mienydd671972010-10-04 16:33:58 +0200104
Derek Allard82d6ec42009-12-22 13:53:53 +0000105 if (in_array($expected, array('is_object', 'is_string', 'is_bool', 'is_true', 'is_false', 'is_int', 'is_numeric', 'is_float', 'is_double', 'is_array', 'is_null'), TRUE))
Derek Allard2067d1a2008-11-13 22:59:24 +0000106 {
107 $expected = str_replace('is_float', 'is_double', $expected);
Barry Mienydd671972010-10-04 16:33:58 +0200108 $result = ($expected($test)) ? TRUE : FALSE;
Derek Allard2067d1a2008-11-13 22:59:24 +0000109 $extype = str_replace(array('true', 'false'), 'bool', str_replace('is_', '', $expected));
110 }
111 else
112 {
Andrey Andreev2a27d312011-12-25 17:08:24 +0200113 $result = ($this->strict == TRUE) ? ($test === $expected) : ($test == $expected);
Derek Allard2067d1a2008-11-13 22:59:24 +0000114 $extype = gettype($expected);
115 }
Barry Mienydd671972010-10-04 16:33:58 +0200116
Derek Allard2067d1a2008-11-13 22:59:24 +0000117 $back = $this->_backtrace();
Barry Mienydd671972010-10-04 16:33:58 +0200118
Derek Allard2067d1a2008-11-13 22:59:24 +0000119 $report[] = array (
120 'test_name' => $test_name,
121 'test_datatype' => gettype($test),
122 'res_datatype' => $extype,
123 'result' => ($result === TRUE) ? 'passed' : 'failed',
124 'file' => $back['file'],
Derek Allard0ce73ef2010-01-18 15:48:25 +0000125 'line' => $back['line'],
126 'notes' => $notes
Derek Allard2067d1a2008-11-13 22:59:24 +0000127 );
128
Derek Allard0ce73ef2010-01-18 15:48:25 +0000129 $this->results[] = $report;
130
Derek Allard2067d1a2008-11-13 22:59:24 +0000131 return($this->report($this->result($report)));
132 }
133
134 // --------------------------------------------------------------------
Barry Mienydd671972010-10-04 16:33:58 +0200135
Derek Allard2067d1a2008-11-13 22:59:24 +0000136 /**
137 * Generate a report
138 *
139 * Displays a table with the test data
140 *
141 * @access public
142 * @return string
143 */
Andrey Andreev2a27d312011-12-25 17:08:24 +0200144 public function report($result = array())
Derek Allard2067d1a2008-11-13 22:59:24 +0000145 {
Andrey Andreev2a27d312011-12-25 17:08:24 +0200146 if (count($result) === 0)
Derek Allard2067d1a2008-11-13 22:59:24 +0000147 {
148 $result = $this->result();
149 }
150
151 $CI =& get_instance();
152 $CI->load->language('unit_test');
153
154 $this->_parse_template();
155
156 $r = '';
157 foreach ($result as $res)
158 {
159 $table = '';
160
161 foreach ($res as $key => $val)
162 {
Derek Allard2067d1a2008-11-13 22:59:24 +0000163 if ($key == $CI->lang->line('ut_result'))
164 {
165 if ($val == $CI->lang->line('ut_passed'))
166 {
167 $val = '<span style="color: #0C0;">'.$val.'</span>';
168 }
169 elseif ($val == $CI->lang->line('ut_failed'))
170 {
171 $val = '<span style="color: #C00;">'.$val.'</span>';
172 }
173 }
174
Andrey Andreev2a27d312011-12-25 17:08:24 +0200175 $table .= str_replace(array('{item}', '{result}'), array($key, $val), $this->_template_rows);
Derek Allard2067d1a2008-11-13 22:59:24 +0000176 }
177
178 $r .= str_replace('{rows}', $table, $this->_template);
179 }
180
181 return $r;
182 }
Barry Mienydd671972010-10-04 16:33:58 +0200183
Derek Allard2067d1a2008-11-13 22:59:24 +0000184 // --------------------------------------------------------------------
Barry Mienydd671972010-10-04 16:33:58 +0200185
Derek Allard2067d1a2008-11-13 22:59:24 +0000186 /**
187 * Use strict comparison
188 *
189 * Causes the evaluation to use === rather than ==
190 *
191 * @access public
192 * @param bool
193 * @return null
194 */
Andrey Andreev2a27d312011-12-25 17:08:24 +0200195 public function use_strict($state = TRUE)
Derek Allard2067d1a2008-11-13 22:59:24 +0000196 {
Andrey Andreev2a27d312011-12-25 17:08:24 +0200197 $this->strict = (bool) $state;
Derek Allard2067d1a2008-11-13 22:59:24 +0000198 }
Barry Mienydd671972010-10-04 16:33:58 +0200199
Derek Allard2067d1a2008-11-13 22:59:24 +0000200 // --------------------------------------------------------------------
Barry Mienydd671972010-10-04 16:33:58 +0200201
Derek Allard2067d1a2008-11-13 22:59:24 +0000202 /**
203 * Make Unit testing active
204 *
205 * Enables/disables unit testing
206 *
207 * @access public
208 * @param bool
209 * @return null
210 */
Andrey Andreev2a27d312011-12-25 17:08:24 +0200211 public function active($state = TRUE)
Derek Allard2067d1a2008-11-13 22:59:24 +0000212 {
Andrey Andreev2a27d312011-12-25 17:08:24 +0200213 $this->active = (bool) $state;
Derek Allard2067d1a2008-11-13 22:59:24 +0000214 }
Barry Mienydd671972010-10-04 16:33:58 +0200215
Derek Allard2067d1a2008-11-13 22:59:24 +0000216 // --------------------------------------------------------------------
Barry Mienydd671972010-10-04 16:33:58 +0200217
Derek Allard2067d1a2008-11-13 22:59:24 +0000218 /**
219 * Result Array
220 *
221 * Returns the raw result data
222 *
223 * @access public
224 * @return array
225 */
Andrey Andreev2a27d312011-12-25 17:08:24 +0200226 public function result($results = array())
Barry Mienydd671972010-10-04 16:33:58 +0200227 {
Derek Allard2067d1a2008-11-13 22:59:24 +0000228 $CI =& get_instance();
229 $CI->load->language('unit_test');
Barry Mienydd671972010-10-04 16:33:58 +0200230
Andrey Andreev2a27d312011-12-25 17:08:24 +0200231 if (count($results) === 0)
Derek Allard2067d1a2008-11-13 22:59:24 +0000232 {
233 $results = $this->results;
234 }
Barry Mienydd671972010-10-04 16:33:58 +0200235
Derek Allard2067d1a2008-11-13 22:59:24 +0000236 $retval = array();
237 foreach ($results as $result)
238 {
239 $temp = array();
240 foreach ($result as $key => $val)
241 {
Derek Allard0ce73ef2010-01-18 15:48:25 +0000242 if ( ! in_array($key, $this->_test_items_visible))
243 {
244 continue;
245 }
246
Derek Allard2067d1a2008-11-13 22:59:24 +0000247 if (is_array($val))
248 {
249 foreach ($val as $k => $v)
250 {
251 if (FALSE !== ($line = $CI->lang->line(strtolower('ut_'.$v))))
252 {
253 $v = $line;
Barry Mienydd671972010-10-04 16:33:58 +0200254 }
255 $temp[$CI->lang->line('ut_'.$k)] = $v;
Derek Allard2067d1a2008-11-13 22:59:24 +0000256 }
257 }
258 else
259 {
260 if (FALSE !== ($line = $CI->lang->line(strtolower('ut_'.$val))))
261 {
262 $val = $line;
Barry Mienydd671972010-10-04 16:33:58 +0200263 }
Derek Allard2067d1a2008-11-13 22:59:24 +0000264 $temp[$CI->lang->line('ut_'.$key)] = $val;
265 }
266 }
Barry Mienydd671972010-10-04 16:33:58 +0200267
Derek Allard2067d1a2008-11-13 22:59:24 +0000268 $retval[] = $temp;
269 }
Barry Mienydd671972010-10-04 16:33:58 +0200270
Derek Allard2067d1a2008-11-13 22:59:24 +0000271 return $retval;
272 }
Barry Mienydd671972010-10-04 16:33:58 +0200273
Derek Allard2067d1a2008-11-13 22:59:24 +0000274 // --------------------------------------------------------------------
Barry Mienydd671972010-10-04 16:33:58 +0200275
Derek Allard2067d1a2008-11-13 22:59:24 +0000276 /**
277 * Set the template
278 *
279 * This lets us set the template to be used to display results
280 *
281 * @access public
282 * @param string
283 * @return void
Barry Mienydd671972010-10-04 16:33:58 +0200284 */
Andrey Andreev2a27d312011-12-25 17:08:24 +0200285 public function set_template($template)
Derek Allard2067d1a2008-11-13 22:59:24 +0000286 {
287 $this->_template = $template;
288 }
Barry Mienydd671972010-10-04 16:33:58 +0200289
Derek Allard2067d1a2008-11-13 22:59:24 +0000290 // --------------------------------------------------------------------
Barry Mienydd671972010-10-04 16:33:58 +0200291
Derek Allard2067d1a2008-11-13 22:59:24 +0000292 /**
293 * Generate a backtrace
294 *
295 * This lets us show file names and line numbers
296 *
297 * @access private
298 * @return array
299 */
Andrey Andreev2a27d312011-12-25 17:08:24 +0200300 private function _backtrace()
Derek Allard2067d1a2008-11-13 22:59:24 +0000301 {
302 if (function_exists('debug_backtrace'))
303 {
304 $back = debug_backtrace();
Andrey Andreev2a27d312011-12-25 17:08:24 +0200305 return array(
306 'file' => (isset($back[1]['file']) ? $back[1]['file'] : ''),
307 'line' => (isset($back[1]['line']) ? $back[1]['line'] : '')
308 );
Derek Allard2067d1a2008-11-13 22:59:24 +0000309 }
310 return array('file' => 'Unknown', 'line' => 'Unknown');
311 }
312
313 // --------------------------------------------------------------------
Barry Mienydd671972010-10-04 16:33:58 +0200314
Derek Allard2067d1a2008-11-13 22:59:24 +0000315 /**
316 * Get Default Template
317 *
318 * @access private
319 * @return string
320 */
Andrey Andreev2a27d312011-12-25 17:08:24 +0200321 private function _default_template()
Barry Mienydd671972010-10-04 16:33:58 +0200322 {
Andrey Andreev2a27d312011-12-25 17:08:24 +0200323 $this->_template = "\n".'<table style="width:100%; font-size:small; margin:10px 0; border-collapse:collapse; border:1px solid #CCC;">{rows}'."\n".'</table>';
Barry Mienydd671972010-10-04 16:33:58 +0200324
Andrey Andreev2a27d312011-12-25 17:08:24 +0200325 $this->_template_rows = "\n\t<tr>\n\t\t".'<th style="text-align: left; border-bottom:1px solid #CCC;">{item}</th>'
326 . "\n\t\t".'<td style="border-bottom:1px solid #CCC;">{result}</td>'."\n\t</tr>";
Derek Allard2067d1a2008-11-13 22:59:24 +0000327 }
Barry Mienydd671972010-10-04 16:33:58 +0200328
Derek Allard2067d1a2008-11-13 22:59:24 +0000329 // --------------------------------------------------------------------
330
331 /**
332 * Parse Template
333 *
334 * Harvests the data within the template {pseudo-variables}
335 *
336 * @access private
337 * @return void
338 */
Andrey Andreev2a27d312011-12-25 17:08:24 +0200339 private function _parse_template()
Barry Mienydd671972010-10-04 16:33:58 +0200340 {
341 if ( ! is_null($this->_template_rows))
342 {
343 return;
344 }
345
Andrey Andreev2a27d312011-12-25 17:08:24 +0200346 if (is_null($this->_template) OR ! preg_match("/\{rows\}(.*?)\{\/rows\}/si", $this->_template, $match))
Barry Mienydd671972010-10-04 16:33:58 +0200347 {
348 $this->_default_template();
349 return;
350 }
351
Andrey Andreev2a27d312011-12-25 17:08:24 +0200352 $this->_template_rows = $match[1];
353 $this->_template = str_replace($match[0], '{rows}', $this->_template);
Barry Mienydd671972010-10-04 16:33:58 +0200354 }
355
Derek Allard2067d1a2008-11-13 22:59:24 +0000356}
357// END Unit_test Class
358
359/**
360 * Helper functions to test boolean true/false
361 *
362 *
363 * @access private
364 * @return bool
365 */
366function is_true($test)
367{
368 return (is_bool($test) AND $test === TRUE) ? TRUE : FALSE;
369}
370function is_false($test)
371{
372 return (is_bool($test) AND $test === FALSE) ? TRUE : FALSE;
373}
374
375
376/* End of file Unit_test.php */
Gerry33c9c3f2011-09-25 00:32:38 +0800377/* Location: ./system/libraries/Unit_test.php */