Git Product home page Git Product logo

expect's Introduction

expect Travis npm package

Notice

This package has been donated to Jest. This means that all future development of expect v21+ will take place at facebook/jest.

You can use jest-codemods to automatically migrate your old tests using [email protected] to the new jest version of expect (>= 21)

Versions prior to v21 will receive limited support and bugfixes, and any future < v21 releases will be published on an npm tag that is not "latest", to avoid causing problems for v21+ users.

[email protected] documentation

expect lets you write better assertions.

When you use expect, you write assertions similarly to how you would say them, e.g. "I expect this value to be equal to 3" or "I expect this array to contain 3". When you write assertions in this way, you don't need to remember the order of actual and expected arguments to functions like assert.equal, which helps you write better tests.

You can think of expect as a more compact alternative to Chai or Sinon.JS, just without the pretty website. ;)

Installation

Using npm:

$ npm install --save expect

Then, use as you would anything else:

// using ES6 modules
import expect, { createSpy, spyOn, isSpy } from 'expect'

// using CommonJS modules
var expect = require('expect')
var createSpy = expect.createSpy
var spyOn = expect.spyOn
var isSpy = expect.isSpy

The UMD build is also available on unpkg:

<script src="https://unpkg.com/expect@%3C21/umd/expect.min.js"></script>

You can find the library on window.expect.

Assertions

toExist

expect(object).toExist([message])

Asserts the given object is truthy.

expect('something truthy').toExist()

Aliases:

  • toBeTruthy

toNotExist

expect(object).toNotExist([message])

Asserts the given object is falsy.

expect(null).toNotExist()

Aliases:

  • toBeFalsy

toBe

expect(object).toBe(value, [message])

Asserts that object is strictly equal to value using ===.

toNotBe

expect(object).toNotBe(value, [message])

Asserts that object is not strictly equal to value using ===.

toEqual

expect(object).toEqual(value, [message])

Asserts that the given object equals value using is-equal.

toNotEqual

expect(object).toNotEqual(value, [message])

Asserts that the given object is not equal to value using is-equal.

toThrow

expect(block).toThrow([error], [message])

Asserts that the given block throws an error. The error argument may be a constructor (to test using instanceof), or a string/RegExp to test against error.message.

expect(function () {
  throw new Error('boom!')
}).toThrow(/boom/)

toNotThrow

expect(block).toNotThrow([message])

Asserts that the given block does not throw.

toBeA(constructor)

expect(object).toBeA(constructor, [message])
expect(object).toBeAn(constructor, [message])

Asserts the given object is an instanceof constructor.

expect(new User).toBeA(User)
expect(new Asset).toBeAn(Asset)

Aliases:

  • toBeAn

toBeA(string)

expect(object).toBeA(string, [message])
expect(object).toBeAn(string, [message])

Asserts the typeof the given object is string.

expect(2).toBeA('number')

Aliases:

  • toBeAn

toNotBeA(constructor)

expect(object).toNotBeA(constructor, [message])
expect(object).toNotBeAn(constructor, [message])

Asserts the given object is not an instanceof constructor.

expect(new Asset).toNotBeA(User)
expect(new User).toNotBeAn(Asset)

Aliases:

  • toNotBeAn

toNotBeA(string)

expect(object).toNotBeA(string, [message])
expect(object).toNotBeAn(string, [message])

Asserts the typeof the given object is not string.

expect('a string').toNotBeA('number')
expect(2).toNotBeAn('object')

Aliases:

  • toNotBeAn

toMatch

expect(string).toMatch(pattern, [message])
expect(object).toMatch(pattern, [message])

Asserts the given string or object matches a pattern. When using a string, pattern must be a RegExp. When using an object, pattern may be anything acceptable to tmatch.

expect('a string').toMatch(/string/)
expect({
  statusCode: 200,
  headers: {
    server: 'nginx/1.6.5'
  }
}).toMatch({
  headers: {
    server: /nginx/
  }
})

toNotMatch

expect(string).toNotMatch(pattern, [message])
expect(object).toNotMatch(pattern, [message])

Asserts the given string or object does not match a pattern. When using a string, pattern must be a RegExp. When using an object, pattern may be anything acceptable to tmatch.

expect('a string').toMatch(/string/)
expect({
  statusCode: 200,
  headers: {
    server: 'nginx/1.6.5'
  }
}).toNotMatch({
  headers: {
    server: /apache/
  }
})

toBeLessThan

expect(number).toBeLessThan(value, [message])
expect(number).toBeFewerThan(value, [message])

