app_generator_test.rb 18.7 KB
Newer Older
J
José Valim 已提交
1
require 'generators/generators_test_helper'
2
require 'rails/generators/rails/app/app_generator'
3
require 'generators/shared_generator_tests'
4
require 'mocha/setup' # FIXME: stop using mocha
J
José Valim 已提交
5

6 7
DEFAULT_APP_FILES = %w(
  .gitignore
A
Arun Agrawal 已提交
8
  README.rdoc
9 10 11
  Gemfile
  Rakefile
  config.ru
J
José Valim 已提交
12 13
  app/assets/javascripts
  app/assets/stylesheets
14
  app/assets/images
15
  app/controllers
F
Francesco Rodriguez 已提交
16
  app/controllers/concerns
17
  app/helpers
18
  app/mailers
19
  app/models
F
Francesco Rodriguez 已提交
20
  app/models/concerns
21
  app/views/layouts
22 23 24
  bin/bundle
  bin/rails
  bin/rake
25
  bin/setup
26 27 28 29 30 31
  config/environments
  config/initializers
  config/locales
  db
  lib
  lib/tasks
32
  lib/assets
33
  log
A
Arun Agrawal 已提交
34
  test/test_helper.rb
35
  test/fixtures
M
Mike Moore 已提交
36 37 38 39
  test/controllers
  test/models
  test/helpers
  test/mailers
40 41
  test/integration
  vendor
J
José Valim 已提交
42
  vendor/assets
A
Arun Agrawal 已提交
43 44
  vendor/assets/stylesheets
  vendor/assets/javascripts
45
  tmp/cache
J
José Valim 已提交
46
  tmp/cache/assets
47 48
)

49 50
class AppGeneratorTest < Rails::Generators::TestCase
  include GeneratorsTestHelper
51
  arguments [destination_root]
52 53

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

56 57
  def default_files
    ::DEFAULT_APP_FILES
58 59
  end

60
  def test_assets
61
    run_generator
62

63 64
    assert_file("app/views/layouts/application.html.erb", /stylesheet_link_tag\s+'application', media: 'all', 'data-turbolinks-track' => true/)
    assert_file("app/views/layouts/application.html.erb", /javascript_include_tag\s+'application', 'data-turbolinks-track' => true/)
65
    assert_file("app/assets/stylesheets/application.css")
A
Arun Agrawal 已提交
66
    assert_file("app/assets/javascripts/application.js")
67 68
  end

69
  def test_invalid_application_name_raises_an_error
70
    content = capture(:stderr){ run_generator [File.join(destination_root, "43-things")] }
71 72 73 74
    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
75
    run_generator [File.join(destination_root, "things-43")]
76
    assert_file "things-43/config/environment.rb", /Rails\.application\.initialize!/
77
    assert_file "things-43/config/application.rb", /^module Things43$/
78 79
  end

80
  def test_application_new_exits_with_non_zero_code_on_invalid_application_name
A
Akira Matsuda 已提交
81
    quietly { system 'rails new test --no-rc' }
82
    assert_equal false, $?.success?
83 84 85 86 87 88 89 90 91 92 93
  end

  def test_application_new_exits_with_message_and_non_zero_code_when_generating_inside_existing_rails_directory
    app_root = File.join(destination_root, 'myfirstapp')
    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?
94 95
  end

96 97 98 99 100 101
  def test_application_new_show_help_message_inside_existing_rails_directory
    app_root = File.join(destination_root, 'myfirstapp')
    run_generator [app_root]
    output = Dir.chdir(app_root) do
      `rails new --help`
    end
102
    assert_match(/rails new APP_PATH \[options\]/, output)
103 104 105
    assert_equal true, $?.success?
  end

106 107 108 109 110 111 112 113
  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]

    Rails.application.config.root = app_moved_root
    Rails.application.class.stubs(:name).returns("Myapp")
114
    Rails.application.stubs(:is_a?).returns(Rails::Application)
115 116 117

    FileUtils.mv(app_root, app_moved_root)

A
Arun Agrawal 已提交
118 119 120
    # make sure we are in correct dir
    FileUtils.cd(app_moved_root)

121 122
    generator = Rails::Generators::AppGenerator.new ["rails"], { with_dispatchers: true },
                                                               destination_root: app_moved_root, shell: @shell
123
    generator.send(:app_const)
124
    quietly { generator.send(:update_config_files) }
