ModelGeneratorTest.php 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267
  1. <?php
  2. namespace yiiunit\gii\generators;
  3. use yii\gii\generators\model\Generator as ModelGenerator;
  4. use yiiunit\gii\GiiTestCase;
  5. /**
  6. * ModelGeneratorTest checks that Gii model generator produces valid results
  7. * @group gii
  8. */
  9. class ModelGeneratorTest extends GiiTestCase
  10. {
  11. public function testAll()
  12. {
  13. $generator = new ModelGenerator();
  14. $generator->template = 'default';
  15. $generator->tableName = '*';
  16. $generator->queryNs = 'application\models';
  17. $valid = $generator->validate();
  18. $this->assertFalse($valid);
  19. $this->assertEquals($generator->getFirstError('queryNs'), 'Namespace must be associated with an existing directory.');
  20. $generator->queryNs = 'app\models';
  21. $valid = $generator->validate();
  22. $this->assertTrue($valid, 'Validation failed: ' . print_r($generator->getErrors(), true));
  23. $files = $generator->generate();
  24. $this->assertEquals(8, count($files));
  25. $expectedNames = [
  26. 'Attribute.php',
  27. 'Category.php',
  28. 'CategoryPhoto.php',
  29. 'Customer.php',
  30. 'Product.php',
  31. 'ProductLanguage.php',
  32. 'Profile.php',
  33. 'Supplier.php',
  34. ];
  35. $fileNames = array_map(function ($f) {
  36. return basename($f->path);
  37. }, $files);
  38. sort($fileNames);
  39. $this->assertEquals($expectedNames, $fileNames);
  40. }
  41. /**
  42. * @return array
  43. */
  44. public function relationsProvider()
  45. {
  46. return [
  47. ['category', 'Category.php', [
  48. [
  49. 'name' => 'function getCategoryPhotos()',
  50. 'relation' => "\$this->hasMany(CategoryPhoto::className(), ['category_id' => 'id']);",
  51. 'expected' => true,
  52. ],
  53. [
  54. 'name' => 'function getProduct()',
  55. 'relation' => "\$this->hasOne(Product::className(), ['category_id' => 'id', 'category_language_code' => 'language_code']);",
  56. 'expected' => true,
  57. ],
  58. ]],
  59. ['category_photo', 'CategoryPhoto.php', [
  60. [
  61. 'name' => 'function getCategory()',
  62. 'relation' => "\$this->hasOne(Category::className(), ['id' => 'category_id']);",
  63. 'expected' => true,
  64. ],
  65. ]],
  66. ['supplier', 'Supplier.php', [
  67. [
  68. 'name' => 'function getProducts()',
  69. 'relation' => "\$this->hasMany(Product::className(), ['supplier_id' => 'id']);",
  70. 'expected' => true,
  71. ],
  72. [
  73. 'name' => 'function getAttributes0()',
  74. 'relation' => "\$this->hasMany(Attribute::className(), ['supplier_id' => 'id']);",
  75. 'expected' => true,
  76. ],
  77. [
  78. 'name' => 'function getAttributes()',
  79. 'relation' => "\$this->hasOne(Attribute::className(), ['supplier_id' => 'id']);",
  80. 'expected' => false,
  81. ],
  82. [
  83. 'name' => 'function getProductLanguage()',
  84. 'relation' => "\$this->hasOne(ProductLanguage::className(), ['supplier_id' => 'id']);",
  85. 'expected' => true,
  86. ],
  87. ]],
  88. ['product', 'Product.php', [
  89. [
  90. 'name' => 'function getSupplier()',
  91. 'relation' => "\$this->hasOne(Supplier::className(), ['id' => 'supplier_id']);",
  92. 'expected' => true,
  93. ],
  94. [
  95. 'name' => 'function getCategory()',
  96. 'relation' => "\$this->hasOne(Category::className(), ['id' => 'category_id', 'language_code' => 'category_language_code']);",
  97. 'expected' => true,
  98. ],
  99. [
  100. 'name' => 'function getProductLanguage()',
  101. 'relation' => "\$this->hasOne(ProductLanguage::className(), ['supplier_id' => 'supplier_id', 'id' => 'id']);",
  102. 'expected' => true,
  103. ],
  104. ]],
  105. ['product_language', 'ProductLanguage.php', [
  106. [
  107. 'name' => 'function getSupplier()',
  108. 'relation' => "\$this->hasOne(Product::className(), ['supplier_id' => 'supplier_id', 'id' => 'id']);",
  109. 'expected' => true,
  110. ],
  111. [
  112. 'name' => 'function getSupplier0()',
  113. 'relation' => "\$this->hasOne(Supplier::className(), ['id' => 'supplier_id']);",
  114. 'expected' => true,
  115. ],
  116. ]],
  117. ];
  118. }
  119. /**
  120. * @dataProvider relationsProvider
  121. * @param $tableName string
  122. * @param $fileName string
  123. * @param $relations array
  124. */
  125. public function testRelations($tableName, $fileName, $relations)
  126. {
  127. $generator = new ModelGenerator();
  128. $generator->template = 'default';
  129. $generator->generateRelationsFromCurrentSchema = false;
  130. $generator->tableName = $tableName;
  131. $files = $generator->generate();
  132. $this->assertEquals(1, count($files));
  133. $this->assertEquals($fileName, basename($files[0]->path));
  134. $code = $files[0]->content;
  135. foreach ($relations as $relation) {
  136. $found = strpos($code, $relation['relation']) !== false;
  137. $this->assertTrue(
  138. $relation['expected'] === $found,
  139. "Relation \"{$relation['relation']}\" should"
  140. . ($relation['expected'] ? '' : ' not')." be there:\n" . $code
  141. );
  142. $found = strpos($code, $relation['name']) !== false;
  143. $this->assertTrue(
  144. $relation['expected'] === $found,
  145. "Relation Name \"{$relation['name']}\" should"
  146. . ($relation['expected'] ? '' : ' not')." be there:\n" . $code
  147. );
  148. }
  149. }
  150. public function testSchemas()
  151. {
  152. }
  153. /**
  154. * @return array
  155. */
  156. public function rulesProvider()
  157. {
  158. return [
  159. ['category_photo', 'CategoryPhoto.php', [
  160. "[['category_id'], 'exist', 'skipOnError' => true, 'targetClass' => Category::className(), 'targetAttribute' => ['category_id' => 'id']],",
  161. "[['category_id', 'display_number'], 'unique', 'targetAttribute' => ['category_id', 'display_number']],",
  162. ]],
  163. ['product', 'Product.php', [
  164. "[['supplier_id'], 'exist', 'skipOnError' => true, 'targetClass' => Supplier::className(), 'targetAttribute' => ['supplier_id' => 'id']],",
  165. "[['category_id', 'category_language_code'], 'exist', 'skipOnError' => true, 'targetClass' => Category::className(), 'targetAttribute' => ['category_id' => 'id', 'category_language_code' => 'language_code']],",
  166. "[['category_id', 'category_language_code'], 'unique', 'targetAttribute' => ['category_id', 'category_language_code']],"
  167. ]],
  168. ['product_language', 'ProductLanguage.php', [
  169. "[['supplier_id', 'id'], 'exist', 'skipOnError' => true, 'targetClass' => Product::className(), 'targetAttribute' => ['supplier_id' => 'supplier_id', 'id' => 'id']],",
  170. "[['supplier_id'], 'exist', 'skipOnError' => true, 'targetClass' => Supplier::className(), 'targetAttribute' => ['supplier_id' => 'id']],",
  171. "[['supplier_id'], 'unique']",
  172. "[['id', 'supplier_id', 'language_code'], 'unique', 'targetAttribute' => ['id', 'supplier_id', 'language_code']]",
  173. "[['id', 'supplier_id'], 'unique', 'targetAttribute' => ['id', 'supplier_id']]",
  174. ]],
  175. ];
  176. }
  177. /**
  178. * @dataProvider rulesProvider
  179. *
  180. * @param $tableName string
  181. * @param $fileName string
  182. * @param $rules array
  183. */
  184. public function testRules($tableName, $fileName, $rules)
  185. {
  186. $generator = new ModelGenerator();
  187. $generator->template = 'default';
  188. $generator->tableName = $tableName;
  189. $files = $generator->generate();
  190. $this->assertEquals(1, count($files));
  191. $this->assertEquals($fileName, basename($files[0]->path));
  192. $code = $files[0]->content;
  193. foreach ($rules as $rule) {
  194. $location = strpos($code, $rule);
  195. $this->assertTrue($location !== false,
  196. "Rule \"{$rule}\" should be there:\n" . $code
  197. );
  198. }
  199. }
  200. public function testGenerateStandardizedCapitalsForClassNames()
  201. {
  202. $modelGenerator = new ModelGeneratorMock;
  203. $modelGenerator->standardizeCapitals = true;
  204. $tableNames = [
  205. 'lower_underline_name' => 'LowerUnderlineName',
  206. 'Ucwords_Underline_Name' => 'UcwordsUnderlineName',
  207. 'UPPER_UNDERLINE_NAME' => 'UpperUnderlineName',
  208. 'lower-hyphen-name' => 'LowerHyphenName',
  209. 'Ucwords-Hyphen-Name' => 'UcwordsHyphenName',
  210. 'UPPER-HYPHEN-NAME' => 'UpperHyphenName',
  211. 'CamelCaseName' => 'CamelCaseName',
  212. 'lowerUcwordsName' => 'LowerUcwordsName',
  213. 'lowername' => 'Lowername',
  214. 'UPPERNAME' => 'Uppername',
  215. ];
  216. foreach ($tableNames as $tableName => $expectedClassName) {
  217. $generatedClassName = $modelGenerator->publicGenerateClassName($tableName);
  218. $this->assertEquals($expectedClassName, $generatedClassName);
  219. }
  220. }
  221. public function testGenerateNotStandardizedCapitalsForClassNames()
  222. {
  223. $modelGenerator = new ModelGeneratorMock;
  224. $modelGenerator->standardizeCapitals = false;
  225. $tableNames = [
  226. 'lower_underline_name' => 'LowerUnderlineName',
  227. 'Ucwords_Underline_Name' => 'UcwordsUnderlineName',
  228. 'UPPER_UNDERLINE_NAME' => 'UPPERUNDERLINENAME',
  229. 'ABBRMyTable' => 'ABBRMyTable',
  230. 'lower-hyphen-name' => 'Lower-hyphen-name',
  231. 'Ucwords-Hyphen-Name' => 'Ucwords-Hyphen-Name',
  232. 'UPPER-HYPHEN-NAME' => 'UPPER-HYPHEN-NAME',
  233. 'CamelCaseName' => 'CamelCaseName',
  234. 'lowerUcwordsName' => 'LowerUcwordsName',
  235. 'lowername' => 'Lowername',
  236. 'UPPERNAME' => 'UPPERNAME',
  237. 'PARTIALUpperName' => 'PARTIALUpperName',
  238. ];
  239. foreach ($tableNames as $tableName => $expectedClassName) {
  240. $generatedClassName = $modelGenerator->publicGenerateClassName($tableName);
  241. $this->assertEquals($expectedClassName, $generatedClassName);
  242. }
  243. }
  244. }