Asserts the given number is less than value.

expect(2).toBeLessThan(3)

Aliases:

  • toBeFewerThan

toBeLessThanOrEqualTo

expect(number).toBeLessThanOrEqualTo(value, [message])

Asserts the given number is less than or equal to value.

expect(2).toBeLessThanOrEqualTo(3)

toBeGreaterThan

expect(number).toBeGreaterThan(value, [message])
expect(number).toBeMoreThan(value, [message])

Asserts the given number is greater than value.

expect(3).toBeGreaterThan(2)

Aliases:

  • toBeMoreThan

toBeGreaterThanOrEqualTo

expect(number).toBeGreaterThanOrEqualTo(value, [message])

Asserts the given number is greater than or equal to value.

expect(3).toBeGreaterThanOrEqualTo(2)

toInclude

expect(array).toInclude(value, [comparator], [message])
expect(object).toInclude(value, [comparator], [message])
expect(string).toInclude(value, [message])

Asserts that a given value is included (or "contained") within another. The actual value may be an array, object, or a string. The comparator function, if given, should compare two objects and return false if they are not equal. The default is to use isEqual.

expect([ 1, 2, 3 ]).toInclude(3)
expect({ a: 1, b: 2 }).toInclude({ b: 2 })
expect({ a: 1, b: 2, c: { d: 3 } }).toInclude({ b: 2, c: { d: 3 } })
expect('hello world').toInclude('world')

Aliases:

  • toContain

toExclude

expect(array).toExclude(value, [comparator], [message])
expect(object).toExclude(value, [comparator], [message])
expect(string).toExclude(value, [message])

Asserts that a given value is not included (or "contained") within another. The actual value may be an array, object, or a string. The comparator function, if given, should compare two objects and return false if they are not equal. The default is to use isEqual.

expect([ 1, 2, 3 ]).toExclude(4)
expect({ a: 1, b: 2 }).toExclude({ c: 2 })
expect({ a: 1, b: 2 }).toExclude({ b: 3 })
expect({ a: 1, b: 2, c: { d: 3 } }).toExclude({ c: { d: 4 } })
expect('hello world').toExclude('goodbye')

Aliases:

  • toNotContain
  • toNotInclude

toIncludeKey(s)

expect(object).toIncludeKeys(keys, [comparator], [message])
expect(object).toIncludeKey(key, [comparator], [message])

Asserts that the given object (may be an array, or a function, or anything with keys) contains all of the provided keys. The optional parameter comparator is a function which if given an object and a string key, it should return a boolean detailing whether or not the key exists in the object. By default, a shallow check with Object.prototype.hasOwnProperty is performed.

expect({ a: 1 }).toIncludeKey('a')
expect({ a: 1, b: 2 }).toIncludeKeys([ 'a', 'b' ])

Aliases:

  • toContainKey(s)

toExcludeKey(s)

expect(object).toExcludeKeys(keys, [comparator], [message])
expect(object).toExcludeKey(key, [comparator], [message])

Asserts that the given object (may be an array, or a function, or anything with keys) does not contain any of the provided keys. The optional parameter comparator is a function which if given an object and a string key, it should return a boolean detailing whether or not the key exists in the object. By default, a shallow check with Object.prototype.hasOwnProperty is performed.

expect({ a: 1 }).toExcludeKey('b')
expect({ a: 1, b: 2 }).toExcludeKeys([ 'c', 'd' ])

Aliases:

  • toNotContainKey(s)
  • toNotIncludeKey(s)

(spy) toHaveBeenCalled

expect(spy).toHaveBeenCalled([message])

Asserts the given spy function has been called at least once.

expect(spy).toHaveBeenCalled()

(spy) toNotHaveBeenCalled

expect(spy).toNotHaveBeenCalled([message])

Asserts the given spy function has not been called.

expect(spy).toNotHaveBeenCalled()

(spy) toHaveBeenCalledWith

expect(spy).toHaveBeenCalledWith(...args)

Asserts the given spy function has been called with the expected arguments.

expect(spy).toHaveBeenCalledWith('foo', 'bar')

Chaining Assertions

Every assertion returns an Expectation object, so you can chain assertions together.

expect(3.14)
  .toExist()
  .toBeLessThan(4)
  .toBeGreaterThan(3)

Spies

expect also includes the ability to create spy functions that can track the calls that are made to other functions and make various assertions based on the arguments and context that were used.

var video = {
  play: function () {},
  pause: function () {},
  rewind: function () {}
}

var spy = expect.spyOn(video, 'play')

video.play('some', 'args')

expect(spy.calls.length).toEqual(1)
expect(spy.calls[0].context).toBe(video)
expect(spy.calls[0].arguments).toEqual([ 'some', 'args' ])
expect(spy).toHaveBeenCalled()
expect(spy).toHaveBeenCalledWith('some', 'args')

spy.restore()
expect.restoreSpies()

createSpy

expect.createSpy([fn], [restore])

Creates a spy function with an (optional) implementation and (optional) restore logic. (In order for your provided implementation to be used, you must call andCallThrough.) For this reason, it's better to use andCall if you don't need custom restore logic.

var spy = expect.createSpy()

spyOn

expect.spyOn(target, method)

Replaces the method in target with a spy.

var video = {
  play: function () {}
}

var spy = expect.spyOn(video, 'play')
video.play()

spy.restore()

restoreSpies

expect.restoreSpies()

Restores all spies created with expect.spyOn(). This is the same as calling spy.restore() on all spies created.

// mocha.js example
beforeEach(function () {
  expect.spyOn(profile, 'load')
})

afterEach(function () {
  expect.restoreSpies()
})

it('works', function () {
  profile.load()
  expect(profile.load).toHaveBeenCalled()
})

Spy methods and properties

andCall

spy.andCall(fn)

Makes the spy invoke a function fn when called.

var dice = createSpy().andCall(function () {
  return (Math.random() * 6) | 0
})

andCallThrough

spy.andCallThrough()

Makes the spy call the original function it's spying on.

spyOn(profile, 'load').andCallThrough()

var getEmail = createSpy(function () {
  return "[email protected]"
}).andCallThrough()

andReturn

spy.andReturn(object)

Makes the spy return a value.

var dice = expect.createSpy().andReturn(3)

andThrow

spy.andThrow(error)

Makes the spy throw an error when called.

var failing = expect.createSpy()
  .andThrow(new Error('Not working'))

restore

spy.restore()

Restores a spy originally created with expect.spyOn().

reset

spy.reset()

Clears out all saved calls to the spy.

calls

spy.calls

An array of objects representing all saved calls to the spy.

You can use the length of the calls array to make assertions about how many times you expect the spy to have been called.

expect(spy.calls.length).toEqual(3)

You can also use the array to make assertions about each individual call. Each call object contains the following properties:

context

spy.calls[index].context

The this value of the call's execution context.

arguments

spy.calls[index].arguments

An array of the arguments passed to the spy for the particular call.

Extending expect

You can add your own assertions using expect.extend and expect.assert:

expect.extend({
  toBeAColor() {
    expect.assert(
      this.actual.match(/^#[a-fA-F0-9]{3,6}$/),
      'expected %s to be an HTML color',
      this.actual
    )
    return this
  }
})

expect('#ff00ff').toBeAColor()

Extensions

  • expect-element Adds assertions that are useful for DOM elements
  • expect-jsx Adds things like expect(ReactComponent).toEqualJSX(<TestComponent prop="yes" />)
  • expect-predicate Adds assertions based on arbitrary predicates
  • expect-enzyme Augments and extends expect to supercharge your enzyme assertions

expect's People

Contributors

ashtonsix avatar briangonzalez avatar calebmer avatar charca avatar codyreichert avatar danny-andrews avatar davidtheclark avatar elado avatar erikras avatar everson avatar evidens avatar granteagon avatar greenkeeperio-bot avatar jeffbski avatar knowbody avatar ljharb avatar mayankchd avatar mjackson avatar nason avatar nfcampos avatar npmcdn-to-unpkg-bot avatar psychollama avatar raydog avatar rodrigo-brito avatar rstacruz avatar skovhus avatar thomaslloyd avatar tryggvigy avatar wuct avatar xixixao avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

expect's Issues

Why include spies?

I am wondering what was the motivation to include test spies inside the library? Sinon.js already has a very good experience and API for spies, stubs, mocks.

I fear that what we will endup in expect is a somehow subset of sinon.js but less powerful.

What do you think? I would remove the test spy API. BTW Sinon.js is close to be working with ES6, master is currently working.

Default messages

Doing this:

expect(2).toEqual(3)

gets you this assertion error:

Error: 2 deepequal 3

Would you like expect to have better default assertion messages, like Expected 2 to equal 3?

Promise support

I am trying to test async(via Promise) redux actions using expect.

Here is what I would like to be able to do:

    loginPromise.then(
      () => {
        expect(dispatch)
          .toHaveBeenCalledWith({type: types.RECEIVE_TOKEN, token: payload});
      }
    );

Or, ideally:

loginPromise.eventually.someAssertion(args...);

//e.g.
loginPromise.eventually
  .toHaveBeenCalledWith({type: types.RECEIVE_TOKEN, token: payload});

Release notes?

Does expect publish release notes anywhere? A recent upgrade from 1.12.2 to 1.13.4 causes some of our tests to break, and I'd like to know exactly what changed in expect to see why. I can go through the commit log but was curious if there's a more "executive summary" source for what changes were included.

Note that we didn't explicitly upgrade - this problem was caused because we had expect listed as ^1.12.0 in our package.json, which caused implicit upgrades to anything in the 1.x series.

expect(null).toEqual(undefined) failing since 1.13.1

This was causing me some issues with rackt/history.

It looks like this test passed before 1.13.1 with deep-equals but fails with is-equal.

I don't know how you want this case to be handled, but since it's a minor version bump, I assume it wasn't intentional. Otherwise, feel free to close.

Expose `Expectation.prototype`

Ever since expect was refactored to ES6, Expectation is now not part of the public API. This means you can't write expect plugins anymore. expect-html-equal is one that's particularly affected by this change.

I'd love to see other plugins for expect to compare HTML (like expect-html-equal), make jQuery assertions (like chai-jquery), compare CSS colors (like chai-colors), compare numbers with a certain precision (like this), and so on.

Better error output for toHaveBeenCalledWith

First, great project! I'm sure you saw my tweet of praise:

https://twitter.com/ericclemmons/status/681615901343399936

toHaveBeenCalledWith

Anyway, having replaced sinon with this, I've noticed that this very readable call...

expect(this.say).toHaveBeenCalledWith("foo");

...yields an error with only half of the picture. There's no telling what it was called with, or never called at all:

Error: spy was never called with [ 'foo' ]

toEqual

However, explicitly using toEqual is much more useful:

expect(this.say.calls[0].arguments).toEqual(["foo"]);
[
-  "bar"
+  "foo"
]

Proposal

I'd recommend mimicking the output of toEqual.

When the spy was called & matched.

No changes.

(Patch) When the spy was never called.

"say" was never called

(Patch) Show all calls.

"name" was called N times without ["foo"]:

1 with ["bar"]

2 with [undefined]

...

(Breaking Feature) Expect the assertion to always reference the last call (e.g. spy.calls[spy.calls.length -1].

This is a suggestion for a possible future release that's largely unrelated to this issue.

"name" was last called with ["bar"], expected ["foo"].

What I like about this approach is that it works great for repeated assertions:

const query = function(params) {
  return axios.get("/api", { params });
};

var spy = expect.spyOn(axios, "get");

query({ foo: "foo" });
expect(spy).toHaveBeenCalledWith("/api", { foo: "foo" });
query({ bar: "bar" });
expect(spy).toHaveBeenCalledWith("/api", { bar: "bar" });

I only list it here because improving the usability of toHaveBeenCalledWith will lend itself to more use :)


What do you think @mjackson?

.toBeGreaterThanOrEqual()

It would be nice to have >= and <= assertions.

Also, this alias may be good: .toCompare('>=', 5) (dont know how to name it!)

Latest release of expect is breaking Redux build

Seems to be a problem with object key ordering.

    // This fails:
    expect(
      [
        {
          type: types.COMPLETE_TODO,
          id: 0
        }, {
          type: types.CLEAR_COMPLETED
        }, {
          type: types.ADD_TODO,
          text: 'Write more tests'
        }
      ].reduce(todos, [
        {
          id: 0,
          completed: false,
          text: 'Use Redux'
        }, {
          id: 1,
          completed: false,
          text: 'Write tests'
        }
      ])
    ).toEqual([
      {
        text: 'Write more tests',
        completed: false,
        id: 2
      }, {
        text: 'Write tests',
        completed: false,
        id: 1
      }
    ])

   // Changing the key order in the argument of `toEqual` as follows passes:
   expect(
      [
        {
          type: types.COMPLETE_TODO,
          id: 0
        }, {
          type: types.CLEAR_COMPLETED
        }, {
          type: types.ADD_TODO,
          text: 'Write more tests'
        }
      ].reduce(todos, [
        {
          id: 0,
          completed: false,
          text: 'Use Redux'
        }, {
          id: 1,
          completed: false,
          text: 'Write tests'
        }
      ])
    ).toEqual([
      {
        id: 2,
        completed: false,
        text: 'Write more tests'
      }, {
        id: 1,
        completed: false,
        text: 'Write tests'
      }
    ])

Could be due to this issue in the new is-equal library

(object) toInclude does not work as expected

According to the doc, (object) toInclude uses assert.deepEqual by default. I expect the following assertion should fail but it does not.

expect({ a: { b: 4 }}).toInclude({ a: {}})

Test for empty object

I have a class that should return an empty object for one of it's properties when it is initialized. How can I test for that?

This didn't work for me for obvious reasons:

const c = new MyClass()
// should return {emptyProp: {}}
expect(c.emptyProp).toBe({})

I don't want to have to bring lodash or something in as a dependency for this test if I don't have to, but I'm not sure how to solve it correctly.

Thanks!! This library is awesome!

Expect tests don't work with the ES6 / ES2015 Set object

Issue

The test below should fail, but it is passing:

it('should fail', () => {
  const actual = new Set('a');
  const expected = new Set('b');
  expect(actual).toEqual(expected);
});

expect-sets

Background & Question

I'm using the expect package from npm. I'm using Babel 5 to use Set. I'm using Node 5, so the Set being used should be native.
Am I doing something wrong, or does this look like a bug in the expect package in the way it handles Sets? I've cross posted a Stack Overflow question as I'm not sure.

p.s. I love this package and am happy I don't have to use Chai. Thank you for building it!

expect(<constructor>).toThrow(/some message/);

I'd like to use this pattern:

expect(MyClass).withArgs(1, 2, 3).toThrow(/Invalid arguments/);

But since you need to use the new keyword to properly call this constructor, it doesn't quite work out. Any ideas on how this can be solved?

Maybe a new keyword:

expect(MyClass).constructor().withArgs(1, 2, 3).toThrow(/Invalid arguments/);

.toBeA('array')

How about it? It would be nice to have a wrapper around expect(Array.isArray(list)).toEqual(true) (yuck).

For reference, chai.js has expect(list).to.be.a('array').

expect(...).toEqual(...) hangs if not equal

This happens when I'm using expect with redux-mock-store and redux-thunk so I'm not sure if this is something you guys can fix but I'll report it anyway. Feel free to close this issue if it can't be fixed here.

Here's an example: https://github.com/davidvuong/node-react-bp/blob/master/test/actions/ColoredSquareActionCreators-test.js#L17-L40

If you replace the body:

store.dispatch(actions.fetchColor()).then(() => {
  expect(store.getActions()).toEqual(expectedActions);
  done();
});

with

store.dispatch(actions.fetchColor()).then(() => {
  expect({}).toEqual([]);
  done();
});

I get an error saying that done is never called because the statement above it hangs (not sure for how longer but longer than the default timeout):

  1) ColoredSquareActionCreators should create async action when fetching color:
     Error: timeout of 2000ms exceeded. Ensure the done() callback is being called in this test.

Any ideas why?

.toBeGreaterThan(-1)

I am having issues with setting a cookie, and test if the cookie is set properly.
When I set a Cookie 'foo' with the value 'bar' and I check the test if it is created succesfully by the following condition:

document.cookie.indexOf('foo=bar')

It returns 0, since the cookie will be added at the beginning of the string. I see that that is correct by the following statement:

expect(document.cookie.indexOf('foo=bar')).toBeGreaterThan(0);

This ofcourse will throw an error (Error: Expected 0 to be greater than 0). Which is ok, but whenever I try to update this test, like so:

expect(document.cookie.indexOf('foo=bar')).toBeGreaterThan(-1);

It gives me a timeout error (Error: timeout of 2000ms exceeded). Could you please explain me, why that is?

expect(<instance function>) and automatically set context

Hi!

I'm not sure if this is actually possible, so just close it if it's not.

In #2 we got support for using .withArgs(...) and .withContext(...), which is awesome. When using instance methods, it would be nice if the context could be set automatically. For example, currently I have to write:

var myInstance = new MyClass();
expect(myInstance.myFunction).withContext(myInstance).withArgs(...).toThrow(/some error message/);

Is it possible to set the context from the method directly?

Add tmatch support to expect(object).toMatch

tmatch does a better job of deeply checking for a partial object in another.

Specifically with:

  • matching arrays and nested objects in arrays.
  • comparing dates
  • matching RegExp to a string

Should we change the code (as I PRed @ #80) to use it?

tmatch(
  {a: 1, b: 2, c: {d: 4, e: {f: 5, g: 6}, h: 7}, i: [{j: 8}, {k: 9, l: 10}], m: 'hello' },
  { b: 2, c: {d: 4, e: {g: 6}}, i:[ {j: 8}, {k: 9} ], m: /ll/ }
)

Use `prepublish` instead of `postinstall`

From npm docs:

Don't use install. Use a .gyp file for compilation, and prepublish for anything else. You should almost never have to explicitly set a preinstall or install script. If you are doing this, please consider if there is another option. The only valid use of install or preinstall scripts is for compilation which must be done on the target architecture.

It doesn't explicitly say 'postinstall', but it does recommend compilation by either .gyp or prepublish. Th current postinstall compile script is something that should be done on prepublish instead.

"scripts": {
  "prepublish": "npm run build"
}

edit: closing this and just making a PR

.toNotBeA

Is there a reason why .toBeA has no negated form?

Pretty much everything else has it

Add `reset` method to spy API

There doesn't appear to be a way to reset spies created with expect.createSpy(). It would basically need to just clear out the call array.

Confusing assertion message with different prototypes

Given a test:

  it("should give helpful messages", function() {
    function Foo() {this.x = 10;}
    let a = {x: 10};
    let b = new Foo();
    expect(a.constructor).toBe(Object);
    expect(b.constructor).toBe(Foo);
    expect(a).toEqual(b);
  });

the test fails (rightfully) on the last assertion, but the message gives you:

      Error: Expected { x: 10 } to equal { x: 10 }
      + expected - actual

which isn't helpful.

Shouldn't the message tell me that the objects compare as different because they have a different constructor?

expect(block).withArgs is undefined, which I produce the error even following example

it('should called withArgs', () => {
    expect(function (check) {
      if (check === 'bad') {
        throw new Error('boom!');
    }
    }).withArgs('bad').toThrow(/boom/);
  })

console always thorws
TypeError: _expect2.default(...).withArgs is not a function

and I tried type of expect(function (check) { if (check === 'bad') { throw new Error('boom!'); } })
I got this: { actual: [Function] }
which means expect(...).withArgs is undefined

Something wrong or Am I missing ?

Show object diffs in Mocha

Here's a comparison of how Chai and Expect handles object diffs. Notice how it's very readable with the diff being shown.

pasted_image_10_5_15__3_09_am

made using this code:

describe('object comparison', function () {
  it('via chai', function () {
    var expect = require('chai').expect
    expect({a:1,b:2,c:3}).to.eq({a:1,b:2,c:4})
  })

  it('via expect', function () {
    var expect = require('../index')
    expect({a:1,b:2,c:3}).toEqual({a:1,b:2,c:4})
  })
})

toEqual throws Range Error when objects with circular references are compared

  it('works when object has circular reference' , function () {
      function circular() {
        this.circularRef = this
      }
      var a = new circular()
      var b = new circular()
      expect(a).toEqual(b)
   })

Throws RangeError: Maximum call stack size exceeded . 

As this package uses deep-equal to check for equality , similar issue has been filed on deep-equal 8 months ago .

I think using deeper for checking for equality would be good as it works when objects with circular references are compared.
It passed all the tests along with circular reference one .

A way to restore all spies

It would be great if we can kill all spies in one go:

afterEach(function () {
  expect.restoreAllSpies();
});

This would be similar to sinon.js's sandbox functionality.

Expect function with arguments to throw error

Hi!

Really love this project, decided to use it for all my asserts/expectations in my unit tests. I'm quite new to it, though, so this issue might be misplaced. Let me know if this functionality already exists, but I couldn't find any.

There is one thing I'm lacking that I noticed existed in another expect framework (expect.js). It is this:
expect(fn).withArgs(invalid, arg).to.throwException();

Because currently, using this framework, I have to write:
expect(function () { myFunction(invalidArgument); }).toThrow(/some error message/);

It would be nice if you could write:
expect(myFunction).withArgs(invalidArgument).toThrow(/some error message/);

... or even (however, above is probably more clear):
expect(myFunction, invalidArgument).toThrow(/some error message/)

Create LICENSE file

Could you please create a LICENSE file and put your copyright information and the text of the MIT license in that file? The MIT license requires that the text of the license accompany the source code. Having a LICENSE file also helps people like myself who package modules for Linux distributions.

Failed at the [email protected] postinstall script 'node npm-scripts/postinstall.js'

I'm trying to npm install a project that have your package as dependecy under Windows 7 SP1 x64 ITA but something goes wrong

verbose stack Error: [email protected] postinstall: `node npm-scripts/postinstall.js`
65930 verbose stack Exit status 1
65930 verbose stack     at EventEmitter.<anonymous> (C:\Users\Piero\AppData\Roaming\npm\node_modules\npm\lib\utils\lifecycle.js:222:16)
65930 verbose stack     at emitTwo (events.js:87:13)
65930 verbose stack     at EventEmitter.emit (events.js:172:7)
65930 verbose stack     at ChildProcess.<anonymous> (C:\Users\Piero\AppData\Roaming\npm\node_modules\npm\lib\utils\spawn.js:24:14)
65930 verbose stack     at emitTwo (events.js:87:13)
65930 verbose stack     at ChildProcess.emit (events.js:172:7)
65930 verbose stack     at maybeClose (internal/child_process.js:818:16)
65930 verbose stack     at Process.ChildProcess._handle.onexit (internal/child_process.js:211:5)
65931 verbose pkgid [email protected]
65932 verbose cwd W:\react-redux-webpack-boilerplate-master
65933 error Windows_NT 6.1.7601
65934 error argv "C:\\Program Files\\nodejs\\node.exe" "C:\\Users\\Piero\\AppData\\Roaming\\npm\\node_modules\\npm\\bin\\npm-cli.js" "install"
65935 error node v4.1.2
65936 error npm  v3.3.7
65937 error code ELIFECYCLE
65938 error [email protected] postinstall: `node npm-scripts/postinstall.js`
65938 error Exit status 1
65939 error Failed at the [email protected] postinstall script 'node npm-scripts/postinstall.js'.
65939 error This is most likely a problem with the expect package,
65939 error not with npm itself.
65939 error Tell the author that this fails on your system:
65939 error     node npm-scripts/postinstall.js
65939 error You can get their info via:
65939 error     npm owner ls expect
65939 error There is likely additional logging output above.
65940 verbose exit [ 1, true ]



toEqual giving false positives when comparing objects in arrays

Hi there! I've been playing around with this for a bit and found out that toEqual returns false positives when comparing objects inside arrays.

Refer to the example below:

let arr1 = [
  {
    id: 0,
    text: 'Array Object 0',
    boo: false
  },
  {
    id: 1,
    text: 'Array Object 1',
    boo: false
  }
];

let arr2 = [
  {
    id: 0,
    text: 'Array Object 0',
    boo: true // value of boo is changed to true here
  },
  {
    id: 1,
    text: 'Array Object 1',
    boo: false
  }
];

expect(arr1).toEqual(arr2);

console.log('All tests passed.');

The above test pass just fine, I am not sure if it's an intended behaviour. Anyone else facing similar issues? Thanks! ๐Ÿ˜„

Don't assume name of node binary

Installing expect in a project on Debian or Ubuntu will fail because the node binary there is called nodejs not node, but the postinstall script in expect unconditionally tries to run node. Here is the output I got from a recent Ubuntu Xenial Docker:

npm ERR! argv "/usr/bin/nodejs" "/usr/bin/npm" "install"
npm ERR! node v4.2.4
npm ERR! npm  v3.5.2
npm ERR! file sh
npm ERR! code ELIFECYCLE
npm ERR! errno ENOENT
npm ERR! syscall spawn

npm ERR! [email protected] postinstall: `node ./npm-scripts/postinstall.js`
npm ERR! spawn ENOENT
npm ERR! 
npm ERR! Failed at the [email protected] postinstall script 'node ./npm-scripts/postinstall.js'.

It seems that npm exports a NODE variable since npm/npm@9c63b76 i.e. for ages now, so you could change that node to $NODE and should be good. Not sure that works on Windows, so please test there.

wrong expectation

Hey Michael,

I was wondering about your expect library. First I thought that I was using it when writing tests in mocha/chai. But apparently that is a different expect lib, right? The syntax looks slightly different.

Maybe it would be beneficial to clarify that in the top of the readme? Also to note that this expect lib fills some shortcomings, that you encountered with mocha/chai's expect.

Is there no need for sinon.js or chai anymore if one uses your expect?

I do understand the tag line "expect lets you write better assertions." I just do not understand the context; better than what?

Would be very nice if you had the time to clarify this!
Cheers

Send the error in the callback

Is there something like this?

expect(42).toBe(7, function (err) {
   /* do something with the error, but call this only if there is an error */
});

expect 1.15 breaks builds

expect 1.15 is not backwards compatible with old releases:

var expect = require('expect')
expect(3).toEqual(2)

/* TypeError: expect is not a function */

I suggest unpublishing 1.15.0, 1.15.1 and republishing them as 2.0.0 instead, or correcting this behavior.

Custom matchers

Hello, is there a way how to extend your library and write custom match functions? For comparison Jasmine supports it.

Object.assert [as default] Error

I think i found the problem because the message "Object.assert [as default]" is displayed on the console when i use this code

Subscription.create({email: emailAddress}).exec(function (error, email) {
      var expect = require('expect');

      if (error) {
        //you will expect the following
        //error to exist on error.Errors based on
        //your custom validation messages
        //return res.json(error);
        expect(error.invalidAttributes.email).toExist;

        expect(error.invalidAttributes.email[0].message).toEqual(Subscription.validationMessages.email.email);

        expect(error.invalidAttributes.email[1].message).toEqual(Subscription.validationMessages.email.required);
        done();
        return res.json(error);
      }

and see this in console


Error: Expected 'A record with that `email` already exists (`[email protected]`).' to equal 'Provide valid email address'
    at Object.assert [as default] (/var/www/nodejs/khayyam_computer/node_modules/expect/lib/assert.js:20:9)
    at Expectation.toEqual (/var/www/nodejs/khayyam_computer/node_modules/expect/lib/Expectation.js:69:26)
    at /var/www/nodejs/khayyam_computer/api/controllers/SiteController.js:81:58
    at wrapper (/var/www/nodejs/khayyam_computer/node_modules/lodash/index.js:3592:19)
    at applyInOriginalCtx (/var/www/nodejs/khayyam_computer/node_modules/sails/node_modules/waterline/lib/waterline/utils/normalize.js:417:80)
    at wrappedCallback (/var/www/nodejs/khayyam_computer/node_modules/sails/node_modules/waterline/lib/waterline/utils/normalize.js:331:16)
    at callback.error (/var/www/nodejs/khayyam_computer/node_modules/sails/node_modules/switchback/lib/normalize.js:42:31)
    at _switch (/var/www/nodejs/khayyam_computer/node_modules/sails/node_modules/switchback/lib/factory.js:56:28)
    at /var/www/nodejs/khayyam_computer/node_modules/sails/node_modules/waterline/lib/waterline/query/dql/create.js:223:14
    at wrapper (/var/www/nodejs/khayyam_computer/node_modules/lodash/index.js:3592:19)
    at applyInOriginalCtx (/var/www/nodejs/khayyam_computer/node_modules/sails/node_modules/waterline/lib/waterline/utils/normalize.js:417:80)
    at wrappedCallback (/var/www/nodejs/khayyam_computer/node_modules/sails/node_modules/waterline/lib/waterline/utils/normalize.js:331:16)
    at callback.error (/var/www/nodejs/khayyam_computer/node_modules/sails/node_modules/switchback/lib/normalize.js:42:31)
    at _switch (/var/www/nodejs/khayyam_computer/node_modules/sails/node_modules/switchback/lib/factory.js:56:28)
    at afterwards (/var/www/nodejs/khayyam_computer/node_modules/sails/node_modules/waterline/lib/waterline/adapter/dql.js:87:16)
    at wrapper (/var/www/nodejs/khayyam_computer/node_modules/lodash/index.js:3592:19)
    at applyInOriginalCtx (/var/www/nodejs/khayyam_computer/node_modules/sails/node_modules/waterline/lib/waterline/utils/normalize.js:417:80)
    at wrappedCallback (/var/www/nodejs/khayyam_computer/node_modules/sails/node_modules/waterline/lib/waterline/utils/normalize.js:331:16)
    at callback.error (/var/www/nodejs/khayyam_computer/node_modules/sails/node_modules/switchback/lib/normalize.js:42:31)
    at _switch (/var/www/nodejs/khayyam_computer/node_modules/sails/node_modules/switchback/lib/factory.js:56:28)
    at sendBackError (/var/www/nodejs/khayyam_computer/node_modules/sails-mysql/lib/connections/spawn.js:97:11)
    at Object.module.exports.poolfully [as releaseConnection] (/var/www/nodejs/khayyam_computer/node_modules/sails-mysql/lib/connections/release.js:28:12)

Process finished with exit code 1

Add a note about comparison with other libraries

There are other popular assertion libraries out there such as chai and expect.js. Perhaps there should be an explanation that compares expect to these libraries.

Personally, here's my take:

  1. I find the .toBeAn('object') neater than .to.be.an('object') since it enforces a one standard way of writing an assertion. I see people often write both expect().to.eq() and expect().eq() interchangeably, which are equivalent in those libraries.
  2. Since expect doesn't rely on Object.defineProperty getters, it is compatible with legacy IE versions.
  3. expect comes with built-in spies and mocking.

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.