initial commit

Add main logic. Add some dogs and some actions.
This commit is contained in:
2018-06-03 18:27:37 +07:00
commit 9aca729675
16 changed files with 2402 additions and 0 deletions

1
.gitignore vendored Normal file
View File

@@ -0,0 +1 @@
/vendor/

27
composer.json Normal file
View File

@@ -0,0 +1,27 @@
{
"name": "dannc/test-devjsru",
"description": "test task",
"type": "project",
"license": "MIT",
"authors": [
{
"name": "dannc",
"email": "dannc.sao@gmail.com"
}
],
"minimum-stability": "RC",
"require": {
"php": "^7.2",
"nategood/commando": "^0.2",
"illuminate/support": "^5.6"
},
"require-dev": {
"squizlabs/php_codesniffer": "^3.0@dev",
"phpunit/phpunit": "^7.2"
},
"autoload": {
"psr-4": {
"Dogs\\": "src/"
}
}
}

2015
composer.lock generated Normal file

File diff suppressed because it is too large Load Diff

38
dogs.php Normal file
View File

@@ -0,0 +1,38 @@
<?php
require_once './vendor/autoload.php';
$cmd = new Commando\Command();
$knownKinds = \Dogs\DogAbstract::getKnownKinds();
$knownActions = \Dogs\DogAbstract::getKnownActions();
$cmd->option()
->require()
->describedAs('Dog kind. Known values: ' . implode(', ', $knownKinds));
$cmd->option()
->require()
->describedAs('Action of dog. Known actions: ' . implode(', ', $knownActions));
$dogKind = $cmd[0];
$dogAction = $cmd[1];
try {
echo "You choose {$dogKind}" . PHP_EOL;
$dog = Dogs\DogAbstract::buildDog($dogKind);
echo "Dog going to {$dogAction}" . PHP_EOL;
$result = $dog->$dogAction();
echo $result;
} catch (Dogs\Exceptions\ApplicationException $e) {
echo $e->getMessage();
return;
} catch (\Throwable $e) {
echo 'Something going wrong.' . PHP_EOL;
echo 'Message: ' . $e->getMessage();
return;
}

14
src/Actions/IHunt.php Normal file
View File

@@ -0,0 +1,14 @@
<?php
namespace Dogs\Actions;
use Dogs\Prey;
interface IHunt
{
/**
* Go to hunt and get a prey
*
* @return \Dogs\Prey
*/
public function makeHunt() : Prey;
}

12
src/Actions/ISound.php Normal file
View File

@@ -0,0 +1,12 @@
<?php
namespace Dogs\Actions;
interface ISound
{
/**
* Make a sound and return it's string representation
*
* @return string
*/
public function makeSound() : string;
}

93
src/DogAbstract.php Normal file
View File

@@ -0,0 +1,93 @@
<?php
namespace Dogs;
use Dogs\Actions\IHunt;
use Dogs\Actions\ISound;
/**
* @method Prey hunt()
* @method string sound()
*/
abstract class DogAbstract implements IHunt, ISound
{
public const KIND_PLUSH_LABRADOR = 'plush-labrador';
public const KIND_PUG = 'pug';
public const KIND_RUBBER_DACHSHUND = 'rubber-dachshund';
public const KIND_SHIBA_INU = 'shiba-inu';
/**
* @return string
*/
abstract public function getKind() : string;
/**
* @param string $name
* @param array $arguments
* @return mixed
* @throws \Dogs\Exceptions\UnknownActionException
*/
public function __call(string $name, array $arguments)
{
$action = "make" . studly_case($name);
if (method_exists($this, $action)) {
return $this->$action();
}
throw new \Dogs\Exceptions\UnknownActionException($name);
}
/**
* Make an instance of dog
*
* @param string $kind
* @return self
* @throws \Dogs\Exceptions\UnknownKindException
*/
public static function buildDog(string $kind) : self
{
if (static::isDog($kind)) {
$kindClass = '\\Dogs\\Kinds\\' . studly_case($kind);
return new $kindClass();
}
throw new \Dogs\Exceptions\UnknownKindException($kind);
}
/**
* Is specified kind is a dog
*
* @param string $kind
* @return boolean
*/
public static function isDog(string $kind) : bool
{
$kindClass = studly_case($kind);
return class_exists("\\Dogs\\Kinds\\{$kindClass}");
}
/**
* @return array|string[]
*/
public static function getKnownKinds() : array
{
return [
static::KIND_PLUSH_LABRADOR,
static::KIND_PUG,
static::KIND_RUBBER_DACHSHUND,
static::KIND_SHIBA_INU
];
}
public static function getKnownActions() : array
{
$allMethods = get_class_methods(static::class);
$actionMethods = array_filter($allMethods, function (string $methodName) {
return strpos($methodName, 'make') === 0;
});
return array_map(function (string $methodName) {
$action = str_replace('make', '', $methodName);
return kebab_case($action);
}, $actionMethods);
}
}

