app_generator_test.rb 17.0 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
  def test_generator_if_skip_active_record_is_given
263
    run_generator [destination_root, "--skip-active-record"]
J
José Valim 已提交
264
    assert_no_file "config/database.yml"
265
    assert_file "config/application.rb", /#\s+require\s+["']active_record\/railtie["']/
266
    assert_file "test/test_helper.rb" do |helper_content|
267
      assert_no_match(/fixtures :all/, helper_content)
268
    end
J
José Valim 已提交
269 270
  end

271
  def test_generator_if_skip_sprockets_is_given
272
    run_generator [destination_root, "--skip-sprockets"]
273
    assert_no_file "config/initializers/assets.rb"
274
    assert_file "config/application.rb" do |content|
275
      assert_match(/#\s+require\s+["']sprockets\/railtie["']/, content)
276
    end
277 278 279
    assert_file "Gemfile" do |content|
      assert_no_match(/sass-rails/, content)
      assert_no_match(/uglifier/, content)
280
      assert_match(/coffee-rails/, content)
281
    end
282 283 284 285 286
    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 已提交
287 288
      assert_no_match(/config\.assets\.js_compressor = :uglifier/, content)
      assert_no_match(/config\.assets\.css_compressor = :sass/, content)
289
    end
290
  end
J
José Valim 已提交
291

292
  def test_inclusion_of_javascript_runtime
293
    run_generator
294
    if defined?(JRUBY_VERSION)
O
Oscar Del Ben 已提交
295
      assert_gem "therubyrhino"
296
    else
297
      assert_file "Gemfile", /# gem 'therubyracer', platforms: :ruby/
298 299 300
    end
  end

301 302 303 304 305 306
  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 已提交
307
    assert_gem "jquery-rails"
308 309 310 311 312 313 314 315
  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 已提交
316
    assert_gem "prototype-rails"
J
José Valim 已提交
317
  end
318

319 320
  def test_javascript_is_skipped_if_required
    run_generator [destination_root, "--skip-javascript"]
321 322 323 324

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

325
    assert_file "app/views/layouts/application.html.erb" do |contents|
326 327
      assert_match(/stylesheet_link_tag\s+'application', media: 'all' %>/, contents)
      assert_no_match(/javascript_include_tag\s+'application' \%>/, contents)
328
    end
329

330
    assert_file "Gemfile" do |content|
331
      assert_no_match(/coffee-rails/, content)
A
Arun Agrawal 已提交
332
      assert_no_match(/jquery-rails/, content)
333
    end
334
  end
335

A
Arun Agrawal 已提交
336 337
  def test_inclusion_of_jbuilder
    run_generator
338
    assert_gem 'jbuilder'
A
Arun Agrawal 已提交
339 340
  end

341
  def test_inclusion_of_a_debugger
342
    run_generator
A
Arun Agrawal 已提交
343 344
    if defined?(JRUBY_VERSION)
      assert_file "Gemfile" do |content|
345
        assert_no_match(/byebug/, content)
A
Arun Agrawal 已提交
346 347
        assert_no_match(/debugger/, content)
      end
348
    elsif RUBY_VERSION < '2.0.0'
349
      assert_gem 'debugger'
350
    else
351
      assert_gem 'byebug'
A
Arun Agrawal 已提交
352
    end
353 354
  end

X
Xavier Noria 已提交
355
  def test_inclusion_of_doc
X
Xavier Noria 已提交
356
    run_generator
X
Xavier Noria 已提交
357
    assert_file 'Gemfile', /gem 'sdoc',\s+'~> 0.4.0',\s+group: :doc/
X
Xavier Noria 已提交
358 359
  end

360
  def test_template_from_dir_pwd
361
    FileUtils.cd(Rails.root)
362
    assert_match(/It works from file!/, run_generator([destination_root, "-m", "lib/template.rb"]))
363 364
  end

J
José Valim 已提交
365 366 367 368 369 370
  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
371
    Rails::Generators::AppGenerator.expects(:usage_path).returns(nil)
372
    assert_match(/Create rails files for app generator/, Rails::Generators::AppGenerator.desc)
J
José Valim 已提交
373 374 375
  end

  def test_default_namespace
376
    assert_match "rails:app", Rails::Generators::AppGenerator.namespace
J
José Valim 已提交
377 378
  end

379 380 381 382 383
  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

384 385
  def test_test_unit_is_removed_from_frameworks_if_skip_test_unit_is_given
    run_generator [destination_root, "--skip-test-unit"]
386 387 388 389 390 391 392
    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["']/
393
    assert_file "config/application.rb", /\s+require\s+["']active_job\/railtie["']/
394 395
  end

396
  def test_new_hash_style
397
    run_generator
398
    assert_file "config/initializers/session_store.rb" do |file|
399
      assert_match(/config.session_store :cookie_store, key: '_.+_session'/, file)
400 401 402
    end
  end

403 404 405 406 407
  def test_pretend_option
    output = run_generator [File.join(destination_root, "myapp"), "--pretend"]
    assert_no_match(/run  bundle install/, output)
  end

408 409 410 411 412 413 414 415 416 417
  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

418 419 420 421 422
  def test_web_console
    run_generator
    assert_gem 'web-console'
  end

423 424
  def test_spring
    run_generator
425
    assert_gem 'spring'
426 427 428
  end

  def test_spring_binstubs
429
    jruby_skip "spring doesn't run on JRuby"
430 431 432 433 434 435
    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
436
    jruby_skip "spring doesn't run on JRuby"
437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452
    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

453 454
  def test_generator_if_skip_turbolinks_is_given
    run_generator [destination_root, "--skip-turbolinks"]
455 456 457 458 459 460 461 462 463 464 465 466

    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

467 468 469 470 471 472 473 474 475 476 477 478
  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|
479
      assert_no_match(/sqlite/i, content)
480 481 482 483 484 485 486
    end
  end

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

    assert_file '.gitignore' do |content|
487
      assert_no_match(/sqlite/i, content)
488 489 490
    end
  end

491 492
  def test_psych_gem
    run_generator
493
    gem_regex = /gem 'psych',\s+'~> 2.0',\s+platforms: :rbx/
494 495 496 497 498 499 500 501 502 503

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

504 505 506 507 508 509 510 511 512 513 514 515 516 517 518
  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

519
  protected
J
José Valim 已提交
520

521
  def action(*args, &block)
522
    capture(:stdout) { generator.send(*args, &block) }
523
  end
O
Oscar Del Ben 已提交
524 525

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