getappmap / appmap-ruby

AppMap client agent for Ruby
https://appland.org
Other
100 stars 13 forks source link

AppMapping of RSwag tests fails when RSpec version is >= 3 #309

Closed kgilpin closed 1 year ago

kgilpin commented 1 year ago

Example from Forem:

  50) Api::V1::Docs::Users PUT /users/:id/suspend /api/users/{id}/suspend put Unknown User ID returns a 404 response
      Failure/Error: VCR.turned_off { ex.run }

      NoMethodError:
        undefined method `metadata' for nil:NilClass
      # ./vendor/bundle/ruby/3.0.0/gems/rswag-specs-2.5.1/lib/rswag/specs/example_group_helpers.rb:98:in `block in run_test!'
      # ./vendor/bundle/ruby/3.0.0/gems/appmap-0.95.0/lib/appmap/rspec.rb:241:in `instance_exec'
      # ./vendor/bundle/ruby/3.0.0/gems/appmap-0.95.0/lib/appmap/rspec.rb:241:in `block in wrap_example_block'
      # ./vendor/bundle/ruby/3.0.0/gems/rspec-core-3.11.0/lib/rspec/core/example.rb:263:in `instance_exec'
      # ./vendor/bundle/ruby/3.0.0/gems/rspec-core-3.11.0/lib/rspec/core/example.rb:263:in `block in run'
      # ./vendor/bundle/ruby/3.0.0/gems/rspec-core-3.11.0/lib/rspec/core/example.rb:511:in `block in with_around_and_singleton_context_hooks'
      # ./vendor/bundle/ruby/3.0.0/gems/rspec-core-3.11.0/lib/rspec/core/example.rb:468:in `block in with_around_example_hooks'
      # vendor/bundle/ruby/3.0.0/gems/rswag-specs-2.5.1/lib/rswag/specs/example_group_helpers.rb
      def run_test!(&block)
        # NOTE: rspec 2.x support
        if RSPEC_VERSION < 3
          before do
            submit_request(example.metadata)
          end

          it "returns a #{metadata[:response][:code]} response" do
            assert_response_matches_metadata(metadata)
            block.call(response) if block_given?
          end
        else
          before do |example|
            submit_request(example.metadata)
          end

          it "returns a #{metadata[:response][:code]} response" do |example|
            # Here, example is nil 
            assert_response_matches_metadata(example.metadata, &block)
            example.instance_exec(response, &block) if block_given?
          end
        end
      end
symwell commented 1 year ago

Suggest adding an rswag test to one of the Rails fixture apps in appmap-ruby and that should be a pretty good way to reproduce it and fix it.

There's a block parameter in this flow that isn't getting propagated through our rspec.rb.

https://github.com/getappmap/appmap-ruby#using-fixture-apps

To reproduce in Forem

RAILS_ENV=test bundle exec rspec --backtrace  ./spec/requests/api/v1/docs/profile_images_spec.rb

edit: Passing the example param now gives a different error if we use in lib/appmap/rspec.rb:241:in `instance_exec'

     instance_exec(fn) { |x| x.call(example) }
     # or:    fn.call(example)

     Failure/Error: VCR.turned_off { ex.run }
       `assert_response_matches_metadata` is not available on an example group (e.g. a `describe` or `context` block). It is only available from within individual examples (e.g. `it` blocks) or from constructs that run in the scope of an example (e.g. `before`, `let`, etc).

Maybe the call that uses example should be executed as a proc from assert_response_matches_metadata, or with eval.

kgilpin commented 1 year ago

:tada: This issue has been resolved in version 0.95.2 :tada:

The release is available on:

Your semantic-release bot :package::rocket: