GitHub Access Token became invalid

It seems like the GitHub access token used for retrieving details about this repository from GitHub became invalid. This might prevent certain types of inspections from being run (in particular, everything related to pull requests).
Please ask an admin of your repository to re-new the access token on this website.
Passed
Push — master ( d6ed85...1d3946 )
by
unknown
06:08 queued 18s
created
src/AttributeMatcher.php 1 patch
Indentation   +66 added lines, -66 removed lines patch added patch discarded remove patch
@@ -10,80 +10,80 @@
 block discarded – undo
10 10
 
11 11
 class AttributeMatcher extends TagMatcher {
12 12
 
13
-	/**
14
-	 * @var Matcher
15
-	 */
16
-	private $attributeNameMatcher;
13
+    /**
14
+     * @var Matcher
15
+     */
16
+    private $attributeNameMatcher;
17 17
 
18
-	/**
19
-	 * @var Matcher|null
20
-	 */
21
-	private $valueMatcher;
18
+    /**
19
+     * @var Matcher|null
20
+     */
21
+    private $valueMatcher;
22 22
 
23
-	/**
24
-	 * @param Matcher|string $attributeName
25
-	 *
26
-	 * @return self
27
-	 */
28
-	public static function withAttribute( $attributeName ) {
29
-		return new static( Util::wrapValueWithIsEqual( $attributeName ) );
30
-	}
23
+    /**
24
+     * @param Matcher|string $attributeName
25
+     *
26
+     * @return self
27
+     */
28
+    public static function withAttribute( $attributeName ) {
29
+        return new static( Util::wrapValueWithIsEqual( $attributeName ) );
30
+    }
31 31
 
32
-	/**
33
-	 * @param Matcher $attributeNameMatcher
34
-	 */
35
-	public function __construct( Matcher $attributeNameMatcher ) {
36
-		parent::__construct();
32
+    /**
33
+     * @param Matcher $attributeNameMatcher
34
+     */
35
+    public function __construct( Matcher $attributeNameMatcher ) {
36
+        parent::__construct();
37 37
 
38
-		$this->attributeNameMatcher = $attributeNameMatcher;
39
-	}
38
+        $this->attributeNameMatcher = $attributeNameMatcher;
39
+    }
40 40
 
41
-	/**
42
-	 * @param Matcher|string $value
43
-	 *
44
-	 * @return AttributeMatcher
45
-	 */
46
-	public function havingValue( $value ) {
47
-		// TODO: Throw exception if value is set
48
-		$result = clone $this;
49
-		$result->valueMatcher = Util::wrapValueWithIsEqual( $value );
41
+    /**
42
+     * @param Matcher|string $value
43
+     *
44
+     * @return AttributeMatcher
45
+     */
46
+    public function havingValue( $value ) {
47
+        // TODO: Throw exception if value is set
48
+        $result = clone $this;
49
+        $result->valueMatcher = Util::wrapValueWithIsEqual( $value );
50 50
 
51
-		return $result;
52
-	}
51
+        return $result;
52
+    }
53 53
 
54
-	public function describeTo( Description $description ) {
55
-		$description->appendText( 'with attribute ' )
56
-			->appendDescriptionOf( $this->attributeNameMatcher );
57
-		if ( $this->valueMatcher ) {
58
-			$description->appendText( ' having value ' )
59
-				->appendDescriptionOf( $this->valueMatcher );
60
-		}
61
-	}
54
+    public function describeTo( Description $description ) {
55
+        $description->appendText( 'with attribute ' )
56
+            ->appendDescriptionOf( $this->attributeNameMatcher );
57
+        if ( $this->valueMatcher ) {
58
+            $description->appendText( ' having value ' )
59
+                ->appendDescriptionOf( $this->valueMatcher );
60
+        }
61
+    }
62 62
 
63
-	/**
64
-	 * @param DOMElement $item
65
-	 * @param Description $mismatchDescription
66
-	 *
67
-	 * @return bool
68
-	 */
69
-	protected function matchesSafelyWithDiagnosticDescription(
70
-		$item, Description $mismatchDescription
71
-	) {
72
-		/** @var DOMAttr $attribute */
73
-		foreach ( $item->attributes as $attribute ) {
74
-			if ( $this->valueMatcher ) {
75
-				if (
76
-					$this->attributeNameMatcher->matches( $attribute->name )
77
-					&& $this->valueMatcher->matches( $attribute->value )
78
-				) {
79
-					return true;
80
-				}
81
-			} elseif ( $this->attributeNameMatcher->matches( $attribute->name ) ) {
82
-				return true;
83
-			}
84
-		}
63
+    /**
64
+     * @param DOMElement $item
65
+     * @param Description $mismatchDescription
66
+     *
67
+     * @return bool
68
+     */
69
+    protected function matchesSafelyWithDiagnosticDescription(
70
+        $item, Description $mismatchDescription
71
+    ) {
72
+        /** @var DOMAttr $attribute */
73
+        foreach ( $item->attributes as $attribute ) {
74
+            if ( $this->valueMatcher ) {
75
+                if (
76
+                    $this->attributeNameMatcher->matches( $attribute->name )
77
+                    && $this->valueMatcher->matches( $attribute->value )
78
+                ) {
79
+                    return true;
80
+                }
81
+            } elseif ( $this->attributeNameMatcher->matches( $attribute->name ) ) {
82
+                return true;
83
+            }
84
+        }
85 85
 
86
-		return false;
87
-	}
86
+        return false;
87
+    }
88 88
 
89 89
 }
Please login to merge, or discard this patch.
src/TagMatcher.php 1 patch
Indentation   +3 added lines, -3 removed lines patch added patch discarded remove patch
@@ -7,8 +7,8 @@
 block discarded – undo
7 7
 
8 8
 abstract class TagMatcher extends TypeSafeDiagnosingMatcher {
9 9
 
10
-	public function __construct() {
11
-		parent::__construct( self::TYPE_OBJECT, DOMElement::class );
12
-	}
10
+    public function __construct() {
11
+        parent::__construct( self::TYPE_OBJECT, DOMElement::class );
12
+    }
13 13
 
14 14
 }
Please login to merge, or discard this patch.
src/ComplexTagMatcher.php 1 patch
Indentation   +216 added lines, -216 removed lines patch added patch discarded remove patch
@@ -12,221 +12,221 @@
 block discarded – undo
