jzgit / qunit-bdd

BDD-style testing for QUnit.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

qunit-bdd

BDD-style testing for QUnit.

describe('keys', function() {
  describe('.camelize', function() {
    it('camelizes top-level keys', function() {
      expect(camelize({ ohai_there: 'friend' })).to.eql({ ohaiThere: 'friend' });
    });

    it('camelizes nested keys', function() {
      expect(camelize({ foo_bar: { bar_baz: 'baz' } }))
        .to.eql({ fooBar: { barBaz: 'baz' } });
    });

    it('camelizes array objects', function() {
      expect(camelize([{ foo_bar: { bar_baz: 'baz' } }, { ohai_there: 'friend' }]))
        .to.eql([{ fooBar: { barBaz: 'baz' } }, { ohaiThere: 'friend' }]);
    });
  });
});

Installation

# Install via NPM.
$ npm install [--save-dev] qunit-bdd

# Install via Bower.
$ bower install [-D] qunit-bdd

# Install from Git.
$ git clone https://github.com/square/qunit-bdd.git
$ cp qunit-bdd/lib/qunit-bdd.js my-project/vendor/qunit-bdd.js

Usage

qunit-bdd has describe and context, just like Mocha and Jasmine. It also provides an assertion syntax similar to expect.js.

describe('Math', function() {
  describe('#pow', function() {
    it('raises the first argument to the power of the second argument', function() {
      expect(Math.pow(0, 6)).to.equal(0, '0**x == 0');
      expect(Math.pow(1, 99)).to.equal(1, '1**x == 1');
      expect(Math.pow(99, 0)).to.equal(1, 'x**0 == 1');
      expect(Math.pow(2, 3)).to.equal(8, 'positive exponent works');
      expect(Math.pow(4, -1)).to.equal(2, 'negative exponent works');
    });
  });
});

qunit-bdd also has before and after to run blocks of code before an after each test run within a context:

// This example uses sinon.js, not included with qunit-bdd.
describe('Profile Page', function() {
  before(function() {
    this.alertStub = sinon.stub(window, 'alert');
  });

  it('alerts on errors', function() {
    doSomethingToCauseAnError();
    expect(this.alertStub.calledWith('UH OH!')).to.be.true();
  });

  after(function() {
    this.alertStub.restore();
  });
});

Additionally, qunit-bdd ships with support for RSpec-style per-context let values, called lazy values in qunit-bdd. This is very useful when you want to declare how to set up a complex object in a top-level context, overriding parts of that setup in nested contexts:

describe('Person', function() {
  lazy('person', function() {
    return new Person({
      firstName: this.firstName,
      lastName: this.lastName,
      dob: this.dob,
      address: this.address
    });
  });

  lazy('address', function() {
    return {
      street1: this.street1,
      street2: this.street2,
      city: this.city,
      state: this.state,
      postal: this.postal
    };
  });

  // Defaults for dependent values could be put here (e.g. firstName, street1, etc).

  describe('#canVote', function() {
    context('when the person is not yet 18', function() {
      lazy('dob', function(){ return new Date(); });

      it('is false', function() {
        expect(this.person.canVote()).to.be.false();
      });
    });

    context('when the person is over 18', function() {
      lazy('dob', function(){ return new Date(0); });

      it('is true', function() {
        expect(this.person.canVote()).to.be.true();
      });
    });
  });
});

The benefit to this approach over setting up your test objects in before is that you can override parts of the built objects declaratively in nested contexts, something you might have used a bunch of helper functions to do with QUnit's default module/test functions.

Configuration

It's still QUnit, so you can write some tests using the module/test style, complete with the usual ok/equal/deepEqual assertions, if you find it more appropriate sometimes. Also, you can export as much or as little of qunit-bdd to the global scope as you like:

// Turn off `lazy` and `context` exports.
// Make sure to set this before loading qunit-bdd.js.
QUNIT_BDD_OPTIONS = {
  GLOBAL: {
    lazy: false,  // don't use lazy
    expect: false // use the regular QUnit assertions (or another set altogether)
  }
};

You can also configure which tests are run, which can aid in debugging. To skip a particular test (or context), use it.skip() instead of it() (or describe.skip() instead of describe()). To run only a particular test (or context), use it.only() instead of it (or describe.only() instead of describe()).

Expectations / Assertions

You can configure the built-in assertion expect() function to add your own custom assertions or override the built-in ones:

expect.configure({
  // expect(2).to.be.even();
  even: function() {
    QUnit.ok(this._actual % 2, 'expected ' + this._actual + ' to be even');
  }
});

Contributing

Setup

First, install the development dependencies:

$ npm install

You may need to install the grunt command-line utility:

$ [sudo] npm install -g grunt-cli

Then, try running the tests:

$ npm test

Development

As you make changes you may find it useful to have everything automatically compiled and ready to test interactively in the browser. You can do that using the develop grunt test:

$ grunt develop

Then go to http://localhost:8000/test in your browser (run with PORT={port} to override the default port).

Pull Requests

Contributions via pull requests are very welcome! Follow the steps in Developing above, then add your feature or bugfix with tests to cover it, push to a branch, and open a pull request.

Any contributors to the master qunit-bdd repository must sign the Individual Contributor License Agreement (CLA). It's a short form that covers our bases and makes sure you're eligible to contribute.

When you have a change you'd like to see in the master repository, send a pull request. Before we merge your request, we'll make sure you're in the list of people who have signed a CLA.

About

BDD-style testing for QUnit.

License:Other


Languages

Language:JavaScript 100.0%