diff --git a/.github/workflows/ext.yml b/.github/workflows/ext.yml new file mode 100644 index 00000000..f3b6c3f1 --- /dev/null +++ b/.github/workflows/ext.yml @@ -0,0 +1,51 @@ +name: Ext Tests + +on: + schedule: [ cron: '0 0 * * *' ] + pull_request: + +jobs: + appraise: + runs-on: ubuntu-latest + strategy: + max-parallel: 1 + matrix: + ruby: + - '3.2' + - '3.3' + - '3.4' + + steps: + - uses: actions/checkout@v3 + + - name: Set up Ruby + uses: ruby/setup-ruby@v1 + with: + ruby-version: ${{ matrix.ruby }} + bundler-cache: true + + - name: Cache Appraisal gems + id: cache-appraisal-gems + uses: actions/cache@v4 + with: + path: vendor/bundle + key: ${{ runner.os }}-appraisals-${{ matrix.ruby }}-${{ hashFiles('gemfiles/*.gemfile.lock') }} + restore-keys: | + ${{ runner.os }}-appraisals-${{ matrix.ruby }}- + + - name: Resolve appraisals dependencies + run: | + bundle config path vendor/bundle + bundle exec appraisal install + + - name: Run all versioned appraisals + if: ${{ github.event_name != 'schedule' }} + run: bundle exec rake appraise + env: + TEST_PG_URL: ${{ secrets.TEST_PG_URL }} + + - name: Run rails_main appraisal + if: ${{ github.event_name == 'schedule' }} + run: bundle exec appraisal rails_main rspec spec/ext/* + env: + TEST_PG_URL: ${{ secrets.TEST_PG_URL }} diff --git a/.gitignore b/.gitignore index 2bde5c3d..d2979490 100644 --- a/.gitignore +++ b/.gitignore @@ -13,3 +13,4 @@ Gemfile.lock # rspec failure tracking .rspec_status + diff --git a/.rspec b/.rspec index 34c5164d..68deb10f 100644 --- a/.rspec +++ b/.rspec @@ -1,3 +1,4 @@ --format documentation --color --require spec_helper +--exclude-pattern 'spec/ext/**/**_spec.rb' diff --git a/Appraisals b/Appraisals new file mode 100644 index 00000000..03473de2 --- /dev/null +++ b/Appraisals @@ -0,0 +1,19 @@ +appraise "rails_7_0" do + gem "activerecord", "~> 7.0.0" +end + +appraise "rails_7_1" do + gem "activerecord", "~> 7.1.0" +end + +appraise "rails_7_2" do + gem "activerecord", "~> 7.2.0" +end + +appraise "rails_8_0" do + gem "activerecord", "~> 8.0.0" +end + +# appraise "rails_main" do +# gem "activerecord", github: "rails/rails" +# end diff --git a/Gemfile b/Gemfile index b8735d3b..7b7c6560 100644 --- a/Gemfile +++ b/Gemfile @@ -22,4 +22,5 @@ group :test do gem "websocket-client-simple" gem "prism" gem "redis-client" + gem "appraisal", "~> 2.5" end diff --git a/Rakefile b/Rakefile index b6ae7341..15887255 100644 --- a/Rakefile +++ b/Rakefile @@ -6,3 +6,17 @@ require "rspec/core/rake_task" RSpec::Core::RakeTask.new(:spec) task default: :spec + +task :appraise do |_, args| + # Pulls all the Rails versions from the Appraisal file + rails_versions = `appraisal list`.split("\n") + # Since we want to test against the main branch separately, + # we remove it from the list. + rails_versions.delete("rails_main") + + rails_versions.each do |rails_version| + puts ">> Appraising #{rails_version}" + + system("bundle exec appraisal #{rails_version} rspec spec/ext/*") + end +end diff --git a/gemfiles/rails_7_0.gemfile b/gemfiles/rails_7_0.gemfile new file mode 100644 index 00000000..67d72cb8 --- /dev/null +++ b/gemfiles/rails_7_0.gemfile @@ -0,0 +1,25 @@ +# This file was generated by Appraisal + +source "https://rubygems.org" + +gem "rake", "~> 13.0" +gem "rspec", "~> 3.0" +gem "yard" +gem "rubocop", "~> 1.65.0", require: false +gem "activerecord", "~> 7.0.0" + +group :test do + gem "http" + gem "pg" + gem "mysql2" + gem "bigdecimal" + gem "connection_pool", "~> 2.0" + gem "rbnacl" + gem "domain_name" + gem "websocket-client-simple" + gem "prism" + gem "redis-client" + gem "appraisal", "~> 2.5" +end + +gemspec path: "../" diff --git a/gemfiles/rails_7_0.gemfile.lock b/gemfiles/rails_7_0.gemfile.lock new file mode 100644 index 00000000..55a158fa --- /dev/null +++ b/gemfiles/rails_7_0.gemfile.lock @@ -0,0 +1,165 @@ +PATH + remote: .. + specs: + rage-rb (1.15.0) + rack (~> 2.0) + rack-test (~> 2.1) + rage-iodine (~> 4.1) + rake (>= 12.0) + thor (~> 1.0) + zeitwerk (~> 2.6) + +GEM + remote: https://rubygems.org/ + specs: + activemodel (7.0.8.7) + activesupport (= 7.0.8.7) + activerecord (7.0.8.7) + activemodel (= 7.0.8.7) + activesupport (= 7.0.8.7) + activesupport (7.0.8.7) + concurrent-ruby (~> 1.0, >= 1.0.2) + i18n (>= 1.6, < 2) + minitest (>= 5.1) + tzinfo (~> 2.0) + addressable (2.8.7) + public_suffix (>= 2.0.2, < 7.0) + appraisal (2.5.0) + bundler + rake + thor (>= 0.14.0) + ast (2.4.3) + base64 (0.3.0) + bigdecimal (3.2.2) + concurrent-ruby (1.3.5) + connection_pool (2.5.3) + diff-lcs (1.6.2) + domain_name (0.6.20240107) + event_emitter (0.2.6) + ffi (1.17.2) + ffi (1.17.2-aarch64-linux-gnu) + ffi (1.17.2-aarch64-linux-musl) + ffi (1.17.2-arm-linux-gnu) + ffi (1.17.2-arm-linux-musl) + ffi (1.17.2-arm64-darwin) + ffi (1.17.2-x86-linux-gnu) + ffi (1.17.2-x86-linux-musl) + ffi (1.17.2-x86_64-darwin) + ffi (1.17.2-x86_64-linux-gnu) + ffi (1.17.2-x86_64-linux-musl) + ffi-compiler (1.3.2) + ffi (>= 1.15.5) + rake + http (5.3.1) + addressable (~> 2.8) + http-cookie (~> 1.0) + http-form_data (~> 2.2) + llhttp-ffi (~> 0.5.0) + http-cookie (1.0.8) + domain_name (~> 0.5) + http-form_data (2.3.0) + i18n (1.14.7) + concurrent-ruby (~> 1.0) + json (2.12.2) + language_server-protocol (3.17.0.5) + llhttp-ffi (0.5.1) + ffi-compiler (~> 1.0) + rake (~> 13.0) + minitest (5.25.5) + mutex_m (0.3.0) + mysql2 (0.5.6) + parallel (1.27.0) + parser (3.3.8.0) + ast (~> 2.4.1) + racc + pg (1.5.9) + prism (1.4.0) + public_suffix (6.0.2) + racc (1.8.1) + rack (2.2.17) + rack-test (2.2.0) + rack (>= 1.3) + rage-iodine (4.1.0) + rainbow (3.1.1) + rake (13.3.0) + rbnacl (7.1.2) + ffi (~> 1) + redis-client (0.25.0) + connection_pool + regexp_parser (2.10.0) + rexml (3.4.1) + rspec (3.13.1) + rspec-core (~> 3.13.0) + rspec-expectations (~> 3.13.0) + rspec-mocks (~> 3.13.0) + rspec-core (3.13.5) + rspec-support (~> 3.13.0) + rspec-expectations (3.13.5) + diff-lcs (>= 1.2.0, < 2.0) + rspec-support (~> 3.13.0) + rspec-mocks (3.13.5) + diff-lcs (>= 1.2.0, < 2.0) + rspec-support (~> 3.13.0) + rspec-support (3.13.4) + rubocop (1.65.1) + json (~> 2.3) + language_server-protocol (>= 3.17.0) + parallel (~> 1.10) + parser (>= 3.3.0.2) + rainbow (>= 2.2.2, < 4.0) + regexp_parser (>= 2.4, < 3.0) + rexml (>= 3.2.5, < 4.0) + rubocop-ast (>= 1.31.1, < 2.0) + ruby-progressbar (~> 1.7) + unicode-display_width (>= 2.4.0, < 3.0) + rubocop-ast (1.45.1) + parser (>= 3.3.7.2) + prism (~> 1.4) + ruby-progressbar (1.13.0) + thor (1.3.2) + tzinfo (2.0.6) + concurrent-ruby (~> 1.0) + unicode-display_width (2.6.0) + websocket (1.2.11) + websocket-client-simple (0.9.0) + base64 + event_emitter + mutex_m + websocket + yard (0.9.37) + zeitwerk (2.7.3) + +PLATFORMS + aarch64-linux-gnu + aarch64-linux-musl + arm-linux-gnu + arm-linux-musl + arm64-darwin + ruby + x86-linux-gnu + x86-linux-musl + x86_64-darwin + x86_64-linux-gnu + x86_64-linux-musl + +DEPENDENCIES + activerecord (~> 7.0.0) + appraisal (~> 2.5) + bigdecimal + connection_pool (~> 2.0) + domain_name + http + mysql2 + pg + prism + rage-rb! + rake (~> 13.0) + rbnacl + redis-client + rspec (~> 3.0) + rubocop (~> 1.65.0) + websocket-client-simple + yard + +BUNDLED WITH + 2.6.5 diff --git a/gemfiles/rails_7_1.gemfile b/gemfiles/rails_7_1.gemfile new file mode 100644 index 00000000..8b1f6190 --- /dev/null +++ b/gemfiles/rails_7_1.gemfile @@ -0,0 +1,25 @@ +# This file was generated by Appraisal + +source "https://rubygems.org" + +gem "rake", "~> 13.0" +gem "rspec", "~> 3.0" +gem "yard" +gem "rubocop", "~> 1.65.0", require: false +gem "activerecord", "~> 7.1.0" + +group :test do + gem "http" + gem "pg" + gem "mysql2" + gem "bigdecimal" + gem "connection_pool", "~> 2.0" + gem "rbnacl" + gem "domain_name" + gem "websocket-client-simple" + gem "prism" + gem "redis-client" + gem "appraisal", "~> 2.5" +end + +gemspec path: "../" diff --git a/gemfiles/rails_7_1.gemfile.lock b/gemfiles/rails_7_1.gemfile.lock new file mode 100644 index 00000000..13138baa --- /dev/null +++ b/gemfiles/rails_7_1.gemfile.lock @@ -0,0 +1,179 @@ +PATH + remote: .. + specs: + rage-rb (1.15.0) + rack (~> 2.0) + rack-test (~> 2.1) + rage-iodine (~> 4.1) + rake (>= 12.0) + thor (~> 1.0) + zeitwerk (~> 2.6) + +GEM + remote: https://rubygems.org/ + specs: + activemodel (7.1.5.1) + activesupport (= 7.1.5.1) + activerecord (7.1.5.1) + activemodel (= 7.1.5.1) + activesupport (= 7.1.5.1) + timeout (>= 0.4.0) + activesupport (7.1.5.1) + base64 + benchmark (>= 0.3) + bigdecimal + concurrent-ruby (~> 1.0, >= 1.0.2) + connection_pool (>= 2.2.5) + drb + i18n (>= 1.6, < 2) + logger (>= 1.4.2) + minitest (>= 5.1) + mutex_m + securerandom (>= 0.3) + tzinfo (~> 2.0) + addressable (2.8.7) + public_suffix (>= 2.0.2, < 7.0) + appraisal (2.5.0) + bundler + rake + thor (>= 0.14.0) + ast (2.4.3) + base64 (0.3.0) + benchmark (0.4.1) + bigdecimal (3.2.2) + concurrent-ruby (1.3.5) + connection_pool (2.5.3) + diff-lcs (1.6.2) + domain_name (0.6.20240107) + drb (2.2.3) + event_emitter (0.2.6) + ffi (1.17.2) + ffi (1.17.2-aarch64-linux-gnu) + ffi (1.17.2-aarch64-linux-musl) + ffi (1.17.2-arm-linux-gnu) + ffi (1.17.2-arm-linux-musl) + ffi (1.17.2-arm64-darwin) + ffi (1.17.2-x86-linux-gnu) + ffi (1.17.2-x86-linux-musl) + ffi (1.17.2-x86_64-darwin) + ffi (1.17.2-x86_64-linux-gnu) + ffi (1.17.2-x86_64-linux-musl) + ffi-compiler (1.3.2) + ffi (>= 1.15.5) + rake + http (5.3.1) + addressable (~> 2.8) + http-cookie (~> 1.0) + http-form_data (~> 2.2) + llhttp-ffi (~> 0.5.0) + http-cookie (1.0.8) + domain_name (~> 0.5) + http-form_data (2.3.0) + i18n (1.14.7) + concurrent-ruby (~> 1.0) + json (2.12.2) + language_server-protocol (3.17.0.5) + llhttp-ffi (0.5.1) + ffi-compiler (~> 1.0) + rake (~> 13.0) + logger (1.7.0) + minitest (5.25.5) + mutex_m (0.3.0) + mysql2 (0.5.6) + parallel (1.27.0) + parser (3.3.8.0) + ast (~> 2.4.1) + racc + pg (1.5.9) + prism (1.4.0) + public_suffix (6.0.2) + racc (1.8.1) + rack (2.2.17) + rack-test (2.2.0) + rack (>= 1.3) + rage-iodine (4.1.0) + rainbow (3.1.1) + rake (13.3.0) + rbnacl (7.1.2) + ffi (~> 1) + redis-client (0.25.0) + connection_pool + regexp_parser (2.10.0) + rexml (3.4.1) + rspec (3.13.1) + rspec-core (~> 3.13.0) + rspec-expectations (~> 3.13.0) + rspec-mocks (~> 3.13.0) + rspec-core (3.13.5) + rspec-support (~> 3.13.0) + rspec-expectations (3.13.5) + diff-lcs (>= 1.2.0, < 2.0) + rspec-support (~> 3.13.0) + rspec-mocks (3.13.5) + diff-lcs (>= 1.2.0, < 2.0) + rspec-support (~> 3.13.0) + rspec-support (3.13.4) + rubocop (1.65.1) + json (~> 2.3) + language_server-protocol (>= 3.17.0) + parallel (~> 1.10) + parser (>= 3.3.0.2) + rainbow (>= 2.2.2, < 4.0) + regexp_parser (>= 2.4, < 3.0) + rexml (>= 3.2.5, < 4.0) + rubocop-ast (>= 1.31.1, < 2.0) + ruby-progressbar (~> 1.7) + unicode-display_width (>= 2.4.0, < 3.0) + rubocop-ast (1.45.1) + parser (>= 3.3.7.2) + prism (~> 1.4) + ruby-progressbar (1.13.0) + securerandom (0.4.1) + thor (1.3.2) + timeout (0.4.3) + tzinfo (2.0.6) + concurrent-ruby (~> 1.0) + unicode-display_width (2.6.0) + websocket (1.2.11) + websocket-client-simple (0.9.0) + base64 + event_emitter + mutex_m + websocket + yard (0.9.37) + zeitwerk (2.7.3) + +PLATFORMS + aarch64-linux-gnu + aarch64-linux-musl + arm-linux-gnu + arm-linux-musl + arm64-darwin + ruby + x86-linux-gnu + x86-linux-musl + x86_64-darwin + x86_64-linux-gnu + x86_64-linux-musl + +DEPENDENCIES + activerecord (~> 7.1.0) + appraisal (~> 2.5) + bigdecimal + connection_pool (~> 2.0) + domain_name + http + mysql2 + pg + prism + rage-rb! + rake (~> 13.0) + rbnacl + redis-client + rspec (~> 3.0) + rubocop (~> 1.65.0) + websocket-client-simple + yard + +BUNDLED WITH + 2.6.5 diff --git a/gemfiles/rails_7_2.gemfile b/gemfiles/rails_7_2.gemfile new file mode 100644 index 00000000..05e410a3 --- /dev/null +++ b/gemfiles/rails_7_2.gemfile @@ -0,0 +1,25 @@ +# This file was generated by Appraisal + +source "https://rubygems.org" + +gem "rake", "~> 13.0" +gem "rspec", "~> 3.0" +gem "yard" +gem "rubocop", "~> 1.65.0", require: false +gem "activerecord", "~> 7.2.0" + +group :test do + gem "http" + gem "pg" + gem "mysql2" + gem "bigdecimal" + gem "connection_pool", "~> 2.0" + gem "rbnacl" + gem "domain_name" + gem "websocket-client-simple" + gem "prism" + gem "redis-client" + gem "appraisal", "~> 2.5" +end + +gemspec path: "../" diff --git a/gemfiles/rails_7_2.gemfile.lock b/gemfiles/rails_7_2.gemfile.lock new file mode 100644 index 00000000..30cdfa54 --- /dev/null +++ b/gemfiles/rails_7_2.gemfile.lock @@ -0,0 +1,178 @@ +PATH + remote: .. + specs: + rage-rb (1.15.0) + rack (~> 2.0) + rack-test (~> 2.1) + rage-iodine (~> 4.1) + rake (>= 12.0) + thor (~> 1.0) + zeitwerk (~> 2.6) + +GEM + remote: https://rubygems.org/ + specs: + activemodel (7.2.2.1) + activesupport (= 7.2.2.1) + activerecord (7.2.2.1) + activemodel (= 7.2.2.1) + activesupport (= 7.2.2.1) + timeout (>= 0.4.0) + activesupport (7.2.2.1) + base64 + benchmark (>= 0.3) + bigdecimal + concurrent-ruby (~> 1.0, >= 1.3.1) + connection_pool (>= 2.2.5) + drb + i18n (>= 1.6, < 2) + logger (>= 1.4.2) + minitest (>= 5.1) + securerandom (>= 0.3) + tzinfo (~> 2.0, >= 2.0.5) + addressable (2.8.7) + public_suffix (>= 2.0.2, < 7.0) + appraisal (2.5.0) + bundler + rake + thor (>= 0.14.0) + ast (2.4.3) + base64 (0.3.0) + benchmark (0.4.1) + bigdecimal (3.2.2) + concurrent-ruby (1.3.5) + connection_pool (2.5.3) + diff-lcs (1.6.2) + domain_name (0.6.20240107) + drb (2.2.3) + event_emitter (0.2.6) + ffi (1.17.2) + ffi (1.17.2-aarch64-linux-gnu) + ffi (1.17.2-aarch64-linux-musl) + ffi (1.17.2-arm-linux-gnu) + ffi (1.17.2-arm-linux-musl) + ffi (1.17.2-arm64-darwin) + ffi (1.17.2-x86-linux-gnu) + ffi (1.17.2-x86-linux-musl) + ffi (1.17.2-x86_64-darwin) + ffi (1.17.2-x86_64-linux-gnu) + ffi (1.17.2-x86_64-linux-musl) + ffi-compiler (1.3.2) + ffi (>= 1.15.5) + rake + http (5.3.1) + addressable (~> 2.8) + http-cookie (~> 1.0) + http-form_data (~> 2.2) + llhttp-ffi (~> 0.5.0) + http-cookie (1.0.8) + domain_name (~> 0.5) + http-form_data (2.3.0) + i18n (1.14.7) + concurrent-ruby (~> 1.0) + json (2.12.2) + language_server-protocol (3.17.0.5) + llhttp-ffi (0.5.1) + ffi-compiler (~> 1.0) + rake (~> 13.0) + logger (1.7.0) + minitest (5.25.5) + mutex_m (0.3.0) + mysql2 (0.5.6) + parallel (1.27.0) + parser (3.3.8.0) + ast (~> 2.4.1) + racc + pg (1.5.9) + prism (1.4.0) + public_suffix (6.0.2) + racc (1.8.1) + rack (2.2.17) + rack-test (2.2.0) + rack (>= 1.3) + rage-iodine (4.1.0) + rainbow (3.1.1) + rake (13.3.0) + rbnacl (7.1.2) + ffi (~> 1) + redis-client (0.25.0) + connection_pool + regexp_parser (2.10.0) + rexml (3.4.1) + rspec (3.13.1) + rspec-core (~> 3.13.0) + rspec-expectations (~> 3.13.0) + rspec-mocks (~> 3.13.0) + rspec-core (3.13.5) + rspec-support (~> 3.13.0) + rspec-expectations (3.13.5) + diff-lcs (>= 1.2.0, < 2.0) + rspec-support (~> 3.13.0) + rspec-mocks (3.13.5) + diff-lcs (>= 1.2.0, < 2.0) + rspec-support (~> 3.13.0) + rspec-support (3.13.4) + rubocop (1.65.1) + json (~> 2.3) + language_server-protocol (>= 3.17.0) + parallel (~> 1.10) + parser (>= 3.3.0.2) + rainbow (>= 2.2.2, < 4.0) + regexp_parser (>= 2.4, < 3.0) + rexml (>= 3.2.5, < 4.0) + rubocop-ast (>= 1.31.1, < 2.0) + ruby-progressbar (~> 1.7) + unicode-display_width (>= 2.4.0, < 3.0) + rubocop-ast (1.45.1) + parser (>= 3.3.7.2) + prism (~> 1.4) + ruby-progressbar (1.13.0) + securerandom (0.4.1) + thor (1.3.2) + timeout (0.4.3) + tzinfo (2.0.6) + concurrent-ruby (~> 1.0) + unicode-display_width (2.6.0) + websocket (1.2.11) + websocket-client-simple (0.9.0) + base64 + event_emitter + mutex_m + websocket + yard (0.9.37) + zeitwerk (2.7.3) + +PLATFORMS + aarch64-linux-gnu + aarch64-linux-musl + arm-linux-gnu + arm-linux-musl + arm64-darwin + ruby + x86-linux-gnu + x86-linux-musl + x86_64-darwin + x86_64-linux-gnu + x86_64-linux-musl + +DEPENDENCIES + activerecord (~> 7.2.0) + appraisal (~> 2.5) + bigdecimal + connection_pool (~> 2.0) + domain_name + http + mysql2 + pg + prism + rage-rb! + rake (~> 13.0) + rbnacl + redis-client + rspec (~> 3.0) + rubocop (~> 1.65.0) + websocket-client-simple + yard + +BUNDLED WITH + 2.6.5 diff --git a/gemfiles/rails_8_0.gemfile b/gemfiles/rails_8_0.gemfile new file mode 100644 index 00000000..6d389719 --- /dev/null +++ b/gemfiles/rails_8_0.gemfile @@ -0,0 +1,25 @@ +# This file was generated by Appraisal + +source "https://rubygems.org" + +gem "rake", "~> 13.0" +gem "rspec", "~> 3.0" +gem "yard" +gem "rubocop", "~> 1.65.0", require: false +gem "activerecord", "~> 8.0.0" + +group :test do + gem "http" + gem "pg" + gem "mysql2" + gem "bigdecimal" + gem "connection_pool", "~> 2.0" + gem "rbnacl" + gem "domain_name" + gem "websocket-client-simple" + gem "prism" + gem "redis-client" + gem "appraisal", "~> 2.5" +end + +gemspec path: "../" diff --git a/gemfiles/rails_8_0.gemfile.lock b/gemfiles/rails_8_0.gemfile.lock new file mode 100644 index 00000000..1b6b6498 --- /dev/null +++ b/gemfiles/rails_8_0.gemfile.lock @@ -0,0 +1,180 @@ +PATH + remote: .. + specs: + rage-rb (1.15.0) + rack (~> 2.0) + rack-test (~> 2.1) + rage-iodine (~> 4.1) + rake (>= 12.0) + thor (~> 1.0) + zeitwerk (~> 2.6) + +GEM + remote: https://rubygems.org/ + specs: + activemodel (8.0.2) + activesupport (= 8.0.2) + activerecord (8.0.2) + activemodel (= 8.0.2) + activesupport (= 8.0.2) + timeout (>= 0.4.0) + activesupport (8.0.2) + base64 + benchmark (>= 0.3) + bigdecimal + concurrent-ruby (~> 1.0, >= 1.3.1) + connection_pool (>= 2.2.5) + drb + i18n (>= 1.6, < 2) + logger (>= 1.4.2) + minitest (>= 5.1) + securerandom (>= 0.3) + tzinfo (~> 2.0, >= 2.0.5) + uri (>= 0.13.1) + addressable (2.8.7) + public_suffix (>= 2.0.2, < 7.0) + appraisal (2.5.0) + bundler + rake + thor (>= 0.14.0) + ast (2.4.3) + base64 (0.3.0) + benchmark (0.4.1) + bigdecimal (3.2.2) + concurrent-ruby (1.3.5) + connection_pool (2.5.3) + diff-lcs (1.6.2) + domain_name (0.6.20240107) + drb (2.2.3) + event_emitter (0.2.6) + ffi (1.17.2) + ffi (1.17.2-aarch64-linux-gnu) + ffi (1.17.2-aarch64-linux-musl) + ffi (1.17.2-arm-linux-gnu) + ffi (1.17.2-arm-linux-musl) + ffi (1.17.2-arm64-darwin) + ffi (1.17.2-x86-linux-gnu) + ffi (1.17.2-x86-linux-musl) + ffi (1.17.2-x86_64-darwin) + ffi (1.17.2-x86_64-linux-gnu) + ffi (1.17.2-x86_64-linux-musl) + ffi-compiler (1.3.2) + ffi (>= 1.15.5) + rake + http (5.3.1) + addressable (~> 2.8) + http-cookie (~> 1.0) + http-form_data (~> 2.2) + llhttp-ffi (~> 0.5.0) + http-cookie (1.0.8) + domain_name (~> 0.5) + http-form_data (2.3.0) + i18n (1.14.7) + concurrent-ruby (~> 1.0) + json (2.12.2) + language_server-protocol (3.17.0.5) + llhttp-ffi (0.5.1) + ffi-compiler (~> 1.0) + rake (~> 13.0) + logger (1.7.0) + minitest (5.25.5) + mutex_m (0.3.0) + mysql2 (0.5.6) + parallel (1.27.0) + parser (3.3.8.0) + ast (~> 2.4.1) + racc + pg (1.5.9) + prism (1.4.0) + public_suffix (6.0.2) + racc (1.8.1) + rack (2.2.17) + rack-test (2.2.0) + rack (>= 1.3) + rage-iodine (4.1.0) + rainbow (3.1.1) + rake (13.3.0) + rbnacl (7.1.2) + ffi (~> 1) + redis-client (0.25.0) + connection_pool + regexp_parser (2.10.0) + rexml (3.4.1) + rspec (3.13.1) + rspec-core (~> 3.13.0) + rspec-expectations (~> 3.13.0) + rspec-mocks (~> 3.13.0) + rspec-core (3.13.5) + rspec-support (~> 3.13.0) + rspec-expectations (3.13.5) + diff-lcs (>= 1.2.0, < 2.0) + rspec-support (~> 3.13.0) + rspec-mocks (3.13.5) + diff-lcs (>= 1.2.0, < 2.0) + rspec-support (~> 3.13.0) + rspec-support (3.13.4) + rubocop (1.65.1) + json (~> 2.3) + language_server-protocol (>= 3.17.0) + parallel (~> 1.10) + parser (>= 3.3.0.2) + rainbow (>= 2.2.2, < 4.0) + regexp_parser (>= 2.4, < 3.0) + rexml (>= 3.2.5, < 4.0) + rubocop-ast (>= 1.31.1, < 2.0) + ruby-progressbar (~> 1.7) + unicode-display_width (>= 2.4.0, < 3.0) + rubocop-ast (1.45.1) + parser (>= 3.3.7.2) + prism (~> 1.4) + ruby-progressbar (1.13.0) + securerandom (0.4.1) + thor (1.3.2) + timeout (0.4.3) + tzinfo (2.0.6) + concurrent-ruby (~> 1.0) + unicode-display_width (2.6.0) + uri (1.0.3) + websocket (1.2.11) + websocket-client-simple (0.9.0) + base64 + event_emitter + mutex_m + websocket + yard (0.9.37) + zeitwerk (2.7.3) + +PLATFORMS + aarch64-linux-gnu + aarch64-linux-musl + arm-linux-gnu + arm-linux-musl + arm64-darwin + ruby + x86-linux-gnu + x86-linux-musl + x86_64-darwin + x86_64-linux-gnu + x86_64-linux-musl + +DEPENDENCIES + activerecord (~> 8.0.0) + appraisal (~> 2.5) + bigdecimal + connection_pool (~> 2.0) + domain_name + http + mysql2 + pg + prism + rage-rb! + rake (~> 13.0) + rbnacl + redis-client + rspec (~> 3.0) + rubocop (~> 1.65.0) + websocket-client-simple + yard + +BUNDLED WITH + 2.6.5 diff --git a/rage.gemspec b/rage.gemspec index b5d39bae..79536e02 100644 --- a/rage.gemspec +++ b/rage.gemspec @@ -20,7 +20,7 @@ Gem::Specification.new do |spec| # The `git ls-files -z` loads the files in the RubyGem that have been added into git. spec.files = Dir.chdir(__dir__) do `git ls-files -z`.split("\x0").reject do |f| - (File.expand_path(f) == __FILE__) || f.start_with?(*%w[bin/ test/ spec/ features/ .git .circleci appveyor .rubocop]) + (File.expand_path(f) == __FILE__) || f.start_with?(*%w[bin/ gemfiles/ test/ spec/ features/ .git .circleci appveyor .rubocop]) end end spec.bindir = "exe" diff --git a/spec/ext/active_record/connection_pool_spec.rb b/spec/ext/active_record/connection_pool_spec.rb new file mode 100644 index 00000000..27495504 --- /dev/null +++ b/spec/ext/active_record/connection_pool_spec.rb @@ -0,0 +1,125 @@ +# frozen_string_literal: true + +require "active_record" + +RSpec.describe Rage::Ext::ActiveRecord::ConnectionPool do + subject { ActiveRecord::Base.connection_pool } + + before :all do + Fiber.set_scheduler(Rage::FiberScheduler.new) + ActiveRecord::Base.establish_connection(url: "#{ENV["TEST_PG_URL"]}") + ActiveRecord::Base.connection_pool.extend(Rage::Ext::ActiveRecord::ConnectionPool) + end + + after :all do + Fiber.set_scheduler(nil) + end + + around do |example| + # we need to init the extension before every test to refresh the subscriptions + subject.__init_rage_extension + + within_reactor do + example.call + -> {} + end + + # cleanup - remove the connections + subject.connections.each do |conn| + conn.disconnect! + subject.__remove__(conn) + end + end + + describe "#with_connection" do + it "checks out a connection" do + subject.with_connection do |conn| + expect(conn.execute("select 1")).to be_a(PG::Result) + end + end + + it "allows nested calls" do + subject.with_connection do |conn| + expect(conn.execute("select 1")).to be_a(PG::Result) + subject.with_connection do |new_conn| + expect(conn.execute("select 2")).to be_a(PG::Result) + end + end + end + + it "correctly checks connections in and out" do + 50.times do + subject.with_connection do |conn| + expect(conn.execute("select 1")).to be_a(PG::Result) + end + end + end + + it "correctly checks connections in and out in different fibers" do + 50.times.map { + Fiber.schedule do + subject.with_connection do |conn| + expect(conn.execute("select 1")).to be_a(PG::Result) + end + end + }.then { |fibers| Fiber.await(fibers) } + end + end + + describe "#release_connection" do + it "correctly releases connections" do + 20.times.map { + Fiber.schedule do + conn = subject.connection + sleep 0.2 + subject.release_connection + end + }.then { |fibers| Fiber.await(fibers) } + end + end + + describe "#active_connection?" do + it "returns false if there is an active connection" do + expect(subject.active_connection?).to be_falsey + end + + it "returns true if there is an active connection" do + subject.connection + expect(subject.active_connection?).to be_truthy + ensure + subject.release_connection + end + + it "works correctly with with_connection" do + subject.with_connection do + expect(subject.active_connection?).to be_truthy + + subject.with_connection do + expect(subject.active_connection?).to be_truthy + end + end + + expect(subject.active_connection?).to be_falsey + end + + it "doesn't share connections between fibers" do + subject.connection + + Fiber.await( + Fiber.schedule { expect(subject.active_connection?).to be_falsey } + ) + ensure + subject.release_connection + end + + it "doesn't share connections between threads" do + subject.connection + + Thread.new { + expect(subject.active_connection?).to be_falsey + }.join + ensure + subject.release_connection + end + end +end