<commit_before>RSpec::Matchers.define :have_attributes do |attrs|
  match do |obj|
    if obj.nil?
      @err_msg = "Unexpected call to have_attributes on NilClass"
    else
      @err_msg = nil
      attrs.each do |attr, expected|
        actual =
          if obj.respond_to?(attr)
            obj.send(attr)
          elsif obj.respond_to?(:[]) && !obj.kind_of?(ActiveRecord::Base)
            obj[attr]
          else
            RuntimeError.new("Unknown attribute '#{attr}'")
          end

        comparing_times = actual.respond_to?(:acts_like_time?) && expected.respond_to?(:acts_like_time?)
        matcher = comparing_times ? BeSameTimeAs : RSpec::Matchers::BuiltIn::Eq
        matcher = matcher.new(expected)

        unless matcher.matches?(actual)
          name_key = [:name, :id, :object_id].detect { |k| obj.respond_to?(k) }
          @err_msg ||= "with #{obj.class.name} #{name_key}:#{obj.send(name_key).inspect}\n\n"
          @err_msg << "testing attribute: \"#{attr}\"\n#{matcher.failure_message_for_should}\n\n"
        end
      end
    end
    @err_msg.nil?
  end

  failure_message_for_should do |_obj|
    @err_msg
  end

  failure_message_for_should_not do |_obj|
    @err_msg
  end

  description do
    "have the same attributes as passed"
  end<commit_msg>Update BeSameTimeAs matcher for RSpec 3<commit_after>RSpec::Matchers.define :have_attributes do |attrs|
  match do |obj|
    if obj.nil?
      @err_msg = "Unexpected call to have_attributes on NilClass"
    else
      @err_msg = nil
      attrs.each do |attr, expected|
        actual =
          if obj.respond_to?(attr)
            obj.send(attr)
          elsif obj.respond_to?(:[]) && !obj.kind_of?(ActiveRecord::Base)
            obj[attr]
          else
            RuntimeError.new("Unknown attribute '#{attr}'")
          end

        matcher = if actual.respond_to?(:acts_like_time?) && expected.respond_to?(:acts_like_time?)
                    be_same_time_as(expected)
                  else
                    eq(expected)
                  end

        unless matcher.matches?(actual)
          name_key = [:name, :id, :object_id].detect { |k| obj.respond_to?(k) }
          @err_msg ||= "with #{obj.class.name} #{name_key}:#{obj.send(name_key).inspect}\n\n"
          @err_msg << "testing attribute: \"#{attr}\"\n#{matcher.failure_message_for_should}\n\n"
        end
      end
    end
    @err_msg.nil?
  end

  failure_message_for_should do |_obj|
    @err_msg
  end

  failure_message_for_should_not do |_obj|
    @err_msg
  end

  description do
    "have the same attributes as passed"
  end
{'fraction_non_alphanumeric': 0.12196998845709889, 'fraction_numerical': 0.00038476337052712584, 'mean_word_length': 2.3942558746736293, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1889588', 'n_tokens_mistral': 854, 'n_tokens_neox': 851, 'n_words': 173}