Skip to content

🦍 (WIP v0.5 and v1) Delightful & pluggable test runner, ES2017 ready! Working on and targeting Node.js v0.10. Try `asia@next`

License

Notifications You must be signed in to change notification settings

tunnckoCore/mukla

Repository files navigation

mukla NPM version mit license NPM monthly downloads npm total downloads

Small, parallel and fast test framework with suppport for async/await, promises, callbacks, streams and observables. Targets and works at node.js v0.10 and above.

code climate code style linux build windows build code coverage dependency status paypal donate

Hightlights

  • Extremely lightweight and fast
  • Small to download and install
  • No implicit globals,
  • No CLI, use plain node test.js
  • Powered by always-done
  • And so supports async/await, promises, observables streams and callbacks
  • Enforces writing atomic tests
  • Simple test syntax - just a single test() function
  • Works seamlessly with istanbul for code coverage
  • Stops after first failing test (also known as "fail fast" or "bail")
  • Built-in core-assert assertion library
  • Targets and works at node.js v0.10 and above
  • No need for build/transpilation/compilation step
  • Backward-compatible with assertit and so testit
  • Easy to porting of mocha-style tests
  • Clean stack traces by default, using stacktrace-metadata
  • Custom reporters, one built-in

Table of Contents

(TOC generated by verb using markdown-toc)

Install

Install with npm

$ npm install mukla --save

or install using yarn

$ yarn add mukla

Usage

For more use-cases see the tests

Write tests in ES2015

import fs from 'fs'
import test from 'mukla'

test(done => {
  test.deepEqual([1, 2], [1, 2]) // passing
  done()
})

// or without `done`, returning Promise
// stream, observerable and so on
test(() => {
  return fs.createReadStream('not exist') // failing test
})

The old way

var fs = require('fs')
var test = require('mukla')

test(function (done) {
  test.deepEqual([1, 2], [1, 2]) // passing
  done()
})

// or without `done`, returning Promise
// stream, observerable and so on
test(function () {
  return fs.createReadStream('not exists') // failing
})

API

Runs fn test and outputs the name of the test. If only function is given and it is anonymous, the name of the test is anonymous, otherwise the name of the fn function.

Params

  • name {String|Function}: the title of the test or fn
  • [fn] {Function}: test function, wrapped in always-done
  • showStack {Boolean}: if boolean true, will print stack when has error

Example

var test = require('mukla')

// failing regular callbacks test
test('title of test', function (done) {
  test.strictEqual(1, 2)
  done()
})

// passing test with anonymous title
test(function (done) {
  test.strictEqual(222, 222)
  done()
})

Supports

Handles completion and errors of async/await, synchronous and asynchronous (callback) functions, also tests that returns streams, promises, child process and observables.

Async/await function support

var test = require('mukla')

test('passing modern test', async function () {
  return await Promise.resolve('foobar')
})

back to top

Promise support

Returning a resolved Promise

var test = require('mukla')

test('passing promise test', function () {
  return Promise.resolve(12345)
})

Returning a rejected Promise

var test = require('mukla')

test('failing test with promise', function () {
  return Promise.reject(new Error('foo bar'))
})

back to top

Observable support

Using .subscribe method of the observable

Empty observable

var test = require('mukla')
var Observable = require('rx').Observable

test('passing test with empty observable', function () {
  return Observable.empty()
})

Successful test wtih observable

var test = require('mukla')
var Observable = require('rx').Observable

alwaysDone(function () {
  return Observable.return([1, 2, 3])
})

Failing observable

var test = require('mukla')
var Observable = require('rx').Observable

test(function () {
  return Observable.throw(new Error('observable error'))
})

back to top

Regular callbacks support

var test = require('mukla')
var fs = require('fs')

test('some callback test', function (done) {
  fs.readFile('./package.json', 'utf8', function (err, res) {
    test.strictEqual(err, null)
    test.strictEqual(typeof res, 'string')
    test.strictEqual(res.length > 0, true)
    done()
  })
})

back to top

Synchronous functions support

Passing sync test

var fs = require('fs')
var test = require('mukla')

test(function () {
  var res = fs.readFileSync('./package.json')
  test.strictEqual(typeof res, 'string')
})

Failing test with title

var test = require('mukla')

test('some failing test', function () {
  JSON.parse('{Sjkfsf:"dfgfg')
})

back to top

Support functions that returns streams

Handles completion of tests using on-stream-end and stream-exhaust, behind the scenes, using always-done

Passing test with unpiped streams

var fs = require('fs')
var test = require('mukla')

test(function () {
  return fs.createReadStream('./package.json')
})

Failing test unpiped streams

var fs = require('fs')
var test = require('mukla')

test('failing stream test', function () {
  return fs.createReadStream('foo bar')
})

Failing test with piped streams

var fs = require('fs')
var test = require('mukla')
var through2 = require('through2')

test(function () {
  var read = fs.createReadStream('foo bar')
  return read.pipe(through2())
})

back to top

Support functions that returns Child Process

Basically, they are streams, so completion is handled using on-stream-end which is drop-in replacement for end-of-stream

Successful exec

var test = require('mukla')
var cp = require('child_process')
var isChildProcess = require('is-child-process')

test('returning child processes', function () {
  var proc = cp.exec('echo hello world')
  test.strictEqual(isChildProcess(proc), true)
  return proc
})

Failing exec

var test = require('mukla')
var cp = require('child_process')

test('should be failing exec test', function () {
  return cp.exec('foo-bar-baz sasa')
})

Failing spawn

var test = require('mukla')
var cp = require('child_process')

test('failing child process spawn test', function () {
  return cp.spawn('foo-bar-baz', ['hello world'])
})

back to top

Handles any errors

uncaught exceptions

var test = require('mukla')

test('should be failing test with ReferenceError', function () {
  foo // ReferenceError
  return 55
})

if test throws

var test = require('mukla')

test('failing test with SyntaxError', function () {
  JSON.parse('{"foo":')
})

back to top

Related

  • always-done: Handle completion and errors with elegance! Support for streams, callbacks, promises, child processes, async/await and sync functions. A drop-in replacement… more | homepage
  • core-assert: Node.js assert as a standalone module | homepage
  • each-promise: Iterate over promises, promise-returning or async/await functions in series or parallel. Support settle (fail-fast), concurrency (limiting) and hooks system (start… more | homepage
  • gruu: Modern, small and powerful testing with TAP output and support for async/await, promises, callbacks, streams and observables, built on always-done. | homepage
  • minibase-is-registered: Plugin for minibase and base, that adds isRegistered method to your application to detect if plugin is already registered and… more | homepage
  • minibase: Minimalist alternative for Base. Build complex APIs with small units called plugins. Works well with most of the already existing… more | homepage
  • try-catch-core: Low-level package to handle completion and errors of sync or asynchronous functions, using once and dezalgo libs. Useful for and… more | homepage

Contributing

Pull requests and stars are always welcome. For bugs and feature requests, please create an issue.
Please read the contributing guidelines for advice on opening issues, pull requests, and coding standards.
If you need some help and can spent some cash, feel free to contact me at CodeMentor.io too.

In short: If you want to contribute to that project, please follow these things

  1. Please DO NOT edit README.md, CHANGELOG.md and .verb.md files. See "Building docs" section.
  2. Ensure anything is okey by installing the dependencies and run the tests. See "Running tests" section.
  3. Always use npm run commit to commit changes instead of git commit, because it is interactive and user-friendly. It uses commitizen behind the scenes, which follows Conventional Changelog idealogy.
  4. Do NOT bump the version in package.json. For that we use npm run release, which is standard-version and follows Conventional Changelog idealogy.

Thanks a lot! :)

Building docs

Documentation and that readme is generated using verb-generate-readme, which is a verb generator, so you need to install both of them and then run verb command like that

$ npm install verbose/verb#dev verb-generate-readme --global && verb

Please don't edit the README directly. Any changes to the readme must be made in .verb.md.

Running tests

Clone repository and run the following in that cloned directory

$ npm install && npm test

Author

Charlike Mike Reagent

License

Copyright © 2015, 2017, Charlike Mike Reagent. Released under the MIT License.


This file was generated by verb-generate-readme, v0.4.3, on March 17, 2017.
Project scaffolded using charlike cli.