stalniy/bdd-lazy-var

Allow for describe-local shared examples

Closed this issue · 10 comments

Shared examples are global in 2.2.6. It would be nice to have them local to the describe block in which they are defined. Here is an example that should pass with local shared examples and does not pass with global shared examples:

describe('context 1', () => {
  sharedExamplesFor('a collection', () => {
    it('has three items', () => {
      expect($subject.size).to.equal(3);
    });

    describe('#has', () => {
      it('returns false with an an item that is not in the collection', () => {
        expect($subject.has(9)).to.be.false;
      });
    });
  });

  describe('Set', () => {
    subject(() => new Set([1, 2, 7]));

    itBehavesLike('a collection');
  });

  describe('Map', () => {
    subject(() => new Map([[2, 1], [7, 5], [3, 4]]));

    itBehavesLike('a collection');
  });
});

describe('context 2', () => {
  sharedExamplesFor('a collection', () => {
    it('has three items', () => {
      expect($subject.size).to.equal(3);
    });

    describe('#has', () => {
      it('returns true with an an item that is in the collection', () => {
        expect($subject.has(7)).to.be.true;
      });
    });
  });

  describe('Set', () => {
    subject(() => new Set([1, 2, 7]));

    itBehavesLike('a collection');
  });

  describe('Map', () => {
    subject(() => new Map([[2, 1], [7, 5], [3, 4]]));

    itBehavesLike('a collection');
  });
});

Hello,

Thanks for the issue. Just want to clarify:

Why don't you seperate sharedExamplesFor('a collection') with additional words, like:

sharedExamplesFor('a general collection') and sharedExamplesFor('a specific type collection')?

Hi @stalniy

Simple: If a project grows big, a global namespace like it is currently used for the shared examples gets cluttered. In our project, we have several modules that do some important logging and in the tests of each module, I have a shared example "invokes the logger". However, the tests inside these shared examples differ across the modules. Of course, I could simply change the name as you suggested, but this does not make the test more readable.

RSpec for Ruby solves that problem like this:

  • If a shared_examples block is not inside any describe or context block, it is global and therefore you can use the shared examples in every test and you need to be careful with the naming of the shared examples.
  • If a shared_examples block is inside a describe or context block, it is accessible only inside of this block. You can have a big test file with local shared examples and do not need to worry about cluttering a global namespace.

makes sense :) I will try to look into this tomorrow

Hi @eugenk

Could you please check the latest master? If all works for you, I will publish a new version tomorrow.

Now sharedExamples is just a special type of lazy variables, so there shouldn't be any issues with them

Unfortunately, this doesn't work. I'm using the code snippet of the initial post of this issue and I'm getting this error:

TypeError: Cannot read property 'getVar' of undefined
    at Variable.value (/path/to/the/project/node_modules/bdd-lazy-var/global.js:225:34)
    at Function.evaluate (/path/to/the/project/node_modules/bdd-lazy-var/global.js:202:25)
    at get (/path/to/the/project/node_modules/bdd-lazy-var/global.js:262:23)
    at includeExamplesFor (/path/to/the/project/node_modules/bdd-lazy-var/global.js:321:22)
    at Suite.<anonymous> (/path/to/the/project/node_modules/bdd-lazy-var/global.js:340:28)
    at SuiteTracker.execute (/path/to/the/project/node_modules/bdd-lazy-var/global.js:407:19)
    at SuiteTracker.trackSuite (/path/to/the/project/node_modules/bdd-lazy-var/global.js:396:12)
    at Suite.defineSuite (/path/to/the/project/node_modules/bdd-lazy-var/global.js:387:19)
    at Object.create (/path/to/the/project/node_modules/mocha/lib/interfaces/common.js:112:19)
    at context.describe.context.context (/path/to/the/project/node_modules/mocha/lib/interfaces/bdd.js:40:27)
    at detectSuite (/path/to/the/project/node_modules/bdd-lazy-var/global.js:382:25)
    at itBehavesLike (/path/to/the/project/node_modules/bdd-lazy-var/global.js:339:16)
    at Suite.describe (/path/to/the/project/test/unit/lib/notification-helper.spec.js:40:5)
    at SuiteTracker.execute (/path/to/the/project/node_modules/bdd-lazy-var/global.js:407:19)
    at SuiteTracker.trackSuite (/path/to/the/project/node_modules/bdd-lazy-var/global.js:396:12)
    at Suite.defineSuite (/path/to/the/project/node_modules/bdd-lazy-var/global.js:387:19)
    at Object.create (/path/to/the/project/node_modules/mocha/lib/interfaces/common.js:112:19)
    at context.describe.context.context (/path/to/the/project/node_modules/mocha/lib/interfaces/bdd.js:40:27)
    at detectSuite (/path/to/the/project/node_modules/bdd-lazy-var/global.js:382:25)
    at Suite.describe (/path/to/the/project/test/unit/lib/notification-helper.spec.js:37:3)
    at SuiteTracker.execute (/path/to/the/project/node_modules/bdd-lazy-var/global.js:407:19)
    at SuiteTracker.trackSuite (/path/to/the/project/node_modules/bdd-lazy-var/global.js:396:12)
    at Suite.defineSuite (/path/to/the/project/node_modules/bdd-lazy-var/global.js:387:19)
    at Object.create (/path/to/the/project/node_modules/mocha/lib/interfaces/common.js:112:19)
    at context.describe.context.context (/path/to/the/project/node_modules/mocha/lib/interfaces/bdd.js:40:27)
    at detectSuite (/path/to/the/project/node_modules/bdd-lazy-var/global.js:382:25)
    at Object.<anonymous> (/path/to/the/project/test/unit/lib/notification-helper.spec.js:24:1)
    at Module._compile (module.js:652:30)
    at Object.Module._extensions..js (module.js:663:10)
    at Module.load (module.js:565:32)
    at tryModuleLoad (module.js:505:12)
    at Function.Module._load (module.js:497:3)
    at Module.require (module.js:596:17)
    at require (internal/module.js:11:18)
    at /path/to/the/project/node_modules/mocha/lib/mocha.js:250:27
    at Array.forEach (<anonymous>)
    at Mocha.loadFiles (/path/to/the/project/node_modules/mocha/lib/mocha.js:247:14)
    at Mocha.run (/path/to/the/project/node_modules/mocha/lib/mocha.js:576:10)
    at Object.<anonymous> (/path/to/the/project/node_modules/mocha/bin/_mocha:637:18)
    at Module._compile (module.js:649:14)
    at Object.Module._extensions..js (module.js:663:10)
    at Module.load (module.js:565:32)
    at tryModuleLoad (module.js:505:12)
    at Function.Module._load (module.js:497:3)
    at Function.Module.runMain (module.js:693:10)
    at startup (bootstrap_node.js:188:16)
    at bootstrap_node.js:609:3

I see. Will check this tomorrow

implemented in bdd-lazy-var@2.3.0

Let me know if it works as expected for you.

I added tests for this case. Also the example you provided works fine

I'm on 2.4.0 now and it works as expected. Thanks!

Cool! You are welcome :)