Create a test to show that abstract parent classes break the model annotator
MODIFY
tests/TestCase/Annotator/ModelAnnotatorTest.php
tests/TestCase/Annotator/ModelAnnotatorTest.php
@@ -244,4 +244,31 @@ class ModelAnnotatorTest extends TestCase {
return $this->getMockBuilder(ModelAnnotator::class)->setMethods(['_storeFile'])->setConstructorArgs([$this->io, $params])->getMock();
}
+ /**
+ * @return void
+ */
+ public function testAnnotateProtectedParent()
+ {
+ $annotator = $this->_getAnnotatorMock([]);
+
+ $expectedContent = str_replace("\r\n", "\n", file_get_contents(TEST_FILES . 'Model/Table/BarBarsAbstractTable.php'));
+ $callback = function ($value) use ($expectedContent) {
+ $value = str_replace(["\r\n", "\r"], "\n", $value);
+ if ($value !== $expectedContent) {
+ $this->_displayDiff($expectedContent, $value);
+ }
+
+ return $value === $expectedContent;
+ };
+ $annotator->expects($this->once())
+ ->method('_storeFile')
+ ->with($this->anything(), $this->callback($callback));
+
+ $path = APP . 'Model/Table/BarBarsAbstractTable.php';
+ $annotator->annotate($path);
+
+ $output = (string)$this->out->output();
+
+ $this->assertTextContains(' -> 14 annotations added', $output);
+ }
}

MODIFY
tests/TestCase/Generator/Task/ModelTaskTest.php
tests/TestCase/Generator/Task/ModelTaskTest.php
@@ -30,6 +30,8 @@ class ModelTaskTest extends TestCase {
$this->assertCount(3, $result);
$expectedMap = [
+ 'Abstract' => '\App\Model\Table\AbstractTable::class',
+ 'BarBarsAbstract' => '\App\Model\Table\BarBarsAbstractTable::class',
'BarBars' => '\App\Model\Table\BarBarsTable::class',
'Callbacks' => '\App\Model\Table\CallbacksTable::class',
'Cars' => '\App\Model\Table\CarsTable::class',

MODIFY
tests/TestCase/Generator/Task/TableAssociationTaskTest.php
tests/TestCase/Generator/Task/TableAssociationTaskTest.php
@@ -30,6 +30,8 @@ class TableAssociationTaskTest extends TestCase {
$this->assertCount(4, $result);
$expectedMap = [
+ 'Abstract' => '\Cake\ORM\Association\BelongsTo::class',
+ 'BarBarsAbstract' => '\Cake\ORM\Association\BelongsTo::class',
'BarBars' => '\Cake\ORM\Association\BelongsTo::class',
'Callbacks' => '\Cake\ORM\Association\BelongsTo::class',
'Cars' => '\Cake\ORM\Association\BelongsTo::class',

ADD
tests/test_app/src/Model/Entity/BarBarsAbstract.php
+<?php
+namespace App\Model\Entity;
+
+use Cake\ORM\Entity;
+
+class BarBarsAbstract extends Entity {
+}

ADD
tests/test_app/src/Model/Table/AbstractTable.php
+<?php
+
+namespace App\Model\Table;
+
+use Cake\ORM\Table;
+
+/**
+ * Class AbstractTable
+ */
+abstract class AbstractTable extends Table
+{
+ /**
+ * @param array $config
+ * @return void
+ */
+ public function initialize(array $config)
+ {
+ parent::initialize($config);
+
+ $this->addBehavior('Timestamp');
+ }
+}

ADD
tests/test_app/src/Model/Table/BarBarsAbstractTable.php
+<?php
+namespace App\Model\Table;
+
+use Cake\ORM\Table;
+
+class BarBarsAbstractTable extends AbstractTable {
+
+ /**
+ * @param array $config
+ * @return void
+ */
+ public function initialize(array $config) {
+ parent::initialize($config);
+
+ $this->setTable('bar_bars');
+ $this->belongsTo('Foo');
+ $this->belongsToMany('Houses', [
+ 'className' => 'Awesome.Houses',
+ 'through' => 'Awesome.Windows',
+ ]);
+ $this->addBehavior('Tools.Confirmable');
+ $this->addBehavior('MyNamespace/MyPlugin.My');
+ }
+
+}

ADD
tests/test_files/Model/Table/BarBarsAbstractTable.php
+<?php
+namespace App\Model\Table;
+
+use Cake\ORM\Table;
+
+/**
+ * @property \App\Model\Table\FooTable&\Cake\ORM\Association\BelongsTo $Foo
+ * @property \Awesome\Model\Table\HousesTable&\Cake\ORM\Association\BelongsToMany $Houses
+ * @property \Awesome\Model\Table\WindowsTable&\Cake\ORM\Association\HasMany $Windows
+ *
+ * @method \App\Model\Entity\BarBarsAbstract get($primaryKey, $options = [])
+ * @method \App\Model\Entity\BarBarsAbstract newEntity($data = null, array $options = [])
+ * @method \App\Model\Entity\BarBarsAbstract[] newEntities(array $data, array $options = [])
+ * @method \App\Model\Entity\BarBarsAbstract|false save(\Cake\Datasource\EntityInterface $entity, $options = [])
+ * @method \App\Model\Entity\BarBarsAbstract saveOrFail(\Cake\Datasource\EntityInterface $entity, $options = [])
+ * @method \App\Model\Entity\BarBarsAbstract patchEntity(\Cake\Datasource\EntityInterface $entity, array $data, array $options = [])
+ * @method \App\Model\Entity\BarBarsAbstract[] patchEntities($entities, array $data, array $options = [])
+ * @method \App\Model\Entity\BarBarsAbstract findOrCreate($search, callable $callback = null, $options = [])
+ *
+ * @mixin \Cake\ORM\Behavior\TimestampBehavior
+ * @mixin \Tools\Model\Behavior\ConfirmableBehavior
+ * @mixin \MyNamespace\MyPlugin\Model\Behavior\MyBehavior
+ */
+class BarBarsAbstractTable extends AbstractTable {
+
+ /**
+ * @param array $config
+ * @return void
+ */
+ public function initialize(array $config) {
+ parent::initialize($config);
+
+ $this->setTable('bar_bars');
+ $this->belongsTo('Foo');
+ $this->belongsToMany('Houses', [
+ 'className' => 'Awesome.Houses',
+ 'through' => 'Awesome.Windows',
+ ]);
+ $this->addBehavior('Tools.Confirmable');
+ $this->addBehavior('MyNamespace/MyPlugin.My');
+ }
+
+}

MODIFY
tests/test_files/meta/phpstorm/.meta.php
tests/test_files/meta/phpstorm/.meta.php
@@ -54,6 +54,8 @@ namespace PHPSTORM_META {
override(
\Cake\Datasource\ModelAwareTrait::loadModel(0),
map([
+ 'Abstract' => \App\Model\Table\AbstractTable::class,
+ 'BarBarsAbstract' => \App\Model\Table\BarBarsAbstractTable::class,
'BarBars' => \App\Model\Table\BarBarsTable::class,
'Callbacks' => \App\Model\Table\CallbacksTable::class,
'Cars' => \App\Model\Table\CarsTable::class,
@@ -90,6 +92,8 @@ namespace PHPSTORM_META {
override(
\Cake\ORM\Locator\LocatorInterface::get(0),
map([
+ 'Abstract' => \App\Model\Table\AbstractTable::class,
+ 'BarBarsAbstract' => \App\Model\Table\BarBarsAbstractTable::class,
'BarBars' => \App\Model\Table\BarBarsTable::class,
'Callbacks' => \App\Model\Table\CallbacksTable::class,
'Cars' => \App\Model\Table\CarsTable::class,
@@ -119,6 +123,8 @@ namespace PHPSTORM_META {
override(
\Cake\ORM\Table::belongToMany(0),
map([
+ 'Abstract' => \Cake\ORM\Association\BelongsToMany::class,
+ 'BarBarsAbstract' => \Cake\ORM\Association\BelongsToMany::class,
'BarBars' => \Cake\ORM\Association\BelongsToMany::class,
'Callbacks' => \Cake\ORM\Association\BelongsToMany::class,
'Cars' => \Cake\ORM\Association\BelongsToMany::class,
@@ -137,6 +143,8 @@ namespace PHPSTORM_META {
override(
\Cake\ORM\Table::belongsTo(0),
map([
+ 'Abstract' => \Cake\ORM\Association\BelongsTo::class,
+ 'BarBarsAbstract' => \Cake\ORM\Association\BelongsTo::class,
'BarBars' => \Cake\ORM\Association\BelongsTo::class,
'Callbacks' => \Cake\ORM\Association\BelongsTo::class,
'Cars' => \Cake\ORM\Association\BelongsTo::class,
@@ -164,6 +172,8 @@ namespace PHPSTORM_META {
override(
\Cake\ORM\Table::hasMany(0),
map([
+ 'Abstract' => \Cake\ORM\Association\HasMany::class,
+ 'BarBarsAbstract' => \Cake\ORM\Association\HasMany::class,
'BarBars' => \Cake\ORM\Association\HasMany::class,
'Callbacks' => \Cake\ORM\Association\HasMany::class,
'Cars' => \Cake\ORM\Association\HasMany::class,
@@ -182,6 +192,8 @@ namespace PHPSTORM_META {
override(
\Cake\ORM\Table::hasOne(0),
map([
+ 'Abstract' => \Cake\ORM\Association\HasOne::class,
+ 'BarBarsAbstract' => \Cake\ORM\Association\HasOne::class,
'BarBars' => \Cake\ORM\Association\HasOne::class,
'Callbacks' => \Cake\ORM\Association\HasOne::class,
'Cars' => \Cake\ORM\Association\HasOne::class,
@@ -200,6 +212,8 @@ namespace PHPSTORM_META {
override(
\Cake\ORM\TableRegistry::get(0),
map([
+ 'Abstract' => \App\Model\Table\AbstractTable::class,
+ 'BarBarsAbstract' => \App\Model\Table\BarBarsAbstractTable::class,
'BarBars' => \App\Model\Table\BarBarsTable::class,
'Callbacks' => \App\Model\Table\CallbacksTable::class,
'Cars' => \App\Model\Table\CarsTable::class,

Create a test to show that abstract parent classes break the model annotator