stalniy/bdd-lazy-var

.only no longer works in bdd-lazy-var/rspec

dkreft opened this issue · 7 comments

Here's my basic test:

var expect = require('chai').expect

describe('.only is messed up', () => {
  def('thing', () => void 0)
  
  context('when thing is overridden', () => {
    def('thing', () => 1)
    
    it('works okay', () => expect($thing).to.equal(1))
  })

  context('another context', () => {
    def('thing', () => 2)
    
    it('works okay', () => expect($thing).to.equal(2))
  })
})

Which works fine as-is:

  .only is messed up
    when thing is overridden
      ✓ works okay
    another context
      ✓ works okay

But if I put an .only on the first it(), the .only is ignored and the whole suite runs:

  .only is messed up
    when thing is overridden
      ✓ this should be the only example we see
    another context
      ✓ works okay

If I move the .only to the first context, I see this:

Message:
    Cannot define "thing" variable twice in the same suite.
Stack:
Error: Cannot define "thing" variable twice in the same suite.
    at Object.lazyVar.register (/workplace/exm-admin-tool/node_modules/bdd-lazy-var/lib/lazy_var.js:39:13)
    at context.def (/workplace/exm-admin-tool/node_modules/bdd-lazy-var/lib/interface.js:116:13)
    at Suite.<anonymous> (/workplace/exm-admin-tool/test/lazy-var-test.js:7:5)
    at Object.create (/workplace/exm-admin-tool/node_modules/mocha/lib/interfaces/common.js:114:19)
    at Object.only (/workplace/exm-admin-tool/node_modules/mocha/lib/interfaces/common.js:79:21)
    at Function.context.describe.only (/workplace/exm-admin-tool/node_modules/mocha/lib/interfaces/bdd.js:68:27)
    at Suite.<anonymous> (/workplace/exm-admin-tool/test/lazy-var-test.js:6:11)
    at Object.suiteTracker.rspec (/workplace/exm-admin-tool/node_modules/bdd-lazy-var/lib/interface.js:52:16)
    at Suite.<anonymous> (/workplace/exm-admin-tool/node_modules/bdd-lazy-var/lib/interface.js:130:42)
    at Object.create (/workplace/exm-admin-tool/node_modules/mocha/lib/interfaces/common.js:114:19)
    at context.describe.context.context (/workplace/exm-admin-tool/node_modules/mocha/lib/interfaces/bdd.js:44:27)
    at context.(anonymous function) (/workplace/exm-admin-tool/node_modules/bdd-lazy-var/lib/interface.js:126:12)
    at Object.<anonymous> (/workplace/exm-admin-tool/test/lazy-var-test.js:3:1)
    at Module._compile (module.js:541:32)
    at loader (/workplace/exm-admin-tool/node_modules/babel-register/lib/node.js:144:5)
    at Object.require.extensions.(anonymous function) [as .js] (/workplace/exm-admin-tool/node_modules/babel-register/lib/node.js:154:7)

If I comment out the very first definition of thing (where I set it to void 0), the .only on the context is ignored:

  .only is messed up
    this context has an .only
      ✓ works okay
    another context
      ✓ works okay

Here are the versions I'm using:

$ mocha --version
2.3.4

$ node -v
v6.3.1

$ npm show bdd-lazy-var version
1.2.0

$ npm show chai version
3.5.0

Hi,

Thanks for the issue. I will take a look.

@dkreft this is what I tried to run in my tests:

  context('variables in ".only" suite', function() {
    def('thing', () => void 0)

    context('when thing is overridden', () => {
      def('thing', () => 1)

      it.only('works okay', () => expect(getVar('thing')).to.equal(1))
    })

    context('another context', () => {
      def('thing', () => 2)

      it('works okay', () => expect(getVar('thing')).to.equal(2))
    })
  });

With the same dependencies except of chai (I used 3.3.0) but it shouldn't impact the mocha's ui. And result is:

stse:~/projects/bdd-lazy-var$ ./node_modules/.bin/mocha --version
2.3.4
stse:~/projects/bdd-lazy-var$ node -v
v6.3.1
stse:~/projects/bdd-lazy-var$ cat package.json | grep version
  "version": "1.2.0",
