Skip to content
This repository was archived by the owner on Nov 30, 2024. It is now read-only.
This repository was archived by the owner on Nov 30, 2024. It is now read-only.

config.include works unpredictably when supplying more than one metadata to filter #3080

Closed
@timdiggins

Description

@timdiggins

Subject of the issue

When supplying more than one metadata to filter for config.before or config.include, I would expect them both to:

  • behave the same (config.before and config.include behave differently)
  • require all the filters (config.before works like this, but config.include seems to just requires any of the metadata to be present)
  • have a determinate order of running - the order they appear in the configuration

Or have I missed some docs where it says don't use more than one metadata to filter on?

Your environment

  • Ruby version: 3.0
  • rspec-core version: v3.13.0

Steps to reproduce

inline ruby
# frozen_string_literal: true

begin
  require "bundler/inline"
rescue LoadError => e
  $stderr.puts "Bundler version 1.10 or later is required. Please update your Bundler"
  raise e
end

gemfile(true) do
  source "https://rubygems.org"

  gem "rspec", "3.13.0" # Activate the gem and version you are reporting the issue against.
end

puts "Ruby version is: #{RUBY_VERSION}"
require 'rspec/autorun'

module TestTypeBase
  def sample_method
    "TestTypeBase"
  end

  attr_reader :test_state
  def store_test_state state
    @test_state ||= []
    @test_state << state
  end
end

module TestTypeSystem
  def sample_method
    "TestTypeSystem"
  end
end

module TestJs
  def sample_method
    "TestJs"
  end
end

module BothSpecified
  def sample_method
    "BothSpecified"
  end
end

RSpec.configure do |config|
  config.include TestTypeBase
  config.include TestTypeSystem, test_type: :system
  config.include TestJs, test_js: true
  config.include BothSpecified, test_type: :system, test_js: true
  config.before(:each) do
    store_test_state("before (all)")
  end
  config.before(:each, test_type: :system) do
    store_test_state("before test_type=system")
  end
  config.before(:each, test_js: true) do
    store_test_state("before test_js=true")
  end
  config.before(:each, test_type: :system, test_js: true) do
    store_test_state("before test_type=system&test_js=true")
  end
end

RSpec.describe "test support" do
  it "with no metadata supplied" do
    aggregate_failures do
      expect(test_state).to include("before (all)")
      expect(is_a?(TestTypeBase)).to be_truthy
      expect(test_state).not_to include("before test_type=system")
      expect(is_a?(TestTypeSystem)).to be_falsey
      expect(test_state).not_to include("before test_js=true")
      expect(is_a?(TestJs)).to be_falsey
      expect(test_state).not_to include("before test_type=system&test_js=true")
      expect(is_a?(BothSpecified)).to be_falsey
      expect(sample_method).to eq("TestTypeBase")
    end
  end
  it "with test_type system", test_type: :system do
    aggregate_failures do
      expect(test_state).to include("before (all)")
      expect(is_a?(TestTypeBase)).to be_truthy
      expect(test_state).to include("before test_type=system")
      expect(is_a?(TestTypeSystem)).to be_truthy
      expect(test_state).not_to include("before test_js=true")
      expect(is_a?(TestJs)).to be_falsey
      expect(test_state).not_to include("before test_type=system&test_js=true") # succeeds
      expect(is_a?(BothSpecified)).to be_falsey # fails
      expect(sample_method).to eq("TestTypeSystem")
    end
  end
  it "with test_js", test_js: true do
    aggregate_failures do
      expect(test_state).to include("before (all)")
      expect(is_a?(TestTypeBase)).to be_truthy
      expect(test_state).not_to include("before test_type=system")
      expect(is_a?(TestTypeSystem)).to be_falsey
      expect(test_state).to include("before test_js=true")
      expect(is_a?(TestJs)).to be_truthy
      expect(test_state).not_to include("before test_type=system&test_js=true") # succeeds
      expect(is_a?(BothSpecified)).to be_falsey # fails
      expect(sample_method).to eq("TestJs")
    end
  end
  describe "with test_type: :system at group level", test_type: :system do
    it "with test_js: true", test_js: true do
      aggregate_failures do
        expect(test_state).to include("before (all)")
        expect(is_a?(TestTypeBase)).to be_truthy
        expect(test_state).to include("before test_type=system")
        expect(is_a?(TestTypeSystem)).to be_truthy
        expect(test_state).to include("before test_js=true")
        expect(is_a?(TestJs)).to be_truthy
        expect(test_state).to include("before test_type=system&test_js=true")
        expect(is_a?(BothSpecified)).to be_truthy
        expect(sample_method).to eq("BothSpecified") # fails - compare below
      end
    end
  end
  describe "with nothing at group level" do
    it "with test_type: :system and test_js: true", test_type: :system, test_js: true do
      aggregate_failures do
        expect(test_state).to include("before (all)")
        expect(is_a?(TestTypeBase)).to be_truthy
        expect(test_state).to include("before test_type=system")
        expect(is_a?(TestTypeSystem)).to be_truthy
        expect(test_state).to include("before test_js=true")
        expect(is_a?(TestJs)).to be_truthy
        expect(test_state).to include("before test_type=system&test_js=true")
        expect(is_a?(BothSpecified)).to be_truthy
        expect(sample_method).to eq("BothSpecified") # succeeds - compare above
      end
    end
  end
end

Expected behavior

No failures.

Actual behavior

3 failures

output of running above code
ruby rspec_issue.rb                                                                                         ─╯
Fetching gem metadata from https://rubygems.org/...
Resolving dependencies...
Ruby version is: 3.0.6
.FFF.

Failures:

  1) test support with test_type system
     Got 2 failures from failure aggregation block.
     # rspec_issue.rb:83:in `block (2 levels) in <main>'

     1.1) Failure/Error: expect(is_a?(BothSpecified)).to be_falsey # fails

            expected: falsey value
                 got: true
          # rspec_issue.rb:91:in `block (3 levels) in <main>'

     1.2) Failure/Error: expect(sample_method).to eq("TestTypeSystem")

            expected: "TestTypeSystem"
                 got: "BothSpecified"

            (compared using ==)
          # rspec_issue.rb:92:in `block (3 levels) in <main>'

  2) test support with test_js
     Got 2 failures from failure aggregation block.
     # rspec_issue.rb:96:in `block (2 levels) in <main>'

     2.1) Failure/Error: expect(is_a?(BothSpecified)).to be_falsey # fails

            expected: falsey value
                 got: true
          # rspec_issue.rb:104:in `block (3 levels) in <main>'

     2.2) Failure/Error: expect(sample_method).to eq("TestJs")

            expected: "TestJs"
                 got: "BothSpecified"

            (compared using ==)
          # rspec_issue.rb:105:in `block (3 levels) in <main>'

  3) test support with test_type: :system at group level with test_js: true
     Failure/Error: expect(sample_method).to eq("BothSpecified") # fails - compare below

       expected: "BothSpecified"
            got: "TestJs"

       (compared using ==)
     # rspec_issue.rb:119:in `block (4 levels) in <main>'
     # rspec_issue.rb:110:in `block (3 levels) in <main>'

Finished in 0.01717 seconds (files took 0.07062 seconds to load)
5 examples, 3 failures

Failed examples:

rspec rspec_issue.rb:82 # test support with test_type system
rspec rspec_issue.rb:95 # test support with test_js
rspec rspec_issue.rb:109 # test

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions