app_generator_test.rb 31.7 KB
Newer Older
1 2
# frozen_string_literal: true

3 4 5
require "generators/generators_test_helper"
require "rails/generators/rails/app/app_generator"
require "generators/shared_generator_tests"
J
José Valim 已提交
6

7 8
DEFAULT_APP_FILES = %w(
  .gitignore
9
  .ruby-version
10
  README.md
11 12 13
  Gemfile
  Rakefile
  config.ru
14 15
  app/assets/config/manifest.js
  app/assets/images
16 17 18
  app/javascript
  app/javascript/channels
  app/javascript/packs/application.js
J
José Valim 已提交
19
  app/assets/stylesheets
20 21 22
  app/assets/stylesheets/application.css
  app/channels/application_cable/channel.rb
  app/channels/application_cable/connection.rb
23
  app/controllers
24
  app/controllers/application_controller.rb
F
Francesco Rodriguez 已提交
25
  app/controllers/concerns
26
  app/helpers
27
  app/helpers/application_helper.rb
28
  app/mailers
29
  app/mailers/application_mailer.rb
30
  app/models
31
  app/models/application_record.rb
F
Francesco Rodriguez 已提交
32
  app/models/concerns
33
  app/jobs
34
  app/jobs/application_job.rb
35
  app/views/layouts
36 37 38
  app/views/layouts/application.html.erb
  app/views/layouts/mailer.html.erb
  app/views/layouts/mailer.text.erb
39 40
  bin/rails
  bin/rake
41
  bin/setup
42 43 44 45 46 47
  bin/update
  bin/yarn
  config/application.rb
  config/boot.rb
  config/cable.yml
  config/environment.rb
48
  config/environments
49 50 51
  config/environments/development.rb
  config/environments/production.rb
  config/environments/test.rb
52
  config/initializers
53 54 55 56
  config/initializers/application_controller_renderer.rb
  config/initializers/assets.rb
  config/initializers/backtrace_silencers.rb
  config/initializers/cookies_serializer.rb
57
  config/initializers/content_security_policy.rb
58 59 60 61
  config/initializers/filter_parameter_logging.rb
  config/initializers/inflections.rb
  config/initializers/mime_types.rb
  config/initializers/wrap_parameters.rb
62
  config/locales
63
  config/locales/en.yml
S
schneems 已提交
64
  config/puma.rb
65
  config/routes.rb
66
  config/credentials.yml.enc
67
  config/spring.rb
68
  config/storage.yml
69
  db
70
  db/seeds.rb
71 72
  lib
  lib/tasks
73
  lib/assets
74
  log
75 76
  package.json
  public
77
  storage
78
  test/application_system_test_case.rb
A
Arun Agrawal 已提交
79
  test/test_helper.rb
80
  test/fixtures
81
  test/fixtures/files
M
Mike Moore 已提交
82 83 84 85
  test/controllers
  test/models
  test/helpers
  test/mailers
86
  test/integration
E
eileencodes 已提交
87
  test/system
88
  vendor
89
  tmp
90
  tmp/cache
J
José Valim 已提交
91
  tmp/cache/assets
92
  tmp/storage
93 94
)

95 96
class AppGeneratorTest < Rails::Generators::TestCase
  include GeneratorsTestHelper
97
  arguments [destination_root]
98 99

  # brings setup, teardown, and some tests
100
  include SharedGeneratorTests
J
José Valim 已提交
101

102 103
  def default_files
    ::DEFAULT_APP_FILES
104 105
  end

106 107 108 109 110 111 112 113 114
  def test_skip_bundle
    assert_not_called(generator([destination_root], skip_bundle: true), :bundle_command) do
      quietly { generator.invoke_all }
      # skip_bundle is only about running bundle install, ensure the Gemfile is still
      # generated.
      assert_file "Gemfile"
    end
  end

115
  def test_assets
116
    run_generator
117

J
Jeroen Visser 已提交
118
    assert_file("app/views/layouts/application.html.erb", /stylesheet_link_tag\s+'application', media: 'all', 'data-turbolinks-track': 'reload'/)
119
    assert_file("app/views/layouts/application.html.erb", /javascript_pack_tag\s+'application', 'data-turbolinks-track': 'reload'/)
120
    assert_file("app/assets/stylesheets/application.css")
121
    assert_file("app/javascript/packs/application.js")
122 123
  end

124 125 126 127 128
  def test_application_job_file_present
    run_generator
    assert_file("app/jobs/application_job.rb")
  end

129
  def test_invalid_application_name_raises_an_error
130
    content = capture(:stderr) { run_generator [File.join(destination_root, "43-things")] }
131 132 133 134
    assert_equal "Invalid application name 43-things. Please give a name which does not start with numbers.\n", content
  end

  def test_invalid_application_name_is_fixed
135
    run_generator [File.join(destination_root, "things-43")]
136
    assert_file "things-43/config/environment.rb", /Rails\.application\.initialize!/
137
    assert_file "things-43/config/application.rb", /^module Things43$/
138 139
  end

140
  def test_application_new_exits_with_non_zero_code_on_invalid_application_name
141
    quietly { system "rails new test --no-rc" }
142
    assert_equal false, $?.success?
143 144 145
  end

  def test_application_new_exits_with_message_and_non_zero_code_when_generating_inside_existing_rails_directory
146
    app_root = File.join(destination_root, "myfirstapp")
147 148 149 150 151 152 153
    run_generator [app_root]
    output = nil
    Dir.chdir(app_root) do
      output = `rails new mysecondapp`
    end
    assert_equal "Can't initialize a new Rails application within the directory of another, please change to a non-Rails directory first.\nType 'rails' for help.\n", output
    assert_equal false, $?.success?
154 155
  end

156
  def test_application_new_show_help_message_inside_existing_rails_directory
157
    app_root = File.join(destination_root, "myfirstapp")
158 159 160 161
    run_generator [app_root]
    output = Dir.chdir(app_root) do
      `rails new --help`
    end
162
    assert_match(/rails new APP_PATH \[options\]/, output)
163 164 165
    assert_equal true, $?.success?
  end

166 167 168 169 170 171
  def test_application_name_is_detected_if_it_exists_and_app_folder_renamed
    app_root       = File.join(destination_root, "myapp")
    app_moved_root = File.join(destination_root, "myapp_moved")

    run_generator [app_root]

172 173 174
    stub_rails_application(app_moved_root) do
      Rails.application.stub(:is_a?, -> *args { Rails::Application }) do
        FileUtils.mv(app_root, app_moved_root)
175

176 177
        # make sure we are in correct dir
        FileUtils.cd(app_moved_root)
178

179
        generator = Rails::Generators::AppGenerator.new ["rails"], [],
180 181 182 183 184 185
                                                                   destination_root: app_moved_root, shell: @shell
        generator.send(:app_const)
        quietly { generator.send(:update_config_files) }
        assert_file "myapp_moved/config/environment.rb", /Rails\.application\.initialize!/
      end
    end
186
  end
187

188
  def test_app_update_generates_correct_session_key
189
    app_root = File.join(destination_root, "myapp")
190
    run_generator [app_root]
191

192
    stub_rails_application(app_root) do
193
      generator = Rails::Generators::AppGenerator.new ["rails"], [], destination_root: app_root, shell: @shell
194 195 196
      generator.send(:app_const)
      quietly { generator.send(:update_config_files) }
    end
197
  end
198

199 200 201 202 203 204
  def test_new_application_use_json_serialzier
    run_generator

    assert_file("config/initializers/cookies_serializer.rb", /Rails\.application\.config\.action_dispatch\.cookies_serializer = :json/)
  end

205 206 207
  def test_new_application_not_include_api_initializers
    run_generator

208
    assert_no_file "config/initializers/cors.rb"
209 210
  end

211
  def test_new_application_doesnt_need_defaults
212
    run_generator
A
Andrew White 已提交
213
    assert_no_file "config/initializers/new_framework_defaults_6_0.rb"
214 215
  end

216 217
  def test_new_application_load_defaults
    app_root = File.join(destination_root, "myfirstapp")
218
    run_generator [app_root]
219

220 221
    output = nil

222 223
    assert_file "#{app_root}/config/application.rb", /\s+config\.load_defaults #{Rails::VERSION::STRING.to_f}/

224
    Dir.chdir(app_root) do
225
      output = `SKIP_REQUIRE_WEBPACKER=true ./bin/rails r "puts Rails.application.config.assets.unknown_asset_fallback"`
226 227 228 229 230
    end

    assert_equal "false\n", output
  end

231
  def test_app_update_keep_the_cookie_serializer_if_it_is_already_configured
232
    app_root = File.join(destination_root, "myapp")
233 234
    run_generator [app_root]

235
    stub_rails_application(app_root) do
236
      generator = Rails::Generators::AppGenerator.new ["rails"], [], destination_root: app_root, shell: @shell
237 238 239 240
      generator.send(:app_const)
      quietly { generator.send(:update_config_files) }
      assert_file("#{app_root}/config/initializers/cookies_serializer.rb", /Rails\.application\.config\.action_dispatch\.cookies_serializer = :json/)
    end
241 242
  end

243
  def test_app_update_set_the_cookie_serializer_to_marshal_if_it_is_not_already_configured
244
    app_root = File.join(destination_root, "myapp")
245 246 247 248
    run_generator [app_root]

    FileUtils.rm("#{app_root}/config/initializers/cookies_serializer.rb")

249
    stub_rails_application(app_root) do
250
      generator = Rails::Generators::AppGenerator.new ["rails"], [], destination_root: app_root, shell: @shell
251 252
      generator.send(:app_const)
      quietly { generator.send(:update_config_files) }
253 254
      assert_file("#{app_root}/config/initializers/cookies_serializer.rb",
                  /Valid options are :json, :marshal, and :hybrid\.\nRails\.application\.config\.action_dispatch\.cookies_serializer = :marshal/)
