From 9c8ccb76cd49fa37e1d5ff2bd846f07721839965 Mon Sep 17 00:00:00 2001 From: zzak Date: Thu, 11 Jan 2024 17:48:59 +0900 Subject: [PATCH] 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 hotwired/stimulus-rails#136. The motivation is to be able to move these tests from railties, see: rails/rails#49679 Co-authored-by: Jonathan Hefner --- .github/workflows/ci.yml | 1 + test/app_helper.rb | 48 ++++++++++++++++++++++++++++ test/installer_test.rb | 69 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 118 insertions(+) create mode 100644 test/app_helper.rb create mode 100644 test/installer_test.rb diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 55168746..955a1e36 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -29,6 +29,7 @@ jobs: rubygems: latest bundler-cache: true + - uses: oven-sh/setup-bun@v1 - name: Run tests id: test run: bundle exec rake TESTOPT=-vdc diff --git a/test/app_helper.rb b/test/app_helper.rb new file mode 100644 index 00000000..dd128dca --- /dev/null +++ b/test/app_helper.rb @@ -0,0 +1,48 @@ +require "rails" +require "rails/test_help" +require "fileutils" + +module RailsAppHelpers + def self.included(base) + base.include ActiveSupport::Testing::Isolation + end + + private + def create_new_rails_app(app_dir, options=[]) + require "rails/generators/rails/app/app_generator" + Rails::Generators::AppGenerator.start([app_dir, *options, "--skip-bundle", "--skip-bootsnap", "--quiet"]) + + Dir.chdir(app_dir) do + gemfile = File.read("Gemfile") + + gemfile.gsub!(/^gem ["']turbo-rails["'].*/, "") + gemfile << %(gem "turbo-rails", path: #{File.expand_path("..", __dir__).inspect}\n) + + if Rails::VERSION::PRE == "alpha" + gemfile.gsub!(/^gem ["']rails["'].*/, "") + gemfile << %(gem "rails", path: #{Gem.loaded_specs["rails"].full_gem_path.inspect}\n) + end + + File.write("Gemfile", gemfile) + + run_command("bundle", "install") + end + end + + def with_new_rails_app(options=[], &block) + require "digest/sha1" + variant = [RUBY_VERSION, Gem.loaded_specs["rails"].full_gem_path,] + app_name = "turbo_test_app_#{Digest::SHA1.hexdigest(variant.to_s)}" + + Dir.mktmpdir do |tmpdir| + create_new_rails_app("#{tmpdir}/#{app_name}", *options) + Dir.chdir("#{tmpdir}/#{app_name}", &block) + end + end + + def run_command(*command) + Bundler.with_unbundled_env do + capture_subprocess_io { system(*command, exception: true) } + end + end +end \ No newline at end of file diff --git a/test/installer_test.rb b/test/installer_test.rb new file mode 100644 index 00000000..9bae361e --- /dev/null +++ b/test/installer_test.rb @@ -0,0 +1,69 @@ +require 'app_helper' + +class InstallerTest < ActiveSupport::TestCase + include RailsAppHelpers + + test "installer" do + with_new_rails_app do + if Rails::VERSION::MAJOR >= 7 && File.read("Gemfile").match?(/importmap-rails/) + run_command("bin/rails", "importmap:install") + end + _out, _err = run_command("bin/rails", "turbo:install") + + assert_match %(import "@hotwired/turbo-rails"\n), File.read("app/javascript/application.js") + + if Rails::VERSION::MAJOR >= 7 + assert_match %(pin "@hotwired/turbo-rails", to: "turbo.min.js"), File.read("config/importmap.rb") + else + assert_match "@hotwired/turbo-rails", File.read("package.json") + assert_match "@hotwired/turbo-rails", File.read("yarn.lock") + end + end + end + + test "installer with no javascript" do + with_new_rails_app %w[--skip-javascript] do + out, _err = run_command("bin/rails", "turbo:install") + + assert_match "You must either be running with node (package.json) or importmap-rails (config/importmap.rb) to use this gem.", out + end + end + + test "installer with pre-existing application.js" do + with_new_rails_app do + if Rails::VERSION::MAJOR >= 7 && File.read("Gemfile").match?(/importmap-rails/) + run_command("bin/rails", "importmap:install") + end + File.write("app/javascript/application.js", "// pre-existing") + _out, _err = run_command("bin/rails", "turbo:install") + + assert_match "// pre-existing", File.read("app/javascript/application.js") + end + end + + if Gem::Version.new(Rails.version) >= Gem::Version.new("7.1") + test "installer with bun" do + with_new_rails_app %w[--javascript=bun] do + run_command("bin/rails", "javascript:install:bun") + _out, _err = run_command("bin/rails", "turbo:install") + + assert_match %(import "@hotwired/turbo-rails"\n), File.read("app/javascript/application.js") + + assert_match "@hotwired/turbo-rails", File.read("package.json") + end + end + end + + private + def with_new_rails_app(options=[], &block) + super do + if Dir.exist?("app/javascript") && !File.exist?("app/javascript/application.js") + File.write("app/javascript/application.js", <<~JS, mode: "a+") + import "./controllers" + JS + end + + block.call + end + end +end \ No newline at end of file