stalniy / bdd-lazy-var

Provides UI for testing frameworks such as mocha, jasmine and jest which allows to define lazy variables and subjects.
MIT License
162 stars 14 forks source link

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

Closed dkreft closed 7 years ago

dkreft commented 7 years ago

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
stalniy commented 7 years ago

Hi,

Thanks for the issue. I will take a look.

stalniy commented 7 years ago

@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?

mknapik commented 7 years ago

@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:

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)
stalniy commented 7 years ago

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

stalniy commented 7 years ago

@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

stalniy commented 7 years ago

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

mknapik commented 7 years ago

@stalniy Perfect, thanks!