Skip to content

Commit 2be77df

Browse files
zzakjonathanhefner
andcommitted
Test installer
This commit adds test coverage for the installer Rake task and application template. The installer is run against a freshly generated Rails app using the version of Rails that is currently loaded. Thus the installer can be tested with different versions of Rails in CI. Similar to rails/importmap-rails#206 for stimulus-rails The motivation is to be able to move these tests from railties, see: rails/rails#49679 Co-authored-by: Jonathan Hefner <[email protected]>
1 parent ae4b675 commit 2be77df

File tree

3 files changed

+130
-0
lines changed

3 files changed

+130
-0
lines changed

.github/workflows/ci.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ jobs:
1212
'6.0.0',
1313
'6.1.0',
1414
'7.0.1',
15+
'7.1.2'
1516
]
1617
ruby: [
1718
'2.7',
@@ -36,6 +37,7 @@ jobs:
3637
ruby-version: ${{ matrix.ruby }}
3738
bundler-cache: false
3839

40+
- uses: oven-sh/setup-bun@v1
3941
- name: Install Dependencies
4042
env:
4143
RAILS_VERSION: ${{ matrix.rails }}

test/installer_test.rb

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
require 'test_helper'
2+
3+
class InstallerTest < ActiveSupport::TestCase
4+
include RailsAppHelpers
5+
6+
test "installer" do
7+
with_new_rails_app do
8+
if Rails::VERSION::MAJOR >= 7 && File.read("Gemfile").match?(/importmap-rails/)
9+
run_command("bin/rails", "importmap:install")
10+
end
11+
_out, _err = run_command("bin/rails", "stimulus:install")
12+
13+
assert_match %r(import "(./)?controllers"), File.read("app/javascript/application.js")
14+
assert_equal File.read("#{__dir__}/../lib/install/app/javascript/controllers/application.js"), File.read("app/javascript/controllers/application.js")
15+
assert_equal File.read("#{__dir__}/../lib/install/app/javascript/controllers/hello_controller.js"), File.read("app/javascript/controllers/hello_controller.js")
16+
17+
if Rails::VERSION::MAJOR >= 7
18+
assert_equal File.read("#{__dir__}/../lib/install/app/javascript/controllers/index_for_importmap.js"), File.read("app/javascript/controllers/index.js")
19+
assert_match %(pin "@hotwired/stimulus", to: "stimulus.min.js"), File.read("config/importmap.rb")
20+
assert_match %(pin "@hotwired/stimulus-loading", to: "stimulus-loading.js"), File.read("config/importmap.rb")
21+
assert_match %(pin_all_from "app/javascript/controllers", under: "controllers"), File.read("config/importmap.rb")
22+
else
23+
assert_equal File.read("#{__dir__}/../lib/install/app/javascript/controllers/index_for_node.js"), File.read("app/javascript/controllers/index.js")
24+
assert_match "@hotwired/stimulus", File.read("package.json")
25+
assert_match "@hotwired/stimulus", File.read("yarn.lock")
26+
end
27+
end
28+
end
29+
30+
test "installer with no javascript" do
31+
with_new_rails_app %w[--skip-javascript] do
32+
out, _err = run_command("bin/rails", "stimulus:install")
33+
34+
assert_match "You must either be running with node (package.json) or importmap-rails (config/importmap.rb) to use this gem.", out
35+
end
36+
end
37+
38+
test "installer with pre-existing application.js" do
39+
with_new_rails_app do
40+
if Rails::VERSION::MAJOR >= 7 && File.read("Gemfile").match?(/importmap-rails/)
41+
run_command("bin/rails", "importmap:install")
42+
end
43+
File.write("app/javascript/application.js", "// pre-existing")
44+
_out, _err = run_command("bin/rails", "stimulus:install")
45+
46+
assert_match "// pre-existing", File.read("app/javascript/application.js")
47+
end
48+
end
49+
50+
if Gem::Version.new(Rails.version) >= Gem::Version.new("7.1")
51+
test "installer with bun" do
52+
with_new_rails_app %w[--javascript=bun] do
53+
run_command("bin/rails", "javascript:install:bun")
54+
_out, _err = run_command("bin/rails", "stimulus:install")
55+
56+
assert_match %r(import "(./)?controllers"), File.read("app/javascript/application.js")
57+
assert_equal File.read("#{__dir__}/../lib/install/app/javascript/controllers/application.js"), File.read("app/javascript/controllers/application.js")
58+
assert_equal File.read("#{__dir__}/../lib/install/app/javascript/controllers/hello_controller.js"), File.read("app/javascript/controllers/hello_controller.js")
59+
60+
assert_equal File.read("#{__dir__}/../lib/install/app/javascript/controllers/index_for_node.js"), File.read("app/javascript/controllers/index.js")
61+
62+
assert_match "@hotwired/stimulus", File.read("package.json")
63+
end
64+
end
65+
end
66+
67+
private
68+
def with_new_rails_app(options=[], &block)
69+
super do
70+
if Dir.exist?("app/javascript") && !File.exist?("app/javascript/application.js")
71+
File.write("app/javascript/application.js", <<~JS, mode: "a+")
72+
import "./controllers"
73+
JS
74+
end
75+
76+
block.call
77+
end
78+
end
79+
end

test/test_helper.rb

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,3 +6,52 @@
66

77
# Set fixture path
88
ActiveSupport::TestCase.file_fixture_path = File.expand_path("fixtures", __dir__)
9+
10+
require "fileutils"
11+
require "rails"
12+
require "rails/test_help"
13+
14+
module RailsAppHelpers
15+
def self.included(base)
16+
base.include ActiveSupport::Testing::Isolation
17+
end
18+
19+
private
20+
def create_new_rails_app(app_dir, options=[])
21+
require "rails/generators/rails/app/app_generator"
22+
Rails::Generators::AppGenerator.start([app_dir, *options, "--skip-bundle", "--skip-bootsnap", "--quiet"])
23+
24+
Dir.chdir(app_dir) do
25+
gemfile = File.read("Gemfile")
26+
27+
gemfile.gsub!(/^gem ["']stimulus-rails["'].*/, "")
28+
gemfile << %(gem "stimulus-rails", path: #{File.expand_path("..", __dir__).inspect}\n)
29+
30+
if Rails::VERSION::PRE == "alpha"
31+
gemfile.gsub!(/^gem ["']rails["'].*/, "")
32+
gemfile << %(gem "rails", path: #{Gem.loaded_specs["rails"].full_gem_path.inspect}\n)
33+
end
34+
35+
File.write("Gemfile", gemfile)
36+
37+
run_command("bundle", "install")
38+
end
39+
end
40+
41+
def with_new_rails_app(options=[], &block)
42+
require "digest/sha1"
43+
variant = [RUBY_VERSION, Gem.loaded_specs["rails"].full_gem_path,]
44+
app_name = "app_#{Digest::SHA1.hexdigest(variant.to_s)}"
45+
46+
Dir.mktmpdir do |tmpdir|
47+
create_new_rails_app("#{tmpdir}/#{app_name}", *options)
48+
Dir.chdir("#{tmpdir}/#{app_name}", &block)
49+
end
50+
end
51+
52+
def run_command(*command)
53+
Bundler.with_unbundled_env do
54+
capture_subprocess_io { system(*command, exception: true) }
55+
end
56+
end
57+
end

0 commit comments

Comments
 (0)