Completed
Push — master ( 35bd4c...c8e02c )
by
unknown
10:31 queued 10s
created

setUp()   B

Complexity

Conditions 2
Paths 2

Size

Total Lines 27
Code Lines 13

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 27
rs 8.8571
c 0
b 0
f 0
cc 2
eloc 13
nc 2
nop 0
1
<?php
2
3
namespace BootstrapComponents\Tests\Integration;
4
5
use BootstrapComponents\ApplicationFactory;
6
use BootstrapComponents\Hooks\OutputPageParserOutput;
7
use BootstrapComponents\Setup;
8
use SMW\DIWikiPage;
9
use SMW\Tests\JsonTestCaseFileHandler;
10
use SMW\Tests\JsonTestCaseScriptRunner;
11
use SMW\Tests\Utils\Validators\StringValidator;
12
13
14
/**
15
 * @see https://github.com/SemanticMediaWiki/SemanticMediaWiki/tree/master/tests#write-integration-tests-using-json-script
16
 *
17
 * `JsonTestCaseScriptRunner` provisioned by SMW is a base class allowing to use a JSON
18
 * format to create test definitions with the objective to compose "real" content
19
 * and test integration with MediaWiki, Semantic MediaWiki, and Scribunto.
20
 *
21
 * The focus is on describing test definitions with its content and specify assertions
22
 * to control the expected base line.
23
 *
24
 * `JsonTestCaseScriptRunner` will handle the tearDown process and ensures that no test
25
 * data are leaked into a production system but requires an active DB connection.
26
 *
27
 * @group extension-bootstrap-components
28
 * @group medium
29
 *
30
 * @license GNU GPL v3+
31
 * @since 1.0
32
 *
33
 * @author mwjames
34
 * @author Tobias Oetterer
35
 */