stse:~/projects/bdd-lazy-var$ npm show chai version
3.5.0


stse:~/projects/bdd-lazy-var$ npm run test-mocha
> bdd-lazy-var@1.2.0 test-mocha-ui /Users/stse/projects/bdd-lazy-var
> npm run mocha -- -u index.js spec/interface_spec.js

  Lazy variables interface
    variables in ".only" suite
      when thing is overridden
        ✓ works okay


  1 passing (10ms)


> bdd-lazy-var@1.2.0 test-global-ui /Users/stse/projects/bdd-lazy-var
> npm run mocha -- -u global.js spec/global_defs_spec.js

  Interface with globally defined lazy vars
    variables in ".only" suite
      when thing is overridden
        ✓ works okay


  1 passing (11ms)


> bdd-lazy-var@1.2.0 test-getter-ui /Users/stse/projects/bdd-lazy-var
> npm run mocha -- -u getter.js spec/getter_defs_spec.js

  Lazy vars defined as getter on "get" function
    variables in ".only" suite
      when thing is overridden
        ✓ works okay


  1 passing (11ms)


> bdd-lazy-var@1.2.0 test-rspec-ui /Users/stse/projects/bdd-lazy-var
> npm run mocha -- -u rspec.js spec/rspec_defs_spec.js

  Interface with rspec suite tracker and globally defined vars
    variables in ".only" suite
      when thing is overridden
        ✓ works okay


  1 passing (10ms)

I don't see your error. The same if I put .only on describe. Maybe there is something else what cause this behavior?

@stalniy
I also run into that problem. I couldn't replicate it with @dkreft code but I prepared my own example which demonstrates the issue. @stalniy Let me know if you've managed to replicate it.
My environment:

  • mocha@3.2.0
  • bdd-lazy-var@1.2.0
  • Node v6.2.0

Works:

const {expect} = require('chai');

const roles = {
  SUPERADMIN: 1,
  USER: 0
};

describe('working', () => {
  subject(() => get('user').role === get('requiredRole'));

  def('user', () => ({role: get('role')}));

  context('when user is a USER', () => {
    def('role', () => roles.USER);

    context('when requires USER', () => {
      def('requiredRole', () => roles.USER);

      it('allows to access', () => {
        expect(subject()).to.eq(true);
      });
    });

    context('when requires SUPERADMIN', () => {
      def('requiredRole', () => roles.SUPERADMIN);

      it('forbids to access', () => {
        expect(subject()).to.eq(false);
      });
    });
  });
});
NODE_ENV=test node_modules/.bin/mocha test/working.js
  working
    when user is a USER
      when requires USER
        ✓ allows to access
      when requires SUPERADMIN
        ✓ forbids to access


  2 passing (9ms)

Does not work:

const {expect} = require('chai');

const roles = {
  SUPERADMIN: 1,
  USER: 0
};

describe.only('not working', () => {
  subject(() => get('user').role === get('requiredRole'));

  def('user', () => ({role: get('role')}));

  context('when user is a USER', () => {
    def('role', () => roles.USER);

    context('when requires USER', () => {
      def('requiredRole', () => roles.USER);

      it('allows to access', () => {
        expect(subject()).to.eq(true);
      });
    });

    context('when requires SUPERADMIN', () => {
      def('requiredRole', () => roles.SUPERADMIN);

      it('forbids to access', () => {
        expect(subject()).to.eq(false);
      });
    });
  });
});
NODE_ENV=test node_modules/.bin/mocha test/not-working.js
  not working
    when user is a USER
      when requires USER
         allows to access
      when requires SUPERADMIN
        1) forbids to access


  1 passing (15ms)
  1 failing

  1) not working when user is a USER when requires SUPERADMIN forbids to access:

      AssertionError: expected true to equal false
      + expected - actual

      -true
      +false

      at Context.it (test/not-working.js:28:30)

Thanks guys for additional details. Plan to fix this during the next few days

@mknapik @dkreft could you please guys check the latest master and let me know if it works ok for you? Published as 1.2.1

I will close this but feel free to reopen if the issue was not fully fixed :)

@stalniy Perfect, thanks!