mageekguy\atoum\script\arguments\parser: lines coverage

86% of 700

OPs

96% of 131

Lines

77% of 128

Branches

30% of 109

Paths
Method OPs OPs % Lines Line % Branches Branches % Paths Path %
mageekguy\atoum\script\arguments\parser::__construct() 17 100% 2 100% 1 0% 1 100%
mageekguy\atoum\script\arguments\parser::__toString() 34 65% 8 100% 15 67% 8 13%
mageekguy\atoum\script\arguments\parser::setSuperglobals() 9 100% 2 100% 1 100% 1 100%
mageekguy\atoum\script\arguments\parser::getSuperglobals() 6 100% 1 100% 1 100% 1 100%
mageekguy\atoum\script\arguments\parser::resetValues() 9 100% 2 100% 1 100% 1 100%
mageekguy\atoum\script\arguments\parser::getHandlers() 6 100% 1 100% 1 100% 1 100%
mageekguy\atoum\script\arguments\parser::getPriorities() 6 100% 1 100% 1 100% 1 100%
mageekguy\atoum\script\arguments\parser::getIterator() 15 100% 1 100% 1 100% 1 100%
mageekguy\atoum\script\arguments\parser::parse() 43 72% 16 94% 6 67% 3 33%
mageekguy\atoum\script\arguments\parser::getValues() 24 100% 1 100% 9 100% 3 100%
mageekguy\atoum\script\arguments\parser::hasFoundArguments() 12 100% 1 100% 1 100% 1 100%
mageekguy\atoum\script\arguments\parser::addHandler() 71 80% 12 100% 12 50% 5 20%
mageekguy\atoum\script\arguments\parser::setDefaultHandler() 33 97% 6 100% 4 75% 2 100%
mageekguy\atoum\script\arguments\parser::getDefaultHandler() 6 100% 1 100% 1 100% 1 100%
mageekguy\atoum\script\arguments\parser::resetHandlers() 17 100% 4 100% 1 100% 1 100%
mageekguy\atoum\script\arguments\parser::argumentIsHandled() 15 100% 1 100% 4 100% 2 100%
mageekguy\atoum\script\arguments\parser::argumentHasHandler() 10 100% 1 100% 1 100% 1 100%
mageekguy\atoum\script\arguments\parser::init() 142 92% 29 97% 23 91% 22 41%
mageekguy\atoum\script\arguments\parser::triggerHandlers() 171 77% 35 91% 37 73% 49 4%
mageekguy\atoum\script\arguments\parser::invokeHandlers() 41 71% 5 100% 6 50% 3 0%
mageekguy\atoum\script\arguments\parser::isArgument() 13 100% 1 100% 1 100% 1 100%
#
1
<?php
2

                    
3
namespace mageekguy\atoum\script\arguments;
4

                    
5
use
6
	mageekguy\atoum,
7
	mageekguy\atoum\exceptions
8
;
9

                    
10
class parser implements \iteratorAggregate
11
{
12
	protected $values = array();
13
	protected $handlers = array();
14
	protected $defaultHandler = null;
15
	protected $priorities = array();
16
	protected $superglobals = null;
17

                    
18
	public function __construct(atoum\superglobals $superglobals = null)100%
19
	{
20
		$this->setSuperglobals($superglobals ?: new atoum\superglobals());
21
	}
22

                    
23
	public function __toString()100%
24
	{
25
		$string = '';
26

                    
27
		foreach ($this->values as $argumentName => $argumentValues)
28
		{
29
			$string .= ($string == '' ? '' : ' ') . $argumentName;
30

                    
31
			foreach ($argumentValues as $argumentValue)
32
			{
33
				$string .= ' ' . $argumentValue;
34
			}
35
		}
36

                    
37
		return $string;
38
	}
39

                    
40
	public function setSuperglobals(atoum\superglobals $superglobals)100%
41
	{
42
		$this->superglobals = $superglobals;
43

                    
44
		return $this;
45
	}
46

                    
47
	public function getSuperglobals()100%
48
	{
49
		return $this->superglobals;
50
	}
51

                    
52
	public function resetValues()100%
53
	{
54
		$this->values = array();
55

                    
56
		return $this;
57
	}
58

                    
59
	public function getHandlers()100%
60
	{
61
		return $this->handlers;
62
	}
63

                    
64
	public function getPriorities()100%
65
	{
66
		return $this->priorities;
67
	}
68

                    
69
	public function getIterator()100%
70
	{
71
		return new \arrayIterator($this->getValues());
72
	}
73

                    
74
	public function parse(atoum\script $script, array $array = array())94%
75
	{
76
		$this->init($array);
77

                    
78
		$priorities = $this->priorities;
79

                    
80
		$values = $this->values;
81

                    
82
		uksort($values, function($arg1, $arg2) use ($priorities) {
83
				switch (true)
84
				{
85
					case isset($priorities[$arg1]) === false:
86
					case isset($priorities[$arg2]) === false:
87
						return PHP_INT_MAX;
88

                    
89
					default:
90
						return ($priorities[$arg1] > $priorities[$arg2] ? -1 : ($priorities[$arg1] == $priorities[$arg2] ? 0 : 1));
91
				}
92
			}
93
		);
94

                    
95
		foreach ($values as $argument => $value)
96
		{
97
			$this->triggerHandlers($argument, $value, $script);
98
		}
99

                    
100
		return $this;
101
	}
102

                    
103
	public function getValues($argument = null)100%
104
	{
105
		return ($argument === null ? $this->values : (isset($this->values[$argument]) === false ? null : $this->values[$argument]));
106
	}
107

                    
108
	public function hasFoundArguments()100%
109
	{
110
		return (sizeof($this->values) > 0);
111
	}
112

                    
113
	public function addHandler(\closure $handler, array $arguments, $priority = 0)100%
114
	{
115
		$invoke = new \reflectionMethod($handler, '__invoke');
116

                    
117
		if ($invoke->getNumberOfParameters() < 3)
118
		{
119
			throw new exceptions\runtime('Handler must take three arguments');
120
		}
121

                    
122
		foreach ($arguments as $argument)
123
		{
124
			if (self::isArgument($argument) === false)
125
			{
126
				throw new exceptions\runtime('Argument \'' . $argument . '\' is invalid');
127
			}
128

                    
129
			$this->handlers[$argument][] = $handler;
130
			$this->priorities[$argument] = (int) $priority;
131
		}
132

                    
133
		return $this;
134
	}
135

                    
136
	public function setDefaultHandler(\closure $handler)100%
137
	{
138
		$reflectedHandler = new \reflectionFunction($handler);
139

                    
140
		if ($reflectedHandler->getNumberOfParameters() < 2)
141
		{
142
			throw new exceptions\runtime('Handler must take two arguments');
143
		}
144

                    
145
		$this->defaultHandler = $handler;
146

                    
147
		return $this;
148
	}
149

                    
150
	public function getDefaultHandler()100%
151
	{
152
		return $this->defaultHandler;
153
	}
154

                    
155
	public function resetHandlers()100%
156
	{
157
		$this->handlers = array();
158
		$this->defaultHandler = null;
159
		$this->priorities = array();
160

                    
161
		return $this;
162
	}
163

                    
164
	public function argumentIsHandled($argument)100%
165
	{
166
		return (isset($this->handlers[$argument]) === true || $this->defaultHandler !== null);
167
	}
168

                    
169
	public function argumentHasHandler($argument)100%
170
	{
171
		return (isset($this->handlers[$argument]) === true);
172
	}
173

                    
174
	public function init(array $array = array())97%
175
	{
176
		if (sizeof($array) <= 0)
177
		{
178
			$array = array_slice($this->superglobals->_SERVER['argv'], 1);
179
		}
180

                    
181
		$this->resetValues();
182

                    
183
		$arguments = new \arrayIterator($array);
184

                    
185
		if (sizeof($arguments) > 0)
186
		{
187
			$value = $arguments->current();
188

                    
189
			if (self::isArgument($value) === false && $this->defaultHandler === null)
190
			{
191
				throw new exceptions\runtime\unexpectedValue('Argument \'' . $value . '\' is invalid');
192
			}
193

                    
194
			$argument = $value;
195

                    
196
			$this->values[$argument] = array();
197

                    
198
			$arguments->next();
199

                    
200
			while ($arguments->valid() === true)
201
			{
202
				$value = $arguments->current();
203

                    
204
				if (self::isArgument($value) === false)
205
				{
206
					$this->values[$argument][] = $value;
207
				}
208
				else
209
				{
210
					$argument = $value;
211

                    
212
					if (isset($this->values[$argument]) === false) {
213
						$this->values[$argument] = array();
214
					}
215
				}
216

                    
217
				$arguments->next();
218
			}
219
		}
220

                    
221
		return $this;
222
	}
223

                    
224
	public function triggerHandlers($argument, array $values, atoum\script $script, & $argumentUsed = null)91%
225
	{
226
		if (isset($this->handlers[$argument]) === true)
227
		{
228
			$this->invokeHandlers($script, $argument, $values);
229
		}
230
		else
231
		{
232
			$closestArgument = null;
233

                    
234
			if (self::isArgument($argument) === true)
235
			{
236
				$min = null;
237
				$argumentMetaphone = metaphone($argument);
238
				$availableArguments = array_keys($this->handlers);
239

                    
240
				natsort($availableArguments);
241

                    
242
				foreach ($availableArguments as $handlerArgument)
243
				{
244
					$levenshtein = levenshtein($argumentMetaphone, metaphone($handlerArgument));
245

                    
246
					if ($levenshtein < (strlen($argument) / 2))
247
					{
248
						if ($min === null || $levenshtein < $min)
249
						{
250
							$min = $levenshtein;
251
							$closestArgument = $handlerArgument;
252
						}
253
					}
254
				}
255
			}
256

                    
257
			switch (true)
258
			{
259
				case $closestArgument === null:
260
					if ($this->defaultHandler === null || $this->defaultHandler->__invoke($script, $argument) === false)
261
					{
262
						throw new exceptions\runtime\unexpectedValue('Argument \'' . $argument . '\' is unknown');
263
					}
264
					break;
265

                    
266
				case $min > 0:
267
					throw new exceptions\runtime\unexpectedValue('Argument \'' . $argument . '\' is unknown, did you mean \'' . $closestArgument . '\'?');
268

                    
269
				default:
270
					$this->invokeHandlers($script, $closestArgument, $values);
271
			}
272
		}
273

                    
274
		return $this;
275
	}
276

                    
277
	public function invokeHandlers(atoum\script $script, $argument, array $values)100%
278
	{
279
		$position = array_search($argument, array_keys($this->values)) + 1;
280

                    
281
		foreach ($this->handlers[$argument] as $handler)
282
		{
283
			$handler->__invoke($script, $argument, $values, $position);
284
		}
285

                    
286
		return $this;
287
	}
288

                    
289
	public static function isArgument($value)100%
290
	{
291
		return (preg_match('/^(\+{1,}|-{1,})[a-z][-_a-z0-9]*/i', $value) === 1);
292
	}
293
}