Skip to content
This repository has been archived by the owner on Jan 31, 2020. It is now read-only.

add IsCountable validator, to enforce type and count elements. #156

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
150 changes: 150 additions & 0 deletions src/IsCountable.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,150 @@
<?php

namespace Zend\Validator;

use Zend\Validator\Exception\RuntimeException;

class IsCountable extends AbstractValidator
{
const NOT_COUNTABLE = 'notCountable';
const NOT_EQUALS = 'notEquals';
const GREATER_THAN = 'greaterThan';
const LESS_THAN = 'lessThan';

/**
* Validation failure message template definitions
*
* @var array
*/
protected $messageTemplates = [
self::NOT_COUNTABLE => "The input must be an array or an instance of \\Countable",
self::NOT_EQUALS => "The input count must equal '%count%'",
self::GREATER_THAN => "The input count must be less than '%max%', inclusively",
self::LESS_THAN => "The input count must be greater than '%min%', inclusively",
];

/**
* Additional variables available for validation failure messages
*
* @var array
*/
protected $messageVariables = [
'count' => ['options' => 'count'],
'min' => ['options' => 'min'],
'max' => ['options' => 'max'],
];

/**
* Options for the between validator
*
* @var array
*/
protected $options = [
'count' => null,
'min' => null,
'max' => null,
];

/**
* Returns true if and only if $value is countable (and the count validates against optional values).
*
* @param string $value
* @return bool
* @throws Exception\RuntimeException
*/
public function isValid($value)
{
if (!(is_array($value) || $value instanceof \Countable)) {
throw new RuntimeException($this->messageTemplates[self::NOT_COUNTABLE]);
}

$count = count($value);

if (is_numeric($this->options['count'])) {
if ($count != $this->options['count']) {
$this->error(self::NOT_EQUALS);
return false;
}

return true;
}

if (is_numeric($this->options['max']) && $count > $this->options['max']) {
$this->error(self::GREATER_THAN);
return false;
}

if (is_numeric($this->options['min']) && $count < $this->options['min']) {
$this->error(self::LESS_THAN);
return false;
}

return true;
}

/**
* Returns the count option
*
* @return mixed
*/
public function getCount()
{
return $this->options['count'];
}

/**
* Sets the count option
*
* @param int $count
* @return self Provides a fluent interface
*/
public function setCount($count)
{
$this->options['count'] = $count;
return $this;
}

/**
* Returns the min option
*
* @return mixed
*/
public function getMin()
{
return $this->options['min'];
}

/**
* Sets the min option
*
* @param int $min
* @return self Provides a fluent interface
*/
public function setMin($min)
{
$this->options['min'] = $min;
return $this;
}

/**
* Returns the max option
*
* @return mixed
*/
public function getMax()
{
return $this->options['max'];
}

/**
* Sets the max option
*
* @param int $max
* @return self Provides a fluent interface
*/
public function setMax($max)
{
$this->options['max'] = $max;
return $this;
}
}
87 changes: 87 additions & 0 deletions test/IsCountableTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
<?php

namespace ZendTest\Validator;

use Zend\Validator\IsCountable;

class IsCountableTest extends \PHPUnit_Framework_TestCase
{
/** @var IsCountable */
private $sut;

protected function setUp()
{
$this->sut = new IsCountable();
}

public function testArrayIsValid()
{
$this->sut->setMin(1);
$this->sut->setMax(10);

self::assertTrue($this->sut->isValid(['Foo']), json_encode($this->sut->getMessages()));
self::assertCount(0, $this->sut->getMessages());
}

public function testIteratorIsValid()
{
self::assertTrue($this->sut->isValid(new \SplQueue()), json_encode($this->sut->getMessages()));
self::assertCount(0, $this->sut->getMessages());
}

public function testValidEquals()
{
$this->sut->setCount(1);

self::assertTrue($this->sut->isValid(['Foo']));
self::assertCount(0, $this->sut->getMessages());
}

public function testValidMax()
{
$this->sut->setMax(1);

self::assertTrue($this->sut->isValid(['Foo']));
self::assertCount(0, $this->sut->getMessages());
}

public function testValidMin()
{
$this->sut->setMin(1);

self::assertTrue($this->sut->isValid(['Foo']));
self::assertCount(0, $this->sut->getMessages());
}

public function testInvalidNotEquals()
{
$this->sut->setCount(2);

self::assertFalse($this->sut->isValid(['Foo']));
self::assertCount(1, $this->sut->getMessages());
}

/**
* @expectedException \Zend\Validator\Exception\RuntimeException
*/
public function testInvalidType()
{
$this->sut->isValid(new \stdClass());
}

public function testInvalidExceedsMax()
{
$this->sut->setMax(1);

self::assertFalse($this->sut->isValid(['Foo', 'Bar']));
self::assertCount(1, $this->sut->getMessages());
}

public function testInvalidExceedsMin()
{
$this->sut->setMin(2);

self::assertFalse($this->sut->isValid(['Foo']));
self::assertCount(1, $this->sut->getMessages());
}
}