# sails-test-helper

Test helper suite for Sails.js using Mocha test framework.

## Dependencies

* [node-test-helper](https://github.com/zand3rs/node-test-helper)
* [mocha](https://github.com/mochajs/mocha)
* [chai](https://github.com/chaijs/chai)
* [sinon](https://github.com/cjohansen/Sinon.JS)
* [sinon-chai](https://github.com/domenic/sinon-chai)
* [supertest](https://github.com/visionmedia/supertest)
* [supertest-session](https://github.com/rjz/supertest-session)
* [sails-factory](https://github.com/zand3rs/sails-factory)


## Installation

```sh
# Local install
$ npm install sails-test-helper

# Global install
$ sudo npm install -g sails-test-helper
```

## Initialization

Copy test suite template to current directory.

```sh
# Local install
$ node_modules/.bin/sails-test-helper init

# Global install
$ sails-test-helper init
```

The following will be copied to the current working directory:

```
Makefile
test/
  factories/
  fixtures/
  helpers/
  unit/
```

## Writing Tests

### Controllers


```javascript
//-- test/unit/controllers/SampleController.test.js
require("sails-test-helper");

describe(TEST_NAME, function() {
  describe("GET index", function() {
    it("should be successful", function(done) {
      request.get("/sample")
        .expect(200)
        .end(done);
    });
  });
});
```


_Execute SampleController test_

```
$ make test

  controllers/SampleController
    GET index
      ✓ should be successful

  1 passing
```


### Models

```javascript
//-- test/unit/models/Sample.test.js
require("sails-test-helper");

describe(TEST_NAME, function() {
  describe(".create()", function() {
    it("should be successful", function(done) {
      Sample.create().exec(function(err, record) {
        expect(err).to.not.exist;
        expect(record).to.exist;
        done();
      });
    });
  });
});
```


_Execute Sample test_

```
$ make test

  models/Sample
    .create()
      ✓ should be successful 

  1 passing
```


## Test Execution

Tests are executed using **_make_** command. Basically the script will look for tests to be executed in **test/unit/** directory.

```sh
# Run all tests
$ make test

# Run tests under a specific directory
# This will run all tests under test/unit/controllers directory
$ make test controllers

# This will run tests under test/unit/controllers and test/unit/models directories
$ make test controllers models

# Run a specific test file
# This will run tests in test/unit/controllers/SampleController.test.js file
$ make test controllers/SampleController.test
```

### Mocha Options

Mocha options can be passed as parameter to **_make_**. By default, **_mocha_** is being executed using the ff. options:

```sh
# recursive with 30 second timeout using spec reporter
$ mocha --recursive -t 30000 -R spec
```

Use **MOCHA_OPTS** commandline variable to pass specific **_mocha_** options to **_make_**.

```sh
# Dot format without colors. Useful for test execution on CI servers such as Jenkins. 
$ make MOCHA_OPTS='-C -R dot' test
```



## Helpers

* TEST_NAME
* TEST_ROOT_PATH
* TEST_HELPERS_PATH
* TEST_FACTORIES_PATH
* TEST_FIXTURES_PATH
* requireHelper()
* [sinon](https://github.com/cjohansen/Sinon.JS)
* [stub()](https://github.com/cjohansen/Sinon.JS)
* [mock()](https://github.com/cjohansen/Sinon.JS)
* [chai](https://github.com/chaijs/chai)
* [expect()](https://github.com/chaijs/chai)
* [should](https://github.com/chaijs/chai)
* [request](https://github.com/rjz/supertest-session)
* [xhr](https://github.com/visionmedia/supertest)
* [factory](https://github.com/zand3rs/sails-factory)



## Custom Helpers

You can write your own test helpers or node modules and save it under **test/helpers/** directory. Use the built-in **requireHelper()** function to load your custom helper.

```javascript
//-- test/unit/services/SampleService.test.js
require("sails-test-helper");

describe(TEST_NAME, function() {
  it("should load my custom helper", function() {
    var my_helper = requireHelper("my_helper");
    expect(my_helper).to.exist;
  });
});
```

If you need to do some initialization prior to all your tests execution, you can put them inside **test/helpers/bootstrap.js** file. This file will be loaded automatically upon test execution.

```javascript
//-- test/helpers/bootstrap.js
//-- global variables can also be initialized here...

before(function(done) {
  //-- anything to run or initialize before running all tests...
  
  done();
});
```

## Factories

You can use the built-in **factory** module to define, build or create factories.

```javascript
//-- test/unit/controllers/SampleController.test.js
require("sails-test-helper");

describe(TEST_NAME, function() {
  before(function(done) {
    //-- define a factory
    factory.define("sample")
      .attr("id", 0, {auto_increment: true});

    //-- create a record
    factory.create("sample", function(sample) {
      done();
    });
  });
  
  describe("GET index", function() {
    before(function(done) {
      Sample.count(function(err, count) {
        expect(err).to.not.exist;
        expect(count).to.be.greaterThan(0);
        done();
      });
    });
    it("should be successful", function(done) {
      request.get("/sample")
        .expect(200)
        .end(done);
    });
  });
});
```

You can also load your factory definitions from **test/factories/** directory through your local bootstrap file.

```javascript
//-- test/helpers/bootstrap.js
before(function(done) {
  factory.load();
  done();
});
```

_Please see [sails-factory](https://github.com/zand3rs/sails-factory) for more details._
