If == matcher fails with empty Diff, error notice should be more helpful. #123

Closed
tvdeyen opened this Issue Mar 16, 2012 · 33 comments

Comments

Projects
None yet
@tvdeyen

tvdeyen commented Mar 16, 2012

Comparing two objects via == that are not equal, but have no differences make rspec fail. The error notice shown is:

Diff:

It would be helpful if an explanation of what's the problem shows up. Like the comparing with eq notice!

@dchelimsky

This comment has been minimized.

Show comment Hide comment
@dchelimsky

dchelimsky Mar 16, 2012

Member

Using == we get this:

     Failure/Error: pessimist.should == pessimist
       expected: #<Pessimist:0x007f8d9c1e3508>
            got: #<Pessimist:0x007f8d9c1e3508> (using ==)
       Diff:

Using eq we get this:


     Failure/Error: pessimist.should eq(pessimist)

       expected: #<Pessimist:0x007fab988ef3a0>
            got: #<Pessimist:0x007fab988ef3a0>

       (compared using ==)

       Diff:

These have the same information, just formatted differently. What is it that you would like to see?

Member

dchelimsky commented Mar 16, 2012

Using == we get this:

     Failure/Error: pessimist.should == pessimist
       expected: #<Pessimist:0x007f8d9c1e3508>
            got: #<Pessimist:0x007f8d9c1e3508> (using ==)
       Diff:

Using eq we get this:


     Failure/Error: pessimist.should eq(pessimist)

       expected: #<Pessimist:0x007fab988ef3a0>
            got: #<Pessimist:0x007fab988ef3a0>

       (compared using ==)

       Diff:

These have the same information, just formatted differently. What is it that you would like to see?

@tvdeyen

This comment has been minimized.

Show comment Hide comment
@tvdeyen

tvdeyen Mar 16, 2012

Why it fails. ;)

Please read this again with a 100000 miles perspective:

Expected A
Got A
Diff

What should this mean? Whats the failure?

If one expects that A equals A and it fails with: "Hey you expected A but got A with a difference of none" its not very helpful, isn't it? ;)

I think a little bit more explaination would be helpful.

Using == we get this:

    Failure/Error: pessimist.should == pessimist
      expected: #<Pessimist:0x007f8d9c1e3508>
           got: #<Pessimist:0x007f8d9c1e3508> (using ==)
      Diff:

Using eq we get this:


    Failure/Error: pessimist.should eq(pessimist)

      expected: #<Pessimist:0x007fab988ef3a0>
           got: #<Pessimist:0x007fab988ef3a0>

      (compared using ==)

      Diff:

These have the same information, just formatted differently. What is it that you would like to see?


Reply to this email directly or view it on GitHub:
#123 (comment)

tvdeyen commented Mar 16, 2012

Why it fails. ;)

Please read this again with a 100000 miles perspective:

Expected A
Got A
Diff

What should this mean? Whats the failure?

If one expects that A equals A and it fails with: "Hey you expected A but got A with a difference of none" its not very helpful, isn't it? ;)

I think a little bit more explaination would be helpful.

Using == we get this:

    Failure/Error: pessimist.should == pessimist
      expected: #<Pessimist:0x007f8d9c1e3508>
           got: #<Pessimist:0x007f8d9c1e3508> (using ==)
      Diff:

Using eq we get this:


    Failure/Error: pessimist.should eq(pessimist)

      expected: #<Pessimist:0x007fab988ef3a0>
           got: #<Pessimist:0x007fab988ef3a0>

      (compared using ==)

      Diff:

These have the same information, just formatted differently. What is it that you would like to see?


Reply to this email directly or view it on GitHub:
#123 (comment)

@dchelimsky

This comment has been minimized.

Show comment Hide comment
@dchelimsky

dchelimsky Mar 16, 2012

Member

I understand the goal and the motivation. I was asking you for a recommendation on wording. How about "A == A returns true, but the objects do not report any difference."

Member

dchelimsky commented Mar 16, 2012

I understand the goal and the motivation. I was asking you for a recommendation on wording. How about "A == A returns true, but the objects do not report any difference."

@tvdeyen

This comment has been minimized.

Show comment Hide comment
@tvdeyen

tvdeyen Mar 16, 2012

Call me stupid, but I think I really don't get it.

The test fails, because "A == A returns true, but the objects do not report any difference."?

What am I missing?

tvdeyen commented Mar 16, 2012

Call me stupid, but I think I really don't get it.

The test fails, because "A == A returns true, but the objects do not report any difference."?

What am I missing?

@dchelimsky

This comment has been minimized.

Show comment Hide comment
@dchelimsky

dchelimsky Mar 16, 2012

Member

That should have been "A == A returns false ..."

Member

dchelimsky commented Mar 16, 2012

That should have been "A == A returns false ..."

@tvdeyen

This comment has been minimized.

Show comment Hide comment
@tvdeyen

tvdeyen Mar 17, 2012

Phew, and I thought I am loosing my mind. :)

What about: "A == A haven't any difference, but returns false. Are you comparing new instances of ActiveRecord Models? Try to save them first."

Or is this too specific?

tvdeyen commented Mar 17, 2012

Phew, and I thought I am loosing my mind. :)

What about: "A == A haven't any difference, but returns false. Are you comparing new instances of ActiveRecord Models? Try to save them first."

Or is this too specific?

@dchelimsky

This comment has been minimized.

Show comment Hide comment
@dchelimsky

dchelimsky Mar 17, 2012

Member

Right track but yes, too specific. How about something like:

"A.==(B) returned false even though the diff between A and B is empty. Check the implementation of A.==."

Member

dchelimsky commented Mar 17, 2012

Right track but yes, too specific. How about something like:

"A.==(B) returned false even though the diff between A and B is empty. Check the implementation of A.==."

@tvdeyen

This comment has been minimized.

Show comment Hide comment
@tvdeyen

tvdeyen Mar 17, 2012

It's ok for me.

But maybe some more people could share their thoughts on this.

tvdeyen commented Mar 17, 2012

It's ok for me.

But maybe some more people could share their thoughts on this.

@justinko

This comment has been minimized.

Show comment Hide comment
@justinko

justinko Mar 17, 2012

Contributor

But maybe some more people could share their thoughts on this.

That just slows things down. We can always iterate on @dchelimsky's suggestion after it's released.

P.S. I think @dchelimsky suggestion is plenty good enough.

Contributor

justinko commented Mar 17, 2012

But maybe some more people could share their thoughts on this.

That just slows things down. We can always iterate on @dchelimsky's suggestion after it's released.

P.S. I think @dchelimsky suggestion is plenty good enough.

@myronmarston

This comment has been minimized.

Show comment Hide comment
@myronmarston

myronmarston Mar 17, 2012

Member

I like @dchelimsky's suggestion, too.

Member

myronmarston commented Mar 17, 2012

I like @dchelimsky's suggestion, too.

@justinko

This comment has been minimized.

Show comment Hide comment
@justinko

justinko Mar 17, 2012

Contributor

@tvdeyen would you like to implement this?

Contributor

justinko commented Mar 17, 2012

@tvdeyen would you like to implement this?

@tvdeyen

This comment has been minimized.

Show comment Hide comment
@tvdeyen

tvdeyen Mar 20, 2012

Ok, why not. But you have to guide me the right way.

tvdeyen commented Mar 20, 2012

Ok, why not. But you have to guide me the right way.

@justinko justinko closed this in e12a2d9 Mar 23, 2012

@agis

This comment has been minimized.

Show comment Hide comment
@agis

agis Sep 18, 2012

I'm having the same failure message in a spec and I would like to know what it exactly means.

agis commented Sep 18, 2012

I'm having the same failure message in a spec and I would like to know what it exactly means.

@alindeman

This comment has been minimized.

Show comment Hide comment
@alindeman

alindeman Sep 18, 2012

Contributor

@agis-, it's likely due to an object that overrides == to provide a more refined definition of equality. What objects are you comparing?

Contributor

alindeman commented Sep 18, 2012

@agis-, it's likely due to an object that overrides == to provide a more refined definition of equality. What objects are you comparing?

@agis

This comment has been minimized.

Show comment Hide comment
@agis

agis Sep 18, 2012

These are the actual specs: https://gist.github.com/3744048

agis commented Sep 18, 2012

These are the actual specs: https://gist.github.com/3744048

@alindeman

This comment has been minimized.

Show comment Hide comment
@alindeman

alindeman Sep 18, 2012

Contributor

Ah, that's ActiveRecord. If two ActiveRecord objects are being compared and both of their #ids are nil, it checks checks whether they are exactly the same instance (which they are not in this case).

tldr: it doesn't look like album saved correctly; otherwise it would have a database-assigned #id.

Contributor

alindeman commented Sep 18, 2012

Ah, that's ActiveRecord. If two ActiveRecord objects are being compared and both of their #ids are nil, it checks checks whether they are exactly the same instance (which they are not in this case).

tldr: it doesn't look like album saved correctly; otherwise it would have a database-assigned #id.

@myronmarston

This comment has been minimized.

Show comment Hide comment
@myronmarston

myronmarston Sep 18, 2012

Member

FWIW, the message that was added here gets printed in some cases where it makes no sense. See #143.

Member

myronmarston commented Sep 18, 2012

FWIW, the message that was added here gets printed in some cases where it makes no sense. See #143.

@agis

This comment has been minimized.

Show comment Hide comment
@agis

agis Sep 18, 2012

I see, thanks @alindeman.

agis commented Sep 18, 2012

I see, thanks @alindeman.

@mjacobus

This comment has been minimized.

Show comment Hide comment
@mjacobus

mjacobus Jun 6, 2013

Same problem here. Inside rspec [hash] == [hash] returns false. In terminal it returns true. Looks like the implementation is working, but the spec test says otherwise.

Terminal:

race = Race.first
teams = race.teams.map(&:attributes)
RaceExportation.new(race).to_hash[:teams] == teams # true

Inside rspec

require 'spec_helper'

describe RaceExportation do
  let(:race) { category.race }
  let(:team) { create(:team, race: race) }

  describe "#to_hash" do
    subject { RaceExportation.new(race).to_hash }

    it "sets :teams key" do
      subject[:teams].should == [team.attributes]
    end
  end
end
  1. RaceExportation#to_hash sets :teams key
    Failure/Error: subject[:teams].should == [team.attributes]
       expected: [{"id"=>40, "race_id"=>107, "name"=>"The Name 6", "slug"=>"the-name-6", "code"=>"avg", "created_at"=>Thu, 06 Jun 2013 11:44:01 BRT -03:00, "updated_at"=>Thu, 06 Jun 2013 11:44:01 BRT -03:00}]
            got: [{"id"=>40, "race_id"=>107, "name"=>"The Name 6", "slug"=>"the-name-6", "code"=>"avg", "created_at"=>Thu, 06 Jun 2013 11:44:01 BRT -03:00, "updated_at"=>Thu, 06 Jun 2013 11:44:01 BRT -03:00}] (using ==)
       Diff:[{"id"=>40, "race_id"=>107, "name"=>"The Name 6", "slug"=>"the-name-6", "code"=>"avg", "created_at"=>Thu, 06 Jun 2013 11:44:01 BRT -03:00, "updated_at"=>Thu, 06 Jun 2013 11:44:01 BRT -03:00}].==([{"id"=>40, "race_id"=>107, "name"=>"The Name 6", "slug"=>"the-name-6", "code"=>"avg", "created_at"=>Thu, 06 Jun 2013 11:44:01 BRT -03:00, "updated_at"=>Thu, 06 Jun 2013 11:44:01 BRT -03:00}]) returned false even though the diff between [{"id"=>40, "race_id"=>107, "name"=>"The Name 6", "slug"=>"the-name-6", "code"=>"avg", "created_at"=>Thu, 06 Jun 2013 11:44:01 BRT -03:00, "updated_at"=>Thu, 06 Jun 2013 11:44:01 BRT -03:00}] and [{"id"=>40, "race_id"=>107, "name"=>"The Name 6", "slug"=>"the-name-6", "code"=>"avg", "created_at"=>Thu, 06 Jun 2013 11:44:01 BRT -03:00, "updated_at"=>Thu, 06 Jun 2013 11:44:01 BRT -03:00}] is empty. Check the implementation of [{"id"=>40, "race_id"=>107, "name"=>"The Name 6", "slug"=>"the-name-6", "code"=>"avg", "created_at"=>Thu, 06 Jun 2013 11:44:01 BRT -03:00, "updated_at"=>Thu, 06 Jun 2013 11:44:01 BRT -03:00}].==.
  1. RaceExportation#to_hash sets :teams key
    Failure/Error: subject[:teams].should eq([team.attributes])
       expected: [{"id"=>42, "race_id"=>109, "name"=>"The Name 6", "slug"=>"the-name-6", "code"=>"avg", "created_at"=>Thu, 06 Jun 2013 11:45:46 BRT -03:00, "updated_at"=>Thu, 06 Jun 2013 11:45:46 BRT -03:00}]
            got: [{"id"=>42, "race_id"=>109, "name"=>"The Name 6", "slug"=>"the-name-6", "code"=>"avg", "created_at"=>Thu, 06 Jun 2013 11:45:46 BRT -03:00, "updated_at"=>Thu, 06 Jun 2013 11:45:46 BRT -03:00}]

       (compared using ==)

       Diff:[{"id"=>42, "race_id"=>109, "name"=>"The Name 6", "slug"=>"the-name-6", "code"=>"avg", "created_at"=>Thu, 06 Jun 2013 11:45:46 BRT -03:00, "updated_at"=>Thu, 06 Jun 2013 11:45:46 BRT -03:00}].==([{"id"=>42, "race_id"=>109, "name"=>"The Name 6", "slug"=>"the-name-6", "code"=>"avg", "created_at"=>Thu, 06 Jun 2013 11:45:46 BRT -03:00, "updated_at"=>Thu, 06 Jun 2013 11:45:46 BRT -03:00}]) returned false even though the diff between [{"id"=>42, "race_id"=>109, "name"=>"The Name 6", "slug"=>"the-name-6", "code"=>"avg", "created_at"=>Thu, 06 Jun 2013 11:45:46 BRT -03:00, "updated_at"=>Thu, 06 Jun 2013 11:45:46 BRT -03:00}] and [{"id"=>42, "race_id"=>109, "name"=>"The Name 6", "slug"=>"the-name-6", "code"=>"avg", "created_at"=>Thu, 06 Jun 2013 11:45:46 BRT -03:00, "updated_at"=>Thu, 06 Jun 2013 11:45:46 BRT -03:00}] is empty. Check the implementation of [{"id"=>42, "race_id"=>109, "name"=>"The Name 6", "slug"=>"the-name-6", "code"=>"avg", "created_at"=>Thu, 06 Jun 2013 11:45:46 BRT -03:00, "updated_at"=>Thu, 06 Jun 2013 11:45:46 BRT -03:00}].==.
  1. RaceExportation#to_hash sets :teams key
    Failure/Error: subject[:teams].should =~ [team.attributes]
       expected collection contained:  [{"id"=>44, "race_id"=>111, "name"=>"The Name 6", "slug"=>"the-name-6", "code"=>"avg", "created_at"=>Thu, 06 Jun 2013 11:48:04 BRT -03:00, "updated_at"=>Thu, 06 Jun 2013 11:48:04 BRT -03:00}]
       actual collection contained:    [{"id"=>44, "race_id"=>111, "name"=>"The Name 6", "slug"=>"the-name-6", "code"=>"avg", "created_at"=>Thu, 06 Jun 2013 11:48:04 BRT -03:00, "updated_at"=>Thu, 06 Jun 2013 11:48:04 BRT -03:00}]
       the missing elements were:      [{"id"=>44, "race_id"=>111, "name"=>"The Name 6", "slug"=>"the-name-6", "code"=>"avg", "created_at"=>Thu, 06 Jun 2013 11:48:04 BRT -03:00, "updated_at"=>Thu, 06 Jun 2013 11:48:04 BRT -03:00}]
       the extra elements were:        [{"id"=>44, "race_id"=>111, "name"=>"The Name 6", "slug"=>"the-name-6", "code"=>"avg", "created_at"=>Thu, 06 Jun 2013 11:48:04 BRT -03:00, "updated_at"=>Thu, 06 Jun 2013 11:48:04 BRT -03:00}]

mjacobus commented Jun 6, 2013

Same problem here. Inside rspec [hash] == [hash] returns false. In terminal it returns true. Looks like the implementation is working, but the spec test says otherwise.

Terminal:

race = Race.first
teams = race.teams.map(&:attributes)
RaceExportation.new(race).to_hash[:teams] == teams # true

Inside rspec

require 'spec_helper'

describe RaceExportation do
  let(:race) { category.race }
  let(:team) { create(:team, race: race) }

  describe "#to_hash" do
    subject { RaceExportation.new(race).to_hash }

    it "sets :teams key" do
      subject[:teams].should == [team.attributes]
    end
  end
end
  1. RaceExportation#to_hash sets :teams key
    Failure/Error: subject[:teams].should == [team.attributes]
       expected: [{"id"=>40, "race_id"=>107, "name"=>"The Name 6", "slug"=>"the-name-6", "code"=>"avg", "created_at"=>Thu, 06 Jun 2013 11:44:01 BRT -03:00, "updated_at"=>Thu, 06 Jun 2013 11:44:01 BRT -03:00}]
            got: [{"id"=>40, "race_id"=>107, "name"=>"The Name 6", "slug"=>"the-name-6", "code"=>"avg", "created_at"=>Thu, 06 Jun 2013 11:44:01 BRT -03:00, "updated_at"=>Thu, 06 Jun 2013 11:44:01 BRT -03:00}] (using ==)
       Diff:[{"id"=>40, "race_id"=>107, "name"=>"The Name 6", "slug"=>"the-name-6", "code"=>"avg", "created_at"=>Thu, 06 Jun 2013 11:44:01 BRT -03:00, "updated_at"=>Thu, 06 Jun 2013 11:44:01 BRT -03:00}].==([{"id"=>40, "race_id"=>107, "name"=>"The Name 6", "slug"=>"the-name-6", "code"=>"avg", "created_at"=>Thu, 06 Jun 2013 11:44:01 BRT -03:00, "updated_at"=>Thu, 06 Jun 2013 11:44:01 BRT -03:00}]) returned false even though the diff between [{"id"=>40, "race_id"=>107, "name"=>"The Name 6", "slug"=>"the-name-6", "code"=>"avg", "created_at"=>Thu, 06 Jun 2013 11:44:01 BRT -03:00, "updated_at"=>Thu, 06 Jun 2013 11:44:01 BRT -03:00}] and [{"id"=>40, "race_id"=>107, "name"=>"The Name 6", "slug"=>"the-name-6", "code"=>"avg", "created_at"=>Thu, 06 Jun 2013 11:44:01 BRT -03:00, "updated_at"=>Thu, 06 Jun 2013 11:44:01 BRT -03:00}] is empty. Check the implementation of [{"id"=>40, "race_id"=>107, "name"=>"The Name 6", "slug"=>"the-name-6", "code"=>"avg", "created_at"=>Thu, 06 Jun 2013 11:44:01 BRT -03:00, "updated_at"=>Thu, 06 Jun 2013 11:44:01 BRT -03:00}].==.
  1. RaceExportation#to_hash sets :teams key
    Failure/Error: subject[:teams].should eq([team.attributes])
       expected: [{"id"=>42, "race_id"=>109, "name"=>"The Name 6", "slug"=>"the-name-6", "code"=>"avg", "created_at"=>Thu, 06 Jun 2013 11:45:46 BRT -03:00, "updated_at"=>Thu, 06 Jun 2013 11:45:46 BRT -03:00}]
            got: [{"id"=>42, "race_id"=>109, "name"=>"The Name 6", "slug"=>"the-name-6", "code"=>"avg", "created_at"=>Thu, 06 Jun 2013 11:45:46 BRT -03:00, "updated_at"=>Thu, 06 Jun 2013 11:45:46 BRT -03:00}]

       (compared using ==)

       Diff:[{"id"=>42, "race_id"=>109, "name"=>"The Name 6", "slug"=>"the-name-6", "code"=>"avg", "created_at"=>Thu, 06 Jun 2013 11:45:46 BRT -03:00, "updated_at"=>Thu, 06 Jun 2013 11:45:46 BRT -03:00}].==([{"id"=>42, "race_id"=>109, "name"=>"The Name 6", "slug"=>"the-name-6", "code"=>"avg", "created_at"=>Thu, 06 Jun 2013 11:45:46 BRT -03:00, "updated_at"=>Thu, 06 Jun 2013 11:45:46 BRT -03:00}]) returned false even though the diff between [{"id"=>42, "race_id"=>109, "name"=>"The Name 6", "slug"=>"the-name-6", "code"=>"avg", "created_at"=>Thu, 06 Jun 2013 11:45:46 BRT -03:00, "updated_at"=>Thu, 06 Jun 2013 11:45:46 BRT -03:00}] and [{"id"=>42, "race_id"=>109, "name"=>"The Name 6", "slug"=>"the-name-6", "code"=>"avg", "created_at"=>Thu, 06 Jun 2013 11:45:46 BRT -03:00, "updated_at"=>Thu, 06 Jun 2013 11:45:46 BRT -03:00}] is empty. Check the implementation of [{"id"=>42, "race_id"=>109, "name"=>"The Name 6", "slug"=>"the-name-6", "code"=>"avg", "created_at"=>Thu, 06 Jun 2013 11:45:46 BRT -03:00, "updated_at"=>Thu, 06 Jun 2013 11:45:46 BRT -03:00}].==.
  1. RaceExportation#to_hash sets :teams key
    Failure/Error: subject[:teams].should =~ [team.attributes]
       expected collection contained:  [{"id"=>44, "race_id"=>111, "name"=>"The Name 6", "slug"=>"the-name-6", "code"=>"avg", "created_at"=>Thu, 06 Jun 2013 11:48:04 BRT -03:00, "updated_at"=>Thu, 06 Jun 2013 11:48:04 BRT -03:00}]
       actual collection contained:    [{"id"=>44, "race_id"=>111, "name"=>"The Name 6", "slug"=>"the-name-6", "code"=>"avg", "created_at"=>Thu, 06 Jun 2013 11:48:04 BRT -03:00, "updated_at"=>Thu, 06 Jun 2013 11:48:04 BRT -03:00}]
       the missing elements were:      [{"id"=>44, "race_id"=>111, "name"=>"The Name 6", "slug"=>"the-name-6", "code"=>"avg", "created_at"=>Thu, 06 Jun 2013 11:48:04 BRT -03:00, "updated_at"=>Thu, 06 Jun 2013 11:48:04 BRT -03:00}]
       the extra elements were:        [{"id"=>44, "race_id"=>111, "name"=>"The Name 6", "slug"=>"the-name-6", "code"=>"avg", "created_at"=>Thu, 06 Jun 2013 11:48:04 BRT -03:00, "updated_at"=>Thu, 06 Jun 2013 11:48:04 BRT -03:00}]
