Completed
Push — master ( d6446f...d11253 )
by Nelson
05:36
created

ImplementsIStrictPropertiesContainer   A

Complexity

Total Complexity 2

Size/Duplication

Total Lines 25
Duplicated Lines 0 %

Coupling/Cohesion

Components 0
Dependencies 0

Importance

Changes 0
Metric Value
dl 0
loc 25
rs 10
c 0
b 0
f 0
wmc 2
lcom 0
cbo 0

3 Methods

Rating   Name   Duplication   Size   Complexity  
objectInstanceProvider() 0 1 ?
A testImplementsIStrictPropertiesContainerInterface() 0 6 1
A testIsUnableToCreateDirectAttributesOutsideOfClassDefinition() 0 4 1
1
<?php
2
/**
3
 * PHP: Nelson Martell Library file
4
 *
5
 * Content:
6
 * - Trait definition
7
 *
8
 * Copyright © 2016-2017 Nelson Martell (http://nelson6e65.github.io)
9
 *
10
 * Licensed under The MIT License (MIT)
11
 * For full copyright and license information, please see the LICENSE
12
 * Redistributions of files must retain the above copyright notice.
13
 *
14
 * @copyright 2016-2017 Nelson Martell
15
 * @link      http://nelson6e65.github.io/php_nml/
16
 * @since     v0.6.0, v0.7.0
17
 * @license   http://www.opensource.org/licenses/mit-license.php The MIT License (MIT)
18
 * */
19
20
namespace NelsonMartell\Test\Helpers;
21
22
use Cake\Utility\Inflector;
23
use NelsonMartell\Extensions\Text;
24
use NelsonMartell\IStrictPropertiesContainer;
25
use SebastianBergmann\Exporter\Exporter;
26
27
/**
28
 * Test helper for classes implementing ``NelsonMartell\IStrictPropertiesContainer`` interface and
29
 * ``NelsonMartell\PropertiesHandler`` trait.
30
 *
31
 *
32
 * @author Nelson Martell <[email protected]>
33
 *
34
 * @see HasReadOnlyProperties
35
 * @see HasReadWriteProperties
36
 * @see HasUnaccesibleProperties
37
 * @see HasWriteOnlyProperties
38
 * */
39
trait ImplementsIStrictPropertiesContainer
40
{
41
    public abstract function objectInstanceProvider();
0 ignored issues
show
Documentation introduced by
For interfaces and abstract methods it is generally a good practice to add a @return annotation even if it is just @return void or @return null, so that implementors know what to do in the overridden method.

For interface and abstract methods, it is impossible to infer the return type from the immediate code. In these cases, it is generally advisible to explicitly annotate these methods with a @return doc comment to communicate to implementors of these methods what they are expected to return.

Loading history...
42
43
    /**
44
     * @dataProvider objectInstanceProvider
45
     * @todo Check returning value of dependency tests.
46
     */
47
    public function testImplementsIStrictPropertiesContainerInterface($obj)
0 ignored issues
show
Documentation introduced by
The return type could not be reliably inferred; please add a @return annotation.

Our type inference engine in quite powerful, but sometimes the code does not provide enough clues to go by. In these cases we request you to add a @return annotation as described here.

Loading history...
48
    {
49
        $this->assertInstanceOf(IStrictPropertiesContainer::class, $obj);
0 ignored issues
show
Bug introduced by
It seems like assertInstanceOf() must be provided by classes using this trait. How about adding it as abstract method to this trait?

This check looks for methods that are used by a trait but not required by it.

To illustrate, let’s look at the following code example

trait Idable {
    public function equalIds(Idable $other) {
        return $this->getId() === $other->getId();
    }
}

The trait Idable provides a method equalsId that in turn relies on the method getId(). If this method does not exist on a class mixing in this trait, the method will fail.

Adding the getId() as an abstract method to the trait will make sure it is available.

Loading history...
50
51
        return $obj;
52
    }
53
54
    /**
55
     * @depends testImplementsIStrictPropertiesContainerInterface
56
     * @dataProvider objectInstanceProvider
57
     * @expectedException \BadMethodCallException
58
     */
59
    public function testIsUnableToCreateDirectAttributesOutsideOfClassDefinition(IStrictPropertiesContainer $obj)
60
    {
61
        $obj->thisPropertyNameIsMaybeImposibleThatExistsInClassToBeUsedAsNameOfPropertyOfAnyClassGiven = 'No way';
0 ignored issues
show
Bug introduced by
Accessing thisPropertyNameIsMaybeI...PropertyOfAnyClassGiven on the interface NelsonMartell\IStrictPropertiesContainer suggest that you code against a concrete implementation. How about adding an instanceof check?

If you access a property on an interface, you most likely code against a concrete implementation of the interface.

Available Fixes

  1. Adding an additional type check:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeInterface $object) {
        if ($object instanceof SomeClass) {
            $a = $object->a;
        }
    }
    
  2. Changing the type hint:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeClass $object) {
        $a = $object->a;
    }
    
Loading history...
62
    }
63
}
64