12 12
 
13 13
 class ComplexTagMatcher extends TagMatcher {
14 14
 
15
-	/**
16
-	 * @link http://www.xmlsoft.org/html/libxml-xmlerror.html#xmlParserErrors
17
-	 * @link https://github.com/Chronic-Dev/libxml2/blob/683f296a905710ff285c28b8644ef3a3d8be9486/include/libxml/xmlerror.h#L257
18
-	 */
19
-	private const XML_UNKNOWN_TAG_ERROR_CODE = 801;
20
-
21
-	/**
22
-	 * @var string
23
-	 */
24
-	private $tagHtmlOutline;
25
-
26
-	/**
27
-	 * @var Matcher
28
-	 */
29
-	private $matcher;
30
-
31
-	/**
32
-	 * @param string $htmlOutline
33
-	 *
34
-	 * @return self
35
-	 */
36
-	public static function tagMatchingOutline( $htmlOutline ) {
37
-		return new self( $htmlOutline );
38
-	}
39
-
40
-	/**
41
-	 * @param string $tagHtmlRepresentation
42
-	 */
43
-	public function __construct( $tagHtmlRepresentation ) {
44
-		parent::__construct();
45
-
46
-		$this->tagHtmlOutline = $tagHtmlRepresentation;
47
-		$this->matcher = $this->createMatcherFromHtml( $tagHtmlRepresentation );
48
-	}
49
-
50
-	/**
51
-	 * @param Description $description
52
-	 */
53
-	public function describeTo( Description $description ) {
54
-		$description->appendText( 'tag matching outline `' )
55
-			->appendText( $this->tagHtmlOutline )
56
-			->appendText( '` ' );
57
-	}
58
-
59
-	/**
60
-	 * @param DOMElement $item
61
-	 * @param Description $mismatchDescription
62
-	 *
63
-	 * @return bool
64
-	 */
65
-	protected function matchesSafelyWithDiagnosticDescription(
66
-		$item, Description $mismatchDescription
67
-	) {
68
-		if ( $this->matcher->matches( $item ) ) {
69
-			return true;
70
-		}
71
-
72
-		$mismatchDescription->appendText( 'was `' )
73
-			->appendText( $this->elementToString( $item ) )
74
-			->appendText( '`' );
75
-		return false;
76
-	}
77
-
78
-	/**
79
-	 * @param string $htmlOutline
80
-	 *
81
-	 * @return Matcher
82
-	 */
83
-	private function createMatcherFromHtml( $htmlOutline ) {
84
-		$document = $this->parseHtml( $htmlOutline );
85
-		$targetTag = $this->getSingleTagFromThe( $document );
86
-
87
-		$this->assertTagDoesNotContainChildren( $targetTag );
88
-
89
-		$attributeMatchers = $this->createAttributeMatchers( $htmlOutline, $targetTag );
90
-		$classMatchers = $this->createClassMatchers( $targetTag );
91
-
92
-		return AllOf::allOf(
93
-			new TagNameMatcher( IsEqual::equalTo( $targetTag->tagName ) ),
94
-			call_user_func_array( [ AllOf::class, 'allOf' ], $attributeMatchers ),
95
-			call_user_func_array( [ AllOf::class, 'allOf' ], $classMatchers )
96
-		);
97
-	}
98
-
99
-	/**
100
-	 * @param \LibXMLError $error
101
-	 *
102
-	 * @return bool
103
-	 */
104
-	private function isUnknownTagError( \LibXMLError $error ) {
105
-		return $error->code === self::XML_UNKNOWN_TAG_ERROR_CODE;
106
-	}
107
-
108
-	/**
109
-	 * @param string $inputHtml
110
-	 * @param string $attributeName
111
-	 *
112
-	 * @return bool
113
-	 */
114
-	private function isBooleanAttribute( $inputHtml, $attributeName ) {
115
-		$quotedName = preg_quote( $attributeName, '/' );
116
-
117
-		return !preg_match( "/\b{$quotedName}\s*=/ui", $inputHtml );
118
-	}
119
-
120
-	/**
121
-	 * @param string $html
122
-	 *
123
-	 * @return DOMDocument
124
-	 * @throws InvalidArgumentException
125
-	 */
126
-	private function parseHtml( $html ) {
127
-		$internalErrors = libxml_use_internal_errors( true );
128
-		$document = new DOMDocument();
129
-
130
-		// phpcs:ignore Generic.PHP.NoSilencedErrors
131
-		if ( !@$document->loadHTML( $html ) ) {
132
-			throw new InvalidArgumentException( "There was some parsing error of `$html`" );
133
-		}
134
-
135
-		$errors = libxml_get_errors();
136
-		libxml_clear_errors();
137
-		libxml_use_internal_errors( $internalErrors );
138
-
139
-		foreach ( $errors as $error ) {
140
-			if ( $this->isUnknownTagError( $error ) ) {
141
-				continue;
142
-			}
143
-
144
-			throw new InvalidArgumentException(
145
-				'There was parsing error: ' . trim( $error->message ) . ' on line ' . $error->line
146
-			);
147
-		}
148
-
149
-		return $document;
150
-	}
151
-
152
-	/**
153
-	 * @param DOMDocument $document
154
-	 *
155
-	 * @return DOMElement
156
-	 * @throws InvalidArgumentException
157
-	 */
158
-	private function getSingleTagFromThe( DOMDocument $document ) {
159
-		$directChildren = $document->documentElement->childNodes->item( 0 )->childNodes;
160
-
161
-		if ( $directChildren->length !== 1 ) {
162
-			throw new InvalidArgumentException(
163
-				'Expected exactly 1 tag description, got ' . $directChildren->length
164
-			);
165
-		}
166
-
167
-		// @phan-suppress-next-line PhanTypeMismatchReturnNullable
168
-		return $directChildren->item( 0 );
169
-	}
170
-
171
-	private function assertTagDoesNotContainChildren( DOMElement $targetTag ) {
172
-		if ( $targetTag->childNodes->length > 0 ) {
173
-			throw new InvalidArgumentException( 'Nested elements are not allowed' );
174
-		}
175
-	}
176
-
177
-	/**
178
-	 * @param string $inputHtml
179
-	 * @param DOMElement $targetTag
180
-	 *
181
-	 * @return AttributeMatcher[]
182
-	 */
183
-	private function createAttributeMatchers( $inputHtml, DOMElement $targetTag ) {
184
-		$attributeMatchers = [];
185
-		/** @var \DOMAttr $attribute */
186
-		foreach ( $targetTag->attributes as $attribute ) {
187
-			if ( $attribute->name === 'class' ) {
188
-				continue;
189
-			}
190
-
191
-			$attributeMatcher = new AttributeMatcher( IsEqual::equalTo( $attribute->name ) );
192
-			if ( !$this->isBooleanAttribute( $inputHtml, $attribute->name ) ) {
193
-				$attributeMatcher = $attributeMatcher->havingValue(
194
-					IsEqual::equalTo( $attribute->value )
195
-				);
196
-			}
197
-
198
-			$attributeMatchers[] = $attributeMatcher;
199
-		}
200
-		return $attributeMatchers;
201
-	}
202
-
203
-	/**
204
-	 * @param DOMElement $targetTag
205
-	 *
206
-	 * @return ClassMatcher[]
207
-	 */
208
-	private function createClassMatchers( DOMElement $targetTag ) {
209
-		$classMatchers = [];
210
-		$classValue = $targetTag->getAttribute( 'class' );
211
-		foreach ( explode( ' ', $classValue ) as $expectedClass ) {
212
-			if ( $expectedClass === '' ) {
213
-				continue;
214
-			}
215
-			$classMatchers[] = new ClassMatcher( IsEqual::equalTo( $expectedClass ) );
216
-		}
217
-		return $classMatchers;
218
-	}
219
-
220
-	/**
221
-	 * @param DOMElement $element
222
-	 *
223
-	 * @return string
224
-	 */
225
-	private function elementToString( DOMElement $element ) {
226
-		$newDocument = new DOMDocument();
227
-		$cloned = $element->cloneNode( true );
228
-		$newDocument->appendChild( $newDocument->importNode( $cloned, true ) );
229
-		return trim( $newDocument->saveHTML() );
230
-	}
15
+    /**
16
+     * @link http://www.xmlsoft.org/html/libxml-xmlerror.html#xmlParserErrors
17
+     * @link https://github.com/Chronic-Dev/libxml2/blob/683f296a905710ff285c28b8644ef3a3d8be9486/include/libxml/xmlerror.h#L257
18
+     */
19
+    private const XML_UNKNOWN_TAG_ERROR_CODE = 801;
20
+
21
+    /**
22
+     * @var string
23
+     */
24
+    private $tagHtmlOutline;
25
+
26
+    /**
27
+     * @var Matcher
28
+     */
29
+    private $matcher;
30
+
31
+    /**
32
+     * @param string $htmlOutline
33
+     *
34
+     * @return self
35
+     */
36
+    public static function tagMatchingOutline( $htmlOutline ) {
37
+        return new self( $htmlOutline );
38
+    }
39
+
40
+    /**
41
+     * @param string $tagHtmlRepresentation
42
+     */
43
+    public function __construct( $tagHtmlRepresentation ) {
44
+        parent::__construct();
45
+
46
+        $this->tagHtmlOutline = $tagHtmlRepresentation;
47
+        $this->matcher = $this->createMatcherFromHtml( $tagHtmlRepresentation );
48
+    }
49
+
50
+    /**
51
+     * @param Description $description
52
+     */
53
+    public function describeTo( Description $description ) {
54
+        $description->appendText( 'tag matching outline `' )
55
+            ->appendText( $this->tagHtmlOutline )
56
+            ->appendText( '` ' );
57
+    }
58
+
59
+    /**
60
+     * @param DOMElement $item
61
+     * @param Description $mismatchDescription
62
+     *
63
+     * @return bool
64
+     */
65
+    protected function matchesSafelyWithDiagnosticDescription(
66
+        $item, Description $mismatchDescription
67
+    ) {
68
+        if ( $this->matcher->matches( $item ) ) {
69
+            return true;
70
+        }
71
+
72
+        $mismatchDescription->appendText( 'was `' )
73
+            ->appendText( $this->elementToString( $item ) )
74
+            ->appendText( '`' );
75
+        return false;
76
+    }
77
+
78
+    /**
79
+     * @param string $htmlOutline
80
+     *
81
+     * @return Matcher
82
+     */
83
+    private function createMatcherFromHtml( $htmlOutline ) {
84
+        $document = $this->parseHtml( $htmlOutline );
85
+        $targetTag = $this->getSingleTagFromThe( $document );
86
+
87
+        $this->assertTagDoesNotContainChildren( $targetTag );
88
+
89
+        $attributeMatchers = $this->createAttributeMatchers( $htmlOutline, $targetTag );
90
+        $classMatchers = $this->createClassMatchers( $targetTag );
91
+
92
+        return AllOf::allOf(
93
+            new TagNameMatcher( IsEqual::equalTo( $targetTag->tagName ) ),
94
+            call_user_func_array( [ AllOf::class, 'allOf' ], $attributeMatchers ),
95
+            call_user_func_array( [ AllOf::class, 'allOf' ], $classMatchers )
96
+        );
97
+    }
98
+
99
+    /**
100
+     * @param \LibXMLError $error
101
+     *
102
+     * @return bool
103
+     */
104
+    private function isUnknownTagError( \LibXMLError $error ) {
105
+        return $error->code === self::XML_UNKNOWN_TAG_ERROR_CODE;
106
+    }
107
+
108
+    /**
109
+     * @param string $inputHtml
110
+     * @param string $attributeName
111
+     *
112
+     * @return bool
113
+     */
114
+    private function isBooleanAttribute( $inputHtml, $attributeName ) {
115
+        $quotedName = preg_quote( $attributeName, '/' );
116
+
117
+        return !preg_match( "/\b{$quotedName}\s*=/ui", $inputHtml );
118
+    }
119
+
120
+    /**
121
+     * @param string $html
122
+     *
123
+     * @return DOMDocument
124
+     * @throws InvalidArgumentException
125
+     */
126
+    private function parseHtml( $html ) {
127
+        $internalErrors = libxml_use_internal_errors( true );
128
+        $document = new DOMDocument();
129
+
130
+        // phpcs:ignore Generic.PHP.NoSilencedErrors
131
+        if ( !@$document->loadHTML( $html ) ) {
132
+            throw new InvalidArgumentException( "There was some parsing error of `$html`" );
133
+        }
134
+
135
+        $errors = libxml_get_errors();
136
+        libxml_clear_errors();
137
+        libxml_use_internal_errors( $internalErrors );
138
+
139
+        foreach ( $errors as $error ) {
140
+            if ( $this->isUnknownTagError( $error ) ) {
141
+                continue;
142
+            }
143
+
144
+            throw new InvalidArgumentException(
145
+                'There was parsing error: ' . trim( $error->message ) . ' on line ' . $error->line
146
+            );
147
+        }
148
+
149
+        return $document;
150
+    }
151
+
152
+    /**
153
+     * @param DOMDocument $document
154
+     *
155
+     * @return DOMElement
156
+     * @throws InvalidArgumentException
157
+     */
158
+    private function getSingleTagFromThe( DOMDocument $document ) {
159
+        $directChildren = $document->documentElement->childNodes->item( 0 )->childNodes;
160
+
161
+        if ( $directChildren->length !== 1 ) {
162
+            throw new InvalidArgumentException(
163
+                'Expected exactly 1 tag description, got ' . $directChildren->length
164
+            );
165
+        }
166
+
167
+        // @phan-suppress-next-line PhanTypeMismatchReturnNullable
168
+        return $directChildren->item( 0 );
169
+    }
170
+
171
+    private function assertTagDoesNotContainChildren( DOMElement $targetTag ) {
172
+        if ( $targetTag->childNodes->length > 0 ) {
173
+            throw new InvalidArgumentException( 'Nested elements are not allowed' );
174
+        }
175
+    }
176
+
177
+    /**
178
+     * @param string $inputHtml
179
+     * @param DOMElement $targetTag
180
+     *
181
+     * @return AttributeMatcher[]
182
+     */
183
+    private function createAttributeMatchers( $inputHtml, DOMElement $targetTag ) {
184
+        $attributeMatchers = [];
185
+        /** @var \DOMAttr $attribute */
186
+        foreach ( $targetTag->attributes as $attribute ) {
187
+            if ( $attribute->name === 'class' ) {
188
+                continue;
189
+            }
190
+
191
+            $attributeMatcher = new AttributeMatcher( IsEqual::equalTo( $attribute->name ) );
192
+            if ( !$this->isBooleanAttribute( $inputHtml, $attribute->name ) ) {
193
+                $attributeMatcher = $attributeMatcher->havingValue(
194
+                    IsEqual::equalTo( $attribute->value )
195
+                );
196
+            }
197
+
198
+            $attributeMatchers[] = $attributeMatcher;
199
+        }
200
+        return $attributeMatchers;
201
+    }
202
+
203
+    /**
204
+     * @param DOMElement $targetTag
205
+     *
206
+     * @return ClassMatcher[]
207
+     */
208
+    private function createClassMatchers( DOMElement $targetTag ) {
209
+        $classMatchers = [];
210
+        $classValue = $targetTag->getAttribute( 'class' );
211
+        foreach ( explode( ' ', $classValue ) as $expectedClass ) {
212
+            if ( $expectedClass === '' ) {
213
+                continue;
214
+            }
215
+            $classMatchers[] = new ClassMatcher( IsEqual::equalTo( $expectedClass ) );
216
+        }
217
+        return $classMatchers;
218
+    }
219
+
220
+    /**
221
+     * @param DOMElement $element
222
+     *
223
+     * @return string
224
+     */
225
+    private function elementToString( DOMElement $element ) {
226
+        $newDocument = new DOMDocument();
227
+        $cloned = $element->cloneNode( true );
228
+        $newDocument->appendChild( $newDocument->importNode( $cloned, true ) );
229
+        return trim( $newDocument->saveHTML() );
230
+    }
231 231
 
232 232
 }
Please login to merge, or discard this patch.
src/DirectChildElementMatcher.php 1 patch
Indentation   +59 added lines, -59 removed lines patch added patch discarded remove patch
@@ -10,64 +10,64 @@
 block discarded – undo
10 10
 
11 11
 class DirectChildElementMatcher extends TypeSafeDiagnosingMatcher {
12 12
 
13
-	/**
14
-	 * @var Matcher|null
15
-	 */
16
-	private $matcher;
17
-
18
-	public static function havingDirectChild( ?Matcher $elementMatcher = null ) {
19
-		return new static( $elementMatcher );
20
-	}
21
-
22
-	public function __construct( ?Matcher $matcher = null ) {
23
-		parent::__construct( DOMNode::class );
24
-		$this->matcher = $matcher;
25
-	}
26
-
27
-	public function describeTo( Description $description ) {
28
-		$description->appendText( 'having direct child ' );
29
-		if ( $this->matcher ) {
30
-			$description->appendDescriptionOf( $this->matcher );
31
-		}
32
-	}
33
-
34
-	/**
35
-	 * @param DOMDocument|DOMNode $item
36
-	 * @param Description $mismatchDescription
37
-	 *
38
-	 * @return bool
39
-	 */
40
-	protected function matchesSafelyWithDiagnosticDescription(
41
-		$item, Description $mismatchDescription
42
-	) {
43
-		if ( $item instanceof DOMDocument ) {
44
-			$item = $item->documentElement->childNodes->item( 0 );
45
-		}
46
-		$directChildren = $item->childNodes;
47
-
48
-		if ( $directChildren->length === 0 ) {
49
-			$mismatchDescription->appendText( 'with no direct children' );
50
-			return false;
51
-		}
52
-
53
-		$childWord = $directChildren->length === 1 ? 'child' : 'children';
54
-
55
-		$mismatchDescription->appendText( "with direct {$childWord} " );
56
-
57
-		if ( !$this->matcher ) {
58
-			return $directChildren->length !== 0;
59
-		}
60
-
61
-		$child = null;
62
-		foreach ( $directChildren as $child ) {
63
-			if ( $this->matcher->matches( $child ) ) {
64
-				return true;
65
-			}
66
-		}
67
-
68
-		$this->matcher->describeMismatch( $child, $mismatchDescription );
69
-
70
-		return false;
71
-	}
13
+    /**
14
+     * @var Matcher|null
15
+     */
16
+    private $matcher;
17
+
18
+    public static function havingDirectChild( ?Matcher $elementMatcher = null ) {
19
+        return new static( $elementMatcher );
20
+    }
21
+
22
+    public function __construct( ?Matcher $matcher = null ) {
23
+        parent::__construct( DOMNode::class );
24
+        $this->matcher = $matcher;
25
+    }
26
+
27
+    public function describeTo( Description $description ) {
28
+        $description->appendText( 'having direct child ' );
29
+        if ( $this->matcher ) {
30
+            $description->appendDescriptionOf( $this->matcher );
31
+        }
32
+    }
33
+
34
+    /**
35
+     * @param DOMDocument|DOMNode $item
36
+     * @param Description $mismatchDescription
37
+     *
38
+     * @return bool
39
+     */
40
+    protected function matchesSafelyWithDiagnosticDescription(
41
+        $item, Description $mismatchDescription
42
+    ) {
43
+        if ( $item instanceof DOMDocument ) {
44
+            $item = $item->documentElement->childNodes->item( 0 );
45
+        }
46
+        $directChildren = $item->childNodes;
47
+
48
+        if ( $directChildren->length === 0 ) {
49
+            $mismatchDescription->appendText( 'with no direct children' );
50
+            return false;
51
+        }
52
+
53
+        $childWord = $directChildren->length === 1 ? 'child' : 'children';
54
+
55
+        $mismatchDescription->appendText( "with direct {$childWord} " );
56
+
57
+        if ( !$this->matcher ) {
58
+            return $directChildren->length !== 0;
59
+        }
60
+
61
+        $child = null;
62
+        foreach ( $directChildren as $child ) {
63
+            if ( $this->matcher->matches( $child ) ) {
64
+                return true;
65
+            }
66
+        }
67
+
68
+        $this->matcher->describeMismatch( $child, $mismatchDescription );
69
+
70
+        return false;
71
+    }
72 72
 
73 73
 }
