Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Strange behavior when comparing objects for equality #1145

Closed
emirotin opened this issue Mar 5, 2014 · 5 comments
Closed

Strange behavior when comparing objects for equality #1145

emirotin opened this issue Mar 5, 2014 · 5 comments

Comments

@emirotin
Copy link

emirotin commented Mar 5, 2014

Here's a sample repo https://github.com/emirotin/mocha-async-fail
There are 4 skipped tests, all built around testing objects equality (there's also 1 running test to demonstrate that there're not configuration errors).

All tests has 2 nested async calls with done() called from the inner.
Both tests use mongo-pool2 package which simply creates MongoDB connection and opens it (thus you need local mongo running on default port, or adjust the settings in the beginning of the file).

Now I "un-skip" tests 1 by 1 and see these results:

The test should not be ok - 1 compares 2 "plain" objects {} for equality inside of the 1st callback. This test properly fails, lists the failing test and shows the diff

Uncaught AssertionError: expected {} to be {}
                                         + expected - actual

This proves that mocha properly handles async exceptions.

The test should not be ok - 2 does the same, but inside the 2nd callback. Same proper result.
This proves that callbacks depth is not the problem per se.

The test should not be ok - 3 compares db connection object to "plain" object {} inside of the 1st callback. This test fails, test suite exits, but does not report which test failed:

  ․․․․

  1 passing (86ms)
  2 pending
  1 failing

  (end of output)

Finally, the test should not be ok - 4 compares two db objects inside of the 2nd callback. This test fails as well, but the suite never exits.

If it matters:
OS X 10.9
node version 0.10.26
mocha version 1.17.1
shouldjs version 3.1.3

@mrjoelkemp
Copy link
Contributor

Agreed. This is pretty strange. I managed to get your tests to work (fail and exit) by doing a console.log at the following locations marked with // LOGGING:

  it('should not be ok - 3', function (done) {
    mongoPool.connect(config, function(err, db1) {
      (!err).should.be.ok;
      (!!db1).should.be.ok;
      console.log('bar') // LOGGING
      // tests exit, but without error erporting
      (db1).should.be.equal({});
      mongoPool.connect(config, function(err, db2) {
        (!err).should.be.ok;
        (!!db2).should.be.ok;
        (db1).should.be.equal({});
        done();
      }, false);
    });
  });

  it('should not be ok - 4', function (done) {
    mongoPool.connect(config, function(err, db1) {
      (!err).should.be.ok;
      (!!db1).should.be.ok;
      mongoPool.connect(config, function(err, db2) {
        (!err).should.be.ok;
        console.log('foo') // LOGGING
        (!!db2).should.be.ok;
        // tests do not exit at all
        (db1).should.be.equal({});
        done();
      }, false);
    });
  });

It'll take me a bit longer to debug through this.

@mrjoelkemp
Copy link
Contributor

The cases below should be equivalent to your tests (without the use of mongo2-pool). These cases work as expected: failing and exiting. This leads me to believe that the problem is caused by mongo2-pool and not Mocha. Unless I'm missing something, I'd say this is a 'wontfix'.

  it('should not be ok - 3', function (done) {
    var db1 = {},
        err = null,
        db2 = {};

    setImmediate(function () {
      (!err).should.be.ok;
      (!!db1).should.be.ok;
      // tests exit, but without error erporting
      (db1).should.be.equal({});
      setImmediate(function () {
        (!err).should.be.ok;
        (!!db2).should.be.ok;
        (db1).should.be.equal({});
        done();
      });
    });
  });

  it('should not be ok - 4', function (done) {
    var db1 = {},
        err = null,
        db2 = {};

    setImmediate(function () {
      (!err).should.be.ok;
      (!!db1).should.be.ok;
      setImmediate(function () {
        (!err).should.be.ok;
        console.log('foo')
        (!!db2).should.be.ok;
        // tests do not exit at all
        (db1).should.be.equal({});
        done();
      });
    });
  });

@emirotin
Copy link
Author

emirotin commented Apr 4, 2014

Yes, this is not reproducible with simpler objects.
My guess was it may be related to deeply comparing too big objects, or may be because they have some circular references.

I think this is mocha issue, a here's why:

  • mongo-pool2 does not do anything extraordinary on its own and is battle-tested in production
  • even if mongo-pool2 is doing something wrong, it does not explain inconsistent behavior of mocha. I mean I just ask it to compare 2 objects of some nature, they are either equal or not, right? But it shows us 4 different behaviors.

@mrjoelkemp
Copy link
Contributor

My guess was it may be related to deeply comparing too big objects, or may be because they have some circular references.

Probably related to #1140.

@boneskull
Copy link
Contributor

please re-open if still issue

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants