diff --git a/composer.json b/composer.json index 6065ad1..631bb1d 100644 --- a/composer.json +++ b/composer.json @@ -10,10 +10,14 @@ } ], "require": { - "php": ">=7.0" + "php": ">=7.0", + "ext-libxml": "*", + "ext-dom": "*", + "ext-simplexml": "*" }, "require-dev": { - "phpunit/phpunit": "6.*" + "phpunit/phpunit": "6.*", + "mikey179/vfsstream": "^1.6" }, "autoload": { "psr-4": { diff --git a/src/Exceptions/FileBadFormatException.php b/src/Exceptions/FileBadFormatException.php index 0ddc5fb..7d645e2 100644 --- a/src/Exceptions/FileBadFormatException.php +++ b/src/Exceptions/FileBadFormatException.php @@ -1,15 +1,21 @@ _xmlObject) === false) { + libxml_use_internal_errors(true); + $domDocument = new \DOMDocument(); + $domDocument->recover = true; + $domDocument->loadXML($this->getFileContents()); + $this->_xmlObject = simplexml_load_string($domDocument->saveXML()); + } + return $this->_xmlObject; + } + + /** + * Returns array representation of attributes of the XML tree node attribute + * If $topLevelKey is sent only that node's attributes are returned + * + * WARNING: This method might take lot of time to complete when XML tree is large + * + * @param string $topLevelKey + * @return array + */ + public function getArray($topLevelKey = '') + { + $xmlObject = $this->getXmlObject(); + if (!empty($topLevelKey)) { + return get_object_vars($xmlObject->$topLevelKey); + } + return get_object_vars($xmlObject); + } + /** + * @inheritdoc + */ + protected function validateFormat() + { + if (filesize($this->_filePath) == 0 || $this->getFileContents() === null) { + throw new FileBadFormatException(); + } + $fileContents = $this->getFileContents(); + if (substr($fileContents, 0, strlen('')) !== '') { + throw new FileBadFormatException(); + } + } } \ No newline at end of file diff --git a/src/FileSystem/File.php b/src/FileSystem/File.php index 6dd2db6..0b57724 100644 --- a/src/FileSystem/File.php +++ b/src/FileSystem/File.php @@ -1,15 +1,70 @@ _filePath = $filePath; + $this->validateFileExists(); + $this->validateFormat(); + } + + /** + * Checks whether the specified file exists + * + * @throws FileNotFoundException + */ + protected function validateFileExists() + { + if (file_exists($this->_filePath) === false) { + throw new FileNotFoundException(); + } + } + + /** + * Checks whether the specified file isn't empty + * + * @throws FileBadFormatException + */ + protected function validateFormat() + { + if (filesize($this->_filePath) == 0 || $this->getFileContents() === null) { + throw new FileBadFormatException(); + } + } + /** + * Loads the file contents if not already loaded and returns the same + * + * @return null|string + */ + public function getFileContents() + { + if (isset($this->_fileContents) === false) { + $this->_fileContents = file_get_contents($this->_filePath); + } + return $this->_fileContents; + } } \ No newline at end of file diff --git a/src/FileSystem/Server/WorldDrop.php b/src/FileSystem/Server/WorldDrop.php index 1200050..0098f4e 100644 --- a/src/FileSystem/Server/WorldDrop.php +++ b/src/FileSystem/Server/WorldDrop.php @@ -1,15 +1,41 @@ getFileContents(); + return explode("\n", $fileContents); + } + /** + * @inheritdoc + */ + protected function validateFormat() + { + if (filesize($this->_filePath) == 0 || $this->getFileContents() === null) { + throw new FileBadFormatException(); + } + $fileContents = $this->getFileContents(); + if (substr($fileContents, 0, strlen('[WorldDrop]')) !== '[WorldDrop]') { + throw new FileBadFormatException(); + } + } } \ No newline at end of file diff --git a/tests/CabalMsgTest.php b/tests/CabalMsgTest.php index 05b39e1..046e884 100644 --- a/tests/CabalMsgTest.php +++ b/tests/CabalMsgTest.php @@ -1,12 +1,66 @@ [ + 'cabal_msg.dec' => '', + 'cabal_msg_invalid.dec' => 'fileSystem = \org\bovigo\vfs\vfsStream::setup('root', 444, $directory); + } + + public function testIsThereAnySyntaxError() + { + $myClass = new \cyberinferno\Cabal\Helpers\FileSystem\Client\CabalMsg($this->fileSystem->url() . '/client/cabal_msg.dec'); + $this->assertTrue(is_object($myClass)); + unset($myClass); + } + + /** + * @expectedException \cyberinferno\Cabal\Helpers\Exceptions\FileNotFoundException + */ + public function testFileNotFoundExceptionIsThrownWhenNoFile() + { + $myClass = new \cyberinferno\Cabal\Helpers\FileSystem\Client\CabalMsg( + $this->fileSystem->url() . '/unknown.dec' + ); + unset($myClass); + } + + /** + * @expectedException \cyberinferno\Cabal\Helpers\Exceptions\FileBadFormatException + */ + public function testFileBadFormatExceptionIsThrownWhenNoFile() + { + $myClass = new \cyberinferno\Cabal\Helpers\FileSystem\Client\CabalMsg( + $this->fileSystem->url() . '/client/cabal_msg_invalid.dec' + ); + unset($myClass); + } + + public function testGetXmlObject() + { + $myClass = new \cyberinferno\Cabal\Helpers\FileSystem\Client\CabalMsg( + $this->fileSystem->url() . '/client/cabal_msg.dec' + ); + $result = $myClass->getXmlObject(); + $this->assertTrue($result instanceof \SimpleXMLElement); + } + public function testGetArray() + { + $myClass = new \cyberinferno\Cabal\Helpers\FileSystem\Client\CabalMsg( + $this->fileSystem->url() . '/client/cabal_msg.dec' + ); + $result = $myClass->getArray(); + $this->assertTrue(is_array($result)); + $result = $myClass->getArray('version'); + $this->assertTrue(!empty($result)); + } } \ No newline at end of file diff --git a/tests/GameConstantsTest.php b/tests/GameConstantsTest.php index 509e7fd..a997e07 100644 --- a/tests/GameConstantsTest.php +++ b/tests/GameConstantsTest.php @@ -40,6 +40,6 @@ public function testListAuras() $myClass = new cyberinferno\Cabal\Helpers\GameConstants(); $result = $myClass::listAuras(); $this->assertTrue(is_array($result)); - $this->assertEquals(6, count($result)); + $this->assertEquals(7, count($result)); } } \ No newline at end of file diff --git a/tests/WorldDropTest.php b/tests/WorldDropTest.php index 3244f60..d25c2a4 100644 --- a/tests/WorldDropTest.php +++ b/tests/WorldDropTest.php @@ -1,12 +1,55 @@ [ + 'World_drop.scp' => '[WorldDrop]', + 'World_drop_invalid.scp' => '[World' + ] + ]; + $this->fileSystem = \org\bovigo\vfs\vfsStream::setup('root', 444, $directory); + } + + public function testIsThereAnySyntaxError() + { + $myClass = new \cyberinferno\Cabal\Helpers\FileSystem\Server\WorldDrop($this->fileSystem->url() . '/server/World_drop.scp'); + $this->assertTrue(is_object($myClass)); + unset($myClass); + } + + /** + * @expectedException \cyberinferno\Cabal\Helpers\Exceptions\FileNotFoundException + */ + public function testFileNotFoundExceptionIsThrownWhenNoFile() + { + $myClass = new \cyberinferno\Cabal\Helpers\FileSystem\Server\WorldDrop( + $this->fileSystem->url() . '/unknown.dec' + ); + unset($myClass); + } + + /** + * @expectedException \cyberinferno\Cabal\Helpers\Exceptions\FileBadFormatException + */ + public function testFileBadFormatExceptionIsThrownWhenNoFile() + { + $myClass = new \cyberinferno\Cabal\Helpers\FileSystem\Server\WorldDrop( + $this->fileSystem->url() . '/server/World_drop_invalid.scp' + ); + unset($myClass); + } + public function testGetArray() + { + $myClass = new \cyberinferno\Cabal\Helpers\FileSystem\Server\WorldDrop( + $this->fileSystem->url() . '/server/World_drop.scp' + ); + $result = $myClass->getArray(); + $this->assertTrue(is_array($result)); + } } \ No newline at end of file