Please login to merge, or discard this patch.
src/HtmlMatcher.php 1 patch
Indentation   +101 added lines, -101 removed lines patch added patch discarded remove patch
@@ -10,106 +10,106 @@
 block discarded – undo
10 10
 
11 11
 class HtmlMatcher extends DiagnosingMatcher {
12 12
 
13
-	/**
14
-	 * @link http://www.xmlsoft.org/html/libxml-xmlerror.html#xmlParserErrors
15
-	 * @link https://github.com/Chronic-Dev/libxml2/blob/683f296a905710ff285c28b8644ef3a3d8be9486/include/libxml/xmlerror.h#L257
16
-	 */
17
-	private const XML_UNKNOWN_TAG_ERROR_CODE = 801;
18
-
19
-	/**
20
-	 * @var Matcher|null
21
-	 */
22
-	private $elementMatcher;
23
-
24
-	/**
25
-	 * @param Matcher|null $elementMatcher
26
-	 *
27
-	 * @return self
28
-	 */
29
-	public static function htmlPiece( ?Matcher $elementMatcher = null ) {
30
-		return new static( $elementMatcher );
31
-	}
32
-
33
-	private function __construct( ?Matcher $elementMatcher = null ) {
34
-		$this->elementMatcher = $elementMatcher;
35
-	}
36
-
37
-	public function describeTo( Description $description ) {
38
-		$description->appendText( 'valid html piece ' );
39
-		if ( $this->elementMatcher ) {
40
-			$description->appendDescriptionOf( $this->elementMatcher );
41
-		}
42
-	}
43
-
44
-	/**
45
-	 * @param string $html
46
-	 * @param Description $mismatchDescription
47
-	 *
48
-	 * @return bool
49
-	 */
50
-	protected function matchesWithDiagnosticDescription( $html, Description $mismatchDescription ) {
51
-		$internalErrors = libxml_use_internal_errors( true );
52
-		libxml_clear_errors();
53
-		$document = new DOMDocument();
54
-
55
-		$html = $this->escapeScriptTagContents( $html );
56
-
57
-		// phpcs:ignore Generic.PHP.NoSilencedErrors
58
-		if ( !@$document->loadHTML( mb_convert_encoding( $html, 'HTML-ENTITIES', 'UTF-8' ) ) ) {
59
-			$mismatchDescription->appendText( 'there was some parsing error' );
60
-			return false;
61
-		}
62
-
63
-		$errors = libxml_get_errors();
64
-		libxml_clear_errors();
65
-		libxml_use_internal_errors( $internalErrors );
66
-
67
-		$result = true;
68
-		foreach ( $errors as $error ) {
69
-			if ( $this->isUnknownTagError( $error ) ) {
70
-				continue;
71
-			}
72
-
73
-			$mismatchDescription->appendText( 'there was parsing error: ' )
74
-				->appendText( trim( $error->message ) )
75
-				->appendText( ' on line ' )
76
-				->appendText( (string)$error->line );
77
-			$result = false;
78
-		}
79
-
80
-		if ( !$result ) {
81
-			return false;
82
-		}
83
-		$mismatchDescription->appendText( 'valid html piece ' );
84
-
85
-		if ( $this->elementMatcher ) {
86
-			$result = $this->elementMatcher->matches( $document );
87
-			$this->elementMatcher->describeMismatch( $document, $mismatchDescription );
88
-		}
89
-
90
-		$mismatchDescription->appendText( "\nActual html:\n" )->appendText( $html );
91
-
92
-		return $result;
93
-	}
94
-
95
-	/**
96
-	 * @param LibXMLError $error
97
-	 *
98
-	 * @return bool
99
-	 */
100
-	private function isUnknownTagError( LibXMLError $error ) {
101
-		return $error->code === self::XML_UNKNOWN_TAG_ERROR_CODE;
102
-	}
103
-
104
-	/**
105
-	 * @param string $html
106
-	 *
107
-	 * @return string HTML
108
-	 */
109
-	private function escapeScriptTagContents( $html ) {
110
-		return preg_replace_callback( '#(<script.*>)(.*)(</script>)#isU', static function ( $matches ) {
111
-			return $matches[1] . str_replace( '</', '<\/', $matches[2] ) . $matches[3];
112
-		}, $html );
113
-	}
13
+    /**
14
+     * @link http://www.xmlsoft.org/html/libxml-xmlerror.html#xmlParserErrors
15
+     * @link https://github.com/Chronic-Dev/libxml2/blob/683f296a905710ff285c28b8644ef3a3d8be9486/include/libxml/xmlerror.h#L257
16
+     */
17
+    private const XML_UNKNOWN_TAG_ERROR_CODE = 801;
18
+
19
+    /**
20
+     * @var Matcher|null
21
+     */
22
+    private $elementMatcher;
23
+
24
+    /**
25
+     * @param Matcher|null $elementMatcher
26
+     *
27
+     * @return self
28
+     */
29
+    public static function htmlPiece( ?Matcher $elementMatcher = null ) {
30
+        return new static( $elementMatcher );
31
+    }
32
+
33
+    private function __construct( ?Matcher $elementMatcher = null ) {
34
+        $this->elementMatcher = $elementMatcher;
35
+    }
36
+
37
+    public function describeTo( Description $description ) {
38
+        $description->appendText( 'valid html piece ' );
39
+        if ( $this->elementMatcher ) {
40
+            $description->appendDescriptionOf( $this->elementMatcher );
41
+        }
42
+    }
43
+
44
+    /**
45
+     * @param string $html
46
+     * @param Description $mismatchDescription
47
+     *
48
+     * @return bool
49
+     */
50
+    protected function matchesWithDiagnosticDescription( $html, Description $mismatchDescription ) {
51
+        $internalErrors = libxml_use_internal_errors( true );
52
+        libxml_clear_errors();
53
+        $document = new DOMDocument();
54
+
55
+        $html = $this->escapeScriptTagContents( $html );
56
+
57
+        // phpcs:ignore Generic.PHP.NoSilencedErrors
58
+        if ( !@$document->loadHTML( mb_convert_encoding( $html, 'HTML-ENTITIES', 'UTF-8' ) ) ) {
59
+            $mismatchDescription->appendText( 'there was some parsing error' );
60
+            return false;
61
+        }
62
+
63
+        $errors = libxml_get_errors();
64
+        libxml_clear_errors();
65
+        libxml_use_internal_errors( $internalErrors );
66
+
67
+        $result = true;
68
+        foreach ( $errors as $error ) {
69
+            if ( $this->isUnknownTagError( $error ) ) {
70
+                continue;
71
+            }
72
+
73
+            $mismatchDescription->appendText( 'there was parsing error: ' )
74
+                ->appendText( trim( $error->message ) )
75
+                ->appendText( ' on line ' )
76
+                ->appendText( (string)$error->line );
77
+            $result = false;
78
+        }
79
+
80
+        if ( !$result ) {
81
+            return false;
82
+        }
83
+        $mismatchDescription->appendText( 'valid html piece ' );
84
+
85
+        if ( $this->elementMatcher ) {
86
+            $result = $this->elementMatcher->matches( $document );
87
+            $this->elementMatcher->describeMismatch( $document, $mismatchDescription );
88
+        }
89
+
90
+        $mismatchDescription->appendText( "\nActual html:\n" )->appendText( $html );
91
+
92
+        return $result;
93
+    }
94
+
95
+    /**
96
+     * @param LibXMLError $error
97
+     *
98
+     * @return bool
99
+     */
100
+    private function isUnknownTagError( LibXMLError $error ) {
101
+        return $error->code === self::XML_UNKNOWN_TAG_ERROR_CODE;
102
+    }
103
+
104
+    /**
105
+     * @param string $html
106
+     *
107
+     * @return string HTML
108
+     */
109
+    private function escapeScriptTagContents( $html ) {
110
+        return preg_replace_callback( '#(<script.*>)(.*)(</script>)#isU', static function ( $matches ) {
111
+            return $matches[1] . str_replace( '</', '<\/', $matches[2] ) . $matches[3];
112
+        }, $html );
113
+    }
114 114
 
115 115
 }
