Skip to content

Commit 9926e7c

Browse files
committed
Major structural improvements
1 parent a57322a commit 9926e7c

File tree

12 files changed

+965
-376
lines changed

12 files changed

+965
-376
lines changed

FileIterator.php

Lines changed: 158 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,158 @@
1+
<?php
2+
declare(strict_types=1);
3+
4+
namespace MaplePHP\Unitary;
5+
6+
use Closure;
7+
use RuntimeException;
8+
use MaplePHP\Blunder\Handlers\CliHandler;
9+
use MaplePHP\Blunder\Run;
10+
use RecursiveDirectoryIterator;
11+
use RecursiveIteratorIterator;
12+
13+
class FileIterator
14+
{
15+
const PATTERN = 'unitary-*.php';
16+
17+
private array $args;
18+
19+
public function __construct(array $args = [])
20+
{
21+
$this->args = $args;
22+
}
23+
24+
/**
25+
* Will Execute all unitary test files.
26+
* @param string $directory
27+
* @return void
28+
* @throws RuntimeException
29+
*/
30+
public function executeAll(string $directory): void
31+
{
32+
$files = $this->findFiles($directory);
33+
if (empty($files)) {
34+
throw new RuntimeException("No files found matching the pattern \"" . static::PATTERN . "\" in directory \"$directory\" ");
35+
} else {
36+
foreach ($files as $file) {
37+
extract($this->args, EXTR_PREFIX_SAME, "wddx");
38+
Unit::resetUnit();
39+
Unit::setHeaders([
40+
"args" => $this->args,
41+
"file" => $file,
42+
"checksum" => md5($file)
43+
]);
44+
45+
$this->requireUnitFile($file)();
46+
if(!Unit::hasUnit()) {
47+
throw new RuntimeException("The Unitary Unit class has not been initiated inside \"$file\".");
48+
}
49+
}
50+
51+
Unit::completed();
52+
}
53+
}
54+
55+
/**
56+
* Will Scan and find all unitary test files
57+
* @param $dir
58+
* @return array
59+
*/
60+
private function findFiles($dir): array
61+
{
62+
$files = [];
63+
$realDir = realpath($dir);
64+
if(!$realDir) {
65+
throw new RuntimeException("Directory \"$dir\" does not exist. Try using a absolut path!");
66+
}
67+
$iterator = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($dir));
68+
foreach ($iterator as $file) {
69+
if (fnmatch(static::PATTERN, $file->getFilename()) &&
70+
(isset($this->args['path']) || !str_contains($file->getPathname(), DIRECTORY_SEPARATOR . "vendor" . DIRECTORY_SEPARATOR ))) {
71+
if(!$this->findExcluded($this->exclude(), $dir, $file->getPathname())) {
72+
$files[] = $file->getPathname();
73+
}
74+
}
75+
}
76+
return $files;
77+
}
78+
79+
/**
80+
* Get exclude parameter
81+
* @return array
82+
*/
83+
function exclude(): array
84+
{
85+
$excl = array();
86+
if(isset($this->args['exclude'])) {
87+
$exclude = explode(',', $this->args['exclude']);
88+
foreach ($exclude as $file) {
89+
$file = str_replace(['"', "'"], "", $file);
90+
$new = trim($file);
91+
$lastChar = substr($new, -1);
92+
if($lastChar === DIRECTORY_SEPARATOR) {
93+
$new .= "*";
94+
}
95+
$excl[] = trim($new);
96+
}
97+
}
98+
return $excl;
99+
}
100+
101+
/**
102+
* Validate a exclude path
103+
* @param array $exclArr
104+
* @param string $relativeDir
105+
* @param string $file
106+
* @return bool
107+
*/
108+
function findExcluded(array $exclArr, string $relativeDir, string $file): bool
109+
{
110+
$file = $this->getNaturalPath($file);
111+
foreach ($exclArr as $excl) {
112+
$relativeExclPath = $this->getNaturalPath($relativeDir . DIRECTORY_SEPARATOR . $excl);
113+
if(fnmatch($relativeExclPath, $file)) {
114+
return true;
115+
}
116+
}
117+
return false;
118+
}
119+
120+
/**
121+
* Get path as natural path
122+
* @param string $path
123+
* @return string
124+
*/
125+
function getNaturalPath(string $path): string
126+
{
127+
return str_replace("\\", "/", $path);
128+
}
129+
130+
/**
131+
* Require file without inheriting any class information
132+
* @param string $file
133+
* @return Closure
134+
*/
135+
private function requireUnitFile(string $file): Closure
136+
{
137+
$call = function() use ($file): void
138+
{
139+
140+
$cli = new CliHandler();
141+
if(isset(self::$headers['args']['trace'])) {
142+
$cli->enableTraceLines(true);
143+
}
144+
$run = new Run($cli);
145+
$run->load();
146+
147+
ob_start();
148+
require_once ($file);
149+
Unit::getUnit()->execute();
150+
151+
$outputBuffer = ob_get_clean();
152+
if($outputBuffer && Unit::hasUnit()) {
153+
Unit::getUnit()->buildNotice("Note:", $outputBuffer, 80);
154+
}
155+
};
156+
return $call->bindTo(null);
157+
}
158+
}

