app_generator_test.rb 27.6 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
  def test_assets
109
    run_generator
110

J
Jeroen Visser 已提交
111 112
    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'/)
113
    assert_file("app/assets/stylesheets/application.css")
A
Arun Agrawal 已提交
114
    assert_file("app/assets/javascripts/application.js")
115 116
  end

117 118 119 120 121
  def test_application_job_file_present
    run_generator
    assert_file("app/jobs/application_job.rb")
  end

122
  def test_invalid_application_name_raises_an_error
123
    content = capture(:stderr) { run_generator [File.join(destination_root, "43-things")] }
124 125 126 127
    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
128
    run_generator [File.join(destination_root, "things-43")]
129
    assert_file "things-43/config/environment.rb", /Rails\.application\.initialize!/
130
    assert_file "things-43/config/application.rb", /^module Things43$/
131 132
  end

133
  def test_application_new_exits_with_non_zero_code_on_invalid_application_name
134
    quietly { system "rails new test --no-rc" }
135
    assert_equal false, $?.success?
136 137 138
  end

  def test_application_new_exits_with_message_and_non_zero_code_when_generating_inside_existing_rails_directory
139
    app_root = File.join(destination_root, "myfirstapp")
140 141 142 143 144 145 146
    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?
147 148
  end

149
  def test_application_new_show_help_message_inside_existing_rails_directory
150
    app_root = File.join(destination_root, "myfirstapp")
151 152 153 154
    run_generator [app_root]
    output = Dir.chdir(app_root) do
      `rails new --help`
    end
155
    assert_match(/rails new APP_PATH \[options\]/, output)
156 157 158
    assert_equal true, $?.success?
  end

159 160 161 162 163 164
  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]

165 166 167
    stub_rails_application(app_moved_root) do
      Rails.application.stub(:is_a?, -> *args { Rails::Application }) do
        FileUtils.mv(app_root, app_moved_root)
168

169 170
        # make sure we are in correct dir
        FileUtils.cd(app_moved_root)
171

172
        generator = Rails::Generators::AppGenerator.new ["rails"], [],
173 174 175 176 177 178
                                                                   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
179
  end
180

181
  def test_app_update_generates_correct_session_key
182
    app_root = File.join(destination_root, "myapp")
183
    run_generator [app_root]
184

185
    stub_rails_application(app_root) do
186
      generator = Rails::Generators::AppGenerator.new ["rails"], [], destination_root: app_root, shell: @shell
187 188 189
      generator.send(:app_const)
      quietly { generator.send(:update_config_files) }
    end
190
  end
191

192 193 194 195 196 197
  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

198 199 200
  def test_new_application_not_include_api_initializers
    run_generator

201
    assert_no_file "config/initializers/cors.rb"
202 203
  end

204
  def test_new_application_doesnt_need_defaults
205
    assert_no_file "config/initializers/new_framework_defaults_5_2.rb"
206 207
  end

208 209 210 211 212 213 214 215 216 217 218 219
  def test_new_application_load_defaults
    app_root = File.join(destination_root, "myfirstapp")
    run_generator [app_root]
    output = nil

    Dir.chdir(app_root) do
      output = `./bin/rails r "puts Rails.application.config.assets.unknown_asset_fallback"`
    end

    assert_equal "false\n", output
  end

220
  def test_app_update_keep_the_cookie_serializer_if_it_is_already_configured
221
    app_root = File.join(destination_root, "myapp")
222 223
    run_generator [app_root]

224
    stub_rails_application(app_root) do
225
      generator = Rails::Generators::AppGenerator.new ["rails"], [], destination_root: app_root, shell: @shell
226 227 228 229
      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
230 231
  end

232
  def test_app_update_set_the_cookie_serializer_to_marshal_if_it_is_not_already_configured
233
    app_root = File.join(destination_root, "myapp")
234 235 236 237
    run_generator [app_root]

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

238
    stub_rails_application(app_root) do
239
      generator = Rails::Generators::AppGenerator.new ["rails"], [], destination_root: app_root, shell: @shell
240 241
      generator.send(:app_const)
      quietly { generator.send(:update_config_files) }
242 243
      assert_file("#{app_root}/config/initializers/cookies_serializer.rb",
                  /Valid options are :json, :marshal, and :hybrid\.\nRails\.application\.config\.action_dispatch\.cookies_serializer = :marshal/)
244
    end
245 246
  end

247
  def test_app_update_create_new_framework_defaults
248
    app_root = File.join(destination_root, "myapp")
249 250
    run_generator [app_root]

