Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

What would be needed for RSpec to fully support TruffleRuby? #68

Open
eregon opened this issue Feb 15, 2022 · 21 comments
Open

What would be needed for RSpec to fully support TruffleRuby? #68

eregon opened this issue Feb 15, 2022 · 21 comments

Comments

@eregon
Copy link

eregon commented Feb 15, 2022

We had some discussions about this years ago but I think it's time to clarify the requirements.

Of course, TruffleRuby would need pass the RSpec test suite, I think it's quite close to that if not already the case.
Maybe @gogainda or @bjfish can check that by running the CI on forks, adding truffleruby to the matrix, and report the results here.

Anything else?

When TruffleRuby already runs Rails and is already in many other gems CI, it does feel weird that such a common gem as RSpec doesn't officially support or test TruffleRuby in CI.
OTOH AFAIK RSpec already works fine on TruffleRuby in practice for running specs, I don't remember any issue running RSpec on TruffleRuby in many years.

If the concern is adding TruffleRuby in CI would slow down development due to e.g. longer CI times for PRs, I think an easy way to address that would be to make the CI job a daily or weekly one.
Still, I think we should measure if it adds any time for a PR workflow and how much, per rspec repo (e.g., maybe rspec-rails takes a while and rspec-support takes very little time).

Another concern I remember is wanting a release of truffleruby in CI, and not truffleruby-head in CI.
That's fine, it might just take a bit longer to wait for the next release.

@JonRowe
Copy link
Member

JonRowe commented Feb 15, 2022

There is not enough bandwidth amongst the team to add another Ruby to the supported set. Unlike Rails we are a small team without the backing of any companies. So the first step would be someone volunteering to maintain TruffleRuby support within RSpec. I would then consider allowing truffle ruby to be added to the general CI matrix for a stable release (no head, I don't want more instability in our builds) when truffle passes stabley. I'll happily setup a long running "truffle-support-dev" branch to facilitate this if the person who steps up to maintain truffle support wishes it.

@bjfish
Copy link

bjfish commented Feb 22, 2022

@JonRowe I'm volunteering to maintain TruffleRuby support within RSpec. I'll follow up again once I've had a chance to review the existing PRs, conversations, and run the specs. cc: @eregon

@gogainda
Copy link

@bjfish if you need any help here pls let me know. Currently I am looking at rspec-core project and already filled one issue which may be related to the failing specs of rspec-core: oracle/truffleruby#2602

@fables-tales
Copy link
Member

(former rspec maintainer chiming in) take this very much as the peanut gallery but I wonder if truffleruby should CI against RSpec, so that you know ahead of time if something is going to break

@pirj
Copy link
Member

pirj commented Feb 22, 2022

Very good point, @penelopezone! We don't have as many changes as TruffleRuby, and breakages to RSpec+TruffleRuby compatibility will supposedly mostly come from TruffleRuby changes, not changes in RSpec.

@eregon
Copy link
Author

eregon commented Feb 23, 2022

Currently TruffleRuby tests a small number of gems in its CI, i.e. in the gate/pre-merge CI (e.g. ffi, because a large part of that code is in the truffleruby repo). It simply doesn't scale to test many gems in TruffleRuby's pre-merge CI.
And if we (= TruffleRuby team) test a gem in TruffleRuby's CI it needs to be a fixed version, as we wouldn't want something broken upstream blocking TruffleRuby changes.

There is existing infrastructure to test a large amount of gems, asynchronously, this is how TruffleRuby plans to test RSpec and many other gems.

Having TruffleRuby in RSpec's CI (even if daily/weekly) is a separate test: it means latest RSpec + fixed TruffleRuby, while the above is testing latest TruffleRuby + fixed RSpec, and so that's useful regardless.
So for example that would catch something new that RSpec uses and doesn't work on TruffleRuby for some reason.
That's very helpful as we can then investigate and fix that.
We also already have a way to track any failure from the RSpec CI, see https://github.com/eregon/truffleruby-gem-tracker/actions, and that's already used for many other gems.

@pirj
Copy link
Member

pirj commented Feb 24, 2022

TruffleRuby in RSpec's CI (even if daily/weekly)

Sounds reasonable. It must be possible to run it on merge to main, while skipping for PRs/branches.

@gogainda
Copy link

I started working on Truffleruby support for Rspec-core here rspec/rspec-core#2942 can some one review the PR?

@bjfish
Copy link

bjfish commented Mar 18, 2022

I ran the test suite locally and saw 33 failures for truffleruby-head. At least 2 appeared to be addressed in rspec/rspec-core#2942.

rspec-core

Failures:

  1) Spec file load errors prints a warning when a helper file exits early
     Failure/Error:
             expect(output).to eq unindent(<<-EOS)
       
               While loading ./helper_with_exit.rb an `exit` / `raise SystemExit` occurred, RSpec will now quit.
               Failure/Error: exit 999
       
               SystemExit:
                 exit
               # ./helper_with_exit.rb:1:in `exit'
               # ./helper_with_exit.rb:1#{spec_line_suffix}
             EOS
     
       expected: "\nWhile loading ./helper_with_exit.rb an `exit` / `raise SystemExit` occurred, RSpec will now quit.\nFailure/Error: exit 999\n\nSystemExit:\n  exit\n# ./helper_with_exit.rb:1:in `exit'\n# ./helper_with_exit.rb:1:in `<top (required)>'\n"
            got: "\nWhile loading ./helper_with_exit.rb an `exit` / `raise SystemExit` occurred, RSpec will now quit.\nFailure/Error: Unable to find <internal:core> core/process.rb to read failed line\n\nSystemExit:\n  SystemExit\n# ./helper_with_exit.rb:1:in `<top (required)>'\n"
     
       (compared using ==)
     
       Diff:
       
       @@ -1,9 +1,8 @@
        
        While loading ./helper_with_exit.rb an `exit` / `raise SystemExit` occurred, RSpec will now quit.
       -Failure/Error: exit 999
       +Failure/Error: Unable to find <internal:core> core/process.rb to read failed line
        
        SystemExit:
       -  exit
       -# ./helper_with_exit.rb:1:in `exit'
       +  SystemExit
        # ./helper_with_exit.rb:1:in `<top (required)>'
       
     # ./spec/integration/spec_file_load_errors_spec.rb:103:in `block (2 levels) in <top (required)>'
     # ./spec/support/sandboxing.rb:16:in `block (3 levels) in <top (required)>'
     # ./spec/support/sandboxing.rb:7:in `block (2 levels) in <top (required)>'
  2) RSpec behaves like library wide checks only loads a known set of stdlibs so gem authors are forced to load libs they use to have passing specs
     Failure/Error: @example_group_instance.instance_exec(self, &@example_block)
     
       expected: []
            got: ["/Users/bfish/Documents/truffleruby-ws/graal/sdk/mxbuild/darwin-amd64/GRAALVM_67F33FC705_JAVA11/graalvm-67f33fc705-java11-22.1.0-dev/Contents/Home/languages/ruby/lib/truffle/truffle/cext_ruby.rb", "/Users/bfish/Documents/truffleruby-ws/graal/sdk/mxbuild/darwin-amd64/GRAALVM_67F33FC705_JAVA11/graalvm-67f33fc705-java11-22.1.0-dev/Contents/Home/languages/ruby/lib/truffle/truffle/cext_constants.rb", "/Users/bfish/Documents/truffleruby-ws/graal/sdk/mxbuild/darwin-amd64/GRAALVM_67F33FC705_JAVA11/graalvm-67f33fc705-java11-22.1.0-dev/Contents/Home/languages/ruby/lib/truffle/truffle/cext_structs.rb", "/Users/bfish/Documents/truffleruby-ws/graal/sdk/mxbuild/darwin-amd64/GRAALVM_67F33FC705_JAVA11/graalvm-67f33fc705-java11-22.1.0-dev/Contents/Home/languages/ruby/lib/truffle/truffle/cext.rb"]
     
       (compared using ==)
     Shared Example Group: "library wide checks" called from ./spec/rspec/core_spec.rb:31
     # ./spec/support/sandboxing.rb:16:in `block (3 levels) in <top (required)>'
     # ./spec/support/sandboxing.rb:7:in `block (2 levels) in <top (required)>'

