Completed
Push — master ( 39bb91...bfc7b3 )
by mw
127:18 queued 92:21
created

QueryTestCaseProcessor::processConceptCase()   B

Complexity

Conditions 4
Paths 8

Size

Total Lines 52
Code Lines 30

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 4
eloc 30
nc 8
nop 1
dl 0
loc 52
rs 8.9408
c 0
b 0
f 0

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
namespace SMW\Tests\Integration\JSONScript;
4
5
use SMW\Store;
6
use SMWQuery as Query;
7
use SMWQueryParser as QueryParser;
8
use Title;
9
10
/**
11
 * @group semantic-mediawiki
12
 * @group medium
13
 *
14
 * @license GNU GPL v2+
15
 * @since 2.2
16
 *
17
 * @author mwjames
18
 */
19
class QueryTestCaseProcessor extends \PHPUnit_Framework_TestCase {
20
21
	/**
22
	 * @var Store
23
	 */
24
	private $store;
25
26
	/**
27
	 * @var QueryParser
28
	 */
29
	private $fileReader;
0 ignored issues
show
Unused Code introduced by
The property $fileReader is not used and could be removed.

This check marks private properties in classes that are never used. Those properties can be removed.

Loading history...
30
31
	/**
32
	 * @var NumberValidator
33
	 */
34
	private $numberValidator;
35
36
	/**
37
	 * @var boolean
38
	 */
39
	private $debug = false;
40
41
	/**
42
	 * @since 2.2
43
	 *
44
	 * @param Store $store
45
	 */
46
	public function __construct( Store $store, $queryResultValidator, $stringValidator, $numberValidator ) {
47
		$this->store = $store;
48
		$this->queryResultValidator = $queryResultValidator;
49
		$this->stringValidator = $stringValidator;
50
		$this->numberValidator = $numberValidator;
51
	}
52
53
	/**
54
	 * @since  2.2
55
	 *
56
	 * @param QueryParser $queryParser
57
	 */
58
	public function setQueryParser( QueryParser $queryParser ) {
59
		$this->queryParser = $queryParser;
60
	}
61
62
	/**
63
	 * @since  2.2
64
	 */
65
	public function getStore() {
66
		return $this->store;
67
	}
68
69
	/**
70
	 * @since  2.2
71
	 */
72
	public function setDebugMode( $debugMode ) {
73
		$this->debug = $debugMode;
74
	}
75
76
	/**
77
	 * @since  2.2
78
	 *
79
	 * @param QueryTestCaseInterpreter $queryTestCaseInterpreter
80
	 */
81
	public function processQueryCase( QueryTestCaseInterpreter $queryTestCaseInterpreter ) {
82
83
		if ( !$queryTestCaseInterpreter->hasCondition() ) {
84
			$this->markTestSkipped( 'Found no condition for ' . $queryTestCaseInterpreter->isAbout() );
85
		}
86
87
		$description = $this->queryParser->getQueryDescription(
88
			$queryTestCaseInterpreter->getCondition()
89
		);
90
91
		$this->printDescriptionToOutput(
92
			$queryTestCaseInterpreter->isAbout(),
93
			$description
94
		);
95
96
		$query = new Query(
97
			$description,
98
			false,
99
			false
0 ignored issues
show
Unused Code introduced by
The call to SMWQuery::__construct() has too many arguments starting with false.

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
100
		);
101
102
		$query->querymode = $queryTestCaseInterpreter->getQueryMode();
103
		$query->setLimit( $queryTestCaseInterpreter->getLimit() );
104
105
		$query->setOffset( $queryTestCaseInterpreter->getOffset() );
106
		$query->setExtraPrintouts( $queryTestCaseInterpreter->getExtraPrintouts() );
107
108
		$query->setSortKeys( $queryTestCaseInterpreter->getSortKeys() );
0 ignored issues
show
Documentation introduced by
$queryTestCaseInterpreter->getSortKeys() is of type integer, but the function expects a array.

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...
109
		$query->setContextPage( $queryTestCaseInterpreter->getSubject() );
110
111
		if ( $queryTestCaseInterpreter->isRequiredToClearStoreCache() ) {
112
			$this->getStore()->clear();
113
		}
114
115
		$queryResult = $this->getStore()->getQueryResult( $query );
116
117
		$this->printQueryResultToOutput( $queryResult );
118
119
		if ( is_string( $queryResult ) ) {
120
			return;
121
		}
122
123
		$this->assertEquals(
124
			$queryTestCaseInterpreter->getExpectedCount(),
125
			$queryResult->getCount(),
126
			'Failed asserting query result count on ' . $queryTestCaseInterpreter->isAbout()
127
		);
128
129
		if ( $queryTestCaseInterpreter->getExpectedErrorCount() > -1 ) {
130
			$this->numberValidator->assertThatCountComparesTo(
131
				$queryTestCaseInterpreter->getExpectedErrorCount(),
132
				$queryResult->getErrors(),
133
				'Failed asserting error count ' . $queryTestCaseInterpreter->isAbout()
134
			);
135
		}
136
137
		if ( $queryTestCaseInterpreter->getExpectedErrorCount() > 0 ) {
138
			return null;
139
		}
140
141
		if ( $queryTestCaseInterpreter->isFromCache() !== null ) {
142
			$this->assertEquals(
143
				$queryTestCaseInterpreter->isFromCache(),
144
				$queryResult->isFromCache(),
145
				'Failed asserting isFromCache for ' . $queryTestCaseInterpreter->isAbout()
146
			);
147
		}
148
149
		$this->queryResultValidator->assertThatQueryResultHasSubjects(
150
			$queryTestCaseInterpreter->getExpectedSubjects(),
151
			$queryResult,
152
			$queryTestCaseInterpreter->isAbout()
153
		);
154
155
		$this->queryResultValidator->assertThatDataItemIsSet(
156
			$queryTestCaseInterpreter->getExpectedDataItems(),
157
			$queryResult,
158
			$queryTestCaseInterpreter->isAbout()
159
		);
160
161
		$this->queryResultValidator->assertThatDataValueIsSet(
162
			$queryTestCaseInterpreter->getExpectedDataValues(),
163
			$queryResult,
164
			$queryTestCaseInterpreter->isAbout()
165
		);
166
	}
167
168
	/**
169
	 * @since  2.2
170
	 *
171
	 * @param QueryTestCaseInterpreter $queryTestCaseInterpreter
172
	 */
173
	public function processConceptCase( QueryTestCaseInterpreter $queryTestCaseInterpreter ) {
174
175
		if ( !$queryTestCaseInterpreter->hasCondition() ) {
176
			$this->markTestSkipped( 'Found no condition for ' . $queryTestCaseInterpreter->isAbout() );
177
		}
178
179
		$description = $this->queryParser->getQueryDescription(
180
			$queryTestCaseInterpreter->getCondition()
181
		);
182
183
		$this->printDescriptionToOutput( $queryTestCaseInterpreter->isAbout(), $description );
184
185
		$query = new Query(
186
			$description,
187
			Query::CONCEPT_DESC
188
		);
189
190
		$query->querymode = $queryTestCaseInterpreter->getQueryMode();
191
		$query->setLimit( $queryTestCaseInterpreter->getLimit() );
192
		$query->setOffset( $queryTestCaseInterpreter->getOffset() );
193
194
		$queryResult = $this->getStore()->getQueryResult( $query );
195
196
		$this->printQueryResultToOutput( $queryResult );
197
198
		$this->assertEquals(
199
			$queryTestCaseInterpreter->getExpectedCount(),
200
			$queryResult->getCount(),
201
			'Failed asserting query result count on ' . $queryTestCaseInterpreter->isAbout()
202
		);
203
204
		if ( $queryTestCaseInterpreter->getExpectedErrorCount() > -1 ) {
205
			$this->numberValidator->assertThatCountComparesTo(
206
				$queryTestCaseInterpreter->getExpectedErrorCount(),
207
				$queryResult->getErrors(),
208
				'Failed asserting error count ' . $queryTestCaseInterpreter->isAbout()
209
			);
210
		}
211
212
		foreach ( $queryTestCaseInterpreter->getExpectedConceptCache() as $expectedConceptCache ) {
213
214
			$concept = Title::newFromText( $expectedConceptCache['concept'], SMW_NS_CONCEPT );
215
216
			$this->getStore()->refreshConceptCache( $concept );
0 ignored issues
show
Bug introduced by
It seems like you code against a specific sub-type and not the parent class SMW\Store as the method refreshConceptCache() does only exist in the following sub-classes of SMW\Store: SMWSQLStore3, SMWSparqlStore, SMW\SPARQLStore\SPARQLStore. Maybe you want to instanceof check for one of these explicitly?

Let’s take a look at an example:

abstract class User
{
    /** @return string */
    abstract public function getPassword();
}

class MyUser extends User
{
    public function getPassword()
    {
        // return something
    }

    public function getDisplayName()
    {
        // return some name.
    }
}

class AuthSystem
{
    public function authenticate(User $user)
    {
        $this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
        // do something.
    }
}

In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different sub-classes of User which does not have a getDisplayName() method, the code will break.

Available Fixes

  1. Change the type-hint for the parameter:

    class AuthSystem
    {
        public function authenticate(MyUser $user) { /* ... */ }
    }
    
  2. Add an additional type-check:

    class AuthSystem
    {
        public function authenticate(User $user)
        {
            if ($user instanceof MyUser) {
                $this->logger->info(/** ... */);
            }
    
            // or alternatively
            if ( ! $user instanceof MyUser) {
                throw new \LogicException(
                    '$user must be an instance of MyUser, '
                   .'other instances are not supported.'
                );
            }
    
        }
    }
    
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types inside the if block in such a case.
  1. Add the method to the parent class:

    abstract class User
    {
        /** @return string */
        abstract public function getPassword();
    
        /** @return string */
        abstract public function getDisplayName();
    }
    
Loading history...
217
218
			$this->assertEquals(
219
				$expectedConceptCache['count'],
220
				$this->getStore()->getConceptCacheStatus( $concept )->getCacheCount(),
0 ignored issues
show
Bug introduced by
It seems like you code against a specific sub-type and not the parent class SMW\Store as the method getConceptCacheStatus() does only exist in the following sub-classes of SMW\Store: SMWSQLStore3, SMWSparqlStore, SMW\SPARQLStore\SPARQLStore. Maybe you want to instanceof check for one of these explicitly?

Let’s take a look at an example:

abstract class User
{
    /** @return string */
    abstract public function getPassword();
}

class MyUser extends User
{
    public function getPassword()
    {
        // return something
    }

    public function getDisplayName()
    {
        // return some name.
    }
}

class AuthSystem
{
    public function authenticate(User $user)
    {
        $this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
        // do something.
    }
}

In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different sub-classes of User which does not have a getDisplayName() method, the code will break.

Available Fixes

  1. Change the type-hint for the parameter:

    class AuthSystem
    {
        public function authenticate(MyUser $user) { /* ... */ }
    }
    
  2. Add an additional type-check:

    class AuthSystem
    {
        public function authenticate(User $user)
        {
            if ($user instanceof MyUser) {
                $this->logger->info(/** ... */);
            }
    
            // or alternatively
            if ( ! $user instanceof MyUser) {
                throw new \LogicException(
                    '$user must be an instance of MyUser, '
                   .'other instances are not supported.'
                );
            }
    
        }
    }
    
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types inside the if block in such a case.
  1. Add the method to the parent class:

    abstract class User
    {
        /** @return string */
        abstract public function getPassword();
    
        /** @return string */
        abstract public function getDisplayName();
    }
    
Loading history...
221
				'Failed asserting conceptcache count on ' . $queryTestCaseInterpreter->isAbout()
222
			);
223
		}
224
	}
225
226
	/**
227
	 * @since  2.2
228
	 *
229
	 * @param QueryTestCaseInterpreter $queryTestCaseInterpreter
230
	 */
231
	public function processFormatCase( QueryTestCaseInterpreter $queryTestCaseInterpreter ) {
232
233
		if ( $queryTestCaseInterpreter->fetchTextFromOutputSubject() === '' ) {
234
			$this->markTestSkipped( 'No content found for ' . $queryTestCaseInterpreter->isAbout() );
235
		}
236
237
		$textOutput = $queryTestCaseInterpreter->fetchTextFromOutputSubject();
238
239
		$this->stringValidator->assertThatStringContains(
240
			$queryTestCaseInterpreter->getExpectedFormatOuputFor( 'to-contain' ),
241
			$textOutput,
242
			$queryTestCaseInterpreter->isAbout()
243
		);
244
	}
245
246
	private function printDescriptionToOutput( $about, $description ) {
247
248
		if ( !$this->debug ) {
249
			return;
250
		}
251
252
		print_r( $about . "\n" );
253
		print_r( $description );
254
	}
255
256
	private function printQueryResultToOutput( $queryResult ) {
257
258
		if ( is_string( $queryResult ) ) {
259
			return print_r( str_replace( array( "&#x0020;", "&#x003A;" ), array( " ", ":" ), $queryResult ) );
260
		}
261
262
		if ( !$this->debug ) {
263
			return;
264
		}
265
266
		print_r( 'QueryResult' . "\n" );
267
		print_r( implode( ',', $queryResult->getQuery()->getErrors() ) );
268
		print_r( implode( ',', $queryResult->getErrors() ) );
269
		print_r( $queryResult->toArray() );
270
	}
271
272
}
273