From 3df09c1ee04e1130d9ba1d012ac89354ec4c33ba Mon Sep 17 00:00:00 2001 From: Bert van Hoekelen Date: Thu, 6 Jul 2017 21:59:00 +0200 Subject: [PATCH 1/2] Clear Carbon mock in tear down. --- src/Illuminate/Foundation/Testing/TestCase.php | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/Illuminate/Foundation/Testing/TestCase.php b/src/Illuminate/Foundation/Testing/TestCase.php index 5c49caad1f57..c08a170da838 100755 --- a/src/Illuminate/Foundation/Testing/TestCase.php +++ b/src/Illuminate/Foundation/Testing/TestCase.php @@ -3,6 +3,7 @@ namespace Illuminate\Foundation\Testing; use Mockery; +use Carbon\Carbon; use Illuminate\Support\Facades\Facade; use Illuminate\Database\Eloquent\Model; use Illuminate\Console\Application as Artisan; @@ -149,6 +150,10 @@ protected function tearDown() Mockery::close(); } + if (class_exists(Carbon::class)) { + Carbon::setTestNow(); + } + $this->afterApplicationCreatedCallbacks = []; $this->beforeApplicationDestroyedCallbacks = []; From 06f01cf50f5060bd23b16d8c651869c97a43f139 Mon Sep 17 00:00:00 2001 From: Bert van Hoekelen Date: Thu, 20 Jul 2017 00:03:57 +0200 Subject: [PATCH 2/2] Make pivot model instantiable. --- src/Illuminate/Database/Eloquent/Model.php | 2 +- .../Eloquent/Relations/MorphToMany.php | 2 +- .../Database/Eloquent/Relations/Pivot.php | 26 +++++++++++++------ .../DatabaseEloquentBelongsToManyTest.php | 5 ++-- tests/Database/DatabaseEloquentPivotTest.php | 26 +++++++++++-------- 5 files changed, 38 insertions(+), 23 deletions(-) diff --git a/src/Illuminate/Database/Eloquent/Model.php b/src/Illuminate/Database/Eloquent/Model.php index e4097287722c..4321504ac3c5 100644 --- a/src/Illuminate/Database/Eloquent/Model.php +++ b/src/Illuminate/Database/Eloquent/Model.php @@ -887,7 +887,7 @@ public function newCollection(array $models = []) public function newPivot(Model $parent, array $attributes, $table, $exists, $using = null) { return $using ? $using::fromRawAttributes($parent, $attributes, $table, $exists) - : new Pivot($parent, $attributes, $table, $exists); + : (new Pivot())->fromAttributes($parent, $attributes, $table, $exists); } /** diff --git a/src/Illuminate/Database/Eloquent/Relations/MorphToMany.php b/src/Illuminate/Database/Eloquent/Relations/MorphToMany.php index 9d14c4471dc1..a40a5820ec72 100644 --- a/src/Illuminate/Database/Eloquent/Relations/MorphToMany.php +++ b/src/Illuminate/Database/Eloquent/Relations/MorphToMany.php @@ -137,7 +137,7 @@ public function newPivot(array $attributes = [], $exists = false) $using = $this->using; $pivot = $using ? $using::fromRawAttributes($this->parent, $attributes, $this->table, $exists) - : new MorphPivot($this->parent, $attributes, $this->table, $exists); + : (new MorphPivot())->fromAttributes($this->parent, $attributes, $this->table, $exists); $pivot->setPivotKeys($this->foreignPivotKey, $this->relatedPivotKey) ->setMorphType($this->morphType) diff --git a/src/Illuminate/Database/Eloquent/Relations/Pivot.php b/src/Illuminate/Database/Eloquent/Relations/Pivot.php index 5b817c423d91..2f6438e685c8 100755 --- a/src/Illuminate/Database/Eloquent/Relations/Pivot.php +++ b/src/Illuminate/Database/Eloquent/Relations/Pivot.php @@ -2,6 +2,7 @@ namespace Illuminate\Database\Eloquent\Relations; +use Illuminate\Support\Str; use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Builder; @@ -42,19 +43,17 @@ class Pivot extends Model * @param array $attributes * @param string $table * @param bool $exists - * @return void + * @return $this */ - public function __construct(Model $parent, $attributes, $table, $exists = false) + public function fromAttributes(Model $parent, $attributes, $table, $exists = false) { - parent::__construct(); - // The pivot model is a "dynamic" model since we will set the tables dynamically // for the instance. This allows it work for any intermediate tables for the // many to many relationship that are defined by this developer's classes. $this->setConnection($parent->getConnectionName()) - ->setTable($table) - ->forceFill($attributes) - ->syncOriginal(); + ->setTable($table) + ->forceFill($attributes) + ->syncOriginal(); // We store off the parent instance so we will access the timestamp column names // for the model, since the pivot model timestamps aren't easily configurable @@ -64,6 +63,8 @@ public function __construct(Model $parent, $attributes, $table, $exists = false) $this->exists = $exists; $this->timestamps = $this->hasTimestampAttributes(); + + return $this; } /** @@ -77,7 +78,7 @@ public function __construct(Model $parent, $attributes, $table, $exists = false) */ public static function fromRawAttributes(Model $parent, $attributes, $table, $exists = false) { - $instance = new static($parent, $attributes, $table, $exists); + $instance = (new static())->fromAttributes($parent, $attributes, $table, $exists); $instance->setRawAttributes($attributes, true); @@ -195,4 +196,13 @@ public function getUpdatedAtColumn() { return $this->pivotParent->getUpdatedAtColumn(); } + + public function getTable() + { + if (! isset($this->table)) { + return str_replace('\\', '', Str::snake(Str::singular(class_basename($this)))); + } + + return $this->table; + } } diff --git a/tests/Database/DatabaseEloquentBelongsToManyTest.php b/tests/Database/DatabaseEloquentBelongsToManyTest.php index 9f7dfcf96162..3ec793dacb2d 100755 --- a/tests/Database/DatabaseEloquentBelongsToManyTest.php +++ b/tests/Database/DatabaseEloquentBelongsToManyTest.php @@ -721,9 +721,10 @@ public function getRelationArguments() $related->shouldReceive('getTable')->andReturn('roles'); $related->shouldReceive('getKeyName')->andReturn('id'); $related->shouldReceive('newPivot')->andReturnUsing(function () { - $reflector = new ReflectionClass('Illuminate\Database\Eloquent\Relations\Pivot'); + $model = new \Illuminate\Database\Eloquent\Relations\Pivot(); + $reflector = new ReflectionClass($model); - return $reflector->newInstanceArgs(func_get_args()); + return $reflector->getMethod('fromAttributes')->invokeArgs($model, func_get_args()); }); $builder->shouldReceive('join')->once()->with('user_role', 'roles.id', '=', 'user_role.role_id'); diff --git a/tests/Database/DatabaseEloquentPivotTest.php b/tests/Database/DatabaseEloquentPivotTest.php index 45b5e25cd6f1..7d841aa5c78e 100755 --- a/tests/Database/DatabaseEloquentPivotTest.php +++ b/tests/Database/DatabaseEloquentPivotTest.php @@ -19,7 +19,7 @@ public function testPropertiesAreSetCorrectly() $parent->shouldReceive('getConnectionName')->twice()->andReturn('connection'); $parent->getConnection()->getQueryGrammar()->shouldReceive('getDateFormat')->andReturn('Y-m-d H:i:s'); $parent->setDateFormat('Y-m-d H:i:s'); - $pivot = new Pivot($parent, ['foo' => 'bar', 'created_at' => '2015-09-12'], 'table', true); + $pivot = (new Pivot())->fromAttributes($parent, ['foo' => 'bar', 'created_at' => '2015-09-12'], 'table', true); $this->assertEquals(['foo' => 'bar', 'created_at' => '2015-09-12 00:00:00'], $pivot->getAttributes()); $this->assertEquals('connection', $pivot->getConnectionName()); @@ -32,7 +32,7 @@ public function testMutatorsAreCalledFromConstructor() $parent = m::mock('Illuminate\Database\Eloquent\Model[getConnectionName]'); $parent->shouldReceive('getConnectionName')->once()->andReturn('connection'); - $pivot = new DatabaseEloquentPivotTestMutatorStub($parent, ['foo' => 'bar'], 'table', true); + $pivot = (new DatabaseEloquentPivotTestMutatorStub())->fromAttributes($parent, ['foo' => 'bar'], 'table', true); $this->assertTrue($pivot->getMutatorCalled()); } @@ -51,7 +51,7 @@ public function testPropertiesUnchangedAreNotDirty() { $parent = m::mock('Illuminate\Database\Eloquent\Model[getConnectionName]'); $parent->shouldReceive('getConnectionName')->once()->andReturn('connection'); - $pivot = new Pivot($parent, ['foo' => 'bar', 'shimy' => 'shake'], 'table', true); + $pivot = (new Pivot())->fromAttributes($parent, ['foo' => 'bar', 'shimy' => 'shake'], 'table', true); $this->assertEquals([], $pivot->getDirty()); } @@ -60,7 +60,7 @@ public function testPropertiesChangedAreDirty() { $parent = m::mock('Illuminate\Database\Eloquent\Model[getConnectionName]'); $parent->shouldReceive('getConnectionName')->once()->andReturn('connection'); - $pivot = new Pivot($parent, ['foo' => 'bar', 'shimy' => 'shake'], 'table', true); + $pivot = (new Pivot())->fromAttributes($parent, ['foo' => 'bar', 'shimy' => 'shake'], 'table', true); $pivot->shimy = 'changed'; $this->assertEquals(['shimy' => 'changed'], $pivot->getDirty()); @@ -71,10 +71,10 @@ public function testTimestampPropertyIsSetIfCreatedAtInAttributes() $parent = m::mock('Illuminate\Database\Eloquent\Model[getConnectionName,getDates]'); $parent->shouldReceive('getConnectionName')->andReturn('connection'); $parent->shouldReceive('getDates')->andReturn([]); - $pivot = new DatabaseEloquentPivotTestDateStub($parent, ['foo' => 'bar', 'created_at' => 'foo'], 'table'); + $pivot = (new DatabaseEloquentPivotTestDateStub())->fromAttributes($parent, ['foo' => 'bar', 'created_at' => 'foo'], 'table'); $this->assertTrue($pivot->timestamps); - $pivot = new DatabaseEloquentPivotTestDateStub($parent, ['foo' => 'bar'], 'table'); + $pivot = (new DatabaseEloquentPivotTestDateStub())->fromAttributes($parent, ['foo' => 'bar'], 'table'); $this->assertFalse($pivot->timestamps); } @@ -82,7 +82,7 @@ public function testKeysCanBeSetProperly() { $parent = m::mock('Illuminate\Database\Eloquent\Model[getConnectionName]'); $parent->shouldReceive('getConnectionName')->once()->andReturn('connection'); - $pivot = new Pivot($parent, ['foo' => 'bar'], 'table'); + $pivot = (new Pivot())->fromAttributes($parent, ['foo' => 'bar'], 'table'); $pivot->setPivotKeys('foreign', 'other'); $this->assertEquals('foreign', $pivot->getForeignKey()); @@ -91,10 +91,7 @@ public function testKeysCanBeSetProperly() public function testDeleteMethodDeletesModelByKeys() { - $parent = m::mock('Illuminate\Database\Eloquent\Model[getConnectionName]'); - $parent->guard([]); - $parent->shouldReceive('getConnectionName')->once()->andReturn('connection'); - $pivot = $this->getMockBuilder('Illuminate\Database\Eloquent\Relations\Pivot')->setMethods(['newQuery'])->setConstructorArgs([$parent, ['foo' => 'bar'], 'table'])->getMock(); + $pivot = $this->getMockBuilder('Illuminate\Database\Eloquent\Relations\Pivot')->setMethods(['newQuery'])->getMock(); $pivot->setPivotKeys('foreign', 'other'); $pivot->foreign = 'foreign.value'; $pivot->other = 'other.value'; @@ -105,6 +102,13 @@ public function testDeleteMethodDeletesModelByKeys() $this->assertTrue($pivot->delete()); } + + public function testPivotModelTableNameIsSingular() + { + $pivot = new Pivot(); + + $this->assertEquals('pivot', $pivot->getTable()); + } } class DatabaseEloquentPivotTestDateStub extends \Illuminate\Database\Eloquent\Relations\Pivot