251
    assert_no_file "#{app_root}/config/initializers/new_framework_defaults_5_2.rb"
252 253

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

258
      assert_file "#{app_root}/config/initializers/new_framework_defaults_5_2.rb"
259 260 261
    end
  end

262
  def test_app_update_does_not_create_rack_cors
263
    app_root = File.join(destination_root, "myapp")
264 265 266
    run_generator [app_root]

    stub_rails_application(app_root) do
267
      generator = Rails::Generators::AppGenerator.new ["rails"], [], destination_root: app_root, shell: @shell
268 269 270 271 272 273
      generator.send(:app_const)
      quietly { generator.send(:update_config_files) }
      assert_no_file "#{app_root}/config/initializers/cors.rb"
    end
  end

274
  def test_app_update_does_not_remove_rack_cors_if_already_present
275
    app_root = File.join(destination_root, "myapp")
276 277 278 279 280
    run_generator [app_root]

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

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

288 289 290 291 292 293 294 295 296 297 298 299 300 301
  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

302 303 304 305 306
  def test_active_storage_mini_magick_gem
    run_generator
    assert_file "Gemfile", /^# gem 'mini_magick'/
  end

307 308 309 310 311 312
  def test_active_storage_install
    command_check = -> command, _ do
      @binstub_called ||= 0
      case command
      when "active_storage:install"
        @binstub_called += 1
C
claudiob 已提交
313
        assert_equal 1, @binstub_called, "active_storage:install expected to be called once, but was called #{@binstub_called} times"
314 315 316 317 318 319 320 321
      end
    end

    generator.stub :rails_command, command_check do
      quietly { generator.invoke_all }
    end
  end

322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375
  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"

    assert_file "#{app_root}/Gemfile" do |content|
      assert_no_match(/gem 'mini_magick'/, content)
    end
  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"

    assert_file "#{app_root}/Gemfile" do |content|
      assert_no_match(/gem 'mini_magick'/, content)
    end
  end

376 377
  def test_application_names_are_not_singularized
    run_generator [File.join(destination_root, "hats")]
378
    assert_file "hats/config/environment.rb", /Rails\.application\.initialize!/
379 380
  end

381 382 383
  def test_gemfile_has_no_whitespace_errors
    run_generator
    absolute = File.expand_path("Gemfile", destination_root)
384
    File.open(absolute, "r") do |f|
385
      f.each_line do |line|
A
Arun Agrawal 已提交
386
        assert_no_match %r{/^[ \t]+$/}, line
387 388 389 390
      end
    end
  end

J
José Valim 已提交
391 392 393
  def test_config_database_is_added_by_default
    run_generator
    assert_file "config/database.yml", /sqlite3/
394
    if defined?(JRUBY_VERSION)
O
Oscar Del Ben 已提交
395
      assert_gem "activerecord-jdbcsqlite3-adapter"
396 397
    else
      assert_gem "sqlite3"
398
    end
399 400 401 402 403
  end

  def test_config_another_database
    run_generator([destination_root, "-d", "mysql"])
    assert_file "config/database.yml", /mysql/
404
    if defined?(JRUBY_VERSION)
O
Oscar Del Ben 已提交
405
      assert_gem "activerecord-jdbcmysql-adapter"
406
    else
407
      assert_gem "mysql2", "'~> 0.4.4'"
408
    end
J
José Valim 已提交
409 410
  end

411 412 413 414 415
  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

416 417 418
  def test_config_postgresql_database
    run_generator([destination_root, "-d", "postgresql"])
    assert_file "config/database.yml", /postgresql/
419
    if defined?(JRUBY_VERSION)
O
Oscar Del Ben 已提交
420
      assert_gem "activerecord-jdbcpostgresql-adapter"
421
    else
422
      assert_gem "pg", "'~> 0.18'"
423 424 425
    end
  end

426
  def test_config_jdbcmysql_database
427
    run_generator([destination_root, "-d", "jdbcmysql"])
428
    assert_file "config/database.yml", /mysql/
O
Oscar Del Ben 已提交
429
    assert_gem "activerecord-jdbcmysql-adapter"
430 431
  end

432 433
  def test_config_jdbcsqlite3_database
    run_generator([destination_root, "-d", "jdbcsqlite3"])
434
    assert_file "config/database.yml", /sqlite3/
O
Oscar Del Ben 已提交
435
    assert_gem "activerecord-jdbcsqlite3-adapter"
436 437
  end

438 439
  def test_config_jdbcpostgresql_database
    run_generator([destination_root, "-d", "jdbcpostgresql"])
440
    assert_file "config/database.yml", /postgresql/
