Completed
Push — master ( 612476...c205d6 )
by smiley
04:22
created

DBResultTest::testEachInvalidCallback()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 3
rs 10
c 0
b 0
f 0
cc 1
eloc 2
nc 1
nop 0
1
<?php
2
/**
3
 * Class DBResultTest
4
 *
5
 * @filesource   DBResultTest.php
6
 * @created      30.05.2017
7
 * @package      chillerlan\DatabaseTest
8
 * @author       Smiley <[email protected]>
9
 * @copyright    2017 Smiley
10
 * @license      MIT
11
 */
12
13
namespace chillerlan\DatabaseTest;
14
15
use chillerlan\Database\DBResult;
16
use Iterator, ArrayAccess, Countable, stdClass;
17
18
class DBResultTest extends TestAbstract{
19
20
	/**
21
	 * @var \chillerlan\Database\DBResult
22
	 */
23
	protected $DBResult;
24
25
	protected function setUp(){
26
		$this->DBResult = new DBResult;
27
28
		foreach(range(0, 9) as $k){
29
			$this->DBResult[] = ['id' => $k, 'hash' => md5($k)];
30
		}
31
32
		$this->DBResult->rewind();
33
	}
34
35
	public function testInstance(){
36
		$this->assertInstanceOf(DBResult::class, $this->DBResult);
37
		$this->assertInstanceOf(Iterator::class, $this->DBResult);
38
		$this->assertInstanceOf(ArrayAccess::class, $this->DBResult);
39
		$this->assertInstanceOf(Countable::class, $this->DBResult);
40
41
		//coverage
42
		new DBResult(new DBResult);
43
		new DBResult(new stdClass);
44
	}
45
46
	/**
47
	 * @expectedException \chillerlan\Database\DBException
48
	 * @expectedExceptionMessage invalid data
49
	 */
50
	public function testConstructInvalidData(){
51
		new DBResult('');
0 ignored issues
show
Documentation introduced by
'' is of type string, but the function expects a object<Traversable>|object<stdClass>|array|null.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
52
	}
53
54
	public function testMagicGetCall(){
55
56
		$this->assertSame(10, $this->DBResult->length);
57
		$this->assertSame(md5(0), $this->DBResult[0]->hash);
58
59
		while($row = $this->DBResult->current()){
60
			$this->assertTrue(isset($row['hash'], $row['id']));
61
62
			$this->assertSame($row->hash, $row->id(function($v){
63
				return md5($v);
64
			}));
65
66
			$this->assertSame(md5($row->id), $row->hash());
67
			$this->assertSame(['id' => $row->id, 'hash' => $row->hash], $row->__toArray());
68
			$this->assertNull($row->foo);
69
			$this->assertNull($row->foo());
70
			$this->assertSame($row->id, $this->DBResult->key());
71
72
			$this->assertTrue($this->DBResult->valid());
73
			unset($this->DBResult[$row->id]);
74
			$this->assertFalse($this->DBResult->valid());
75
76
			$this->DBResult->next();
77
		}
78
79
	}
80
81
	public function testEach(){
82
		$this->DBResult->__each(function($row, $i){
83
			/** @var \chillerlan\Database\DBResultRow $row */
84
			$this->assertSame($row->id, $i);
0 ignored issues
show
Documentation introduced by
The property id does not exist on object<chillerlan\Database\DBResultRow>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

If the property has read access only, you can use the @property-read annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
85
			$this->assertSame(md5($row->id), $row->hash());
0 ignored issues
show
Documentation introduced by
The property id does not exist on object<chillerlan\Database\DBResultRow>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

If the property has read access only, you can use the @property-read annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
Documentation Bug introduced by
The method hash does not exist on object<chillerlan\Database\DBResultRow>? Since you implemented __call, maybe consider adding a @method annotation.

If you implement __call and you know which methods are available, you can improve IDE auto-completion and static analysis by adding a @method annotation to the class.

This is often the case, when __call is implemented by a parent class and only the child class knows which methods exist:

class ParentClass {
    private $data = array();

    public function __call($method, array $args) {
        if (0 === strpos($method, 'get')) {
            return $this->data[strtolower(substr($method, 3))];
        }

        throw new \LogicException(sprintf('Unsupported method: %s', $method));
    }
}

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
86
87
			$row->__each(function($v, $j) use ($row){
88
				$this->assertSame($row->{$j}, $v);
89
				$this->assertSame($row[$j], $v);
90
			});
91
		});
92
	}
93
94
	/**
95
	 * @expectedException \chillerlan\Database\DBException
96
	 * @expectedExceptionMessage invalid callback
97
	 */
98
	public function testEachInvalidCallback(){
99
		$this->DBResult->__each('foo');
100
	}
101
102
	public function testMerge(){
103
		$r1 = new DBResult([['id' => 1]]);
104
		$this->assertSame(1, $r1[0]->id);
105
106
		$r2 = new DBResult([['id' => 2]]);
107
		$this->assertSame(2, $r2[0]->id);
108
109
		$r1->__merge($r2)->__reverse();
110
111
		$this->assertSame(2, $r1[0]->id);
112
		$this->assertSame(1, $r1[1]->id);
113
	}
114
}
115