UNPKG

must

Version:

Testing and assertion library with friendly BDD syntax — awesome.must.be.true(). Many expressive matchers and is test runner and framework agnostic. Follows RFC 2119 with its use of MUST. Good and well tested stuff.

768 lines (629 loc) 25.4 kB
var _ = require("lodash") var O = require("oolong") var Must = require("../..") var assert = require("./assert") describe("Must.prototype.eql", function() { // Allow using new Boolean, String, Number: /* jshint -W053 */ /* eslint no-new-wrappers: 0 */ function eql(a, b) { Must(a).be.eql(b) } testNull(eql) testBoolean(eql) testNumber(eql) testString(eql) testSymbol(eql) testRegExp(eql) testDate(eql) testFunction(eql) it("must fail given an empty array and empty object", function() { // Can't think of an assertion library that would be nuts enough to consider // {} equivalent to []. Oh yeah, I can! For fucks sake, this is reason #42 // why Must.js is better! assert.fail(function() { Must({}).be.eql([]) }) assert.fail(function() { Must([]).be.eql({}) }) }) describe("given Array", function() { it("must pass given equivalent empty arrays", function() { assert.pass(function() { Must([]).be.eql([]) }) }) it("must pass given empty array and Array.prototype", function() { assert.pass(function() { Must([]).be.eql(Array.prototype) }) }) it("must pass given equivalent arrays", function() { assert.pass(function() { Must([1]).be.eql([1]) }) }) it("must pass given identical arrays", function() { var array = [] assert.pass(function() { Must(array).be.eql(array) }) }) it("must fail given an empty and non-empty array", function() { assert.fail(function() { Must([]).be.eql([1]) }) assert.fail(function() { Must([1]).be.eql([]) }) }) it("must fail given a smaller and a larger array", function() { assert.fail(function() { Must([1]).be.eql([1, 2]) }) assert.fail(function() { Must([1, 2]).be.eql([1]) }) }) it("must pass given equivalent nested arrays", function() { assert.pass(function() { Must([1, [2], 3]).be.eql([1, [2], 3]) }) }) it("must fail given unequivalent nested arrays", function() { assert.fail(function() { Must([1, [2], 3]).be.eql([1, [42], 3]) }) }) describe("with circular references", function() { it("must pass if equivalent", function() { var a = [1, 2, 3] a.push(a) a.push(5) var b = [1, 2, 3] b.push(b) b.push(5) assert.pass(function() { Must(a).be.eql(b) }) }) it("must fail if only one circular", function() { var a = [1, 2, 3] a.push(a) a.push(5) var b = [1, 2, 3, [1, 2, 3, 5], 5] assert.fail(function() { Must(a).be.eql(b) }) assert.fail(function() { Must(b).be.eql(a) }) }) it("must fail if circular to different levels", function() { var a = [1, 2, 3] a.push(a) var b = [1, 2, 3] var bInside = [1, 2, 3] bInside.push(bInside) b.push(bInside) assert.fail(function() { Must(a).be.eql(b) }) assert.fail(function() { Must(b).be.eql(a) }) }) }) describe("with nested values", function() { function nestedEql(a, b) { Must([a]).be.eql([b]) } testNull(nestedEql) testBoolean(nestedEql) testNumber(nestedEql) testString(nestedEql) testSymbol(nestedEql) testRegExp(nestedEql) testDate(nestedEql) testFunction(nestedEql) }) }) describe("given Object", function() { testObjectProperties(eql, _.identity) it("must pass given empty inherited objects", function() { var a = Object.create({}) var b = Object.create({}) assert.pass(function() { Must(a).be.eql(b) }) }) it("must pass given empty ancestored objects", function() { var a = Object.create(Object.create({})) var b = Object.create(Object.create({})) assert.pass(function() { Must(a).be.eql(b) }) }) it("must pass given empty objects inherited from null", function() { var a = Object.create(null) var b = Object.create(null) assert.pass(function() { Must(a).be.eql(b) }) }) it("must pass given empty objects ancestored from null", function() { var a = Object.create(Object.create(null)) var b = Object.create(Object.create(null)) assert.pass(function() { Must(a).be.eql(b) }) }) it("must pass given equivalent inherited objects", function() { var a = Object.create({love: 42}) var b = Object.create({love: 42}) assert.pass(function() { Must(a).be.eql(b) }) }) it("must pass given equivalent ancestored objects", function() { var a = Object.create(Object.create({love: 42})) var b = Object.create(Object.create({love: 42})) assert.pass(function() { Must(a).be.eql(b) }) }) it("must pass given equivalent objects inherited from null", function() { var a = Object.create(null, {life: {value: 42, enumerable: true}}) var b = Object.create(null, {life: {value: 42, enumerable: true}}) assert.pass(function() { Must(a).be.eql(b) }) }) it("must pass given equivalent objects ancestored from null", function() { var a = Object.create(Object.create(null, { life: {value: 42, enumerable: true} })) var b = Object.create(Object.create(null, { life: {value: 42, enumerable: true} })) assert.pass(function() { Must(a).be.eql(b) }) }) it("must fail given unequivalent inherited objects", function() { var a = Object.create({love: 42}) var b = Object.create({love: 69}) assert.fail(function() { Must(a).be.eql(b) }) }) it("must fail given unequivalent ancestored objects", function() { var a = Object.create(Object.create({love: 42})) var b = Object.create(Object.create({love: 69})) assert.fail(function() { Must(a).be.eql(b) }) }) it("must fail given unequivalent objects inherited from null", function() { var a = Object.create(null, {life: {value: 42, enumerable: true}}) var b = Object.create(null, {life: {value: 69, enumerable: true}}) assert.fail(function() { Must(a).be.eql(b) }) }) it("must fail given unequivalent objects ancestored from null", function() { var a = Object.create(Object.create(null, { life: {value: 42, enumerable: true} })) var b = Object.create(Object.create(null, { life: {value: 69, enumerable: true} })) assert.fail(function() { Must(a).be.eql(b) }) }) }) describe("given Object with constructor", function() { function Attributes(attrs) { O.assign(this, attrs) } testObjectProperties(eql, function(attrs) { return new Attributes(attrs) }) it("must pass given equivalent objects", function() { function Value(value) { this.value = value } var a = new Value(42); a.name = "Something" var b = new Value(42); b.name = "Something" assert.pass(function() { Must(a).be.eql(b) }) }) it("must pass given non-function valueOfs", function() { function Value(value) { this.value = value } Value.prototype.valueOf = 42 var a = new Value(42) var b = new Value(42) assert.pass(function() { Must(a).be.eql(b) }) }) it("must pass given one with unenumerable valueOf", function() { function Value(value) { this.value = value } var a = new Value(42) var b = new Value(42) Object.defineProperty(b, "valueOf", { value: function() { return this.value }, configurable: 1, writable: 1 }) assert.pass(function() { Must(a).be.eql(b) }) }) it("must fail given unequivalent objects", function() { function Value(value) { this.value = value } var a = new Value(42); a.name = "Something" var b = new Value(42); b.name = "Other" assert.fail(function() { Must(a).be.eql(b) }) }) it("must fail given different constructors", function() { function A() {} function B() {} assert.fail(function() { Must(new A).eql(new B) }) }) it("must fail given instance and plain object", function() { function Model() {} var a = new Model, b = {} assert.fail(function() { Must(a).eql(b) }) assert.fail(function() { Must(b).eql(a) }) }) it("must fail given subclassed constructor", function() { function Value(value) { this.value = value } function MoreValue(value) { this.value = value } MoreValue.prototype = Object.create(Value.prototype, { constructor: {value: MoreValue, configurable: true, writable: true} }) var a = new Value(42) var b = new MoreValue(42) assert.fail(function() { Must(a).be.eql(b) }) }) }) describe("given Object with valueOf", function() { it("must pass given equal value", function() { function Valuable(value) { this.value = value } Valuable.prototype.valueOf = function() { return this.value } var a = new Valuable(42), b = new Valuable(42) assert.pass(function() { Must(a).eql(b) }) }) it("must pass given equal value with unequivalent properties", function() { function Valuable(value, other) { this.value = value this.other = other } Valuable.prototype.valueOf = function() { return this.value } var a = new Valuable(42, 1), b = new Valuable(42, 2) assert.pass(function() { Must(a).eql(b) }) }) it("must pass given equal value but different valueOfs", function() { function Valuable(value) { this.valueOf = function() { return value } } var a = new Valuable(42), b = new Valuable(42) assert.pass(function() { Must(a).eql(b) }) }) it("must fail given unequivalent values", function() { function Valuable(value) { this.value = value } Valuable.prototype.valueOf = function() { return this.value } var a = new Valuable(42), b = new Valuable(69) assert.fail(function() { Must(a).eql(b) }) }) it("must fail given differently typed values", function() { function Valuable(value) { this.value = value } Valuable.prototype.valueOf = function() { return this.value } var a = new Valuable(42), b = new Valuable("42") assert.fail(function() { Must(a).eql(b) }) }) it("must pass given equivalent array values", function() { function Value(value) { this.value = value } Value.prototype.valueOf = function() { return [42, this.value] } var a = new Value(42) var b = new Value(42) assert.pass(function() { Must(a).eql(b) }) }) it("must fail given unequivalent array values", function() { function Value(value) { this.value = value } Value.prototype.valueOf = function() { return [42, this.value] } var a = new Value(42) var b = new Value(69) assert.fail(function() { Must(a).eql(b) }) }) it("must pass given null inherited value objects", function() { function Value(value) { this.value = value } Value.prototype = Object.create(null, { constructor: {value: Value, configurable: true, writeable: true} }) Value.prototype.valueOf = function() { return this.value } var a = new Value(42) var b = new Value(42) assert.pass(function() { Must(a).eql(b) }) }) it("must fail given instance and plain object", function() { function Value(value) { this.value = value } Value.prototype.valueOf = function() { return this.value } var a = new Value(42) var b = {valueOf: function() { return 42 }} assert.fail(function() { Must(a).eql(b) }) }) it("must fail given different construtors", function() { function A(value) { this.value = value } A.prototype.valueOf = function() { return this.value } function B(value) { this.value = value } B.prototype.valueOf = function() { return this.value } assert.fail(function() { Must(new A(42)).eql(new B(42)) }) }) it("must fail given subclassed constructor", function() { function Value(value) { this.value = value } Value.prototype.valueOf = function() { return this.value } function MoreValue(value) { this.value = value } MoreValue.prototype = Object.create(Value.prototype, { constructor: {value: MoreValue, configurable: true, writable: true} }) var a = new Value(42) var b = new MoreValue(42) assert.fail(function() { Must(a).eql(b) }) }) it("must fail given overwritten constructor properties", function() { function A(value) { this.value = value } A.prototype.valueOf = function() { return this.value } function B(value) { this.value = value } B.prototype.valueOf = function() { return this.value } var a = new A(42) var b = new B(42) a.constructor = b.constructor = function() {} assert.fail(function() { Must(a).eql(b) }) }) it("must return false given plain object", function() { var a = {valueOf: function() { return 1 }} var b = {valueOf: function() { return 1 }} assert.fail(function() { Must(a).eql(b) }) }) it("must return false given null inherited plain objects", function() { var a = Object.create(null); a.valueOf = function() { return 42 } var b = Object.create(null); b.valueOf = function() { return 42 } assert.fail(function() { Must(a).eql(b) }) }) }) require("./_assertion_error_test")(function() { Must("secret").eql(42) }, { actual: "secret", expected: 42, diffable: true, message: "\"secret\" must be equivalent to 42" }) describe(".not", function() { it("must invert the assertion", function() { assert.fail(function() { Must("secret").not.eql("secret") }) }) }) }) function testNull(egal) { it("must pass given nulls", function() { assert.pass(function() { egal(null, null) }) }) it("must pass given undefineds", function() { assert.pass(function() { egal(undefined, undefined) }) }) it("must fail given null and undefined", function() { assert.fail(function() { egal(null, undefined) }) assert.fail(function() { egal(undefined, null) }) }) } function testBoolean(egal) { describe("given Boolean", function() { it("must pass given identical primitives", function() { assert.pass(function() { egal(true, true) }) assert.pass(function() { egal(false, false) }) }) it("must fail given unidentical primitives", function() { assert.fail(function() { egal(true, false) }) assert.fail(function() { egal(false, true) }) }) it("must pass given equivalent objects", function() { assert.pass(function() { egal(new Boolean(true), new Boolean(true)) }) assert.pass(function() { egal(new Boolean(false), new Boolean(false)) }) }) it("must fail given unequivalent objects", function() { assert.fail(function() { egal(new Boolean(true), new Boolean(false)) }) assert.fail(function() { egal(new Boolean(false), new Boolean(true)) }) }) it("must fail given equivalent primitive and object", function() { assert.fail(function() { egal(true, new Boolean(true)) }) assert.fail(function() { egal(new Boolean(true), true) }) assert.fail(function() { egal(false, new Boolean(false)) }) assert.fail(function() { egal(new Boolean(false), false) }) }) }) } function testNumber(egal) { describe("given Number", function() { it("must pass given identical primitives", function() { assert.pass(function() { egal(42, 42) }) }) it("must fail given unequivalent primitives", function() { assert.fail(function() { egal(42, 1337) }) }) it("must pass given equivalent objects", function() { assert.pass(function() { egal(new Number(42), new Number(42)) }) }) it("must fail given unequivalent objects", function() { assert.fail(function() { egal(new Number(42), new Number(69)) }) }) it("must fail given equivalent primitive and object", function() { assert.fail(function() { egal(42, new Number(42)) }) assert.fail(function() { egal(new Number(42), 42) }) }) it("must fail given string primitive", function() { assert.fail(function() { egal(42, "42") }) }) it("must fail given string object", function() { assert.fail(function() { egal(42, new String("42")) }) }) describe("given -0", function() { it("must pass given primitives", function() { assert.pass(function() { egal(-0, +0) }) assert.pass(function() { egal(+0, -0) }) }) it("must pass given objects", function() { assert.pass(function() { egal(new Number(-0), new Number(+0)) }) assert.pass(function() { egal(new Number(+0), new Number(-0)) }) }) it("must fail given primitive and object", function() { assert.fail(function() { egal(-0, new Number(+0)) }) assert.fail(function() { egal(new Number(-0), +0) }) }) }) describe("given NaN", function() { it("must pass given primitives", function() { assert.pass(function() { egal(NaN, NaN) }) }) it("must pass given objects", function() { assert.pass(function() { egal(new Number(NaN), new Number(NaN)) }) }) it("must fail given primitive and object", function() { assert.fail(function() { egal(NaN, new Number(NaN)) }) assert.fail(function() { egal(new Number(NaN), NaN) }) }) it("must fail given number and NaN", function() { assert.fail(function() { egal(42, NaN) }) assert.fail(function() { egal(NaN, 42) }) }) }) describe("given Infinity", function() { it("must pass given identical primitives", function() { assert.pass(function() { egal(Infinity, Infinity) }) assert.pass(function() { egal(-Infinity, -Infinity) }) }) it("must fail given unequivalent primitives", function() { assert.fail(function() { egal(Infinity, -Infinity) }) assert.fail(function() { egal(-Infinity, Infinity) }) }) it("must pass given equivalent objects", function() { assert.pass(function() { egal(new Number(Infinity), new Number(Infinity)) }) assert.pass(function() { egal(new Number(-Infinity), new Number(-Infinity)) }) }) it("must fail given unequivalent objects", function() { assert.fail(function() { egal(new Number(Infinity), new Number(-Infinity)) }) assert.fail(function() { egal(new Number(-Infinity), new Number(Infinity)) }) }) it("must fail given equivalent primitive and object", function() { assert.fail(function() { egal(Infinity, new Number(Infinity)) }) assert.fail(function() { egal(new Number(Infinity), Infinity) }) assert.fail(function() { egal(-Infinity, new Number(-Infinity)) }) assert.fail(function() { egal(new Number(-Infinity), -Infinity) }) }) it("must fail given number and infinity", function() { assert.fail(function() { egal(42, Infinity) }) assert.fail(function() { egal(42, -Infinity) }) }) }) }) } function testString(egal) { describe("given String", function() { it("must pass given identical primitives", function() { assert.pass(function() { egal("ok", "ok") }) }) it("must fail given unequivalent primitives", function() { assert.fail(function() { egal("ok", "nok") }) }) it("must pass given equivalent objects", function() { assert.pass(function() { egal(new String("a"), new String("a")) }) }) it("must fail given unequivalent objects", function() { assert.fail(function() { egal(new String("a"), new String("b")) }) }) it("must fail given equivalent primitive and object", function() { assert.fail(function() { egal("ok", new String("ok")) }) assert.fail(function() { egal(new String("ok"), "ok") }) }) it("must fail given equivalent number primitive", function() { assert.fail(function() { egal("1", 1) }) }) it("must fail given equivalent number object", function() { assert.fail(function() { egal("1", new Number(1)) }) }) }) } function testSymbol(egal) { var desc = typeof Symbol != "undefined" ? describe : xdescribe desc("given Symbol", function() { it("must pass given identical symbols", function() { var symbol = Symbol() assert.pass(function() { egal(symbol, symbol) }) }) it("must fail given two anonymous symbols", function() { assert.fail(function() { egal(Symbol(), Symbol()) }) }) it("must fail given two named symbols", function() { assert.fail(function() { egal(Symbol("iterator"), Symbol("iterator")) }) }) }) } function testRegExp(egal) { describe("given RegExp", function() { it("must pass given equivalent regexps", function() { assert.pass(function() { egal(/a/, /a/) }) }) it("must fail given unequivalent regexps", function() { assert.fail(function() { egal(/a/, /b/) }) }) it("must fail given unequivalent flags", function() { assert.fail(function() { egal(/a/ig, /a/g) }) }) it("must fail given RegExp and string primitive", function() { assert.fail(function() { egal(/a/, "/a/") }) }) }) } function testDate(egal) { describe("given Date", function() { it("must pass given identical dates", function() { var now = new Date assert.pass(function() { egal(now, now) }) }) it("must pass given equivalent dates", function() { assert.pass(function() { egal(new Date(7), new Date(7)) }) }) it("must fail given unequivalent dates", function() { assert.fail(function() { egal(new Date(69), new Date(42)) }) }) it("must fail given Date and number primitive", function() { assert.fail(function() { egal(new Date(69), 69) }) }) }) } function testFunction(egal) { describe("given Function", function() { it("must pass given identical functions", function() { function fn() {} assert.pass(function() { egal(fn, fn) }) }) it("must fail given equivalent functions", function() { assert.fail(function() { egal(function() {}, function() {}) }) }) }) } function testObjectProperties(egal, create) { describe("given Object with properties", function() { it("must pass given identical objects", function() { var obj = create({a: 42, b: 69}) assert.pass(function() { egal(obj, obj) }) }) it("must pass given empty objects", function() { assert.pass(function() { Must(create({})).be.eql(create({})) }) }) it("must fail given an empty and filled object", function() { assert.fail(function() { egal({}, create({a: 42})) }) assert.fail(function() { Must(create({a: 42})).be.eql(create({})) }) }) it("must fail given a smaller and larger object", function() { var a = create({a: 42, b: 69}) var b = create({a: 42}) assert.fail(function() { egal(a, b) }) assert.fail(function() { egal(b, a) }) }) // This was a bug I discovered on Jun 12, 2015 related to not comparing // keys equivalence before comparing their values. it("must fail given equal amount of keys undefined keys", function() { var obj = {name: undefined} assert.fail(function() { egal(obj, {age: undefined}) }) assert.fail(function() { egal(obj, {age: 13}) }) }) it("must pass given equivalent objects", function() { var a = create({a: 42, b: 69}) var b = create({a: 42, b: 69}) assert.pass(function() { egal(a, b) }) }) it("must fail given objects with differently typed properties", function() { var a = create({a: "42", b: 69}) var b = create({a: 42, b: 69}) assert.fail(function() { egal(a, b) }) }) it("must pass given an object with set constructor property", function() { var a = create({constructor: 1337}) var b = create({constructor: 1337}) assert.pass(function() { egal(a, b) }) }) it("must pass given a deep object", function() { var a = create({life: {love: 69}}) var b = create({life: {love: 69}}) assert.pass(function() { egal(a, b) }) }) it("must fail given an unequivalent deep object", function() { var a = create({life: {love: 69}}) var b = create({life: {love: 42}}) assert.fail(function() { egal(a, b) }) }) describe("with circular references", function() { it("must pass if equivalent", function() { var a = create({life: {love: 69}}) a.self = a var b = create({life: {love: 69}}) b.self = b assert.pass(function() { egal(a, b) }) }) it("must fail if only one circular", function() { var a = create({life: {love: 69}}) a.self = a var b = create({life: {love: 69}}) b.self = {life: {love: 69}, self: {}} assert.fail(function() { egal(a, b) }) assert.fail(function() { egal(b, a) }) }) it("must fail if circular to different levels", function() { var a = create({life: {love: 69}}) a.self = a var b = create({life: {love: 69}}) var bInside = create({life: {love: 69}}) bInside.self = bInside b.self = bInside assert.fail(function() { egal(a, b) }) assert.fail(function() { egal(b, a) }) }) }) }) }