diff --git a/README.md b/README.md index 0aaf5cdeb..88274d8cc 100644 --- a/README.md +++ b/README.md @@ -222,6 +222,25 @@ To use Webpacker with [Elm](http://elm-lang.org), create a new app with `rails n The Elm library and core packages will be added via Yarn and Elm itself. An example `Main.elm` app is also added to your project in `app/javascript` so that you can experiment with Elm right away. +## Testing + +Webpacker provides a `Webpacker::TestHelper`, which includes a setup to +pre-compile webpacker assets when running tests. + +```rb +# Test the example react component message +require "webpacker/test_helper" +require "application_system_test_case" + +class HomesTest < ApplicationSystemTestCase + include Webpacker::TestHelper + test "can see the hello message" do + visit root_url + assert_selector "h5", text: "Hello! David" + end +end +``` + ## Troubleshooting * If you get this error `ENOENT: no such file or directory - node-sass` on Heroku diff --git a/lib/tasks/installers.rake b/lib/tasks/installers.rake index f96d7eb7a..3875fa66d 100644 --- a/lib/tasks/installers.rake +++ b/lib/tasks/installers.rake @@ -1,4 +1,4 @@ -INSTALLERS = { +installers = { "Angular": :angular, "Elm": :elm, "React": :react, @@ -7,7 +7,7 @@ INSTALLERS = { namespace :webpacker do namespace :install do - INSTALLERS.each do |name, task_name| + installers.each do |name, task_name| desc "Install everything needed for #{name}" task task_name => ["webpacker:verify_install"] do template = File.expand_path("../install/#{task_name}.rb", __dir__) diff --git a/lib/tasks/webpacker/compile.rake b/lib/tasks/webpacker/compile.rake index 9001064f5..42b4e5c18 100644 --- a/lib/tasks/webpacker/compile.rake +++ b/lib/tasks/webpacker/compile.rake @@ -1,6 +1,5 @@ require "webpacker/env" require "webpacker/configuration" -REGEX_MAP = /\A.*\.map\z/ namespace :webpacker do desc "Compile javascript packs using webpack for production with digests" @@ -25,12 +24,6 @@ namespace :webpacker do end end -# Compile packs prior to system and controller tests running -if Rake::Task.task_defined?("test:system") - Rake::Task["test:system"].enhance(["webpacker:compile_before_test"]) - Rake::Task["test:controllers"].enhance(["webpacker:compile_before_test"]) -end - # Compile packs after we've compiled all other assets during precompilation if Rake::Task.task_defined?("assets:precompile") Rake::Task["assets:precompile"].enhance do diff --git a/lib/tasks/webpacker/install.rake b/lib/tasks/webpacker/install.rake index 685d4fe3c..fd310356a 100644 --- a/lib/tasks/webpacker/install.rake +++ b/lib/tasks/webpacker/install.rake @@ -1,12 +1,12 @@ -WEBPACKER_APP_TEMPLATE_PATH = File.expand_path("../../install/template.rb", __dir__) +install_template_path = File.expand_path("../../install/template.rb", __dir__) namespace :webpacker do desc "Install webpacker in this application" task install: [:check_node, :check_yarn] do if Rails::VERSION::MAJOR >= 5 - exec "#{RbConfig.ruby} ./bin/rails app:template LOCATION=#{WEBPACKER_APP_TEMPLATE_PATH}" + exec "#{RbConfig.ruby} ./bin/rails app:template LOCATION=#{install_template_path}" else - exec "#{RbConfig.ruby} ./bin/rake rails:template LOCATION=#{WEBPACKER_APP_TEMPLATE_PATH}" + exec "#{RbConfig.ruby} ./bin/rake rails:template LOCATION=#{install_template_path}" end end end diff --git a/lib/webpacker/test_helper.rb b/lib/webpacker/test_helper.rb new file mode 100644 index 000000000..072e6e9d1 --- /dev/null +++ b/lib/webpacker/test_helper.rb @@ -0,0 +1,25 @@ +require "rake" +require "webpacker" + +module Webpacker::TestHelper + extend ActiveSupport::Concern + + included do + setup :compile_webpack_assets + end + + def compile_webpack_assets + Rails.cache.fetch(["webpacker", "manifest", checksum]) do + @load_rakefile ||= Rake.load_rakefile(Rails.root.join("Rakefile")) + Rake::Task["webpacker:compile"].invoke + Rake::Task["webpacker:compile"].reenable + end + end + + private + + def checksum + files = Dir["#{Webpacker::Configuration.source}/**/*", "package.json", "yarn.lock"].reject { |f| File.directory?(f) } + files.map { |f| File.mtime(f).utc.to_i }.max.to_s + end +end