Ensure user-provided SupportVectorMachine paths are valid (#126)

This commit is contained in:
Marcin Michalski 2017-09-02 22:44:19 +02:00 committed by Arkadiusz Kondas
parent ba2b8c8a9c
commit 61d2b7d115
3 changed files with 121 additions and 9 deletions

View File

@ -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));
}
}

View File

@ -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);
}
}
}
}

View File

@ -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');
}
}