@mjacobus

This comment has been minimized.

Show comment Hide comment
@mjacobus

mjacobus Jun 6, 2013

Turns out it is something related to Time. As my time stubbing didnt work I did that workaround (im not very proud of it).

describe RaceExportation do
  def remove_times(object)
    if object.class == Array
      object.map{|e| remove_times(e)}
    else
      object.except('created_at', 'updated_at')
    end
  end

   # let(){}..

   it "sets :teams key" do
      remove_times(subject[:teams]).should == remove_times([team.attributes])
   end
end

mjacobus commented Jun 6, 2013

Turns out it is something related to Time. As my time stubbing didnt work I did that workaround (im not very proud of it).

describe RaceExportation do
  def remove_times(object)
    if object.class == Array
      object.map{|e| remove_times(e)}
    else
      object.except('created_at', 'updated_at')
    end
  end

   # let(){}..

   it "sets :teams key" do
      remove_times(subject[:teams]).should == remove_times([team.attributes])
   end
end
@AdrienBD

This comment has been minimized.

Show comment Hide comment
@AdrienBD

AdrienBD Sep 7, 2015

Sorry to reopen this issue but I am facing the empty diff message again...
This time I am not comparing rails Object but their json :

RSpec::Mocks::MockExpectationError: ElasticSearchUtils received :index_stat with unexpected arguments
  expected: (:download, {"action"=>"download", "active"=>true, "created_at"=>Sat, 05 Sep 2015 10:04:59 CEST +02:00, "device_id"=>nil, "mobile_application_id"=>189, "mobile_application_update_id"=>292, "store_id"=>932, "updated_at"=>Mon, 07 Sep 2015 10:04:59 CEST +02:00, "user_id"=>663, "version"=>1, "id"=>"55ed452b4d42507f6e000000"})
       got: (:download, {"action"=>"download", "active"=>true, "created_at"=>Sat, 05 Sep 2015 10:04:59 CEST +02:00, "device_id"=>nil, "mobile_application_id"=>189, "mobile_application_update_id"=>292, "store_id"=>932, "updated_at"=>Mon, 07 Sep 2015 10:04:59 CEST +02:00, "user_id"=>663, "version"=>1, "id"=>"55ed452b4d42507f6e000000"})
