Skip to content

Commit 234d3e4

Browse files
committed
added type checking to FilesDiffCommandInterface
1 parent 2eb81fc commit 234d3e4

File tree

2 files changed

+216
-76
lines changed

2 files changed

+216
-76
lines changed

src/FilesDiffCommand.php

Lines changed: 191 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,35 @@
22

33
namespace Differ;
44

5-
class FilesDiffCommand implements CommandInterface
5+
class FilesDiffCommand implements FilesDiffCommandInterface
66
{
77
private FileReaderInterface $fileReader;
8+
9+
/**
10+
* @var array<int,string> $filesPaths
11+
*/
812
private array $filesPaths;
13+
14+
/**
15+
* @var array<mixed,mixed> $filesDataItems
16+
*/
917
private array $filesDataItems;
18+
19+
/**
20+
* @var array<mixed,mixed> $content1Descriptor
21+
*/
1022
private array $content1Descriptor;
23+
24+
/**
25+
* @var array<mixed,mixed> $content2Descriptor
26+
*/
1127
private array $content2Descriptor;
28+
29+
/**
30+
* @var array<mixed,mixed> $differenceDescriptor
31+
*/
1232
private array $differenceDescriptor;
33+
1334
private const array STATUS_KEYS = [
1435
"not changed", "changed", "added", "deleted", "empty", "new value"
1536
];
@@ -21,7 +42,10 @@ public function __construct(FileReaderInterface $reader)
2142
$this->fileReader = $reader;
2243
}
2344

