Failed Conditions
Pull Request — master (#8)
by
unknown
02:28
created

src/ArrayAssertsTrait.php (1 issue)

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

1
<?php
2
3
namespace Chadicus;
4
5
/**
6
 * Trait for adding asserts for arrays
7
 */
8
trait ArrayAssertsTrait
9
{
10
    /**
11
     * Asserts the given $actual array is the same as the $expected array disregarding index order
12
     *
13
     * @param array       $expected The expected array.
14
     * @param mixed       $actual   The actual array.
15
     * @param string|null $prefix   Prefix to use with error messages. Useful for nested arrays.
16
     *
17
     * @return void
18
     */
19
    public function assertSameArray(array $expected, $actual, $prefix = null)
20
    {
21
        //assert that the actual value is an array
22
        $this->assertInternalType('array', $actual, '$actual was not an array');
23
24
        $expectedKeys = array_keys($expected);
25
        $actualKeys = array_keys($actual);
26
27
        //find any keys in the expected array that are not present in the actual array
28
        $missingExpectedKeys = array_diff($expectedKeys, $actualKeys);
29
        $this->assertCount(
30
            0,
31
            $missingExpectedKeys,
32
            sprintf(
33
                '$actual array is missing %d keys: %s',
34
                count($missingExpectedKeys),
35
                implode(', ', $missingExpectedKeys)
36
            )
37
        );
38
39
        //find any keys in the actual array that are not expected in the expected array
40
        $unexpectedKeys = array_diff($actualKeys, $expectedKeys);
41
        $this->assertCount(
42
            0,
43
            $unexpectedKeys,
44
            sprintf(
45
                '$actual array contains %d unexpected keys: %s',
46
                count($unexpectedKeys),
47
                implode(', ', $unexpectedKeys)
48
            )
49
        );
50
51
        //Assert all values are the same value and type.
52
        //Recursively call assertSameArray on array values
53
        foreach ($expected as $key => $value) {
54
            //If a sub array is indexed numerically we just want to ensure all the values are present and not their keys.
55
            if (is_array($value) && self::isIndexed($value)) {
56
                $difference = array_diff($value, $actual[$key]);
57
                $this->assertEquals(count($difference), 0);
58
                continue;
59
            }
60
61
            if (is_array($value)) {
62
                $this->assertSameArray($value, $actual[$key], "{$prefix}{$key}.");
63
                continue;
64
            }
65
66
            $this->assertSame(
67
                $value,
68
                $actual[$key],
69
                sprintf(
70
                    "{$prefix}{$key} value is not correct expected %s\nfound %s",
71
                    var_export($value, 1),
72
                    var_export($actual[$key], 1)
73
                )
74
            );
75
        }
76
    }
77
78
    /**
79
     * Determines if an array is an indexed array i.e. an array with numeric and sequential keys
80
     *
81
     * @param array $subject The array to check if indexed
0 ignored issues
show
Coding Style Documentation introduced by
Parameter comment must end with a full stop
Loading history...
82
     *
83
     * @return bool
84
     */
85
    private function isIndexed(array $subject) : bool {
86
        $nonNumericKeyCount = count(array_filter(array_keys($subject), 'is_string'));
87
        if ($nonNumericKeyCount > 0) {
88
            return false;
89
        }
90
        
91
        //If the array keys are from 0 to N they are sequential and therefore numerically indexed.
92
        return array_keys($subject) === range(0, count($subject) -1);
93
    }
94
95
    /**
96
     * Asserts the number of elements of an array, Countable or Traversable.
97
     *
98
     * Ensures this method must be provided by classes using this trait.
99
     *
100
     * @param integer $expectedCount The expected number of items in $haystack.
101
     * @param mixed   $haystack      The array, countable or traversable object containing items.
102
     * @param string  $message       Optional error message to give upon failure.
103
     *
104
     * @return void
105
     */
106
    abstract public function assertCount($expectedCount, $haystack, $message = '');
107
108
    /**
109
     * Asserts that a variable is of a given type.
110
     *
111
     * Ensures this method must be provided by classes using this trait.
112
     *
113
     * @param string $expected The expected internal type.
114
     * @param mixed  $actual   The variable to verify.
115
     * @param string $message  Optional error message to give upon failure.
116
     *
117
     * @return void
118
     */
119
    abstract public function assertInternalType($expected, $actual, $message = '');
120
121
    /**
122
     * Asserts that two variables have the same type and value. Used on objects, it asserts that two variables reference
123
     * the same object.
124
     *
125
     * Ensures this method must be provided by classes using this trait.
126
     *
127
     * @param string $expected The expected value.
128
     * @param mixed  $actual   The actual value.
129
     * @param string $message  Optional error message to give upon failure.
130
     *
131
     * @return void
132
     */
133
    abstract public function assertSame($expected, $actual, $message = '');
134
}
135