diff --git a/.github/workflows/ruby.yml b/.github/workflows/ruby.yml new file mode 100644 index 0000000..d3e4e81 --- /dev/null +++ b/.github/workflows/ruby.yml @@ -0,0 +1,42 @@ +# Runs the RSpec suite against the supported Ruby x Rails matrix. +# See https://github.com/marketplace/actions/setup-ruby-jruby-and-truffleruby + +name: Ruby + +on: + push: + branches: ['master'] + pull_request: + branches: ['master'] + schedule: + - cron: '0 0 * * 0' + workflow_dispatch: + +permissions: + contents: read + +jobs: + test: + runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + ruby-version: ['3.1', '3.2', '3.3', '3.4'] + rails: ['7.2', '8.0', '8.1'] + exclude: + # Rails 8 requires Ruby >= 3.2. + - ruby-version: '3.1' + rails: '8.0' + - ruby-version: '3.1' + rails: '8.1' + env: + BUNDLE_GEMFILE: ${{ github.workspace }}/gemfiles/rails_${{ matrix.rails }}.gemfile + steps: + - uses: actions/checkout@v4 + - name: Set up Ruby + uses: ruby/setup-ruby@v1 + with: + ruby-version: ${{ matrix.ruby-version }} + bundler-cache: true # runs 'bundle install' and caches installed gems automatically + - name: Run tests + run: bundle exec rake diff --git a/.gitignore b/.gitignore index 86d37ac..013d41f 100644 --- a/.gitignore +++ b/.gitignore @@ -9,6 +9,9 @@ /vendor/bundle /Gemfile.lock +# Ignore lockfiles generated by Appraisal for the test matrix. +gemfiles/*.gemfile.lock + # Ignore generated code coverage information /spec/coverage/* /coverage/* diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index be9ea53..0000000 --- a/.travis.yml +++ /dev/null @@ -1,17 +0,0 @@ -sudo: false -language: ruby -rvm: - - 2.5.3 - - 3.0.4 - - ruby-head -matrix: - allow_failures: - - rvm: ruby-head -bundler_args: "--jobs=3 --retry=3" -cache: bundler - -after_script: - - bundle exec codeclimate-test-reporter - -before_install: - - gem update bundler diff --git a/Appraisals b/Appraisals new file mode 100644 index 0000000..8b2c9fc --- /dev/null +++ b/Appraisals @@ -0,0 +1,17 @@ +# Test matrix of Rails versions. Regenerate the gemfiles/ directory after editing this file: +# +# bundle exec appraisal generate +# +# The gem only depends on activesupport (runtime) and railties (for the Engine), both of which are +# pulled in transitively by the `rails` meta-gem at a consistent version. +appraise 'rails-7.2' do + gem 'rails', '~> 7.2' +end + +appraise 'rails-8.0' do + gem 'rails', '~> 8.0' +end + +appraise 'rails-8.1' do + gem 'rails', '~> 8.1' +end diff --git a/coursemology-polyglot.gemspec b/coursemology-polyglot.gemspec index cd5609d..1d0eec9 100644 --- a/coursemology-polyglot.gemspec +++ b/coursemology-polyglot.gemspec @@ -25,9 +25,13 @@ programming languages supported in Coursemology. spec.add_development_dependency 'rake' spec.add_development_dependency 'rspec' spec.add_development_dependency 'simplecov' - spec.add_development_dependency 'coveralls' + spec.add_development_dependency 'coveralls_reborn' spec.add_development_dependency 'codeclimate-test-reporter' + # Runs the test suite against multiple Rails versions. See the Appraisals file and + # gemfiles/ directory. + spec.add_development_dependency 'appraisal', '~> 2.5' + spec.add_dependency 'activesupport', '>= 4.2' # For autoloading in Rails applications, as well as the Ace modes inclusion. Keep this as the diff --git a/gemfiles/rails_7.2.gemfile b/gemfiles/rails_7.2.gemfile new file mode 100644 index 0000000..978120d --- /dev/null +++ b/gemfiles/rails_7.2.gemfile @@ -0,0 +1,7 @@ +# This file was generated by Appraisal + +source "https://rubygems.org" + +gem "rails", "~> 7.2" + +gemspec path: "../" diff --git a/gemfiles/rails_8.0.gemfile b/gemfiles/rails_8.0.gemfile new file mode 100644 index 0000000..0b55d5a --- /dev/null +++ b/gemfiles/rails_8.0.gemfile @@ -0,0 +1,7 @@ +# This file was generated by Appraisal + +source "https://rubygems.org" + +gem "rails", "~> 8.0" + +gemspec path: "../" diff --git a/gemfiles/rails_8.1.gemfile b/gemfiles/rails_8.1.gemfile new file mode 100644 index 0000000..c88a868 --- /dev/null +++ b/gemfiles/rails_8.1.gemfile @@ -0,0 +1,7 @@ +# This file was generated by Appraisal + +source "https://rubygems.org" + +gem "rails", "~> 8.1" + +gemspec path: "../" diff --git a/spec/coursemology/polyglot/concrete_language_spec.rb b/spec/coursemology/polyglot/concrete_language_spec.rb index c75138f..66b1e45 100644 --- a/spec/coursemology/polyglot/concrete_language_spec.rb +++ b/spec/coursemology/polyglot/concrete_language_spec.rb @@ -6,38 +6,21 @@ class self::DummyLanguage < Coursemology::Polyglot::Language concrete_language 'Dummy Concrete Language' end - class self::DummyOverriddenNameLanguage < self::DummyLanguage - concrete_language 'Dummy Overridden Concrete Language' - - def self.name - 'Coursemology::Polyglot::Language::Dummy::OverriddenNameLanguage'.freeze - end + class self::DummyLanguageWithDockerImage < self::DummyLanguage + concrete_language 'Dummy Docker Image Language', docker_image: 'dummy-docker' end describe '.docker_image' do - it 'removes the Coursemology::Polyglot::Language prefix' do - expect(self.class::DummyOverriddenNameLanguage.docker_image).to \ - start_with('dummy') - end - - it 'preserves the nesting of namespaces' do - expect(self.class::DummyOverriddenNameLanguage.docker_image).to \ - eq('dummy-overridden_name_language') - end - - context 'when the name contains Point surrounded by numerals' do - class self::DummyLanguage1Point0 < self::DummyLanguage; end - - it 'converts "Point" to dots' do - expect(self.class::DummyLanguage1Point0.docker_image).to end_with('dummy_language1.0') + context 'when no explicit Docker image is specified' do + it 'returns nil' do + # An unset Docker image marks a language as not runnable (e.g. a deprecated language). + expect(self.class::DummyLanguage.docker_image).to be_nil end end - context 'when the name contains Point but not surrounded by numerals' do - class self::DummyLanguagePoint < self::DummyLanguage; end - - it 'preserves "Point"' do - expect(self.class::DummyLanguagePoint.docker_image).to end_with('dummy_language_point') + context 'when an explicit Docker image is specified' do + it 'returns the explicit image name' do + expect(self.class::DummyLanguageWithDockerImage.docker_image).to eq('dummy-docker') end end end diff --git a/spec/coursemology/polyglot/language/python_spec.rb b/spec/coursemology/polyglot/language/python_spec.rb index 1e1c61d..c1b696c 100644 --- a/spec/coursemology/polyglot/language/python_spec.rb +++ b/spec/coursemology/polyglot/language/python_spec.rb @@ -149,7 +149,7 @@ expect(subject.class.dependencies[1][:name]).to eq('fnss') expect(subject.class.dependencies[1][:version]).to eq('0.9.1') - expect(subject.class.dependencies[2][:name]).to eq('formulas') + expect(subject.class.dependencies[2][:name]).to eq('formulas[excel]') expect(subject.class.dependencies[2][:version]).to eq('1.3.4') end end diff --git a/spec/coursemology/polyglot/language_spec.rb b/spec/coursemology/polyglot/language_spec.rb index e7f4240..647f002 100644 --- a/spec/coursemology/polyglot/language_spec.rb +++ b/spec/coursemology/polyglot/language_spec.rb @@ -38,9 +38,8 @@ class self::DummyLanguageWithDockerImage < self::DummyLanguage end context 'when no explicit Docker image is specified' do - it 'generates an image name' do - expect(self.class::DummyLanguage.docker_image).to \ - eq('r_spec-example_groups-coursemology_polyglot_language-dummy_language') + it 'returns nil' do + expect(self.class::DummyLanguage.docker_image).to be_nil end end end