PageRenderTime 25ms CodeModel.GetById 16ms RepoModel.GetById 1ms app.codeStats 0ms

/common/libraries/plugin/simpletest/dumper.php

https://bitbucket.org/chamilo/chamilo-dev/
PHP | 395 lines | 219 code | 18 blank | 158 comment | 32 complexity | 4cbea182b45b6c027c84426117f9b23e MD5 | raw file
Possible License(s): GPL-2.0, BSD-3-Clause, LGPL-2.1, LGPL-3.0, GPL-3.0, MIT
  1. <?php
  2. /**
  3. * base include file for SimpleTest
  4. * @package SimpleTest
  5. * @subpackage UnitTester
  6. * @version $Id: dumper.php 1723 2008-04-08 00:34:10Z lastcraft $
  7. */
  8. /**
  9. * does type matter
  10. */
  11. if (! defined('TYPE_MATTERS'))
  12. {
  13. define('TYPE_MATTERS', true);
  14. }
  15. /**
  16. * Displays variables as text and does diffs.
  17. * @package SimpleTest
  18. * @subpackage UnitTester
  19. */
  20. class SimpleDumper
  21. {
  22. /**
  23. * Renders a variable in a shorter form than print_r().
  24. * @param mixed $value Variable to render as a string.
  25. * @return string Human readable string form.
  26. * @access public
  27. */
  28. function describeValue($value)
  29. {
  30. $type = $this->getType($value);
  31. switch ($type)
  32. {
  33. case "Null" :
  34. return "NULL";
  35. case "Boolean" :
  36. return "Boolean: " . ($value ? "true" : "false");
  37. case "Array" :
  38. return "Array: " . count($value) . " items";
  39. case "Object" :
  40. return "Object: of " . get_class($value);
  41. case "String" :
  42. return "String: " . $this->clipString($value, 200);
  43. default :
  44. return "$type: $value";
  45. }
  46. return "Unknown";
  47. }
  48. /**
  49. * Gets the string representation of a type.
  50. * @param mixed $value Variable to check against.
  51. * @return string Type.
  52. * @access public
  53. */
  54. function getType($value)
  55. {
  56. if (! isset($value))
  57. {
  58. return "Null";
  59. }
  60. elseif (is_bool($value))
  61. {
  62. return "Boolean";
  63. }
  64. elseif (is_string($value))
  65. {
  66. return "String";
  67. }
  68. elseif (is_integer($value))
  69. {
  70. return "Integer";
  71. }
  72. elseif (is_float($value))
  73. {
  74. return "Float";
  75. }
  76. elseif (is_array($value))
  77. {
  78. return "Array";
  79. }
  80. elseif (is_resource($value))
  81. {
  82. return "Resource";
  83. }
  84. elseif (is_object($value))
  85. {
  86. return "Object";
  87. }
  88. return "Unknown";
  89. }
  90. /**
  91. * Creates a human readable description of the
  92. * difference between two variables. Uses a
  93. * dynamic call.
  94. * @param mixed $first First variable.
  95. * @param mixed $second Value to compare with.
  96. * @param boolean $identical If true then type anomolies count.
  97. * @return string Description of difference.
  98. * @access public
  99. */
  100. function describeDifference($first, $second, $identical = false)
  101. {
  102. if ($identical)
  103. {
  104. if (! $this->_isTypeMatch($first, $second))
  105. {
  106. return "with type mismatch as [" . $this->describeValue($first) . "] does not match [" . $this->describeValue($second) . "]";
  107. }
  108. }
  109. $type = $this->getType($first);
  110. if ($type == "Unknown")
  111. {
  112. return "with unknown type";
  113. }
  114. $method = '_describe' . $type . 'Difference';
  115. return $this->$method($first, $second, $identical);
  116. }
  117. /**
  118. * Tests to see if types match.
  119. * @param mixed $first First variable.
  120. * @param mixed $second Value to compare with.
  121. * @return boolean True if matches.
  122. * @access private
  123. */
  124. function _isTypeMatch($first, $second)
  125. {
  126. return ($this->getType($first) == $this->getType($second));
  127. }
  128. /**
  129. * Clips a string to a maximum length.
  130. * @param string $value String to truncate.
  131. * @param integer $size Minimum string size to show.
  132. * @param integer $position Centre of string section.
  133. * @return string Shortened version.
  134. * @access public
  135. */
  136. function clipString($value, $size, $position = 0)
  137. {
  138. $length = strlen($value);
  139. if ($length <= $size)
  140. {
  141. return $value;
  142. }
  143. $position = min($position, $length);
  144. $start = ($size / 2 > $position ? 0 : $position - $size / 2);
  145. if ($start + $size > $length)
  146. {
  147. $start = $length - $size;
  148. }
  149. $value = substr($value, $start, $size);
  150. return ($start > 0 ? "..." : "") . $value . ($start + $size < $length ? "..." : "");
  151. }
  152. /**
  153. * Creates a human readable description of the
  154. * difference between two variables. The minimal
  155. * version.
  156. * @param null $first First value.
  157. * @param mixed $second Value to compare with.
  158. * @return string Human readable description.
  159. * @access private
  160. */
  161. function _describeGenericDifference($first, $second)
  162. {
  163. return "as [" . $this->describeValue($first) . "] does not match [" . $this->describeValue($second) . "]";
  164. }
  165. /**
  166. * Creates a human readable description of the
  167. * difference between a null and another variable.
  168. * @param null $first First null.
  169. * @param mixed $second Null to compare with.
  170. * @param boolean $identical If true then type anomolies count.
  171. * @return string Human readable description.
  172. * @access private
  173. */
  174. function _describeNullDifference($first, $second, $identical)
  175. {
  176. return $this->_describeGenericDifference($first, $second);
  177. }
  178. /**
  179. * Creates a human readable description of the
  180. * difference between a boolean and another variable.
  181. * @param boolean $first First boolean.
  182. * @param mixed $second Boolean to compare with.
  183. * @param boolean $identical If true then type anomolies count.
  184. * @return string Human readable description.
  185. * @access private
  186. */
  187. function _describeBooleanDifference($first, $second, $identical)
  188. {
  189. return $this->_describeGenericDifference($first, $second);
  190. }
  191. /**
  192. * Creates a human readable description of the
  193. * difference between a string and another variable.
  194. * @param string $first First string.
  195. * @param mixed $second String to compare with.
  196. * @param boolean $identical If true then type anomolies count.
  197. * @return string Human readable description.
  198. * @access private
  199. */
  200. function _describeStringDifference($first, $second, $identical)
  201. {
  202. if (is_object($second) || is_array($second))
  203. {
  204. return $this->_describeGenericDifference($first, $second);
  205. }
  206. $position = $this->_stringDiffersAt($first, $second);
  207. $message = "at character $position";
  208. $message .= " with [" . $this->clipString($first, 200, $position) . "] and [" . $this->clipString($second, 200, $position) . "]";
  209. return $message;
  210. }
  211. /**
  212. * Creates a human readable description of the
  213. * difference between an integer and another variable.
  214. * @param integer $first First number.
  215. * @param mixed $second Number to compare with.
  216. * @param boolean $identical If true then type anomolies count.
  217. * @return string Human readable description.
  218. * @access private
  219. */
  220. function _describeIntegerDifference($first, $second, $identical)
  221. {
  222. if (is_object($second) || is_array($second))
  223. {
  224. return $this->_describeGenericDifference($first, $second);
  225. }
  226. return "because [" . $this->describeValue($first) . "] differs from [" . $this->describeValue($second) . "] by " . abs($first - $second);
  227. }
  228. /**
  229. * Creates a human readable description of the
  230. * difference between two floating point numbers.
  231. * @param float $first First float.
  232. * @param mixed $second Float to compare with.
  233. * @param boolean $identical If true then type anomolies count.
  234. * @return string Human readable description.
  235. * @access private
  236. */
  237. function _describeFloatDifference($first, $second, $identical)
  238. {
  239. if (is_object($second) || is_array($second))
  240. {
  241. return $this->_describeGenericDifference($first, $second);
  242. }
  243. return "because [" . $this->describeValue($first) . "] differs from [" . $this->describeValue($second) . "] by " . abs($first - $second);
  244. }
  245. /**
  246. * Creates a human readable description of the
  247. * difference between two arrays.
  248. * @param array $first First array.
  249. * @param mixed $second Array to compare with.
  250. * @param boolean $identical If true then type anomolies count.
  251. * @return string Human readable description.
  252. * @access private
  253. */
  254. function _describeArrayDifference($first, $second, $identical)
  255. {
  256. if (! is_array($second))
  257. {
  258. return $this->_describeGenericDifference($first, $second);
  259. }
  260. if (! $this->_isMatchingKeys($first, $second, $identical))
  261. {
  262. return "as key list [" . implode(", ", array_keys($first)) . "] does not match key list [" . implode(", ", array_keys($second)) . "]";
  263. }
  264. foreach (array_keys($first) as $key)
  265. {
  266. if ($identical && ($first[$key] === $second[$key]))
  267. {
  268. continue;
  269. }
  270. if (! $identical && ($first[$key] == $second[$key]))
  271. {
  272. continue;
  273. }
  274. return "with member [$key] " . $this->describeDifference($first[$key], $second[$key], $identical);
  275. }
  276. return "";
  277. }
  278. /**
  279. * Compares two arrays to see if their key lists match.
  280. * For an identical match, the ordering and types of the keys
  281. * is significant.
  282. * @param array $first First array.
  283. * @param array $second Array to compare with.
  284. * @param boolean $identical If true then type anomolies count.
  285. * @return boolean True if matching.
  286. * @access private
  287. */
  288. function _isMatchingKeys($first, $second, $identical)
  289. {
  290. $first_keys = array_keys($first);
  291. $second_keys = array_keys($second);
  292. if ($identical)
  293. {
  294. return ($first_keys === $second_keys);
  295. }
  296. sort($first_keys);
  297. sort($second_keys);
  298. return ($first_keys == $second_keys);
  299. }
  300. /**
  301. * Creates a human readable description of the
  302. * difference between a resource and another variable.
  303. * @param resource $first First resource.
  304. * @param mixed $second Resource to compare with.
  305. * @param boolean $identical If true then type anomolies count.
  306. * @return string Human readable description.
  307. * @access private
  308. */
  309. function _describeResourceDifference($first, $second, $identical)
  310. {
  311. return $this->_describeGenericDifference($first, $second);
  312. }
  313. /**
  314. * Creates a human readable description of the
  315. * difference between two objects.
  316. * @param object $first First object.
  317. * @param mixed $second Object to compare with.
  318. * @param boolean $identical If true then type anomolies count.
  319. * @return string Human readable description.
  320. * @access private
  321. */
  322. function _describeObjectDifference($first, $second, $identical)
  323. {
  324. if (! is_object($second))
  325. {
  326. return $this->_describeGenericDifference($first, $second);
  327. }
  328. return $this->_describeArrayDifference(get_object_vars($first), get_object_vars($second), $identical);
  329. }
  330. /**
  331. * Find the first character position that differs
  332. * in two strings by binary chop.
  333. * @param string $first First string.
  334. * @param string $second String to compare with.
  335. * @return integer Position of first differing
  336. * character.
  337. * @access private
  338. */
  339. function _stringDiffersAt($first, $second)
  340. {
  341. if (! $first || ! $second)
  342. {
  343. return 0;
  344. }
  345. if (strlen($first) < strlen($second))
  346. {
  347. list($first, $second) = array($second, $first);
  348. }
  349. $position = 0;
  350. $step = strlen($first);
  351. while ($step > 1)
  352. {
  353. $step = (integer) (($step + 1) / 2);
  354. if (strncmp($first, $second, $position + $step) == 0)
  355. {
  356. $position += $step;
  357. }
  358. }
  359. return $position;
  360. }
  361. /**
  362. * Sends a formatted dump of a variable to a string.
  363. * @param mixed $variable Variable to display.
  364. * @return string Output from print_r().
  365. * @access public
  366. * @static
  367. */
  368. function dump($variable)
  369. {
  370. ob_start();
  371. print_r($variable);
  372. $formatted = ob_get_contents();
  373. ob_end_clean();
  374. return $formatted;
  375. }
  376. }
  377. ?>