diff --git a/composer.json b/composer.json index f500e33..6dae92f 100755 --- a/composer.json +++ b/composer.json @@ -38,7 +38,7 @@ } }, "scripts": { - "pest": "vendor/bin/pest", + "test": "vendor/bin/phpunit", "fix-style": "vendor/bin/php-cs-fixer fix", "check-style": "vendor/bin/php-cs-fixer fix --diff --dry-run" }, diff --git a/src/Bits.php b/src/Bits.php index c5d8ff8..729a4e8 100644 --- a/src/Bits.php +++ b/src/Bits.php @@ -49,7 +49,8 @@ public static function castUsing(array $arguments): BitsCast { return match (reset($arguments)) { 'sonyflake', 'sonyflakes' => new BitsCast(app(MakesSonyflakes::class)), - default => new BitsCast(app(MakesSnowflakes::class)), + 'snowflake', 'snowflakes' => new BitsCast(app(MakesSnowflakes::class)), + default => new BitsCast(app(MakesBits::class)), }; } diff --git a/src/Database/HasSnowflakes.php b/src/Database/HasSnowflakes.php index 5ca4546..6594d11 100644 --- a/src/Database/HasSnowflakes.php +++ b/src/Database/HasSnowflakes.php @@ -2,12 +2,18 @@ namespace Glhd\Bits\Database; -use Glhd\Bits\Snowflake; +use Glhd\Bits\Bits; +use Glhd\Bits\Contracts\MakesBits; +/** + * @mixin \Illuminate\Database\Eloquent\Model + */ trait HasSnowflakes { protected function initializeHasSnowflakes(): void { + $this->mergeCasts(array_fill_keys($this->uniqueIds(), Bits::class)); + if (property_exists($this, 'usesUniqueIds')) { $this->usesUniqueIds = true; return; @@ -23,7 +29,7 @@ public function uniqueIds() public function newUniqueId() { - return Snowflake::make()->id(); + return app(MakesBits::class)->make()->id(); } public function getIncrementing() diff --git a/tests/Feature/SnowflakeCastTest.php b/tests/Feature/SnowflakeCastTest.php index 6a1aca6..d90326b 100644 --- a/tests/Feature/SnowflakeCastTest.php +++ b/tests/Feature/SnowflakeCastTest.php @@ -8,7 +8,9 @@ use Glhd\Bits\Tests\TestCase; use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Schema\Blueprint; +use Illuminate\Foundation\Application; use Illuminate\Support\Facades\Schema; +use PHPUnit\Framework\Attributes\DataProvider; class SnowflakeCastTest extends TestCase { @@ -23,30 +25,57 @@ protected function setUp(): void $table->string('label')->nullable(); $table->timestamps(); }); + + Schema::create('test_casts_method_models', function(Blueprint $table) { + $table->unsignedBigInteger('id')->primary(); + $table->string('label')->nullable(); + $table->timestamps(); + }); + + Schema::create('test_automatic_casts_models', function(Blueprint $table) { + $table->unsignedBigInteger('id')->primary(); + $table->string('label')->nullable(); + $table->timestamps(); + }); } - - public function test_it_casts_attributes(): void + + /** @param class-string $class */ + #[DataProvider('modelClassProvider')] + public function test_it_casts_attributes(string $class): void { - $model1 = TestModel::create(); - $model2 = TestModel::create(); + $model1 = $class::create(); + $model2 = $class::create(); $this->assertInstanceOf(Snowflake::class, $model1->id); $this->assertInstanceOf(Snowflake::class, $model2->id); $this->assertTrue($model2->id->id() > $model1->id->id()); } - - public function test_you_can_set_id_manually(): void + + /** @param class-string $class */ + #[DataProvider('modelClassProvider')] + public function test_you_can_set_id_manually(string $class): void { - $model = TestModel::forceCreate(['id' => 123]); + $model = $class::forceCreate(['id' => 123]); $this->assertEquals(123, $model->id->id()); - $model = TestModel::find(123); + $model = $class::find(123); $this->assertEquals(123, $model->id->id()); - $this->assertEquals(1, TestModel::count()); + $this->assertEquals(1, $class::count()); + } + + public static function modelClassProvider(): array + { + $with_casts_method = (int) Application::VERSION >= 11; + + return array_filter([ + 'casts property' => [TestModel::class], + 'casts method' => $with_casts_method ? [TestCastsMethodModel::class] : null, + 'automatic casting' => [TestAutomaticCastsModel::class], + ]); } } @@ -58,3 +87,20 @@ class TestModel extends Model 'id' => Snowflake::class, ]; } + +class TestCastsMethodModel extends Model +{ + use HasSnowflakes; + + protected function casts() + { + return [ + 'id' => Snowflake::class, + ]; + } +} + +class TestAutomaticCastsModel extends Model +{ + use HasSnowflakes; +} diff --git a/tests/Feature/SonyflakeCastTest.php b/tests/Feature/SonyflakeCastTest.php new file mode 100644 index 0000000..e50845c --- /dev/null +++ b/tests/Feature/SonyflakeCastTest.php @@ -0,0 +1,109 @@ +unsignedBigInteger('id')->primary(); + $table->string('label')->nullable(); + $table->timestamps(); + }); + + Schema::create('test_sonyflake_casts_method_models', function(Blueprint $table) { + $table->unsignedBigInteger('id')->primary(); + $table->string('label')->nullable(); + $table->timestamps(); + }); + + Schema::create('test_sonyflake_automatic_casts_models', function(Blueprint $table) { + $table->unsignedBigInteger('id')->primary(); + $table->string('label')->nullable(); + $table->timestamps(); + }); + } + + /** @param class-string $class */ + #[DataProvider('modelClassProvider')] + #[DefineEnvironment('usesSonyflakes')] + public function test_it_casts_attributes(string $class): void + { + $model1 = $class::create(); + $model2 = $class::create(); + + $this->assertInstanceOf(Sonyflake::class, $model1->id); + $this->assertInstanceOf(Sonyflake::class, $model2->id); + + $this->assertTrue($model2->id->id() > $model1->id->id()); + } + + /** @param class-string $class */ + #[DataProvider('modelClassProvider')] + #[DefineEnvironment('usesSonyflakes')] + public function test_you_can_set_id_manually(string $class): void + { + $model = $class::forceCreate(['id' => 123]); + + $this->assertEquals(123, $model->id->id()); + + $model = $class::find(123); + + $this->assertEquals(123, $model->id->id()); + + $this->assertEquals(1, $class::count()); + } + + public static function modelClassProvider(): array + { + $with_casts_method = (int) Application::VERSION >= 11; + + return [ + 'casts property' => [TestSonyflakeModel::class], + 'casts method' => $with_casts_method ? [TestSonyflakeCastsMethodModel::class] : null, + 'automatic casting' => [TestSonyflakeAutomaticCastsModel::class], + ]; + } +} + +class TestSonyflakeModel extends Model +{ + use HasSnowflakes; + + protected $casts = [ + 'id' => Sonyflake::class, + ]; +} + +class TestSonyflakeCastsMethodModel extends Model +{ + use HasSnowflakes; + + protected function casts() + { + return [ + 'id' => Sonyflake::class, + ]; + } +} + +class TestSonyflakeAutomaticCastsModel extends Model +{ + use HasSnowflakes; +} diff --git a/tests/TestCase.php b/tests/TestCase.php index d046886..5f641c3 100644 --- a/tests/TestCase.php +++ b/tests/TestCase.php @@ -46,4 +46,9 @@ protected function getApplicationTimezone($app) { return 'America/New_York'; } + + protected function usesSonyflakes($app): void + { + $app['config']->set('bits.format', 'sonyflake'); + } }