skryukov / skooma

Skooma is a Ruby library for validating API implementations against OpenAPI documents.
MIT License
140 stars 5 forks source link

In Rspec, named subject breaks matching wrapper #7

Closed ScotterC closed 9 months ago

ScotterC commented 9 months ago

Rubocop encouraged me to name my subjects which revealed this unexpected behavior with Skooma. By naming the subject it seems to evaluate the schema as an integer and not properly map to the spec. I've included a couple different scenarios below that I explored and what works and what doesn't.

require "rails_helper"

describe "/conversations/:conversation_id", type: :request do
  let(:conversation) { create(:conversation) }

  describe "GET" do
    subject { get "/api/v1/conversations/#{conversation.uuid}", as: :json }

    # Works
    it { is_expected.to conform_schema(200) }

    # Works
    it "expects a 200 response when inline" do
      expect(
        get("/api/v1/conversations/#{conversation.uuid}", as: :json)
      ).to conform_schema(200)
    end

    # Doesn't Work but didn't expect it to
    #   NoMethodError:
    #   undefined method `env' for nil:NilClass
    #   skooma-0.2.1/lib/skooma/matchers/wrapper.rb:17:in `mapped_response'
    it "expects a 200 response when evaluated as a block" do
      expect {
        subject
      }.to conform_schema(200)
    end

    context "with named subject" do
      subject(:response) { get "/api/v1/conversations/#{conversation.uuid}", as: :json }

      # NoMethodError:
      # undefined method `to_a' for 200:Integer
      # skooma-0.2.1/lib/skooma/env_mapper.rb:31:in `map_response' 
      it "expects 200 with named subject and calling subject" do
        expect(subject).to conform_schema(200)
      end

      # NoMethodError:
      # undefined method `to_a' for 200:Integer
      # skooma-0.2.1/lib/skooma/env_mapper.rb:31:in `map_response' 
      it "expects 200 with named subject called by name" do
        expect(response).to conform_schema(200)
      end

      # Doesn't Work, same as block evaluation
      # NoMethodError:
      # undefined method `env' for nil:NilClass
      # skooma-0.2.1/lib/skooma/matchers/wrapper.rb:17:in `mapped_response'
      it "expects a 200 response when evaluated as a block" do
        expect {
          response
        }.to conform_schema(200)
      end
    end
  end
end
skryukov commented 9 months ago

Hey, @ScotterC thanks for the detailed example! ❤️

The problem is that subject(:response) shadows ActionDispatch's response, great finding, will fix it soon!

ScotterC commented 9 months ago

👍🙏