diff --git a/src/Phpml/Exception/InvalidArgumentException.php b/src/Phpml/Exception/InvalidArgumentException.php index 313ca79..2c32a6a 100644 --- a/src/Phpml/Exception/InvalidArgumentException.php +++ b/src/Phpml/Exception/InvalidArgumentException.php @@ -39,7 +39,7 @@ class InvalidArgumentException extends \Exception */ public static function arraySizeToSmall($minimumSize = 2) { - return new self(sprintf('The array must have at least %s elements', $minimumSize)); + return new self(sprintf('The array must have at least %d elements', $minimumSize)); } /** @@ -73,7 +73,7 @@ class InvalidArgumentException extends \Exception */ public static function invalidTarget($target) { - return new self('Target with value '.$target.' is not part of the accepted classes'); + return new self(sprintf('Target with value "%s" is not part of the accepted classes', $target)); } /** @@ -83,7 +83,7 @@ class InvalidArgumentException extends \Exception */ public static function invalidStopWordsLanguage(string $language) { - return new self(sprintf('Can\'t find %s language for StopWords', $language)); + return new self(sprintf('Can\'t find "%s" language for StopWords', $language)); } /** @@ -110,8 +110,51 @@ class InvalidArgumentException extends \Exception return new self('Provide at least 2 different classes'); } + /** + * @return InvalidArgumentException + */ public static function inconsistentClasses() { return new self('The provided classes don\'t match the classes provided in the constructor'); } + + /** + * @param string $file + * + * @return InvalidArgumentException + */ + public static function fileNotFound(string $file) + { + return new self(sprintf('File "%s" not found', $file)); + } + + /** + * @param string $file + * + * @return InvalidArgumentException + */ + public static function fileNotExecutable(string $file) + { + return new self(sprintf('File "%s" is not executable', $file)); + } + + /** + * @param string $path + * + * @return InvalidArgumentException + */ + public static function pathNotFound(string $path) + { + return new self(sprintf('The specified path "%s" does not exist', $path)); + } + + /** + * @param string $path + * + * @return InvalidArgumentException + */ + public static function pathNotWritable(string $path) + { + return new self(sprintf('The specified path "%s" is not writable', $path)); + } } diff --git a/src/Phpml/SupportVectorMachine/SupportVectorMachine.php b/src/Phpml/SupportVectorMachine/SupportVectorMachine.php index b29bfa5..9ee3c3b 100644 --- a/src/Phpml/SupportVectorMachine/SupportVectorMachine.php +++ b/src/Phpml/SupportVectorMachine/SupportVectorMachine.php @@ -4,6 +4,7 @@ declare(strict_types=1); namespace Phpml\SupportVectorMachine; +use Phpml\Exception\InvalidArgumentException; use Phpml\Helper\Trainable; class SupportVectorMachine @@ -140,25 +141,29 @@ class SupportVectorMachine /** * @param string $binPath * - * @return $this + * @throws InvalidArgumentException */ public function setBinPath(string $binPath) { - $this->binPath = $binPath; + $this->ensureDirectorySeparator($binPath); + $this->verifyBinPath($binPath); - return $this; + $this->binPath = $binPath; } /** * @param string $varPath * - * @return $this + * @throws InvalidArgumentException */ public function setVarPath(string $varPath) { - $this->varPath = $varPath; + if (!is_writable($varPath)) { + throw InvalidArgumentException::pathNotWritable($varPath); + } - return $this; + $this->ensureDirectorySeparator($varPath); + $this->varPath = $varPath; } /** @@ -270,4 +275,38 @@ class SupportVectorMachine escapeshellarg($modelFileName) ); } + + /** + * @param string $path + */ + private function ensureDirectorySeparator(string &$path) + { + if (substr($path, -1) !== DIRECTORY_SEPARATOR) { + $path .= DIRECTORY_SEPARATOR; + } + } + + /** + * @param string $path + * + * @throws InvalidArgumentException + */ + private function verifyBinPath(string $path) + { + if (!is_dir($path)) { + throw InvalidArgumentException::pathNotFound($path); + } + + $osExtension = $this->getOSExtension(); + foreach (['svm-predict', 'svm-scale', 'svm-train'] as $filename) { + $filePath = $path.$filename.$osExtension; + if (!file_exists($filePath)) { + throw InvalidArgumentException::fileNotFound($filePath); + } + + if (!is_executable($filePath)) { + throw InvalidArgumentException::fileNotExecutable($filePath); + } + } + } } diff --git a/tests/Phpml/SupportVectorMachine/SupportVectorMachineTest.php b/tests/Phpml/SupportVectorMachine/SupportVectorMachineTest.php index 1953829..4cc6d57 100644 --- a/tests/Phpml/SupportVectorMachine/SupportVectorMachineTest.php +++ b/tests/Phpml/SupportVectorMachine/SupportVectorMachineTest.php @@ -80,4 +80,34 @@ SV $this->assertEquals('b', $predictions[1]); $this->assertEquals('c', $predictions[2]); } + + /** + * @expectedException \Phpml\Exception\InvalidArgumentException + * @expectedExceptionMessage is not writable + */ + public function testThrowExceptionWhenVarPathIsNotWritable() + { + $svm = new SupportVectorMachine(Type::C_SVC, Kernel::RBF); + $svm->setVarPath('var-path'); + } + + /** + * @expectedException \Phpml\Exception\InvalidArgumentException + * @expectedExceptionMessage does not exist + */ + public function testThrowExceptionWhenBinPathDoesNotExist() + { + $svm = new SupportVectorMachine(Type::C_SVC, Kernel::RBF); + $svm->setBinPath('bin-path'); + } + + /** + * @expectedException \Phpml\Exception\InvalidArgumentException + * @expectedExceptionMessage not found + */ + public function testThrowExceptionWhenFileIsNotFoundInBinPath() + { + $svm = new SupportVectorMachine(Type::C_SVC, Kernel::RBF); + $svm->setBinPath('var'); + } }