Skip to content

Commit

Permalink
[1.x] Add ability to resolve feature instance. (#118)
Browse files Browse the repository at this point in the history
* Enable retrieval of feature implementation

* Formatting
  • Loading branch information
timacdonald authored Aug 7, 2024
1 parent 716b019 commit 07884ea
Show file tree
Hide file tree
Showing 2 changed files with 56 additions and 0 deletions.
32 changes: 32 additions & 0 deletions src/Drivers/Decorator.php
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,13 @@ class Decorator implements CanListStoredFeatures, Driver
*/
protected $cache;

/**
* Map of feature names to their implementations.
*
* @var array<string, mixed>
*/
protected $nameMap = [];

/**
* Create a new driver decorator instance.
*
Expand Down Expand Up @@ -122,6 +129,10 @@ public function define($feature, $resolver = null): void
$this->container->make($feature)->name ?? $feature,
new LazilyResolvedFeature($feature),
];

$this->nameMap[$feature] = $resolver->feature;
} else {
$this->nameMap[$feature] = $resolver;
}

$this->driver->define($feature, function ($scope) use ($feature, $resolver) {
Expand Down Expand Up @@ -488,6 +499,27 @@ public function name($feature)
return $this->resolveFeature($feature);
}

/**
* Retrieve the feature's class.
*
* @param string $feature
* @return mixed
*/
public function instance($name)
{
$feature = $this->nameMap[$name] ?? $name;

if (is_string($feature) && class_exists($feature)) {
return $this->container->make($feature);
}

if ($feature instanceof Closure || $feature instanceof Lottery) {
return $feature;
}

return fn () => $feature;
}

/**
* Resolve the feature name and ensure it is defined.
*
Expand Down
24 changes: 24 additions & 0 deletions tests/Feature/ArrayDriverTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

namespace Tests\Feature;

use Closure;
use Illuminate\Container\Container;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Config;
Expand Down Expand Up @@ -1154,6 +1155,29 @@ public function test_it_can_list_stored_features()

$this->assertSame(Feature::stored(), ['bar']);
}

public function test_it_can_resolve_feature_instance()
{
Feature::define(MyFeature::class);
$this->assertInstanceOf(MyFeature::class, Feature::instance('my-feature'));
$this->assertInstanceOf(MyFeature::class, Feature::instance(MyFeature::class));

Feature::define(MyUnnamedFeature::class);
$this->assertInstanceOf(MyUnnamedFeature::class, Feature::instance(MyUnnamedFeature::class));

Feature::define('closure-based-feature', $closure = fn () => true);
$this->assertSame($closure, Feature::instance('closure-based-feature'));

Feature::define('value-based-feature', '123');
$feature = Feature::instance('value-based-feature');
$this->assertInstanceOf(Closure::class, $feature);
$this->assertSame('123', $feature());

Feature::define('lottery-based-feature', Lottery::odds(1, 1)->winner(fn () => '345'));
$feature = Feature::instance('lottery-based-feature');
$this->assertInstanceOf(Lottery::class, $feature);
$this->assertSame('345', $feature());
}
}

class MyFeature
Expand Down

0 comments on commit 07884ea

Please sign in to comment.