Please login to merge, or discard this patch.
src/XmlNodeRecursiveIterator.php 1 patch
Indentation   +20 added lines, -20 removed lines patch added patch discarded remove patch
@@ -6,27 +6,27 @@
 block discarded – undo
6 6
 
7 7
 class XmlNodeRecursiveIterator extends \ArrayIterator {
8 8
 
9
-	public function __construct( \DOMNodeList $nodeList ) {
10
-		$queue = $this->addElementsToQueue( [], $nodeList );
11
-		parent::__construct( $queue );
12
-	}
9
+    public function __construct( \DOMNodeList $nodeList ) {
10
+        $queue = $this->addElementsToQueue( [], $nodeList );
11
+        parent::__construct( $queue );
12
+    }
13 13
 
14
-	/**
15
-	 * @param DOMNode[] $queue
16
-	 * @param \DOMNodeList $nodeList
17
-	 *
18
-	 * @return DOMNode[] New queue
19
-	 */
20
-	private function addElementsToQueue( array $queue, \DOMNodeList $nodeList ) {
21
-		/** @var DOMNode $node */
22
-		foreach ( $nodeList as $node ) {
23
-			$queue[] = $node;
24
-			if ( $node->childNodes !== null ) {
25
-				$queue = $this->addElementsToQueue( $queue, $node->childNodes );
26
-			}
27
-		}
14
+    /**
15
+     * @param DOMNode[] $queue
16
+     * @param \DOMNodeList $nodeList
17
+     *
18
+     * @return DOMNode[] New queue
19
+     */
20
+    private function addElementsToQueue( array $queue, \DOMNodeList $nodeList ) {
21
+        /** @var DOMNode $node */
22
+        foreach ( $nodeList as $node ) {
23
+            $queue[] = $node;
24
+            if ( $node->childNodes !== null ) {
25
+                $queue = $this->addElementsToQueue( $queue, $node->childNodes );
26
+            }
27
+        }
28 28
 
29
-		return $queue;
30
-	}
29
+        return $queue;
30
+    }
31 31
 
32 32
 }
