Merge pull request #22808 from colemanw/searchKitMailingTask
[civicrm-core.git] / Civi / Test / GenericAssertionsTrait.php
1 <?php
2
3 namespace Civi\Test;
4
5 /**
6 * Class ExtraAssertionsTrait
7 * @package Civi\Test
8 *
9 * A small library of generic assertions - which are slightly more sophisticated than
10 * the default (`assertEquals()`, `assertTrue()`) but *not* domain specific.
11 */
12 trait GenericAssertionsTrait {
13
14 /**
15 * @param string $expected
16 * Ex: 'array', 'object', 'int'
17 * @param $actual
18 * The variable/item to check.
19 * @param string $message
20 */
21 public function assertType($expected, $actual, $message = '') {
22 return $this->assertInternalType($expected, $actual, $message);
23 }
24
25 /**
26 * Assert that two array-trees are exactly equal.
27 *
28 * The ordering of keys do not affect the outcome (within either the roots
29 * or in any child elements).
30 *
31 * Error messages will reveal a readable -path-, regardless of how many
32 * levels of nesting are present.
33 *
34 * @param array $expected
35 * @param array $actual
36 */
37 public function assertTreeEquals($expected, $actual) {
38 $e = [];
39 $a = [];
40 \CRM_Utils_Array::flatten($expected, $e, '', ':::');
41 \CRM_Utils_Array::flatten($actual, $a, '', ':::');
42 ksort($e);
43 ksort($a);
44
45 $this->assertEquals($e, $a);
46 }
47
48 /**
49 * Assert that two numbers are approximately equal,
50 * give or take some $tolerance.
51 *
52 * @param int|float $expected
53 * @param int|float $actual
54 * @param int|float $tolerance
55 * Any differences <$tolerance are considered irrelevant.
56 * Differences >=$tolerance are considered relevant.
57 * @param string $message
58 */
59 public function assertApproxEquals($expected, $actual, $tolerance, $message = NULL) {
60 if ($tolerance == 1 && is_int($expected) && is_int($actual)) {
61 // ^^ loose equality is on purpose
62 throw new \CRM_Core_Exception('assertApproxEquals is a fractions-first thinking function and compares integers with a tolerance of 1 as if they are identical. You want a bigger number, such as 2, or 5.');
63 }
64 $diff = abs($actual - $expected);
65 if ($message === NULL) {
66 $message = sprintf("approx-equals: expected=[%.3f] actual=[%.3f] diff=[%.3f] tolerance=[%.3f]", $expected, $actual, $diff, $tolerance);
67 }
68 $this->assertTrue($diff < $tolerance, $message);
69 }
70
71 /**
72 * Assert attributes are equal.
73 *
74 * @param array $expectedValues
75 * @param array $actualValues
76 * @param string $message
77 *
78 * @throws \PHPUnit_Framework_AssertionFailedError
79 */
80 public function assertAttributesEquals($expectedValues, $actualValues, $message = NULL) {
81 foreach ($expectedValues as $paramName => $paramValue) {
82 if (isset($actualValues[$paramName])) {
83 $this->assertEquals($paramValue, $actualValues[$paramName], "Value Mismatch On $paramName - value 1 is " . print_r($paramValue, TRUE) . " value 2 is " . print_r($actualValues[$paramName], TRUE));
84 }
85 else {
86 $this->assertNull($expectedValues[$paramName], "Attribute '$paramName' not present in actual array and we expected it to be " . $expectedValues[$paramName]);
87 }
88 }
89 }
90
91 /**
92 * @param string|int $key
93 * @param array $list
94 */
95 public function assertArrayKeyExists($key, &$list) {
96 $result = isset($list[$key]);
97 $this->assertTrue($result, sprintf("%s element exists?", $key));
98 }
99
100 /**
101 * @param string|int $key
102 * @param array $list
103 */
104 public function assertArrayValueNotNull($key, &$list) {
105 $this->assertArrayKeyExists($key, $list);
106
107 $value = $list[$key] ?? NULL;
108 $this->assertTrue($value,
109 sprintf("%s element not null?", $key)
110 );
111 }
112
113 /**
114 * Assert the 2 arrays have the same values.
115 *
116 * The order of arrays, and keys of the arrays, do not affect the outcome.
117 *
118 * @param array $array1
119 * @param array $array2
120 */
121 public function assertArrayValuesEqual($array1, $array2) {
122 $array1 = array_values($array1);
123 $array2 = array_values($array2);
124 sort($array1);
125 sort($array2);
126 $this->assertEquals($array1, $array2);
127 }
128
129 }