View File

@@ -0,0 +1,6 @@
<?php
namespace Dogs\Exceptions;
class ApplicationException extends \Exception
{
}

View File

@@ -0,0 +1,6 @@
<?php
namespace Dogs\Exceptions;
class InabilityToDoAction extends ApplicationException
{
}

View File

@@ -0,0 +1,15 @@
<?php
namespace Dogs\Exceptions;
class UnknownActionException extends ApplicationException
{
/**
* @param string $action
* @param \Trowable $previous
*/
public function __construct(string $action, \Trowable $previous = null)
{
$message = "Dog can not do action: {$action}";
parent::__construct($message, 400, $previous);
}
}

View File

@@ -0,0 +1,11 @@
<?php
namespace Dogs\Exceptions;
class UnknownKindException extends ApplicationException
{
public function __construct(string $kind, \Throwable $previous = null)
{
$message = "Kind {$kind} is not defined";
return parent::__construct($message, 400, $previous);
}
}

View File

@@ -0,0 +1,32 @@
<?php
namespace Dogs\Kinds;
use Dogs\Prey;
use Illuminate\Support\Collection;
class PlushLabrador extends \Dogs\DogAbstract
{
/**
* @inheritDoc
*/
public function getKind() : string
{
return static::KIND_PLUSH_LABRADOR;
}
/**
* @inheritDoc
*/
public function makeHunt() : Prey
{
throw new \Dogs\Exceptions\InabilityToDoAction('This is just a toy.');
}
/**
* @inheritDoc
*/
public function makeSound() : string
{
throw new \Dogs\Exceptions\InabilityToDoAction('That toy does not make sound');
}
}

31
src/Kinds/Pug.php Normal file
View File

@@ -0,0 +1,31 @@
<?php
namespace Dogs\Kinds;
use Dogs\Prey;
class Pug extends \Dogs\DogAbstract
{
/**
* @inheritDoc
*/
public function getKind() : string
{
return static::KIND_PUG;
}
/**
* @inheritDoc
*/
public function makeHunt() : Prey
{
throw new \Dogs\Exceptions\InabilityToDoAction('Pug is too lazy to do that.');
}
/**
* @inheritDoc
*/
public function makeSound() : string
{
return '"arghp! arghp!"';
}
}

View File

@@ -0,0 +1,32 @@
<?php
namespace Dogs\Kinds;
use Dogs\Prey;
use Illuminate\Support\Collection;
class RubberDachshund extends \Dogs\DogAbstract
{
/**
* @inheritDoc
*/
public function getKind() : string
{
return static::KIND_RUBBER_DACHSHUND;
}
/**
* @inheritDoc
*/
public function makeHunt() : Prey
{
throw new \Dogs\Exceptions\InabilityToDoAction('This is just a toy.');
}
/**
* @inheritDoc
*/
public function makeSound() : string
{
return '"quack! quack!"';
}
}

37
src/Kinds/ShibaInu.php Normal file
View File

@@ -0,0 +1,37 @@
<?php
namespace Dogs\Kinds;
use Dogs\Prey;
use Illuminate\Support\Collection;
class ShibaInu extends \Dogs\DogAbstract
{
/**
* @inheritDoc
*/
public function getKind() : string
{
return static::KIND_SHIBA_INU;
}
/**
* @inheritDoc
*/
public function makeHunt() : Prey
{
$preys = new Collection([
new \Dogs\Prey('duck'),
new \Dogs\Prey('twig'),
new \Dogs\Prey('cat')
]);
return $preys->random();
}
/**
* @inheritDoc
*/
public function makeSound() : string
{
return '"woof! woof!"';
}
}

32
src/Prey.php Normal file
View File

@@ -0,0 +1,32 @@
<?php
namespace Dogs;
class Prey
{
/** @var string $name */
protected $name;
/**
* @param string $name
*/
public function __construct(string $name)
{
$this->name = $name;
}
/**
* @return string
*/
public function getName() : string
{
return $this->name;
}
/**
* @return string
*/
public function __toString() : string
{
return "Prey: {$this->getName()}";
}
}