Skip to content

Commit b1a9ed0

Browse files
author
Guido Contreras Woda
committed
Tests and a found bugfix: laravel sorts alphabetical to deduce many-to-many join tables
1 parent 4e3748b commit b1a9ed0

File tree

2 files changed

+129
-2
lines changed

2 files changed

+129
-2
lines changed

src/Configuration/LaravelNamingStrategy.php

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,14 @@ public function joinColumnName($propertyName)
7373
*/
7474
public function joinTableName($sourceEntity, $targetEntity, $propertyName = null)
7575
{
76-
return $this->classToFieldName($sourceEntity) . '_' . $this->classToFieldName($targetEntity);
76+
$names = [
77+
$this->classToFieldName($sourceEntity),
78+
$this->classToFieldName($targetEntity)
79+
];
80+
81+
sort($names);
82+
83+
return implode('_', $names);
7784
}
7885

7986
/**
@@ -103,7 +110,7 @@ private function classToFieldName($className)
103110
*
104111
* @return string
105112
*/
106-
function embeddedFieldToColumnName($propertyName, $embeddedColumnName, $className = null, $embeddedClassName = null)
113+
public function embeddedFieldToColumnName($propertyName, $embeddedColumnName, $className = null, $embeddedClassName = null)
107114
{
108115
return $propertyName.'_'.$embeddedColumnName;
109116
}
Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
1+
<?php namespace Tests\Configuration;
2+
3+
use Illuminate\Support\Str;
4+
use Mitch\LaravelDoctrine\Configuration\LaravelNamingStrategy;
5+
6+
class LaravelNamingStrategyTest extends \PHPUnit_Framework_TestCase
7+
{
8+
/**
9+
* @type LaravelNamingStrategy
10+
*/
11+
private $laravelNamingStrategy;
12+
13+
public function setUp()
14+
{
15+
// Mocking Str would be overkill
16+
$this->laravelNamingStrategy = new LaravelNamingStrategy(new Str());
17+
}
18+
19+
public function testProperTableName()
20+
{
21+
// Singular namespaced StudlyCase class
22+
$className = 'Acme\\ClassName';
23+
24+
$tableName = $this->laravelNamingStrategy->classToTableName($className);
25+
26+
// Plural, snake_cased table name
27+
$this->assertEquals('class_names', $tableName);
28+
}
29+
30+
public function testProperColumnName()
31+
{
32+
// Columns derive from snakeCased fields
33+
$field = 'createdAt';
34+
35+
$columnName = $this->laravelNamingStrategy->propertyToColumnName($field);
36+
37+
// And columns are just the snake_cased field
38+
$this->assertEquals('created_at', $columnName);
39+
}
40+
41+
public function testProperColumnNameWithClassName()
42+
{
43+
// Columns derive from snakeCased fields
44+
$field = 'createdAt';
45+
46+
// Singular namespaced StudlyCase class
47+
$className = 'Acme\\ClassName';
48+
49+
$columnName = $this->laravelNamingStrategy->propertyToColumnName($field, $className);
50+
51+
// Class name shouldn't affect how the column is called
52+
$this->assertEquals('created_at', $columnName);
53+
}
54+
55+
public function testEmbeddedColumnName()
56+
{
57+
// Laravel doesn't have embeddeds
58+
$embeddedField = 'address';
59+
$field = 'street1';
60+
61+
$columnName = $this->laravelNamingStrategy->embeddedFieldToColumnName($embeddedField, $field);
62+
63+
// So this is just like Doctrine's default naming strategy
64+
$this->assertEquals('address_street1', $columnName);
65+
}
66+
67+
public function testReferenceColumn()
68+
{
69+
// Laravel's convention is just 'id', like the default Doctrine
70+
$columnName = $this->laravelNamingStrategy->referenceColumnName();
71+
72+
$this->assertEquals('id', $columnName);
73+
}
74+
75+
public function testJoinColumnName()
76+
{
77+
// Given a User -> belongsTo -> Group
78+
$field = 'group';
79+
80+
$columnName = $this->laravelNamingStrategy->joinColumnName($field);
81+
82+
// We expect to have a group_id in the users table
83+
$this->assertEquals('group_id', $columnName);
84+
}
85+
86+
public function testBelongsToManyJoinTable()
87+
{
88+
// Laravel doesn't do as Doctrine's default here
89+
$sourceModel = 'Acme\\ClassName';
90+
91+
// We don't care about "source" or "target"
92+
$targetModel = 'Acme\\AnotherClass';
93+
94+
// We should have it sorted by alphabetical order
95+
$tableName = $this->laravelNamingStrategy->joinTableName($sourceModel, $targetModel);
96+
$this->assertEquals('another_class_class_name', $tableName);
97+
98+
// Let's test swapping parameters, just in case...
99+
$tableName = $this->laravelNamingStrategy->joinTableName($targetModel, $sourceModel);
100+
$this->assertEquals('another_class_class_name', $tableName);
101+
}
102+
103+
public function testJoinKeyColumnName()
104+
{
105+
// This case is similar to Doctrine's default as well
106+
$className = 'Acme\\Foo';
107+
108+
// If no reference name is given, we use 'id'
109+
$columnName = $this->laravelNamingStrategy->joinKeyColumnName($className);
110+
111+
// And expect singular_snake_id column
112+
$this->assertEquals('foo_id', $columnName);
113+
114+
// Given a reference name
115+
$columnName = $this->laravelNamingStrategy->joinKeyColumnName($className, 'reference');
116+
117+
// Same thing, but with that reference instead of 'id'
118+
$this->assertEquals('foo_reference', $columnName);
119+
}
120+
}

0 commit comments

Comments
 (0)