Skip to content

Commit 73c0493

Browse files
committed
Implement Package::implementation() to load implementations of a given type
1 parent fabe0fa commit 73c0493

File tree

4 files changed

+61
-1
lines changed

4 files changed

+61
-1
lines changed

src/main/php/lang/reflection/Package.class.php

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,21 @@ public function type($name) {
122122
throw new IllegalArgumentException('Given type '.$type.' is not in package '.$this->name);
123123
}
124124

125+
/**
126+
* Returns an implementation for a given type
127+
*
128+
* @param string|lang.reflection.Type $type
129+
* @param string $name
130+
* @return lang.reflection.Type
131+
* @throws lang.IllegalArgumentException
132+
*/
133+
public function implementation($type, $name) {
134+
$impl= $this->type($name);
135+
if ($impl->is($type)) return $impl;
136+
137+
throw new IllegalArgumentException('Given type '.$impl->name().' is not an implementation of '.$type);
138+
}
139+
125140
/** @return string */
126141
public function hashCode() { return md5($this->name); }
127142

src/test/php/lang/reflection/unittest/PackageTest.class.php

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,19 @@
11
<?php namespace lang\reflection\unittest;
22

3-
use lang\IllegalArgumentException;
43
use lang\reflection\Package;
4+
use lang\reflection\unittest\fixture\{Instruction, CreateInstruction};
5+
use lang\{Reflection, IllegalArgumentException};
56
use test\{Assert, Expect, Test, Values};
67

78
class PackageTest {
9+
const FIXTURES= 'lang.reflection.unittest.fixture';
10+
11+
/** @return iterable */
12+
private function instructions() {
13+
yield [Instruction::class, 'class literal'];
14+
yield ['lang.reflection.unittest.fixture.Instruction', 'class name'];
15+
yield [Reflection::type(Instruction::class), 'type'];
16+
}
817

918
#[Test, Values(['lang.reflection', 'lang\reflection', 'lang.reflection.'])]
1019
public function name($arg) {
@@ -102,4 +111,30 @@ public function type_via_full_name() {
102111
public function type_with_namespace() {
103112
(new Package('lang'))->type('util.Date');
104113
}
114+
115+
#[Test, Values(from: 'instructions')]
116+
public function implementation_by_name($type) {
117+
Assert::equals(
118+
Reflection::type(CreateInstruction::class),
119+
(new Package(self::FIXTURES))->implementation($type, 'CreateInstruction')
120+
);
121+
}
122+
123+
#[Test, Values(from: 'instructions')]
124+
public function implementation_by_class($type) {
125+
Assert::equals(
126+
Reflection::type(CreateInstruction::class),
127+
(new Package(self::FIXTURES))->implementation($type, CreateInstruction::class)
128+
);
129+
}
130+
131+
#[Test, Expect(class: IllegalArgumentException::class, message: '/Given type util.Date is not in package .+/')]
132+
public function implementation_not_in_package() {
133+
(new Package(self::FIXTURES))->implementation(Instruction::class, 'util.Date');
134+
}
135+
136+
#[Test, Expect(class: IllegalArgumentException::class, message: '/Given type .+ is not an implementation of lang.Runnable/')]
137+
public function not_an_implementation() {
138+
(new Package(self::FIXTURES))->implementation('lang.Runnable', 'CreateInstruction');
139+
}
105140
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
<?php namespace lang\reflection\unittest\fixture;
2+
3+
class CreateInstruction implements Instruction {
4+
5+
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
<?php namespace lang\reflection\unittest\fixture;
2+
3+
interface Instruction {
4+
5+
}

0 commit comments

Comments
 (0)