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

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

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

104 105
  def default_files
    ::DEFAULT_APP_FILES
106 107
  end

108 109 110 111 112 113 114 115 116
  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

117
  def test_assets
118
    run_generator
119

J
Jeroen Visser 已提交
120 121
    assert_file("app/views/layouts/application.html.erb", /stylesheet_link_tag\s+'application', media: 'all', 'data-turbolinks-track': 'reload'/)
    assert_file("app/views/layouts/application.html.erb", /javascript_include_tag\s+'application', 'data-turbolinks-track': 'reload'/)
122
    assert_file("app/assets/stylesheets/application.css")
A
Arun Agrawal 已提交
123
    assert_file("app/assets/javascripts/application.js")
124 125
  end

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

131
  def test_invalid_application_name_raises_an_error
132
    content = capture(:stderr) { run_generator [File.join(destination_root, "43-things")] }
133 134 135 136
    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
137
    run_generator [File.join(destination_root, "things-43")]
138
    assert_file "things-43/config/environment.rb", /Rails\.application\.initialize!/
139
    assert_file "things-43/config/application.rb", /^module Things43$/
140 141
  end

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

  def test_application_new_exits_with_message_and_non_zero_code_when_generating_inside_existing_rails_directory
148
    app_root = File.join(destination_root, "myfirstapp")
149 150 151 152 153 154 155
    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?
156 157
  end

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

168 169 170 171 172 173
  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]

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

178 179
        # make sure we are in correct dir
        FileUtils.cd(app_moved_root)
180

181
        generator = Rails::Generators::AppGenerator.new ["rails"], [],
182 183 184 185 186 187
                                                                   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
188
  end
189

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

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

201 202 203 204 205 206
  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

207 208 209
  def test_new_application_not_include_api_initializers
    run_generator

210
    assert_no_file "config/initializers/cors.rb"
211 212
  end

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

217 218 219 220 221
  def test_new_application_load_defaults
    app_root = File.join(destination_root, "myfirstapp")
    run_generator [app_root]
    output = nil

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

224 225 226 227 228 229 230
    Dir.chdir(app_root) do
      output = `./bin/rails r "puts Rails.application.config.assets.unknown_asset_fallback"`
    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
  def test_application_names_are_not_singularized
    run_generator [File.join(destination_root, "hats")]
443
    assert_file "hats/config/environment.rb", /Rails\.application\.initialize!/
444 445
  end

446 447 448
  def test_gemfile_has_no_whitespace_errors
    run_generator
    absolute = File.expand_path("Gemfile", destination_root)
449
    File.open(absolute, "r") do |f|
450
      f.each_line do |line|
A
Arun Agrawal 已提交
451
        assert_no_match %r{/^[ \t]+$/}, line
452 453 454 455
      end
    end
  end

J
José Valim 已提交
456 457 458
  def test_config_database_is_added_by_default
    run_generator
    assert_file "config/database.yml", /sqlite3/
459
    if defined?(JRUBY_VERSION)
O
Oscar Del Ben 已提交
460
      assert_gem "activerecord-jdbcsqlite3-adapter"
461 462
    else
      assert_gem "sqlite3"
463
    end
464 465
  end

466
  def test_config_mysql_database
467 468
    run_generator([destination_root, "-d", "mysql"])
    assert_file "config/database.yml", /mysql/
469
    if defined?(JRUBY_VERSION)
O
Oscar Del Ben 已提交
470
      assert_gem "activerecord-jdbcmysql-adapter"
471
    else
472
      assert_gem "mysql2", "'>= 0.4.4', '< 0.6.0'"
473
    end
J
José Valim 已提交
474 475
  end

476 477 478 479 480
  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

481 482 483
  def test_config_postgresql_database
    run_generator([destination_root, "-d", "postgresql"])
    assert_file "config/database.yml", /postgresql/
484
    if defined?(JRUBY_VERSION)
O
Oscar Del Ben 已提交
485
      assert_gem "activerecord-jdbcpostgresql-adapter"
486
    else
487
      assert_gem "pg", "'>= 0.18', '< 2.0'"
488 489 490
    end
  end

491
  def test_config_jdbcmysql_database
492
    run_generator([destination_root, "-d", "jdbcmysql"])
493
    assert_file "config/database.yml", /mysql/
O
Oscar Del Ben 已提交
494
    assert_gem "activerecord-jdbcmysql-adapter"
495 496
  end

497 498
  def test_config_jdbcsqlite3_database
    run_generator([destination_root, "-d", "jdbcsqlite3"])
499
    assert_file "config/database.yml", /sqlite3/
O
Oscar Del Ben 已提交
500
    assert_gem "activerecord-jdbcsqlite3-adapter"
501 502
  end

503 504
  def test_config_jdbcpostgresql_database
    run_generator([destination_root, "-d", "jdbcpostgresql"])
505
    assert_file "config/database.yml", /postgresql/
O
Oscar Del Ben 已提交
506
    assert_gem "activerecord-jdbcpostgresql-adapter"
507 508
  end

A
Arun Agrawal 已提交
509
  def test_config_jdbc_database
510
    run_generator([destination_root, "-d", "jdbc"])
A
Arun Agrawal 已提交
511
    assert_file "config/database.yml", /jdbc/
512
    assert_file "config/database.yml", /mssql/
O
Oscar Del Ben 已提交
513
    assert_gem "activerecord-jdbc-adapter"
A
Arun Agrawal 已提交
514 515
  end

516 517
  if defined?(JRUBY_VERSION)
    def test_config_jdbc_database_when_no_option_given
518
      run_generator
519
      assert_file "config/database.yml", /sqlite3/
O
Oscar Del Ben 已提交
520
      assert_gem "activerecord-jdbcsqlite3-adapter"
521 522 523
    end
  end

S
schneems 已提交
524 525
  def test_generator_defaults_to_puma_version
    run_generator [destination_root]
526
    assert_gem "puma", "'~> 3.11'"
S
schneems 已提交
527 528
  end

S
schneems 已提交
529 530 531
  def test_generator_if_skip_puma_is_given
    run_generator [destination_root, "--skip-puma"]
    assert_no_file "config/puma.rb"
532
    assert_no_gem "puma"
S
schneems 已提交
533 534
  end

535 536 537
  def test_generator_has_assets_gems
    run_generator

538 539
    assert_gem "sass-rails"
    assert_gem "uglifier"
540 541
  end

542 543
  def test_action_cable_redis_gems
    run_generator
544
    assert_file "Gemfile", /^# gem 'redis'/
545 546
  end

547 548
  def test_generator_if_skip_test_is_given
    run_generator [destination_root, "--skip-test"]
549 550 551

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

552 553 554
    assert_no_gem "capybara"
    assert_no_gem "selenium-webdriver"
    assert_no_gem "chromedriver-helper"
555 556

    assert_no_directory("test")
557 558 559
  end

  def test_generator_if_skip_system_test_is_given
560
    run_generator [destination_root, "--skip-system-test"]
561 562 563
    assert_no_gem "capybara"
    assert_no_gem "selenium-webdriver"
    assert_no_gem "chromedriver-helper"
564 565 566 567

    assert_directory("test")

    assert_no_directory("test/system")
568 569
  end

570
  def test_does_not_generate_system_test_files_if_skip_system_test_is_given
571
    run_generator [destination_root, "--skip-system-test"]
572 573 574 575 576 577 578 579 580

    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

581
  def test_inclusion_of_javascript_runtime
582
    run_generator
583
    if defined?(JRUBY_VERSION)
O
Oscar Del Ben 已提交
584
      assert_gem "therubyrhino"
585 586
    elsif RUBY_PLATFORM =~ /mingw|mswin/
      assert_gem "duktape"
587
    else
S
Sam 已提交
588
      assert_file "Gemfile", /# gem 'mini_racer', platforms: :ruby/
589 590 591
    end
  end

592
  def test_rails_ujs_is_the_default_ujs_library
593 594
    run_generator
    assert_file "app/assets/javascripts/application.js" do |contents|
595
      assert_match %r{^//= require rails-ujs}, contents
596 597 598
    end
  end

599 600
  def test_javascript_is_skipped_if_required
    run_generator [destination_root, "--skip-javascript"]
601 602 603

    assert_no_file "app/assets/javascripts"

604
    assert_file "app/views/layouts/application.html.erb" do |contents|
605 606
      assert_match(/stylesheet_link_tag\s+'application', media: 'all' %>/, contents)
      assert_no_match(/javascript_include_tag\s+'application' \%>/, contents)
607
    end
608

609 610
    assert_no_gem "coffee-rails"
    assert_no_gem "uglifier"
611 612 613

    assert_file "config/environments/production.rb" do |content|
      assert_no_match(/config\.assets\.js_compressor = :uglifier/, content)
614
    end
615
  end
616

S
Sean Griffin 已提交
617 618 619 620 621 622 623 624 625
  def test_coffeescript_is_skipped_if_required
    run_generator [destination_root, "--skip-coffee"]

    assert_file "Gemfile" do |content|
      assert_no_match(/coffee-rails/, content)
      assert_match(/uglifier/, content)
    end
  end

A
Arun Agrawal 已提交
626 627
  def test_inclusion_of_jbuilder
    run_generator
628
    assert_gem "jbuilder"
A
Arun Agrawal 已提交
629 630
  end

631
  def test_inclusion_of_a_debugger
632
    run_generator
633
    if defined?(JRUBY_VERSION) || RUBY_ENGINE == "rbx"
634
      assert_no_gem "byebug"
635
    else
636
      assert_gem "byebug"
A
Arun Agrawal 已提交
637
    end
638 639
  end

640
  def test_inclusion_of_listen_related_configuration_by_default
641
    run_generator
642
    if RbConfig::CONFIG["host_os"] =~ /darwin|linux/
643
      assert_listen_related_configuration
644
    else
645
      assert_no_listen_related_configuration
646 647 648
    end
  end

649
  def test_non_inclusion_of_listen_related_configuration_if_skip_listen
650
    run_generator [destination_root, "--skip-listen"]
651 652 653
    assert_no_listen_related_configuration
  end

654 655
  def test_evented_file_update_checker_config
    run_generator
656 657
    assert_file "config/environments/development.rb" do |content|
      if RbConfig::CONFIG["host_os"] =~ /darwin|linux/
658
        assert_match(/^\s*config\.file_watcher = ActiveSupport::EventedFileUpdateChecker/, content)
659
      else
660
        assert_match(/^\s*# config\.file_watcher = ActiveSupport::EventedFileUpdateChecker/, content)
661 662 663 664
      end
    end
  end

665
  def test_template_from_dir_pwd
666
    FileUtils.cd(Rails.root)
667
    assert_match(/It works from file!/, run_generator([destination_root, "-m", "lib/template.rb"]))
668 669
  end

J
José Valim 已提交
670
  def test_usage_read_from_file
671 672 673
    assert_called(File, :read, returns: "USAGE FROM FILE") do
      assert_equal "USAGE FROM FILE", Rails::Generators::AppGenerator.desc
    end
J
José Valim 已提交
674 675 676
  end

  def test_default_usage
677 678 679
    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 已提交
680 681 682
  end

  def test_default_namespace
683
    assert_match "rails:app", Rails::Generators::AppGenerator.namespace
J
José Valim 已提交
684 685
  end

686
  def test_file_is_added_for_backwards_compatibility
687 688
    action :file, "lib/test_file.rb", "heres test data"
    assert_file "lib/test_file.rb", "heres test data"
689 690
  end

691 692 693
  def test_pretend_option
    output = run_generator [File.join(destination_root, "myapp"), "--pretend"]
    assert_no_match(/run  bundle install/, output)
694
    assert_no_match(/run  git init/, output)
695 696
  end

697 698 699 700 701
  def test_quiet_option
    output = run_generator [File.join(destination_root, "myapp"), "--quiet"]
    assert_empty output
  end

702
  def test_force_option_overwrites_every_file_except_master_key
703 704 705
    run_generator [File.join(destination_root, "myapp")]
    output = run_generator [File.join(destination_root, "myapp"), "--force"]
    assert_match(/force/, output)
706
    assert_no_match("force  config/master.key", output)
707 708
  end

709
  def test_application_name_with_spaces
710
    path = File.join(destination_root, "foo bar")
711 712

    # This also applies to MySQL apps but not with SQLite
713
    run_generator [path, "-d", "postgresql"]
714 715 716 717

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

718 719
  def test_web_console
    run_generator
720
    assert_gem "web-console"
721 722
  end

723 724 725 726
  def test_web_console_with_dev_option
    run_generator [destination_root, "--dev"]

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

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

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

741 742 743 744 745 746
  def test_generation_runs_bundle_install
    assert_generates_with_bundler
  end

  def test_dev_option
    assert_generates_with_bundler dev: true
747 748
    rails_path = File.expand_path("../../..", Rails.root)
    assert_file "Gemfile", /^gem\s+["']rails["'],\s+path:\s+["']#{Regexp.escape(rails_path)}["']$/
749 750 751 752
  end

  def test_edge_option
    assert_generates_with_bundler edge: true
753
    assert_file "Gemfile", %r{^gem\s+["']rails["'],\s+github:\s+["']#{Regexp.escape("rails/rails")}["']$}
754 755
  end

756 757
  def test_spring
    run_generator
758
    assert_gem "spring"
759 760 761
  end

  def test_spring_binstubs
762
    jruby_skip "spring doesn't run on JRuby"
763 764 765 766
    command_check = -> command do
      @binstub_called ||= 0

      case command
767
      when "install"
768
        # Called when running bundle, we just want to stub it so nothing to do here.
769
      when "exec spring binstub --all"
770 771 772 773 774 775 776 777
        @binstub_called += 1
        assert_equal 1, @binstub_called, "exec spring binstub --all expected to be called once, but was called #{@install_called} times."
      end
    end

    generator.stub :bundle_command, command_check do
      quietly { generator.invoke_all }
    end
778 779 780
  end

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

785
      assert_no_gem "spring"
786 787 788 789 790 791
    end
  end

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

792
    assert_no_file "config/spring.rb"
793
    assert_no_gem "spring"
794 795
  end

796 797 798
  def test_spring_with_dev_option
    run_generator [destination_root, "--dev"]

799
    assert_no_gem "spring"
800 801
  end

802 803 804
  def test_webpack_option
    command_check = -> command, *_ do
      @called ||= 0
T
Tsukuru Tanimichi 已提交
805 806 807 808
      if command == "webpacker:install"
        @called += 1
        assert_equal 1, @called, "webpacker:install expected to be called once, but was called #{@called} times."
      end
809 810
    end

T
Tsukuru Tanimichi 已提交
811
    generator([destination_root], webpack: "webpack").stub(:rails_command, command_check) do
812 813 814
      generator.stub :bundle_command, nil do
        quietly { generator.invoke_all }
      end
815 816 817 818 819
    end

    assert_gem "webpacker"
  end

820 821 822 823 824 825 826 827 828 829 830 831 832 833 834
  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
835 836 837
      generator.stub :bundle_command, nil do
        quietly { generator.invoke_all }
      end
838 839 840
    end
  end

841 842
  def test_generator_if_skip_turbolinks_is_given
    run_generator [destination_root, "--skip-turbolinks"]
843

844
    assert_no_gem "turbolinks"
845 846 847 848 849 850 851 852
    assert_file "app/views/layouts/application.html.erb" do |content|
      assert_no_match(/data-turbolinks-track/, content)
    end
    assert_file "app/assets/javascripts/application.js" do |content|
      assert_no_match(/turbolinks/, content)
    end
  end

Y
yuuji.yaginuma 已提交
853 854 855
  def test_bootsnap
    run_generator

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

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

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

878 879 880
  def test_bootsnap_with_dev_option
    run_generator [destination_root, "--dev"]

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

887 888 889 890 891 892 893
  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|
894 895 896 897 898 899 900
      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
901 902 903
    end
  end

904 905 906 907 908
  def test_version_control_initializes_git_repo
    run_generator [destination_root]
    assert_directory ".git"
  end

909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931
  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

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

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

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

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

955
    sequence = ["git init", "install", "exec spring binstub --all", "echo ran after_bundle"]
956
    @sequence_step ||= 0
957
    ensure_bundler_first = -> command, options = nil do
958 959 960 961 962 963 964
      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
965 966 967
          generator.stub(:rails_command, ensure_bundler_first) do
            quietly { generator.invoke_all }
          end
968 969 970
        end
      end
    end
971

972
    assert_equal 4, @sequence_step
973 974
  end

975 976 977 978 979 980 981 982
  def test_gitignore
    run_generator

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

E
eileencodes 已提交
983 984 985 986
  def test_system_tests_directory_generated
    run_generator

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

990 991 992 993 994 995 996 997 998
  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 已提交
999
  private
1000 1001 1002 1003 1004
    def stub_rails_application(root)
      Rails.application.config.root = root
      Rails.application.class.stub(:name, "Myapp") do
        yield
      end
1005 1006
    end

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

1011 1012 1013 1014 1015 1016
    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
1017
    end
1018

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

1025
    def assert_listen_related_configuration
1026 1027
      assert_gem "listen"
      assert_gem "spring-watcher-listen"
1028

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

1034
    def assert_no_listen_related_configuration
1035
      assert_no_gem "listen"
1036

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

1042 1043 1044 1045 1046 1047 1048
    def assert_generates_with_bundler(options = {})
      generator([destination_root], options)

      command_check = -> command do
        @install_called ||= 0

        case command
1049
        when "install"
1050 1051
          @install_called += 1
          assert_equal 1, @install_called, "install expected to be called once, but was called #{@install_called} times"
1052
        when "exec spring binstub --all"
1053 1054 1055 1056 1057 1058 1059
          # Called when running tests with spring, let through unscathed.
        end
      end

      generator.stub :bundle_command, command_check do
        quietly { generator.invoke_all }
      end
1060
    end
1061
end