125
    assert_file "myapp_moved/config/environment.rb", /Rails\.application\.initialize!/
126
    assert_file "myapp_moved/config/initializers/session_store.rb", /_myapp_session/
127
  end
128

129 130 131
  def test_rails_update_generates_correct_session_key
    app_root = File.join(destination_root, 'myapp')
    run_generator [app_root]
132

133 134 135 136
    Rails.application.config.root = app_root
    Rails.application.class.stubs(:name).returns("Myapp")
    Rails.application.stubs(:is_a?).returns(Rails::Application)

137
    generator = Rails::Generators::AppGenerator.new ["rails"], { with_dispatchers: true }, destination_root: app_root, shell: @shell
138
    generator.send(:app_const)
139
    quietly { generator.send(:update_config_files) }
140 141
    assert_file "myapp/config/initializers/session_store.rb", /_myapp_session/
  end
142

143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178
  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

  def test_rails_update_keep_the_cookie_serializer_if_it_is_already_configured
    app_root = File.join(destination_root, 'myapp')
    run_generator [app_root]

    Rails.application.config.root = app_root
    Rails.application.class.stubs(:name).returns("Myapp")
    Rails.application.stubs(:is_a?).returns(Rails::Application)

    generator = Rails::Generators::AppGenerator.new ["rails"], { with_dispatchers: true }, destination_root: app_root, shell: @shell
    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

  def test_rails_update_set_the_cookie_serializer_to_marchal_if_it_is_not_already_configured
    app_root = File.join(destination_root, 'myapp')
    run_generator [app_root]

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

    Rails.application.config.root = app_root
    Rails.application.class.stubs(:name).returns("Myapp")
    Rails.application.stubs(:is_a?).returns(Rails::Application)

    generator = Rails::Generators::AppGenerator.new ["rails"], { with_dispatchers: true }, destination_root: app_root, shell: @shell
    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 = :marshal/)
  end

179 180
  def test_application_names_are_not_singularized
    run_generator [File.join(destination_root, "hats")]
181
    assert_file "hats/config/environment.rb", /Rails\.application\.initialize!/
182 183
  end

184 185 186 187 188
  def test_gemfile_has_no_whitespace_errors
    run_generator
    absolute = File.expand_path("Gemfile", destination_root)
    File.open(absolute, 'r') do |f|
      f.each_line do |line|
A
Arun Agrawal 已提交
189
        assert_no_match %r{/^[ \t]+$/}, line
190 191 192 193
      end
    end
  end

J
José Valim 已提交
194 195 196
  def test_config_database_is_added_by_default
    run_generator
    assert_file "config/database.yml", /sqlite3/
197
    if defined?(JRUBY_VERSION)
O
Oscar Del Ben 已提交
198
      assert_gem "activerecord-jdbcsqlite3-adapter"
199 200
    else
      assert_gem "sqlite3"
201
    end
202 203 204 205 206
  end

  def test_config_another_database
    run_generator([destination_root, "-d", "mysql"])
    assert_file "config/database.yml", /mysql/
207
    if defined?(JRUBY_VERSION)
O
Oscar Del Ben 已提交
208
      assert_gem "activerecord-jdbcmysql-adapter"
209 210
    else
      assert_gem "mysql2"
211
    end
J
José Valim 已提交
212 213
  end

214 215 216 217 218
  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

219 220 221
  def test_config_postgresql_database
    run_generator([destination_root, "-d", "postgresql"])
    assert_file "config/database.yml", /postgresql/
222
    if defined?(JRUBY_VERSION)
O
Oscar Del Ben 已提交
223
      assert_gem "activerecord-jdbcpostgresql-adapter"
224 225
    else
      assert_gem "pg"
226 227 228
    end
  end

229 230
  def test_config_jdbcmysql_database
    run_generator([destination_root, "-d", "jdbcmysql"])
231
    assert_file "config/database.yml", /mysql/
O
Oscar Del Ben 已提交
232
    assert_gem "activerecord-jdbcmysql-adapter"
233 234
  end

235 236
  def test_config_jdbcsqlite3_database
    run_generator([destination_root, "-d", "jdbcsqlite3"])
237
    assert_file "config/database.yml", /sqlite3/
O
Oscar Del Ben 已提交
238
    assert_gem "activerecord-jdbcsqlite3-adapter"
239 240
  end