255
    end
256 257
  end

258
  def test_app_update_create_new_framework_defaults
259
    app_root = File.join(destination_root, "myapp")
260 261
    run_generator [app_root]

A
Andrew White 已提交
262
    assert_no_file "#{app_root}/config/initializers/new_framework_defaults_6_0.rb"
263 264

    stub_rails_application(app_root) do
K
Koichi ITO 已提交
265
      generator = Rails::Generators::AppGenerator.new ["rails"], { update: true }, { destination_root: app_root, shell: @shell }
266 267
      generator.send(:app_const)
      quietly { generator.send(:update_config_files) }
268

A
Andrew White 已提交
269
      assert_file "#{app_root}/config/initializers/new_framework_defaults_6_0.rb"
270 271 272
    end
  end

273
  def test_app_update_does_not_create_rack_cors
274
    app_root = File.join(destination_root, "myapp")
275 276 277
    run_generator [app_root]

    stub_rails_application(app_root) do
278
      generator = Rails::Generators::AppGenerator.new ["rails"], [], destination_root: app_root, shell: @shell
279 280 281 282 283 284
      generator.send(:app_const)
      quietly { generator.send(:update_config_files) }
      assert_no_file "#{app_root}/config/initializers/cors.rb"
    end
  end

285
  def test_app_update_does_not_remove_rack_cors_if_already_present
286
    app_root = File.join(destination_root, "myapp")
287 288 289 290 291
    run_generator [app_root]

    FileUtils.touch("#{app_root}/config/initializers/cors.rb")

    stub_rails_application(app_root) do
292
      generator = Rails::Generators::AppGenerator.new ["rails"], [], destination_root: app_root, shell: @shell
293 294 295 296 297 298
      generator.send(:app_const)
      quietly { generator.send(:update_config_files) }
      assert_file "#{app_root}/config/initializers/cors.rb"
    end
  end

299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319
  def test_app_update_does_not_generate_yarn_contents_when_bin_yarn_is_not_used
    app_root = File.join(destination_root, "myapp")
    run_generator [app_root, "--skip-yarn"]

    stub_rails_application(app_root) do
      generator = Rails::Generators::AppGenerator.new ["rails"], { update: true, skip_yarn: true }, { destination_root: app_root, shell: @shell }
      generator.send(:app_const)
      quietly { generator.send(:update_bin_files) }

      assert_no_file "#{app_root}/bin/yarn"

      assert_file "#{app_root}/bin/setup" do |content|
        assert_no_match(/system\('bin\/yarn'\)/, content)
      end

      assert_file "#{app_root}/bin/update" do |content|
        assert_no_match(/system\('bin\/yarn'\)/, content)
      end
    end
  end

320 321 322 323 324 325 326 327 328 329 330 331 332
  def test_app_update_does_not_generate_assets_initializer_when_skip_sprockets_is_given
    app_root = File.join(destination_root, "myapp")
    run_generator [app_root, "--skip-sprockets"]

    stub_rails_application(app_root) do
      generator = Rails::Generators::AppGenerator.new ["rails"], { update: true, skip_sprockets: true }, { destination_root: app_root, shell: @shell }
      generator.send(:app_const)
      quietly { generator.send(:update_config_files) }

      assert_no_file "#{app_root}/config/initializers/assets.rb"
    end
  end

333 334 335 336 337 338 339 340 341 342 343
  def test_app_update_does_not_generate_spring_contents_when_skip_spring_is_given
    app_root = File.join(destination_root, "myapp")
    run_generator [app_root, "--skip-spring"]

    FileUtils.cd(app_root) do
      quietly { system("bin/rails app:update") }
    end

    assert_no_file "#{app_root}/config/spring.rb"
  end

344 345 346 347 348 349 350 351 352 353 354 355 356 357
  def test_app_update_does_not_generate_action_cable_contents_when_skip_action_cable_is_given
    app_root = File.join(destination_root, "myapp")
    run_generator [app_root, "--skip-action-cable"]

    FileUtils.cd(app_root) do
      quietly { system("bin/rails app:update") }
    end

    assert_no_file "#{app_root}/config/cable.yml"
    assert_file "#{app_root}/config/environments/production.rb" do |content|
      assert_no_match(/config\.action_cable/, content)
    end
  end

358 359 360 361 362 363 364 365 366 367 368 369 370
  def test_app_update_does_not_generate_bootsnap_contents_when_skip_bootsnap_is_given
    app_root = File.join(destination_root, "myapp")
    run_generator [app_root, "--skip-bootsnap"]

    FileUtils.cd(app_root) do
      quietly { system("bin/rails app:update") }
    end

    assert_file "#{app_root}/config/boot.rb" do |content|
      assert_no_match(/require 'bootsnap\/setup'/, content)
    end
  end

Y
yuuji.yaginuma 已提交
371
  def test_gem_for_active_storage
372
    run_generator
373
    assert_file "Gemfile", /^# gem 'image_processing'/
374 375
  end

