Failed Conditions
Pull Request — master (#25)
by Chad
02:50
created

AbstractEntityTest::offsetGet()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 5
rs 9.4285
c 0
b 0
f 0
cc 1
eloc 3
nc 1
nop 0
1
<?php
2
namespace Chadicus\Marvel\Api\Entities;
3
4
use DominionEnterprises\Util;
5
6
/**
7
 * Unit tests for the AbstractEntity class.
8
 *
9
 * @coversDefaultClass \Chadicus\Marvel\Api\Entities\AbstractEntity
10
 */
11
final class AbstractEntityTest extends \PHPUnit_Framework_TestCase
12
{
13
    /**
14
     * Verify basic functionality of fromArrays()
15
     *
16
     * @test
17
     * @covers ::fromArrays
18
     * @covers ::__construct
19
     * @covers ::__call
20
     * @covers ::__get
21
     *
22
     * @return void
23
     */
24
    public function basicUsage()
25
    {
26
        $actual = SimpleEntity::fromArrays([['field' => 'foo'], ['field' => 'bar']]);
27
        $this->assertSame(2, count($actual));
28
29
        $this->assertSame('foo', $actual[0]->field);
0 ignored issues
show
Documentation introduced by
The property field does not exist on object<Chadicus\Marvel\A...ntities\AbstractEntity>. 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...
30
        $this->assertSame('bar', $actual[1]->getField());
0 ignored issues
show
Documentation Bug introduced by
The method getField does not exist on object<Chadicus\Marvel\A...ntities\AbstractEntity>? 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...
31
    }
32
33
    /**
34
     * Verify behavior of __get() with invalid property name.
35
     *
36
     * @test
37
     * @covers ::__get
38
     * @expectedException \Chadicus\Spl\Exceptions\UndefinedPropertyException
39
     * @expectedExceptionMessage Undefined Property Chadicus\Marvel\Api\Entities\SimpleEntity::$foo
40
     *
41
     * @return void
42
     */
43
    public function getUndefined()
44
    {
45
        (new SimpleEntity([]))->foo;
0 ignored issues
show
Documentation introduced by
The property foo does not exist on object<Chadicus\Marvel\Api\Entities\SimpleEntity>. 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...
46
    }
47
48
    /**
49
     * Verify behavior of __call() with a non-get method call.
50
     *
51
     * @test
52
     * @covers ::__call
53
     * @expectedException \BadMethodCallException
54
     * @expectedExceptionMessage Chadicus\Marvel\Api\Entities\SimpleEntity::doSomething() does not exist
55
     *
56
     * @return void
57
     */
58
    public function callNonGet()
59
    {
60
        (new SimpleEntity([]))->doSomething();
0 ignored issues
show
Documentation Bug introduced by
The method doSomething does not exist on object<Chadicus\Marvel\Api\Entities\SimpleEntity>? 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...
61
    }
62
63
    /**
64
     * Verify behavior of __call() with a un defined property.
65
     *
66
     * @test
67
     * @covers ::__call
68
     * @expectedException \BadMethodCallException
69
     * @expectedExceptionMessage Chadicus\Marvel\Api\Entities\SimpleEntity::getFoo() does not exist
70
     *
71
     * @return void
72
     */
73
    public function callUndefined()
74
    {
75
        (new SimpleEntity([]))->getFoo();
0 ignored issues
show
Documentation Bug introduced by
The method getFoo does not exist on object<Chadicus\Marvel\Api\Entities\SimpleEntity>? 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...
76
    }
77
78
    /**
79
     * Verify basic behavior of fromArray().
80
     *
81
     * @test
82
     * @covers ::fromArray
83
     *
84
     * @return void
85
     */
86
    public function fromArray()
87
    {
88
        $actual = SimpleEntity::fromArray(['field' => 'foo']);
89
        $this->assertSame('foo', $actual->getField());
0 ignored issues
show
Documentation Bug introduced by
The method getField does not exist on object<Chadicus\Marvel\A...ntities\AbstractEntity>? 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...
90
    }
91
92
    /**
93
     * Verify basic behavior of offsetExists().
94
     *
95
     * @test
96
     * @covers ::offsetExists
97
     *
98
     * @return void
99
     */
100
    public function offsetExists()
101
    {
102
        $entity = SimpleEntity::fromArray(['field' => 'foo']);
103
        $this->assertTrue(isset($entity['field']));
104
        $this->assertFalse(isset($entity['notExists']));
105
    }
106
107
    /**
108
     * Verify basic behavior of offsetGet().
109
     *
110
     * @test
111
     * @covers ::offsetGet
112
     *
113
     * @return void
114
     */
115
    public function offsetGet()
116
    {
117
        $entity = SimpleEntity::fromArray(['field' => 'foo']);
118
        $this->assertSame('foo', $entity['field']);
119
    }
120
121
    /**
122
     * Verify basic behavior of offsetSet().
123
     *
124
     * @test
125
     * @covers ::offsetSet
126
     * @expectedException \Chadicus\Spl\Exceptions\NotAllowedException
127
     * @expectedExceptionMessage Chadicus\Marvel\Api\Entities\SimpleEntity::$field is read-only
128
     *
129
     * @return void
130
     */
131
    public function offsetSet()
132
    {
133
        $entity = SimpleEntity::fromArray(['field' => 'foo']);
134
        $entity['field'] = 'bar';
135
    }
136
137
    /**
138
     * Verify basic behavior of offsetUnset().
139
     *
140
     * @test
141
     * @covers ::offsetUnset
142
     * @expectedException \Chadicus\Spl\Exceptions\NotAllowedException
143
     * @expectedExceptionMessage Chadicus\Marvel\Api\Entities\SimpleEntity::$field is read-only
144
     *
145
     * @return void
146
     */
147
    public function offsetUnset()
148
    {
149
        $entity = SimpleEntity::fromArray(['field' => 'foo']);
150
        unset($entity['field']);
151
    }
152
}
153