Handlers/FileHandler.php

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
<?php
2+
declare(strict_types=1);
3+
4+
namespace MaplePHP\Unitary\Handlers;
5+
6+
use MaplePHP\Http\Stream;
7+
use MaplePHP\Http\UploadedFile;
8+
use MaplePHP\Prompts\Command;
9+
10+
class FileHandler implements HandlerInterface
11+
{
12+
private string $file;
13+
private Stream $stream;
14+
private Command $command;
15+
16+
/**
17+
* Construct the file handler
18+
* The handler will pass stream to a file
19+
* @param string $file
20+
*/
21+
public function __construct(string $file)
22+
{
23+
$this->stream = new Stream(Stream::TEMP);
24+
$this->command = new Command($this->stream);
25+
$this->command->getAnsi()->disableAnsi(true);
26+
$this->file = $file;
27+
}
28+
29+
/**
30+
* Access the command stream
31+
* @return Command
32+
*/
33+
public function getCommand(): Command
34+
{
35+
return $this->command;
36+
}
37+
38+
/**
39+
* Execute the handler
40+
* This will automatically be called inside the Unit execution
41+
* @return void
42+
*/
43+
public function execute(): void
44+
{
45+
$upload = new UploadedFile($this->stream);
46+
$upload->moveTo($this->file);
47+
}
48+
}

Handlers/HandlerInterface.php

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
<?php
2+
declare(strict_types=1);
3+
4+
namespace MaplePHP\Unitary\Handlers;
5+
6+
use MaplePHP\Prompts\Command;
7+
8+
interface HandlerInterface
9+
{
10+
11+
/**
12+
* Access the command stream
13+
* @return Command
14+
*/
15+
public function getCommand(): Command;
16+
17+
/**
18+
* Execute the handler
19+
* This will automatically be called inside the Unit execution
20+
* @return void
21+
*/
22+
public function execute(): void;
23+
}

Handlers/HtmlHandler.php

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
<?php
2+
declare(strict_types=1);
3+
4+
namespace MaplePHP\Unitary\Handlers;
5+
6+
use MaplePHP\Http\Stream;
7+
use MaplePHP\Prompts\Command;
8+
9+
class HtmlHandler implements HandlerInterface
10+
{
11+
private Stream $stream;
12+
private Command $command;
13+
14+
/**
15+
* Construct the file handler
16+
* The handler will pass stream to a file
17+
*/
18+
public function __construct()
19+
{
20+
$this->stream = new Stream(Stream::TEMP);
21+
$this->command = new Command($this->stream);
22+
$this->command->getAnsi()->disableAnsi(true);
23+
}
24+
25+
/**
26+
* Access the command stream
27+
* @return Command
28+
*/
29+
public function getCommand(): Command
30+
{
31+
return $this->command;
32+
}
33+
34+
/**
35+
* Execute the handler
36+
* This will automatically be called inside the Unit execution
37+
* @return void
38+
*/
39+
public function execute(): void
40+
{
41+
$this->stream->rewind();
42+
$out = $this->stream->getContents();
43+
$style = 'background-color: #F1F1F1; color: #000; font-size: 2rem; font-weight: normal; font-family: "Lucida Console", Monaco, monospace;';
44+
$out = str_replace(["[", "]"], ['<span style="background-color: #666; color: #FFF; padding: 4px 2px">', '</span>'], $out);
45+
echo '<pre style="' . $style . '">' . $out . '</pre>';
46+
}
47+
}

0 commit comments

Comments
 (0)