241 242
  def test_config_jdbcpostgresql_database
    run_generator([destination_root, "-d", "jdbcpostgresql"])
243
    assert_file "config/database.yml", /postgresql/
O
Oscar Del Ben 已提交
244
    assert_gem "activerecord-jdbcpostgresql-adapter"
245 246
  end

A
Arun Agrawal 已提交
247 248 249
  def test_config_jdbc_database
    run_generator([destination_root, "-d", "jdbc"])
    assert_file "config/database.yml", /jdbc/
250
    assert_file "config/database.yml", /mssql/
O
Oscar Del Ben 已提交
251
    assert_gem "activerecord-jdbc-adapter"
A
Arun Agrawal 已提交
252 253
  end

254 255
  if defined?(JRUBY_VERSION)
    def test_config_jdbc_database_when_no_option_given
256
      run_generator
257
      assert_file "config/database.yml", /sqlite3/
O
Oscar Del Ben 已提交
258
      assert_gem "activerecord-jdbcsqlite3-adapter"
259 260 261
    end
  end

262 263 264 265 266 267 268 269 270 271 272 273 274 275
  def test_generator_without_skips
    run_generator
    assert_file "config/application.rb", /\s+require\s+["']rails\/all["']/
    assert_file "config/environments/development.rb" do |content|
      assert_match(/config\.action_mailer\.raise_delivery_errors = false/, content)
    end
    assert_file "config/environments/test.rb" do |content|
      assert_match(/config\.action_mailer\.delivery_method = :test/, content)
    end
    assert_file "config/environments/production.rb" do |content|
      assert_match(/# config\.action_mailer\.raise_delivery_errors = false/, content)
    end
  end

276
  def test_generator_if_skip_active_record_is_given
277
    run_generator [destination_root, "--skip-active-record"]
J
José Valim 已提交
278
    assert_no_file "config/database.yml"
279
    assert_file "config/application.rb", /#\s+require\s+["']active_record\/railtie["']/
280
    assert_file "test/test_helper.rb" do |helper_content|
281
      assert_no_match(/fixtures :all/, helper_content)
282
    end
J
José Valim 已提交
283 284
  end

285 286 287 288 289 290 291 292 293 294 295 296 297 298
  def test_generator_if_skip_action_mailer_is_given
    run_generator [destination_root, "--skip-action-mailer"]
    assert_file "config/application.rb", /#\s+require\s+["']action_mailer\/railtie["']/
    assert_file "config/environments/development.rb" do |content|
      assert_no_match(/config\.action_mailer/, content)
    end
    assert_file "config/environments/test.rb" do |content|
      assert_no_match(/config\.action_mailer/, content)
    end
    assert_file "config/environments/production.rb" do |content|
      assert_no_match(/config\.action_mailer/, content)
    end
  end

299
  def test_generator_if_skip_sprockets_is_given
300
    run_generator [destination_root, "--skip-sprockets"]
301
    assert_no_file "config/initializers/assets.rb"
302
    assert_file "config/application.rb" do |content|
303
      assert_match(/#\s+require\s+["']sprockets\/railtie["']/, content)
304
    end
305 306 307
    assert_file "Gemfile" do |content|
      assert_no_match(/sass-rails/, content)
      assert_no_match(/uglifier/, content)
308
      assert_match(/coffee-rails/, content)
309
    end
310 311 312 313 314
    assert_file "config/environments/development.rb" do |content|
      assert_no_match(/config\.assets\.debug = true/, content)
    end
    assert_file "config/environments/production.rb" do |content|
      assert_no_match(/config\.assets\.digest = true/, content)
J
Joshua Peek 已提交
315 316
      assert_no_match(/config\.assets\.js_compressor = :uglifier/, content)
      assert_no_match(/config\.assets\.css_compressor = :sass/, content)
317
    end
318
  end
J
José Valim 已提交
319

320
  def test_inclusion_of_javascript_runtime
321
    run_generator
322
    if defined?(JRUBY_VERSION)
O
Oscar Del Ben 已提交
323
      assert_gem "therubyrhino"
324
    else
325
      assert_file "Gemfile", /# gem 'therubyracer', platforms: :ruby/
326 327 328
    end
  end

329 330 331 332 333 334
  def test_jquery_is_the_default_javascript_library
    run_generator
    assert_file "app/assets/javascripts/application.js" do |contents|
      assert_match %r{^//= require jquery}, contents
      assert_match %r{^//= require jquery_ujs}, contents
    end
A
Arun Agrawal 已提交
335
    assert_gem "jquery-rails"
336 337 338 339 340 341 342 343
  end

  def test_other_javascript_libraries
    run_generator [destination_root, '-j', 'prototype']
    assert_file "app/assets/javascripts/application.js" do |contents|
      assert_match %r{^//= require prototype}, contents
      assert_match %r{^//= require prototype_ujs}, contents
    end
O
Oscar Del Ben 已提交
344
    assert_gem "prototype-rails"
J
José Valim 已提交
345
  end
346

347 348
  def test_javascript_is_skipped_if_required
    run_generator [destination_root, "--skip-javascript"]
349 350 351 352

    assert_no_file "app/assets/javascripts"
    assert_no_file "vendor/assets/javascripts"

353
    assert_file "app/views/layouts/application.html.erb" do |contents|
354 355
      assert_match(/stylesheet_link_tag\s+'application', media: 'all' %>/, contents)
      assert_no_match(/javascript_include_tag\s+'application' \%>/, contents)
356
    end
357

358
    assert_file "Gemfile" do |content|
359
      assert_no_match(/coffee-rails/, content)
A
Arun Agrawal 已提交
360
      assert_no_match(/jquery-rails/, content)
361
    end
362
  end
363

A
Arun Agrawal 已提交
364 365
  def test_inclusion_of_jbuilder
    run_generator
366
    assert_gem 'jbuilder'
A
Arun Agrawal 已提交
367 368
  end

369
  def test_inclusion_of_a_debugger
370
    run_generator
371
    if defined?(JRUBY_VERSION) || RUBY_ENGINE == "rbx"
A
Arun Agrawal 已提交
372
      assert_file "Gemfile" do |content|
373
        assert_no_match(/byebug/, content)
A
Arun Agrawal 已提交
374 375
        assert_no_match(/debugger/, content)
      end
376
    elsif RUBY_VERSION < '2.0.0'
377
      assert_gem 'debugger'
378
    else
379
      assert_gem 'byebug'
A
Arun Agrawal 已提交
380
    end
381 382
  end

X
Xavier Noria 已提交
383
  def test_inclusion_of_doc
X
Xavier Noria 已提交
384
    run_generator
X
Xavier Noria 已提交
385
    assert_file 'Gemfile', /gem 'sdoc',\s+'~> 0.4.0',\s+group: :doc/
X
Xavier Noria 已提交
386 387
  end

388
  def test_template_from_dir_pwd
389
    FileUtils.cd(Rails.root)
390
    assert_match(/It works from file!/, run_generator([destination_root, "-m", "lib/template.rb"]))
391 392
  end

J
José Valim 已提交
393 394 395 396 397 398
  def test_usage_read_from_file
    File.expects(:read).returns("USAGE FROM FILE")
    assert_equal "USAGE FROM FILE", Rails::Generators::AppGenerator.desc
  end

  def test_default_usage
399
    Rails::Generators::AppGenerator.expects(:usage_path).returns(nil)
400
    assert_match(/Create rails files for app generator/, Rails::Generators::AppGenerator.desc)
J
José Valim 已提交
401 402 403
  end

  def test_default_namespace
404
    assert_match "rails:app", Rails::Generators::AppGenerator.namespace
J
José Valim 已提交
405 406
  end

407 408 409 410 411
  def test_file_is_added_for_backwards_compatibility
    action :file, 'lib/test_file.rb', 'heres test data'
    assert_file 'lib/test_file.rb', 'heres test data'
  end

412 413
  def test_test_unit_is_removed_from_frameworks_if_skip_test_unit_is_given
    run_generator [destination_root, "--skip-test-unit"]
414 415 416 417 418 419 420
    assert_file "config/application.rb", /#\s+require\s+["']rails\/test_unit\/railtie["']/
  end

  def test_no_active_record_or_test_unit_if_skips_given
    run_generator [destination_root, "--skip-test-unit", "--skip-active-record"]
    assert_file "config/application.rb", /#\s+require\s+["']rails\/test_unit\/railtie["']/
    assert_file "config/application.rb", /#\s+require\s+["']active_record\/railtie["']/
421
    assert_file "config/application.rb", /\s+require\s+["']active_job\/railtie["']/
422 423
  end

424
  def test_new_hash_style
425
    run_generator
426
    assert_file "config/initializers/session_store.rb" do |file|
427
      assert_match(/config.session_store :cookie_store, key: '_.+_session'/, file)
428 429 430
    end
  end

431 432 433 434 435
  def test_pretend_option
    output = run_generator [File.join(destination_root, "myapp"), "--pretend"]
    assert_no_match(/run  bundle install/, output)
  end

436 437 438 439 440 441 442 443 444 445
  def test_application_name_with_spaces
    path = File.join(destination_root, "foo bar".shellescape)

    # This also applies to MySQL apps but not with SQLite
    run_generator [path, "-d", 'postgresql']

    assert_file "foo bar/config/database.yml", /database: foo_bar_development/
    assert_file "foo bar/config/initializers/session_store.rb", /key: '_foo_bar/
  end

446 447 448 449 450
  def test_web_console
    run_generator
    assert_gem 'web-console'
  end

451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468
  def test_web_console_with_dev_option
    run_generator [destination_root, "--dev"]

    assert_file "Gemfile" do |content|
      assert_match(/gem 'web-console',\s+github: "rails\/web-console"/, content)
      assert_no_match(/gem 'web-console', '~> 2.0'/, content)
    end
  end

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

    assert_file "Gemfile" do |content|
      assert_match(/gem 'web-console',\s+github: "rails\/web-console"/, content)
      assert_no_match(/gem 'web-console', '~> 2.0'/, content)
    end
  end

469 470
  def test_spring
    run_generator
471
    assert_gem 'spring'
472 473 474
  end

  def test_spring_binstubs
475
    jruby_skip "spring doesn't run on JRuby"
476 477 478 479 480 481
    generator.stubs(:bundle_command).with('install')
    generator.expects(:bundle_command).with('exec spring binstub --all').once
    quietly { generator.invoke_all }
  end

  def test_spring_no_fork
482
    jruby_skip "spring doesn't run on JRuby"
483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498
    Process.stubs(:respond_to?).with(:fork).returns(false)
    run_generator

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

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

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

499 500
  def test_generator_if_skip_turbolinks_is_given
    run_generator [destination_root, "--skip-turbolinks"]
501 502 503 504 505 506 507 508 509 510 511 512

    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

513 514 515 516 517 518 519 520 521 522 523 524
  def test_gitignore_when_sqlite3
    run_generator

    assert_file '.gitignore' do |content|
      assert_match(/sqlite3/, content)
    end
  end

  def test_gitignore_when_no_active_record
    run_generator [destination_root, '--skip-active-record']

    assert_file '.gitignore' do |content|
525
      assert_no_match(/sqlite/i, content)
526 527 528 529 530 531 532
    end
  end

  def test_gitignore_when_non_sqlite3_db
    run_generator([destination_root, "-d", "mysql"])

    assert_file '.gitignore' do |content|
533
      assert_no_match(/sqlite/i, content)
534 535 536
    end
  end

537 538
  def test_psych_gem
    run_generator
539
    gem_regex = /gem 'psych',\s+'~> 2.0',\s+platforms: :rbx/
540 541 542 543 544 545 546 547 548 549

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

550 551 552 553 554 555 556 557 558 559 560 561 562 563 564
  def test_after_bundle_callback
    path = 'http://example.org/rails_template'
    template = %{ after_bundle { run 'echo ran after_bundle' } }
    template.instance_eval "def read; self; end" # Make the string respond to read

    generator([destination_root], template: path).expects(:open).with(path, 'Accept' => 'application/x-thor-template').returns(template)

    bundler_first = sequence('bundle, binstubs, after_bundle')
    generator.expects(:bundle_command).with('install').once.in_sequence(bundler_first)
    generator.expects(:bundle_command).with('exec spring binstub --all').in_sequence(bundler_first)
    generator.expects(:run).with('echo ran after_bundle').in_sequence(bundler_first)

    quietly { generator.invoke_all }
  end

565
  protected
J
José Valim 已提交
566

567
  def action(*args, &block)
568
    capture(:stdout) { generator.send(*args, &block) }
569
  end
O
Oscar Del Ben 已提交
570 571

  def assert_gem(gem)
572
    assert_file "Gemfile", /^\s*gem\s+["']#{gem}["']$*/
O
Oscar Del Ben 已提交
573
  end
574
end