stalniy/bdd-lazy-var

Subject not defined correctly after "empty" context

iain-b opened this issue · 1 comments

I've been trying to upgrade to 2.1.2 from 1.3.1 and I'm encountering some issues.

If I do not define any variables in a context then subsequent sibling contexts do not have the subject defined correctly (they get the subject which was defined at the parent level, it seems.)

I'm happy to help out with a fix but I'd need some pointers to where I might look in the code.

  describe('testing', () => {
    const TestComponent = ({ numberOfRows, header }) => (
      <span>
        <h3>{header}</h3>
        {Array.from(Array(numberOfRows).keys()).map(n => <span className="row">{n}</span>)}
      </span>
    );

    // shallow is from from enzyme
    subject(() => shallow(<TestComponent {...get('props')} />));

    def('props', () => ({
      numberOfRows: get('numberOfRows'),
      header: get('header'),
    }));
    def('numberOfRows', 1);
    def('header', 'asdfasdf');

    context('the rows', () => {
      subject(() => subject().find('span.row'));

      // passes
      context('where there are now rows', () => {
        def('numberOfRows', 0);

        it('renders no rows', () => {
          expect(subject()).to.have.length(0);
        });
      });

      // passes
      context('where there are multiple rows 1', () => {
        def('numberOfRows', 3);

        it('renders multiple rows', () => {
          expect(subject()).to.have.length(3);
        });
      });

      // passes
      context('where there is one row ', () => {
        // def('numberOfRows', 1);
        // it seems the subject is not redefined with the correct parameters for _subsequent_
        // contexts unless there's a call to `def` here.
        // def('header', 'wut?')
        // def('asdfasdf', 'asdfasdf');


        it('renders the correct rows', () => {
          expect(subject()).to.have.length(1);
        });
      });

      // fails: expected ... to have a length of 3 but got 1
      context('where there are multiple rows 2', () => {
        // This fails unless there is some def in the above context.
        def('numberOfRows', 3);

        it('renders multiple rows', () => {
          expect(subject()).to.have.length(3);
        });
      });
    });
  });

Just will add some info here. In 1.x version I used built-in context inheritance in mocha. It allowed me to define variable in the root context and that variable becomes available for all nested scopes.

In version v2 I changed this. It was not easy to get access to context in jasmine and jest. That's why I was forced to implement own inheritance logic.

This logic is implemented in https://github.com/stalniy/bdd-lazy-var/blob/master/lib/suite_tracker.js trackSuite method.

SuiteTracker overrides describe function and collects information for all created suites. When suite tree is created then it creates parent to child relationship in linkParentToChildMetadataAndFlush

For suites which doesn't have defined variables it just copies parent metadata (sets metadata by reference) this is Metadata.setVirtual.

So this is the main logic hopefully it will help to understand where the issue is. I will try to look at this today if have time. If not - on Sunday.

Thanks for using lazy vars! :)