O
Oscar Del Ben 已提交
441
    assert_gem "activerecord-jdbcpostgresql-adapter"
442 443
  end

A
Arun Agrawal 已提交
444
  def test_config_jdbc_database
445
    run_generator([destination_root, "-d", "jdbc"])
A
Arun Agrawal 已提交
446
    assert_file "config/database.yml", /jdbc/
447
    assert_file "config/database.yml", /mssql/
O
Oscar Del Ben 已提交
448
    assert_gem "activerecord-jdbc-adapter"
A
Arun Agrawal 已提交
449 450
  end

451 452
  if defined?(JRUBY_VERSION)
    def test_config_jdbc_database_when_no_option_given
453
      run_generator
454
      assert_file "config/database.yml", /sqlite3/
O
Oscar Del Ben 已提交
455
      assert_gem "activerecord-jdbcsqlite3-adapter"
456 457 458
    end
  end

S
schneems 已提交
459 460
  def test_generator_defaults_to_puma_version
    run_generator [destination_root]
461
    assert_gem "puma", "'~> 3.11'"
S
schneems 已提交
462 463
  end

S
schneems 已提交
464 465 466 467 468 469 470 471
  def test_generator_if_skip_puma_is_given
    run_generator [destination_root, "--skip-puma"]
    assert_no_file "config/puma.rb"
    assert_file "Gemfile" do |content|
      assert_no_match(/puma/, content)
    end
  end

472 473 474
  def test_generator_has_assets_gems
    run_generator

475 476
    assert_gem "sass-rails"
    assert_gem "uglifier"
477 478
  end

479 480
  def test_action_cable_redis_gems
    run_generator
481
    assert_file "Gemfile", /^# gem 'redis'/
482 483
  end

484 485
  def test_generator_if_skip_test_is_given
    run_generator [destination_root, "--skip-test"]
486 487 488

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

489 490 491
    assert_file "Gemfile" do |content|
      assert_no_match(/capybara/, content)
      assert_no_match(/selenium-webdriver/, content)
492
      assert_no_match(/chromedriver-helper/, content)
493
    end
494 495

    assert_no_directory("test")
496 497 498
  end

  def test_generator_if_skip_system_test_is_given
499
    run_generator [destination_root, "--skip-system-test"]
500 501 502
    assert_file "Gemfile" do |content|
      assert_no_match(/capybara/, content)
      assert_no_match(/selenium-webdriver/, content)
503
      assert_no_match(/chromedriver-helper/, content)
504
    end
505 506 507 508

    assert_directory("test")

    assert_no_directory("test/system")
509 510
  end

511
  def test_does_not_generate_system_test_files_if_skip_system_test_is_given
512
    run_generator [destination_root, "--skip-system-test"]
513 514 515 516 517 518 519 520 521

    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

522
  def test_inclusion_of_javascript_runtime
523
    run_generator
524
    if defined?(JRUBY_VERSION)
O
Oscar Del Ben 已提交
525
      assert_gem "therubyrhino"
526 527
    elsif RUBY_PLATFORM =~ /mingw|mswin/
      assert_gem "duktape"
528
    else
S
Sam 已提交
529
      assert_file "Gemfile", /# gem 'mini_racer', platforms: :ruby/
530 531 532
    end
  end

533
  def test_rails_ujs_is_the_default_ujs_library
534 535
    run_generator
    assert_file "app/assets/javascripts/application.js" do |contents|
