Skip to content

Commit 0800c44

Browse files
kubawerloskeradus
authored andcommitted
Allow PHPUnit 8 (#5)
1 parent 130a84a commit 0800c44

File tree

5 files changed

+149
-3
lines changed

5 files changed

+149
-3
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
/.php_cs
22
/.php_cs.cache
3+
/.phpunit.result.cache
34
/composer.lock
45
/vendor/

.travis.yml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,8 @@ php:
1414
- 7.0
1515
- 7.1
1616
- 7.2
17-
- nightly
17+
- 7.3
18+
- 7.4snapshot
1819

1920
env:
2021
global:

composer.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
],
1515
"require": {
1616
"php": "^5.5 || ^7.0",
17-
"phpunit/phpunit": "^5.7.23 || ^6.4.3 || ^7.0",
17+
"phpunit/phpunit": "^5.7.23 || ^6.4.3 || ^7.0 || ^8.0",
1818
"phpunitgoodpractices/polyfill": "^1.1"
1919
},
2020
"conflict": {

src/Constraint/XmlMatchesXsd.php

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@
1414

1515
if (version_compare(\PHPUnit\Runner\Version::id(), '7.0.0') < 0) {
1616
class_alias(XmlMatchesXsdForV5::class, XmlMatchesXsd::class);
17-
} else {
17+
} elseif (version_compare(\PHPUnit\Runner\Version::id(), '8.0.0') < 0) {
1818
class_alias(XmlMatchesXsdForV7::class, XmlMatchesXsd::class);
19+
} else {
20+
class_alias(XmlMatchesXsdForV8::class, XmlMatchesXsd::class);
1921
}

src/Constraint/XmlMatchesXsdForV8.php

Lines changed: 142 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,142 @@
1+
<?php
2+
3+
/*
4+
* This file is part of PHP CS Fixer / PHPUnit Constraint XmlMatchesXsd.
5+
*
6+
* (c) SpacePossum
7+
* Dariusz Rumiński <[email protected]>
8+
*
9+
* This source file is subject to the MIT license that is bundled
10+
* with this source code in the file LICENSE.
11+
*/
12+
13+
namespace PhpCsFixer\PhpunitConstraintXmlMatchesXsd\Constraint;
14+
15+
use PHPUnit\Framework\Constraint\Constraint;
16+
17+
/**
18+
* @author SpacePossum
19+
*
20+
* @internal
21+
*/
22+
final class XmlMatchesXsdForV8 extends Constraint
23+
{
24+
/**
25+
* @var string[]
26+
*/
27+
private $xmlConstraintErrors = [];
28+
29+
/**
30+
* @var string
31+
*/
32+
private $xsd;
33+
34+
/**
35+
* @param string $xsd
36+
*/
37+
public function __construct($xsd)
38+
{
39+
// replace first only
40+
$needle = 'http://www.w3.org/2001/xml.xsd';
41+
if (false !== $pos = strpos($xsd, $needle)) {
42+
$xsd = substr_replace($xsd, 'file:///'.str_replace('\\', '/', __DIR__).'/xml.xsd', $pos, \strlen($needle));
43+
}
44+
45+
$this->xsd = $xsd;
46+
}
47+
48+
/**
49+
* {@inheritdoc}
50+
*/
51+
public function toString(): string
52+
{
53+
return 'matches XSD';
54+
}
55+
56+
/**
57+
* {@inheritdoc}
58+
*/
59+
protected function failureDescription($other): string
60+
{
61+
if (\is_string($other)) {
62+
return sprintf("%s %s.\n%s", $other, $this->toString(), implode("\n", $this->xmlConstraintErrors));
63+
}
64+
65+
if (\is_object($other)) {
66+
$type = sprintf('%s#%s', \get_class($other), method_exists($other, '__toString') ? $other->__toString() : '');
67+
} elseif (null === $other) {
68+
$type = 'null';
69+
} else {
70+
$type = \gettype($other).'#'.$other;
71+
}
72+
73+
return $type.' '.$this->toString();
74+
}
75+
76+
/**
77+
* {@inheritdoc}
78+
*/
79+
protected function matches($other): bool
80+
{
81+
return \is_string($other)
82+
? $this->stringMatches($other)
83+
: false
84+
;
85+
}
86+
87+
/**
88+
* @param string $other
89+
*
90+
* @return bool
91+
*/
92+
private function stringMatches($other)
93+
{
94+
$internalErrors = libxml_use_internal_errors(true);
95+
$disableEntities = libxml_disable_entity_loader(true);
96+
libxml_clear_errors();
97+
98+
$dom = new \DOMDocument();
99+
$dom->preserveWhiteSpace = false;
100+
$dom->validateOnParse = true;
101+
102+
if (!@$dom->loadXML($other, LIBXML_NONET | (\defined('LIBXML_COMPACT') ? LIBXML_COMPACT : 0))) {
103+
libxml_disable_entity_loader($disableEntities);
104+
$this->setXMLConstraintErrors();
105+
libxml_clear_errors();
106+
libxml_use_internal_errors($internalErrors);
107+
108+
return false;
109+
}
110+
111+
$dom->normalizeDocument();
112+
113+
libxml_disable_entity_loader($disableEntities);
114+
libxml_clear_errors();
115+
116+
if (false === $result = @$dom->schemaValidateSource($this->xsd)) {
117+
$this->setXMLConstraintErrors();
118+
}
119+
120+
libxml_clear_errors();
121+
libxml_use_internal_errors($internalErrors);
122+
123+
return $result;
124+
}
125+
126+
private function setXMLConstraintErrors()
127+
{
128+
foreach (libxml_get_errors() as $error) {
129+
if (LIBXML_ERR_WARNING === $error->level) {
130+
$level = 'warning ';
131+
} elseif (LIBXML_ERR_ERROR === $error->level) {
132+
$level = 'error ';
133+
} elseif (LIBXML_ERR_FATAL === $error->level) {
134+
$level = 'fatal ';
135+
} else {
136+
$level = '';
137+
}
138+
139+
$this->xmlConstraintErrors[] = sprintf('[%s%s] %s (line %d, column %d).', $level, $error->code, trim($error->message), $error->line, $error->column);
140+
}
141+
}
142+
}

0 commit comments

Comments
 (0)