Completed
Push — master ( d48601...03ac5e )
by Jeroen De
13s queued 10s
created

tests/phpunit/ObservableMessageReporterTest.php (2 issues)

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

1
<?php
2
3
namespace Onoi\MessageReporter\Tests;
4
5
use Onoi\MessageReporter\ObservableMessageReporter;
6
use Onoi\MessageReporter\MessageReporter;
7
8
/**
9
 * @covers \Onoi\MessageReporter\ObservableMessageReporter
10
 * @group onoi-message-reporter
11
 *
12
 * @license GNU GPL v2+
13
 * @since 1.0
14
 *
15
 * @author Jeroen De Dauw < [email protected] >
16
 */
17
class ObservableMessageReporterTest extends MessageReporterTestCase {
18
19
	public function testCanConstruct() {
20
21
		$this->assertInstanceOf(
22
			'\Onoi\MessageReporter\ObservableMessageReporter',
23
			new ObservableMessageReporter()
24
		);
25
	}
26
27
	/**
28
	 * @return MessageReporter[]
29
	 */
30
	public function getInstances() {
31
		$instances = array();
32
33
		$instances[] = new ObservableMessageReporter();
34
35
		$reporter = new ObservableMessageReporter();
36
		$reporter->registerMessageReporter( new ObservableMessageReporter() );
37
		$callback0 = function( $string ) {};
38
		$callback1 = function( $string ) {};
39
		$instances[] = $reporter;
40
41
		$reporter = clone $reporter;
42
		$reporter->registerReporterCallback( $callback0 );
43
		$reporter->registerReporterCallback( $callback1 );
44
		$instances[] = $reporter;
45
46
		return $instances;
0 ignored issues
show
Bug Best Practice introduced by
The return type of return $instances; (Onoi\MessageReporter\ObservableMessageReporter[]) is incompatible with the return type declared by the abstract method Onoi\MessageReporter\Tes...rTestCase::getInstances of type Onoi\MessageReporter\Tests\MessageReporter[].

If you return a value from a function or method, it should be a sub-type of the type that is given by the parent type f.e. an interface, or abstract method. This is more formally defined by the Lizkov substitution principle, and guarantees that classes that depend on the parent type can use any instance of a child type interchangably. This principle also belongs to the SOLID principles for object oriented design.

Let’s take a look at an example:

class Author {
    private $name;

    public function __construct($name) {
        $this->name = $name;
    }

    public function getName() {
        return $this->name;
    }
}

abstract class Post {
    public function getAuthor() {
        return 'Johannes';
    }
}

class BlogPost extends Post {
    public function getAuthor() {
        return new Author('Johannes');
    }
}

class ForumPost extends Post { /* ... */ }

function my_function(Post $post) {
    echo strtoupper($post->getAuthor());
}

Our function my_function expects a Post object, and outputs the author of the post. The base class Post returns a simple string and outputting a simple string will work just fine. However, the child class BlogPost which is a sub-type of Post instead decided to return an object, and is therefore violating the SOLID principles. If a BlogPost were passed to my_function, PHP would not complain, but ultimately fail when executing the strtoupper call in its body.

Loading history...
47
	}
48
49
	/**
50
	 * @dataProvider reportMessageProvider
51
	 *
52
	 * @param string $message
53
	 */
54
	public function testCallbackInvocation( $message ) {
55
		$callCount = 0;
56
		$asserter = array( $this, 'assertEquals' );
57
58
		$callback0 = function( $actual ) use ( $message, &$callCount, $asserter ) {
59
			$callCount += 1;
60
			call_user_func( $asserter, $message, $actual );
61
		};
62
63
		$callback1 = function( $actual ) use ( $message, &$callCount, $asserter ) {
64
			$callCount += 1;
65
			call_user_func( $asserter, $message, $actual );
66
		};
67
68
		$reporter = new ObservableMessageReporter();
69
		$reporter->registerReporterCallback( $callback0 );
70
		$reporter->registerReporterCallback( $callback1 );
71
72
		$reporter->reportMessage( $message );
73
74
		$this->assertEquals( 2, $callCount );
75
76
		$reporter->reportMessage( $message );
77
78
		$this->assertEquals( 4, $callCount );
79
	}
80
81
	/**
82
	 * @dataProvider reportMessageProvider
83
	 *
84
	 * @param string $message
85
	 */
86
	public function testReporterInvocation( $message ) {
87
		$callCount = 0;
88
		$asserter = array( $this, 'assertEquals' );
89
90
		$callback0 = function( $actual ) use ( $message, &$callCount, $asserter ) {
91
			$callCount += 1;
92
			call_user_func( $asserter, $message, $actual );
93
		};
94
95
		$callback1 = function( $actual ) use ( $message, &$callCount, $asserter ) {
96
			$callCount += 1;
97
			call_user_func( $asserter, $message, $actual );
98
		};
99
100
		$reporter0 = new ObservableMessageReporter();
101
		$reporter0->registerReporterCallback( $callback0 );
102
103
		$reporter1 = new ObservableMessageReporter();
104
		$reporter1->registerReporterCallback( $callback1 );
105
106
		$reporter = new ObservableMessageReporter();
107
		$reporter->registerMessageReporter( $reporter0 );
108
		$reporter->registerMessageReporter( $reporter1 );
109
110
		$reporter->reportMessage( $message );
111
112
		$this->assertEquals( 2, $callCount );
113
114
		$reporter->reportMessage( $message );
115
116
		$this->assertEquals( 4, $callCount );
117
	}
118
119
	public function testDoNoFailOnNotCallableHandler() {
120
121
		$reporter = new ObservableMessageReporter();
122
123
		$reporter->registerReporterCallback( null );
124
		$reporter->registerReporterCallback( array( $this, 'functionDoesNotExist' ) );
125
126
		$callCount = 0;
127
128
		$reporter->registerReporterCallback( function( $actual ) use ( &$callCount ) {
0 ignored issues
show
The parameter $actual is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
129
			$callCount += 1;
130
		} );
131
132
		$reporter->reportMessage( 'Foo' );
133
134
		$this->assertEquals(
135
			1,
136
			$callCount
137
		);
138
	}
139
140
}
141