Passed
Push — master ( eaf66d...5fa21f )
by Caen
13:40 queued 12s
created

TestView::assertSeeTimes()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 9
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
cc 1
eloc 4
c 2
b 0
f 0
nc 1
nop 2
dl 0
loc 9
rs 10
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Hyde\Testing\Support;
6
7
use Hyde\Hyde;
8
use Illuminate\Support\Str;
9
use JetBrains\PhpStorm\NoReturn;
10
use Illuminate\Testing\Assert as PHPUnit;
11
12
/**
13
 * @todo Unify API with the TestableHtmlDocument and TestableHtmlElement classes.
14
 */
15
class TestView extends \Illuminate\Testing\TestView
16
{
17
    /**
18
     * Assert that the given HTML is contained within the view.
19
     *
20
     * @return $this
21
     */
22
    public function assertSeeHtml(string $value, bool $ignoreFormatting = false): static
23
    {
24
        if ($ignoreFormatting) {
25
            return $this->assertSeeHtmlIgnoringFormatting($value);
26
        }
27
28
        return $this->assertSee($value, false);
29
    }
30
31
    /**
32
     * Assert that the given HTML is contained within the view text, ignoring whitespace and newlines.
33
     *
34
     * @return $this
35
     */
36
    public function assertSeeHtmlIgnoringFormatting(string $value): static
37
    {
38
        PHPUnit::assertStringContainsString($this->trimNewlinesAndIndentation($value), $this->trimNewlinesAndIndentation($this->rendered));
39
40
        return $this;
41
    }
42
43
    /**
44
     * Assert that the given string is contained exactly `$times` within the view.
45
     *
46
     * @return $this
47
     */
48
    public function assertSeeTimes(string $value, int $times = 1): static
49
    {
50
        $this->assertSee($value, false);
51
52
        $count = substr_count($this->rendered, $value);
53
54
        PHPUnit::assertSame($times, $count, "The string '$value' was found $count times, expected $times.");
55
56
        return $this;
57
    }
58
59
    /**
60
     * Assert that the given string is contained exactly once within the view.
61
     *
62
     * @return $this
63
     */
64
    public function assertSeeOnce(string $value): static
65
    {
66
        return $this->assertSeeTimes($value);
67
    }
68
69
    /**
70
     * Assert that the given HTML element is contained within the view.
71
     *
72
     * @return $this
73
     */
74
    public function assertHasElement(string $element): static
75
    {
76
        $element = trim($element, '</>');
77
78
        if (str_starts_with($element, '#')) {
79
            return $this->assertHasId($element);
80
        }
81
82
        PHPUnit::assertStringContainsString("<$element", $this->rendered, "The element '$element' was not found.");
83
84
        return $this;
85
    }
86
87
    /**
88
     * Assert that the HTML attribute value is contained within the view.
89
     *
90
     * @return $this
91
     */
92
    public function assertAttributeIs(string $attribute, ?string $expectedValue = null): static
93
    {
94
        if ($expectedValue === null) {
95
            [$attributeName, $expectedValue] = explode('=', $attribute);
96
            $expectedValue = trim($expectedValue, '"');
97
        } else {
98
            $attributeName = $attribute;
99
        }
100
101
        static::assertHasAttribute($attributeName);
0 ignored issues
show
Bug Best Practice introduced by
The method Hyde\Testing\Support\Tes...w::assertHasAttribute() is not static, but was called statically. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

101
        static::/** @scrutinizer ignore-call */ 
102
                assertHasAttribute($attributeName);
Loading history...
102
103
        PHPUnit::assertStringContainsString($attributeName.'="'.$expectedValue.'"', $this->rendered, "The attribute '$attributeName' with value '$expectedValue' was not found.");
104
105
        return $this;
106
    }
107
108
    /**
109
     * Assert that the HTML attribute is present within the view.
110
     *
111
     * @return $this
112
     */
113
    public function assertHasAttribute(string $attributeName): static
114
    {
115
        PHPUnit::assertStringContainsString($attributeName.'="', $this->rendered, "The attribute '$attributeName' was not found.");
116
117
        return $this;
118
    }
119
120
    /**
121
     * Assert that the HTML attribute is not present within the view.
122
     *
123
     * @return $this
124
     */
125
    public function assertDoesNotHaveAttribute(string $attributeName): static
126
    {
127
        PHPUnit::assertStringNotContainsString($attributeName.'="', $this->rendered, "The attribute '$attributeName' was found.");
128
129
        return $this;
130
    }
131
132
    /**
133
     * Assert that the given HTML ID is contained within the view.
134
     *
135
     * @return $this
136
     */
137
    public function assertHasId(string $id): static
138
    {
139
        $id = trim($id, '#');
140
141
        PHPUnit::assertStringContainsString("id=\"$id\"", $this->rendered, "The id '$id' was not found.");
142
143
        return $this;
144
    }
145
146
    /**
147
     * Assert that the given CSS class is contained within the view.
148
     *
149
     * @return $this
150
     */
151
    public function assertHasClass(string $class): static
152
    {
153
        PHPUnit::assertContains($class, $this->findClasses(), "The class '$class' was not found.");
154
155
        return $this;
156
    }
157
158
    /**
159
     * Assert that the given CSS class is not contained within the view.
160
     *
161
     * @return $this
162
     */
163
    public function assertDoesNotHaveClass(string $class): static
164
    {
165
        PHPUnit::assertNotContains($class, $this->findClasses(), "The class '$class' was found.");
166
167
        return $this;
168
    }
169
170
    /**
171
     * Assert that the given text is equals the view's text content.
172
     *
173
     * @return $this
174
     */
175
    public function assertTextIs(string $value): static
176
    {
177
        PHPUnit::assertSame($value, strip_tags($this->rendered));
178
179
        return $this;
180
    }
181
182
    #[NoReturn]
183
    public function dd(bool $writeHtml = true): void
184
    {
185
        if ($writeHtml) {
186
            $viewName = Str::after(Str::after(basename(class_basename($this->view->getName())), '.'), '.');
187
            file_put_contents(Hyde::path(Str::kebab($viewName.'.html')), $this->rendered);
188
        }
189
190
        exit(trim($this->rendered)."\n\n");
0 ignored issues
show
Best Practice introduced by
Using exit here is not recommended.

In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.

Loading history...
191
    }
192
193
    protected function trimNewlinesAndIndentation(string $value): string
194
    {
195
        return str_replace(['    ', "\t", "\n", "\r"], '', $value);
196
    }
197
198
    /** @return array<string> */
199
    protected function findClasses(): array
200
    {
201
        preg_match_all('/class="([^"]+)"/', $this->rendered, $matches);
202
203
        return explode(' ', $matches[1][0]);
204
    }
205
}
206