app_generator_test.rb 31.3 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 [destination_root, "--no-skip-javascript"]
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
A
Andrew White 已提交
212
    assert_no_file "config/initializers/new_framework_defaults_6_0.rb"
213 214
  end

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

219 220
    output = nil

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

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

    assert_equal "false\n", output
  end

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

234
    stub_rails_application(app_root) do
235
      generator = Rails::Generators::AppGenerator.new ["rails"], [], destination_root: app_root, shell: @shell
236 237 238 239
      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
240 241
  end

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

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

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

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

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

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

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

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

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

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

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

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

298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318
  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

319 320 321 322 323 324 325 326 327 328 329 330 331
  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

332 333 334 335 336 337 338 339 340 341 342
  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

343 344 345 346 347 348 349 350 351 352 353 354 355 356
  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

357 358 359 360 361 362 363 364 365 366 367 368 369
  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 已提交
370
  def test_gem_for_active_storage
371
    run_generator
372
    assert_file "Gemfile", /^# gem 'image_processing'/
373 374
  end

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

378
    assert_no_gem "image_processing"
379 380
  end

381 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
  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

427 428 429 430 431 432 433 434 435 436 437 438 439
  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

440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463
  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

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

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

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

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

499 500 501 502 503
  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

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

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

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

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

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

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

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

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

558 559 560
  def test_generator_has_assets_gems
    run_generator

561
    assert_gem "sass-rails"
562 563
  end

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

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

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

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

    assert_no_directory("test")
579 580 581
  end

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

    assert_directory("test")

    assert_no_directory("test/system")
590 591
  end

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

    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

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

    assert_no_file "app/assets/javascripts"

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

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

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

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

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

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

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

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

  def test_default_usage
665 666 667
    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 已提交
668 669 670
  end

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    assert_bundler_command_called("install")
733 734 735
  end

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

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

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

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

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

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

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

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

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

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

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

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

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

784
    assert_no_gem "spring"
785 786
  end

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

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

802
    assert_no_gem "webpacker"
803 804
  end

805 806 807 808 809 810 811 812 813 814 815 816 817 818 819
  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
820 821 822
      generator.stub :bundle_command, nil do
        quietly { generator.invoke_all }
      end
823
    end
824 825

    assert_gem "webpacker"
826 827
  end

828
  def test_generator_if_skip_turbolinks_is_given
829
    run_generator [destination_root, "--skip-turbolinks", "--no-skip-javascript"]
830

831
    assert_no_gem "turbolinks"
832 833 834
    assert_file "app/views/layouts/application.html.erb" do |content|
      assert_no_match(/data-turbolinks-track/, content)
    end
835
    assert_file "app/javascript/packs/application.js" do |content|
836 837 838 839
      assert_no_match(/turbolinks/, content)
    end
  end

Y
yuuji.yaginuma 已提交
840
  def test_bootsnap
841
    run_generator [destination_root, "--no-skip-bootsnap"]
Y
yuuji.yaginuma 已提交
842

843 844 845 846 847 848
    unless defined?(JRUBY_VERSION)
      assert_gem "bootsnap"
      assert_file "config/boot.rb" do |content|
        assert_match(/require 'bootsnap\/setup'/, content)
      end
    else
849
      assert_no_gem "bootsnap"
850 851 852
      assert_file "config/boot.rb" do |content|
        assert_no_match(/require 'bootsnap\/setup'/, content)
      end
Y
yuuji.yaginuma 已提交
853 854 855 856 857 858
    end
  end

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

859
    assert_no_gem "bootsnap"
Y
yuuji.yaginuma 已提交
860 861 862 863 864
    assert_file "config/boot.rb" do |content|
      assert_no_match(/require 'bootsnap\/setup'/, content)
    end
  end

865 866 867
  def test_bootsnap_with_dev_option
    run_generator [destination_root, "--dev"]

868
    assert_no_gem "bootsnap"
869 870 871 872 873
    assert_file "config/boot.rb" do |content|
      assert_no_match(/require 'bootsnap\/setup'/, content)
    end
  end

874 875 876 877 878 879 880
  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|
881 882 883 884 885 886 887
      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
888 889 890
    end
  end

891 892 893 894 895
  def test_version_control_initializes_git_repo
    run_generator [destination_root]
    assert_directory ".git"
  end

896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918
  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

919 920
  def test_psych_gem
    run_generator
921
    gem_regex = /gem 'psych',\s+'~> 2\.0',\s+platforms: :rbx/
922 923 924 925 926 927 928 929 930 931

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

932
  def test_after_bundle_callback
933
    path = "http://example.org/rails_template"
934
    template = +%{ after_bundle { run 'echo ran after_bundle' } }
935 936
    template.instance_eval "def read; self; end" # Make the string respond to read

937
    check_open = -> *args do
938
      assert_equal [ path, "Accept" => "application/x-thor-template" ], args
939 940
      template
    end
941

942
    sequence = ["git init", "install", "binstubs bundler", "exec spring binstub --all", "webpacker:install", "echo ran after_bundle"]
943
    @sequence_step ||= 0
944
    ensure_bundler_first = -> command, options = nil do
945 946 947 948 949 950 951
      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
952 953 954
          generator.stub(:rails_command, ensure_bundler_first) do
            quietly { generator.invoke_all }
          end
955 956 957
        end
      end
    end
958

959
    assert_equal 6, @sequence_step
960 961
  end

962 963 964 965 966 967 968 969
  def test_gitignore
    run_generator

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

E
eileencodes 已提交
970 971 972 973
  def test_system_tests_directory_generated
    run_generator

    assert_directory("test/system")
974
    assert_file("test/system/.keep")
E
eileencodes 已提交
975 976
  end

977 978 979 980 981 982 983 984 985
  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 已提交
986
  private
987 988 989 990 991
    def stub_rails_application(root)
      Rails.application.config.root = root
      Rails.application.class.stub(:name, "Myapp") do
        yield
      end
992 993
    end

994 995 996
    def action(*args, &block)
      capture(:stdout) { generator.send(*args, &block) }
    end
O
Oscar Del Ben 已提交
997

998 999 1000 1001 1002 1003
    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
1004
    end
1005

1006 1007 1008 1009 1010 1011
    def assert_no_gem(gem)
      assert_file "Gemfile" do |content|
        assert_no_match(gem, content)
      end
    end

1012
    def assert_listen_related_configuration
1013 1014
      assert_gem "listen"
      assert_gem "spring-watcher-listen"
1015

1016
      assert_file "config/environments/development.rb" do |content|
1017
        assert_match(/^\s*config\.file_watcher = ActiveSupport::EventedFileUpdateChecker/, content)
1018
      end
1019 1020
    end

1021
    def assert_no_listen_related_configuration
1022
      assert_no_gem "listen"
1023

1024
      assert_file "config/environments/development.rb" do |content|
1025
        assert_match(/^\s*# config\.file_watcher = ActiveSupport::EventedFileUpdateChecker/, content)
1026
      end
1027 1028
    end

1029
    def assert_bundler_command_called(target_command)
1030
      command_check = -> command do
1031
        @command_called ||= 0
1032 1033

        case command
1034 1035 1036
        when target_command
          @command_called += 1
          assert_equal 1, @command_called, "#{command} expected to be called once, but was called #{@command_called} times."
1037 1038 1039 1040 1041 1042
        end
      end

      generator.stub :bundle_command, command_check do
        quietly { generator.invoke_all }
      end
1043
    end
1044
end