Page MenuHomeDevCentral

D2507.id6323.diff
No OneTemporary

D2507.id6323.diff

diff --git a/src/IO/Directory.php b/src/IO/Directory.php
--- a/src/IO/Directory.php
+++ b/src/IO/Directory.php
@@ -75,4 +75,15 @@
);
}
+ /**
+ * @return Directory[]
+ */
+ public function getSubdirectories () : array {
+ return array_map(
+ function ($dir) {
+ return new Directory($dir);
+ }, glob("$this->path/*", GLOB_ONLYDIR)
+ );
+ }
+
}
diff --git a/src/Registration/PSR4/PSR4Namespace.php b/src/Registration/PSR4/PSR4Namespace.php
new file mode 100644
--- /dev/null
+++ b/src/Registration/PSR4/PSR4Namespace.php
@@ -0,0 +1,75 @@
+<?php
+
+namespace Keruald\OmniTools\Registration\PSR4;
+
+use Keruald\OmniTools\IO\Directory;
+use Keruald\OmniTools\IO\File;
+
+class PSR4Namespace {
+
+ public function __construct (
+ public string $namespacePrefix,
+ public string $baseDirectory,
+ ) {
+ }
+
+ ///
+ /// Auto-discovery
+ ///
+
+ /**
+ * Discover classes in the namespace folder following PSR-4 convention,
+ * directly at top-level, ignoring subdirectories.
+ *
+ * @see discoverRecursive
+ * @return string[]
+ */
+ public function discover () : array {
+ $files = (new Directory($this->baseDirectory))
+ ->glob("*.php");
+
+ return array_map(function (File $file) {
+ return $this->namespacePrefix
+ . "\\" . $file->getFileNameWithoutExtension();
+ }, $files);
+ }
+
+ /**
+ * Discover classes in the namespace folder following PSR-4 convention,
+ * including all subfolders.
+ *
+ * @return string[]
+ */
+ public function discoverRecursive () : array {
+ $classes = $this->discover();
+
+ $subDirectories = (new Directory($this->baseDirectory))
+ ->getSubdirectories();
+
+ foreach ($subDirectories as $dir) {
+ $ns = new PSR4Namespace(
+ $this->namespacePrefix . "\\" . $dir->getDirectoryName(),
+ $dir->getPath(),
+ );
+
+ array_push($classes, ...$ns->discoverRecursive());
+ }
+
+ return $classes;
+ }
+
+ /**
+ * Discover classes for a specific namespace in a specific folder,
+ * following the PSR-4 convention, including all subfolders.
+ *
+ * @return string[]
+ */
+ public static function discoverAllClasses (
+ string $namespacePrefix,
+ string $baseDirectory
+ ) : array {
+ $ns = new PSR4Namespace($namespacePrefix, $baseDirectory);
+ return $ns->discoverRecursive();
+ }
+
+}
diff --git a/tests/Registration/PSR4/PSR4NamespaceTest.php b/tests/Registration/PSR4/PSR4NamespaceTest.php
new file mode 100644
--- /dev/null
+++ b/tests/Registration/PSR4/PSR4NamespaceTest.php
@@ -0,0 +1,83 @@
+<?php
+
+namespace Keruald\OmniTools\Tests\Registration\PSR4;
+
+use Keruald\OmniTools\Registration\PSR4\PSR4Namespace;
+
+use Keruald\OmniTools\Tests\WithData;
+use PHPUnit\Framework\TestCase;
+
+class PSR4NamespaceTest extends TestCase {
+
+ use WithData;
+
+ ///
+ /// Discovery tests
+ ///
+
+ const ALL_CLASSES = [
+ "Acme\\SolarSystemLib\\Sun",
+ "Acme\\SolarSystemLib\\Planets\\Pluton",
+ "Acme\\SolarSystemLib\\Planets\\Inner\\Mercure",
+ "Acme\\SolarSystemLib\\Planets\\Inner\\Venus",
+ ];
+
+ /**
+ * @dataProvider provideClasses
+ */
+ public function testDiscover (
+ string $path, string $prefix, array $expected
+ ) : void {
+ $ns = new PSR4Namespace($prefix, $this->getDataPath($path));
+
+ $this->assertEquals($expected, $ns->discover());
+ }
+
+ public function testDiscoverRecursive () : void {
+ $baseDirectory = $this->getDataPath("SolarSystemLib");
+ $ns = new PSR4Namespace("Acme\\SolarSystemLib", $baseDirectory);
+
+ $this->assertEquals(self::ALL_CLASSES, $ns->discoverRecursive());
+ }
+
+ public function testDiscoverAllClasses () : void {
+ $actual = PSR4Namespace::discoverAllClasses(
+ "Acme\\SolarSystemLib",
+ $this->getDataPath("SolarSystemLib"),
+ );
+
+ $this->assertEquals(self::ALL_CLASSES, $actual);
+
+ }
+
+ ///
+ /// Data providers
+ ///
+
+ public function provideClasses () : iterable {
+ // [string $path, string $prefix, string[] $expectedClasses]
+ yield ["MockLib", "Acme\\MockLib", [
+ "Acme\\MockLib\\Bar",
+ "Acme\\MockLib\\Foo",
+ ]];
+
+ yield ["SolarSystemLib", "Acme\\SolarSystemLib", [
+ "Acme\\SolarSystemLib\\Sun",
+ ]];
+
+ yield ["SolarSystemLib/Planets", "Acme\\SolarSystemLib\\Planets", [
+ "Acme\\SolarSystemLib\\Planets\\Pluton",
+ ]];
+
+ yield [
+ "SolarSystemLib/Planets/Inner",
+ "Acme\\SolarSystemLib\\Planets\\Inner",
+ [
+ "Acme\\SolarSystemLib\\Planets\\Inner\\Mercure",
+ "Acme\\SolarSystemLib\\Planets\\Inner\\Venus",
+ ]
+ ];
+
+ yield ["NotExisting", "AnyPrefix", []];
+ }
+}
diff --git a/tests/data/SolarSystemLib/Planets/Inner/Mercure.php b/tests/data/SolarSystemLib/Planets/Inner/Mercure.php
new file mode 100644
--- /dev/null
+++ b/tests/data/SolarSystemLib/Planets/Inner/Mercure.php
@@ -0,0 +1,7 @@
+<?php
+
+namespace Acme\SolarSystemLib\Planets\Inner;
+
+class Mercure {
+
+}
diff --git a/tests/data/SolarSystemLib/Planets/Inner/Venus.php b/tests/data/SolarSystemLib/Planets/Inner/Venus.php
new file mode 100644
--- /dev/null
+++ b/tests/data/SolarSystemLib/Planets/Inner/Venus.php
@@ -0,0 +1,7 @@
+<?php
+
+namespace Acme\SolarSystemLib\Planets\Inner;
+
+class Venus {
+
+}
diff --git a/tests/data/SolarSystemLib/Planets/Pluton.php b/tests/data/SolarSystemLib/Planets/Pluton.php
new file mode 100644
--- /dev/null
+++ b/tests/data/SolarSystemLib/Planets/Pluton.php
@@ -0,0 +1,7 @@
+<?php
+
+namespace Acme\SolarSystemLib\Planets;
+
+class Pluton {
+
+}
diff --git a/tests/data/SolarSystemLib/Sun.php b/tests/data/SolarSystemLib/Sun.php
new file mode 100644
--- /dev/null
+++ b/tests/data/SolarSystemLib/Sun.php
@@ -0,0 +1,7 @@
+<?php
+
+namespace Acme\SolarSystemLib;
+
+class Sun {
+
+}

File Metadata

Mime Type
text/plain
Expires
Mon, Nov 25, 19:02 (5 h, 39 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
2263019
Default Alt Text
D2507.id6323.diff (6 KB)

Event Timeline