blob: 7afe40b09da15ed74c95c5f33004dd30ee494dc6 [file] [log] [blame]
Derek Jones4b9c6292011-07-01 17:40:48 -05001<?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
8 *
9 * Licensed under the Open Software License version 3.0
10 *
11 * 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
Derek Allard0ce73ef2010-01-18 15:48:25 +000043 var $active = TRUE;
Barry Mienydd671972010-10-04 16:33:58 +020044 var $results = array();
Derek Allard0ce73ef2010-01-18 15:48:25 +000045 var $strict = FALSE;
Barry Mienydd671972010-10-04 16:33:58 +020046 var $_template = NULL;
Derek Allard0ce73ef2010-01-18 15:48:25 +000047 var $_template_rows = NULL;
48 var $_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 */
77 function set_test_items($items = array())
78 {
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 */
Derek Allard0ce73ef2010-01-18 15:48:25 +000098 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 {
113 if ($this->strict == TRUE)
Barry Mienydd671972010-10-04 16:33:58 +0200114 $result = ($test === $expected) ? TRUE : FALSE;
Derek Allard2067d1a2008-11-13 22:59:24 +0000115 else
Barry Mienydd671972010-10-04 16:33:58 +0200116 $result = ($test == $expected) ? TRUE : FALSE;
117
Derek Allard2067d1a2008-11-13 22:59:24 +0000118 $extype = gettype($expected);
119 }
Barry Mienydd671972010-10-04 16:33:58 +0200120
Derek Allard2067d1a2008-11-13 22:59:24 +0000121 $back = $this->_backtrace();
Barry Mienydd671972010-10-04 16:33:58 +0200122
Derek Allard2067d1a2008-11-13 22:59:24 +0000123 $report[] = array (
124 'test_name' => $test_name,
125 'test_datatype' => gettype($test),
126 'res_datatype' => $extype,
127 'result' => ($result === TRUE) ? 'passed' : 'failed',
128 'file' => $back['file'],
Derek Allard0ce73ef2010-01-18 15:48:25 +0000129 'line' => $back['line'],
130 'notes' => $notes
Derek Allard2067d1a2008-11-13 22:59:24 +0000131 );
132
Derek Allard0ce73ef2010-01-18 15:48:25 +0000133 $this->results[] = $report;
134
Derek Allard2067d1a2008-11-13 22:59:24 +0000135 return($this->report($this->result($report)));
136 }
137
138 // --------------------------------------------------------------------
Barry Mienydd671972010-10-04 16:33:58 +0200139
Derek Allard2067d1a2008-11-13 22:59:24 +0000140 /**
141 * Generate a report
142 *
143 * Displays a table with the test data
144 *
145 * @access public
146 * @return string
147 */
148 function report($result = array())
149 {
150 if (count($result) == 0)
151 {
152 $result = $this->result();
153 }
154
155 $CI =& get_instance();
156 $CI->load->language('unit_test');
157
158 $this->_parse_template();
159
160 $r = '';
161 foreach ($result as $res)
162 {
163 $table = '';
164
165 foreach ($res as $key => $val)
166 {
Derek Allard2067d1a2008-11-13 22:59:24 +0000167 if ($key == $CI->lang->line('ut_result'))
168 {
169 if ($val == $CI->lang->line('ut_passed'))
170 {
171 $val = '<span style="color: #0C0;">'.$val.'</span>';
172 }
173 elseif ($val == $CI->lang->line('ut_failed'))
174 {
175 $val = '<span style="color: #C00;">'.$val.'</span>';
176 }
177 }
178
179 $temp = $this->_template_rows;
180 $temp = str_replace('{item}', $key, $temp);
181 $temp = str_replace('{result}', $val, $temp);
182 $table .= $temp;
183 }
184
185 $r .= str_replace('{rows}', $table, $this->_template);
186 }
187
188 return $r;
189 }
Barry Mienydd671972010-10-04 16:33:58 +0200190
Derek Allard2067d1a2008-11-13 22:59:24 +0000191 // --------------------------------------------------------------------
Barry Mienydd671972010-10-04 16:33:58 +0200192
Derek Allard2067d1a2008-11-13 22:59:24 +0000193 /**
194 * Use strict comparison
195 *
196 * Causes the evaluation to use === rather than ==
197 *
198 * @access public
199 * @param bool
200 * @return null
201 */
202 function use_strict($state = TRUE)
203 {
204 $this->strict = ($state == FALSE) ? FALSE : TRUE;
205 }
Barry Mienydd671972010-10-04 16:33:58 +0200206
Derek Allard2067d1a2008-11-13 22:59:24 +0000207 // --------------------------------------------------------------------
Barry Mienydd671972010-10-04 16:33:58 +0200208
Derek Allard2067d1a2008-11-13 22:59:24 +0000209 /**
210 * Make Unit testing active
211 *
212 * Enables/disables unit testing
213 *
214 * @access public
215 * @param bool
216 * @return null
217 */
218 function active($state = TRUE)
219 {
220 $this->active = ($state == FALSE) ? FALSE : TRUE;
221 }
Barry Mienydd671972010-10-04 16:33:58 +0200222
Derek Allard2067d1a2008-11-13 22:59:24 +0000223 // --------------------------------------------------------------------
Barry Mienydd671972010-10-04 16:33:58 +0200224
Derek Allard2067d1a2008-11-13 22:59:24 +0000225 /**
226 * Result Array
227 *
228 * Returns the raw result data
229 *
230 * @access public
231 * @return array
232 */
233 function result($results = array())
Barry Mienydd671972010-10-04 16:33:58 +0200234 {
Derek Allard2067d1a2008-11-13 22:59:24 +0000235 $CI =& get_instance();
236 $CI->load->language('unit_test');
Barry Mienydd671972010-10-04 16:33:58 +0200237
Derek Allard2067d1a2008-11-13 22:59:24 +0000238 if (count($results) == 0)
239 {
240 $results = $this->results;
241 }
Barry Mienydd671972010-10-04 16:33:58 +0200242
Derek Allard2067d1a2008-11-13 22:59:24 +0000243 $retval = array();
244 foreach ($results as $result)
245 {
246 $temp = array();
247 foreach ($result as $key => $val)
248 {
Derek Allard0ce73ef2010-01-18 15:48:25 +0000249 if ( ! in_array($key, $this->_test_items_visible))
250 {
251 continue;
252 }
253
Derek Allard2067d1a2008-11-13 22:59:24 +0000254 if (is_array($val))
255 {
256 foreach ($val as $k => $v)
257 {
258 if (FALSE !== ($line = $CI->lang->line(strtolower('ut_'.$v))))
259 {
260 $v = $line;
Barry Mienydd671972010-10-04 16:33:58 +0200261 }
262 $temp[$CI->lang->line('ut_'.$k)] = $v;
Derek Allard2067d1a2008-11-13 22:59:24 +0000263 }
264 }
265 else
266 {
267 if (FALSE !== ($line = $CI->lang->line(strtolower('ut_'.$val))))
268 {
269 $val = $line;
Barry Mienydd671972010-10-04 16:33:58 +0200270 }
Derek Allard2067d1a2008-11-13 22:59:24 +0000271 $temp[$CI->lang->line('ut_'.$key)] = $val;
272 }
273 }
Barry Mienydd671972010-10-04 16:33:58 +0200274
Derek Allard2067d1a2008-11-13 22:59:24 +0000275 $retval[] = $temp;
276 }
Barry Mienydd671972010-10-04 16:33:58 +0200277
Derek Allard2067d1a2008-11-13 22:59:24 +0000278 return $retval;
279 }
Barry Mienydd671972010-10-04 16:33:58 +0200280
Derek Allard2067d1a2008-11-13 22:59:24 +0000281 // --------------------------------------------------------------------
Barry Mienydd671972010-10-04 16:33:58 +0200282
Derek Allard2067d1a2008-11-13 22:59:24 +0000283 /**
284 * Set the template
285 *
286 * This lets us set the template to be used to display results
287 *
288 * @access public
289 * @param string
290 * @return void
Barry Mienydd671972010-10-04 16:33:58 +0200291 */
Derek Allard2067d1a2008-11-13 22:59:24 +0000292 function set_template($template)
293 {
294 $this->_template = $template;
295 }
Barry Mienydd671972010-10-04 16:33:58 +0200296
Derek Allard2067d1a2008-11-13 22:59:24 +0000297 // --------------------------------------------------------------------
Barry Mienydd671972010-10-04 16:33:58 +0200298
Derek Allard2067d1a2008-11-13 22:59:24 +0000299 /**
300 * Generate a backtrace
301 *
302 * This lets us show file names and line numbers
303 *
304 * @access private
305 * @return array
306 */
307 function _backtrace()
308 {
309 if (function_exists('debug_backtrace'))
310 {
311 $back = debug_backtrace();
Barry Mienydd671972010-10-04 16:33:58 +0200312
Derek Allard2067d1a2008-11-13 22:59:24 +0000313 $file = ( ! isset($back['1']['file'])) ? '' : $back['1']['file'];
314 $line = ( ! isset($back['1']['line'])) ? '' : $back['1']['line'];
Barry Mienydd671972010-10-04 16:33:58 +0200315
Derek Allard2067d1a2008-11-13 22:59:24 +0000316 return array('file' => $file, 'line' => $line);
317 }
318 return array('file' => 'Unknown', 'line' => 'Unknown');
319 }
320
321 // --------------------------------------------------------------------
Barry Mienydd671972010-10-04 16:33:58 +0200322
Derek Allard2067d1a2008-11-13 22:59:24 +0000323 /**
324 * Get Default Template
325 *
326 * @access private
327 * @return string
328 */
329 function _default_template()
Barry Mienydd671972010-10-04 16:33:58 +0200330 {
Derek Allard2067d1a2008-11-13 22:59:24 +0000331 $this->_template = "\n".'<table style="width:100%; font-size:small; margin:10px 0; border-collapse:collapse; border:1px solid #CCC;">';
332 $this->_template .= '{rows}';
333 $this->_template .= "\n".'</table>';
Barry Mienydd671972010-10-04 16:33:58 +0200334
Derek Allard2067d1a2008-11-13 22:59:24 +0000335 $this->_template_rows = "\n\t".'<tr>';
336 $this->_template_rows .= "\n\t\t".'<th style="text-align: left; border-bottom:1px solid #CCC;">{item}</th>';
337 $this->_template_rows .= "\n\t\t".'<td style="border-bottom:1px solid #CCC;">{result}</td>';
Barry Mienydd671972010-10-04 16:33:58 +0200338 $this->_template_rows .= "\n\t".'</tr>';
Derek Allard2067d1a2008-11-13 22:59:24 +0000339 }
Barry Mienydd671972010-10-04 16:33:58 +0200340
Derek Allard2067d1a2008-11-13 22:59:24 +0000341 // --------------------------------------------------------------------
342
343 /**
344 * Parse Template
345 *
346 * Harvests the data within the template {pseudo-variables}
347 *
348 * @access private
349 * @return void
350 */
Barry Mienydd671972010-10-04 16:33:58 +0200351 function _parse_template()
352 {
353 if ( ! is_null($this->_template_rows))
354 {
355 return;
356 }
357
358 if (is_null($this->_template))
359 {
360 $this->_default_template();
361 return;
362 }
363
Derek Allard2067d1a2008-11-13 22:59:24 +0000364 if ( ! preg_match("/\{rows\}(.*?)\{\/rows\}/si", $this->_template, $match))
365 {
Barry Mienydd671972010-10-04 16:33:58 +0200366 $this->_default_template();
367 return;
Derek Allard2067d1a2008-11-13 22:59:24 +0000368 }
369
370 $this->_template_rows = $match['1'];
Barry Mienydd671972010-10-04 16:33:58 +0200371 $this->_template = str_replace($match['0'], '{rows}', $this->_template);
372 }
373
Derek Allard2067d1a2008-11-13 22:59:24 +0000374}
375// END Unit_test Class
376
377/**
378 * Helper functions to test boolean true/false
379 *
380 *
381 * @access private
382 * @return bool
383 */
384function is_true($test)
385{
386 return (is_bool($test) AND $test === TRUE) ? TRUE : FALSE;
387}
388function is_false($test)
389{
390 return (is_bool($test) AND $test === FALSE) ? TRUE : FALSE;
391}
392
393
394/* End of file Unit_test.php */
Gerry33c9c3f2011-09-25 00:32:38 +0800395/* Location: ./system/libraries/Unit_test.php */