Please login to merge, or discard this patch.
src/TagNameMatcher.php 1 patch
Indentation   +41 added lines, -41 removed lines patch added patch discarded remove patch
@@ -9,46 +9,46 @@
 block discarded – undo
9 9
 
10 10
 class TagNameMatcher extends TagMatcher {
11 11
 
12
-	/**
13
-	 * @var Matcher
14
-	 */
15
-	private $tagNameMatcher;
16
-
17
-	/**
18
-	 * @param Matcher|string $tagName
19
-	 *
20
-	 * @return self
21
-	 */
22
-	public static function withTagName( $tagName ) {
23
-		return new static( Util::wrapValueWithIsEqual( $tagName ) );
24
-	}
25
-
26
-	public function __construct( Matcher $tagNameMatcher ) {
27
-		parent::__construct();
28
-		$this->tagNameMatcher = $tagNameMatcher;
29
-	}
30
-
31
-	public function describeTo( Description $description ) {
32
-		$description->appendText( 'with tag name ' )
33
-			->appendDescriptionOf( $this->tagNameMatcher );
34
-	}
35
-
36
-	/**
37
-	 * @param DOMElement $item
38
-	 * @param Description $mismatchDescription
39
-	 *
40
-	 * @return bool
41
-	 */
42
-	protected function matchesSafelyWithDiagnosticDescription(
43
-		$item, Description $mismatchDescription
44
-	) {
45
-		if ( $this->tagNameMatcher->matches( $item->tagName ) ) {
46
-			return true;
47
-		}
48
-
49
-		$mismatchDescription->appendText( 'tag name ' );
50
-		$this->tagNameMatcher->describeMismatch( $item->tagName, $mismatchDescription );
51
-		return false;
52
-	}
12
+    /**
13
+     * @var Matcher
14
+     */
15
+    private $tagNameMatcher;
16
+
17
+    /**
18
+     * @param Matcher|string $tagName
19
+     *
20
+     * @return self
21
+     */
22
+    public static function withTagName( $tagName ) {
23
+        return new static( Util::wrapValueWithIsEqual( $tagName ) );
24
+    }
25
+
26
+    public function __construct( Matcher $tagNameMatcher ) {
27
+        parent::__construct();
28
+        $this->tagNameMatcher = $tagNameMatcher;
29
+    }
30
+
31
+    public function describeTo( Description $description ) {
32
+        $description->appendText( 'with tag name ' )
33
+            ->appendDescriptionOf( $this->tagNameMatcher );
34
+    }
35
+
36
+    /**
37
+     * @param DOMElement $item
38
+     * @param Description $mismatchDescription
39
+     *
40
+     * @return bool
41
+     */
42
+    protected function matchesSafelyWithDiagnosticDescription(
43
+        $item, Description $mismatchDescription
44
+    ) {
45
+        if ( $this->tagNameMatcher->matches( $item->tagName ) ) {
46
+            return true;
47
+        }
48
+
49
+        $mismatchDescription->appendText( 'tag name ' );
50
+        $this->tagNameMatcher->describeMismatch( $item->tagName, $mismatchDescription );
51
+        return false;
52
+    }
53 53
 
54 54
 }