24-
private function normalizeData($data)
45+
/**
46+
* @param mixed $data
47+
*/
48+
private function normalizeData(mixed $data): mixed
2549
{
2650
$normalizedValue = $data;
2751
if (is_bool($data)) {
@@ -42,42 +66,69 @@ private function normalizeData($data)
4266
return $normalizedValue;
4367
}
4468

69+
/**
70+
* @param array<string> $fileContentKeys
71+
* @param array<string,mixed> $initContentDescriptor
72+
* @return array<mixed,mixed>
73+
*/
4574
private function getContent(
4675
$fileContentKeys,
4776
$initContentDescriptor
4877
): array {
49-
return array_reduce(
78+
$result = array_reduce(
5079
$fileContentKeys,
5180
function ($contentDescriptor, $fileKey) {
52-
$fileItem = $contentDescriptor['fileContent'];
81+
$fileItem = is_array($contentDescriptor) ? $contentDescriptor['fileContent'] : "";
82+
83+
$fileContent = is_array($fileItem) ? $fileItem[$fileKey] : $fileItem;//"";
84+
85+
$levelNum = is_array($contentDescriptor) ? $contentDescriptor["level"] : 0;
86+
$level = is_numeric($levelNum) ?
87+
($levelNum + 1) : throw new DifferException("internal error: level is not numeric\n");
5388

54-
$fileContent = $fileItem[$fileKey];
89+
$historyValue = is_array($contentDescriptor) ? $contentDescriptor["history"] : "";
90+
$historyString = is_string($historyValue) ? $historyValue : "";
91+
$history = ($historyString === "") ? $fileKey : $historyString . "." . $fileKey;
5592

56-
$level = $contentDescriptor["level"] + 1;
57-
$history = ($contentDescriptor["history"] === "") ?
58-
$fileKey : $contentDescriptor["history"] . "." . $fileKey;
5993
$fileContentKeys = array_keys(
6094
is_array($fileContent) ? $fileContent : []
6195
);
6296
asort($fileContentKeys);
97+
6398
$initContentDescriptor = [
6499
"level" => $level,
65100
"history" => $history,
66101
"fileKey" => $fileKey,
67-
"fileContent" => $fileContent
102+
"fileContent" => $fileContent,
103+
"output" => []
68104
];
69105

70-
$contentDescriptor['output'][] = $this->getContent(
71-
$fileContentKeys,
72-
$initContentDescriptor
73-
);
106+
if (is_array($contentDescriptor) && isset($contentDescriptor['output'])) {
107+
if (is_array($contentDescriptor['output'])) {
108+
$contentDescriptor['output'][] = $this->getContent(
109+
$fileContentKeys,
110+
$initContentDescriptor
111+
);
112+
}
113+
}
74114

75115
return $contentDescriptor;
76116
},
77117
$initContentDescriptor
78118
);
119+
if (is_array($result)) {
120+
return $result;
121+
} else {
122+
return [];
123+
}
79124
}
80125

126+
/**
127+
* @param null|string|array<string|mixed>|mixed $file1Content
128+
* @param null|string|array<string|mixed>|mixed $file2Content
129+
* @param string $currentStatus
130+
* @param boolean $nextItemIsNotArray
131+
*/
81132
private function getNextItemStatus(
82133
$file1Content,
83134
$file2Content,
@@ -103,6 +154,15 @@ private function getNextItemStatus(
103154
return $status;
104155
}
105156

157+
/**
158+
* @param string $status
159+
* @param int $level
160+
* @param string $fileKey
161+
* @param string $history
162+
* @param null|mixed $file1Content
163+
* @param null|mixed $file2Content
164+
* @return array<string|mixed>
165+
*/
106166
private function getInitDifferenceDescriptor(
107167
$status,
108168
$level,
@@ -135,25 +195,44 @@ private function getInitDifferenceDescriptor(
135195
return $initDifferenceDescriptor;
136196
}
137197

138-
public function getStatusKeys()
198+
/**
199+
* @return array<int,string>
200+
*/
201+
public function getStatusKeys(): array
139202
{
140203
return self::STATUS_KEYS;
141204
}
142205

206+
/**
207+
* @param array<int,string> $fileContentKeys
208+
* @param array<mixed> $initDifferenceDescriptor
209+
* @return mixed
210+
*/
143211
private function getDifference(
144212
$fileContentKeys,
145213
$initDifferenceDescriptor
146-
): array {
214+
): mixed {
147215
return array_reduce(
148216
$fileContentKeys,
149217
function ($differenceDescriptor, $fileKey) {
150-
$file1Item = $differenceDescriptor["file1Content"];
151-
$file2Item = $differenceDescriptor["file2Content"];
218+
$file1Item = is_array($differenceDescriptor) ? $differenceDescriptor["file1Content"] : [];
219+
$file2Item = is_array($differenceDescriptor) ? $differenceDescriptor["file2Content"] : [];
220+
221+
$file1Content = null;
222+
if (is_array($file1Item)) {
223+
$file1Content = in_array($fileKey, $file1Item) ? $file1Item[$fileKey] : null;
224+
}
225+
$file2Content = null;
226+
if (is_array($file2Item)) {
227+
$file2Content = in_array($fileKey, $file2Item) ? $file2Item[$fileKey] : null;
228+
}
152229

153-
$file1Content = $file1Item[$fileKey] ?? null;
154-
$file2Content = $file2Item[$fileKey] ?? null;
155230
$nextItemIsNotArray = !(is_array($file1Item) && is_array($file2Item));
156-
$currentStatus = $differenceDescriptor['status'];
231+
$currentStatus = "not changed";
232+
if (is_array($differenceDescriptor)) {
233+
$tmpStatus = $differenceDescriptor['status'];
234+
$currentStatus = is_string($tmpStatus) ? $tmpStatus : "not changed";
235+
}
157236

158237
$status = $this->getNextItemStatus(
159238
$file1Content,
@@ -162,9 +241,16 @@ function ($differenceDescriptor, $fileKey) {
162241
$nextItemIsNotArray
163242
);
164243

165-
$level = $differenceDescriptor["level"] + 1;
166-
$history = ($differenceDescriptor["history"] === "") ?
167-
$fileKey : $differenceDescriptor["history"] . "." . $fileKey;
244+
$prevLevel = is_array($differenceDescriptor) ? $differenceDescriptor["level"] : 0;
245+
$level = is_integer($prevLevel) ? $prevLevel + 1 : 0;
246+
$history = "";
247+
if (is_array($differenceDescriptor)) {
248+
$nextHistory = $differenceDescriptor["history"];
249+
$strHistory = is_string($nextHistory) ? $nextHistory : "";
250+
$history = ($differenceDescriptor["history"] === "") ?
251+
$fileKey : $strHistory . "." . $fileKey;
252+
}
253+
168254
$contentKeys = array_keys(array_merge(
169255
is_array($file1Content) ? $file1Content : [],
170256
is_array($file2Content) ? $file2Content : []
@@ -180,80 +266,100 @@ function ($differenceDescriptor, $fileKey) {
180266
$file2Content
181267
);
182268

183-
$differenceDescriptor["output"][] = $this->getDifference(
184-
$contentKeys,
185-
$initDifferenceDescriptor
186-
);
269+
if (is_array($differenceDescriptor)) {
270+
if (is_array($differenceDescriptor["output"])) {
271+
$differenceDescriptor["output"][] = $this->getDifference(
272+
$contentKeys,
273+
$initDifferenceDescriptor
274+
);
275+
}
276+
}
277+
187278
return $differenceDescriptor;
188279
},
189280
$initDifferenceDescriptor
190281
);
191282
}
192283

193-
public function execute(CommandInterface $command = null): CommandInterface
284+
public function execute(CommandLineParserInterface $command): FilesDiffCommandInterface
194285
{
195-
if (!is_null($command)) {
286+
$fileNames = $command->getFileNames();
287+
if (is_array($fileNames)) {
196288
$this->filesPaths = [
197-
$command->getFileNames()['FILE1'],
198-
$command->getFileNames()['FILE2']
289+
is_string($fileNames['FILE1']) ? $fileNames['FILE1'] : "",
290+
is_string($fileNames['FILE2']) ? $fileNames['FILE2'] : ""
199291
];
292+
};
200293

201-
foreach ($this->filesPaths as $filePath) {
202-
$this->filesDataItems[] = $this->fileReader->readFile($filePath);
203-
}
294+
foreach ($this->filesPaths as $filePath) {
295+
$this->filesDataItems[] = $this->fileReader->readFile($filePath);
296+
}
204297

298+
$filesDataItems = $this->filesDataItems[0];
299+
$file1Content = [];
300+
if (is_array($filesDataItems)) {
205301
$file1Content = array_map(
206302
fn($item) => $this->normalizeData($item),
207-
$this->filesDataItems[0],
303+
$filesDataItems
208304
);
305+
}
209306

307+
$filesDataItems = $this->filesDataItems[1];
308+
$file2Content = [];
309+
if (is_array($filesDataItems)) {
210310
$file2Content = array_map(
211311
fn($item) => $this->normalizeData($item),
212-
$this->filesDataItems[1]
213-
);
214-
215-
$fileKeys = array_keys($file1Content);
216-
asort($fileKeys);
217-
$initContent1Descriptor = [
218-
"level" => 0,
219-
"fileKey" => "initKey",
220-
"history" => "",
221-
"fileContent" => $file1Content
222-
];
223-
224-
$this->content1Descriptor = $this->getContent(
225-
$fileKeys,
226-
$initContent1Descriptor
312+
$filesDataItems
227313
);
314+
}
228315

229-
$fileKeys = array_keys($file2Content);
230-
asort($fileKeys);
231-
$initContent2Descriptor = [
232-
"level" => 0,
233-
"fileKey" => "initKey",
234-
"history" => "",
235-
"fileContent" => $file2Content
236-
];
316+
$fileKeys = array_keys($file1Content);
317+
asort($fileKeys);
318+
$initContent1Descriptor = [
319+
"level" => 0,
320+
"fileKey" => "initKey",
321+
"history" => "",
322+
"fileContent" => $file1Content,
323+
"output" => []
324+
];
325+
326+
$this->content1Descriptor = $this->getContent(
327+
$fileKeys,
328+
$initContent1Descriptor
329+
);
237330

238-
$this->content2Descriptor = $this->getContent(
239-
$fileKeys,
240-
$initContent2Descriptor
241-
);
331+
$fileKeys = array_keys($file2Content);
332+
asort($fileKeys);
333+
$initContent2Descriptor = [
334+
"level" => 0,
335+
"fileKey" => "initKey",
336+
"history" => "",
337+
"fileContent" => $file2Content,
338+
"output" => []
339+
];
340+
341+
$this->content2Descriptor = $this->getContent(
342+
$fileKeys,
343+
$initContent2Descriptor
344+
);
242345

243-
$mergedFileKeys = array_keys(array_merge($file1Content, $file2Content));
244-
asort($mergedFileKeys);
245-
$initDifferenceDescriptor = [
246-
"level" => 0,
247-
"status" => "init",
248-
"fileKey" => "initKey",
249-
"history" => "",
250-
"file1Content" => $file1Content,
251-
"file2Content" => $file2Content,
252-
];
253-
$this->differenceDescriptor = $this->getDifference(
254-
$mergedFileKeys,
255-
$initDifferenceDescriptor
256-
);
346+
$mergedFileKeys = array_keys(array_merge($file1Content, $file2Content));
347+
asort($mergedFileKeys);
348+
$initDifferenceDescriptor = [
349+
"level" => 0,
350+
"status" => "init",
351+
"fileKey" => "initKey",
352+
"history" => "",
353+
"file1Content" => $file1Content,
354+
"file2Content" => $file2Content,
355+
"output" => []
356+
];
357+
$differenceResult = $this->getDifference(
358+
$mergedFileKeys,
359+
$initDifferenceDescriptor
360+
);
361+
if (is_array($differenceResult)) {
362+
$this->differenceDescriptor = $differenceResult;
257363
}
258364

259365
return $this;
@@ -271,16 +377,25 @@ public function getFile2Name(): string
271377
return end($filename2Path);
272378
}
273379

380+
/**
381+
* @return array<mixed,mixed>
382+
*/
274383
public function getContent1Descriptor(): array
275384
{
276385
return $this->content1Descriptor;
277386
}
278387

388+
/**
389+
* @return array<mixed,mixed>
390+
*/
279391
public function getContent2Descriptor(): array
280392
{
281393
return $this->content2Descriptor;
282394
}
283395

396+
/**
397+
* @return array<mixed,mixed>
398+
*/
284399
public function getDifferenceDescriptor(): array
285400
{
286401
return $this->differenceDescriptor;

0 commit comments

Comments
 (0)