LimeTesterObject.php 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121
  1. <?php
  2. /*
  3. * This file is part of the Lime framework.
  4. *
  5. * (c) Fabien Potencier <fabien.potencier@symfony-project.com>
  6. * (c) Bernhard Schussek <bernhard.schussek@symfony-project.com>
  7. *
  8. * This source file is subject to the MIT license that is bundled
  9. * with this source code in the file LICENSE.
  10. */
  11. class LimeTesterObject extends LimeTesterArray
  12. {
  13. private static
  14. $equal = array(),
  15. $unequal = array();
  16. private
  17. $object = null;
  18. public static function toArray($object)
  19. {
  20. if (!is_object($object))
  21. {
  22. throw new InvalidArgumentException('The argument must be an object');
  23. }
  24. $array = array();
  25. foreach ((array)$object as $key => $value)
  26. {
  27. // properties are transformed to keys in the following way:
  28. // private $property => "\0Classname\0property"
  29. // protected $property => "\0*\0property"
  30. // public $property => "property"
  31. if (preg_match('/^\0.+\0(.+)$/', $key, $matches))
  32. {
  33. $key = $matches[1];
  34. }
  35. $array[$key] = $value;
  36. }
  37. return $array;
  38. }
  39. public function __construct($object)
  40. {
  41. $this->object = $object;
  42. $this->type = get_class($object);
  43. parent::__construct(self::toArray($object));
  44. }
  45. protected function getType()
  46. {
  47. return 'object('.$this->type.')';
  48. }
  49. public function is(LimeTesterInterface $expected)
  50. {
  51. // allow comparison with strings if object implements __toString()
  52. if ($expected instanceof LimeTesterString && method_exists($this->object, '__toString'))
  53. {
  54. if ($expected->value != (string)$this->object)
  55. {
  56. throw new LimeAssertionFailedException($this, $expected);
  57. }
  58. }
  59. else
  60. {
  61. // don't compare twice to allow for cyclic dependencies
  62. if (in_array(array($this->value, $expected->value), self::$equal, true) || in_array(array($expected->value, $this->value), self::$equal, true))
  63. {
  64. return;
  65. }
  66. self::$equal[] = array($this->value, $expected->value);
  67. // don't compare objects if they are identical
  68. // this helps to avoid the error "maximum function nesting level reached"
  69. // CAUTION: this conditional clause is not tested
  70. if (!$expected instanceof self || $this->object !== $expected->object)
  71. {
  72. parent::is($expected);
  73. }
  74. }
  75. }
  76. public function isnt(LimeTesterInterface $expected)
  77. {
  78. // don't compare twice to allow for cyclic dependencies
  79. if (in_array(array($this->value, $expected->value), self::$unequal, true) || in_array(array($expected->value, $this->value), self::$unequal, true))
  80. {
  81. return;
  82. }
  83. self::$unequal[] = array($this->value, $expected->value);
  84. parent::isnt($expected);
  85. }
  86. public function same(LimeTesterInterface $expected)
  87. {
  88. if (!$expected instanceof self || $this->object !== $expected->object)
  89. {
  90. throw new LimeAssertionFailedException($this, $expected);
  91. }
  92. }
  93. public function isntSame(LimeTesterInterface $expected)
  94. {
  95. if ($expected instanceof self && $this->object === $expected->object)
  96. {
  97. throw new LimeAssertionFailedException($this, $expected);
  98. }
  99. }
  100. }