loadXML($xmlFile); $errors = libxml_get_errors(); libxml_clear_errors(); $this->assertEmpty($errors, print_r($errors, true)); $schemaLocations = []; preg_match('/xsi:noNamespaceSchemaLocation=\s*"(urn:[^"]+)"/s', $xmlFile, $schemaLocations); $this->assertEquals( 2, count($schemaLocations), 'The XML file at ' . $filename . ' does not have a schema properly defined. It should ' . 'have a xsi:noNamespaceSchemaLocation attribute defined with a URN path. E.g. ' . 'xsi:noNamespaceSchemaLocation="urn:magento:framework:Relative_Path/something.xsd"' ); try { $errors = \Magento\Framework\Config\Dom::validateDomDocument($dom, $schemaLocations[1]); } catch (\Exception $exception) { $errors = [$exception->__toString()]; } $this->assertEmpty( $errors, "Error validating $filename against {$schemaLocations[1]}\n" . print_r($errors, true) ); }, $this->getXmlFiles() ); } public function getSchemas() { $componentRegistrar = new ComponentRegistrar(); $codeSchemas = []; foreach ($componentRegistrar->getPaths(ComponentRegistrar::MODULE) as $modulePath) { $codeSchemas = array_merge($codeSchemas, $this->_getFiles($modulePath, '*.xsd')); } $libSchemas = []; foreach ($componentRegistrar->getPaths(ComponentRegistrar::LIBRARY) as $libraryPath) { $libSchemas = array_merge($libSchemas, $this->_getFiles($libraryPath, '*.xsd')); } return $this->_dataSet(array_merge($codeSchemas, $libSchemas)); } public function getXmlFiles() { $componentRegistrar = new ComponentRegistrar(); $codeXml = []; foreach ($componentRegistrar->getPaths(ComponentRegistrar::MODULE) as $modulePath) { $codeXml = array_merge($codeXml, $this->_getFiles($modulePath, '*.xml', '/.\/Test\/./')); } $this->_filterSpecialCases($codeXml); $designXml = []; foreach ($componentRegistrar->getPaths(ComponentRegistrar::THEME) as $themePath) { $designXml = array_merge($designXml, $this->_getFiles($themePath, '*.xml')); } $libXml = []; foreach ($componentRegistrar->getPaths(ComponentRegistrar::LIBRARY) as $libraryPath) { $libXml = array_merge($libXml, $this->_getFiles($libraryPath, '*.xml', '/.\/Test\/./')); } return $this->_dataSet(array_merge($codeXml, $designXml, $libXml)); } protected function _getFiles($dir, $pattern, $skipDirPattern = '') { $files = glob($dir . '/' . $pattern, GLOB_NOSORT); if (empty($skipDirPattern) || !preg_match($skipDirPattern, $dir)) { foreach (glob($dir . '/*', GLOB_ONLYDIR | GLOB_NOSORT) as $newDir) { $files = array_merge($files, $this->_getFiles($newDir, $pattern, $skipDirPattern)); } } return $files; } /** * Files that are exempt from validation * * @param array &$files */ private function _filterSpecialCases(&$files) { $list = [ '#etc/countries.xml$#', '#conf/schema.xml$#', '#layout/swagger_index_index.xml$#', '#Doc/etc/doc/vars.xml$#', '#phpunit.xml$#', '#etc/db_schema.xml$#', '#Test/Mftf#', ]; foreach ($list as $pattern) { foreach ($files as $key => $value) { if (preg_match($pattern, $value)) { unset($files[$key]); } } } } protected function _dataSet($files) { $data = []; foreach ($files as $file) { $data[substr($file, strlen(BP))] = [$file]; } return $data; } }