36
class BootstrapComponentsJsonTestCaseScriptRunnerTest extends JsonTestCaseScriptRunner {
37
38
	/**
39
	 * @var StringValidator
40
	 */
41
	private $stringValidator;
42
43
	/**
44
	 * @var Setup
45
	 */
46
	private $setup;
47
48
	/**
49
	 * @throws \ConfigException
50
	 * @throws \MWException
51
	 */
52
	protected function setUp() {
53
		wfDebugLog( 'BootstrapComponents', 'Running the JsonTestCaseScriptRunnerTest setup.' );
54
		parent::setUp();
55
56
		$validatorFactory = $this->testEnvironment->getUtilityFactory()->newValidatorFactory();
57
58
		$this->stringValidator = $validatorFactory->newStringValidator();
59
60
		// at this point, I normally would need to reset the complete lookup in the ApplicationFactory.
61
		// Unfortunately, this causes problems with the re-registering of the parser function hooks and
62
		// passing them the correct new NestingController
63
		// here's to hoping, this is only botched in testing environment.
64
		ApplicationFactory::getInstance()->resetLookup( 'ParserOutputHelper' );
65
66
		#@fixme this is foobar to make modals work in integration tests. find a better solution
67
		# see also \BootstrapComponents\AbstractComponent::getParserOutputHelper
68
		if ( !defined( 'BSC_INTEGRATION_TEST' ) ) {
69
			define( 'BSC_INTEGRATION_TEST', true );
70
		}
71
72
		$this->setup = new Setup( [] );
73
		$this->setup->clear();
74
		$hookCallbackList = $this->setup->buildHookCallbackListFor(
75
			Setup::AVAILABLE_HOOKS
76
		);
77
		$this->setup->register( $hookCallbackList );
78
	}
79
80
	/**
81
	 * @see JsonTestCaseScriptRunner::getRequiredJsonTestCaseMinVersion
82
	 * @return string
83
	 */
84
	protected function getRequiredJsonTestCaseMinVersion() {
85
		return '1';
86
	}
87
88
	/**
89
	 * @see JsonTestCaseScriptRunner::getTestCaseLocation
90
	 * @return string
91
	 */
92
	protected function getTestCaseLocation() {
93
		return __DIR__ . '/TestCases';
94
	}
95
96
	/**
97
	 * Returns a list of files, an empty list is a sign to run all registered
98
	 * tests.
99
	 *
100
	 * @see JsonTestCaseScriptRunner::getListOfAllowedTestCaseFiles
101
	 */
102
	protected function getAllowedTestCaseFiles() {
103
		return array();
104
	}
105
106
	/**
107
	 * @see JsonTestCaseScriptRunner::runTestCaseFile
108
	 *
109
	 * @param JsonTestCaseFileHandler $jsonTestCaseFileHandler
110
	 */
111
	protected function runTestCaseFile( JsonTestCaseFileHandler $jsonTestCaseFileHandler ) {
112
113
		$this->checkEnvironmentToSkipCurrentTest( $jsonTestCaseFileHandler );
114
115
		// Setup
116
		$this->prepareTest( $jsonTestCaseFileHandler );
117
118
		// Run test cases
119
		$this->doRunParserTests( $jsonTestCaseFileHandler );
120
	}
121
122
	/**
123
	 * @param JsonTestCaseFileHandler $jsonTestCaseFileHandler
124
	 */
125
	private function doRunParserTests( JsonTestCaseFileHandler $jsonTestCaseFileHandler ) {
126
127
		foreach ( $jsonTestCaseFileHandler->findTestCasesByType( 'parser' ) as $case ) {
128
129
			if ( !isset( $case['subject'] ) ) {
130
				break;
131
			}
132
133
			// Assert function are defined individually by each TestCaseRunner
134
			// to ensure a wide range of scenarios can be supported.
135
			$this->assertParserOutputForCase( $case );
136
		}
137
	}
138
139
	/**
140
	 * Prepares the test case: setting of global configuration changes (json section "settings",
141
	 * creation of defined pages (json section "setup")
142
	 *
143
	 * @param JsonTestCaseFileHandler $jsonTestCaseFileHandler
144
	 */
145
	private function prepareTest( JsonTestCaseFileHandler $jsonTestCaseFileHandler ) {
146
147
		// Defines settings that can be altered during a test run with each test
148
		// having the possibility to change those values, settings will be reset to
149
		// the original value (from before the test) after the test has finished.
150
		$permittedSettings = array(
151
			'wgLanguageCode',
152
			'wgContLang',
153
			'wgLang'
154
		);
155
156
		foreach ( $permittedSettings as $key ) {
157
			$this->changeGlobalSettingTo(
158
				$key,
159
				$jsonTestCaseFileHandler->getSettingsFor( $key )
160
			);
161
		}
162
163
		$this->createPagesFrom(
164
			$jsonTestCaseFileHandler->getPageCreationSetupList(),
165
			NS_MAIN
166
		);
167
	}
168
169
	/**
170
	 * Assert the text content if available from the parse process and
171
	 * accessible using the ParserOutput object.
172
	 *
173
	 * ```
174
	 * "assert-output": {
175
	 * 	"to-contain": [
176
	 * 		"Foo"
177
	 * 	],
178
	 * 	"not-contain": [
179
	 * 		"Bar"
180
	 * 	]
181
	 * }
182
	 * ```
183
	 * @param array $case
184
	 */
185
	private function assertParserOutputForCase( array $case ) {
186
187
		if ( !isset( $case['assert-output'] ) ) {
188
			return;
189
		}
190
191
		$subject = DIWikiPage::newFromText(
192
			$case['subject'],
193
			isset( $case['namespace'] ) ? constant( $case['namespace'] ) : NS_MAIN
194
		);
195
196
		/** @var \ParserOutput $parserOutput */
197
		$parserOutput = $this->testEnvironment->getUtilityFactory()->newPageReader()->getEditInfo( $subject->getTitle() )->output;
198
199
		try {
200
			$outputPage = $this->getMockBuilder( 'OutputPage' )
201
				->disableOriginalConstructor()
202
				->getMock();
203
			/** @noinspection PhpParamsInspection */
204
			$hook = new OutputPageParserOutput( $outputPage, $parserOutput );
205
			$hook->process();
206
		} catch ( \Exception $e ) {
207
			// nothing
208
		}
209
210
		if ( isset( $case['assert-output']['to-contain'] ) ) {
211
			$this->stringValidator->assertThatStringContains(
212
				$case['assert-output']['to-contain'],
213
				$parserOutput->getText(),
214
				$case['about']
215
			);
216
		}
217
218
		if ( isset( $case['assert-output']['not-contain'] ) ) {
219
			$this->stringValidator->assertThatStringNotContains(
220
				$case['assert-output']['not-contain'],
221
				$parserOutput->getText(),
222
				$case['about']
223
			);
224
		}
225
	}
226
}
227