stalniy/bdd-lazy-var

Need help getting the getter syntax to work in mocha

dkniffin opened this issue · 24 comments

Hey. I really like the idea of this library, and have been wanting something like it for a while. Unfortunately, I can't quite seem to get it working in the way I want.

I'd like to use the get. syntax with mocha. I'm using the -u bdd-lazy-var flag when running mocha. Is that the right way to do that? In the docs, I see different usage here, but I'm not sure where I'd put that in my app, since I'm not currently doing new Mocha() anywhere.

Hi,

If you want to use getter syntax you need to include it like this:

mocha -u bdd-lazy-var/getter

With that, I can get get('varname') to work, but not get.varname

That's really strange!

Could you please share your setup?

This is what I did:

// index.spec.js
const { expect } = require('chai')

describe('test', () => {
  def('value', () => 5)

  it('works', () => {
    expect(get.value).to.equal(5)
  })
})

and then

$ npm test

> test@1.0.0 test /home/sergii/projects/test
> mocha -u bdd-lazy-var/getter index.spec.js



  test
    ✓ works


  1 passing (6ms)

The configs for the app I'm trying to install this into is pretty complex, but let me see if I can boil it down to the basic parts:

  • I'm running yarn test, which maps to NODE_ENV=test mocha -u bdd-lazy-var/getter --require babel-core/register --opts 'support/mocha.opts' 'src/**/*.spec.*'
  • support/mocha.opts has the following:
--require support/addons.js
--require support/loaders.js
--require support/globals.js
  • support/addons.js has the following:
const chai = require('chai');
const chaiAsPromised = require('chai-as-promised');
const chaiImmutable = require('chai-immutable');
const chaiSorted = require('chai-sorted');
const Enzyme = require('enzyme');
const Adapter = require('enzyme-adapter-react-16');

chai.use(chaiAsPromised);
chai.use(chaiImmutable);
chai.use(chaiSorted);

Enzyme.configure({ adapter: new Adapter() });
  • support/loaders.js has the following:
const nullExtensions = ['.css', '.scss', '.sass', '.png', '.jpg', '.svg'];

nullExtensions.forEach(function(extension) {
  require.extensions[extension] = function() {};
});
  • support/globals.js has the following:
const chai = require('chai');
const faker = require('faker');
const enzyme = require('enzyme');
const sinon = require('sinon');
const fixtureFactory = require('./fixtures/factories');

global.expect = chai.expect;
global.faker = faker;
global.fixture = fixtureFactory;
global.sandbox = sinon.sandbox;
global.shallow = enzyme.shallow;
global.window = {
  location: {
    hostname: 'localhost'
  }
};
// NOTE: get and def come from the bdd-lazy-var library

Then, with a slightly modified version of your test above:

describe.only('test', () => {
  def('value', () => 5);

  it('works', () => {
    expect(get.value).to.equal(5);
  });
});

I get

> yt
yarn run v1.3.2
$ NODE_ENV=test mocha -u bdd-lazy-var/getter --require babel-core/register --opts 'support/mocha.opts' 'src/**/*.spec.*'


  test
    1) works


  0 passing (468ms)
  1 failing

  1) test
       works:
     AssertionError: expected undefined to equal 5
      at Context.<anonymous> (src/test.spec.js:5:26)



error Command failed with exit code 1.
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.

Created a repository to test things :) https://github.com/stalniy/bdd-lazy-var-test . Currently it works. Will try to add babel/register and loaders

@stalniy Awesome, thanks! Let me know how it goes

@stalniy I'm still investigating on my end, and I realized if I only run that one test, it works fine. Something else is messing with it.

maybe you already use some get variable and it overrides provided by bdd-lazy-var ?

added everything except of ./fixtures/factories and tests still works

Alright, I'm very confused now. I went through and commented out all of my other spec files, but it's still failing:

> yt
yarn run v1.3.2
$ NODE_ENV=test mocha -u bdd-lazy-var/getter --require babel-core/register --opts 'support/mocha.opts' 'src/**/*.spec.js'


  test
    1) works


  0 passing (41ms)
  1 failing

  1) test
       works:
     AssertionError: expected undefined to equal 5
      at Context.<anonymous> (src/test.spec.js:5:26)



error Command failed with exit code 1.
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.

Then if I just change it to run that single file (src/**/*.spec.js vs src/test.spec.js) it works:

> yt
yarn run v1.3.2
$ NODE_ENV=test mocha -u bdd-lazy-var/getter --require babel-core/register --opts 'support/mocha.opts' 'src/test.spec.js'


  test
    ✓ works


  1 passing (49ms)

✨  Done in 1.77s.

try to do this in your test:

describe.only('test', () => {
  def('value', () => 5);

  it('works', () => {
    console.log(get)
    console.log('value' in get)

    expect(get.value).to.equal(5);
  });
});

Failing version:

> yt
yarn run v1.3.2
$ NODE_ENV=test mocha -u bdd-lazy-var/getter --require babel-core/register --opts 'support/mocha.opts' 'src/**/*.spec.js'


  test
{ [Function: get$$1] variable: [Function], definitionOf: [Function] }
false
    1) works


  0 passing (49ms)
  1 failing

  1) test
       works:
     AssertionError: expected undefined to equal 5
      at Context.<anonymous> (src/test.spec.js:8:26)



error Command failed with exit code 1.
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.

Working version:

> yt
yarn run v1.3.2
$ NODE_ENV=test mocha -u bdd-lazy-var/getter --require babel-core/register --opts 'support/mocha.opts' 'src/test.spec.js'


  test
{ [Function: get$$1]
  variable: [Function],
  definitionOf: [Function],
  [Symbol(__lazyVars)]: { value: true } }
true
    ✓ works


  1 passing (51ms)

✨  Done in 2.65s.

ok, so the good news is that it uses the correct get function :) Now lets check whether in some other places you use require('bdd-lazy-var') (without /getter). Potentially it may override bdd-lazy-var/getter

Nope, a quick search doesn't show any other instances of bdd-lazy-var, other than the -u, and the package.json version and yarn.lock

Also, just as a sanity check, I made sure this spec is the only one with content:

> cat src/**/*.spec.js | grep -v '//' | grep -Ev "^$"
describe('test', function() {
  def('value', function() {
    return 5;
  });
  it('works', function() {
    console.log(get);
    expect(get.value).to.equal(5);
  });
});

Where does that functionality get set up in the library? I see get here: https://github.com/stalniy/bdd-lazy-var/blob/master/lib/interface.js#L6, but how do you manage putting the properties onto get.?

I see.
Another idea. Let's try to use 2 files with tests in that example repo. Maybe the issue is that the lib redefines itself if used for 2 files

I'm currently a bit busy. Can't test. But will try to look into it in few hours at home

Awesome. Thanks for your help on this! No rush

I set properties on get inside lib/interface/dialects/bdd_*_getter.js

There is a hook function, onDefine which is called each time def is called

This is a bug. Looks like nobody except of you tried to use getter dialect ;) Some time I used get('varName') and then switched to $varName.

Going to fix this soon!

the issue appears when you have 2 separate files with tests. Mocha defines ui interface for each tests file. My tests were not able to catch this error because I have only 1 file for tests :)

I was able to reproduce this issue in that example repo

Nice! Glad I could be helpful. 😄

Published 2.2.2 version. Now everything should work as expected

Thanks for the issue 👍