Diff:

I even checked that the created_at and updated_at times where identical to the millisecond.
Could anyone help me on that ?

AdrienBD commented Sep 7, 2015

Sorry to reopen this issue but I am facing the empty diff message again...
This time I am not comparing rails Object but their json :

RSpec::Mocks::MockExpectationError: ElasticSearchUtils received :index_stat with unexpected arguments
  expected: (:download, {"action"=>"download", "active"=>true, "created_at"=>Sat, 05 Sep 2015 10:04:59 CEST +02:00, "device_id"=>nil, "mobile_application_id"=>189, "mobile_application_update_id"=>292, "store_id"=>932, "updated_at"=>Mon, 07 Sep 2015 10:04:59 CEST +02:00, "user_id"=>663, "version"=>1, "id"=>"55ed452b4d42507f6e000000"})
       got: (:download, {"action"=>"download", "active"=>true, "created_at"=>Sat, 05 Sep 2015 10:04:59 CEST +02:00, "device_id"=>nil, "mobile_application_id"=>189, "mobile_application_update_id"=>292, "store_id"=>932, "updated_at"=>Mon, 07 Sep 2015 10:04:59 CEST +02:00, "user_id"=>663, "version"=>1, "id"=>"55ed452b4d42507f6e000000"})
Diff:

I even checked that the created_at and updated_at times where identical to the millisecond.
Could anyone help me on that ?

@JonRowe

This comment has been minimized.

Show comment Hide comment
@JonRowe

JonRowe Sep 7, 2015

Member

Are the times equal in ruby? Regardless of clock equalness.

Member

JonRowe commented Sep 7, 2015

Are the times equal in ruby? Regardless of clock equalness.

@AdrienBD

This comment has been minimized.

Show comment Hide comment
@AdrienBD

AdrienBD Sep 7, 2015

Not sure if I understand what you asked for but this returns true :

p json_1['created_at'] == stat_1.created_at

json_1 being the json created with the as_json method of stat_1. stat_1 is a mongoid entity I create at the beginning of the test.

AdrienBD commented Sep 7, 2015

Not sure if I understand what you asked for but this returns true :

p json_1['created_at'] == stat_1.created_at

json_1 being the json created with the as_json method of stat_1. stat_1 is a mongoid entity I create at the beginning of the test.

@JonRowe

This comment has been minimized.

Show comment Hide comment
@JonRowe

JonRowe Sep 7, 2015

Member

Same for updated_at and gist how you're comparing json_1 with stat_1?

Member

JonRowe commented Sep 7, 2015

Same for updated_at and gist how you're comparing json_1 with stat_1?

@AdrienBD

This comment has been minimized.

Show comment Hide comment
@AdrienBD

AdrienBD Sep 7, 2015

Here is the gist with the prints in a before ... do block, both returning true : https://gist.github.com/AdrienBD/1eb993716eebad9a918b

AdrienBD commented Sep 7, 2015

Here is the gist with the prints in a before ... do block, both returning true : https://gist.github.com/AdrienBD/1eb993716eebad9a918b

@JonRowe

This comment has been minimized.

Show comment Hide comment
@JonRowe

JonRowe Sep 7, 2015

Member

I'd guess id is a string in one and a Bson::ObjectId in another...

Member

JonRowe commented Sep 7, 2015

I'd guess id is a string in one and a Bson::ObjectId in another...

@AdrienBD

This comment has been minimized.

Show comment Hide comment
@AdrienBD

AdrienBD Sep 7, 2015

No because the method is as follows :

def index_download_stats
    indexed_ids = []
    download_stats = Stat.downloads.not_indexed.all
    download_stats.each do |stat|
      json = stat.as_json(except: [:_id, :indexed])
      json['id'] = stat.id.to_s
      result = ElasticSearchUtils.index_stat :download, json
      indexed_ids << stat.id if result['created']
    end
    Stat.in(_id: indexed_ids).update_all indexed: true
  end

As you may see here, I give to the method ElasticSearchUtils.index_stat the json where I replaced the id with its string equivalent. In my test, I just want to make sure the method is called with the correct argument. Apparently it is called with different arguments but the message does not tell me what is different... If I had a string on one side and a Bson on the other, I would see it in the diff wouldn't I ?

AdrienBD commented Sep 7, 2015

No because the method is as follows :

def index_download_stats
    indexed_ids = []
    download_stats = Stat.downloads.not_indexed.all
    download_stats.each do |stat|
      json = stat.as_json(except: [:_id, :indexed])
      json['id'] = stat.id.to_s
      result = ElasticSearchUtils.index_stat :download, json
      indexed_ids << stat.id if result['created']
    end
    Stat.in(_id: indexed_ids).update_all indexed: true
  end

As you may see here, I give to the method ElasticSearchUtils.index_stat the json where I replaced the id with its string equivalent. In my test, I just want to make sure the method is called with the correct argument. Apparently it is called with different arguments but the message does not tell me what is different... If I had a string on one side and a Bson on the other, I would see it in the diff wouldn't I ?

@JonRowe

This comment has been minimized.

Show comment Hide comment
@JonRowe

JonRowe Sep 7, 2015

Member

If the diff is empty but they are not equal it's a symptom of something being printed to_s in the diff thats not in the object, time is the usual culprit but there are others.

Member

JonRowe commented Sep 7, 2015

If the diff is empty but they are not equal it's a symptom of something being printed to_s in the diff thats not in the object, time is the usual culprit but there are others.

@AdrienBD

This comment has been minimized.

Show comment Hide comment
@AdrienBD

AdrienBD Sep 7, 2015

Well if I fail to remove the Bson id from the Stat object in the test, I get an error but with an explicit diff that I can use :

RSpec::Mocks::MockExpectationError: ElasticSearchUtils received :index_stat with unexpected arguments
  expected: (:download, {"_id"=>BSON::ObjectId('55ed51324d4250818c000000'), "action"=>"download", "active"=>true, "created_at"=>Sat, 05 Sep 2015 10:56:18 CEST +02:00, "device_id"=>nil, "mobile_application_id"=>239, "mobile_application_update_id"=>342, "store_id"=>1282, "updated_at"=>Mon, 07 Sep 2015 10:56:18 CEST +02:00, "user_id"=>913, "version"=>1, "id"=>"55ed51324d4250818c000000"})
       got: (:download, {"action"=>"download", "active"=>true, "created_at"=>Sat, 05 Sep 2015 10:56:18 CEST +02:00, "device_id"=>nil, "mobile_application_id"=>239, "mobile_application_update_id"=>342, "store_id"=>1282, "updated_at"=>Mon, 07 Sep 2015 10:56:18 CEST +02:00, "user_id"=>913, "version"=>1, "id"=>"55ed51324d4250818c000000"})