536
      assert_match %r{^//= require rails-ujs}, contents
537 538 539
    end
  end

540 541
  def test_javascript_is_skipped_if_required
    run_generator [destination_root, "--skip-javascript"]
542 543 544

    assert_no_file "app/assets/javascripts"

545
    assert_file "app/views/layouts/application.html.erb" do |contents|
546 547
      assert_match(/stylesheet_link_tag\s+'application', media: 'all' %>/, contents)
      assert_no_match(/javascript_include_tag\s+'application' \%>/, contents)
548
    end
549

550
    assert_file "Gemfile" do |content|
551
      assert_no_match(/coffee-rails/, content)
552 553 554 555 556
      assert_no_match(/uglifier/, content)
    end

    assert_file "config/environments/production.rb" do |content|
      assert_no_match(/config\.assets\.js_compressor = :uglifier/, content)
557
    end
558
  end
559

S
Sean Griffin 已提交
560 561 562 563 564 565 566 567 568
  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 已提交
569 570
  def test_inclusion_of_jbuilder
    run_generator
571
    assert_gem "jbuilder"
A
Arun Agrawal 已提交
572 573
  end

574
  def test_inclusion_of_a_debugger
575
    run_generator
576
    if defined?(JRUBY_VERSION) || RUBY_ENGINE == "rbx"
A
Arun Agrawal 已提交
577
      assert_file "Gemfile" do |content|
578
        assert_no_match(/byebug/, content)
A
Arun Agrawal 已提交
579
      end
580
    else
581
      assert_gem "byebug"
A
Arun Agrawal 已提交
582
    end
583 584
  end

585
  def test_inclusion_of_listen_related_configuration_by_default
586
    run_generator
587
    if RbConfig::CONFIG["host_os"] =~ /darwin|linux/
588
      assert_listen_related_configuration
589
    else
590
      assert_no_listen_related_configuration
591 592 593
    end
  end

594
  def test_non_inclusion_of_listen_related_configuration_if_skip_listen
595
    run_generator [destination_root, "--skip-listen"]
596 597 598
    assert_no_listen_related_configuration
  end

599 600
  def test_evented_file_update_checker_config
    run_generator
601 602
    assert_file "config/environments/development.rb" do |content|
      if RbConfig::CONFIG["host_os"] =~ /darwin|linux/
603
        assert_match(/^\s*config\.file_watcher = ActiveSupport::EventedFileUpdateChecker/, content)
604
      else
605
        assert_match(/^\s*# config\.file_watcher = ActiveSupport::EventedFileUpdateChecker/, content)
606 607 608 609
      end
    end
  end

610
  def test_template_from_dir_pwd
611
    FileUtils.cd(Rails.root)
612
    assert_match(/It works from file!/, run_generator([destination_root, "-m", "lib/template.rb"]))
613 614
  end

J
José Valim 已提交
615
  def test_usage_read_from_file
616 617 618
    assert_called(File, :read, returns: "USAGE FROM FILE") do
      assert_equal "USAGE FROM FILE", Rails::Generators::AppGenerator.desc
    end
J
José Valim 已提交
619 620 621
  end

  def test_default_usage
622 623 624
    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 已提交
625 626 627
  end

  def test_default_namespace
628
    assert_match "rails:app", Rails::Generators::AppGenerator.namespace
J
José Valim 已提交
629 630
  end

631
  def test_file_is_added_for_backwards_compatibility
632 633
    action :file, "lib/test_file.rb", "heres test data"
    assert_file "lib/test_file.rb", "heres test data"
634 635
  end

636 637 638
  def test_pretend_option
    output = run_generator [File.join(destination_root, "myapp"), "--pretend"]
    assert_no_match(/run  bundle install/, output)
639
    assert_no_match(/run  git init/, output)
640 641
  end

642 643 644 645 646
  def test_quiet_option
    output = run_generator [File.join(destination_root, "myapp"), "--quiet"]
    assert_empty output
  end

647
  def test_application_name_with_spaces
648
    path = File.join(destination_root, "foo bar")
649 650

    # This also applies to MySQL apps but not with SQLite
651
    run_generator [path, "-d", "postgresql"]
652 653 654 655

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

656 657
  def test_web_console
    run_generator
658
    assert_gem "web-console"
659 660
  end

661 662 663 664
  def test_web_console_with_dev_option
    run_generator [destination_root, "--dev"]

    assert_file "Gemfile" do |content|
M
Mehmet Emin İNAÇ 已提交
665
      assert_match(/gem 'web-console',\s+github: 'rails\/web-console'/, content)
666
      assert_no_match(/\Agem 'web-console', '>= 3\.3\.0'\z/, content)
667 668 669 670 671 672 673
    end
  end

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

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

679 680 681 682 683 684
  def test_generation_runs_bundle_install
    assert_generates_with_bundler
  end

  def test_dev_option
    assert_generates_with_bundler dev: true
685 686
    rails_path = File.expand_path("../../..", Rails.root)
    assert_file "Gemfile", /^gem\s+["']rails["'],\s+path:\s+["']#{Regexp.escape(rails_path)}["']$/
687 688 689 690
  end

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

694 695
  def test_spring
    run_generator
696
    assert_gem "spring"
697 698 699
  end

  def test_spring_binstubs
700
    jruby_skip "spring doesn't run on JRuby"
701 702 703 704
    command_check = -> command do
      @binstub_called ||= 0

      case command
705
      when "install"
706
        # Called when running bundle, we just want to stub it so nothing to do here.
707
      when "exec spring binstub --all"
708 709 710 711 712 713 714 715
        @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
716 717 718
  end

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

723 724 725
      assert_file "Gemfile" do |content|
        assert_no_match(/spring/, content)
      end
726 727 728 729 730 731
    end
  end

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

732
    assert_no_file "config/spring.rb"
733 734 735 736 737
    assert_file "Gemfile" do |content|
      assert_no_match(/spring/, content)
    end
  end

738 739 740 741 742 743 744 745
  def test_spring_with_dev_option
    run_generator [destination_root, "--dev"]

    assert_file "Gemfile" do |content|
      assert_no_match(/spring/, content)
    end
  end

746 747 748
  def test_webpack_option
    command_check = -> command, *_ do
      @called ||= 0
T
Tsukuru Tanimichi 已提交
749 750 751 752
      if command == "webpacker:install"
        @called += 1
        assert_equal 1, @called, "webpacker:install expected to be called once, but was called #{@called} times."
      end
753 754
    end

T
Tsukuru Tanimichi 已提交
755
    generator([destination_root], webpack: "webpack").stub(:rails_command, command_check) do
756 757 758 759 760 761
      quietly { generator.invoke_all }
    end

    assert_gem "webpacker"
  end

762 763
  def test_generator_if_skip_turbolinks_is_given
    run_generator [destination_root, "--skip-turbolinks"]
764 765 766 767 768 769 770 771 772 773 774 775

    assert_file "Gemfile" do |content|
      assert_no_match(/turbolinks/, content)
    end
    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

776 777 778 779 780 781 782 783 784 785 786
  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|
      assert_match(/#{RUBY_VERSION}/, content)
    end
  end

787 788 789 790 791
  def test_version_control_initializes_git_repo
    run_generator [destination_root]
    assert_directory ".git"
  end

792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814
  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

815 816
  def test_psych_gem
    run_generator
817
    gem_regex = /gem 'psych',\s+'~> 2\.0',\s+platforms: :rbx/
818 819 820 821 822 823 824 825 826 827

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

828
  def test_after_bundle_callback
829
    path = "http://example.org/rails_template"
830
    template = %{ after_bundle { run 'echo ran after_bundle' } }.dup
831 832
    template.instance_eval "def read; self; end" # Make the string respond to read

833
    check_open = -> *args do
834
      assert_equal [ path, "Accept" => "application/x-thor-template" ], args
835 836
      template
    end
837

838
    sequence = ["git init", "install", "exec spring binstub --all", "active_storage:install", "echo ran after_bundle"]
839
    @sequence_step ||= 0
840
    ensure_bundler_first = -> command, options = nil do
841 842 843 844 845 846 847
      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
848 849 850
          generator.stub(:rails_command, ensure_bundler_first) do
            quietly { generator.invoke_all }
          end
851 852 853
        end
      end
    end
854

855
    assert_equal 5, @sequence_step
856 857
  end

858 859 860 861 862 863 864 865
  def test_gitignore
    run_generator

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

E
eileencodes 已提交
866 867 868 869 870 871 872 873
  def test_system_tests_directory_generated
    run_generator

    assert_file("test/system/.keep")
    assert_directory("test/system")
  end

  private
874 875 876 877 878
    def stub_rails_application(root)
      Rails.application.config.root = root
      Rails.application.class.stub(:name, "Myapp") do
        yield
      end
879 880
    end

881 882 883
    def action(*args, &block)
      capture(:stdout) { generator.send(*args, &block) }
    end
O
Oscar Del Ben 已提交
884

885 886 887 888 889 890
    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
891
    end
892

893
    def assert_listen_related_configuration
894 895
      assert_gem "listen"
      assert_gem "spring-watcher-listen"
896

897
      assert_file "config/environments/development.rb" do |content|
898
        assert_match(/^\s*config\.file_watcher = ActiveSupport::EventedFileUpdateChecker/, content)
899
      end
900 901
    end

902
    def assert_no_listen_related_configuration
903
      assert_file "Gemfile" do |content|
904 905 906
        assert_no_match(/listen/, content)
      end

907
      assert_file "config/environments/development.rb" do |content|
908
        assert_match(/^\s*# config\.file_watcher = ActiveSupport::EventedFileUpdateChecker/, content)
909
      end
910 911
    end

912 913 914 915 916 917 918
    def assert_generates_with_bundler(options = {})
      generator([destination_root], options)

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

        case command
919
        when "install"
920 921
          @install_called += 1
          assert_equal 1, @install_called, "install expected to be called once, but was called #{@install_called} times"
922
        when "exec spring binstub --all"
923 924 925 926 927 928 929
          # Called when running tests with spring, let through unscathed.
        end
      end

      generator.stub :bundle_command, command_check do
        quietly { generator.invoke_all }
      end
930
    end
931
end