Conversation
8b837a8 to
d2d0e51
Compare
71685ad to
6135d5d
Compare
| Scenario: Using in controller specs | ||
| Given a file named "spec/controllers/users_controller_spec.rb" with: | ||
| """ruby | ||
| require "rails_helper" | ||
|
|
||
| RSpec.describe UsersController, type: :controller do | ||
| describe "POST #create" do | ||
| it "reports validation errors" do | ||
| expect { | ||
| post :create, params: { user: { email: "invalid" } } | ||
| }.to have_reported_error(ValidationError) | ||
| end | ||
| end | ||
| end | ||
| """ | ||
| When I run `rspec spec/controllers/users_controller_spec.rb` | ||
| Then the examples should all pass | ||
|
|
||
| Scenario: Using in request specs | ||
| Given a file named "spec/requests/users_spec.rb" with: | ||
| """ruby | ||
| require "rails_helper" | ||
|
|
||
| RSpec.describe "Users", type: :request do | ||
| describe "POST /users" do | ||
| it "reports processing errors" do | ||
| expect { | ||
| post "/users", params: { user: { name: "Test" } } | ||
| }.to have_reported_error.with(context: "user_creation") | ||
| end | ||
| end | ||
| end | ||
| """ | ||
| When I run `rspec spec/requests/users_spec.rb` | ||
| Then the examples should all pass | ||
|
|
There was a problem hiding this comment.
This isn't a controller / request specific matcher so these feel out of place, why these, why not every aspect of Rails... I'd just cut them.
|
👋 I think this would be a great addition, sorry for the size of the review its been on my todo list for a while, its mostly just grammar / wording tweaks plus a few "fit" things. The one change I do want to see though is dropping instance matching, I don't think it makes sense over just providing class / message / using with. |
|
@JonRowe thanks for review.
Which of these you would rather go with? or
?? I assume, that first option is prefered to keep similarity with |
|
Given that you already have But if you insisted on |
|
It makes sense to separate matching of args passed to |
The only argument that the exception class accepts is "message". We can of course subclass it and support way more than that, but I'm not sure if we should support this in a matcher? I have a feeling, that having a matcher interface similar to |
|
I hadn't clocked that the extra attributes were in addition to the error, I think matching the |
|
Here is a source code for Rails.error.report. These attributes in rails case have a name "context". so |
f90fc3b to
2488a71
Compare
| end | ||
|
|
||
| def failure_message | ||
| if !@error_subscriber.events.empty? && !@attributes.empty? |
|
|
||
| def failure_message | ||
| if !@error_subscriber.events.empty? && !@attributes.empty? | ||
| event_context = @error_subscriber.events.last.attributes[:context] |
There was a problem hiding this comment.
Won’t it be confusing to use last when several errors were reported?
| return "Expected error message to be '#{@expected_message}', but got: #{reported_errors}" | ||
| end | ||
| else | ||
| if @expected_error && !actual_error.is_a?(@expected_error) |
There was a problem hiding this comment.
actual_error should be is_a? expected_class, no? Just by looking at the implementation. Or what is the case when they won’t match?
|
|
||
| private | ||
|
|
||
| def error_matches_expectation? |
There was a problem hiding this comment.
Is the last condition necessary? We already check if it’s empty? before calling this method.
There was a problem hiding this comment.
This particular method checks that the error matches one that we expect, not just that the error occurred.
pirj
left a comment
There was a problem hiding this comment.
A fee minor things and simplifications and it looks good to go.
Let’s leave out matching multiple with chains, severity qualifiers, and all extras for later.
| # | ||
| # @param expected_error_or_message [Class, String, Regexp, nil] the expected error class, message string, or message pattern | ||
| # @param expected_message [String, Regexp, nil] the expected error message to match | ||
| def have_reported_error(expected_error_or_message = UndefinedValue, expected_message = nil) |
There was a problem hiding this comment.
We have default attributes both here and in the initializer. Worth leaving just here?
There was a problem hiding this comment.
There are still defaults both here and there:
def initialize(expected_error_or_message = UndefinedValue, expected_message = nil)
Let's remove there.
| end | ||
|
|
||
| def self.process_with_context | ||
| Rails.error.report(ArgumentError.new("Invalid input"), context: { context: "user_processing", severity: :error }) |
There was a problem hiding this comment.
Nested context here, too. Rename inner to topic: or :section?
Commit grammar improvements Co-authored-by: Jon Rowe <mail@jonrowe.co.uk>
Co-authored-by: Phil Pirozhkov <pirj@users.noreply.github.com>
b5568a0 to
aa4c84d
Compare
fixes #2827
rspec-rails is missing support for Rails ErrorReporter, this was introduced to rails in v7 and has been evolving ever since. With my client, we have moved to using ErrorReporter as a unified error reporting interface, so we can easily move from one error tracking software to another with minimal code changes. And we had a need to test this interface with rspec, so we implemented our own matcher to handle this.
I'm suggesting our internal implementation as is. This is probably not suitable as is for this gem, but I'd like to open discussion with this starting point.
Example usage
TODO
Outline of things that we want to do before marking this as completed.
values_match?(@attributes, actual)for matchermatching_reportsmethod.