Y
yuuji.yaginuma 已提交
376
  def test_gem_for_active_storage_when_skip_active_storage_is_given
377
    run_generator [destination_root, "--skip-active-storage"]
378

379
    assert_no_gem "image_processing"
380 381
  end

382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427
  def test_app_update_does_not_generate_active_storage_contents_when_skip_active_storage_is_given
    app_root = File.join(destination_root, "myapp")
    run_generator [app_root, "--skip-active-storage"]

    FileUtils.cd(app_root) do
      quietly { system("bin/rails app:update") }
    end

    assert_file "#{app_root}/config/environments/development.rb" do |content|
      assert_no_match(/config\.active_storage/, content)
    end

    assert_file "#{app_root}/config/environments/production.rb" do |content|
      assert_no_match(/config\.active_storage/, content)
    end

    assert_file "#{app_root}/config/environments/test.rb" do |content|
      assert_no_match(/config\.active_storage/, content)
    end

    assert_no_file "#{app_root}/config/storage.yml"
  end

  def test_app_update_does_not_generate_active_storage_contents_when_skip_active_record_is_given
    app_root = File.join(destination_root, "myapp")
    run_generator [app_root, "--skip-active-record"]

    FileUtils.cd(app_root) do
      quietly { system("bin/rails app:update") }
    end

    assert_file "#{app_root}/config/environments/development.rb" do |content|
      assert_no_match(/config\.active_storage/, content)
    end

    assert_file "#{app_root}/config/environments/production.rb" do |content|
      assert_no_match(/config\.active_storage/, content)
    end

    assert_file "#{app_root}/config/environments/test.rb" do |content|
      assert_no_match(/config\.active_storage/, content)
    end

    assert_no_file "#{app_root}/config/storage.yml"
  end

428 429 430 431 432 433 434 435 436 437 438 439 440
  def test_app_update_does_not_change_config_target_version
    run_generator

    FileUtils.cd(destination_root) do
      config = "config/application.rb"
      content = File.read(config)
      File.write(config, content.gsub(/config\.load_defaults #{Rails::VERSION::STRING.to_f}/, "config.load_defaults 5.1"))
      quietly { system("bin/rails app:update") }
    end

    assert_file "config/application.rb", /\s+config\.load_defaults 5\.1/
  end

441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464
  def test_app_update_does_not_change_app_name_when_app_name_is_hyphenated_name
    app_root = File.join(destination_root, "hyphenated-app")
    run_generator [app_root, "-d", "postgresql"]

    assert_file "#{app_root}/config/database.yml" do |content|
      assert_match(/hyphenated_app_development/, content)
      assert_no_match(/hyphenated-app_development/, content)
    end

    assert_file "#{app_root}/config/cable.yml" do |content|
      assert_match(/hyphenated_app/, content)
      assert_no_match(/hyphenated-app/, content)
    end

    FileUtils.cd(app_root) do
      quietly { system("bin/rails app:update") }
    end

    assert_file "#{app_root}/config/cable.yml" do |content|
      assert_match(/hyphenated_app/, content)
      assert_no_match(/hyphenated-app/, content)
    end
  end

465 466
  def test_application_names_are_not_singularized
    run_generator [File.join(destination_root, "hats")]
467
    assert_file "hats/config/environment.rb", /Rails\.application\.initialize!/
468 469
  end

470 471 472
  def test_gemfile_has_no_whitespace_errors
    run_generator
    absolute = File.expand_path("Gemfile", destination_root)
473
    File.open(absolute, "r") do |f|
474
      f.each_line do |line|
A
Arun Agrawal 已提交
475
        assert_no_match %r{/^[ \t]+$/}, line
476 477 478 479
      end
    end
  end

J
José Valim 已提交
480 481 482
  def test_config_database_is_added_by_default
    run_generator
    assert_file "config/database.yml", /sqlite3/
483
    if defined?(JRUBY_VERSION)
O
Oscar Del Ben 已提交
484
      assert_gem "activerecord-jdbcsqlite3-adapter"
485 486
    else
      assert_gem "sqlite3"
487
    end
488 489
  end

490
  def test_config_mysql_database
491 492
    run_generator([destination_root, "-d", "mysql"])
    assert_file "config/database.yml", /mysql/
493
    if defined?(JRUBY_VERSION)
O
Oscar Del Ben 已提交
494
      assert_gem "activerecord-jdbcmysql-adapter"
495
    else
496
      assert_gem "mysql2", "'>= 0.4.4'"
497
    end
J
José Valim 已提交
498 499
  end

500 501 502 503 504
  def test_config_database_app_name_with_period
    run_generator [File.join(destination_root, "common.usage.com"), "-d", "postgresql"]
    assert_file "common.usage.com/config/database.yml", /common_usage_com/
  end

505 506 507
  def test_config_postgresql_database
    run_generator([destination_root, "-d", "postgresql"])
    assert_file "config/database.yml", /postgresql/
508
    if defined?(JRUBY_VERSION)
O
Oscar Del Ben 已提交
509
      assert_gem "activerecord-jdbcpostgresql-adapter"
510
    else
511
      assert_gem "pg", "'>= 0.18', '< 2.0'"
512 513 514
    end
  end

515
  def test_config_jdbcmysql_database
516
    run_generator([destination_root, "-d", "jdbcmysql"])
517
    assert_file "config/database.yml", /mysql/
O
Oscar Del Ben 已提交
518
    assert_gem "activerecord-jdbcmysql-adapter"
519 520
  end

521 522
  def test_config_jdbcsqlite3_database
    run_generator([destination_root, "-d", "jdbcsqlite3"])
523
    assert_file "config/database.yml", /sqlite3/
O
Oscar Del Ben 已提交
524
    assert_gem "activerecord-jdbcsqlite3-adapter"
525 526
  end

527 528
  def test_config_jdbcpostgresql_database
    run_generator([destination_root, "-d", "jdbcpostgresql"])
529
    assert_file "config/database.yml", /postgresql/
O
Oscar Del Ben 已提交
530
    assert_gem "activerecord-jdbcpostgresql-adapter"
531 532
  end

A
Arun Agrawal 已提交
533
  def test_config_jdbc_database
534
    run_generator([destination_root, "-d", "jdbc"])
A
Arun Agrawal 已提交
535
    assert_file "config/database.yml", /jdbc/
536
    assert_file "config/database.yml", /mssql/
O
Oscar Del Ben 已提交
537
    assert_gem "activerecord-jdbc-adapter"
A
Arun Agrawal 已提交
538 539
  end

540 541
  if defined?(JRUBY_VERSION)
    def test_config_jdbc_database_when_no_option_given
542
      run_generator
543
      assert_file "config/database.yml", /sqlite3/
O
Oscar Del Ben 已提交
544
      assert_gem "activerecord-jdbcsqlite3-adapter"
545 546 547
    end
  end

S
schneems 已提交
548 549
  def test_generator_defaults_to_puma_version
    run_generator [destination_root]
550
    assert_gem "puma", "'~> 3.11'"
S
schneems 已提交
551 552
  end

S
schneems 已提交
553 554 555
  def test_generator_if_skip_puma_is_given
    run_generator [destination_root, "--skip-puma"]
    assert_no_file "config/puma.rb"
556
    assert_no_gem "puma"
S
schneems 已提交
557 558
  end

559 560 561
  def test_generator_has_assets_gems
    run_generator

562
    assert_gem "sass-rails"
563 564
  end

565 566
  def test_action_cable_redis_gems
    run_generator
567
    assert_file "Gemfile", /^# gem 'redis'/
568 569
  end

570 571
  def test_generator_if_skip_test_is_given
    run_generator [destination_root, "--skip-test"]
572 573 574

    assert_file "config/application.rb", /#\s+require\s+["']rails\/test_unit\/railtie["']/

575 576 577
    assert_no_gem "capybara"
    assert_no_gem "selenium-webdriver"
    assert_no_gem "chromedriver-helper"
578 579

    assert_no_directory("test")
580 581 582
  end

  def test_generator_if_skip_system_test_is_given
583
    run_generator [destination_root, "--skip-system-test"]
584 585 586
    assert_no_gem "capybara"
    assert_no_gem "selenium-webdriver"
    assert_no_gem "chromedriver-helper"
587 588 589 590

    assert_directory("test")

    assert_no_directory("test/system")
591 592
  end

593
  def test_does_not_generate_system_test_files_if_skip_system_test_is_given
594
    run_generator [destination_root, "--skip-system-test"]
595 596 597 598 599 600 601 602 603

    Dir.chdir(destination_root) do
      quietly { `./bin/rails g scaffold User` }

      assert_no_file("test/application_system_test_case.rb")
      assert_no_file("test/system/users_test.rb")
    end
  end

604 605
  def test_javascript_is_skipped_if_required
    run_generator [destination_root, "--skip-javascript"]
606

607
    assert_no_file "app/javascript"
608

609
    assert_file "app/views/layouts/application.html.erb" do |contents|
610 611
      assert_match(/stylesheet_link_tag\s+'application', media: 'all' %>/, contents)
      assert_no_match(/javascript_include_tag\s+'application' \%>/, contents)
612
    end
S
Sean Griffin 已提交
613 614
  end

A
Arun Agrawal 已提交
615 616
  def test_inclusion_of_jbuilder
    run_generator
617
    assert_gem "jbuilder"
A
Arun Agrawal 已提交
618 619
  end

620
  def test_inclusion_of_a_debugger
621
    run_generator
622
    if defined?(JRUBY_VERSION) || RUBY_ENGINE == "rbx"
623
      assert_no_gem "byebug"
624
    else
625
      assert_gem "byebug"
A
Arun Agrawal 已提交
626
    end
627 628
  end

629
  def test_inclusion_of_listen_related_configuration_by_default
630
    run_generator
631
    if RbConfig::CONFIG["host_os"] =~ /darwin|linux/
632
      assert_listen_related_configuration
633
    else
634
      assert_no_listen_related_configuration
635 636 637
    end
  end

638
  def test_non_inclusion_of_listen_related_configuration_if_skip_listen
639
    run_generator [destination_root, "--skip-listen"]
640 641 642
    assert_no_listen_related_configuration
  end

643 644
  def test_evented_file_update_checker_config
    run_generator
645 646
    assert_file "config/environments/development.rb" do |content|
      if RbConfig::CONFIG["host_os"] =~ /darwin|linux/
647
        assert_match(/^\s*config\.file_watcher = ActiveSupport::EventedFileUpdateChecker/, content)
648
      else
649
        assert_match(/^\s*# config\.file_watcher = ActiveSupport::EventedFileUpdateChecker/, content)
650 651 652 653
      end
    end
  end

654
  def test_template_from_dir_pwd
655
    FileUtils.cd(Rails.root)
656
    assert_match(/It works from file!/, run_generator([destination_root, "-m", "lib/template.rb"]))
657 658
  end

J
José Valim 已提交
659
  def test_usage_read_from_file
660 661 662
    assert_called(File, :read, returns: "USAGE FROM FILE") do
      assert_equal "USAGE FROM FILE", Rails::Generators::AppGenerator.desc
    end
J
José Valim 已提交
663 664 665
  end

  def test_default_usage
666 667 668
    assert_called(Rails::Generators::AppGenerator, :usage_path, returns: nil) do
      assert_match(/Create rails files for app generator/, Rails::Generators::AppGenerator.desc)
    end
J
José Valim 已提交
669 670 671
  end

  def test_default_namespace
672
    assert_match "rails:app", Rails::Generators::AppGenerator.namespace
J
José Valim 已提交
673 674
  end

675
  def test_file_is_added_for_backwards_compatibility
676 677
    action :file, "lib/test_file.rb", "heres test data"
    assert_file "lib/test_file.rb", "heres test data"
678 679
  end

680 681 682
  def test_pretend_option
    output = run_generator [File.join(destination_root, "myapp"), "--pretend"]
    assert_no_match(/run  bundle install/, output)
683
    assert_no_match(/run  git init/, output)
684 685
  end

686 687 688 689 690
  def test_quiet_option
    output = run_generator [File.join(destination_root, "myapp"), "--quiet"]
    assert_empty output
  end

691
  def test_force_option_overwrites_every_file_except_master_key
692 693 694
    run_generator [File.join(destination_root, "myapp")]
    output = run_generator [File.join(destination_root, "myapp"), "--force"]
    assert_match(/force/, output)
695
    assert_no_match("force  config/master.key", output)
696 697
  end

698
  def test_application_name_with_spaces
699
    path = File.join(destination_root, "foo bar")
700 701

    # This also applies to MySQL apps but not with SQLite
702
    run_generator [path, "-d", "postgresql"]
703 704 705 706

    assert_file "foo bar/config/database.yml", /database: foo_bar_development/
  end

707 708
  def test_web_console
    run_generator
709
    assert_gem "web-console"
710 711
  end

712 713 714 715
  def test_web_console_with_dev_option
    run_generator [destination_root, "--dev"]

    assert_file "Gemfile" do |content|
M
Mehmet Emin İNAÇ 已提交
716
      assert_match(/gem 'web-console',\s+github: 'rails\/web-console'/, content)
717
      assert_no_match(/\Agem 'web-console', '>= 3\.3\.0'\z/, content)
718 719 720 721 722 723 724
    end
  end

  def test_web_console_with_edge_option
    run_generator [destination_root, "--edge"]

    assert_file "Gemfile" do |content|
M
Mehmet Emin İNAÇ 已提交
725
      assert_match(/gem 'web-console',\s+github: 'rails\/web-console'/, content)
726
      assert_no_match(/\Agem 'web-console', '>= 3\.3\.0'\z/, content)
727 728 729
    end
  end

730
  def test_generation_runs_bundle_install
731 732 733
    generator([destination_root], {})

    assert_bundler_command_called("install")
734 735 736
  end

  def test_dev_option
737 738 739
    generator([destination_root], dev: true)

    assert_bundler_command_called("install")
740 741
    rails_path = File.expand_path("../../..", Rails.root)
    assert_file "Gemfile", /^gem\s+["']rails["'],\s+path:\s+["']#{Regexp.escape(rails_path)}["']$/
742 743 744
  end

  def test_edge_option
745 746 747
    generator([destination_root], edge: true)

    assert_bundler_command_called("install")
748
    assert_file "Gemfile", %r{^gem\s+["']rails["'],\s+github:\s+["']#{Regexp.escape("rails/rails")}["']$}
749 750
  end

751 752
  def test_spring
    run_generator
753
    assert_gem "spring"
754 755
  end

756 757 758 759
  def test_bundler_binstub
    assert_bundler_command_called("binstubs bundler")
  end

760
  def test_spring_binstubs
761
    jruby_skip "spring doesn't run on JRuby"
762

763
    assert_bundler_command_called("exec spring binstub --all")
764 765 766
  end

  def test_spring_no_fork
767
    jruby_skip "spring doesn't run on JRuby"
R
Rafael Mendonça França 已提交
768
    assert_called_with(Process, :respond_to?, [[:fork], [:fork]], returns: false) do
769
      run_generator
770

771
      assert_no_gem "spring"
772 773 774 775 776 777
    end
  end

  def test_skip_spring
    run_generator [destination_root, "--skip-spring"]

778
    assert_no_file "config/spring.rb"
779
    assert_no_gem "spring"
780 781
  end

782 783 784
  def test_spring_with_dev_option
    run_generator [destination_root, "--dev"]

785
    assert_no_gem "spring"
786 787
  end

788
  def test_skip_javascript_option
789 790
    command_check = -> command, *_ do
      @called ||= 0
T
Tsukuru Tanimichi 已提交
791 792
      if command == "webpacker:install"
        @called += 1
793
        assert_equal 0, @called, "webpacker:install expected not to be called once, but was called #{@called} times."
T
Tsukuru Tanimichi 已提交
794
      end
795 796
    end

797
    generator([destination_root], skip_javascript: true).stub(:rails_command, command_check) do
798 799 800
      generator.stub :bundle_command, nil do
        quietly { generator.invoke_all }
      end
801 802
    end

803
    assert_no_gem "webpacker"
804 805
  end

806 807 808 809 810 811 812 813 814 815 816 817 818 819 820
  def test_webpack_option_with_js_framework
    command_check = -> command, *_ do
      case command
      when "webpacker:install"
        @webpacker ||= 0
        @webpacker += 1
        assert_equal 1, @webpacker, "webpacker:install expected to be called once, but was called #{@webpacker} times."
      when "webpacker:install:react"
        @react ||= 0
        @react += 1
        assert_equal 1, @react, "webpacker:install:react expected to be called once, but was called #{@react} times."
      end
    end

    generator([destination_root], webpack: "react").stub(:rails_command, command_check) do
821 822 823
      generator.stub :bundle_command, nil do
        quietly { generator.invoke_all }
      end
824
    end
825 826

    assert_gem "webpacker"
827 828
  end

Y
yuuji.yaginuma 已提交
829 830 831 832 833 834 835 836 837 838 839 840 841 842
  def test_skip_webpack_install
    command_check = -> command do
      if command == "webpacker:install"
        assert false, "webpacker:install expected not to be called."
      end
    end

    generator([destination_root], skip_webpack_install: true).stub(:rails_command, command_check) do
      quietly { generator.invoke_all }
    end

    assert_gem "webpacker"
  end

843
  def test_generator_if_skip_turbolinks_is_given
844
    run_generator [destination_root, "--skip-turbolinks"]
845

846
    assert_no_gem "turbolinks"
847 848 849
    assert_file "app/views/layouts/application.html.erb" do |content|
      assert_no_match(/data-turbolinks-track/, content)
    end
850
    assert_file "app/javascript/packs/application.js" do |content|
851 852 853 854
      assert_no_match(/turbolinks/, content)
    end
  end

Y
yuuji.yaginuma 已提交
855
  def test_bootsnap
856
    run_generator [destination_root, "--no-skip-bootsnap"]
Y
yuuji.yaginuma 已提交
857

858 859 860 861 862 863
    unless defined?(JRUBY_VERSION)
      assert_gem "bootsnap"
      assert_file "config/boot.rb" do |content|
        assert_match(/require 'bootsnap\/setup'/, content)
      end
    else
864
      assert_no_gem "bootsnap"
865 866 867
      assert_file "config/boot.rb" do |content|
        assert_no_match(/require 'bootsnap\/setup'/, content)
      end
Y
yuuji.yaginuma 已提交
868 869 870 871 872 873
    end
  end

  def test_skip_bootsnap
    run_generator [destination_root, "--skip-bootsnap"]

874
    assert_no_gem "bootsnap"
Y
yuuji.yaginuma 已提交
875 876 877 878 879
    assert_file "config/boot.rb" do |content|
      assert_no_match(/require 'bootsnap\/setup'/, content)
    end
  end

880 881 882
  def test_bootsnap_with_dev_option
    run_generator [destination_root, "--dev"]

883
    assert_no_gem "bootsnap"
884 885 886 887 888
    assert_file "config/boot.rb" do |content|
      assert_no_match(/require 'bootsnap\/setup'/, content)
    end
  end

889 890 891 892 893 894 895
  def test_inclusion_of_ruby_version
    run_generator

    assert_file "Gemfile" do |content|
      assert_match(/ruby '#{RUBY_VERSION}'/, content)
    end
    assert_file ".ruby-version" do |content|
896 897 898 899 900 901 902
      if ENV["RBENV_VERSION"]
        assert_match(/#{ENV["RBENV_VERSION"]}/, content)
      elsif ENV["rvm_ruby_string"]
        assert_match(/#{ENV["rvm_ruby_string"]}/, content)
      else
        assert_match(/#{RUBY_ENGINE}-#{RUBY_ENGINE_VERSION}/, content)
      end
903 904 905
    end
  end

906 907 908 909 910
  def test_version_control_initializes_git_repo
    run_generator [destination_root]
    assert_directory ".git"
  end

911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933
  def test_create_keeps
    run_generator
    folders_with_keep = %w(
      app/assets/images
      app/controllers/concerns
      app/models/concerns
      lib/tasks
      lib/assets
      log
      test/fixtures
      test/fixtures/files
      test/controllers
      test/mailers
      test/models
      test/helpers
      test/integration
      tmp
    )
    folders_with_keep.each do |folder|
      assert_file("#{folder}/.keep")
    end
  end

934 935
  def test_psych_gem
    run_generator
936
    gem_regex = /gem 'psych',\s+'~> 2\.0',\s+platforms: :rbx/
937 938 939 940 941 942 943 944 945 946

    assert_file "Gemfile" do |content|
      if defined?(Rubinius)
        assert_match(gem_regex, content)
      else
        assert_no_match(gem_regex, content)
      end
    end
  end

947
  def test_after_bundle_callback
948
    path = "http://example.org/rails_template"
949
    template = +%{ after_bundle { run 'echo ran after_bundle' } }
950 951
    template.instance_eval "def read; self; end" # Make the string respond to read

952
    check_open = -> *args do
953
      assert_equal [ path, "Accept" => "application/x-thor-template" ], args
954 955
      template
    end
956

957
    sequence = ["git init", "install", "binstubs bundler", "exec spring binstub --all", "webpacker:install", "echo ran after_bundle"]
958
    @sequence_step ||= 0
959
    ensure_bundler_first = -> command, options = nil do
960 961 962 963 964 965 966
      assert_equal sequence[@sequence_step], command, "commands should be called in sequence #{sequence}"
      @sequence_step += 1
    end

    generator([destination_root], template: path).stub(:open, check_open, template) do
      generator.stub(:bundle_command, ensure_bundler_first) do
        generator.stub(:run, ensure_bundler_first) do
967 968 969
          generator.stub(:rails_command, ensure_bundler_first) do
            quietly { generator.invoke_all }
          end
970 971 972
        end
      end
    end
973

974
    assert_equal 6, @sequence_step
975 976
  end

977 978 979 980 981 982 983 984
  def test_gitignore
    run_generator

    assert_file ".gitignore" do |content|
      assert_match(/config\/master\.key/, content)
    end
  end

E
eileencodes 已提交
985 986 987 988
  def test_system_tests_directory_generated
    run_generator

    assert_directory("test/system")
989
    assert_file("test/system/.keep")
E
eileencodes 已提交
990 991
  end

992 993 994 995 996 997 998 999 1000
  unless Gem.win_platform?
    def test_master_key_is_only_readable_by_the_owner
      run_generator

      stat = File.stat("config/master.key")
      assert_equal "100600", sprintf("%o", stat.mode)
    end
  end

E
eileencodes 已提交
1001
  private
1002 1003 1004 1005 1006
    def stub_rails_application(root)
      Rails.application.config.root = root
      Rails.application.class.stub(:name, "Myapp") do
        yield
      end
1007 1008
    end

1009 1010 1011
    def action(*args, &block)
      capture(:stdout) { generator.send(*args, &block) }
    end
O
Oscar Del Ben 已提交
1012

1013 1014 1015 1016 1017 1018
    def assert_gem(gem, constraint = nil)
      if constraint
        assert_file "Gemfile", /^\s*gem\s+["']#{gem}["'], #{constraint}$*/
      else
        assert_file "Gemfile", /^\s*gem\s+["']#{gem}["']$*/
      end
1019
    end
1020

1021 1022 1023 1024 1025 1026
    def assert_no_gem(gem)
      assert_file "Gemfile" do |content|
        assert_no_match(gem, content)
      end
    end

1027
    def assert_listen_related_configuration
1028 1029
      assert_gem "listen"
      assert_gem "spring-watcher-listen"
1030

1031
      assert_file "config/environments/development.rb" do |content|
1032
        assert_match(/^\s*config\.file_watcher = ActiveSupport::EventedFileUpdateChecker/, content)
1033
      end
1034 1035
    end

1036
    def assert_no_listen_related_configuration
1037
      assert_no_gem "listen"
1038

1039
      assert_file "config/environments/development.rb" do |content|
1040
        assert_match(/^\s*# config\.file_watcher = ActiveSupport::EventedFileUpdateChecker/, content)
1041
      end
1042 1043
    end

1044
    def assert_bundler_command_called(target_command)
1045
      command_check = -> command do
1046
        @command_called ||= 0
1047 1048

        case command
1049 1050 1051
        when target_command
          @command_called += 1
          assert_equal 1, @command_called, "#{command} expected to be called once, but was called #{@command_called} times."
1052 1053 1054 1055 1056 1057
        end
      end

      generator.stub :bundle_command, command_check do
        quietly { generator.invoke_all }
      end
1058
    end
1059
end