Please login to merge, or discard this patch.
src/RootElementMatcher.php 1 patch
Indentation   +50 added lines, -50 removed lines patch added patch discarded remove patch
@@ -9,62 +9,62 @@
 block discarded – undo
9 9
 
10 10
 class RootElementMatcher extends TypeSafeDiagnosingMatcher {
11 11
 
12
-	/**
13
-	 * @var Matcher|null
14
-	 */
15
-	private $tagMatcher;
12
+    /**
13
+     * @var Matcher|null
14
+     */
15
+    private $tagMatcher;
16 16
 
17
-	/**
18
-	 * @param Matcher|null $tagMatcher
19
-	 *
20
-	 * @return static
21
-	 */
22
-	public static function havingRootElement( ?Matcher $tagMatcher = null ) {
23
-		return new static( $tagMatcher );
24
-	}
17
+    /**
18
+     * @param Matcher|null $tagMatcher
19
+     *
20
+     * @return static
21
+     */
22
+    public static function havingRootElement( ?Matcher $tagMatcher = null ) {
23
+        return new static( $tagMatcher );
24
+    }
25 25
 
26
-	public function __construct( ?Matcher $tagMatcher = null ) {
27
-		parent::__construct( self::TYPE_OBJECT, DOMDocument::class );
28
-		$this->tagMatcher = $tagMatcher;
29
-	}
26
+    public function __construct( ?Matcher $tagMatcher = null ) {
27
+        parent::__construct( self::TYPE_OBJECT, DOMDocument::class );
28
+        $this->tagMatcher = $tagMatcher;
29
+    }
30 30
 
31
-	public function describeTo( Description $description ) {
32
-		$description->appendText( 'having root element ' );
33
-		if ( $this->tagMatcher ) {
34
-			$description->appendDescriptionOf( $this->tagMatcher );
35
-		}
36
-	}
31
+    public function describeTo( Description $description ) {
32
+        $description->appendText( 'having root element ' );
33
+        if ( $this->tagMatcher ) {
34
+            $description->appendDescriptionOf( $this->tagMatcher );
35
+        }
36
+    }
37 37
 
38
-	/**
39
-	 * @param DOMDocument $item
40
-	 * @param Description $mismatchDescription
41
-	 *
42
-	 * @return bool
43
-	 */
44
-	protected function matchesSafelyWithDiagnosticDescription(
45
-		$item, Description $mismatchDescription
46
-	) {
47
-		$DOMNodeList = $item->documentElement->childNodes->item( 0 )->childNodes;
48
-		if ( $DOMNodeList->length > 1 ) {
49
-			// TODO Test this description
50
-			$mismatchDescription->appendText( 'having ' . $DOMNodeList->length . ' root elements ' );
51
-			return false;
52
-		}
38
+    /**
39
+     * @param DOMDocument $item
40
+     * @param Description $mismatchDescription
41
+     *
42
+     * @return bool
43
+     */
44
+    protected function matchesSafelyWithDiagnosticDescription(
45
+        $item, Description $mismatchDescription
46
+    ) {
47
+        $DOMNodeList = $item->documentElement->childNodes->item( 0 )->childNodes;
48
+        if ( $DOMNodeList->length > 1 ) {
49
+            // TODO Test this description
50
+            $mismatchDescription->appendText( 'having ' . $DOMNodeList->length . ' root elements ' );
51
+            return false;
52
+        }
53 53
 
54
-		$target = $DOMNodeList->item( 0 );
55
-		if ( !$target ) {
56
-			// TODO Reproduce?
57
-			$mismatchDescription->appendText( 'having no root elements ' );
58
-			return false;
59
-		}
54
+        $target = $DOMNodeList->item( 0 );
55
+        if ( !$target ) {
56
+            // TODO Reproduce?
57
+            $mismatchDescription->appendText( 'having no root elements ' );
58
+            return false;
59
+        }
60 60
 
61
-		if ( $this->tagMatcher ) {
62
-			$mismatchDescription->appendText( 'root element ' );
63
-			$this->tagMatcher->describeMismatch( $target, $mismatchDescription );
64
-			return $this->tagMatcher->matches( $target );
65
-		}
61
+        if ( $this->tagMatcher ) {
62
+            $mismatchDescription->appendText( 'root element ' );
63
+            $this->tagMatcher->describeMismatch( $target, $mismatchDescription );
64
+            return $this->tagMatcher->matches( $target );
65
+        }
66 66
 
67
-		return true;
68
-	}
67
+        return true;
68
+    }
69 69
 
70 70
 }