rspec-expectations

  • RSpec::Expectations::FailureAggregator when used via aggregate_failures message formatting enumerates the failures with an index label, the path of each failure and a blank line in between
  1) RSpec::Expectations::FailureAggregator when used via `aggregate_failures` message formatting enumerates the failures with an index label, the path of each failure and a blank line in between
     Failure/Error:
       expect {
         aggregate_failures do
           expect(1).to be_even
           expect(2).to be_odd
           expect(3).to be_even
         end
       }.to fail_including { dedent <<-EOS }
         |  1) expected `1.even?` to return true, got false
         |     ./spec/rspec/expectations/failure_aggregator_spec.rb:#{__LINE__ - 6}#{exception_complement(5)}
         |
     
       expected "Got 3 failures from failure aggregation block:\n\n  1) expected `1.even?` to return true, got false\...ec/rspec/expectations/failure_aggregator_spec.rb:274:in `block (5 levels) in <module:Expectations>'" to include "  1) expected `1.even?` to return true, got false\n     ./spec/rspec/expectations/failure_aggregator...got false\n     ./spec/rspec/expectations/failure_aggregator_spec.rb:274:in `block in Expectations'"
       Diff:
       @@ -1,10 +1,19 @@
       -  1) expected `1.even?` to return true, got false\n     ./spec/rspec/expectations/failure_aggregator_spec.rb:272:in `block in Expectations'\n\n  2) expected `2.odd?` to return true, got false\n     ./spec/rspec/expectations/failure_aggregator_spec.rb:273:in `block in Expectations'\n\n  3) expected `3.even?` to return true, got false\n     ./spec/rspec/expectations/failure_aggregator_spec.rb:274:in `block in Expectations'
       +Got 3 failures from failure aggregation block:
       +
       +  1) expected `1.even?` to return true, got false
       +     ./spec/rspec/expectations/failure_aggregator_spec.rb:272:in `block (5 levels) in <module:Expectations>'
       +
       +  2) expected `2.odd?` to return true, got false
       +     ./spec/rspec/expectations/failure_aggregator_spec.rb:273:in `block (5 levels) in <module:Expectations>'
       +
       +  3) expected `3.even?` to return true, got false
       +     ./spec/rspec/expectations/failure_aggregator_spec.rb:274:in `block (5 levels) in <module:Expectations>'
       
     # ./spec/rspec/expectations/failure_aggregator_spec.rb:270:in `block (3 levels) in <module:Expectations>'
  • RSpec::Expectations::FailureAggregator when used via aggregate_failures message formatting when the failure messages have multiple lines accounts for the width of the index when indenting
  2) RSpec::Expectations::FailureAggregator when used via `aggregate_failures` message formatting when the failure messages have multiple lines accounts for the width of the index when indenting
     Failure/Error:
       expect {
         aggregate_failures do
           1.upto(10) do |i|
             expect(i).to fail_with_multiple_lines
           end
         end
       }.to fail_including { dedent <<-EOS }
         |  9)  line 1
         |      9
         |      line 3
     
       expected "Got 10 failures from failure aggregation block:\n\n  1)  line 1\n      1\n      line 3\n      ./spec...ec/rspec/expectations/failure_aggregator_spec.rb:366:in `block (7 levels) in <module:Expectations>'" to include "  9)  line 1\n      9\n      line 3\n      ./spec/rspec/expectations/failure_aggregator_spec.rb:366:...  line 3\n      ./spec/rspec/expectations/failure_aggregator_spec.rb:366:in `block in Expectations'"
       Diff:
       @@ -1,51 +1,101 @@
       -  9)  line 1\n      9\n      line 3\n      ./spec/rspec/expectations/failure_aggregator_spec.rb:366:in `block in Expectations'\n\n  10) line 1\n      10\n      line 3\n      ./spec/rspec/expectations/failure_aggregator_spec.rb:366:in `block in Expectations'
       +Got 10 failures from failure aggregation block:
       +
       +  1)  line 1
       +      1
       +      line 3
       +      ./spec/rspec/expectations/failure_aggregator_spec.rb:366:in `block (7 levels) in <module:Expectations>'
       +
       +  2)  line 1
       +      2
       +      line 3
       +      ./spec/rspec/expectations/failure_aggregator_spec.rb:366:in `block (7 levels) in <module:Expectations>'
       +
       +  3)  line 1
       +      3
       +      line 3
       +      ./spec/rspec/expectations/failure_aggregator_spec.rb:366:in `block (7 levels) in <module:Expectations>'
       +
       +  4)  line 1
       +      4
       +      line 3
       +      ./spec/rspec/expectations/failure_aggregator_spec.rb:366:in `block (7 levels) in <module:Expectations>'
       +
       +  5)  line 1
       +      5
       +      line 3
       +      ./spec/rspec/expectations/failure_aggregator_spec.rb:366:in `block (7 levels) in <module:Expectations>'
       +
       +  6)  line 1
       +      6
       +      line 3
       +      ./spec/rspec/expectations/failure_aggregator_spec.rb:366:in `block (7 levels) in <module:Expectations>'
       +
       +  7)  line 1
       +      7
       +      line 3
       +      ./spec/rspec/expectations/failure_aggregator_spec.rb:366:in `block (7 levels) in <module:Expectations>'
       +
       +  8)  line 1
       +      8
       +      line 3
       +      ./spec/rspec/expectations/failure_aggregator_spec.rb:366:in `block (7 levels) in <module:Expectations>'
       +
       +  9)  line 1
       +      9
       +      line 3
       +      ./spec/rspec/expectations/failure_aggregator_spec.rb:366:in `block (7 levels) in <module:Expectations>'
       +
       +  10) line 1
       +      10
       +      line 3
       +      ./spec/rspec/expectations/failure_aggregator_spec.rb:366:in `block (7 levels) in <module:Expectations>'
       
     # ./spec/rspec/expectations/failure_aggregator_spec.rb:363:in `block (4 levels) in <module:Expectations>'
  • RSpec::Expectations::FailureAggregator when used via aggregate_failures message formatting when the failure messages have multiple lines indents them appropriately so that they still line up
  3) RSpec::Expectations::FailureAggregator when used via `aggregate_failures` message formatting when the failure messages have multiple lines indents them appropriately so that they still line up
     Failure/Error:
       expect {
         aggregate_failures do
           expect(:a).to fail_with_multiple_lines
           expect(:b).to fail_with_multiple_lines
         end
       }.to fail_including { dedent <<-EOS }
         |  1) line 1
         |     a
         |     line 3
         |     ./spec/rspec/expectations/failure_aggregator_spec.rb:#{__LINE__ - 7}#{exception_complement(6)}
     
       expected "Got 2 failures from failure aggregation block:\n\n  1) line 1\n     a\n     line 3\n     ./spec/rspe...ec/rspec/expectations/failure_aggregator_spec.rb:347:in `block (6 levels) in <module:Expectations>'" to include "  1) line 1\n     a\n     line 3\n     ./spec/rspec/expectations/failure_aggregator_spec.rb:346:in `...   line 3\n     ./spec/rspec/expectations/failure_aggregator_spec.rb:347:in `block in Expectations'"
       Diff:
       @@ -1,11 +1,21 @@
       -  1) line 1\n     a\n     line 3\n     ./spec/rspec/expectations/failure_aggregator_spec.rb:346:in `block in Expectations'\n\n  2) line 1\n     b\n     line 3\n     ./spec/rspec/expectations/failure_aggregator_spec.rb:347:in `block in Expectations'
       +Got 2 failures from failure aggregation block:
       +
       +  1) line 1
       +     a
       +     line 3
       +     ./spec/rspec/expectations/failure_aggregator_spec.rb:346:in `block (6 levels) in <module:Expectations>'
       +
       +  2) line 1
       +     b
       +     line 3
       +     ./spec/rspec/expectations/failure_aggregator_spec.rb:347:in `block (6 levels) in <module:Expectations>'
       
     # ./spec/rspec/expectations/failure_aggregator_spec.rb:344:in `block (4 levels) in <module:Expectations>'
  • RSpec::Expectations::FailureAggregator when used via aggregate_failures message formatting when the failure messages starts and ends with line breaks (as the eq failure message does) strips the excess line breaks so that it formats well
  4) RSpec::Expectations::FailureAggregator when used via `aggregate_failures` message formatting when the failure messages starts and ends with line breaks (as the `eq` failure message does) strips the excess line breaks so that it formats well
     Failure/Error:
       expect {
         aggregate_failures do
           expect(1).to eq 2
           expect(1).to eq 3
           expect(1).to eq 4
         end
       }.to fail_including { dedent <<-EOS }
         |  1) expected: 2
         |          got: 1
         |
     
       expected "Got 3 failures from failure aggregation block:\n\n  1) expected: 2\n          got: 1\n\n     (compar...ec/rspec/expectations/failure_aggregator_spec.rb:395:in `block (6 levels) in <module:Expectations>'" to include "  1) expected: 2\n          got: 1\n\n     (compared using ==)\n\n     ./spec/rspec/expectations/fai...ing ==)\n\n     ./spec/rspec/expectations/failure_aggregator_spec.rb:395:in `block in Expectations'"
       Diff:
       @@ -1,22 +1,43 @@
       -  1) expected: 2\n          got: 1\n\n     (compared using ==)\n\n     ./spec/rspec/expectations/failure_aggregator_spec.rb:393:in `block in Expectations'\n\n  2) expected: 3\n          got: 1\n\n     (compared using ==)\n\n     ./spec/rspec/expectations/failure_aggregator_spec.rb:394:in `block in Expectations'\n\n  3) expected: 4\n          got: 1\n\n     (compared using ==)\n\n     ./spec/rspec/expectations/failure_aggregator_spec.rb:395:in `block in Expectations'
       +Got 3 failures from failure aggregation block:
       +
       +  1) expected: 2
       +          got: 1
       +
       +     (compared using ==)
       +
       +     ./spec/rspec/expectations/failure_aggregator_spec.rb:393:in `block (6 levels) in <module:Expectations>'
       +
       +  2) expected: 3
       +          got: 1
       +
       +     (compared using ==)
       +
       +     ./spec/rspec/expectations/failure_aggregator_spec.rb:394:in `block (6 levels) in <module:Expectations>'
       +
       +  3) expected: 4
       +          got: 1
       +
       +     (compared using ==)
       +
       +     ./spec/rspec/expectations/failure_aggregator_spec.rb:395:in `block (6 levels) in <module:Expectations>'
       
     # ./spec/rspec/expectations/failure_aggregator_spec.rb:391:in `block (4 levels) in <module:Expectations>'
  • RSpec::Expectations::FailureAggregator when used via aggregate_failures message formatting when another error has occcured includes it in the failure message
  5) RSpec::Expectations::FailureAggregator when used via `aggregate_failures` message formatting when another error has occcured includes it in the failure message
     Failure/Error:
       expect {
         aggregate_failures do
           expect(1).to be_even
           raise "boom"
         end
       }.to fail_including { dedent <<-EOS }
         |Got 1 failure and 1 other error from failure aggregation block:
         |
         |  1) expected `1.even?` to return true, got false
         |     ./spec/rspec/expectations/failure_aggregator_spec.rb:#{__LINE__ - 7}#{exception_complement(6)}
     
       expected "Got 1 failure and 1 other error from failure aggregation block:\n\n  1) expected `1.even?` to return...ec/rspec/expectations/failure_aggregator_spec.rb:321:in `block (6 levels) in <module:Expectations>'" to include "Got 1 failure and 1 other error from failure aggregation block:\n\n  1) expected `1.even?` to return...ror: boom\n     ./spec/rspec/expectations/failure_aggregator_spec.rb:321:in `block in Expectations'"
       Diff:
       @@ -1,7 +1,13 @@
       -Got 1 failure and 1 other error from failure aggregation block:\n\n  1) expected `1.even?` to return true, got false\n     ./spec/rspec/expectations/failure_aggregator_spec.rb:320:in `block in Expectations'\n\n  2) RuntimeError: boom\n     ./spec/rspec/expectations/failure_aggregator_spec.rb:321:in `block in Expectations'
       +Got 1 failure and 1 other error from failure aggregation block:
       +
       +  1) expected `1.even?` to return true, got false
       +     ./spec/rspec/expectations/failure_aggregator_spec.rb:320:in `block (6 levels) in <module:Expectations>'
       +
       +  2) RuntimeError: boom
       +     ./spec/rspec/expectations/failure_aggregator_spec.rb:321:in `block (6 levels) in <module:Expectations>'
       
     # ./spec/rspec/expectations/failure_aggregator_spec.rb:318:in `block (4 levels) in <module:Expectations>'

** rspec-mocks**

  • RSpec::Mocks::Matchers::Receive expect_any_instance_of(...).to receive behaves like an expect syntax expectation behaves like a receive matcher without yielding receiver allows a do...end block implementation with keyword args to be provided
Failures:

  1) RSpec::Mocks::Matchers::Receive expect_any_instance_of(...).to receive behaves like an expect syntax expectation behaves like a receive matcher without yielding receiver allows a `do...end` block implementation with keyword args to be provided
     Failure/Error: 
     
       expected: :arg
            got: nil
     
       (compared using ==)
     Shared Example Group: "a receive matcher" called from ./spec/rspec/mocks/matchers/receive_spec.rb:199
     Shared Example Group: "an expect syntax expectation" called from ./spec/rspec/mocks/matchers/receive_spec.rb:515
     # ./spec/rspec/mocks/matchers/receive_spec.rb:81:in `block (5 levels) in <unused>'
     # ./spec/rspec/mocks/matchers/receive_spec.rb:63:in `block (4 levels) in <module:Mocks>'
  • RSpec::Mocks::Matchers::Receive expect_any_instance_of(...).to receive behaves like an expect syntax expectation behaves like a receive matcher without yielding receiver allows a do...end block implementation with required keyword args
  2) RSpec::Mocks::Matchers::Receive expect_any_instance_of(...).to receive behaves like an expect syntax expectation behaves like a receive matcher without yielding receiver allows a `do...end` block implementation with required keyword args
     Failure/Error: it 'allows a `do...end` block implementation with required keyword args' do
     
     ArgumentError:
       missing keyword: kw
     Shared Example Group: "a receive matcher" called from ./spec/rspec/mocks/matchers/receive_spec.rb:199
     Shared Example Group: "an expect syntax expectation" called from ./spec/rspec/mocks/matchers/receive_spec.rb:515
     # ./spec/rspec/mocks/matchers/receive_spec.rb:105:in `block (6 levels) in <unused>'
     # ./spec/rspec/mocks/matchers/receive_spec.rb:109:in `block (5 levels) in <unused>'
     # ./spec/rspec/mocks/matchers/receive_spec.rb:63:in `block (4 levels) in <module:Mocks>'
  • RSpec::Mocks::Matchers::Receive expect_any_instance_of(...).to receive behaves like an expect syntax expectation behaves like a receive matcher without yielding receiver allows a do...end block implementation with optional keyword args to be provided
  3) RSpec::Mocks::Matchers::Receive expect_any_instance_of(...).to receive behaves like an expect syntax expectation behaves like a receive matcher without yielding receiver allows a `do...end` block implementation with optional keyword args to be provided
     Failure/Error: 
     
       expected: 1
            got: :arg
     
       (compared using ==)
     Shared Example Group: "a receive matcher" called from ./spec/rspec/mocks/matchers/receive_spec.rb:199
     Shared Example Group: "an expect syntax expectation" called from ./spec/rspec/mocks/matchers/receive_spec.rb:515
     # ./spec/rspec/mocks/matchers/receive_spec.rb:89:in `block (5 levels) in <unused>'
     # ./spec/rspec/mocks/matchers/receive_spec.rb:63:in `block (4 levels) in <module:Mocks>'
  • RSpec::Mocks::Matchers::Receive expect(...).to receive behaves like an expect syntax expectation behaves like a receive matcher without yielding receiver allows a do...end block implementation with optional keyword args to be provided
  4) RSpec::Mocks::Matchers::Receive expect(...).to receive behaves like an expect syntax expectation behaves like a receive matcher without yielding receiver allows a `do...end` block implementation with optional keyword args to be provided
     Failure/Error: 
     
       expected: 1
            got: :arg
     
       (compared using ==)
     Shared Example Group: "a receive matcher" called from ./spec/rspec/mocks/matchers/receive_spec.rb:199
     Shared Example Group: "an expect syntax expectation" called from ./spec/rspec/mocks/matchers/receive_spec.rb:400
     # ./spec/rspec/mocks/matchers/receive_spec.rb:89:in `block (5 levels) in <unused>'
     # ./spec/rspec/mocks/matchers/receive_spec.rb:63:in `block (4 levels) in <module:Mocks>'
  • RSpec::Mocks::Matchers::Receive expect(...).to receive behaves like an expect syntax expectation behaves like a receive matcher without yielding receiver allows a do...end block implementation with required keyword args
  5) RSpec::Mocks::Matchers::Receive expect(...).to receive behaves like an expect syntax expectation behaves like a receive matcher without yielding receiver allows a `do...end` block implementation with required keyword args
     Failure/Error: it 'allows a `do...end` block implementation with required keyword args' do
     
     ArgumentError:
       missing keyword: kw
     Shared Example Group: "a receive matcher" called from ./spec/rspec/mocks/matchers/receive_spec.rb:199
     Shared Example Group: "an expect syntax expectation" called from ./spec/rspec/mocks/matchers/receive_spec.rb:400
     # ./spec/rspec/mocks/matchers/receive_spec.rb:105:in `block (6 levels) in <unused>'
     # ./spec/rspec/mocks/matchers/receive_spec.rb:109:in `block (5 levels) in <unused>'
     # ./spec/rspec/mocks/matchers/receive_spec.rb:63:in `block (4 levels) in <module:Mocks>'
  • RSpec::Mocks::Matchers::Receive expect(...).to receive behaves like an expect syntax expectation behaves like a receive matcher without yielding receiver allows a do...end block implementation with keyword args to be provided
  6) RSpec::Mocks::Matchers::Receive expect(...).to receive behaves like an expect syntax expectation behaves like a receive matcher without yielding receiver allows a `do...end` block implementation with keyword args to be provided
     Failure/Error: 
     
       expected: :arg
            got: nil
     
       (compared using ==)
     Shared Example Group: "a receive matcher" called from ./spec/rspec/mocks/matchers/receive_spec.rb:199
     Shared Example Group: "an expect syntax expectation" called from ./spec/rspec/mocks/matchers/receive_spec.rb:400
     # ./spec/rspec/mocks/matchers/receive_spec.rb:81:in `block (5 levels) in <unused>'
     # ./spec/rspec/mocks/matchers/receive_spec.rb:63:in `block (4 levels) in <module:Mocks>'
  • RSpec::Mocks::Matchers::Receive allow_any_instance_of(...).to receive behaves like an expect syntax allowance behaves like a receive matcher without yielding receiver allows a do...end block implementation with required keyword args
  7) RSpec::Mocks::Matchers::Receive allow_any_instance_of(...).to receive behaves like an expect syntax allowance behaves like a receive matcher without yielding receiver allows a `do...end` block implementation with required keyword args
     Failure/Error: it 'allows a `do...end` block implementation with required keyword args' do
     
     ArgumentError:
       missing keyword: kw
     Shared Example Group: "a receive matcher" called from ./spec/rspec/mocks/matchers/receive_spec.rb:178
     Shared Example Group: "an expect syntax allowance" called from ./spec/rspec/mocks/matchers/receive_spec.rb:382
     # ./spec/rspec/mocks/matchers/receive_spec.rb:105:in `block (6 levels) in <unused>'
     # ./spec/rspec/mocks/matchers/receive_spec.rb:109:in `block (5 levels) in <unused>'
     # ./spec/rspec/mocks/matchers/receive_spec.rb:63:in `block (4 levels) in <module:Mocks>'
  • RSpec::Mocks::Matchers::Receive allow_any_instance_of(...).to receive behaves like an expect syntax allowance behaves like a receive matcher without yielding receiver allows a do...end block implementation with optional keyword args to be provided
  8) RSpec::Mocks::Matchers::Receive allow_any_instance_of(...).to receive behaves like an expect syntax allowance behaves like a receive matcher without yielding receiver allows a `do...end` block implementation with optional keyword args to be provided
     Failure/Error: 
     
       expected: 1
            got: :arg
     
       (compared using ==)
     Shared Example Group: "a receive matcher" called from ./spec/rspec/mocks/matchers/receive_spec.rb:178
     Shared Example Group: "an expect syntax allowance" called from ./spec/rspec/mocks/matchers/receive_spec.rb:382
     # ./spec/rspec/mocks/matchers/receive_spec.rb:89:in `block (5 levels) in <unused>'
     # ./spec/rspec/mocks/matchers/receive_spec.rb:63:in `block (4 levels) in <module:Mocks>'
  • RSpec::Mocks::Matchers::Receive allow_any_instance_of(...).to receive behaves like an expect syntax allowance behaves like a receive matcher without yielding receiver allows a do...end block implementation with keyword args to be provided
  9) RSpec::Mocks::Matchers::Receive allow_any_instance_of(...).to receive behaves like an expect syntax allowance behaves like a receive matcher without yielding receiver allows a `do...end` block implementation with keyword args to be provided
     Failure/Error: 
     
       expected: :arg
            got: nil
     
       (compared using ==)
     Shared Example Group: "a receive matcher" called from ./spec/rspec/mocks/matchers/receive_spec.rb:178
     Shared Example Group: "an expect syntax allowance" called from ./spec/rspec/mocks/matchers/receive_spec.rb:382
     # ./spec/rspec/mocks/matchers/receive_spec.rb:81:in `block (5 levels) in <unused>'
     # ./spec/rspec/mocks/matchers/receive_spec.rb:63:in `block (4 levels) in <module:Mocks>'
  • RSpec::Mocks::Matchers::Receive allow(...).to receive behaves like an expect syntax allowance behaves like a receive matcher without yielding receiver allows a do...end block implementation with keyword args to be provided
  10) RSpec::Mocks::Matchers::Receive allow(...).to receive behaves like an expect syntax allowance behaves like a receive matcher without yielding receiver allows a `do...end` block implementation with keyword args to be provided
      Failure/Error: 
      
        expected: :arg
             got: nil
      
        (compared using ==)
      Shared Example Group: "a receive matcher" called from ./spec/rspec/mocks/matchers/receive_spec.rb:178
      Shared Example Group: "an expect syntax allowance" called from ./spec/rspec/mocks/matchers/receive_spec.rb:320
      # ./spec/rspec/mocks/matchers/receive_spec.rb:81:in `block (5 levels) in <unused>'
      # ./spec/rspec/mocks/matchers/receive_spec.rb:63:in `block (4 levels) in <module:Mocks>'
  • RSpec::Mocks::Matchers::Receive allow(...).to receive behaves like an expect syntax allowance behaves like a receive matcher without yielding receiver allows a do...end block implementation with optional keyword args to be provided
  11) RSpec::Mocks::Matchers::Receive allow(...).to receive behaves like an expect syntax allowance behaves like a receive matcher without yielding receiver allows a `do...end` block implementation with optional keyword args to be provided
      Failure/Error: 
      
        expected: 1
             got: :arg
      
        (compared using ==)
      Shared Example Group: "a receive matcher" called from ./spec/rspec/mocks/matchers/receive_spec.rb:178
      Shared Example Group: "an expect syntax allowance" called from ./spec/rspec/mocks/matchers/receive_spec.rb:320
      # ./spec/rspec/mocks/matchers/receive_spec.rb:89:in `block (5 levels) in <unused>'
      # ./spec/rspec/mocks/matchers/receive_spec.rb:63:in `block (4 levels) in <module:Mocks>'
  • RSpec::Mocks::Matchers::Receive allow(...).to receive behaves like an expect syntax allowance behaves like a receive matcher without yielding receiver allows a do...end block implementation with required keyword args
  12) RSpec::Mocks::Matchers::Receive allow(...).to receive behaves like an expect syntax allowance behaves like a receive matcher without yielding receiver allows a `do...end` block implementation with required keyword args
      Failure/Error: it 'allows a `do...end` block implementation with required keyword args' do
      
      ArgumentError:
        missing keyword: kw
      Shared Example Group: "a receive matcher" called from ./spec/rspec/mocks/matchers/receive_spec.rb:178
      Shared Example Group: "an expect syntax allowance" called from ./spec/rspec/mocks/matchers/receive_spec.rb:320
      # ./spec/rspec/mocks/matchers/receive_spec.rb:105:in `block (6 levels) in <unused>'
      # ./spec/rspec/mocks/matchers/receive_spec.rb:109:in `block (5 levels) in <unused>'
      # ./spec/rspec/mocks/matchers/receive_spec.rb:63:in `block (4 levels) in <module:Mocks>'
  • argument matchers matching handling non-matcher arguments matches against a hash submitted and received by value
  13) argument matchers matching handling non-matcher arguments matches against a hash submitted and received by value
      Failure/Error: a_double.random_call(:a => "a", :b => "b")
      
        #<Double (anonymous)> received :random_call with unexpected arguments
          expected: ({:a=>"a", :b=>"b"})
               got: ({:a=>"a", :b=>"b"})
        Diff:
        
      # ./spec/rspec/mocks/argument_matchers_spec.rb:381:in `block (3 levels) in <module:Mocks>'
  • Marshal extensions #dump when rspec-mocks has been fully initialized applying and unapplying patch is idempotent
  14) Marshal extensions #dump when rspec-mocks has been fully initialized applying and unapplying patch is idempotent
      Failure/Error: expect { Marshal.dump(obj) }.to raise_error(TypeError)
        expected TypeError but nothing was raised
      # ./spec/rspec/mocks/marshal_extension_spec.rb:46:in `block (4 levels) in <top (required)>'
  • A partial double can accept an inner hash as a message argument
  15) A partial double can accept an inner hash as a message argument
      Failure/Error: expect(object).to receive(:foobar).with(:key => "value").and_return(1)
      
        #<Object:0x3bd38> received :foobar with unexpected arguments
          expected: ({:key=>"value"})
               got: ({:key=>"value"})
        Diff:
        
      # ./spec/rspec/mocks/partial_double_spec.rb:89:in `block (3 levels) in <unused>'
  • A partial double can accept a hash as a message argument
  16) A partial double can accept a hash as a message argument
      Failure/Error: expect(object.foobar(:key => "value")).to equal(1)
      
        #<Object:0x3c458> received :foobar with unexpected arguments
          expected: ({:key=>"value"})
               got: ({:key=>"value"})
        Diff:
        
      # ./spec/rspec/mocks/partial_double_spec.rb:81:in `block (2 levels) in <module:Mocks>'
  • #any_instance when stubbing aliased methods tracks aliased method calls
  17) #any_instance when stubbing aliased methods tracks aliased method calls
      Failure/Error: parent_aliased_method
      
      NameError:
        undefined local variable or method `parent_aliased_method' for #<AnyInstanceSpec::ParentClass:0x4b928>
      # ./spec/rspec/mocks/any_instance_spec.rb:20:in `caller_of_parent_aliased_method'
      # ./spec/rspec/mocks/any_instance_spec.rb:210:in `block (4 levels) in <module:Mocks>'
  • and_call_original on a partial double works for methods that accept keyword arguments
  18) and_call_original on a partial double works for methods that accept keyword arguments
      Failure/Error: it "works for methods that accept keyword arguments" do
      
      ArgumentError:
        wrong number of arguments (given 1, expected 0)
      # ./spec/rspec/mocks/and_call_original_spec.rb:238:in `foo'
      # ./spec/rspec/mocks/and_call_original_spec.rb:240:in `block (4 levels) in <unused>'
  • and_call_original on a partial double when using any_instance works for instance methods that use required keyword arguments
  19) and_call_original on a partial double when using any_instance works for instance methods that use required keyword arguments
      Failure/Error:
        binding.eval(<<-RUBY, __FILE__, __LINE__)
        def meth_5(x:)
          x
        end
        RUBY
      
      ArgumentError:
        wrong number of arguments (given 1, expected 0)
      # ./spec/rspec/mocks/and_call_original_spec.rb:28:in `meth_5'
      # ./spec/rspec/mocks/and_call_original_spec.rb:170:in `block (5 levels) in <unused>'
  • and_call_original on a partial double when using any_instance works for instance methods that use optional keyword arguments with an argument supplied
  20) and_call_original on a partial double when using any_instance works for instance methods that use optional keyword arguments with an argument supplied
      Failure/Error: 
      
      ArgumentError:
        wrong number of arguments (given 1, expected 0)
      # ./spec/rspec/mocks/and_call_original_spec.rb:20:in `meth_4'
      # ./spec/rspec/mocks/and_call_original_spec.rb:161:in `block (5 levels) in <unused>'
  • and_call_original on a partial double when using any_instance works for instance methods that use double splat
  21) and_call_original on a partial double when using any_instance works for instance methods that use double splat
      Failure/Error:
                  binding.eval(<<-RUBY, __FILE__, __LINE__)
                  def meth_3(**kwargs)
                    kwargs
                  end
        
                  def meth_4(x: 1)
                    x
                  end
                  RUBY
      
      ArgumentError:
        wrong number of arguments (given 1, expected 0)
      # ./spec/rspec/mocks/and_call_original_spec.rb:16:in `meth_3'
      # ./spec/rspec/mocks/and_call_original_spec.rb:151:in `block (5 levels) in <unused>'
  • with default syntax configuration it warns about should once, regardless of how many times it is called
    Failure/Error: o.should_receive(:bees)
  22) with default syntax configuration it warns about should once, regardless of how many times it is called
      Failure/Error: o.should_receive(:bees)
      
        RSpec received :deprecate with unexpected arguments
          expected: (/Using.*without explicitly enabling/, {:replacement=>"the new `:expect` syntax or explicitly enable `:should`"})
               got: ("Using `should_receive` from rspec-mocks' old `:should` syntax without explicitly enabling the syntax", {:replacement=>"the new `:expect` syntax or explicitly enable `:should`"})
        Diff:
        @@ -1 +1 @@
        -[/Using.*without explicitly enabling/,
        +["Using `should_receive` from rspec-mocks' old `:should` syntax without explicitly enabling the syntax",
        
      # ./spec/rspec/mocks/should_syntax_spec.rb:480:in `block (2 levels) in <top (required)>'
  • with default syntax configuration warns about should not once, regardless of how many times it is called
    Failure/Error: o.should_not_receive(:bees)
  23) with default syntax configuration warns about should not once, regardless of how many times it is called
      Failure/Error: o.should_not_receive(:bees)
      
        RSpec received :deprecate with unexpected arguments
          expected: (/Using.*without explicitly enabling/, {:replacement=>"the new `:expect` syntax or explicitly enable `:should`"})
               got: ("Using `should_not_receive` from rspec-mocks' old `:should` syntax without explicitly enabling the syntax", {:replacement=>"the new `:expect` syntax or explicitly enable `:should`"})
        Diff:
        @@ -1 +1 @@
        -[/Using.*without explicitly enabling/,
        +["Using `should_not_receive` from rspec-mocks' old `:should` syntax without explicitly enabling the syntax",
        
      # ./spec/rspec/mocks/should_syntax_spec.rb:492:in `block (2 levels) in <top (required)>'
  • with default syntax configuration warns about unstubbing once, regardless of how many times it is called
  24) with default syntax configuration warns about unstubbing once, regardless of how many times it is called
      Failure/Error: o.unstub(:faces)
      
        RSpec received :deprecate with unexpected arguments
          expected: (/Using.*without explicitly enabling/, {:replacement=>"`allow(...).to receive(...).and_call_original` or explicitly enable `:should`"})
               got: ("Using `unstub` from rspec-mocks' old `:should` syntax without explicitly enabling the syntax", {:replacement=>"`allow(...).to receive(...).and_call_original` or explicitly enable `:should`"})
        Diff:
        @@ -1 +1 @@
        -[/Using.*without explicitly enabling/,
        +["Using `unstub` from rspec-mocks' old `:should` syntax without explicitly enabling the syntax",
        
      # ./spec/rspec/mocks/should_syntax_spec.rb:550:in `block (2 levels) in <top (required)>'
  • with default syntax configuration warns about stubbing once, regardless of how many times it is called
  25) with default syntax configuration warns about stubbing once, regardless of how many times it is called
      Failure/Error: o.stub(:faces)
      
        RSpec received :deprecate with unexpected arguments
          expected: (/Using.*without explicitly enabling/, {:replacement=>"the new `:expect` syntax or explicitly enable `:should`"})
               got: ("Using `stub` from rspec-mocks' old `:should` syntax without explicitly enabling the syntax", {:replacement=>"the new `:expect` syntax or explicitly enable `:should`"})
        Diff:
        @@ -1 +1 @@
        -[/Using.*without explicitly enabling/,
        +["Using `stub` from rspec-mocks' old `:should` syntax without explicitly enabling the syntax",
        
      # ./spec/rspec/mocks/should_syntax_spec.rb:502:in `block (2 levels) in <top (required)>'

rspec-rails

  • Configuration clears ActionMailer::Base::Deliveries after each example only has deliveries from this test
  1) Configuration clears ActionMailer::Base::Deliveries after each example only has deliveries from this test (e.g. from email_2@example.com)
     Failure/Error:
       def welcome(to:)
         mail(to: to, subject: 'subject', body: render(inline: "Hello", layout: false))
       end
     
     ArgumentError:
       wrong number of arguments (given 1, expected 0)
     # ./spec/rspec/rails/configuration_spec.rb:273:in `welcome'
     # /Users/bfish/Documents/truffleruby-ws/graal/sdk/mxbuild/darwin-amd64/GRAALVM_67F33FC705_JAVA11/graalvm-67f33fc705-java11-22.1.0-dev/Contents/Home/languages/ruby/lib/gems/gems/actionpack-6.0.4.7/lib/abstract_controller/base.rb:195:in `process_action'
     # /Users/bfish/Documents/truffleruby-ws/graal/sdk/mxbuild/darwin-amd64/GRAALVM_67F33FC705_JAVA11/graalvm-67f33fc705-java11-22.1.0-dev/Contents/Home/languages/ruby/lib/gems/gems/actionpack-6.0.4.7/lib/abstract_controller/callbacks.rb:42:in `block in process_action'
     # /Users/bfish/Documents/truffleruby-ws/graal/sdk/mxbuild/darwin-amd64/GRAALVM_67F33FC705_JAVA11/graalvm-67f33fc705-java11-22.1.0-dev/Contents/Home/languages/ruby/lib/gems/gems/activesupport-6.0.4.7/lib/active_support/callbacks.rb:101:in `run_callbacks'
     # /Users/bfish/Documents/truffleruby-ws/graal/sdk/mxbuild/darwin-amd64/GRAALVM_67F33FC705_JAVA11/graalvm-67f33fc705-java11-22.1.0-dev/Contents/Home/languages/ruby/lib/gems/gems/actionpack-6.0.4.7/lib/abstract_controller/callbacks.rb:41:in `process_action'
     # /Users/bfish/Documents/truffleruby-ws/graal/sdk/mxbuild/darwin-amd64/GRAALVM_67F33FC705_JAVA11/graalvm-67f33fc705-java11-22.1.0-dev/Contents/Home/languages/ruby/lib/gems/gems/actionpack-6.0.4.7/lib/abstract_controller/base.rb:136:in `process'
     # /Users/bfish/Documents/truffleruby-ws/graal/sdk/mxbuild/darwin-amd64/GRAALVM_67F33FC705_JAVA11/graalvm-67f33fc705-java11-22.1.0-dev/Contents/Home/languages/ruby/lib/gems/gems/actionmailer-6.0.4.7/lib/action_mailer/rescuable.rb:25:in `block in process'
     # /Users/bfish/Documents/truffleruby-ws/graal/sdk/mxbuild/darwin-amd64/GRAALVM_67F33FC705_JAVA11/graalvm-67f33fc705-java11-22.1.0-dev/Contents/Home/languages/ruby/lib/gems/gems/actionmailer-6.0.4.7/lib/action_mailer/rescuable.rb:17:in `handle_exceptions'
     # /Users/bfish/Documents/truffleruby-ws/graal/sdk/mxbuild/darwin-amd64/GRAALVM_67F33FC705_JAVA11/graalvm-67f33fc705-java11-22.1.0-dev/Contents/Home/languages/ruby/lib/gems/gems/actionmailer-6.0.4.7/lib/action_mailer/rescuable.rb:24:in `process'
     # /Users/bfish/Documents/truffleruby-ws/graal/sdk/mxbuild/darwin-amd64/GRAALVM_67F33FC705_JAVA11/graalvm-67f33fc705-java11-22.1.0-dev/Contents/Home/languages/ruby/lib/gems/gems/actionview-6.0.4.7/lib/action_view/rendering.rb:39:in `process'
     # /Users/bfish/Documents/truffleruby-ws/graal/sdk/mxbuild/darwin-amd64/GRAALVM_67F33FC705_JAVA11/graalvm-67f33fc705-java11-22.1.0-dev/Contents/Home/languages/ruby/lib/gems/gems/actionmailer-6.0.4.7/lib/action_mailer/base.rb:637:in `block in process'
     # /Users/bfish/Documents/truffleruby-ws/graal/sdk/mxbuild/darwin-amd64/GRAALVM_67F33FC705_JAVA11/graalvm-67f33fc705-java11-22.1.0-dev/Contents/Home/languages/ruby/lib/gems/gems/activesupport-6.0.4.7/lib/active_support/notifications.rb:180:in `block in instrument'
     # /Users/bfish/Documents/truffleruby-ws/graal/sdk/mxbuild/darwin-amd64/GRAALVM_67F33FC705_JAVA11/graalvm-67f33fc705-java11-22.1.0-dev/Contents/Home/languages/ruby/lib/gems/gems/activesupport-6.0.4.7/lib/active_support/notifications/instrumenter.rb:24:in `instrument'
     # /Users/bfish/Documents/truffleruby-ws/graal/sdk/mxbuild/darwin-amd64/GRAALVM_67F33FC705_JAVA11/graalvm-67f33fc705-java11-22.1.0-dev/Contents/Home/languages/ruby/lib/gems/gems/activesupport-6.0.4.7/lib/active_support/notifications.rb:180:in `instrument'
     # /Users/bfish/Documents/truffleruby-ws/graal/sdk/mxbuild/darwin-amd64/GRAALVM_67F33FC705_JAVA11/graalvm-67f33fc705-java11-22.1.0-dev/Contents/Home/languages/ruby/lib/gems/gems/actionmailer-6.0.4.7/lib/action_mailer/base.rb:636:in `process'
     # /Users/bfish/Documents/truffleruby-ws/graal/sdk/mxbuild/darwin-amd64/GRAALVM_67F33FC705_JAVA11/graalvm-67f33fc705-java11-22.1.0-dev/Contents/Home/languages/ruby/lib/gems/gems/actionmailer-6.0.4.7/lib/action_mailer/message_delivery.rb:124:in `block in processed_mailer'
     # /Users/bfish/Documents/truffleruby-ws/graal/sdk/mxbuild/darwin-amd64/GRAALVM_67F33FC705_JAVA11/graalvm-67f33fc705-java11-22.1.0-dev/Contents/Home/languages/ruby/lib/gems/gems/actionmailer-6.0.4.7/lib/action_mailer/message_delivery.rb:123:in `processed_mailer'
     # /Users/bfish/Documents/truffleruby-ws/graal/sdk/mxbuild/darwin-amd64/GRAALVM_67F33FC705_JAVA11/graalvm-67f33fc705-java11-22.1.0-dev/Contents/Home/languages/ruby/lib/gems/gems/actionmailer-6.0.4.7/lib/action_mailer/message_delivery.rb:114:in `deliver_now'
     # ./spec/rspec/rails/configuration_spec.rb:290:in `block (3 levels) in <top (required)>'
     # ./spec/spec_helper.rb:74:in `block (3 levels) in <top (required)>'
     # ./spec/spec_helper.rb:68:in `block (2 levels) in <top (required)>'
  • Configuration clears ActionMailer::Base::Deliveries after each example only has deliveries from this test
  2) Configuration clears ActionMailer::Base::Deliveries after each example only has deliveries from this test (e.g. from email@example.com)
     Failure/Error:
       def welcome(to:)
         mail(to: to, subject: 'subject', body: render(inline: "Hello", layout: false))
       end
     
     ArgumentError:
       wrong number of arguments (given 1, expected 0)
     # ./spec/rspec/rails/configuration_spec.rb:273:in `welcome'
     # /Users/bfish/Documents/truffleruby-ws/graal/sdk/mxbuild/darwin-amd64/GRAALVM_67F33FC705_JAVA11/graalvm-67f33fc705-java11-22.1.0-dev/Contents/Home/languages/ruby/lib/gems/gems/actionpack-6.0.4.7/lib/abstract_controller/base.rb:195:in `process_action'
     # /Users/bfish/Documents/truffleruby-ws/graal/sdk/mxbuild/darwin-amd64/GRAALVM_67F33FC705_JAVA11/graalvm-67f33fc705-java11-22.1.0-dev/Contents/Home/languages/ruby/lib/gems/gems/actionpack-6.0.4.7/lib/abstract_controller/callbacks.rb:42:in `block in process_action'
     # /Users/bfish/Documents/truffleruby-ws/graal/sdk/mxbuild/darwin-amd64/GRAALVM_67F33FC705_JAVA11/graalvm-67f33fc705-java11-22.1.0-dev/Contents/Home/languages/ruby/lib/gems/gems/activesupport-6.0.4.7/lib/active_support/callbacks.rb:101:in `run_callbacks'
     # /Users/bfish/Documents/truffleruby-ws/graal/sdk/mxbuild/darwin-amd64/GRAALVM_67F33FC705_JAVA11/graalvm-67f33fc705-java11-22.1.0-dev/Contents/Home/languages/ruby/lib/gems/gems/actionpack-6.0.4.7/lib/abstract_controller/callbacks.rb:41:in `process_action'
     # /Users/bfish/Documents/truffleruby-ws/graal/sdk/mxbuild/darwin-amd64/GRAALVM_67F33FC705_JAVA11/graalvm-67f33fc705-java11-22.1.0-dev/Contents/Home/languages/ruby/lib/gems/gems/actionpack-6.0.4.7/lib/abstract_controller/base.rb:136:in `process'
     # /Users/bfish/Documents/truffleruby-ws/graal/sdk/mxbuild/darwin-amd64/GRAALVM_67F33FC705_JAVA11/graalvm-67f33fc705-java11-22.1.0-dev/Contents/Home/languages/ruby/lib/gems/gems/actionmailer-6.0.4.7/lib/action_mailer/rescuable.rb:25:in `block in process'
     # /Users/bfish/Documents/truffleruby-ws/graal/sdk/mxbuild/darwin-amd64/GRAALVM_67F33FC705_JAVA11/graalvm-67f33fc705-java11-22.1.0-dev/Contents/Home/languages/ruby/lib/gems/gems/actionmailer-6.0.4.7/lib/action_mailer/rescuable.rb:17:in `handle_exceptions'
     # /Users/bfish/Documents/truffleruby-ws/graal/sdk/mxbuild/darwin-amd64/GRAALVM_67F33FC705_JAVA11/graalvm-67f33fc705-java11-22.1.0-dev/Contents/Home/languages/ruby/lib/gems/gems/actionmailer-6.0.4.7/lib/action_mailer/rescuable.rb:24:in `process'
     # /Users/bfish/Documents/truffleruby-ws/graal/sdk/mxbuild/darwin-amd64/GRAALVM_67F33FC705_JAVA11/graalvm-67f33fc705-java11-22.1.0-dev/Contents/Home/languages/ruby/lib/gems/gems/actionview-6.0.4.7/lib/action_view/rendering.rb:39:in `process'
     # /Users/bfish/Documents/truffleruby-ws/graal/sdk/mxbuild/darwin-amd64/GRAALVM_67F33FC705_JAVA11/graalvm-67f33fc705-java11-22.1.0-dev/Contents/Home/languages/ruby/lib/gems/gems/actionmailer-6.0.4.7/lib/action_mailer/base.rb:637:in `block in process'
     # /Users/bfish/Documents/truffleruby-ws/graal/sdk/mxbuild/darwin-amd64/GRAALVM_67F33FC705_JAVA11/graalvm-67f33fc705-java11-22.1.0-dev/Contents/Home/languages/ruby/lib/gems/gems/activesupport-6.0.4.7/lib/active_support/notifications.rb:180:in `block in instrument'
     # /Users/bfish/Documents/truffleruby-ws/graal/sdk/mxbuild/darwin-amd64/GRAALVM_67F33FC705_JAVA11/graalvm-67f33fc705-java11-22.1.0-dev/Contents/Home/languages/ruby/lib/gems/gems/activesupport-6.0.4.7/lib/active_support/notifications/instrumenter.rb:24:in `instrument'
     # /Users/bfish/Documents/truffleruby-ws/graal/sdk/mxbuild/darwin-amd64/GRAALVM_67F33FC705_JAVA11/graalvm-67f33fc705-java11-22.1.0-dev/Contents/Home/languages/ruby/lib/gems/gems/activesupport-6.0.4.7/lib/active_support/notifications.rb:180:in `instrument'
     # /Users/bfish/Documents/truffleruby-ws/graal/sdk/mxbuild/darwin-amd64/GRAALVM_67F33FC705_JAVA11/graalvm-67f33fc705-java11-22.1.0-dev/Contents/Home/languages/ruby/lib/gems/gems/actionmailer-6.0.4.7/lib/action_mailer/base.rb:636:in `process'
     # /Users/bfish/Documents/truffleruby-ws/graal/sdk/mxbuild/darwin-amd64/GRAALVM_67F33FC705_JAVA11/graalvm-67f33fc705-java11-22.1.0-dev/Contents/Home/languages/ruby/lib/gems/gems/actionmailer-6.0.4.7/lib/action_mailer/message_delivery.rb:124:in `block in processed_mailer'
     # /Users/bfish/Documents/truffleruby-ws/graal/sdk/mxbuild/darwin-amd64/GRAALVM_67F33FC705_JAVA11/graalvm-67f33fc705-java11-22.1.0-dev/Contents/Home/languages/ruby/lib/gems/gems/actionmailer-6.0.4.7/lib/action_mailer/message_delivery.rb:123:in `processed_mailer'
     # /Users/bfish/Documents/truffleruby-ws/graal/sdk/mxbuild/darwin-amd64/GRAALVM_67F33FC705_JAVA11/graalvm-67f33fc705-java11-22.1.0-dev/Contents/Home/languages/ruby/lib/gems/gems/actionmailer-6.0.4.7/lib/action_mailer/message_delivery.rb:114:in `deliver_now'
     # ./spec/rspec/rails/configuration_spec.rb:284:in `block (3 levels) in <top (required)>'
     # ./spec/spec_helper.rb:74:in `block (3 levels) in <top (required)>'
     # ./spec/spec_helper.rb:68:in `block (2 levels) in <top (required)>'

@eregon
Copy link
Author

eregon commented Mar 21, 2022

I got a fix for the kwargs-related failures: rspec/rspec-mocks#1464

@bjfish
Copy link

bjfish commented Mar 21, 2022

I've submitted a possible fix for the rspec-expectation failures:
https://github.com/rspec/rspec-expectations/pull/1364/files

@JonRowe
Copy link
Member

JonRowe commented Mar 23, 2022

To clarify my comments from the original rspec-core pr, #2942, I'd actually be ok with having a seperate CI build on our repos that runs cron and on branches with truffle in the name.

My hesistation about adding truffle is to the main CI pass that runs on merges to main and to PR reviews. A seperate workflow that doesn't affect MRI prs would be fine with me.

@eregon
Copy link
Author

eregon commented Mar 24, 2022

Right, I think adding a daily or weekly run would be helpful, once truffleruby passes all specs of one of the rspec gems (gem by gem is helpful for incremental progress, especially given the current multi-repo setup).
Is it OK to use truffleruby-head there? (and we can switch to a release as soon as there is one with the needed fixes in truffleruby)
As you said, that won't run on PRs or on push (except maybe push to branches with truffle in the name if that's possible).

@JonRowe
Copy link
Member

JonRowe commented Mar 24, 2022

Yes.

@gogainda
Copy link

gogainda commented Mar 30, 2022

Most of the issues in rspec-core were resolved here rspec/rspec-core#2946 , except for one:

1) Spec file load errors prints a warning when a helper file exits early
     Failure/Error:
             expect(output).to eq unindent(<<-EOS)

               While loading ./helper_with_exit.rb an `exit` / `raise SystemExit` occurred, RSpec will now quit.
               Failure/Error: exit 999

               SystemExit:
                 exit
               # ./helper_with_exit.rb:1:in `exit'
               # ./helper_with_exit.rb:1#{spec_line_suffix}
             EOS

       expected: "\nWhile loading ./helper_with_exit.rb an `exit` / `raise SystemExit` occurred, RSpec will now quit.\nFailure/Error: exit 999\n\nSystemExit:\n  exit\n# ./helper_with_exit.rb:1:in `exit'\n# ./helper_with_exit.rb:1:in `<top (required)>'\n"
            got: "\nWhile loading ./helper_with_exit.rb an `exit` / `raise SystemExit` occurred, RSpec will now quit.\nFailure/Error: exit 999\n\nSystemExit:\n  exit\n# ./helper_with_exit.rb:1:in `<top (required)>'\n"

       (compared using ==)

       Diff:
       @@ -4,6 +4,5 @@

        SystemExit:
          exit
       -# ./helper_with_exit.rb:1:in `exit'
        # ./helper_with_exit.rb:1:in `<top (required)>'

@eregon
Copy link
Author

eregon commented Mar 31, 2022

I looked into the above, and that difference is expected. For:

begin
  exit 999
rescue SystemExit => e
  puts e.backtrace
end
$ ruby -v exit.rb
ruby 3.0.3p157 (2021-11-24 revision 3fb7d2cadc) [x86_64-linux]
exit.rb:2:in `exit'
exit.rb:2:in `<main>'

$ ruby -v exit.rb
truffleruby 22.2.0-dev-f545dce9, like ruby 3.0.2, Interpreted JVM [x86_64-linux]
<internal:core> core/process.rb:82:in `exit'
<internal:core> core/kernel.rb:315:in `exit'
exit.rb:2:in `<main>'

I'll make a PR to adapt the expected output.

For CRuby it shows exit.rb:2:in 'exit' even though Kernel#exit is clearly not defined there, but that's what CRuby does for methods defined in C.
For TruffleRuby we the true location of both Process.exit and Kernel#exit, and these are rightfully filtered out rearlier as it's all code the user has no interest in.

For some reason running rspec-core specs with bundle exec rake spec works better than bundle exec rspec spec, I did not figure that out yet. Might be due to whether bundler uses a subprocesses or execve() in place, although that does not seem too likely.

@bjfish
Copy link

bjfish commented Apr 4, 2022

Created a PR for a failing expectations spec:
rspec/rspec-expectations#1366

@eregon
Copy link
Author

eregon commented Apr 13, 2022

I think we should disable the usage of Ripper by RSpec for TruffleRuby, in practice it seems currently very slow (seconds of pause just before showing errors & backtraces) and so it hurts the user experience a lot more than help. @bjfish Could you look into that?

@gogainda
Copy link

Just for my understanding, what Ripper was used for in RSpec?

@pirj
Copy link
Member

pirj commented Apr 14, 2022

This spec would explain it the best, @gogainda.

@eregon
Copy link
Author

eregon commented Apr 15, 2022

I read that spec but it didn't help me much 😅
My understanding is it's used for slightly better formatting of errors/failures (not sure of the details).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants