diff --git a/.github/workflows/rspec-shared.yml b/.github/workflows/rspec-shared.yml new file mode 100644 index 0000000..629a388 --- /dev/null +++ b/.github/workflows/rspec-shared.yml @@ -0,0 +1,32 @@ +name: RSpec Shared + +on: + workflow_call: + inputs: + rspec-task: + required: true + type: string + +jobs: + rspec: + runs-on: ubuntu-latest + steps: + - name: Checkout code + uses: actions/checkout@v4 + - name: Set up Ruby + uses: ruby/setup-ruby@v1 + with: + ruby-version: "3.2" + bundler-cache: true + - name: Install dependencies + run: bundle install + - name: Run tests + env: + RAILS_ENV: test + run: bundle exec rake ${{ inputs.rspec-task }} + - name: Upload coverage results + uses: actions/upload-artifact@master + if: always() + with: + name: coverage-report-${{ github.run_id }}-ubuntu-latest-ruby-3.2 + path: coverage diff --git a/.github/workflows/rspec.yml b/.github/workflows/rspec.yml index ec5b499..4ebaa0e 100644 --- a/.github/workflows/rspec.yml +++ b/.github/workflows/rspec.yml @@ -5,28 +5,17 @@ on: branches: - main pull_request: + workflow_dispatch: jobs: - rspec: - runs-on: ubuntu-latest - name: RSpec - steps: - - name: Checkout code - uses: actions/checkout@v4 - - name: Set up Ruby - uses: ruby/setup-ruby@v1 - with: - ruby-version: "3.2" - bundler-cache: true - - name: Install dependencies - run: bundle install - - name: Run tests - env: - RAILS_ENV: test - run: bundle exec rspec --format documentation - - name: Upload coverage results - uses: actions/upload-artifact@master - if: always() - with: - name: coverage-report-${{ github.run_id }}-ubuntu-latest-ruby-3.2 - path: coverage + non-rails-rspec: + name: RSpec (non-rails) + uses: ./.github/workflows/rspec-shared.yml + with: + rspec-task: non_rails_spec + + rails-rspec: + name: RSpec (on rails) + uses: ./.github/workflows/rspec-shared.yml + with: + rspec-task: rails_spec diff --git a/Gemfile b/Gemfile index 07e5742..560cc00 100644 --- a/Gemfile +++ b/Gemfile @@ -9,6 +9,7 @@ group :development do end group :test do + gem 'rails', '~> 7.1.1' gem 'rspec', '~> 3.2' gem 'simplecov', '~> 0.21' end diff --git a/Rakefile b/Rakefile index 4f957ff..3c7fbd9 100644 --- a/Rakefile +++ b/Rakefile @@ -4,7 +4,46 @@ require 'bundler/gem_tasks' require 'rubocop/rake_task' require 'rspec/core/rake_task' -RSpec::Core::RakeTask.new(:spec) RuboCop::RakeTask.new +RSpec::Core::RakeTask.new(:spec) + +task default: %i[rubocop spec] + +desc 'Run tests on non-rails environment' +task :non_rails_spec do + ENV.delete('RAILS_APP_PATH') + + Rake::Task[:spec].invoke +end + +DUMMY_RAILS_APP_PATH = 'tmp/test/dummy/' + +desc 'Run tests on rails environment' +task :rails_spec do + ENV['RAILS_APP_PATH'] = File.expand_path(DUMMY_RAILS_APP_PATH, __dir__) + + Rake::Task['rails:generate_dummy_app'].invoke(ENV.fetch('RAILS_APP_PATH')) + Rake::Task[:spec].invoke +end + +namespace :rails do + desc 'Generate dummy rails application' + task :generate_dummy_app, [:app_path] do |_t, args| + app_path = args.fetch(:app_path) + + if Dir.exist?(app_path) + puts "Using Rails application at #{app_path} as a dummy..." + next + end -task default: %i[spec rubocop] + puts 'Generating dummy Rails application...' + system( + "rails new #{app_path} " \ + '--skip-git --skip-asset-pipeline --skip-action-cable ' \ + '--skip-action-mailer --skip-action-mailbox --skip-action-text ' \ + '--skip-active-record --skip-active-job --skip-active-storage ' \ + '--skip-javascript --skip-hotwire --skip-jbuilder ' \ + '--skip-test --skip-system-test --skip-bootsnap ', + ) + end +end diff --git a/spec/rspec_settings.rb b/spec/rspec_settings.rb index 031370b..60bff55 100644 --- a/spec/rspec_settings.rb +++ b/spec/rspec_settings.rb @@ -3,11 +3,28 @@ require 'simplecov' SimpleCov.start do add_filter '/spec/' + add_filter %r{^/tmp/} end require 'uber_task' require 'colorize' +rails_app_path = ENV.fetch('RAILS_APP_PATH', nil) + +if rails_app_path + unless Dir.exist?(rails_app_path) + raise "Rails application at #{rails_app_path} doesn't exit" + end + + require File.expand_path( + File.join(rails_app_path, '/config/environment.rb'), + __dir__, + ) + + ENV['RAILS_ROOT'] = rails_app_path + raise 'Failed to load Rails application' unless defined?(Rails) +end + RSpec.configure do |config| config.expect_with :rspec do |c| c.syntax = :expect diff --git a/spec/uber_task/internal/path_spec.rb b/spec/uber_task/internal/path_spec.rb index dd95db7..980179f 100644 --- a/spec/uber_task/internal/path_spec.rb +++ b/spec/uber_task/internal/path_spec.rb @@ -26,7 +26,7 @@ end context 'in rails' do - let(:rails_root) { Pathname.new(Dir.pwd) } + let(:rails_root) { defined?(Rails) ? Rails.root : Pathname.new(Dir.pwd) } let(:paths) do [ rails_root.join('abc').to_s, @@ -36,7 +36,7 @@ end before do - stub_const('Rails', double(root: rails_root)) + stub_const('Rails', double(root: rails_root)) unless defined?(Rails) end it 'shortens paths' do diff --git a/spec/uber_task/logger_spec.rb b/spec/uber_task/logger_spec.rb index 14f87dc..1a5c565 100644 --- a/spec/uber_task/logger_spec.rb +++ b/spec/uber_task/logger_spec.rb @@ -14,8 +14,12 @@ ) end - context 'when Rails logger is not defined' do - it 'uses stdout logger by default' do + it 'uses Rails or stdout logger by default' do + if defined?(Rails) + expect(Rails.logger).to receive(:info).with('some message') + + described_class.logger.info('some message') + else expect do described_class.logger.info('some message') end.to output(/some message/).to_stdout