Diff:
@@ -1,6 +1,5 @@
 [:download,
- {"_id"=>BSON::ObjectId('55ed51324d4250818c000000'),
-  "action"=>"download",
+ {"action"=>"download",
   "active"=>true,
   "created_at"=>Sat, 05 Sep 2015 10:56:18 CEST +02:00,
   "device_id"=>nil,

So I guess the culprit is not in the BSON id this time, no ?

AdrienBD commented Sep 7, 2015

Well if I fail to remove the Bson id from the Stat object in the test, I get an error but with an explicit diff that I can use :

RSpec::Mocks::MockExpectationError: ElasticSearchUtils received :index_stat with unexpected arguments
  expected: (:download, {"_id"=>BSON::ObjectId('55ed51324d4250818c000000'), "action"=>"download", "active"=>true, "created_at"=>Sat, 05 Sep 2015 10:56:18 CEST +02:00, "device_id"=>nil, "mobile_application_id"=>239, "mobile_application_update_id"=>342, "store_id"=>1282, "updated_at"=>Mon, 07 Sep 2015 10:56:18 CEST +02:00, "user_id"=>913, "version"=>1, "id"=>"55ed51324d4250818c000000"})
       got: (:download, {"action"=>"download", "active"=>true, "created_at"=>Sat, 05 Sep 2015 10:56:18 CEST +02:00, "device_id"=>nil, "mobile_application_id"=>239, "mobile_application_update_id"=>342, "store_id"=>1282, "updated_at"=>Mon, 07 Sep 2015 10:56:18 CEST +02:00, "user_id"=>913, "version"=>1, "id"=>"55ed51324d4250818c000000"})
Diff:
@@ -1,6 +1,5 @@
 [:download,
- {"_id"=>BSON::ObjectId('55ed51324d4250818c000000'),
-  "action"=>"download",
+ {"action"=>"download",
   "active"=>true,
   "created_at"=>Sat, 05 Sep 2015 10:56:18 CEST +02:00,
   "device_id"=>nil,

So I guess the culprit is not in the BSON id this time, no ?

@AdrienBD

This comment has been minimized.

Show comment Hide comment
@AdrienBD

AdrienBD Sep 7, 2015

I was thinking maybe the diff is not empty but is actually some white spaces but I have no idea what could create that and how to check that.

AdrienBD commented Sep 7, 2015

I was thinking maybe the diff is not empty but is actually some white spaces but I have no idea what could create that and how to check that.

@ryanwanger

This comment has been minimized.

Show comment Hide comment
@ryanwanger

ryanwanger Sep 10, 2015

Getting something similar at the moment...

`Failure/Error: expect(ExpandedCompany.find(@company.id)).to eq(@expanded_company)

   expected: #<Company:0x007fe6a1813be0 @id="company-1", @sf_id="", @name="Company 1", @created_at="", @modified_at="", @url="", @logo_url="", @status="", @brief_description="", @description="", @email="", @location={}, @full_time_employees=0, @angellist_url="", @twitter_url="", @crunchbase_url="", @sessions=[], @session_names=[], @programs=[], @roles=[], @funding=[{"round_amount"=>100}], @press=[], @jobs=[], @tags=[], @people=[]>
        got: #<Company:0x007fe6a1813be0 @id="company-1", @sf_id="", @name="Company 1", @created_at="", @modified_at="", @url="", @logo_url="", @status="", @brief_description="", @description="", @email="", @location={}, @full_time_employees=0, @angellist_url="", @twitter_url="", @crunchbase_url="", @sessions=[], @session_names=[], @programs=[], @roles=[], @funding=[{"round_amount"=>100}], @press=[], @jobs=[], @tags=[], @people=[]>

   (compared using ==)

   Diff:

`

Not sure why these objects are not == ?

Edit: I'm using SimpleDelegator, if that could be the issue.

Getting something similar at the moment...

`Failure/Error: expect(ExpandedCompany.find(@company.id)).to eq(@expanded_company)

   expected: #<Company:0x007fe6a1813be0 @id="company-1", @sf_id="", @name="Company 1", @created_at="", @modified_at="", @url="", @logo_url="", @status="", @brief_description="", @description="", @email="", @location={}, @full_time_employees=0, @angellist_url="", @twitter_url="", @crunchbase_url="", @sessions=[], @session_names=[], @programs=[], @roles=[], @funding=[{"round_amount"=>100}], @press=[], @jobs=[], @tags=[], @people=[]>
        got: #<Company:0x007fe6a1813be0 @id="company-1", @sf_id="", @name="Company 1", @created_at="", @modified_at="", @url="", @logo_url="", @status="", @brief_description="", @description="", @email="", @location={}, @full_time_employees=0, @angellist_url="", @twitter_url="", @crunchbase_url="", @sessions=[], @session_names=[], @programs=[], @roles=[], @funding=[{"round_amount"=>100}], @press=[], @jobs=[], @tags=[], @people=[]>

   (compared using ==)

   Diff:

`

Not sure why these objects are not == ?

Edit: I'm using SimpleDelegator, if that could be the issue.

@JonRowe

This comment has been minimized.

Show comment Hide comment
@JonRowe

JonRowe Sep 10, 2015

Member

@ryanwanger you have to specifically delegate == to the underlying object if you want active record like == behaviour, two different simple delegator instances won't eq each other but will print out an inspect string form the underlying object e.g.:

2.2.3 :001 > require 'delegate'
 => true
2.2.3 :002 > object = Object.new
 => #<Object:0x007fc8921de8b0>
2.2.3 :003 > klass = Class.new(SimpleDelegator)
 => #<Class:0x007fc89221c700>
2.2.3 :004 > klass.new(object) == klass.new(object)
 => false
2.2.3 :005 > klass.new(object).inspect
 => "#<Object:0x007fc8921de8b0>"
Member

JonRowe commented Sep 10, 2015

@ryanwanger you have to specifically delegate == to the underlying object if you want active record like == behaviour, two different simple delegator instances won't eq each other but will print out an inspect string form the underlying object e.g.:

2.2.3 :001 > require 'delegate'
 => true
2.2.3 :002 > object = Object.new
 => #<Object:0x007fc8921de8b0>
2.2.3 :003 > klass = Class.new(SimpleDelegator)
 => #<Class:0x007fc89221c700>
2.2.3 :004 > klass.new(object) == klass.new(object)
 => false
2.2.3 :005 > klass.new(object).inspect
 => "#<Object:0x007fc8921de8b0>"
@atz

This comment has been minimized.

Show comment Hide comment
@atz

atz Jun 10, 2017

It seems to depend on what is delegated:

> file = File.open('/etc/passwd')
 => #<File:/etc/passwd> 
> file == file
 => true 
> SimpleDelegator.new(1) == SimpleDelegator.new(1)
 => true 
> SimpleDelegator.new(file) == SimpleDelegator.new(file)
 => false 

This seems like a flaw in SimpleDelegator, since the internal objects themselves can tell you they are equivalent:

SimpleDelegator.new(file).__getobj__ == SimpleDelegator.new(file).__getobj__
 => true 

atz commented Jun 10, 2017

It seems to depend on what is delegated:

> file = File.open('/etc/passwd')
 => #<File:/etc/passwd> 
> file == file
 => true 
> SimpleDelegator.new(1) == SimpleDelegator.new(1)
 => true 
> SimpleDelegator.new(file) == SimpleDelegator.new(file)
 => false 

This seems like a flaw in SimpleDelegator, since the internal objects themselves can tell you they are equivalent:

SimpleDelegator.new(file).__getobj__ == SimpleDelegator.new(file).__getobj__
 => true 
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment