Skip to content

Commit

Permalink
Test dartsass:install command
Browse files Browse the repository at this point in the history
This adds test coverage for the `dartsass:install` command.  The command
is tested 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.
  • Loading branch information
jonathanhefner committed Dec 3, 2023
1 parent 80e058a commit b423960
Show file tree
Hide file tree
Showing 2 changed files with 142 additions and 0 deletions.
71 changes: 71 additions & 0 deletions test/installer_test.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
require "test_helper"

class InstallerTest < ActiveSupport::TestCase
include RailsAppHelpers

test "installer" do
with_new_rails_app do
out, _err = run_command("bin/rails", "dartsass:install")

assert_match "<DONE>", out
assert_equal 0, File.size("app/assets/builds/.keep")
assert_match "/app/assets/builds/*\n!/app/assets/builds/.keep", File.read(".gitignore")
assert_equal File.read("#{__dir__}/../lib/install/application.scss"), File.read("app/assets/stylesheets/application.scss")
assert_equal File.read("#{__dir__}/../lib/install/Procfile.dev"), File.read("Procfile.dev")
assert_equal File.read("#{__dir__}/../lib/install/dev"), File.read("bin/dev")
assert_equal 0700, File.stat("bin/dev").mode & 0700

if sprockets?
assert_match "//= link_tree ../builds", File.read("app/assets/config/manifest.js")
assert_no_match "//= link_directory ../stylesheets .css", File.read("app/assets/config/manifest.js")
end
end
end

test "installer with missing .gitignore" do
with_new_rails_app do
FileUtils.rm(".gitignore")
out, _err = run_command("bin/rails", "dartsass:install")

assert_match "<DONE>", out
assert_not File.exist?(".gitignore")
end
end

test "installer with pre-existing application.scss" do
with_new_rails_app do
File.write("app/assets/stylesheets/application.scss", "// pre-existing")
out, _err = run_command("bin/rails", "dartsass:install")

assert_match "<DONE>", out
assert_equal "// pre-existing", File.read("app/assets/stylesheets/application.scss")
end
end

test "installer with pre-existing Procfile" do
with_new_rails_app do
File.write("Procfile.dev", "pre: existing\n")
out, _err = run_command("bin/rails", "dartsass:install")

assert_match "<DONE>", out
assert_equal "pre: existing\ncss: bin/rails dartsass:watch\n", File.read("Procfile.dev")
end
end

private
def with_new_rails_app(&block)
super do
# Override `dartsass:build` to check that installation completed and to reduce test run time.
File.write("Rakefile", <<~RAKEFILE, mode: "a+")
Rake::Task["dartsass:build"].clear
namespace :dartsass do
task build: :environment do
puts "<DONE>"
end
end
RAKEFILE

block.call
end
end
end
71 changes: 71 additions & 0 deletions test/test_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,74 @@
require "fileutils"
require "rails"
require "rails/test_help"

module RailsAppHelpers
def self.included(base)
base.include ActiveSupport::Testing::Isolation
end

private
def sprockets?
Gem.loaded_specs.key?("sprockets-rails")
end

def propshaft?
Gem.loaded_specs.key?("propshaft")
end

def asset_pipeline_option
if Rails::VERSION::MAJOR > 7
if propshaft?
"--asset-pipeline=propshaft"
elsif sprockets?
"--asset-pipeline=sprockets"
end
end
end

def create_new_rails_app(app_dir)
require "rails/generators/rails/app/app_generator"
Rails::Generators::AppGenerator.start([app_dir, *asset_pipeline_option, "--skip-bundle", "--skip-bootsnap", "--quiet"])

Dir.chdir(app_dir) do
gemfile = File.read("Gemfile")

gemfile.gsub!(/^gem ["']sassc?-rails["'].*/, "") # for Rails 6.1 and 7.0
gemfile.gsub!(/^gem ["']dartsass-rails["'].*/, "")
gemfile << %(gem "dartsass-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(&block)
require "digest/sha1"
variant = [Gem.loaded_specs["rails"].full_gem_path, asset_pipeline_option]
app_name = "app_#{Digest::SHA1.hexdigest(variant.to_s)}"
cache_dir = "#{__dir__}/../tmp"

Dir.mktmpdir do |tmpdir|
if Dir.exist?("#{cache_dir}/#{app_name}")
FileUtils.cp_r("#{cache_dir}/#{app_name}", tmpdir)
else
create_new_rails_app("#{tmpdir}/#{app_name}")
FileUtils.cp_r("#{tmpdir}/#{app_name}", cache_dir) # Cache app for future runs.
end

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

0 comments on commit b423960

Please sign in to comment.