enzymejs / chai-enzyme

Chai.js assertions and convenience functions for testing React Components with enzyme
MIT License
787 stars 72 forks source link

chai test negation `not.` doesnt work as expected #86

Open lloydntim opened 8 years ago

lloydntim commented 8 years ago

The not. chainable getter does not work within the assertion. E.g. `expect('faz').not.to.be('bar') fails the test.

ayrton commented 8 years ago

Can you please elaborate a bit more.

The following expectation seems to be valid:

expect('faz').not.to.eq('bar');
devboell commented 8 years ago

I think I ran into the same issue.

edit Have a look here for code that reproduces my error: https://github.com/devboell/chai-enzyme-error.git

The error seems to occur when chai-enzyme and dirty-chai work together with mocha in watch mode.

Please confirm if you can reproduce the error, even if chai-enzyme is not the cause.

thanks

ayrton commented 8 years ago

Can you edit your example to a complete reproducible bug. Both the component and tests without any cruft please, I can have a look at what might possibly be wrong then.

ayrton commented 8 years ago

I have tried to reproduce this issue with the following code:

class Fixture extends React.Component {
  render () {
    return (
      <div className='root' />
    )
  }
}

const it = createTest(<Fixture />)

describe('#className', () => {
  describe('(className)', () => {
    it('passes when the actual matches the expected', (wrapper) => {
      expect(wrapper).to.have.className('root')
      expect(wrapper).not.to.have.className('foo')
    })

    it('fails when the actual does not match the expected', (wrapper) => {
      expect(wrapper).not.to.have.className('root')
    });
  })
})

And this is the output:

$ NODE_ENV=test npme mocha test/className.test.js

  #className
    (className)
      ✓ (shallow): passes when the actual matches the expected
      ✓ (mount): passes when the actual matches the expected
      ✓ (render): passes when the actual matches the expected
      1) (shallow): fails when the actual does not match the expected
      2) (mount): fails when the actual does not match the expected
      3) (render): fails when the actual does not match the expected

  3 passing (467ms)
  3 failing

  1) #className (className) (shallow): fails when the actual does not match the expected:
     AssertionError: expected <Fixture /> not to have a 'root' class, but it has 'root'

     HTML:

     <div class="root"></div>
      at className.test.js:19:35
      at Context.<anonymous> (createTest.js:14:7)
      at callFn (/Users/adc/Developer/producthunt/chai-enzyme/node_modules/mocha/lib/runnable.js:315:21)
      at Test.Runnable.run (/Users/adc/Developer/producthunt/chai-enzyme/node_modules/mocha/lib/runnable.js:308:7)
      at Runner.runTest (/Users/adc/Developer/producthunt/chai-enzyme/node_modules/mocha/lib/runner.js:422:10)
      at /Users/adc/Developer/producthunt/chai-enzyme/node_modules/mocha/lib/runner.js:533:12
      at next (/Users/adc/Developer/producthunt/chai-enzyme/node_modules/mocha/lib/runner.js:342:14)
      at /Users/adc/Developer/producthunt/chai-enzyme/node_modules/mocha/lib/runner.js:352:7
      at next (/Users/adc/Developer/producthunt/chai-enzyme/node_modules/mocha/lib/runner.js:284:14)
      at Immediate._onImmediate (/Users/adc/Developer/producthunt/chai-enzyme/node_modules/mocha/lib/runner.js:320:5)
      at processImmediate [as _immediateCallback] (timers.js:383:17)

  2) #className (className) (mount): fails when the actual does not match the expected:
     AssertionError: expected <Fixture /> not to have a 'root' class, but it has 'root'

     HTML:

     <div data-reactroot="" class="root"></div>
      at className.test.js:19:35
      at Context.<anonymous> (createTest.js:20:7)
      at callFn (/Users/adc/Developer/producthunt/chai-enzyme/node_modules/mocha/lib/runnable.js:315:21)
      at Test.Runnable.run (/Users/adc/Developer/producthunt/chai-enzyme/node_modules/mocha/lib/runnable.js:308:7)
      at Runner.runTest (/Users/adc/Developer/producthunt/chai-enzyme/node_modules/mocha/lib/runner.js:422:10)
      at /Users/adc/Developer/producthunt/chai-enzyme/node_modules/mocha/lib/runner.js:533:12
      at next (/Users/adc/Developer/producthunt/chai-enzyme/node_modules/mocha/lib/runner.js:342:14)
      at /Users/adc/Developer/producthunt/chai-enzyme/node_modules/mocha/lib/runner.js:352:7
      at next (/Users/adc/Developer/producthunt/chai-enzyme/node_modules/mocha/lib/runner.js:284:14)
      at Immediate._onImmediate (/Users/adc/Developer/producthunt/chai-enzyme/node_modules/mocha/lib/runner.js:320:5)
      at processImmediate [as _immediateCallback] (timers.js:383:17)

  3) #className (className) (render): fails when the actual does not match the expected:
     AssertionError: expected the node in <??? /> not to have a 'root' class, but it has 'root'

     HTML:

     <div class="root"></div>
      at className.test.js:19:35
      at Context.<anonymous> (createTest.js:26:7)
      at callFn (/Users/adc/Developer/producthunt/chai-enzyme/node_modules/mocha/lib/runnable.js:315:21)
      at Test.Runnable.run (/Users/adc/Developer/producthunt/chai-enzyme/node_modules/mocha/lib/runnable.js:308:7)
      at Runner.runTest (/Users/adc/Developer/producthunt/chai-enzyme/node_modules/mocha/lib/runner.js:422:10)
      at /Users/adc/Developer/producthunt/chai-enzyme/node_modules/mocha/lib/runner.js:533:12
      at next (/Users/adc/Developer/producthunt/chai-enzyme/node_modules/mocha/lib/runner.js:342:14)
      at /Users/adc/Developer/producthunt/chai-enzyme/node_modules/mocha/lib/runner.js:352:7
      at next (/Users/adc/Developer/producthunt/chai-enzyme/node_modules/mocha/lib/runner.js:284:14)
      at Immediate._onImmediate (/Users/adc/Developer/producthunt/chai-enzyme/node_modules/mocha/lib/runner.js:320:5)
      at processImmediate [as _immediateCallback] (timers.js:383:17)

So I don't think this is a bug in chai-enzyme unless I'm missing something?

devboell commented 8 years ago

Hi there,

Indeed, I don't get the bug when I just use chai-enzyme, it only happens in combination with the dirty-chai lib. I think the repo I made demonstrates that (unless it is something particular to my machine)

It's not a show-stopper for me, I stopped using dirty-chai. Possibly it's interesting for you to find out how another library can cause this strange assertion behaviour on your lib.

I opened an issue on the dirty-chai repo as well, but haven't received a reply yet.

cheers

droarty commented 8 years ago

I ran into this with expect. Per your documentation I can test to see if .find() is finding anything. And it works just fine:

    expect(wrapper.find(".logo-area")).to.exist
    expect(wrapper.find(".logo-area").length).to.eq(1)
    expect(wrapper.find(".logo-area")).to.be.present

However, when I try to test for something that should not be there, it fails.

    expect(wrapper.find(".missing-class")).to.not.exist  // Fails
    expect(wrapper.find(".missing-class").length).to.not.eq(1)  // Passes
    expect(wrapper.find(".missing-class")).to.not.be.present   // Fails

I don't see the use of .not in the documentation but would have expected it to work. Or rather, it would be nice to make it work. Thanks.

ljharb commented 8 years ago

@droarty that's because not.to.exist only passes when the value is null or undefined. .find always returns a wrapper object.

The only thing you should be using there is expect(…).to.have.lengthOf(x) (and the inverse).

ayrton commented 8 years ago

@droarty that's right - this was also reported in #83, the offer still stands a PR to emphasise this behaviour is greatly appreciated. Thanks for explaining btw @ljharb

droarty commented 8 years ago

Thanks for the quick replies. I would offer to edit the documentation but I also have a question on the issue raised in PR #83 which I will address there.