502 lines
16 KiB
PHP
502 lines
16 KiB
PHP
<?php
|
|
/*
|
|
* This file is part of the Comparator package.
|
|
*
|
|
* (c) Sebastian Bergmann <sebastian@phpunit.de>
|
|
*
|
|
* For the full copyright and license information, please view the LICENSE
|
|
* file that was distributed with this source code.
|
|
*/
|
|
|
|
namespace SebastianBergmann\Comparator;
|
|
|
|
use DateTime;
|
|
use DateTimeImmutable;
|
|
use DateTimeZone;
|
|
|
|
/**
|
|
* @coversDefaultClass SebastianBergmann\Comparator\DateTimeComparator
|
|
*
|
|
*/
|
|
class DateTimeComparatorTest
|
|
{
|
|
private $comparator;
|
|
|
|
protected function setUp()
|
|
{
|
|
$this->comparator = new DateTimeComparator;
|
|
}
|
|
|
|
public function acceptsFailsProvider()
|
|
{
|
|
$datetime = new DateTime;
|
|
|
|
return array(
|
|
array($datetime, null),
|
|
array(null, $datetime),
|
|
array(null, null)
|
|
);
|
|
}
|
|
|
|
public function assertEqualsSucceedsProvider()
|
|
{
|
|
return array(
|
|
array(
|
|
new DateTime('2013-03-29 04:13:35', new DateTimeZone('America/New_York')),
|
|
new DateTime('2013-03-29 04:13:35', new DateTimeZone('America/New_York'))
|
|
),
|
|
array(
|
|
new DateTime('2013-03-29 04:13:35', new DateTimeZone('America/New_York')),
|
|
new DateTime('2013-03-29 04:13:25', new DateTimeZone('America/New_York')),
|
|
10
|
|
),
|
|
array(
|
|
new DateTime('2013-03-29 04:13:35', new DateTimeZone('America/New_York')),
|
|
new DateTime('2013-03-29 04:14:40', new DateTimeZone('America/New_York')),
|
|
65
|
|
),
|
|
array(
|
|
new DateTime('2013-03-29', new DateTimeZone('America/New_York')),
|
|
new DateTime('2013-03-29', new DateTimeZone('America/New_York'))
|
|
),
|
|
array(
|
|
new DateTime('2013-03-29 04:13:35', new DateTimeZone('America/New_York')),
|
|
new DateTime('2013-03-29 03:13:35', new DateTimeZone('America/Chicago'))
|
|
),
|
|
array(
|
|
new DateTime('2013-03-29 04:13:35', new DateTimeZone('America/New_York')),
|
|
new DateTime('2013-03-29 03:13:49', new DateTimeZone('America/Chicago')),
|
|
15
|
|
),
|
|
array(
|
|
new DateTime('2013-03-30', new DateTimeZone('America/New_York')),
|
|
new DateTime('2013-03-29 23:00:00', new DateTimeZone('America/Chicago'))
|
|
),
|
|
array(
|
|
new DateTime('2013-03-30', new DateTimeZone('America/New_York')),
|
|
new DateTime('2013-03-29 23:01:30', new DateTimeZone('America/Chicago')),
|
|
100
|
|
),
|
|
array(
|
|
new DateTime('@1364616000'),
|
|
new DateTime('2013-03-29 23:00:00', new DateTimeZone('America/Chicago'))
|
|
),
|
|
array(
|
|
new DateTime('2013-03-29T05:13:35-0500'),
|
|
new DateTime('2013-03-29T04:13:35-0600')
|
|
)
|
|
);
|
|
}
|
|
|
|
public function assertEqualsFailsProvider()
|
|
{
|
|
return array(
|
|
array(
|
|
new DateTime('2013-03-29 04:13:35', new DateTimeZone('America/New_York')),
|
|
new DateTime('2013-03-29 03:13:35', new DateTimeZone('America/New_York'))
|
|
),
|
|
array(
|
|
new DateTime('2013-03-29 04:13:35', new DateTimeZone('America/New_York')),
|
|
new DateTime('2013-03-29 03:13:35', new DateTimeZone('America/New_York')),
|
|
3500
|
|
),
|
|
array(
|
|
new DateTime('2013-03-29 04:13:35', new DateTimeZone('America/New_York')),
|
|
new DateTime('2013-03-29 05:13:35', new DateTimeZone('America/New_York')),
|
|
3500
|
|
),
|
|
array(
|
|
new DateTime('2013-03-29', new DateTimeZone('America/New_York')),
|
|
new DateTime('2013-03-30', new DateTimeZone('America/New_York'))
|
|
),
|
|
array(
|
|
new DateTime('2013-03-29', new DateTimeZone('America/New_York')),
|
|
new DateTime('2013-03-30', new DateTimeZone('America/New_York')),
|
|
43200
|
|
),
|
|
array(
|
|
new DateTime('2013-03-29 04:13:35', new DateTimeZone('America/New_York')),
|
|
new DateTime('2013-03-29 04:13:35', new DateTimeZone('America/Chicago')),
|
|
),
|
|
array(
|
|
new DateTime('2013-03-29 04:13:35', new DateTimeZone('America/New_York')),
|
|
new DateTime('2013-03-29 04:13:35', new DateTimeZone('America/Chicago')),
|
|
3500
|
|
),
|
|
array(
|
|
new DateTime('2013-03-30', new DateTimeZone('America/New_York')),
|
|
new DateTime('2013-03-30', new DateTimeZone('America/Chicago'))
|
|
),
|
|
array(
|
|
new DateTime('2013-03-29T05:13:35-0600'),
|
|
new DateTime('2013-03-29T04:13:35-0600')
|
|
),
|
|
array(
|
|
new DateTime('2013-03-29T05:13:35-0600'),
|
|
new DateTime('2013-03-29T05:13:35-0500')
|
|
),
|
|
);
|
|
}
|
|
|
|
/**
|
|
* @covers ::accepts
|
|
*/
|
|
public function testAcceptsSucceeds()
|
|
{
|
|
$this->assertTrue(
|
|
$this->comparator->accepts(
|
|
new DateTime,
|
|
new DateTime
|
|
)
|
|
);
|
|
}
|
|
|
|
/**
|
|
* @covers ::accepts
|
|
* @dataProvider acceptsFailsProvider
|
|
*/
|
|
public function testAcceptsFails($expected, $actual)
|
|
{
|
|
$this->assertFalse(
|
|
$this->comparator->accepts($expected, $actual)
|
|
);
|
|
}
|
|
|
|
/**
|
|
* @covers ::assertEquals
|
|
* @dataProvider assertEqualsSucceedsProvider
|
|
*/
|
|
function testAssertEqualsSucceeds($expected, $actual, $delta = 0.0)
|
|
{
|
|
$exception = null;
|
|
|
|
try {
|
|
$this->comparator->assertEquals($expected, $actual, $delta);
|
|
}
|
|
|
|
catch (ComparisonFailure $exception) {
|
|
}
|
|
|
|
$this->assertNull($exception, 'Unexpected ComparisonFailure');
|
|
}
|
|
|
|
/**
|
|
* @covers ::assertEquals
|
|
* @dataProvider assertEqualsFailsProvider
|
|
*/
|
|
function testAssertEqualsFails($expected, $actual, $delta = 0.0)
|
|
{
|
|
$this->setExpectedException(
|
|
'SebastianBergmann\\Comparator\\ComparisonFailure',
|
|
'Failed asserting that two DateTime objects are equal.'
|
|
);
|
|
$this->comparator->assertEquals($expected, $actual, $delta);
|
|
}
|
|
|
|
/**
|
|
* @requires PHP 5.5
|
|
* @covers ::accepts
|
|
*/
|
|
function testAcceptsDateTimeInterface()
|
|
{
|
|
$this->assertTrue($this->comparator->accepts(new DateTime, new DateTimeImmutable));
|
|
}
|
|
|
|
/**
|
|
* @requires PHP 5.5
|
|
* @covers ::assertEquals
|
|
*/
|
|
function testSupportsDateTimeInterface()
|
|
{
|
|
$this->comparator->assertEquals(
|
|
new DateTime('2013-03-29 04:13:35', new DateTimeZone('America/New_York')),
|
|
new DateTimeImmutable('2013-03-29 04:13:35', new DateTimeZone('America/New_York'))
|
|
);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
function assertEqualsSucceedsProvider()
|
|
{
|
|
return array(
|
|
array(
|
|
new DateTime('2013-03-29 04:13:35', new DateTimeZone('America/New_York')),
|
|
new DateTime('2013-03-29 04:13:35', new DateTimeZone('America/New_York'))
|
|
),
|
|
array(
|
|
new DateTime('2013-03-29 04:13:35', new DateTimeZone('America/New_York')),
|
|
new DateTime('2013-03-29 04:13:25', new DateTimeZone('America/New_York')),
|
|
10
|
|
),
|
|
array(
|
|
new DateTime('2013-03-29 04:13:35', new DateTimeZone('America/New_York')),
|
|
new DateTime('2013-03-29 04:14:40', new DateTimeZone('America/New_York')),
|
|
65
|
|
),
|
|
array(
|
|
new DateTime('2013-03-29', new DateTimeZone('America/New_York')),
|
|
new DateTime('2013-03-29', new DateTimeZone('America/New_York'))
|
|
),
|
|
array(
|
|
new DateTime('2013-03-29 04:13:35', new DateTimeZone('America/New_York')),
|
|
new DateTime('2013-03-29 03:13:35', new DateTimeZone('America/Chicago'))
|
|
),
|
|
array(
|
|
new DateTime('2013-03-29 04:13:35', new DateTimeZone('America/New_York')),
|
|
new DateTime('2013-03-29 03:13:49', new DateTimeZone('America/Chicago')),
|
|
15
|
|
),
|
|
array(
|
|
new DateTime('2013-03-30', new DateTimeZone('America/New_York')),
|
|
new DateTime('2013-03-29 23:00:00', new DateTimeZone('America/Chicago'))
|
|
),
|
|
array(
|
|
new DateTime('2013-03-30', new DateTimeZone('America/New_York')),
|
|
new DateTime('2013-03-29 23:01:30', new DateTimeZone('America/Chicago')),
|
|
100
|
|
),
|
|
array(
|
|
new DateTime('@1364616000'),
|
|
new DateTime('2013-03-29 23:00:00', new DateTimeZone('America/Chicago'))
|
|
),
|
|
array(
|
|
new DateTime('2013-03-29T05:13:35-0500'),
|
|
new DateTime('2013-03-29T04:13:35-0600')
|
|
)
|
|
);
|
|
}
|
|
|
|
|
|
function assertEqualsFailsProvider()
|
|
{
|
|
return array(
|
|
array(
|
|
new DateTime('2013-03-29 04:13:35', new DateTimeZone('America/New_York')),
|
|
new DateTime('2013-03-29 03:13:35', new DateTimeZone('America/New_York'))
|
|
),
|
|
array(
|
|
new DateTime('2013-03-29 04:13:35', new DateTimeZone('America/New_York')),
|
|
new DateTime('2013-03-29 03:13:35', new DateTimeZone('America/New_York')),
|
|
3500
|
|
),
|
|
array(
|
|
new DateTime('2013-03-29 04:13:35', new DateTimeZone('America/New_York')),
|
|
new DateTime('2013-03-29 05:13:35', new DateTimeZone('America/New_York')),
|
|
3500
|
|
),
|
|
array(
|
|
new DateTime('2013-03-29', new DateTimeZone('America/New_York')),
|
|
new DateTime('2013-03-30', new DateTimeZone('America/New_York'))
|
|
),
|
|
array(
|
|
new DateTime('2013-03-29', new DateTimeZone('America/New_York')),
|
|
new DateTime('2013-03-30', new DateTimeZone('America/New_York')),
|
|
43200
|
|
),
|
|
array(
|
|
new DateTime('2013-03-29 04:13:35', new DateTimeZone('America/New_York')),
|
|
new DateTime('2013-03-29 04:13:35', new DateTimeZone('America/Chicago')),
|
|
),
|
|
array(
|
|
new DateTime('2013-03-29 04:13:35', new DateTimeZone('America/New_York')),
|
|
new DateTime('2013-03-29 04:13:35', new DateTimeZone('America/Chicago')),
|
|
3500
|
|
),
|
|
array(
|
|
new DateTime('2013-03-30', new DateTimeZone('America/New_York')),
|
|
new DateTime('2013-03-30', new DateTimeZone('America/Chicago'))
|
|
),
|
|
array(
|
|
new DateTime('2013-03-29T05:13:35-0600'),
|
|
new DateTime('2013-03-29T04:13:35-0600')
|
|
),
|
|
array(
|
|
new DateTime('2013-03-29T05:13:35-0600'),
|
|
new DateTime('2013-03-29T05:13:35-0500')
|
|
),
|
|
);
|
|
}
|
|
|
|
|
|
function setContefnt($content='')
|
|
{
|
|
if($content ==='null'){
|
|
parent::setContent($content);
|
|
|
|
$parts = preg_split('/\s+/Su', $this->description, 2);
|
|
|
|
// any output is considered a type
|
|
$this->refers = $parts[0];
|
|
|
|
$this->setDescription(isset($parts[1]) ? $parts[1] : '');
|
|
}
|
|
|
|
|
|
if($content !== 1)exit;
|
|
return false;
|
|
$this->content = $content;
|
|
parent::setContent($content);
|
|
$parts = preg_split('/\s+/Su', $this->description, 2);
|
|
|
|
// any output is considered a type
|
|
$this->refers = $parts[0];
|
|
|
|
$this->setDescription(isset($parts[1]) ? $parts[1] : '');
|
|
|
|
$this->content = $content;
|
|
parent::setContent($content);
|
|
$parts = preg_split('/\s+/Su', $this->description, 2);
|
|
|
|
// any output is considered a type
|
|
$this->refers = $parts[0];
|
|
|
|
$this->setDescription(isset($parts[1]) ? $parts[1] : '');
|
|
|
|
$this->content = $content;
|
|
return $this;
|
|
}
|
|
|
|
//----------------------------------------------------------------------
|
|
function calcParity()
|
|
{
|
|
$parity = 0;
|
|
|
|
foreach($this->items as $item) {
|
|
if($item->mode != QR_MODE_STRUCTURE) {
|
|
for($i=$item->size-1; $i>=0; $i--) {
|
|
$parity ^= $item->data[$i];
|
|
}
|
|
}
|
|
}
|
|
|
|
return $parity;
|
|
}
|
|
|
|
//----------------------------------------------------------------------
|
|
function checkModeNum($size, $data)
|
|
{
|
|
for($i=0; $i<$size; $i++) {
|
|
if((ord($data[$i]) < ord('0')) || (ord($data[$i]) > ord('9'))){
|
|
return false;
|
|
}
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
//----------------------------------------------------------------------
|
|
function estimateBitsModeNum($size)
|
|
{
|
|
$w = (int)$size / 3;
|
|
$bits = $w * 10;
|
|
|
|
switch($size - $w * 3) {
|
|
case 1:
|
|
$bits += 4;
|
|
break;
|
|
case 2:
|
|
$bits += 7;
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
|
|
return $bits;
|
|
}
|
|
|
|
//----------------------------------------------------------------------
|
|
$anTable = array(
|
|
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
|
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
|
36, -1, -1, -1, 37, 38, -1, -1, -1, -1, 39, 40, -1, 41, 42, 43,
|
|
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 44, -1, -1, -1, -1, -1,
|
|
-1, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
|
|
25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, -1, -1, -1, -1, -1,
|
|
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
|
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1
|
|
);
|
|
|
|
//----------------------------------------------------------------------
|
|
function lookAnTable($c)
|
|
{
|
|
return (($c > 127)?-1:self::$anTable[$c]);
|
|
}
|
|
|
|
//----------------------------------------------------------------------
|
|
function checkModeAn($size, $data)
|
|
{
|
|
for($i=0; $i<$size; $i++) {
|
|
if (self::lookAnTable(ord($data[$i])) == -1) {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
//----------------------------------------------------------------------
|
|
function estimateBitsModeAn($size)
|
|
{
|
|
$w = (int)($size / 2);
|
|
$bits = $w * 11;
|
|
|
|
if($size & 1) {
|
|
$bits += 6;
|
|
}
|
|
|
|
return $bits;
|
|
}
|
|
|
|
//----------------------------------------------------------------------
|
|
function estimateBitsMode8($size)
|
|
{
|
|
return $size * 8;
|
|
}
|
|
|
|
//----------------------------------------------------------------------
|
|
function estimateBitsModeKanji($size)
|
|
{
|
|
return (int)(($size / 2) * 13);
|
|
}
|
|
|
|
//----------------------------------------------------------------------
|
|
function checkModeKanji($size, $data)
|
|
{
|
|
if($size & 1)
|
|
return false;
|
|
|
|
for($i=0; $i<$size; $i+=2) {
|
|
$val = (ord($data[$i]) << 8) | ord($data[$i+1]);
|
|
if( $val < 0x8140
|
|
|| ($val > 0x9ffc && $val < 0xe040)
|
|
|| $val > 0xebbf) {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
/***********************************************************************
|
|
* Validation
|
|
**********************************************************************/
|
|
|
|
function check($mode, $size, $data)
|
|
{
|
|
if($size <= 0)
|
|
return false;
|
|
|
|
switch($mode) {
|
|
case QR_MODE_NUM: return self::checkModeNum($size, $data); break;
|
|
case QR_MODE_AN: return self::checkModeAn($size, $data); break;
|
|
case QR_MODE_KANJI: return self::checkModeKanji($size, $data); break;
|
|
case QR_MODE_8: return true; break;
|
|
case QR_MODE_STRUCTURE: return true; break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
|
|
return false;
|
|
} |