// Licensed to the Software Freedom Conservancy (SFC) under one // or more contributor license agreements. See the NOTICE file // distributed with this work for additional information // regarding copyright ownership. The SFC licenses this file // to you under the Apache License, Version 2.0 (the // "License"); you may not use this file except in compliance // with the License. You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, // software distributed under the License is distributed on an // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY // KIND, either express or implied. See the License for the // specific language governing permissions and limitations // under the License. 'use strict'; const assert = require('../../testing/assert'); const AssertionError = require('assert').AssertionError; const assertTrue = require('assert').ok; const assertEqual = require('assert').equal; const assertThrows = require('assert').throws; const fail = require('assert').fail; describe('assert', function() { describe('atLeast', function() { it('compares subject >= value', function() { assert(1).atLeast(0); assert(1).atLeast(1); assertThrows(() => assert(1).atLeast(2)); }); it('accepts failure message', function() { assertThrows( () => assert(1).atLeast(2, 'hi there!'), (error) => error.message.indexOf('hi there') != -1); }); it('fails if given a non-numeric subject', function() { assertThrows(() => assert('a').atLeast(1)); }); it('fails if given a non-numeric bound', function() { assertThrows(() => assert(1).atLeast('a')); }); it('waits for promised subject', function() { return assert(Promise.resolve(123)).atLeast(100); }); it('waits for promised subject (with failure)', function() { return assert(Promise.resolve(100)) .atLeast(123) .then(() => fail('should have failed'), function(e) { assertInstanceOf(AssertionError, e); assertEqual('100 >= 123', e.message); }); }); }); describe('atMost', function() { it('compares subject <= value', function() { assertThrows(() => assert(1).atMost(0)); assert(1).atMost(1); assert(1).atMost(2); }); it('accepts failure message', function() { assertThrows( () => assert(1).atMost(0, 'hi there!'), (error) => error.message.indexOf('hi there!') != -1); }); it('fails if given a non-numeric subject', function() { assertThrows(() => assert(1).atMost('a')); }); it('fails if given a non-numeric bound', function() { assertThrows(() => assert('a').atMost(1)); }); it('waits for promised subject', function() { return assert(Promise.resolve(100)).atMost(123); }); it('waits for promised subject (with failure)', function() { return assert(Promise.resolve(123)) .atMost(100) .then(() => fail('should have failed'), function(e) { assertInstanceOf(AssertionError, e); assertEqual('123 <= 100', e.message); }); }); }); describe('greaterThan', function() { it('compares subject > value', function() { assertThrows(() => assert(1).greaterThan(1)); assertThrows(() => assert(1).greaterThan(2)); assert(2).greaterThan(1); }); it('accepts failure message', function() { assertThrows( () => assert(0).greaterThan(1, 'hi there!'), (error) => error.message.indexOf('hi there!') != -1); }); it('fails if given a non-numeric subject', function() { assertThrows(() => assert('a').atMost(1)); }); it('fails if given a non-numeric bound', function() { assertThrows(() => assert(1).atMost('a')); }); it('waits for promised subject', function() { return assert(Promise.resolve(123)).greaterThan(100); }); it('waits for promised subject (with failure)', function() { return assert(Promise.resolve(100)) .greaterThan(123) .then(() => fail('should have failed'), function(e) { assertInstanceOf(AssertionError, e); assertEqual('100 > 123', e.message); }); }); }); describe('lessThan', function() { it('compares subject < value', function() { assertThrows(() => assert(1).lessThan(0)); assertThrows(() => assert(1).lessThan(1)); assert(1).lessThan(2); }); it('accepts failure message', function() { assertThrows( () => assert(1).lessThan(0, 'hi there!'), (error) => error.message.indexOf('hi there!') != -1); }); it('fails if given a non-numeric subject', function() { assertThrows(() => assert('a').lessThan(1)); }); it('fails if given a non-numeric bound', function() { assertThrows(() => assert(1).lessThan('a')); }); it('waits for promised subject', function() { return assert(Promise.resolve(100)).lessThan(123); }); it('waits for promised subject (with failure)', function() { return assert(Promise.resolve(123)) .lessThan(100) .then(() => fail('should have failed'), function(e) { assertInstanceOf(AssertionError, e); assertEqual('123 < 100', e.message); }); }); }); describe('closeTo', function() { it('accepts values within epislon of target', function() { assert(123).closeTo(123, 0); assert(123).closeTo(124, 1); assert(125).closeTo(124, 1); assertThrows(() => assert(123).closeTo(125, .1)); assertThrows(() => assert(1./3).closeTo(.8, .01)); }); it('waits for promised values', function() { let p = new Promise(resolve => setTimeout(() => resolve(123), 10)); return assert(p).closeTo(124, 1); }); }); describe('instanceOf', function() { it('works with direct instances', function() { assert(Error('foo')).instanceOf(Error); }); it('works with sub-types', function() { assert(TypeError('foo')).instanceOf(Error); }); it('parent types are not instances of sub-types', function() { assertThrows(() => assert(Error('foo')).instanceOf(TypeError)); }); }); describe('isNull', function() { it('normal case', function() { assert(null).isNull(); assertThrows(() => assert(1).isNull()); }); it('handles promised values', function() { let p = new Promise(function(f) { setTimeout(() => f(null), 10); }); return assert(p).isNull(); }); it('does not match on undefined', function() { assertThrows(() => assert(void(0)).isNull()); }) }); describe('isUndefined', function() { it('normal case', function() { assert(void(0)).isUndefined(); assertThrows(() => assert(1).isUndefined()); }); it('handles promised values', function() { let p = new Promise(function(f) { setTimeout(() => f(void(0)), 10); }); return assert(p).isUndefined(); }); it('does not match on null', function() { assertThrows(() => assert(null).isUndefined()); }) }); describe('contains', function() { it('works with strings', function() { assert('abc').contains('a'); assert('abc').contains('ab'); assert('abc').contains('abc'); assert('abc').contains('bc'); assert('abc').contains('c'); assertThrows(() => assert('abc').contains('d')); }); it('works with arrays', function() { assert([1, 2, 3]).contains(1); assert([1, 2, 3]).contains(2); assert([1, 2, 3]).contains(3); assertThrows(() => assert([1, 2]).contains(3)); }); it('works with maps', function() { let m = new Map; m.set(1, 2); assert(m).contains(1); assertThrows(() => assert(m).contains(2)); }); it('works with sets', function() { let s = new Set; s.add(1); assert(s).contains(1); assertThrows(() => assert(s).contains(2)); }); it('requires an array, string, map, or set subject', function() { assertThrows(() => assert(123).contains('a')); }); }); describe('endsWith', function() { it('works', function() { assert('abc').endsWith('abc'); assert('abc').endsWith('bc'); assert('abc').endsWith('c'); assertThrows(() => assert('abc').endsWith('d')); }) }); describe('startsWith', function() { it('works', function() { assert('abc').startsWith('abc'); assert('abc').startsWith('ab'); assert('abc').startsWith('a'); assertThrows(() => assert('abc').startsWith('d')); }) }); describe('matches', function() { it('requires a regex value', function() { assertThrows(() => assert('abc').matches(1234)); }); it('requires a string value', function() { assertThrows(() => assert(1234).matches(/abc/)); }); it('requires a string value (promise case)', function() { return assert(Promise.resolve(1234)) .matches(/abc/) .then(fail, function(error) { assertEqual( 'Expected a string matching /abc/, got <1234> (number)', error.message); }); }); it('applies regex', function() { assert('abc').matches(/abc/); assertThrows(() => assert('def').matches(/abc/)); }); }); describe('isTrue', function() { it('only accepts booleans', function() { assertThrows(() => assert(123).isTrue()); }); it('accepts true values', function() { assert(true).isTrue(); assert(Boolean('abc')).isTrue(); return assert(Promise.resolve(true)).isTrue(); }); it('rejects false values', function() { assertThrows(() => assert(false).isTrue()); assertThrows(() => assert(Boolean(0)).isTrue()); return assert(Promise.resolve(false)).isTrue() .then(fail, function() {/*no-op, ok*/}); }); }); describe('isFalse', function() { it('only accepts booleans', function() { assertThrows(() => assert(123).isFalse()); }) it('accepts false values', function() { assert(false).isFalse(); assert(Boolean('')).isFalse(); return assert(Promise.resolve(false)).isFalse(); }); it('rejects true values', function() { assertThrows(() => assert(true).isFalse()); assertThrows(() => assert(Boolean(1)).isFalse()); return assert(Promise.resolve(true)).isFalse() .then(fail, function() {/*no-op, ok*/}); }); }); describe('isEqualTo', function() { it('is strict equality', function() { assert('abc').isEqualTo('abc'); assert('abc').equals('abc'); assert('abc').equalTo('abc'); assertThrows(() => assert('1').isEqualTo(1)); }); }); describe('notEqualTo', function() { it('tests strict equality', function() { assert('1').notEqualTo(1); assert(1).notEqualTo('1'); assertThrows(() => assert('abc').notEqualTo('abc')); }); }); function assertInstanceOf(ctor, value) { assertTrue(value instanceof ctor); } });