├── .gitignore ├── aliases.md ├── generate.php ├── readme.md └── tests ├── .DS_Store └── generate_task.test.php /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | -------------------------------------------------------------------------------- /aliases.md: -------------------------------------------------------------------------------- 1 | Here are some aliases that you can add to your `~/.bash_profile` file. 2 | 3 | ```bash 4 | alias g:c="php artisan generate:controller" 5 | alias g:m="php artisan generate:model" 6 | alias g:v="php artisan generate:view" 7 | alias g:mig-"php artisan generate:migration" 8 | alias g:a="php artisan generate:assets" 9 | alias g:t="php artisan generate:test" 10 | alias g:r="php artisan generate:resource" 11 | ``` 12 | 13 | Now, for example, to generate a new controller and methods, you can simply do: 14 | 15 | ```bash 16 | g:c admin index edit 17 | ``` 18 | -------------------------------------------------------------------------------- /generate.php: -------------------------------------------------------------------------------- 1 | 15 | * @license haha - whatever you want. 16 | * @version 0.8 17 | * @since July 26, 2012 18 | * 19 | */ 20 | class Generate_Task 21 | { 22 | 23 | /* 24 | * Set these paths to the location of your assets. 25 | */ 26 | public static $css_dir = 'css/'; 27 | public static $sass_dir = 'css/sass/'; 28 | public static $less_dir = 'css/less/'; 29 | 30 | public static $js_dir = 'js/'; 31 | public static $coffee_dir = 'js/coffee/'; 32 | 33 | /* 34 | * The content for the generate file 35 | */ 36 | public static $content; 37 | 38 | 39 | /** 40 | * Time Savers 41 | * 42 | */ 43 | public function c($args) { return $this->controller($args); } 44 | public function m($args) { return $this->model($args); } 45 | public function mig($args) { return $this->migration($args); } 46 | public function v($args) { return $this->view($args); } 47 | public function a($args) { return $this->assets($args); } 48 | public function t($args) { return $this->test($args); } 49 | public function r($args) { return $this->resource($args); } 50 | 51 | 52 | /** 53 | * Simply echos out some help info. 54 | * 55 | */ 56 | public function help() { $this->run(); } 57 | public function run() 58 | { 59 | echo <<path('controllers') . strtolower("$class_name.php"); 97 | 98 | // Begin building up the file's content 99 | Content::new_class($class_name . '_Controller', 'Base_Controller'); 100 | 101 | $content = ''; 102 | // Let's see if they added "restful" anywhere in the args. 103 | $restful_pos = array_search('restful', $args); 104 | if ( $restful_pos !== false ) { 105 | array_splice($args, $restful_pos, 1); 106 | $content .= 'public $restful = true;'; 107 | } 108 | 109 | // Now we filter through the args, and create the funcs. 110 | foreach($args as $method) { 111 | // Were params supplied? Like index:post? 112 | if ( strpos($method, ':') !== false ) { 113 | list($method, $verb) = explode(':', $method); 114 | $content .= Content::func("{$verb}_{$method}"); 115 | } else { 116 | $action = $restful_pos ? 'get' : 'action'; 117 | $content .= Content::func("{$action}_{$method}"); 118 | } 119 | } 120 | 121 | // Add methods/actions to class. 122 | Content::add_after('{', $content); 123 | 124 | // Prettify 125 | $this->prettify(); 126 | 127 | // Create the file 128 | $this->write_to_file($file_path); 129 | } 130 | 131 | 132 | /** 133 | * Generate a model file + boilerplate. (To be expanded.) 134 | * 135 | * USAGE 136 | * 137 | * php artisan generate:model User 138 | * 139 | * @param $args array 140 | * @return string 141 | */ 142 | public function model($args) 143 | { 144 | // Name of the class and file 145 | $class_name = is_array($args) ? ucwords($args[0]) : ucwords($args); 146 | 147 | $file_path = $this->path('models') . strtolower("$class_name.php"); 148 | 149 | // Begin building up the file's content 150 | Content::new_class($class_name, 'Eloquent' ); 151 | $this->prettify(); 152 | 153 | // Create the file 154 | $this->write_to_file($file_path); 155 | } 156 | 157 | 158 | /** 159 | * Generate a migration file + schema 160 | * 161 | * INSTRUCTIONS: 162 | * - Separate each word with an underscore 163 | * - Name your migrations according to what you're doing 164 | * - Try to use the `table` keyword, to hint at the table name: create_users_table 165 | * - Use the `add`, `create`, `update` and `delete` keywords, according to your needs. 166 | * - For each field, specify its name and type: id:integer, or body:text 167 | * - You may also specify additional options, like: age:integer:nullable, or email:string:unique 168 | * 169 | * 170 | * USAGE OPTIONS 171 | * 172 | * php artisan generate:migration create_users_table 173 | * php artisan generate:migration create_users_table id:integer email:string:unique age:integer:nullable 174 | * php artisan generate:migration add_user_id_to_posts_table user_id:integer 175 | * php artisan generate:migration delete_active_from_users_table active:boolean 176 | * 177 | * @param $args array 178 | * @return string 179 | */ 180 | public function migration($args) 181 | { 182 | if ( empty($args) ) { 183 | echo "Error: Please provide a name for your migration.\n"; 184 | return; 185 | } 186 | 187 | $class_name = array_shift($args); 188 | 189 | // Determine what the table name should be. 190 | $table_name = $this->parse_table_name($class_name); 191 | 192 | // Capitalize where necessary: a_simple_string => A_Simple_String 193 | $class_name = implode('_', array_map('ucwords', explode('_', $class_name))); 194 | 195 | // Let's create the path to where the migration will be stored. 196 | $file_path = $this->path('migrations') . date('Y_m_d_His') . strtolower("_$class_name.php"); 197 | 198 | $this->generate_migration($class_name, $table_name, $args); 199 | 200 | return $this->write_to_file($file_path); 201 | } 202 | 203 | 204 | /** 205 | * Create any number of views 206 | * 207 | * USAGE: 208 | * 209 | * php artisan generate:view home show 210 | * php artisan generate:view home.index home.show 211 | * 212 | * @param $args array 213 | * @return void 214 | */ 215 | public function view($paths) 216 | { 217 | if ( empty($paths) ) { 218 | echo "Warning: no views were specified. Add some!\n"; 219 | return; 220 | } 221 | 222 | foreach( $paths as $path ) { 223 | $file_path = $this->path('views') . str_replace('.', '/', $path) . '.blade.php'; 224 | self::$content = "This is the $file_path view"; 225 | $this->write_to_file($file_path); 226 | } 227 | } 228 | 229 | 230 | /** 231 | * Create assets in the public directory 232 | * 233 | * USAGE: 234 | * php artisan generate:assets style1.css some_module.js 235 | * 236 | * @param $assets array 237 | * @return void 238 | */ 239 | public function assets($assets) 240 | { 241 | if( empty($assets) ) { 242 | echo "Please specify the assets that you would like to create."; 243 | return; 244 | } 245 | 246 | foreach( $assets as $asset ) { 247 | // What type of file? CSS, JS? 248 | $ext = pathinfo($asset); 249 | if ( !isset($ext['extension']) ) { 250 | // Hmm - not sure what to do. 251 | echo "Warning: Could not determine file type. Please specify an extension."; 252 | continue; 253 | } 254 | 255 | // Set the path, dependent upon the file type. 256 | switch ($ext['extension']) { 257 | case 'js': 258 | $path = self::$js_dir . $asset; 259 | break; 260 | 261 | case 'coffee': 262 | $path = self::$coffee_dir . $asset; 263 | break; 264 | 265 | case 'scss': 266 | case 'sass': 267 | $path = self::$sass_dir . $asset; 268 | break; 269 | 270 | case 'less': 271 | $path = self::$less_dir . $asset; 272 | break; 273 | 274 | case 'css': 275 | default: 276 | $path = self::$css_dir . $asset; 277 | break; 278 | } 279 | 280 | $this->write_to_file(path('public') . $path, ''); 281 | } 282 | } 283 | 284 | 285 | /** 286 | * Create PHPUnit test classes with optional methods 287 | * 288 | * USAGE: 289 | * 290 | * php artisan generate:test membership 291 | * php artisan generate:test membership can_disable_user can_reset_user_password 292 | * 293 | * @param $args array 294 | * @return void 295 | */ 296 | public function test($args) 297 | { 298 | if ( empty($args) ) { 299 | echo "Please specify a name for your test class.\n"; 300 | return; 301 | } 302 | 303 | $class_name = ucwords(array_shift($args)); 304 | 305 | $file_path = $this->path('tests') . strtolower("{$class_name}.test.php"); 306 | 307 | // Begin building up the file's content 308 | Content::new_class($class_name . '_Test', 'PHPUnit_Framework_TestCase'); 309 | 310 | // add the functions 311 | $tests = ''; 312 | foreach($args as $test) { 313 | // make lower case 314 | $tests .= Content::func("test_{$test}"); 315 | } 316 | 317 | // add funcs to class 318 | Content::add_after('{', $tests); 319 | 320 | // Create the file 321 | $this->write_to_file($file_path, $this->prettify()); 322 | } 323 | 324 | 325 | /** 326 | * Creates the content for the migration file. 327 | * 328 | * @param $class_name string 329 | * @param $table_name string 330 | * @param $args array 331 | * @return void 332 | */ 333 | protected function generate_migration($class_name, $table_name, $args) 334 | { 335 | // Figure out what type of event is occuring. Create, Delete, Add? 336 | list($table_action, $table_event) = $this->parse_action_type($class_name); 337 | 338 | // Now, we begin creating the contents of the file. 339 | Content::new_class($class_name); 340 | 341 | /* The Migration Up Function */ 342 | $up = $this->migration_up($table_event, $table_action, $table_name, $args); 343 | 344 | /* The Migration Down Function */ 345 | $down = $this->migration_down($table_event, $table_action, $table_name, $args); 346 | 347 | // Add both the up and down function to the migration class. 348 | Content::add_after('{', $up . $down); 349 | 350 | return $this->prettify(); 351 | } 352 | 353 | 354 | protected function migration_up($table_event, $table_action, $table_name, $args) 355 | { 356 | $up = Content::func('up'); 357 | 358 | // Insert a new schema function into the up function. 359 | $up = $this->add_after('{', Content::schema($table_action, $table_name), $up); 360 | 361 | // Create the field rules for for the schema 362 | if ( $table_event === 'create' ) { 363 | $fields = $this->add_columns($args); 364 | $fields .= $this->set_column('timestamps', null) . ';'; 365 | } 366 | 367 | else if ( $table_event === 'delete' ) { 368 | $fields = $this->drop_columns($args); 369 | } 370 | 371 | else if ( $table_event === 'add' || $table_event === 'update' ) { 372 | $fields = $this->add_columns($args); 373 | } 374 | 375 | // Insert the fields into the schema function 376 | return $this->add_after('function($table) {', $fields, $up); 377 | } 378 | 379 | 380 | protected function migration_down($table_event, $table_action, $table_name, $args) 381 | { 382 | $down = Content::func('down'); 383 | 384 | if ( $table_event === 'create' ) { 385 | $schema = Content::schema('drop', $table_name, false); 386 | 387 | // Add drop schema into down function 388 | $down = $this->add_after('{', $schema, $down); 389 | } else { 390 | // for delete, add, and update 391 | $schema = Content::schema('table', $table_name); 392 | } 393 | 394 | if ( $table_event === 'delete' ) { 395 | $fields = $this->add_columns($args); 396 | 397 | // add fields to schema 398 | $schema = $this->add_after('function($table) {', $fields, $schema); 399 | 400 | // add schema to down function 401 | $down = $this->add_after('{', $schema, $down); 402 | } 403 | 404 | else if ( $table_event === 'add' ) { 405 | $fields = $this->drop_columns($args); 406 | 407 | // add fields to schema 408 | $schema = $this->add_after('function($table) {', $fields, $schema); 409 | 410 | // add schema to down function 411 | $down = $this->add_after('{', $schema, $down); 412 | 413 | } 414 | 415 | else if ( $table_event === 'update' ) { 416 | // add schema to down function 417 | $down = $this->add_after('{', $schema, $down); 418 | } 419 | 420 | return $down; 421 | } 422 | 423 | 424 | /** 425 | * Generate resource (model, controller, and views) 426 | * 427 | * @param $args array 428 | * @return void 429 | */ 430 | public function resource($args) 431 | { 432 | // Pluralize controller name 433 | if ( !preg_match('/admin|config/', $args[0]) ) { 434 | $args[0] = Str::plural($args[0]); 435 | } 436 | $this->controller($args); 437 | 438 | // Singular for everything else 439 | $resource_name = Str::singular(array_shift($args)); 440 | 441 | // Let's take any supplied view names, and set them 442 | // in the resource name's directory. 443 | $views = array_map(function($val) use($resource_name) { 444 | return "{$resource_name}.{$val}"; 445 | }, $args); 446 | 447 | $this->view($views); 448 | 449 | $this->model($resource_name); 450 | } 451 | 452 | 453 | /** 454 | * Figure out what the name of the table is. 455 | * 456 | * Fetch the value that comes right before "_table" 457 | * Or try to grab the very last word that comes after "_" - create_*users* 458 | * If all else fails, return a generic "TABLE", to be filled in by the user. 459 | * 460 | * @param $class_name string 461 | * @return string 462 | */ 463 | protected function parse_table_name($class_name) 464 | { 465 | // Try to figure out the table name 466 | // We'll use the word that comes immediately before "_table" 467 | // create_users_table => users 468 | preg_match('/([a-zA-Z]+)_table/', $class_name, $matches); 469 | 470 | if ( empty($matches) ) { 471 | // Or, if the user doesn't write "table", we'll just use 472 | // the text at the end of the string 473 | // create_users => users 474 | preg_match('/_([a-zA-Z]+)$/', $class_name, $matches); 475 | } 476 | 477 | // Hmm - I'm stumped. Just use a generic name. 478 | return empty($matches) 479 | ? "TABLE" 480 | : $matches[1]; 481 | } 482 | 483 | 484 | /** 485 | * Write the contents to the specified file 486 | * 487 | * @param $file_path string 488 | * @param $content string 489 | * @param $type string [model|controller|migration] 490 | * @return void 491 | */ 492 | protected function write_to_file($file_path, $success = '') 493 | { 494 | $success = $success ?: "Create: $file_path.\n"; 495 | 496 | if ( File::exists($file_path) ) { 497 | // we don't want to overwrite it 498 | echo "Warning: File already exists at $file_path\n"; 499 | return; 500 | } 501 | 502 | // As a precaution, let's see if we need to make the folder. 503 | File::mkdir(dirname($file_path)); 504 | 505 | if ( File::put($file_path, self::$content) !== false ) { 506 | echo $success; 507 | } else { 508 | echo "Whoops - something...erghh...went wrong!\n"; 509 | } 510 | } 511 | 512 | 513 | /** 514 | * Try to determine what type of table action should occur. 515 | * Add, Create, Delete?? 516 | * 517 | * @param $class_name string 518 | * @return aray 519 | */ 520 | protected function parse_action_type($class_name) 521 | { 522 | // What type of action? Creating a table? Adding a column? Deleting? 523 | if ( preg_match('/delete|update|add(?=_)/i', $class_name, $matches) ) { 524 | $table_action = 'table'; 525 | $table_event = strtolower($matches[0]); 526 | } else { 527 | $table_action = $table_event = 'create'; 528 | } 529 | 530 | return array($table_action, $table_event); 531 | } 532 | 533 | 534 | protected function increment() 535 | { 536 | return "\$table->increments('id')"; 537 | } 538 | 539 | 540 | protected function set_column($type, $field = '') 541 | { 542 | return empty($field) 543 | ? "\$table->$type()" 544 | : "\$table->$type('$field')"; 545 | } 546 | 547 | 548 | protected function add_option($option) 549 | { 550 | return "->{$option}()"; 551 | } 552 | 553 | 554 | /** 555 | * Add columns 556 | * 557 | * Filters through the provided args, and builds up the schema text. 558 | * 559 | * @param $args array 560 | * @return string 561 | */ 562 | protected function add_columns($args) 563 | { 564 | $content = ''; 565 | 566 | // Build up the schema 567 | foreach( $args as $arg ) { 568 | // Like age, integer, and nullable 569 | @list($field, $type, $setting) = explode(':', $arg); 570 | 571 | if ( !$type ) { 572 | echo "There was an error in your formatting. Please try again. Did you specify both a field and data type for each? age:int\n"; 573 | die(); 574 | } 575 | 576 | // Primary key check 577 | if ( $field === 'id' and $type === 'integer' ) { 578 | $rule = $this->increment(); 579 | } else { 580 | $rule = $this->set_column($type, $field); 581 | 582 | if ( !empty($setting) ) { 583 | $rule .= $this->add_option($setting); 584 | } 585 | } 586 | 587 | $content .= $rule . ";"; 588 | } 589 | 590 | return $content; 591 | } 592 | 593 | 594 | /** 595 | * Drop Columns 596 | * 597 | * Filters through the args and applies the "drop_column" syntax 598 | * 599 | * @param $args array 600 | * @return string 601 | */ 602 | protected function drop_columns($args) 603 | { 604 | $fields = array_map(function($val) { 605 | $bits = explode(':', $val); 606 | return "'$bits[0]'"; 607 | }, $args); 608 | 609 | if ( count($fields) === 1 ) { 610 | return "\$table->drop_column($fields[0]);"; 611 | } else { 612 | return "\$table->drop_column(array(" . implode(', ', $fields) . "));"; 613 | } 614 | } 615 | 616 | public function path($dir) 617 | { 618 | return path('app') . "$dir/"; 619 | } 620 | 621 | 622 | /** 623 | * Crazy sloppy prettify. TODO - Cleanup 624 | * 625 | * @param $content string 626 | * @return string 627 | */ 628 | protected function prettify() 629 | { 630 | $content = self::$content; 631 | 632 | $content = str_replace(' 2 | __ _ 3 | / / __ _ _ __ __ ___ _____| | 4 | / / / _` | '__/ _` \ \ / / _ \ | 5 | / /__| (_| | | | (_| |\ V / __/ | 6 | \____/\__,_|_| \__,_| \_/ \___|_| 7 | 8 | ___ _ 9 | / _ \___ _ __ ___ _ __ __ _| |_ ___ _ __ 10 | / /_\/ _ \ '_ \ / _ \ '__/ _` | __/ _ \| '__| 11 | / /_\\ __/ | | | __/ | | (_| | || (_) | | 12 | \____/\___|_| |_|\___|_| \__,_|\__\___/|_| 13 | 14 | 15 | 16 | On its own, when running migrations, Laravel simply creates the specified file, and adds a bit of boilerplate code. It's then up to you to fill in the Schema and such. ...Well that's a pain. 17 | 18 | This generator task will fill in the gaps. It can generate several things: 19 | 20 | - [Controllers and actions](#controllers) 21 | - [Models](#models) 22 | - [Views](#views) 23 | - [Migrations and Schema](#migrations) 24 | - [Resources](#resources) 25 | - [Assets](#assets) 26 | - [Tests](#tests) 27 | 28 | ## Installation 29 | 30 | Simply download the `generate.php` file from this repo, and save it to your `application/tasks/` directory. Now, we can execute the various methods from the command line, via Artisan. 31 | 32 | ### Controllers 33 | 34 | To generate a controller for your project, run: 35 | 36 | ```bash 37 | php artisan generate:controller Admin 38 | ``` 39 | 40 | This will create a file, `application/controllers/admin.php`, with the following contents: 41 | 42 | ```php 43 | timestamps(); 140 | }); 141 | } 142 | 143 | public function down() 144 | { 145 | Schema::drop('users'); 146 | } 147 | 148 | } 149 | ``` 150 | 151 | Not bad, not bad. But what about the schema? Let's specify the fields for the table. 152 | 153 | ```bash 154 | php artisan generate:migration create_users_table id:integer name:string email_address:string 155 | ``` 156 | 157 | That will give us: 158 | 159 | ```php 160 | increments('id'); 170 | $table->string('name'); 171 | $table->string('email_address'); 172 | $table->timestamps(); 173 | }); 174 | } 175 | 176 | public function down() 177 | { 178 | Schema::drop('users'); 179 | } 180 | 181 | } 182 | ``` 183 | 184 | Ahh hell yeah. Notice that it automatically applies the `timestamps()`. A bit opinionated maybe, but it only takes a second to delete, if you don't want them. 185 | 186 | You can also specify other options, such as making your `email` field unique, or the `age` field optional - like this: 187 | 188 | ```bash 189 | php artisan generate:migration create_users_table id:integer name:string email_address:string:unique age:integer:nullable 190 | ``` 191 | 192 | Now we get: 193 | 194 | ```php 195 | increments('id'); 205 | $table->string('name'); 206 | $table->string('email_address')->unique(); 207 | $table->integer('age')->nullable(); 208 | $table->timestamps(); 209 | }); 210 | } 211 | 212 | public function down() 213 | { 214 | Schema::drop('users'); 215 | } 216 | 217 | } 218 | ``` 219 | 220 | Sweet! 221 | 222 | #### Keywords 223 | 224 | It's important to remember that the script tries to figure out what you're trying to accomplish. So it's important that you use keywords, like "add" or "delete". Here's some examples: 225 | 226 | ```bash 227 | php artisan generate:migration add_user_id_to_posts_table user_id:integer 228 | php artisan generate:migration delete_user_id_from_posts_table user_id:integer 229 | php artisan generate:migration create_posts_table title:string body:text 230 | ``` 231 | 232 | There's three best practices worth noting here: 233 | 234 | 1. Our class/file names are very readable. That's important. 235 | 2. The script uses the word that comes before "_table" as the table name. So, for `create_users_table`, it'll set the table name to `users`. 236 | 3. I've used the CRUD keywords to describe what I want to do. 237 | 238 | If we run the second example: 239 | 240 | ```bash 241 | php artisan generate:migration delete_user_id_from_posts_table user_id:integer 242 | ``` 243 | 244 | ...we get: 245 | 246 | ```php 247 | drop_column('user_id'); 257 | }); 258 | } 259 | 260 | public function down() 261 | { 262 | Schema::table('posts', function($table) 263 | { 264 | $table->integer('user_id'); 265 | }); 266 | } 267 | 268 | } 269 | ``` 270 | 271 | ### Views 272 | 273 | Views are a cinch to generate. 274 | 275 | ```bash 276 | php artisan generate:view index show 277 | ``` 278 | 279 | This will create two files within the `views` folder: 280 | 281 | 1. index.blade.php 282 | 2. show.blade.php 283 | 284 | You can also specify subdirectories, via the period. 285 | 286 | ```bash 287 | php artisan generate:view home.index home.edit 288 | ``` 289 | 290 | Which will create: 291 | 292 | 1. home/index.blade.php 293 | 2. home/edit.blade.php 294 | 295 | ### Resources 296 | 297 | But what if you want to save some time, and add a few things at once? Generating a resource will produce a 298 | controller, model, and view files. For example: 299 | 300 | ```bash 301 | php artisan generate:resource post index show 302 | ``` 303 | 304 | This will create: 305 | 306 | 1. A `post.php` model 307 | 2. A `posts.php` controller with index + show actions 308 | 3. A post views folder with `index.blade.php` and `show.blade.php` views. 309 | 310 | ### Putting It All Together 311 | 312 | So let's rapidly generate a resource for blog posts. 313 | 314 | ```bash 315 | php artisan generate:resource post index show 316 | php artisan generate:migration create_posts_table id:integer title:string body:text 317 | php artisan migrate 318 | ``` 319 | 320 | Of course, if you haven't already installed the migrations table, you'd do that first: `php artisan migrate:install`. 321 | 322 | With those three lines of code, you now have: 323 | 324 | 1. A controller with two actions 325 | 2. A post model 326 | 3. a post views folder with two views: index and show 327 | 4. A new `posts` table in your db with id, title, and body fields. 328 | 329 | Nifty, ay? 330 | 331 | 332 | ### Assets 333 | 334 | Just as a convenience, you can also generate stylesheets and scripts through the command line. 335 | 336 | ```bash 337 | php artisan generate:assets style.css style2.css admin/script.js 338 | ``` 339 | 340 | This will create three files: 341 | 342 | ```bash 343 | public/css/style.css 344 | public/css/style2.css 345 | public/js/admin/script.js 346 | ``` 347 | 348 | Note: that may seem like a lot to write for a simple task, but you can always create aliases for this stuff. 349 | 350 | ```bash 351 | alias la="php artisan generate:assets"; 352 | ``` 353 | Now, it's as easy as doing: 354 | 355 | ```bash 356 | la style.css script.js 357 | ``` 358 | 359 | The default directory paths are: 360 | 361 | - CSS => `public/css/` 362 | - JavaScript => `public/js/` 363 | - CoffeeScript => `public/js/coffee/` 364 | - Sass (sass or scss extension) => `public/css/sass` 365 | 366 | 367 | ### Tests 368 | 369 | Laravel Generator can also generate PHPUnit test classes for you, like so: 370 | 371 | ```bash 372 | php artisan generate:test user 373 | ``` 374 | 375 | If you only specify a class name, as we've done above, you'll get: 376 | 377 | ```php 378 | `generate:c` 418 | - `generate:model` => `generate:m` 419 | - `generate:migration` => `generate:mig` 420 | - `generate:view` => `generate:v` 421 | - `generate:resource` => `generate:r` 422 | - `generate:assets` => `generate:a` 423 | 424 | You could also just create Bash aliases, like this: 425 | 426 | ```bash 427 | alias g:c="php artisan generate:controller"; 428 | alias g:m="php artisan generate:model" 429 | ``` 430 | 431 | Now, to create a controller, you can simply type: 432 | 433 | ```bash 434 | g:c config index 435 | ```` 436 | 437 | [Refer here](https://github.com/JeffreyWay/Laravel-Generator/blob/master/aliases.md) for more alias recommendations. 438 | -------------------------------------------------------------------------------- /tests/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mnishihan/Laravel-Generator/9ddeefeb24a1f8966626fe6ea4cf3c1dc664c085/tests/.DS_Store -------------------------------------------------------------------------------- /tests/generate_task.test.php: -------------------------------------------------------------------------------- 1 | generate = new Generate_Task; 27 | } 28 | 29 | 30 | // @group models 31 | public function test_can_create_model_file() 32 | { 33 | $this->generate->model('Book'); 34 | 35 | $this->assertFileExists(self::$model); 36 | } 37 | 38 | 39 | // @group controllers 40 | public function test_can_create_controller_file() 41 | { 42 | $this->generate->controller(array( 43 | 'Admin' 44 | )); 45 | 46 | $this->assertFileExists(self::$controller); 47 | } 48 | 49 | 50 | public function test_can_add_actions() 51 | { 52 | $this->generate->controller(array( 53 | 'Admin', 54 | 'index', 55 | 'show' 56 | )); 57 | 58 | $contents = File::get(self::$controller); 59 | 60 | $this->assertContains('action_index', $contents); 61 | $this->assertContains('action_show', $contents); 62 | } 63 | 64 | 65 | public function test_controllers_can_be_restful() 66 | { 67 | $this->generate->controller(array( 68 | 'admin', 69 | 'index', 70 | 'index:post', 71 | 'update:put', 72 | 'restful' 73 | )); 74 | 75 | $contents = file::get(self::$controller); 76 | 77 | $this->assertContains('public $restful = true', $contents); 78 | $this->assertContains('get_index', $contents); 79 | $this->assertContains('post_index', $contents); 80 | $this->assertContains('put_update', $contents); 81 | } 82 | 83 | 84 | public function test_restful_can_be_any_argument() 85 | { 86 | $this->generate->controller(array( 87 | 'admin', 88 | 'restful', 89 | 'index:post', 90 | )); 91 | 92 | $contents = file::get(self::$controller); 93 | 94 | $this->assertContains('public $restful = true', $contents); 95 | $this->assertContains('post_index', $contents); 96 | } 97 | 98 | 99 | // @group migrations 100 | public function test_can_create_migration_files() 101 | { 102 | $this->generate->migration(array( 103 | 'create_users_table' 104 | )); 105 | 106 | $file = File::latest(self::$migration); 107 | $this->assertFileExists((string)$file); 108 | } 109 | 110 | 111 | public function test_migration_offers_boilerplate_code() 112 | { 113 | $this->generate->migration(array( 114 | 'create_users_table' 115 | )); 116 | 117 | $file = File::latest(self::$migration); 118 | $contents = File::get($file); 119 | 120 | $this->assertContains('class Create_Users_Table', $contents); 121 | $this->assertContains('public function up', $contents); 122 | $this->assertContains('public function down', $contents); 123 | } 124 | 125 | 126 | public function test_migration_sets_up_create_schema() 127 | { 128 | $this->generate->migration(array( 129 | 'create_users_table', 130 | 'id:integer', 131 | 'email:string' 132 | )); 133 | 134 | $file = File::latest(self::$migration); 135 | $contents = File::get($file); 136 | 137 | $this->assertContains('Schema::create', $contents); 138 | $this->assertContains("\$table->increments('id')", $contents); 139 | $this->assertContains("\$table->string('email')", $contents); 140 | 141 | // Dropping too 142 | $this->assertContains("Schema::drop('users')", $contents); 143 | } 144 | 145 | 146 | public function test_migration_sets_up_add_schema() 147 | { 148 | $this->generate->migration(array( 149 | 'add_user_id_to_posts_table', 150 | 'user_id:integer' 151 | )); 152 | 153 | $file = File::latest(self::$migration); 154 | $contents = File::get($file); 155 | 156 | $this->assertContains("Schema::table('posts'", $contents); 157 | $this->assertContains("\$table->integer('user_id')", $contents); 158 | $this->assertContains("\$table->drop_column('user_id')", $contents); 159 | } 160 | 161 | 162 | // @group views 163 | public function test_can_create_views() 164 | { 165 | $this->generate->view(array( 166 | 'book', 167 | 'test' 168 | )); 169 | 170 | // Views default to blade 171 | $this->assertFileExists(self::$view . 'book.blade.php'); 172 | $this->assertFileExists(self::$view . 'test.blade.php'); 173 | } 174 | 175 | 176 | public function test_can_create_nested_views() 177 | { 178 | $this->generate->view(array( 179 | 'book.index', 180 | 'book.admin.show', 181 | 'book' 182 | )); 183 | 184 | $this->assertFileExists(self::$view . 'book/index.blade.php'); 185 | $this->assertFileExists(self::$view . 'book/admin/show.blade.php'); 186 | $this->assertFileExists(self::$view . 'book.blade.php'); 187 | } 188 | 189 | 190 | // @group resource 191 | public function test_can_create_resources() 192 | { 193 | $this->generate->resource(array( 194 | 'user', 195 | 'index', 196 | 'show' 197 | )); 198 | 199 | $this->assertFileExists(self::$view . 'user/index.blade.php'); 200 | $this->assertFileExists(self::$view . 'user/show.blade.php'); 201 | 202 | $this->assertFileExists(path('app') . 'models/user.php'); 203 | $this->assertFileExists(path('app') . 'controllers/users.php'); 204 | } 205 | 206 | 207 | // @group assets 208 | public function test_can_create_assets() 209 | { 210 | $this->generate->assets(array( 211 | 'style1.css', 212 | 'style2.css', 213 | 'script1.js' 214 | )); 215 | 216 | $css_path = path('public') . '/css'; 217 | $js_path = path('public') . '/js'; 218 | 219 | $this->assertFileExists("$css_path/style1.css"); 220 | $this->assertFileExists("$css_path/style2.css"); 221 | $this->assertFileExists("$js_path/script1.js"); 222 | } 223 | 224 | 225 | public function test_can_create_nested_assets() 226 | { 227 | $this->generate->assets(array( 228 | 'admin/style.css', 229 | 'style3.css', 230 | )); 231 | 232 | $css_path = path('public') . '/css'; 233 | $js_path = path('public') . '/js'; 234 | 235 | $this->assertFileExists("$css_path/style3.css"); 236 | $this->assertFileExists("$css_path/admin/style.css"); 237 | } 238 | 239 | 240 | // @group test 241 | public function test_can_create_test_files() 242 | { 243 | $this->generate->test(array( 244 | 'user', 245 | 'can_disable_user', 246 | 'can_reset_user_password' 247 | )); 248 | 249 | $file = File::latest($this->generate->path('tests')); 250 | $this->assertFileExists((string)$file); 251 | 252 | $content = File::get($file); 253 | $this->assertContains('class User_Test extends PHPUnit_Framework_TestCase', $content); 254 | $this->assertContains('public function test_can_disable_user()', $content); 255 | $this->assertContains('public function test_can_reset_user_password()', $content); 256 | } 257 | 258 | 259 | public function tearDown() 260 | { 261 | ob_end_clean(); 262 | 263 | File::delete(path('app') . 'controllers/admin.php'); 264 | File::cleandir(path('app') . 'models'); 265 | File::cleandir(path('app') . 'migrations'); 266 | File::cleandir(path('app') . 'views'); 267 | File::cleandir(path('public') . 'css'); 268 | File::cleandir(path('public') . 'js'); 269 | } 270 | } --------------------------------------------------------------------------------