0

I am writing my first custom matcher in rspec. I would like to provide a failure message with a break down on why the comparison has failed. Effectively I would like to output the differences between the expected and the actual object. I effectively just need to do this with 2 arrays on the object. I have done some research and am trying to use =~ as described here. It mentions it has an informative failure message but I am struggling to access the failure message. I would effectively just like to return the combined failure message for two separate arrays to give an informative reason for the matcher returning false.

My attempt is as follows

    RSpec::Matchers.define :have_same_state_as_measure_table do |expected_measure_table , max_delta = 1e-06|

  match do |actual_measure_table|
   actual_measure_table.equivalence(expected_measure_table, max_delta)
  end

  description do
    "checks if measure has same state as expected measure table within a given number of precision"
  end

  # Optional method description
  description do
    "checks if measure has same state as expected measure table, within a given level of precision"
  end

  # Optional failure messages
  failure_message do |actual_measure_table|
    mismatch_string = ""
    mismatch_string += (actual_measure_table.columns =~ expected_measure_table.columns || "")
    mismatch_string += (actual_measure_table.names =~ expected_measure_table.names || "")
    "Measure tables missmatch as follows %s" % (mismatch_string.to_s)
  end

  failure_message_when_negated do |actual_measure_table|
    "expected friend not to be in zipcode"
  end

  end
Community
  • 1
  • 1
Donovan Thomson
  • 2,375
  • 3
  • 17
  • 25

1 Answers1

0

My final matcher was as follows :

class CompareMeasureTables

  attr_reader :expected_measure_table, :max_delta, :actual_measure_table

  def initialize(expected_measure_table, max_delta=1e-06)
    @expected_measure_table = expected_measure_table
    @max_delta = max_delta
  end

  def description
    "Checks if measure has same state as expected measure table, within a given level of precision"
  end

  def matches?(actual_measure_table)
    @actual_measure_table = actual_measure_table
    actual_measure_table.equivalence(expected_measure_table, max_delta, false)
  end

  def failure_message
    @mismatch_description = ""
    if actual_measure_table.columns.sort != expected_measure_table.columns.sort
      @mismatch_description += "\nColumns mismatch \nExpected =" + expected_measure_table.columns.inspect
      @mismatch_description += "\nActual =" + actual_measure_table.columns.inspect
    end

    if (@mismatch_description == "")
      @mismatch_description += "\nData mismatch \nExpected =" + (expected_measure_table.records - actual_measure_table.records).inspect
      @mismatch_description += "\nActual =" + (actual_measure_table.records - expected_measure_table.records).inspect
      @mismatch_description += "\nTolerance set at #{@max_delta}"
    end

    "Measure tables mismatch as follows %s" % (@mismatch_description)
  end

end
Donovan Thomson
  • 2,375
  • 3
  • 17
  • 25