app_generator_test.rb 27.0 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 59 60 61 62
  config/initializers/application_controller_renderer.rb
  config/initializers/assets.rb
  config/initializers/backtrace_silencers.rb
  config/initializers/cookies_serializer.rb
  config/initializers/filter_parameter_logging.rb
  config/initializers/inflections.rb
  config/initializers/mime_types.rb
  config/initializers/wrap_parameters.rb
63
  config/locales
64
  config/locales/en.yml
S
schneems 已提交
65
  config/puma.rb
66
  config/routes.rb
67
  config/credentials.yml.enc
68
  config/spring.rb
69
  config/storage.yml
70
  db
71
  db/seeds.rb
72 73
  lib
  lib/tasks
74
  lib/assets
75
  log
76 77
  package.json
  public
78
  storage
79
  test/application_system_test_case.rb
A
Arun Agrawal 已提交
80
  test/test_helper.rb
81
  test/fixtures
82
  test/fixtures/files
M
Mike Moore 已提交
83 84 85 86
  test/controllers
  test/models
  test/helpers
  test/mailers
87
  test/integration
E
eileencodes 已提交
88
  test/system
89
  vendor
90
  tmp
91
  tmp/cache
J
José Valim 已提交
92
  tmp/cache/assets
93
  tmp/storage
94 95
)

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

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

103 104
  def default_files
    ::DEFAULT_APP_FILES
105 106
  end

107
  def test_assets
108
    run_generator
109

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

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

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

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

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

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

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

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

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

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

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

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

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

197 198 199
  def test_new_application_not_include_api_initializers
    run_generator

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

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

207 208 209 210 211 212 213 214 215 216 217 218
  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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

S
schneems 已提交
458 459
  def test_generator_defaults_to_puma_version
    run_generator [destination_root]
R
Roberto Miranda 已提交
460
    assert_gem "puma", "'~> 3.7'"
S
schneems 已提交
461 462
  end

S
schneems 已提交
463 464 465 466 467 468 469 470
  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

471 472 473
  def test_generator_has_assets_gems
    run_generator

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

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

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

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

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

    assert_no_directory("test")
495 496 497
  end

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

    assert_directory("test")

    assert_no_directory("test/system")
508 509
  end

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

    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

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

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

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

    assert_no_file "app/assets/javascripts"

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

678 679 680 681 682 683
  def test_generation_runs_bundle_install
    assert_generates_with_bundler
  end

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

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

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

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

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

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

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

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

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

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

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

745 746
  def test_generator_if_skip_turbolinks_is_given
    run_generator [destination_root, "--skip-turbolinks"]
747 748 749 750 751 752 753 754 755 756 757 758

    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

759 760 761 762 763 764 765 766 767 768 769
  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

770 771 772 773 774
  def test_version_control_initializes_git_repo
    run_generator [destination_root]
    assert_directory ".git"
  end

775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797
  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

798 799
  def test_psych_gem
    run_generator
800
    gem_regex = /gem 'psych',\s+'~> 2\.0',\s+platforms: :rbx/
801 802 803 804 805 806 807 808 809 810

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

811
  def test_after_bundle_callback
812
    path = "http://example.org/rails_template"
813
    template = %{ after_bundle { run 'echo ran after_bundle' } }.dup
814 815
    template.instance_eval "def read; self; end" # Make the string respond to read

816
    check_open = -> *args do
817
      assert_equal [ path, "Accept" => "application/x-thor-template" ], args
818 819
      template
    end
820

821
    sequence = ["git init", "install", "exec spring binstub --all", "active_storage:install", "echo ran after_bundle"]
822
    @sequence_step ||= 0
823
    ensure_bundler_first = -> command, options = nil do
824 825 826 827 828 829 830
      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
831 832 833
          generator.stub(:rails_command, ensure_bundler_first) do
            quietly { generator.invoke_all }
          end
834 835 836
        end
      end
    end
837

838
    assert_equal 5, @sequence_step
839 840
  end

E
eileencodes 已提交
841 842 843 844 845 846 847 848
  def test_system_tests_directory_generated
    run_generator

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

  private
849 850 851 852 853
    def stub_rails_application(root)
      Rails.application.config.root = root
      Rails.application.class.stub(:name, "Myapp") do
        yield
      end
854 855
    end

856 857 858
    def action(*args, &block)
      capture(:stdout) { generator.send(*args, &block) }
    end
O
Oscar Del Ben 已提交
859

860 861 862 863 864 865
    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
866
    end
867

868
    def assert_listen_related_configuration
869 870
      assert_gem "listen"
      assert_gem "spring-watcher-listen"
871

872
      assert_file "config/environments/development.rb" do |content|
873
        assert_match(/^\s*config\.file_watcher = ActiveSupport::EventedFileUpdateChecker/, content)
874
      end
875 876
    end

877
    def assert_no_listen_related_configuration
878
      assert_file "Gemfile" do |content|
879 880 881
        assert_no_match(/listen/, content)
      end

882
      assert_file "config/environments/development.rb" do |content|
883
        assert_match(/^\s*# config\.file_watcher = ActiveSupport::EventedFileUpdateChecker/, content)
884
      end
885 886
    end

887 888 889 890 891 892 893
    def assert_generates_with_bundler(options = {})
      generator([destination_root], options)

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

        case command
894
        when "install"
895 896
          @install_called += 1
          assert_equal 1, @install_called, "install expected to be called once, but was called #{@install_called} times"
897
        when "exec spring binstub --all"
898 899 900 901 902 903 904
          # Called when running tests with spring, let through unscathed.
        end
      end

      generator.stub :bundle_command, command_check do
        quietly { generator.invoke_all }
      end
905
    end
906
end