Skip to content
GitLab
Next
Projects Groups Snippets
  • /
  • Help
    • Help
    • Support
    • Community forum
    • Submit feedback
    • Contribute to GitLab
  • Sign in / Register
  • GitLab GitLab
  • Project information
    • Project information
    • Activity
    • Labels
    • Members
  • Repository
    • Repository
    • Files
    • Commits
    • Branches
    • Tags
    • Contributors
    • Graph
    • Compare
    • Locked Files
  • Issues 44,761
    • Issues 44,761
    • List
    • Boards
    • Service Desk
    • Milestones
    • Iterations
    • Requirements
  • Merge requests 1,330
    • Merge requests 1,330
  • CI/CD
    • CI/CD
    • Pipelines
    • Jobs
    • Schedules
    • Test Cases
  • Deployments
    • Deployments
    • Environments
    • Releases
  • Packages and registries
    • Packages and registries
    • Package Registry
    • Container Registry
    • Infrastructure Registry
  • Monitor
    • Monitor
    • Metrics
    • Incidents
  • Analytics
    • Analytics
    • Value stream
    • CI/CD
    • Code review
    • Insights
    • Issue
    • Repository
  • Snippets
    • Snippets
  • Activity
  • Graph
  • Create a new issue
  • Jobs
  • Commits
  • Issue Boards
Collapse sidebar
  • GitLab.orgGitLab.org
  • GitLabGitLab
  • Issues
  • #337614
Closed
Open
Issue created Aug 04, 2021 by Matthias Käppler@mkaeppler2️⃣Maintainer

Ruby 3: RSpec table syntax broken for Integer tables

Problem

While working towards a working CI build with Ruby 3, I ran into an issue where RSpec tests that use rspec-parameterized table syntax were breaking whenever they consisted of Integer operands, e.g.:

    where(:index, :percentage, :is_enabled) do
      50  | 40 | false
      40  | 50 | true
      nil | 50 | false
    end

This is currently failing because the |-operator refinement added by this gem is not going into effect, thus leading to Ruby interpreting the pipe verbatim i.e. as the bit-wise OR. This then leads to the block returning integer values instead of Table instances.

Example test failure: https://gitlab.com/gitlab-org/gitlab/-/jobs/1470020798

Analysis

I have already spent 1day+ on trying to get to the bottom of this. I have a strong suspicion that the Ruby method cache is polluted somehow, since adding this snippet to the top of the spec file will turn the test green:

module M
  refine Integer do
    def |
      # nop
    end
  end
end

I suspect what's happening is that this (unused) refinement triggers a rebuild of the method cache, thus leading to the RSpec refinement being correctly picked up. But I am not sure.

I am fairly certain it is not other Integer refinements shadowing this one since none that I found also redefine |:

git@24d3a948733e:~/gitlab$ grep -r 'refine Integer' /data/cache/bundle-2.7.2/ruby/3.0.0/gems/**/*
/data/cache/bundle-2.7.2/ruby/3.0.0/gems/rexml-3.2.5/lib/rexml/xpath_parser.rb:    refine Integer do
/data/cache/bundle-2.7.2/ruby/3.0.0/gems/rspec-parameterized-0.4.2/lib/rspec/parameterized/table_syntax.rb:        refine Integer do
/data/cache/bundle-2.7.2/ruby/3.0.0/gems/rspec-parameterized-0.5.0/lib/rspec/parameterized/table_syntax.rb:        refine Integer do

I was also able to fix this issue by running the test with a reduced dependency footprint e.g. by not using spec_helper and/or spring, since those will pull in the entire application dependency stack. When comparing Integer.ancestors between the minimal dependency stack where the test passes and the full stack, I get this diff in code added to the Integer class:

[Net::BER::Extensions::Integer,
 RQRCode::CoreExtensions::Integer::Bitwise,
 MessagePack::CoreExt,
 ActiveSupport::ForkTracker::CoreExtPrivate,
 ActiveSupport::ForkTracker::CoreExt,
 Pry::Shell::Patches::Object,
 GettextI18nRails::HtmlSafeTranslations,
 FastGettext::Translation,
 ERB::Util,
 ActiveSupport::ForkTracker::CoreExtPrivate,
 ActiveSupport::ForkTracker::CoreExt]

So another possibility is that one of these extensions collides with the table-syntax refinement. Or maybe it is merely the structure of the ancestor chain that triggers it, which I think is more likely than it being any of these particular extensions. (I already looked at most of them, and I have found no evidence as to why they would shadow |.)

Related links

  • Ruby 3 build MR: !50640 (closed)
  • https://bugs.ruby-lang.org/issues/17806
Edited Aug 05, 2021 by Matthias Käppler
Assignee
Assign to
Time tracking