1<?php
2/*
3 * This file is part of the Comparator package.
4 *
5 * (c) Sebastian Bergmann <sebastian@phpunit.de>
6 *
7 * For the full copyright and license information, please view the LICENSE
8 * file that was distributed with this source code.
9 */
10
11namespace SebastianBergmann\Comparator;
12
13/**
14 * Compares scalar or NULL values for equality.
15 */
16class ScalarComparator extends Comparator
17{
18    /**
19     * Returns whether the comparator can compare two values.
20     *
21     * @param  mixed $expected The first value to compare
22     * @param  mixed $actual   The second value to compare
23     * @return bool
24     * @since  Method available since Release 3.6.0
25     */
26    public function accepts($expected, $actual)
27    {
28        return ((is_scalar($expected) xor null === $expected) &&
29               (is_scalar($actual) xor null === $actual))
30               // allow comparison between strings and objects featuring __toString()
31               || (is_string($expected) && is_object($actual) && method_exists($actual, '__toString'))
32               || (is_object($expected) && method_exists($expected, '__toString') && is_string($actual));
33    }
34
35    /**
36     * Asserts that two values are equal.
37     *
38     * @param mixed $expected     First value to compare
39     * @param mixed $actual       Second value to compare
40     * @param float $delta        Allowed numerical distance between two values to consider them equal
41     * @param bool  $canonicalize Arrays are sorted before comparison when set to true
42     * @param bool  $ignoreCase   Case is ignored when set to true
43     *
44     * @throws ComparisonFailure
45     */
46    public function assertEquals($expected, $actual, $delta = 0.0, $canonicalize = false, $ignoreCase = false)
47    {
48        $expectedToCompare = $expected;
49        $actualToCompare   = $actual;
50
51        // always compare as strings to avoid strange behaviour
52        // otherwise 0 == 'Foobar'
53        if (is_string($expected) || is_string($actual)) {
54            $expectedToCompare = (string) $expectedToCompare;
55            $actualToCompare   = (string) $actualToCompare;
56
57            if ($ignoreCase) {
58                $expectedToCompare = strtolower($expectedToCompare);
59                $actualToCompare   = strtolower($actualToCompare);
60            }
61        }
62
63        if ($expectedToCompare != $actualToCompare) {
64            if (is_string($expected) && is_string($actual)) {
65                throw new ComparisonFailure(
66                    $expected,
67                    $actual,
68                    $this->exporter->export($expected),
69                    $this->exporter->export($actual),
70                    false,
71                    'Failed asserting that two strings are equal.'
72                );
73            }
74
75            throw new ComparisonFailure(
76                $expected,
77                $actual,
78                // no diff is required
79                '',
80                '',
81                false,
82                sprintf(
83                    'Failed asserting that %s matches expected %s.',
84                    $this->exporter->export($actual),
85                    $this->exporter->export($expected)
86                )
87            );
88        }
89    }
90}
91