diff --git a/Dockerfile b/Dockerfile
new file mode 100644
index 00000000..b469041f
--- /dev/null
+++ b/Dockerfile
@@ -0,0 +1,29 @@
+# docker-compose up -d && docker logs -f scribe_app_1
+FROM ubuntu:jammy
+ARG DEBIAN_FRONTEND=noninteractive
+ENV TZ=Etc/UTC
+
+# APT
+RUN apt-get -qq update && apt-get install -qq \
+ make \
+ curl \
+ php \
+ php-curl \
+ php-xml \
+ php-sqlite3 \
+ php-bcmath \
+ php-curl \
+ php-gd \
+ php-imagick \
+ php-intl \
+ php-mbstring \
+ php-pdo \
+ php-zip \
+ php-soap \
+ php-pcov \
+ git \
+ p7zip-full
+
+# Composer Install
+RUN curl -sS https://getcomposer.org/installer | php && \
+ mv composer.phar /usr/local/bin/composer
diff --git a/Makefile b/Makefile
new file mode 100644
index 00000000..7c1b2d5f
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,5 @@
+install:
+ composer install
+
+test: install
+ composer test-ci
diff --git a/camel/Camel.php b/camel/Camel.php
index 28d03d30..46e00c46 100644
--- a/camel/Camel.php
+++ b/camel/Camel.php
@@ -6,20 +6,21 @@
use Illuminate\Support\Arr;
use Illuminate\Support\Str;
use Knuckles\Camel\Output\OutputEndpointData;
+use Knuckles\Scribe\Configuration\CacheConfiguration;
use Knuckles\Scribe\Tools\Utils;
use Symfony\Component\Yaml\Yaml;
class Camel
{
- public static function cacheDir(string $docsName = 'scribe'): string
+ public static function cacheDir(CacheConfiguration $docsObject): string
{
- return ".$docsName/endpoints.cache";
+ return $docsObject . "/endpoints.cache";
}
- public static function camelDir(string $docsName = 'scribe'): string
+ public static function camelDir(CacheConfiguration $docsObject): string
{
- return ".$docsName/endpoints";
+ return $docsObject . "/endpoints";
}
/**
diff --git a/docker-compose.yml b/docker-compose.yml
new file mode 100644
index 00000000..ca66d286
--- /dev/null
+++ b/docker-compose.yml
@@ -0,0 +1,11 @@
+# Allow devs to run the unit tests in a dockerized environment
+# clear && docker-compose up -d && docker logs -f scribe_app_1
+version: '3.7'
+services:
+ app:
+ build:
+ context: ./
+ volumes:
+ - ./:/testing
+ working_dir: /testing
+ command: make test
diff --git a/phpunit.xml b/phpunit.xml
index 813fd914..a25bbb4e 100644
--- a/phpunit.xml
+++ b/phpunit.xml
@@ -41,6 +41,7 @@
tests/Unit/ExtractorTest.php
tests/Unit/ExtractorPluginSystemTest.php
tests/Unit/ConfigDifferTest.php
+ tests/Unit/CacheConfigurationTest.php
tests/Unit/ExtractedEndpointDataTest.php
diff --git a/src/Commands/GenerateDocumentation.php b/src/Commands/GenerateDocumentation.php
index c899377a..76440a57 100644
--- a/src/Commands/GenerateDocumentation.php
+++ b/src/Commands/GenerateDocumentation.php
@@ -7,6 +7,7 @@
use Illuminate\Support\Facades\URL;
use Illuminate\Support\Str;
use Knuckles\Camel\Camel;
+use Knuckles\Scribe\Configuration\CacheConfiguration;
use Knuckles\Scribe\GroupedEndpoints\GroupedEndpointsFactory;
use Knuckles\Scribe\Matching\RouteMatcherInterface;
use Knuckles\Scribe\Tools\ConsoleOutputUtils as c;
@@ -24,6 +25,7 @@ class GenerateDocumentation extends Command
{--no-extraction : Skip extraction of route and API info and just transform the YAML and Markdown files into HTML}
{--no-upgrade-check : Skip checking for config file upgrades. Won't make things faster, but can be helpful if the command is buggy}
{--config=scribe : choose which config file to use}
+ {--cache-directory= : choose which cache directory to use}
";
protected $description = 'Generate API documentation from your Laravel/Dingo routes.';
@@ -34,7 +36,8 @@ class GenerateDocumentation extends Command
protected bool $forcing;
- protected string $configName;
+ /** @var CacheConfiguration */
+ protected CacheConfiguration $configObject;
public function handle(RouteMatcherInterface $routeMatcher, GroupedEndpointsFactory $groupedEndpointsFactory): void
{
@@ -47,9 +50,9 @@ public function handle(RouteMatcherInterface $routeMatcher, GroupedEndpointsFact
}
// Extraction stage - extract endpoint info either from app or existing Camel files (previously extracted data)
- $groupedEndpointsInstance = $groupedEndpointsFactory->make($this, $routeMatcher, $this->configName);
+ $groupedEndpointsInstance = $groupedEndpointsFactory->make($this, $routeMatcher, $this->configObject);
$extractedEndpoints = $groupedEndpointsInstance->get();
- $userDefinedEndpoints = Camel::loadUserDefinedEndpoints(Camel::camelDir($this->configName));
+ $userDefinedEndpoints = Camel::loadUserDefinedEndpoints(Camel::camelDir($this->configObject));
$groupedEndpoints = $this->mergeUserDefinedEndpoints($extractedEndpoints, $userDefinedEndpoints);
// Output stage
@@ -61,7 +64,7 @@ public function handle(RouteMatcherInterface $routeMatcher, GroupedEndpointsFact
$this->writeExampleCustomEndpoint();
}
- $writer = new Writer($this->docConfig, $this->configName);
+ $writer = new Writer($this->docConfig, $this->configObject);
$writer->writeDocs($groupedEndpoints);
$this->upgradeConfigFileIfNeeded();
@@ -98,12 +101,17 @@ public function bootstrap(): void
c::bootstrapOutput($this->output);
- $this->configName = $this->option('config');
- if (!config($this->configName)) {
- throw new \InvalidArgumentException("The specified config (config/{$this->configName}.php) doesn't exist.");
+ $configName = $this->option('config');
+ if (!config($configName)) {
+ throw new \InvalidArgumentException("The specified config (config/{$configName}.php) doesn't exist.");
}
- $this->docConfig = new DocumentationConfig(config($this->configName));
+ $this->configObject = new CacheConfiguration($configName, $configName, true);
+ if ($this->hasOption('cache-directory') && !empty($this->option('cache-directory'))) {
+ $this->configObject = new CacheConfiguration($this->option('cache-directory'), $configName, false);
+ }
+
+ $this->docConfig = new DocumentationConfig(config($this->configObject->getScribeConfigFile()));
// Force root URL so it works in Postman collection
$baseUrl = $this->docConfig->get('base_url') ?? config('app.url');
@@ -146,7 +154,7 @@ protected function mergeUserDefinedEndpoints(array $groupedEndpoints, array $use
protected function writeExampleCustomEndpoint(): void
{
// We add an example to guide users in case they need to add a custom endpoint.
- copy(__DIR__ . '/../../resources/example_custom_endpoint.yaml', Camel::camelDir($this->configName) . '/custom.0.yaml');
+ copy(__DIR__ . '/../../resources/example_custom_endpoint.yaml', Camel::camelDir($this->configObject) . '/custom.0.yaml');
}
protected function upgradeConfigFileIfNeeded(): void
@@ -155,12 +163,12 @@ protected function upgradeConfigFileIfNeeded(): void
$this->info("Checking for any pending upgrades to your config file...");
try {
- if (! $this->laravel['files']->exists($this->laravel->configPath("{$this->configName}.php"))) {
+ if (! $this->laravel['files']->exists($this->laravel->configPath($this->configObject->getScribeConfigFile() . ".php"))) {
$this->info("No config file to upgrade.");
return;
}
- $upgrader = Upgrader::ofConfigFile("config/{$this->configName}.php", __DIR__ . '/../../config/scribe.php')
+ $upgrader = Upgrader::ofConfigFile("config/" . $this->configObject->getScribeConfigFile() . ".php", __DIR__ . '/../../config/scribe.php')
->dontTouch(
'routes', 'example_languages', 'database_connections_to_transact', 'strategies', 'laravel.middleware',
'postman.overrides', 'openapi.overrides', 'groups', 'examples.models_source'
diff --git a/src/Configuration/CacheConfiguration.php b/src/Configuration/CacheConfiguration.php
new file mode 100644
index 00000000..b19ccf8d
--- /dev/null
+++ b/src/Configuration/CacheConfiguration.php
@@ -0,0 +1,46 @@
+cacheDir = $cacheDir;
+ $this->scribeConfig = $scribeConfig;
+ $this->isHidden = $isHidden;
+ }
+
+ /**
+ * @return string
+ */
+ public function getScribeConfigFile(): string
+ {
+ return $this->scribeConfig;
+ }
+
+ /**
+ * @return string
+ */
+ public function __toString(): string
+ {
+ return ($this->isHidden ? '.' : '') . $this->cacheDir;
+ }
+}
diff --git a/src/Extracting/ApiDetails.php b/src/Extracting/ApiDetails.php
index febe4b9c..d4285e75 100644
--- a/src/Extracting/ApiDetails.php
+++ b/src/Extracting/ApiDetails.php
@@ -2,6 +2,7 @@
namespace Knuckles\Scribe\Extracting;
+use Knuckles\Scribe\Configuration\CacheConfiguration;
use Knuckles\Scribe\Tools\ConsoleOutputUtils as c;
use Knuckles\Scribe\Tools\Utils as u;
use Knuckles\Scribe\Tools\DocumentationConfig;
@@ -23,9 +24,9 @@ class ApiDetails
private array $lastKnownFileContentHashes = [];
- public function __construct(DocumentationConfig $config = null, bool $preserveUserChanges = true, string $docsName = 'scribe')
+ public function __construct(DocumentationConfig $config = null, bool $preserveUserChanges = true, CacheConfiguration $docsName)
{
- $this->markdownOutputPath = ".{$docsName}"; //.scribe by default
+ $this->markdownOutputPath = $docsName; //.scribe by default
// If no config is injected, pull from global. Makes testing easier.
$this->config = $config ?: new DocumentationConfig(config($docsName));
$this->baseUrl = $this->config->get('base_url') ?? config('app.url');
diff --git a/src/GroupedEndpoints/GroupedEndpointsFactory.php b/src/GroupedEndpoints/GroupedEndpointsFactory.php
index 022454ef..c2c4de88 100644
--- a/src/GroupedEndpoints/GroupedEndpointsFactory.php
+++ b/src/GroupedEndpoints/GroupedEndpointsFactory.php
@@ -3,12 +3,16 @@
namespace Knuckles\Scribe\GroupedEndpoints;
use Knuckles\Scribe\Commands\GenerateDocumentation;
+use Knuckles\Scribe\Configuration\CacheConfiguration;
use Knuckles\Scribe\Matching\RouteMatcherInterface;
class GroupedEndpointsFactory
{
- public function make(GenerateDocumentation $command, RouteMatcherInterface $routeMatcher, string $docsName = 'scribe'): GroupedEndpointsContract
- {
+ public function make(
+ GenerateDocumentation $command,
+ RouteMatcherInterface $routeMatcher,
+ CacheConfiguration $docsName
+ ): GroupedEndpointsContract {
if ($command->isForcing()) {
return static::fromApp($command, $routeMatcher, false, $docsName);
}
@@ -24,12 +28,12 @@ public static function fromApp(
GenerateDocumentation $command,
RouteMatcherInterface $routeMatcher,
bool $preserveUserChanges,
- string $docsName = 'scribe'
+ CacheConfiguration $docsName
): GroupedEndpointsFromApp {
return new GroupedEndpointsFromApp($command, $routeMatcher, $preserveUserChanges, $docsName);
}
- public static function fromCamelDir(string $docsName = 'scribe'): GroupedEndpointsFromCamelDir
+ public static function fromCamelDir(CacheConfiguration $docsName): GroupedEndpointsFromCamelDir
{
return new GroupedEndpointsFromCamelDir($docsName);
}
diff --git a/src/GroupedEndpoints/GroupedEndpointsFromApp.php b/src/GroupedEndpoints/GroupedEndpointsFromApp.php
index 18209ffb..987f55ab 100644
--- a/src/GroupedEndpoints/GroupedEndpointsFromApp.php
+++ b/src/GroupedEndpoints/GroupedEndpointsFromApp.php
@@ -10,6 +10,7 @@
use Knuckles\Camel\Extraction\ExtractedEndpointData;
use Knuckles\Camel\Output\OutputEndpointData;
use Knuckles\Scribe\Commands\GenerateDocumentation;
+use Knuckles\Scribe\Configuration\CacheConfiguration;
use Knuckles\Scribe\Exceptions\CouldntGetRouteDetails;
use Knuckles\Scribe\Extracting\ApiDetails;
use Knuckles\Scribe\Extracting\Extractor;
@@ -34,10 +35,11 @@ class GroupedEndpointsFromApp implements GroupedEndpointsContract
public static string $cacheDir;
public function __construct(
- private GenerateDocumentation $command, private RouteMatcherInterface $routeMatcher,
- private bool $preserveUserChanges = true, protected string $docsName = 'scribe'
- )
- {
+ private GenerateDocumentation $command,
+ private RouteMatcherInterface $routeMatcher,
+ private bool $preserveUserChanges = true,
+ protected CacheConfiguration $docsName
+ ) {
$this->docConfig = $command->getDocConfig();
static::$camelDir = Camel::camelDir($this->docsName);
diff --git a/src/GroupedEndpoints/GroupedEndpointsFromCamelDir.php b/src/GroupedEndpoints/GroupedEndpointsFromCamelDir.php
index ad80a69f..b78450d5 100644
--- a/src/GroupedEndpoints/GroupedEndpointsFromCamelDir.php
+++ b/src/GroupedEndpoints/GroupedEndpointsFromCamelDir.php
@@ -3,12 +3,13 @@
namespace Knuckles\Scribe\GroupedEndpoints;
use Knuckles\Camel\Camel;
+use Knuckles\Scribe\Configuration\CacheConfiguration;
class GroupedEndpointsFromCamelDir implements GroupedEndpointsContract
{
- protected string $docsName;
+ protected CacheConfiguration $docsName;
- public function __construct(string $docsName = 'scribe')
+ public function __construct(CacheConfiguration $docsName)
{
$this->docsName = $docsName;
}
diff --git a/src/Writing/Writer.php b/src/Writing/Writer.php
index c3a03539..f24a594c 100644
--- a/src/Writing/Writer.php
+++ b/src/Writing/Writer.php
@@ -3,6 +3,7 @@
namespace Knuckles\Scribe\Writing;
use Illuminate\Support\Facades\Storage;
+use Knuckles\Scribe\Configuration\CacheConfiguration;
use Knuckles\Scribe\Tools\ConsoleOutputUtils as c;
use Knuckles\Scribe\Tools\DocumentationConfig;
use Knuckles\Scribe\Tools\Globals;
@@ -15,7 +16,7 @@ class Writer
* The "name" of this docs instance. By default, it is "scribe".
* Used for multi-docs.
*/
- public string $docsName;
+ public CacheConfiguration $docsName;
private DocumentationConfig $config;
@@ -40,21 +41,21 @@ class Writer
private string $laravelAssetsPath;
- public function __construct(DocumentationConfig $config = null, $docsName = 'scribe')
+ public function __construct(DocumentationConfig $config = null, CacheConfiguration $docsName)
{
$this->docsName = $docsName;
// If no config is injected, pull from global, for easier testing.
- $this->config = $config ?: new DocumentationConfig(config($docsName));
+ $this->config = $config ?: new DocumentationConfig(config($docsName->getScribeConfigFile()));
$this->isStatic = $this->config->get('type') === 'static';
- $this->markdownOutputPath = ".{$docsName}"; //.scribe by default
+ $this->markdownOutputPath = $docsName; //.scribe by default
$this->laravelTypeOutputPath = $this->getLaravelTypeOutputPath();
$this->staticTypeOutputPath = rtrim($this->config->get('static.output_path', 'public/docs'), '/');
$this->laravelAssetsPath = $this->config->get('laravel.assets_directory')
? '/' . $this->config->get('laravel.assets_directory')
- : "/vendor/$this->docsName";
+ : "/vendor/" . $this->docsName->getScribeConfigFile();
}
/**
@@ -86,8 +87,8 @@ protected function writePostmanCollection(array $groups): void
$collectionPath = "{$this->staticTypeOutputPath}/collection.json";
file_put_contents($collectionPath, $collection);
} else {
- Storage::disk('local')->put("{$this->docsName}/collection.json", $collection);
- $collectionPath = Storage::disk('local')->path("$this->docsName/collection.json");
+ Storage::disk('local')->put($this->docsName->getScribeConfigFile() . "/collection.json", $collection);
+ $collectionPath = Storage::disk('local')->path($this->docsName->getScribeConfigFile() . "/collection.json");
}
c::success("Wrote Postman collection to: {$this->makePathFriendly($collectionPath)}");
@@ -105,8 +106,8 @@ protected function writeOpenAPISpec(array $parsedRoutes): void
$specPath = "{$this->staticTypeOutputPath}/openapi.yaml";
file_put_contents($specPath, $spec);
} else {
- Storage::disk('local')->put("{$this->docsName}/openapi.yaml", $spec);
- $specPath = Storage::disk('local')->path("$this->docsName/openapi.yaml");
+ Storage::disk('local')->put($this->docsName->getScribeConfigFile() . "/openapi.yaml", $spec);
+ $specPath = Storage::disk('local')->path($this->docsName->getScribeConfigFile() . "/openapi.yaml");
}
c::success("Wrote OpenAPI specification to: {$this->makePathFriendly($specPath)}");
@@ -180,8 +181,8 @@ protected function performFinalTasksForLaravelType(): void
// Rewrite asset links to go through Laravel
$contents = preg_replace('#href="\.\./docs/css/(.+?)"#', 'href="{{ asset("' . $this->laravelAssetsPath . '/css/$1") }}"', $contents);
$contents = preg_replace('#src="\.\./docs/(js|images)/(.+?)"#', 'src="{{ asset("' . $this->laravelAssetsPath . '/$1/$2") }}"', $contents);
- $contents = str_replace('href="../docs/collection.json"', 'href="{{ route("' . $this->docsName . '.postman") }}"', $contents);
- $contents = str_replace('href="../docs/openapi.yaml"', 'href="{{ route("' . $this->docsName . '.openapi") }}"', $contents);
+ $contents = str_replace('href="../docs/collection.json"', 'href="{{ route("' . $this->docsName->getScribeConfigFile() . '.postman") }}"', $contents);
+ $contents = str_replace('href="../docs/openapi.yaml"', 'href="{{ route("' . $this->docsName->getScribeConfigFile() . '.openapi") }}"', $contents);
file_put_contents("$this->laravelTypeOutputPath/index.blade.php", $contents);
}
@@ -228,7 +229,7 @@ protected function getLaravelTypeOutputPath(): ?string
{
if ($this->isStatic) return null;
- return config('view.paths.0', function_exists('base_path') ? base_path("resources/views") : "resources/views") . "/$this->docsName";
+ return config('view.paths.0', function_exists('base_path') ? base_path("resources/views") : "resources/views") . "/" . $this->docsName->getScribeConfigFile();
}
/**
diff --git a/tests/GenerateDocumentation/OutputTest.php b/tests/GenerateDocumentation/OutputTest.php
index 52f4ede8..a6dc73d6 100644
--- a/tests/GenerateDocumentation/OutputTest.php
+++ b/tests/GenerateDocumentation/OutputTest.php
@@ -139,39 +139,82 @@ public function generates_laravel_type_output()
/** @test */
public function supports_multi_docs_in_laravel_type_output()
+ {
+ $this->supports_base_test(["--config" => "scribe_admin"], '.scribe_admin');
+ }
+
+ /** @test */
+ public function supports_separate_hidden_cache_directory()
+ {
+ $this->supports_base_test([
+ "--config" => "scribe_admin",
+ "--cache-directory" => ".scribe_admin_dir"
+ ], '.scribe_admin_dir');
+ }
+
+ /** @test */
+ public function supports_separate_non_hidden_cache_directory()
+ {
+ $this->supports_base_test([
+ "--config" => "scribe_admin",
+ "--cache-directory" => "scribe_admin_dir"
+ ], 'scribe_admin_dir');
+ }
+
+ /** @test */
+ public function supports_unrelated_temp_directory()
+ {
+ $this->supports_base_test([
+ "--config" => "bananas_are_good",
+ "--cache-directory" => "5.5/Apple/26"
+ ], '5.5/Apple/26');
+ }
+
+ /**
+ * Base test for
+ * - supports_multi_docs_in_laravel_type_output
+ * - supports_separate_hidden_cache_directory
+ * - supports_separate_non_hidden_cache_directory
+ * - supports_unrelated_temp_directory
+ *
+ * @param $generate
+ * @param $assertDir
+ * @return void
+ */
+ private function supports_base_test($generate, $assertDir)
{
RouteFacade::post('/api/withQueryParameters', [TestController::class, 'withQueryParameters']);
- config(['scribe_admin' => config('scribe')]);
+ config([$generate['--config'] => config('scribe')]);
$title = "The Real Admin API";
- config(['scribe_admin.title' => $title]);
- config(['scribe_admin.type' => 'laravel']);
- config(['scribe_admin.postman.enabled' => true]);
- config(['scribe_admin.openapi.enabled' => true]);
+ config([$generate['--config'] . '.title' => $title]);
+ config([$generate['--config'] . '.type' => 'laravel']);
+ config([$generate['--config'] . '.postman.enabled' => true]);
+ config([$generate['--config'] . '.openapi.enabled' => true]);
- $output = $this->generate(["--config" => "scribe_admin"]);
+ $output = $this->generate($generate);
$this->assertStringContainsString(
- "Wrote Blade docs to: vendor/orchestra/testbench-core/laravel/resources/views/scribe_admin", $output
+ "Wrote Blade docs to: vendor/orchestra/testbench-core/laravel/resources/views/" . $generate['--config'], $output
);
$this->assertStringContainsString(
- "Wrote Laravel assets to: vendor/orchestra/testbench-core/laravel/public/vendor/scribe_admin", $output
+ "Wrote Laravel assets to: vendor/orchestra/testbench-core/laravel/public/vendor/" . $generate['--config'], $output
);
$this->assertStringContainsString(
- "Wrote Postman collection to: vendor/orchestra/testbench-core/laravel/storage/app/scribe_admin/collection.json", $output
+ "Wrote Postman collection to: vendor/orchestra/testbench-core/laravel/storage/app/" . $generate['--config'] . "/collection.json", $output
);
$this->assertStringContainsString(
- "Wrote OpenAPI specification to: vendor/orchestra/testbench-core/laravel/storage/app/scribe_admin/openapi.yaml", $output
+ "Wrote OpenAPI specification to: vendor/orchestra/testbench-core/laravel/storage/app/" . $generate['--config'] . "/openapi.yaml", $output
);
$paths = collect([
- Storage::disk('local')->path('scribe_admin/collection.json'),
- Storage::disk('local')->path('scribe_admin/openapi.yaml'),
- View::getFinder()->find('scribe_admin/index'),
+ Storage::disk('local')->path( $generate['--config'] . '/collection.json'),
+ Storage::disk('local')->path($generate['--config'] . '/openapi.yaml'),
+ View::getFinder()->find($generate['--config'] . '/index'),
]);
$paths->each(fn($path) => $this->assertFileContainsString($path, $title));
$paths->each(fn($path) => unlink($path));
- $this->assertDirectoryExists(".scribe_admin");
- Utils::deleteDirectoryAndContents(".scribe_admin");
+ $this->assertDirectoryExists($assertDir);
+ Utils::deleteDirectoryAndContents($assertDir);
}
/** @test */
diff --git a/tests/Unit/CacheConfigurationTest.php b/tests/Unit/CacheConfigurationTest.php
new file mode 100644
index 00000000..e5422cd3
--- /dev/null
+++ b/tests/Unit/CacheConfigurationTest.php
@@ -0,0 +1,37 @@
+assertEquals('.scribe', $cacheConfiguration);
+ }
+
+ /** @test */
+ public function object_coerses_into_non_hidden_string()
+ {
+ $cacheConfiguration = new CacheConfiguration('scribe', 'scribe', false);
+ $this->assertEquals('scribe', $cacheConfiguration);
+ }
+
+ /** @test */
+ public function object_coerses_into_hidden_string_for_subdirs()
+ {
+ $cacheConfiguration = new CacheConfiguration('scribe/bob', 'scribe', true);
+ $this->assertEquals('.scribe/bob', $cacheConfiguration);
+ }
+
+ /** @test */
+ public function object_coerses_into_non_hidden_string_for_subdirs()
+ {
+ $cacheConfiguration = new CacheConfiguration('scribe/bob/dave', 'scribe', false);
+ $this->assertEquals('scribe/bob/dave', $cacheConfiguration);
+ }
+}