Coder Social home page Coder Social logo

smithy-describe's Introduction

smithy:describe

Circle CI

A simple 'describe' like syntax for testing meteor packages with Tinytest. It also ships with sinon, chai and a couple of helper functions to ease your testing efforts.

Install

To install it in your own package, simply add it as a test dependency:

Package.onTest(function(api) {
  api.use('smithy:describe');
  // Add your test files
});

tinytest, ecmascript and underscore are already implied on smithy:describe so you can use them right away.

Usage

smithy:describe uses a syntax very similar to mocha, jasmine or even rspec. And it also bundles sinon and chai, which are commonly used with mocha. This allows you to define your tests using a syntax similar to the one describe above.

describe('Some Scenario', function() {
  describe('When some context is set', function() {
    before(function() {
      // runs before all tests (it functions)
    });

    after(function() {
      // runs after all tests (it functions)
    });

    beforeEach(function() {
      // runs before each test
    });

    afterEach(function() {
      // runs after each test
    });

    it('test 1', function() {
      // first test
      expect(1).to.equal(1);
    });

    it('test 2', function() {
      // second test
      expect(2).to.equal(2);
    });
  });
});

describe('Some Async Scenario', function() {
  describe('Async context', function() {
    before(function(done) {
      Meteor.setTimeout(() => {
        done();
      });
    });

    it('test async', function(done) {
      // async test (needs try/catch on every async block, or you can use catchable/promisify)
      Meteor.setTimeout(() => {
        catchable(done, () => {
          expect('async').to.equal('async');
          done();
        });
      });
    });
  });
});

Game Rules

Particularly when dealing with asynchronous tests, there are some rules you must follow in order to get results from your tests, either that they passed, or more importantly, why they failed. These rules apply to any of the test hooks or the tests itself, meaning before, after, beforeEach, afterEach and it.

So, the rule of thumb is basically: Every asynchronous block must call done() as the last statement, and done(exception) when an exception is raised.

try/catch

You can fulfill the previous rule using try/catch statements like in the example below, but don't worry, we provide some helpers to avoid this mess.

it('test async', function(done) { // *done* params lets smithy:describe know it's and async test.
  Meteor.call('Method1', (e, r) => {
    try {
      expect(r).to.equal(true);
      Meteor.call('Method2', (e, r) => {
        try {
          expect(r).to.be.ok;
          done();
        } catch (e) {
          done(e);
        }
      });
    } catch (e) {
      done(e);
    }
  });
});

catchable

Many try/catch statements could easily pollute and affect the readability of your tests, so a catchable function is provided to reduce some lines of code.

it('test async', function(done) { // *done* params lets smithy:describe know it's and async test.
  Meteor.call('Method1', (e, r) => {
    catchable(done, () => {
      expect(r).to.equal(true);
      Meteor.call('Method2', (e, r) => {
        catchable(done, () => {
          expect(r).to.be.ok;
          done();
        });
      });
    });
  });
});

promisify

promisify is a function that wraps an async function that expects a callback with error and result as parameters (like most Meteor functions) and returns a Promise, you can also create promises by your self if your use case doesn't apply for promisify.

it('test async', function(done) { // *done* params lets smithy:describe know it's and async test.
  promisify(Meteor.call, 'Method1').then((r) => {
    expect(r).to.equal(true);
    return promisify(Meteor.call, 'Method2');
  }).then((r) => {
    expect(r).to.be.ok;
    done();
  }).catch((e) => {
    done(e);
  });
});

Or, with ```Promise.all()``

it('test async', function(done) { // *done* params lets smithy:describe know it's and async test.
  Promise.all([promisify(Meteor.call, 'Method1'), promisify(Meteor.call, 'Method2')]).then((values) => {
    expect(values[0]).to.equal(true);
    expect(values[1]).to.be.ok;
    done()
  }).catch((e) => {
    done(e);
  });
});

Thanks

This package was heavily inspired by peterellisjones:describe.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.