Completed
Push — master ( 93a702...008e2c )
by Alexander
03:47
created

RemoteCoverageHelper::findDirectorySeparator()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 8
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 2.0625

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 8
ccs 3
cts 4
cp 0.75
rs 9.4285
cc 2
eloc 4
nc 2
nop 1
crap 2.0625
1
<?php
2
/**
3
 * This file is part of the phpunit-mink library.
4
 * For the full copyright and license information, please view
5
 * the LICENSE file that was distributed with this source code.
6
 *
7
 * @copyright Alexander Obuhovich <[email protected]>
8
 * @link      https://github.com/aik099/phpunit-mink
9
 */
10
11
namespace aik099\PHPUnit\RemoteCoverage;
12
13
14
/**
15
 * Class collects remove code coverage information and maps patch from remote to local server.
16
 *
17
 * @method \Mockery\Expectation shouldReceive(string $name)
18
 */
19
class RemoteCoverageHelper
20
{
21
22
	/**
23
	 * Remote URL.
24
	 *
25
	 * @var RemoteUrl
26
	 */
27
	private $_remoteUrl;
28
29
	/**
30
	 * Creates an instance of remote coverage class.
31
	 *
32
	 * @param RemoteUrl $remote_url Remote URL.
33
	 */
34 12
	public function __construct(RemoteUrl $remote_url)
35
	{
36 12
		$this->_remoteUrl = $remote_url;
37 12
	}
38
39
	/**
40
	 * Retrieves remote coverage information.
41
	 *
42
	 * @param string $coverage_script_url Coverage script irl.
43
	 * @param string $test_id             Test ID.
44
	 *
45
	 * @throws \RuntimeException Broken code coverage retrieved.
46
	 * @return array
47
	 */
48 7
	public function get($coverage_script_url, $test_id)
49
	{
50 7
		$url = $this->createUrl($coverage_script_url, $test_id);
51 4
		$buffer = $this->_remoteUrl->getPageContent($url);
52
53 4
		if ( $buffer !== false ) {
54 2
			$coverage_data = unserialize($buffer);
55
56 2
			if ( is_array($coverage_data) ) {
57 1
				return $this->matchLocalAndRemotePaths($coverage_data);
58
			}
59
60 1
			throw new \RuntimeException('Empty or invalid code coverage data received from url "' . $url . '"');
61
		}
62
63 2
		return array();
64
	}
65
66
	/**
67
	 * Returns url for remote code coverage collection.
68
	 *
69
	 * @param string $coverage_script_url Coverage script irl.
70
	 * @param string $test_id             Test ID.
71
	 *
72
	 * @return string
73
	 * @throws \InvalidArgumentException When empty coverage script url given.
74
	 */
75 7
	protected function createUrl($coverage_script_url, $test_id)
76
	{
77 7
		if ( !$coverage_script_url || !$test_id ) {
78 3
			throw new \InvalidArgumentException('Both Coverage script URL and Test ID must be filled in');
79
		}
80
81
		$query_string = array(
82 4
			'rct_mode' => 'output',
83 4
			RemoteCoverageTool::TEST_ID_VARIABLE => $test_id,
84 4
		);
85
86 4
		$url = $coverage_script_url;
87 4
		$url .= strpos($url, '?') === false ? '?' : '&';
88 4
		$url .= http_build_query($query_string);
89
90 4
		return $url;
91
	}
92
93
	/**
94
	 * Returns only files from remote server, that are matching files on test machine.
95
	 *
96
	 * @param array $coverage Remote coverage information.
97
	 *
98
	 * @return array
99
	 * @author Mattis Stordalen Flister <[email protected]>
100
	 */
101 1
	protected function matchLocalAndRemotePaths(array $coverage)
102
	{
103 1
		$coverage_with_local_paths = array();
104
105 1
		foreach ( $coverage as $original_remote_path => $data ) {
106 1
			$remote_path = $original_remote_path;
107 1
			$separator = $this->findDirectorySeparator($remote_path);
108
109 1
			while ( !($local_path = stream_resolve_include_path($remote_path)) &&
110 1
				strpos($remote_path, $separator) !== false ) {
111 1
				$remote_path = substr($remote_path, strpos($remote_path, $separator) + 1);
112 1
			}
113
114 1
			if ( $local_path && md5_file($local_path) == $data['md5'] ) {
115 1
				$coverage_with_local_paths[$local_path] = $data['coverage'];
116 1
			}
117 1
		}
118
119 1
		return $coverage_with_local_paths;
120
	}
121
122
	/**
123
	 * Returns path separator in given path.
124
	 *
125
	 * @param string $path Path to file.
126
	 *
127
	 * @return string
128
	 * @author Mattis Stordalen Flister <[email protected]>
129
	 */
130 1
	protected function findDirectorySeparator($path)
131
	{
132 1
		if ( strpos($path, '/') !== false ) {
133 1
			return '/';
134
		}
135
136
		return '\\';
137
	}
138
139
}
140