Please login to merge, or discard this patch.
src/functions.php 1 patch
Indentation   +58 added lines, -58 removed lines patch added patch discarded remove patch
@@ -12,87 +12,87 @@
 block discarded – undo
12 12
 use WMDE\HamcrestHtml\TextContentsMatcher;
13 13
 
14 14
 if ( !function_exists( 'htmlPiece' ) ) {
15
-	/**
16
-	 * @param Matcher|null $elementMatcher
17
-	 *
18
-	 * @return HtmlMatcher
19
-	 */
20
-	function htmlPiece( ?Matcher $elementMatcher = null ) {
21
-		return HtmlMatcher::htmlPiece( $elementMatcher );
22
-	}
15
+    /**
16
+     * @param Matcher|null $elementMatcher
17
+     *
18
+     * @return HtmlMatcher
19
+     */
20
+    function htmlPiece( ?Matcher $elementMatcher = null ) {
21
+        return HtmlMatcher::htmlPiece( $elementMatcher );
22
+    }
23 23
 }
24 24
 
25 25
 if ( !function_exists( 'havingRootElement' ) ) {
26
-	function havingRootElement( ?Matcher $matcher = null ) {
27
-		return RootElementMatcher::havingRootElement( $matcher );
28
-	}
26
+    function havingRootElement( ?Matcher $matcher = null ) {
27
+        return RootElementMatcher::havingRootElement( $matcher );
28
+    }
29 29
 }
30 30
 
31 31
 if ( !function_exists( 'havingDirectChild' ) ) {
32
-	function havingDirectChild( ?Matcher $elementMatcher = null ) {
33
-		return DirectChildElementMatcher::havingDirectChild( $elementMatcher );
34
-	}
32
+    function havingDirectChild( ?Matcher $elementMatcher = null ) {
33
+        return DirectChildElementMatcher::havingDirectChild( $elementMatcher );
34
+    }
35 35
 }
36 36
 
37 37
 if ( !function_exists( 'havingChild' ) ) {
38
-	function havingChild( ?Matcher $elementMatcher = null ) {
39
-		return ChildElementMatcher::havingChild( $elementMatcher );
40
-	}
38
+    function havingChild( ?Matcher $elementMatcher = null ) {
39
+        return ChildElementMatcher::havingChild( $elementMatcher );
40
+    }
41 41
 }
42 42
 
43 43
 if ( !function_exists( 'withTagName' ) ) {
44
-	/**
45
-	 * @param Matcher|string $tagName
46
-	 *
47
-	 * @return TagNameMatcher
48
-	 */
49
-	function withTagName( $tagName ) {
50
-		return TagNameMatcher::withTagName( $tagName );
51
-	}
44
+    /**
45
+     * @param Matcher|string $tagName
46
+     *
47
+     * @return TagNameMatcher
48
+     */
49
+    function withTagName( $tagName ) {
50
+        return TagNameMatcher::withTagName( $tagName );
51
+    }
52 52
 }
53 53
 
54 54
 if ( !function_exists( 'withAttribute' ) ) {
55
-	/**
56
-	 * @param Matcher|string $attributeName
57
-	 *
58
-	 * @return AttributeMatcher
59
-	 */
60
-	function withAttribute( $attributeName ) {
61
-		return AttributeMatcher::withAttribute( $attributeName );
62
-	}
55
+    /**
56
+     * @param Matcher|string $attributeName
57
+     *
58
+     * @return AttributeMatcher
59
+     */
60
+    function withAttribute( $attributeName ) {
61
+        return AttributeMatcher::withAttribute( $attributeName );
62
+    }
63 63
 }
64 64
 
65 65
 if ( !function_exists( 'withClass' ) ) {
66
-	/**
67
-	 * @param Matcher|string $class
68
-	 *
69
-	 * @return ClassMatcher
70
-	 */
71
-	function withClass( $class ) {
72
-		// TODO don't allow to call with empty string
66
+    /**
67
+     * @param Matcher|string $class
68
+     *
69
+     * @return ClassMatcher
70
+     */
71
+    function withClass( $class ) {
72
+        // TODO don't allow to call with empty string
73 73
 
74
-		return ClassMatcher::withClass( $class );
75
-	}
74
+        return ClassMatcher::withClass( $class );
75
+    }
76 76
 }
77 77
 
78 78
 if ( !function_exists( 'havingTextContents' ) ) {
79
-	/**
80
-	 * @param Matcher|string $text
81
-	 *
82
-	 * @return TextContentsMatcher
83
-	 */
84
-	function havingTextContents( $text ) {
85
-		return TextContentsMatcher::havingTextContents( $text );
86
-	}
79
+    /**
80
+     * @param Matcher|string $text
81
+     *
82
+     * @return TextContentsMatcher
83
+     */
84
+    function havingTextContents( $text ) {
85
+        return TextContentsMatcher::havingTextContents( $text );
86
+    }
87 87
 }
88 88
 
89 89
 if ( !function_exists( 'tagMatchingOutline' ) ) {
90
-	/**
91
-	 * @param string $htmlOutline
92
-	 *
93
-	 * @return ComplexTagMatcher
94
-	 */
95
-	function tagMatchingOutline( $htmlOutline ) {
96
-		return ComplexTagMatcher::tagMatchingOutline( $htmlOutline );
97
-	}
90
+    /**
91
+     * @param string $htmlOutline
92
+     *
93
+     * @return ComplexTagMatcher
94
+     */
95
+    function tagMatchingOutline( $htmlOutline ) {
96
+        return ComplexTagMatcher::tagMatchingOutline( $htmlOutline );
97
+    }
98 98
 }
Please login to merge, or discard this patch.