-
-
Notifications
You must be signed in to change notification settings - Fork 6
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #110 from hydephp/create-static-file-collections
Create static file collections
- Loading branch information
Showing
6 changed files
with
308 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
68 changes: 68 additions & 0 deletions
68
packages/framework/src/Modules/DataCollections/DataCollection.php
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,68 @@ | ||
<?php | ||
|
||
namespace Hyde\Framework\Modules\DataCollections; | ||
|
||
use Hyde\Framework\Hyde; | ||
use Hyde\Framework\Models\MarkdownDocument; | ||
use Hyde\Framework\Services\MarkdownFileService; | ||
use Illuminate\Support\Collection; | ||
|
||
/** | ||
* Generates Laravel Collections from static data files, | ||
* such as Markdown components and YAML files. | ||
* | ||
* @see \Hyde\Framework\Testing\Modules\DataCollections\DataCollectionTest\DataCollectionTest | ||
*/ | ||
class DataCollection extends Collection | ||
{ | ||
public string $key; | ||
|
||
protected float $timeStart; | ||
public float $parseTimeInMs; | ||
|
||
public static string $sourceDirectory = '_data'; | ||
|
||
public function __construct(string $key) | ||
{ | ||
$this->timeStart = microtime(true); | ||
$this->key = $key; | ||
|
||
parent::__construct(); | ||
} | ||
|
||
public function getCollection(): DataCollection | ||
{ | ||
$this->parseTimeInMs = round((microtime(true) - $this->timeStart) * 1000, 2); | ||
unset($this->timeStart); | ||
|
||
return $this; | ||
} | ||
|
||
public function getMarkdownFiles(): array | ||
{ | ||
return glob(Hyde::path( | ||
static::$sourceDirectory.'/'.$this->key.'/*'.MarkdownDocument::$fileExtension | ||
)); | ||
} | ||
|
||
/** | ||
* Get a collection of Markdown documents in the _data/<$key> directory. | ||
* Each Markdown file will be parsed into a MarkdownDocument with front matter. | ||
* | ||
* @param string $key for a subdirectory of the _data directory | ||
* @return DataCollection<\Hyde\Framework\Models\MarkdownDocument> | ||
*/ | ||
public static function markdown(string $key): DataCollection | ||
{ | ||
$collection = new DataCollection($key); | ||
foreach ($collection->getMarkdownFiles() as $file) { | ||
if (! str_starts_with(basename($file), '_')) { | ||
$collection->push( | ||
(new MarkdownFileService($file))->get() | ||
); | ||
} | ||
} | ||
|
||
return $collection->getCollection(); | ||
} | ||
} |
29 changes: 29 additions & 0 deletions
29
packages/framework/src/Modules/DataCollections/DataCollectionServiceProvider.php
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
<?php | ||
|
||
namespace Hyde\Framework\Modules\DataCollections; | ||
|
||
use Hyde\Framework\Hyde; | ||
use Illuminate\Foundation\AliasLoader; | ||
use Illuminate\Support\ServiceProvider; | ||
|
||
/** | ||
* @see \Hyde\Framework\Testing\Modules\DataCollections\DataCollectionTest\DataCollectionTest | ||
*/ | ||
class DataCollectionServiceProvider extends ServiceProvider | ||
{ | ||
public function register() | ||
{ | ||
// Register the class alias | ||
AliasLoader::getInstance()->alias( | ||
'MarkdownCollection', Facades\MarkdownCollection::class | ||
); | ||
} | ||
|
||
public function boot() | ||
{ | ||
// Create the _data directory if it doesn't exist | ||
if (! is_dir(Hyde::path('_data'))) { | ||
mkdir(Hyde::path('_data')); | ||
} | ||
} | ||
} |
16 changes: 16 additions & 0 deletions
16
packages/framework/src/Modules/DataCollections/Facades/MarkdownCollection.php
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
<?php | ||
|
||
namespace Hyde\Framework\Modules\DataCollections\Facades; | ||
|
||
use Hyde\Framework\Modules\DataCollections\DataCollection; | ||
|
||
/** | ||
* @see \Hyde\Framework\Testing\Modules\DataCollections\DataCollectionTest\DataCollectionTest | ||
*/ | ||
class MarkdownCollection | ||
{ | ||
public static function get(string $collectionKey): DataCollection | ||
{ | ||
return DataCollection::markdown($collectionKey); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,10 @@ | ||
# Hyde Modules | ||
|
||
This directory contains self-contained code modules, | ||
that may eventually be extracted into packages. | ||
that may eventually be extracted into packages. | ||
|
||
They may also be merged into the Hyde core. | ||
|
||
As these modules may be experimental, | ||
the namespaces used may be changed without notice | ||
as per the current 0.x semantic versioning range. |
176 changes: 176 additions & 0 deletions
176
.../Hyde/Framework/Testing/Modules/DataCollections/DataCollectionTest/DataCollectionTest.php
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,176 @@ | ||
<?php | ||
|
||
namespace Hyde\Framework\Testing\Modules\DataCollections\DataCollectionTest; | ||
|
||
use Hyde\Framework\Hyde; | ||
use Hyde\Framework\Models\MarkdownDocument; | ||
use Hyde\Framework\Modules\DataCollections\DataCollection; | ||
use Hyde\Framework\Modules\DataCollections\DataCollectionServiceProvider; | ||
use Hyde\Framework\Modules\DataCollections\Facades\MarkdownCollection; | ||
use Hyde\Testing\TestCase; | ||
use Illuminate\Foundation\AliasLoader; | ||
use Illuminate\Support\Collection; | ||
use Illuminate\Support\Facades\File; | ||
|
||
/** | ||
* @covers \Hyde\Framework\Modules\DataCollections\DataCollection | ||
* @covers \Hyde\Framework\Modules\DataCollections\DataCollectionServiceProvider | ||
* @covers \Hyde\Framework\Modules\DataCollections\Facades\MarkdownCollection | ||
*/ | ||
class DataCollectionTest extends TestCase | ||
{ | ||
// constructor creates new data collection instance | ||
public function test_constructor_creates_new_data_collection_instance() | ||
{ | ||
$class = new DataCollection('foo'); | ||
$this->assertInstanceOf(DataCollection::class, $class); | ||
$this->assertInstanceOf(Collection::class, $class); | ||
} | ||
|
||
public function test_constructor_sets_key() | ||
{ | ||
$class = new DataCollection('foo'); | ||
$this->assertEquals('foo', $class->key); | ||
} | ||
|
||
public function test_key_is_required() | ||
{ | ||
$this->expectException(\ArgumentCountError::class); | ||
new DataCollection(); | ||
} | ||
|
||
public function test_get_collection_method_returns_the_collection_instance() | ||
{ | ||
$class = new DataCollection('foo'); | ||
$this->assertSame($class, $class->getCollection()); | ||
} | ||
|
||
public function test_get_collection_method_sets_parse_time_in_ms() | ||
{ | ||
$class = new DataCollection('foo'); | ||
$class->getCollection(); | ||
$this->assertIsFloat($class->parseTimeInMs); | ||
} | ||
|
||
public function test_get_markdown_files_method_returns_empty_array_if_the_specified_directory_does_not_exist() | ||
{ | ||
$class = new DataCollection('foo'); | ||
$this->assertIsArray($class->getMarkdownFiles()); | ||
$this->assertEmpty($class->getMarkdownFiles()); | ||
} | ||
|
||
public function test_get_markdown_files_method_returns_empty_array_if_no_files_are_found_in_specified_directory() | ||
{ | ||
mkdir(Hyde::path('_data/foo')); | ||
$class = new DataCollection('foo'); | ||
$this->assertIsArray($class->getMarkdownFiles()); | ||
$this->assertEmpty($class->getMarkdownFiles()); | ||
rmdir(Hyde::path('_data/foo')); | ||
} | ||
|
||
public function test_get_markdown_files_method_returns_an_array_of_markdown_files_in_the_specified_directory() | ||
{ | ||
mkdir(Hyde::path('_data/foo')); | ||
touch(Hyde::path('_data/foo/foo.md')); | ||
touch(Hyde::path('_data/foo/bar.md')); | ||
|
||
$this->assertEquals([ | ||
Hyde::path('_data/foo/bar.md'), | ||
Hyde::path('_data/foo/foo.md'), | ||
], (new DataCollection('foo'))->getMarkdownFiles()); | ||
|
||
File::deleteDirectory(Hyde::path('_data/foo')); | ||
} | ||
|
||
public function test_get_markdown_files_method_does_not_include_files_in_subdirectories() | ||
{ | ||
mkdir(Hyde::path('_data/foo')); | ||
mkdir(Hyde::path('_data/foo/bar')); | ||
touch(Hyde::path('_data/foo/foo.md')); | ||
touch(Hyde::path('_data/foo/bar/bar.md')); | ||
$this->assertEquals([ | ||
Hyde::path('_data/foo/foo.md'), | ||
], (new DataCollection('foo'))->getMarkdownFiles()); | ||
File::deleteDirectory(Hyde::path('_data/foo')); | ||
} | ||
|
||
public function test_get_markdown_files_method_does_not_include_files_with_extensions_other_than_md() | ||
{ | ||
mkdir(Hyde::path('_data/foo')); | ||
touch(Hyde::path('_data/foo/foo.md')); | ||
touch(Hyde::path('_data/foo/bar.txt')); | ||
$this->assertEquals([ | ||
Hyde::path('_data/foo/foo.md'), | ||
], (new DataCollection('foo'))->getMarkdownFiles()); | ||
File::deleteDirectory(Hyde::path('_data/foo')); | ||
} | ||
|
||
public function test_static_markdown_helper_returns_new_data_collection_instance() | ||
{ | ||
$this->assertInstanceOf(DataCollection::class, DataCollection::markdown('foo')); | ||
} | ||
|
||
public function test_static_markdown_helper_discovers_and_parses_markdown_files_in_the_specified_directory() | ||
{ | ||
mkdir(Hyde::path('_data/foo')); | ||
touch(Hyde::path('_data/foo/foo.md')); | ||
touch(Hyde::path('_data/foo/bar.md')); | ||
|
||
$collection = DataCollection::markdown('foo'); | ||
|
||
$this->assertContainsOnlyInstancesOf(MarkdownDocument::class, $collection); | ||
|
||
File::deleteDirectory(Hyde::path('_data/foo')); | ||
} | ||
|
||
public function test_static_markdown_helper_ignores_files_starting_with_an_underscore() | ||
{ | ||
mkdir(Hyde::path('_data/foo')); | ||
touch(Hyde::path('_data/foo/foo.md')); | ||
touch(Hyde::path('_data/foo/_bar.md')); | ||
$this->assertCount(1, DataCollection::markdown('foo')); | ||
File::deleteDirectory(Hyde::path('_data/foo')); | ||
} | ||
|
||
public function test_markdown_facade_returns_same_result_as_static_markdown_helper() | ||
{ | ||
$expected = DataCollection::markdown('foo'); | ||
$actual = MarkdownCollection::get('foo'); | ||
unset($expected->parseTimeInMs); | ||
unset($actual->parseTimeInMs); | ||
$this->assertEquals($expected, $actual); | ||
} | ||
|
||
// Test DataCollectionServiceProvider registers the facade as an alias | ||
public function test_data_collection_service_provider_registers_the_facade_as_an_alias() | ||
{ | ||
$this->assertArrayHasKey('MarkdownCollection', AliasLoader::getInstance()->getAliases()); | ||
$this->assertContains(MarkdownCollection::class, AliasLoader::getInstance()->getAliases()); | ||
} | ||
|
||
public function test_data_collection_service_provider_creates_the__data_directory_if_it_does_not_exist() | ||
{ | ||
File::deleteDirectory(Hyde::path('_data')); | ||
$this->assertFileDoesNotExist(Hyde::path('_data')); | ||
|
||
(new DataCollectionServiceProvider($this->app))->boot(); | ||
|
||
$this->assertFileExists(Hyde::path('_data')); | ||
} | ||
|
||
public function test_class_has_static_source_directory_property() | ||
{ | ||
$this->assertEquals('_data', DataCollection::$sourceDirectory); | ||
} | ||
|
||
public function test_source_directory_can_be_changed() | ||
{ | ||
DataCollection::$sourceDirectory = 'foo'; | ||
mkdir(Hyde::path('foo/bar'), recursive: true); | ||
touch(Hyde::path('foo/bar/foo.md')); | ||
$this->assertEquals([ | ||
Hyde::path('foo/bar/foo.md'), | ||
], (new DataCollection('bar'))->getMarkdownFiles()); | ||
File::deleteDirectory(Hyde::path('foo')); | ||
} | ||
} |