diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml new file mode 100644 index 0000000..948bb25 --- /dev/null +++ b/.github/workflows/tests.yml @@ -0,0 +1,44 @@ +name: Run Tests + +on: + push: + branches: [ "main" ] + pull_request: + branches: [ "main" ] + +jobs: + spec: + runs-on: ubuntu-latest + + strategy: + matrix: + ruby_version: + - "3.1" + - "3.2" + - "3.3" + gemfile: + - "rails70" + - "rails71" + - "rails72" + - "rails80" + exclude: + - ruby_version: "3.1" + gemfile: "rails80" + include: + - ruby_version: "head" + gemfile: "rails-main" + + env: + BUNDLE_GEMFILE: ${{ github.workspace }}/gemfiles/${{ matrix.gemfile }}.gemfile + + steps: + - uses: actions/checkout@v4 + + - name: Set up Ruby + uses: ruby/setup-ruby@v1 + with: + ruby-version: ${{ matrix.ruby_version }} + bundler-cache: true + + - name: Run Tests + run: bundle exec rake diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 279ee40..0000000 --- a/.travis.yml +++ /dev/null @@ -1,61 +0,0 @@ -dist: bionic -language: ruby - -rvm: - - "2.3" - - "2.4" - - "2.5" - - "2.6" - - ruby-head - -gemfile: - - Gemfile - - gemfiles/rails50.gemfile - - gemfiles/rails51.gemfile - - gemfiles/rails52.gemfile - - gemfiles/rails60.gemfile - -matrix: - include: - # Rails 4.2 requires Bundler 1.x which was being difficult to use with - # Travis and Ruby 2.6+ since Bundler is now packaged with Ruby. - - rvm: "2.3" - gemfile: gemfiles/rails42.gemfile - - rvm: "2.4" - gemfile: gemfiles/rails42.gemfile - - rvm: "2.5" - gemfile: gemfiles/rails42.gemfile - - # Test Rails master against the latest stable version of Ruby - - rvm: "ruby" - gemfile: gemfiles/rails-master.gemfile - - exclude: - - rvm: "2.3" - gemfile: Gemfile - - rvm: "2.3" - gemfile: gemfiles/rails60.gemfile - - rvm: "2.4" - gemfile: Gemfile - - rvm: "2.4" - gemfile: gemfiles/rails60.gemfile - allow_failures: - - rvm: ruby-head - - gemfile: gemfiles/rails-master.gemfile - -before_install: - # Use bundler 1.x with Rails 4.2 - - "([[ $BUNDLE_GEMFILE =~ rails42 ]] && (gem uninstall -v '>= 2' -ax bundler || true) && gem install bundler -v '< 2') || true" - -script: - - bundle exec rspec --format=documentation - -# Report test cover to codeclimate -after_success: - - bundle exec codeclimate-test-reporter - -notifications: - webhooks: - on_start: always - urls: - - https://buildlight.collectiveidea.com/ diff --git a/CHANGELOG.md b/CHANGELOG.md index e093590..11c13ef 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,11 @@ +## 2.3.0 / TBD + +* [ENHANCEMENT] Add support for test-unit +* [ENHANCEMENT] Add support for Ruby 3.1+ and Rails 7.0+ +* [ENHANCEMENT] Drop support for EOL Ruby and Rails versions +* [ENHANCEMENT] Change depdency from all of Rails to just railties +* [ENHANCEMENT] Prefer spec/rails_helper.rb when available + ## 2.2.0 / 2019-09-01 * [ENHANCEMENT] Add support for Ruby 2.6 diff --git a/README.md b/README.md index 308f3bb..b1d69d7 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ # Interactor Rails [![Gem](https://img.shields.io/gem/v/interactor-rails.svg?style=flat-square)](http://rubygems.org/gems/interactor-rails) -[![Build](https://img.shields.io/travis/collectiveidea/interactor-rails/master.svg?style=flat-square)](https://travis-ci.org/collectiveidea/interactor-rails) +[![Build](https://github.com/collectiveidea/interactor-rails/actions/workflows/tests.yml/badge.svg)](https://github.com/collectiveidea/interactor-rails/actions/workflows/tests.yml) [![Coverage](https://img.shields.io/codeclimate/coverage-letter/collectiveidea/interactor-rails.svg?style=flat-square)](https://codeclimate.com/github/collectiveidea/interactor-rails) [![Maintainability](https://img.shields.io/codeclimate/maintainability/collectiveidea/interactor-rails.svg?style=flat-square)](https://codeclimate.com/github/collectiveidea/interactor-rails) @@ -16,8 +16,8 @@ Add this line to your application's Gemfile: gem "interactor-rails", "~> 2.0" ``` -Interactor Rails is compatible with Ruby 2.3, 2.4, or 2.5 on Rails 4.2, 5.0, -5.1, 5.2 or 6.0. +Interactor Rails is tested against Ruby 3.1 and newer on Rails 7.0 or newer. +For older versions of Ruby and Rails use version 2.2.1. ## Usage diff --git a/gemfiles/rails-master.gemfile b/gemfiles/rails-main.gemfile similarity index 100% rename from gemfiles/rails-master.gemfile rename to gemfiles/rails-main.gemfile diff --git a/gemfiles/rails60.gemfile b/gemfiles/rails60.gemfile deleted file mode 100644 index e8d675e..0000000 --- a/gemfiles/rails60.gemfile +++ /dev/null @@ -1,11 +0,0 @@ -source "https://rubygems.org" - -gemspec path: ".." - -gem "rails", "~> 6.0.0" - -group :test do - gem "aruba" - gem "codeclimate-test-reporter", "~> 1.0" - gem "rspec" -end diff --git a/gemfiles/rails52.gemfile b/gemfiles/rails70.gemfile similarity index 85% rename from gemfiles/rails52.gemfile rename to gemfiles/rails70.gemfile index a0236d9..c62b9c8 100644 --- a/gemfiles/rails52.gemfile +++ b/gemfiles/rails70.gemfile @@ -2,7 +2,7 @@ source "https://rubygems.org" gemspec path: ".." -gem "rails", "~> 5.2.0" +gem "rails", "~> 7.0.0" group :test do gem "aruba" diff --git a/gemfiles/rails42.gemfile b/gemfiles/rails71.gemfile similarity index 85% rename from gemfiles/rails42.gemfile rename to gemfiles/rails71.gemfile index d546131..930bbfe 100644 --- a/gemfiles/rails42.gemfile +++ b/gemfiles/rails71.gemfile @@ -2,7 +2,7 @@ source "https://rubygems.org" gemspec path: ".." -gem "rails", "~> 4.2.0" +gem "rails", "~> 7.1.0" group :test do gem "aruba" diff --git a/gemfiles/rails50.gemfile b/gemfiles/rails72.gemfile similarity index 85% rename from gemfiles/rails50.gemfile rename to gemfiles/rails72.gemfile index 48e1e7d..760a50a 100644 --- a/gemfiles/rails50.gemfile +++ b/gemfiles/rails72.gemfile @@ -2,7 +2,7 @@ source "https://rubygems.org" gemspec path: ".." -gem "rails", "~> 5.0.0" +gem "rails", "~> 7.2.0" group :test do gem "aruba" diff --git a/gemfiles/rails51.gemfile b/gemfiles/rails80.gemfile similarity index 85% rename from gemfiles/rails51.gemfile rename to gemfiles/rails80.gemfile index e6aadca..5d2523d 100644 --- a/gemfiles/rails51.gemfile +++ b/gemfiles/rails80.gemfile @@ -2,7 +2,7 @@ source "https://rubygems.org" gemspec path: ".." -gem "rails", "~> 5.1.0" +gem "rails", "~> 8.0.0" group :test do gem "aruba" diff --git a/interactor-rails.gemspec b/interactor-rails.gemspec index 971cd10..f234f4c 100644 --- a/interactor-rails.gemspec +++ b/interactor-rails.gemspec @@ -1,4 +1,4 @@ -# encoding: utf-8 +# frozen_string_literal: true Gem::Specification.new do |spec| spec.name = "interactor-rails" @@ -15,7 +15,7 @@ Gem::Specification.new do |spec| spec.test_files = spec.files.grep(/^spec/) spec.add_dependency "interactor", "~> 3.0" - spec.add_dependency "rails", ">= 4.2" + spec.add_dependency "railties", ">= 7.0" spec.add_development_dependency "bundler" spec.add_development_dependency "rake" diff --git a/lib/generators/interactor.rb b/lib/generators/interactor.rb index 063df82..f666049 100644 --- a/lib/generators/interactor.rb +++ b/lib/generators/interactor.rb @@ -1,12 +1,29 @@ module Interactor class Generator < ::Rails::Generators::NamedBase def self.source_root - File.expand_path("../templates", __FILE__) + File.expand_path("templates", __dir__) end def generate template "#{self.class.generator_name}.erb", File.join("app/interactors", class_path, "#{file_name}.rb") - template "spec.erb", File.join("spec/interactors", class_path, "#{file_name}_spec.rb") + + if use_test_unit? + template "test.erb", File.join("test/interactors", class_path, "#{file_name}_test.rb") + else + template "spec.erb", File.join("spec/interactors", class_path, "#{file_name}_spec.rb") + end + end + + def use_test_unit? + ::Rails.application.config.generators.options[:rails][:test_framework] == :test_unit + end + + def rspec_helper_file + if File.exist?("spec/rails_helper.rb") + "rails_helper" + else + "spec_helper" + end end end end diff --git a/lib/generators/templates/spec.erb b/lib/generators/templates/spec.erb index 95070b3..a6f856a 100644 --- a/lib/generators/templates/spec.erb +++ b/lib/generators/templates/spec.erb @@ -1,4 +1,4 @@ -require 'spec_helper' +require "<%= rspec_helper_file %>" RSpec.describe <%= class_name %>, type: :interactor do describe '.call' do diff --git a/lib/generators/templates/test.erb b/lib/generators/templates/test.erb new file mode 100644 index 0000000..39eb17c --- /dev/null +++ b/lib/generators/templates/test.erb @@ -0,0 +1,7 @@ +require "test_helper" + +class <%= class_name %>Test < ActiveSupport::TestCase + # test "the truth" do + # assert true + # end +end diff --git a/spec/interactor/rails_spec.rb b/spec/interactor/rails_spec.rb index 217032c..cfb1d5e 100644 --- a/spec/interactor/rails_spec.rb +++ b/spec/interactor/rails_spec.rb @@ -1,22 +1,18 @@ module Interactor describe "Rails" do - def last_command_started - # Account for older versions of Aruba as required by Rails 3.0 - Aruba::Api.method_defined?(:last_command_started) ? super : last_command - end - before do - run_command_and_stop <<-CMD + run_command_and_stop <<~CMD bundle exec rails new example \ - --skip-yarn \ - --skip-gemfile \ --skip-git \ --skip-keeps \ --skip-action-mailer \ - --skip-active-record \ - --skip-puma \ + --skip-action-mailbox \ + --skip-action-text \ --skip-action-cable \ - --skip-sprockets \ + --skip-active-record \ + --skip-active-job \ + --skip-active-storage \ + --skip-asset-pipeline \ --skip-spring \ --skip-listen \ --skip-coffee \ @@ -28,12 +24,14 @@ def last_command_started --skip-bundle \ --skip-bootsnap \ --quiet - CMD + CMD + cd "example" - write_file "Gemfile", <<-EOF + write_file "Gemfile", <<~FILE gem "rails" gem "interactor-rails", path: "#{ROOT}" - EOF + FILE + run_command_and_stop "bundle install" end @@ -44,27 +42,27 @@ def last_command_started path = "app/interactors/place_order.rb" expect(path).to be_an_existing_file - expect(path).to have_file_content(<<-EOF) -class PlaceOrder - include Interactor + expect(path).to have_file_content(<<~FILE) + class PlaceOrder + include Interactor - def call - # TODO - end -end -EOF + def call + # TODO + end + end + FILE - path = 'spec/interactors/place_order_spec.rb' + path = "spec/interactors/place_order_spec.rb" expect(path).to be_an_existing_file - expect(path).to have_file_content(<<-EOF) -require 'spec_helper' - -RSpec.describe PlaceOrder, type: :interactor do - describe '.call' do - pending "add some examples to (or delete) \#{__FILE__}" - end -end -EOF + expect(path).to have_file_content(<<~FILE) + require "spec_helper" + + RSpec.describe PlaceOrder, type: :interactor do + describe '.call' do + pending "add some examples to (or delete) \#{__FILE__}" + end + end + FILE end it "requires a name" do @@ -79,74 +77,74 @@ def call path = "app/interactors/invoice/place_order.rb" expect(path).to be_an_existing_file - expect(path).to have_file_content(<<-EOF) -class Invoice::PlaceOrder - include Interactor + expect(path).to have_file_content(<<~FILE) + class Invoice::PlaceOrder + include Interactor - def call - # TODO - end -end -EOF + def call + # TODO + end + end + FILE path = "spec/interactors/invoice/place_order_spec.rb" expect(path).to be_an_existing_file - expect(path).to have_file_content(<<-EOF) -require 'spec_helper' - -RSpec.describe Invoice::PlaceOrder, type: :interactor do - describe '.call' do - pending "add some examples to (or delete) \#{__FILE__}" - end -end -EOF + expect(path).to have_file_content(<<~FILE) + require "spec_helper" + + RSpec.describe Invoice::PlaceOrder, type: :interactor do + describe '.call' do + pending "add some examples to (or delete) \#{__FILE__}" + end + end + FILE end end context "interactor:organizer" do it "generates an organizer" do - run_command_and_stop <<-CMD + run_command_and_stop <<~CMD bundle exec rails generate interactor:organizer place_order - CMD + CMD path = "app/interactors/place_order.rb" expect(path).to be_an_existing_file - expect(path).to have_file_content(<<-EOF) -class PlaceOrder - include Interactor::Organizer + expect(path).to have_file_content(<<~FILE) + class PlaceOrder + include Interactor::Organizer - # organize Interactor1, Interactor2 -end -EOF + # organize Interactor1, Interactor2 + end + FILE path = "spec/interactors/place_order_spec.rb" expect(path).to be_an_existing_file - expect(path).to have_file_content(<<-EOF) -require 'spec_helper' - -RSpec.describe PlaceOrder, type: :interactor do - describe '.call' do - pending "add some examples to (or delete) \#{__FILE__}" - end -end -EOF + expect(path).to have_file_content(<<~FILE) + require "spec_helper" + + RSpec.describe PlaceOrder, type: :interactor do + describe '.call' do + pending "add some examples to (or delete) \#{__FILE__}" + end + end + FILE end it "generates an organizer with interactors" do - run_command_and_stop <<-CMD + run_command_and_stop <<~CMD bundle exec rails generate interactor:organizer place_order \ charge_card fulfill_order - CMD + CMD path = "app/interactors/place_order.rb" expect(path).to be_an_existing_file - expect(path).to have_file_content(<<-EOF) -class PlaceOrder - include Interactor::Organizer + expect(path).to have_file_content(<<~FILE) + class PlaceOrder + include Interactor::Organizer - organize ChargeCard, FulfillOrder -end -EOF + organize ChargeCard, FulfillOrder + end + FILE end it "requires a name" do @@ -161,38 +159,85 @@ class PlaceOrder path = "app/interactors/invoice/place_order.rb" expect(path).to be_an_existing_file - expect(path).to have_file_content(<<-EOF) -class Invoice::PlaceOrder - include Interactor::Organizer + expect(path).to have_file_content(<<~FILE) + class Invoice::PlaceOrder + include Interactor::Organizer - # organize Interactor1, Interactor2 -end -EOF + # organize Interactor1, Interactor2 + end + FILE path = "spec/interactors/invoice/place_order_spec.rb" expect(path).to be_an_existing_file - expect(path).to have_file_content(<<-EOF) -require 'spec_helper' - -RSpec.describe Invoice::PlaceOrder, type: :interactor do - describe '.call' do - pending "add some examples to (or delete) \#{__FILE__}" - end -end -EOF + expect(path).to have_file_content(<<~FILE) + require "spec_helper" + + RSpec.describe Invoice::PlaceOrder, type: :interactor do + describe '.call' do + pending "add some examples to (or delete) \#{__FILE__}" + end + end + FILE end end + + it "prefers rails_helper if available" do + write_file "spec/rails_helper.rb", <<~FILE + require "spec_helper" + FILE + + run_command_and_stop "bundle exec rails generate interactor place_order" + + path = "spec/interactors/place_order_spec.rb" + expect(path).to be_an_existing_file + expect(path).to have_file_content(<<~FILE) + require "rails_helper" + + RSpec.describe PlaceOrder, type: :interactor do + describe '.call' do + pending "add some examples to (or delete) \#{__FILE__}" + end + end + FILE + ensure + remove("spec/rails_helper.rb") + end + end + + it "support test unit instead of rspec" do + # Enable test-unit support since it is skipped while generating the app. + write_file "config/initializers/test_unit.rb", <<~FILE + require "rails/test_unit/railtie" + FILE + + run_command_and_stop "bundle exec rails generate interactor invoice/place_order" + + path = "spec/interactors/invoice/place_order_spec.rb" + expect(path).not_to be_an_existing_file + + path = "test/interactors/invoice/place_order_test.rb" + expect(path).to be_an_existing_file + + expect(path).to have_file_content(<<~FILE) + require "test_helper" + + class Invoice::PlaceOrderTest < ActiveSupport::TestCase + # test "the truth" do + # assert true + # end + end + FILE + ensure + remove("config/initializers/test_unit.rb") end it "auto-loads interactors" do run_command_and_stop "bundle exec rails generate interactor place_order" - run_command_and_stop "bundle exec rails runner PlaceOrder" end it "auto-loads organizers" do run_command_and_stop "bundle exec rails generate interactor:organizer place_order" - run_command_and_stop "bundle exec rails runner PlaceOrder" end end