Completed
Push — dev2 ( 764ed3...9e10b9 )
by Gordon
26:05 queued 17:34
created

ElasticsearchBaseTest   A

Complexity

Total Complexity 25

Size/Duplication

Total Lines 234
Duplicated Lines 10.26 %

Coupling/Cohesion

Components 1
Dependencies 13

Test Coverage

Coverage 25.95%
Metric Value
wmc 25
lcom 1
cbo 13
dl 24
loc 234
ccs 34
cts 131
cp 0.2595
rs 10

13 Methods

Rating   Name   Duplication   Size   Complexity  
A setUpOnce() 0 17 1
A devBuild() 0 5 1
A publishSiteTree() 0 7 2
A generateAssertionsFromArray() 9 9 2
A generateAssertionsFromArray1D() 9 9 2
A generateAssertionsFromArrayRecurse() 0 5 1
B recurseArrayAssertion() 0 23 4
A checkTabExists() 0 16 2
A checkFieldExists() 0 6 1
A invokeMethod() 0 8 1
B setUp() 6 50 4
A checkNumberOfIndexedDocuments() 0 17 2
A getNumberOfIndexedDocuments() 0 12 2

How to fix   Duplicated Code   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

1
<?php
2
use SilverStripe\Elastica\ElasticaUtil;
3
use SilverStripe\Elastica\ReindexTask;
4
use SilverStripe\Elastica\ElasticaService;
5
6
class ElasticsearchBaseTest extends SapphireTest {
7
8
	public static $ignoreFixtureFileFor = array();
9
10
	protected $extraDataObjects = array(
11
		'SearchableTestPage','FlickrPhotoTO','FlickrAuthorTO','FlickrSetTO','FlickrTagTO',
12
		'SearchableTestFatherPage','SearchableTestGrandFatherPage','AutoCompleteOption'
13
	);
14
15
16
	public function setUpOnce() {
17
		ElasticaUtil::setPrinterOutput(false);
18
19
		// add Searchable extension where appropriate
20
		FlickrSetTO::add_extension('SilverStripe\Elastica\Searchable');
21
		FlickrPhotoTO::add_extension('SilverStripe\Elastica\Searchable');
22
		FlickrTagTO::add_extension('SilverStripe\Elastica\Searchable');
23
		FlickrAuthorTO::add_extension('SilverStripe\Elastica\Searchable');
24
		SearchableTestPage::add_extension('SilverStripe\Elastica\Searchable');
25
26
27
		$config = Config::inst();
28
		$config->remove('Injector', 'SilverStripe\Elastica\ElasticaService');
29
		$constructor = array('constructor' => array('%$Elastica\Client', 'elastica_ss_module_test'));
30
		$config->update('Injector', 'SilverStripe\Elastica\ElasticaService', $constructor);
31
		parent::setUpOnce();
32
	}
33
34
35 1
	public function setUp() {
0 ignored issues
show
Coding Style introduced by
setUp uses the super-global variable $_GET which is generally not recommended.

Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable:

// Bad
class Router
{
    public function generate($path)
    {
        return $_SERVER['HOST'].$path;
    }
}

// Better
class Router
{
    private $host;

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

    public function generate($path)
    {
        return $this->host.$path;
    }
}

class Controller
{
    public function myAction(Request $request)
    {
        // Instead of
        $page = isset($_GET['page']) ? intval($_GET['page']) : 1;

        // Better (assuming you use the Symfony2 request)
        $page = $request->query->get('page', 1);
    }
}
Loading history...
36
		// no need to index here as it's done when fixtures are loaded during setup method
37 1
		$cache = SS_Cache::factory('elasticsearch');
38 1
		$cache->clean(Zend_Cache::CLEANING_MODE_ALL);
39 1
		SS_Cache::set_cache_lifetime('elasticsearch', 3600, 1000);
40
41
		// this needs to be called in order to create the list of searchable
42
		// classes and fields that are available.  Simulates part of a build
43 1
		$classes = array('SearchableTestPage','SiteTree','Page','FlickrPhotoTO','FlickrSetTO',
44 1
			'FlickrTagTO', 'FlickrAuthorTO');
45 1
		$this->requireDefaultRecordsFrom = $classes;
46
47
48
		// clear the index
49 1
		$this->service = Injector::inst()->create('SilverStripe\Elastica\ElasticaService');
50 1
		$this->service->setTestMode(true);
51
52
		// A previous test may have deleted the index and then failed, so check for this
53 1
		if (!$this->service->getIndex()->exists()) {
54 1
			$this->service->getIndex()->create();
55 1
		}
56 1
		$this->service->reset();
57
58
		// FIXME - use request getVar instead?
59 1
		$_GET['progress'] = 20;
60
		// load fixtures
61
62 1
		$orig_fixture_file = static::$fixture_file;
63
64 1 View Code Duplication
		foreach (static::$ignoreFixtureFileFor as $testPattern) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
65 1
			$pattern = '/'.$testPattern.'/';
66 1
			if (preg_match($pattern, $this->getName())) {
67
				static::$fixture_file = null;
68
			}
69 1
		}
70
71 1
		parent::setUp();
72 1
		static::$fixture_file = $orig_fixture_file;
73
74 1
		$this->publishSiteTree();
75
76 1
		$this->service->reset();
77
78
		// index loaded fixtures
79 1
		$task = new ReindexTask($this->service);
80
		// null request is fine as no parameters used
81
82 1
		$task->run(null);
83
84 1
	}
85
86
87
	protected function devBuild() {
88
		$task = new \BuildTask();
89
		// null request is fine as no parameters used
90
		$task->run(null);
91
	}
92
93
94 1
	private function publishSiteTree() {
95 1
		foreach (SiteTree::get()->getIterator() as $page) {
96
			// temporarily disable Elasticsearch indexing, it will be done in a batch
97 1
			$page->IndexingOff = true;
98 1
			$page->publish('Stage','Live');
99 1
		}
100 1
	}
101
102
103 View Code Duplication
	public function generateAssertionsFromArray($toAssert) {
1 ignored issue
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
104
		echo '$expected = array('."\n";
105
		foreach ($toAssert as $key => $value) {
106
			$escValue = str_replace("'", '\\\'', $value);
107
			echo "'$key' => '$escValue',\n";
108
		}
109
		echo ");\n";
110
		echo '$this->assertEquals($expected, $somevar);'."\n";
111
	}
112
113
114 View Code Duplication
	public function generateAssertionsFromArray1D($toAssert) {
1 ignored issue
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
115
		echo '$expected = array('."\n";
116
		foreach ($toAssert as $key => $value) {
117
			$escValue = str_replace("'", '\\\'', $value);
118
			echo "'$escValue',";
119
		}
120
		echo ");\n";
121
		echo '$this->assertEquals($expected, $somevar);'."\n";
122
	}
123
124
125
	public function generateAssertionsFromArrayRecurse($toAssert) {
126
		echo '$expected = ';
127
			$this->recurseArrayAssertion($toAssert,1, 'FIXME');
128
		echo '$this->assertEquals($expected, $somevar);'."\n";
129
	}
130
131
132
	private function recurseArrayAssertion($toAssert, $depth, $parentKey) {
133
		$prefix = str_repeat("\t",$depth);
134
		echo "\t{$prefix}'$parentKey' => array(\n";
135
		$ctr = 0;
136
		$len = sizeof(array_keys($toAssert));
137
		foreach ($toAssert as $key => $value) {
138
			if (is_array($value)) {
139
				$this->recurseArrayAssertion($value, $depth+1, $key);
140
			} else {
141
				$escValue = str_replace("'", '\\\'', $value);
142
				$comma = ',';
143
				if ($ctr == $len-1) {
144
					$comma = '';
145
				}
146
				echo "\t\t$prefix'$key' => '$escValue'$comma\n";
147
			}
148
149
			$ctr++;
150
151
		}
152
		echo "\t$prefix),\n";
153
154
	}
155
156
157
	/*
158
	Helper methods for testing CMS fields
159
	 */
160
	public function checkTabExists($fields, $tabName) {
161
		$tab = $fields->findOrMakeTab("Root.{$tabName}");
162
		$actualTabName = $tab->getName();
163
		$splits = explode('.', $tabName);
164
		$size = sizeof($splits);
165
		$nameToCheck = end($splits);
166
		$this->assertEquals($actualTabName, $nameToCheck);
167
		if ($size == 1) {
168
			$this->assertEquals("Root_${tabName}", $tab->id());
169
		} else {
170
			$expected = "Root_{$splits[0]}_set_{$splits[1]}";
171
			$this->assertEquals($expected, $tab->id());
172
		}
173
174
		return $tab;
175
	}
176
177
178
	public function checkFieldExists($tab,$fieldName) {
179
		$fields = $tab->Fields();
0 ignored issues
show
Unused Code introduced by
$fields is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
180
		$field = $tab->fieldByName($fieldName);
181
		$this->assertTrue($field != null);
182
		return $field;
183
	}
184
185
186
	/**
187
	 * From https://jtreminio.com/2013/03/unit-testing-tutorial-part-3-testing-protected-private-methods-coverage-reports-and-crap/
188
	 * Call protected/private method of a class.
189
	 *
190
	 * @param object &$object    Instantiated object that we will run method on.
191
	 * @param string $methodName Method name to call
192
	 * @param array  $parameters Array of parameters to pass into method.
193
	 *
194
	 * @return mixed Method return.
195
	 */
196
	public function invokeMethod(&$object, $methodName, array $parameters = array())
197
	{
198
	    $reflection = new \ReflectionClass(get_class($object));
199 1
	    $method = $reflection->getMethod($methodName);
200
	    $method->setAccessible(true);
201
202
	    return $method->invokeArgs($object, $parameters);
203
	}
204
205
206
	public function checkNumberOfIndexedDocuments($expectedAmount) {
207
		$index = $this->service->getIndex();
208
		$status = $index->getStatus()->getData();
209
210
		$numberDocsInIndex = -1; // flag value for not yet indexed
0 ignored issues
show
Unused Code introduced by
$numberDocsInIndex is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
211
		error_log('CHECKING NUMBER OF INDEXED DOCUMENTS, SHOULD BE ' . $expectedAmount);
212
		error_log(print_r($status,1));
213
214
		if (isset($status['indices']['elastica_ss_module_test_en_us']['docs'])) {
215
			$numberDocsInIndex = $status['indices']['elastica_ss_module_test_en_us']['docs']['num_docs'];
216
			error_log('DOCUMENTS FOUND:'.$numberDocsInIndex);
217
		} else {
218 1
			$numberDocsInIndex = 0;
219
		}
220
221
		$this->assertEquals($expectedAmount,$numberDocsInIndex);
222
	}
223
224
	/*
225
	Get the number of documents in an index.  It is assumed the index exists, if not the test will fail
226
	 */
227
	public function getNumberOfIndexedDocuments() {
228
		$index = $this->service->getIndex();
229
		$status = $index->getStatus()->getData();
230
231
		$numberDocsInIndex = -1; // flag value for not yet indexed
232
		if (isset($status['indices']['elastica_ss_module_test_en_us']['docs'])) {
233
			$numberDocsInIndex = $status['indices']['elastica_ss_module_test_en_us']['docs']['num_docs'];
234
		}
235
236
		$this->assertGreaterThan(-1, $numberDocsInIndex);
237
		return $numberDocsInIndex;
238
	}
239
}
240