/** * Tests for the assertion functions in mongo/shell/assert.js. */ (() => { "use strict"; const tests = []; const kDefaultTimeoutMS = 10 * 1000; const kSmallTimeoutMS = 200; const kSmallRetryIntervalMS = 1; const kDefaultRetryAttempts = 5; /* doassert tests */ tests.push(function callingDoAssertWithStringThrowsException() { const expectedError = 'hello world'; const actualError = assert.throws(() => { doassert(expectedError); }); assert.eq('Error: ' + expectedError, actualError, 'doAssert should throw passed msg as exception'); }); tests.push(function callingDoAssertWithObjectThrowsException() { const expectedError = {err: 'hello world'}; const actualError = assert.throws(() => { doassert(expectedError); }); assert.eq('Error: ' + tojson(expectedError), actualError, 'doAssert should throw passed object as exception'); }); tests.push(function callingDoAssertWithStringPassedAsFunctionThrowsException() { const expectedError = 'hello world'; const actualError = assert.throws(() => { doassert(() => { return expectedError; }); }); assert.eq('Error: ' + expectedError, actualError, 'doAssert should throw passed msg as exception'); }); tests.push(function callingDoAssertWithObjectAsFunctionThrowsException() { const expectedError = {err: 'hello world'}; const actualError = assert.throws(() => { doassert(() => { return expectedError; }); }); assert.eq('Error: ' + tojson(expectedError), actualError, 'doAssert should throw passed object as exception'); }); /* assert tests */ tests.push(function assertShouldFailForMoreThan2Args() { const err = assert.throws(() => { assert(1, 2, 3); }); assert.neq(-1, err.message.indexOf('Too many parameters'), 'Too many params message should be displayed'); }); tests.push(function assertShouldNotThrowExceptionForTrue() { assert.doesNotThrow(() => { assert(true, 'message'); }); }); tests.push(function assertShouldThrowExceptionForFalse() { const expectedMessage = 'message'; const err = assert.throws(() => { assert(false, expectedMessage); }); assert.neq( -1, err.message.indexOf(expectedMessage), 'assert message should be thrown on error'); }); tests.push(function assertShouldThrowExceptionForFalseWithDefaultMessage() { const defaultMessage = 'assert failed'; const err = assert.throws(() => { assert(false); }); assert.eq(defaultMessage, err.message, 'assert message should be thrown on error'); }); tests.push(function assertShouldThrowExceptionForFalseWithDefaultMessagePrefix() { const prefix = 'assert failed'; const message = 'the assertion failed'; const err = assert.throws(() => { assert(false, message); }); assert.neq(-1, err.message.indexOf(prefix), 'assert message should should contain prefix'); assert.neq(-1, err.message.indexOf(message), 'assert message should should contain original message'); }); tests.push(function assertShouldNotCallMsgFunctionsOnSuccess() { var called = false; assert(true, () => { called = true; }); assert.eq(false, called, 'called should not have been udpated'); }); tests.push(function assertShouldCallMsgFunctionsOnFailure() { var called = false; assert.throws(() => { assert(false, () => { called = true; return 'error message'; }); }); assert.eq(true, called, 'called should not have been udpated'); }); /* assert.automsg tests */ tests.push(function automsgShouldPassToAssert() { const defaultMessage = '1 === 2'; const err = assert.throws(() => { assert.automsg(defaultMessage); }); assert.neq(-1, err.message.indexOf(defaultMessage), 'default message should be returned'); }); /* assert.eq tests */ tests.push(function eqShouldPassOnEquality() { assert.doesNotThrow(() => { assert.eq(3, 3); }); }); tests.push(function eqShouldFailWhenNotEqual() { assert.throws(() => { assert.eq(2, 3); }); }); tests.push(function eqShouldNotCallMsgFunctionOnSuccess() { var called = false; assert.doesNotThrow(() => { assert.eq(3, 3, () => { called = true; }); }); assert.eq(false, called, 'msg function should not have been called'); }); tests.push(function eqShouldCallMsgFunctionOnFailure() { var called = false; assert.throws(() => { assert.eq(1, 3, () => { called = true; }); }); assert.eq(true, called, 'msg function should have been called'); }); tests.push(function eqShouldPassOnObjectsWithSameContent() { const a = {'foo': true}; const b = {'foo': true}; assert.doesNotThrow(() => { assert.eq(a, b); }, [], 'eq should not throw exception on two objects with the same content'); }); /* assert.eq.automsg tests */ tests.push(function eqAutomsgShouldCreateMessage() { const defaultMessage = '[1] != [2]'; const err = assert.throws(() => { assert.eq.automsg(1, 2); }); assert.neq(-1, err.message.indexOf(defaultMessage), 'default message should be returned'); }); /* assert.neq tests */ tests.push(function neqShouldFailOnEquality() { assert.throws(() => { assert.neq(3, 3); }); }); tests.push(function neqShouldPassWhenNotEqual() { assert.doesNotThrow(() => { assert.neq(2, 3); }); }); tests.push(function neqShouldFailOnObjectsWithSameContent() { const a = {'foo': true}; const b = {'foo': true}; assert.throws(() => { assert.neq(a, b); }, [], 'neq should throw exception on two objects with the same content'); }); /* assert.hasFields tests */ tests.push(function hasFieldsRequiresAnArrayOfFields() { const object = {field1: 1, field2: 1, field3: 1}; assert.throws(() => { assert.hasFields(object, 'field1'); }); }); tests.push(function hasFieldsShouldPassWhenObjectHasField() { const object = {field1: 1, field2: 1, field3: 1}; assert.doesNotThrow(() => { assert.hasFields(object, ['field1']); }); }); tests.push(function hasFieldsShouldFailWhenObjectDoesNotHaveField() { const object = {field1: 1, field2: 1, field3: 1}; assert.throws(() => { assert.hasFields(object, ['fieldDoesNotExist']); }); }); /* assert.contains tests */ tests.push(function containsShouldOnlyWorkOnArrays() { assert.throws(() => { assert.contains(42, 5); }); }); tests.push(function containsShouldPassIfArrayContainsValue() { const array = [1, 2, 3]; assert.doesNotThrow(() => { assert.contains(2, array); }); }); tests.push(function containsShouldFailIfArrayDoesNotContainValue() { const array = [1, 2, 3]; assert.throws(() => { assert.contains(42, array); }); }); /* assert.soon tests */ tests.push(function soonPassesWhenFunctionPasses() { assert.doesNotThrow(() => { assert.soon(() => { return true; }); }); }); tests.push(function soonFailsIfMethodNeverPasses() { assert.throws(() => { assert.soon(() => { return false; }, 'assert message', kSmallTimeoutMS, kSmallRetryIntervalMS); }); }); tests.push(function soonPassesIfMethodEventuallyPasses() { var count = 0; assert.doesNotThrow(() => { assert.soon(() => { count += 1; return count === 3; }, 'assert message', kDefaultTimeoutMS, kSmallRetryIntervalMS); }); }); /* assert.soonNoExcept tests */ tests.push(function soonNoExceptEventuallyPassesEvenWithExceptions() { var count = 0; assert.doesNotThrow(() => { assert.soonNoExcept(() => { count += 1; if (count < 3) { throw new Error('failed'); } return true; }, 'assert message', kDefaultTimeoutMS, kSmallRetryIntervalMS); }); }); tests.push(function soonNoExceptFailsIfExceptionAlwaysThrown() { var count = 0; assert.throws(() => { assert.soonNoExcept(() => { throw new Error('failed'); }, 'assert message', kSmallTimeoutMS, kSmallRetryIntervalMS); }); }); /* assert.retry tests */ tests.push(function retryPassesAfterAFewAttempts() { var count = 0; assert.doesNotThrow(() => { assert.retry(() => { count += 1; return count === 3; }, 'assert message', kDefaultRetryAttempts, kSmallRetryIntervalMS); }); }); tests.push(function retryFailsAfterMaxAttempts() { assert.throws(() => { assert.retry(() => { return false; }, 'assert message', kDefaultRetryAttempts, kSmallRetryIntervalMS); }); }); /* assert.retryNoExcept tests */ tests.push(function retryNoExceptPassesAfterAFewAttempts() { var count = 0; assert.doesNotThrow(() => { assert.retryNoExcept(() => { count += 1; if (count < 3) { throw new Error('failed'); } return count === 3; }, 'assert message', kDefaultRetryAttempts, kSmallRetryIntervalMS); }); }); tests.push(function retryNoExceptFailsAfterMaxAttempts() { assert.throws(() => { assert.retryNoExcept(() => { throw new Error('failed'); }, 'assert message', kDefaultRetryAttempts, kSmallRetryIntervalMS); }); }); /* assert.time tests */ tests.push(function timeIsSuccessfulIfFuncExecutesInTime() { assert.doesNotThrow(() => { assert.time(() => { return true; }, 'assert message', kDefaultTimeoutMS); }); }); tests.push(function timeFailsIfFuncDoesNotFinishInTime() { assert.throws(() => { assert.time(() => { return true; }, 'assert message', -5 * 60 * 1000); }); }); /* assert.isnull tests */ tests.push(function isnullPassesOnNull() { assert.doesNotThrow(() => { assert.isnull(null); }); }); tests.push(function isnullPassesOnUndefined() { assert.doesNotThrow(() => { assert.isnull(undefined); }); }); tests.push(function isnullFailsOnNotNull() { assert.throws(() => { assert.isnull('hello world'); }); }); /* assert.lt tests */ tests.push(function ltPassesWhenLessThan() { assert.doesNotThrow(() => { assert.lt(3, 5); }); }); tests.push(function ltFailsWhenNotLessThan() { assert.throws(() => { assert.lt(5, 3); }); }); tests.push(function ltFailsWhenEqual() { assert.throws(() => { assert.lt(5, 5); }); }); tests.push(function ltPassesWhenLessThanWithTimestamps() { assert.doesNotThrow(() => { assert.lt(Timestamp(3, 0), Timestamp(10, 0)); }); }); tests.push(function ltFailsWhenNotLessThanWithTimestamps() { assert.throws(() => { assert.lt(Timestamp(0, 10), Timestamp(0, 3)); }); }); tests.push(function ltFailsWhenEqualWithTimestamps() { assert.throws(() => { assert.lt(Timestamp(5, 0), Timestamp(5, 0)); }); }); /* assert.gt tests */ tests.push(function gtPassesWhenGreaterThan() { assert.doesNotThrow(() => { assert.gt(5, 3); }); }); tests.push(function gtFailsWhenNotGreaterThan() { assert.throws(() => { assert.gt(3, 5); }); }); tests.push(function gtFailsWhenEqual() { assert.throws(() => { assert.gt(5, 5); }); }); /* assert.lte tests */ tests.push(function ltePassesWhenLessThan() { assert.doesNotThrow(() => { assert.lte(3, 5); }); }); tests.push(function lteFailsWhenNotLessThan() { assert.throws(() => { assert.lte(5, 3); }); }); tests.push(function ltePassesWhenEqual() { assert.doesNotThrow(() => { assert.lte(5, 5); }); }); /* assert.gte tests */ tests.push(function gtePassesWhenGreaterThan() { assert.doesNotThrow(() => { assert.gte(5, 3); }); }); tests.push(function gteFailsWhenNotGreaterThan() { assert.throws(() => { assert.gte(3, 5); }); }); tests.push(function gtePassesWhenEqual() { assert.doesNotThrow(() => { assert.gte(5, 5); }); }); tests.push(function gtePassesWhenGreaterThanWithTimestamps() { assert.doesNotThrow(() => { assert.gte(Timestamp(0, 10), Timestamp(0, 3)); }); }); tests.push(function gteFailsWhenNotGreaterThanWithTimestamps() { assert.throws(() => { assert.gte(Timestamp(0, 3), Timestamp(0, 10)); }); }); tests.push(function gtePassesWhenEqualWIthTimestamps() { assert.doesNotThrow(() => { assert.gte(Timestamp(5, 0), Timestamp(5, 0)); }); }); /* assert.betweenIn tests */ tests.push(function betweenInPassWhenNumberIsBetween() { assert.doesNotThrow(() => { assert.betweenIn(3, 4, 5); }); }); tests.push(function betweenInFailsWhenNumberIsNotBetween() { assert.throws(() => { assert.betweenIn(3, 5, 4); }); }); tests.push(function betweenInPassWhenNumbersEqual() { assert.doesNotThrow(() => { assert.betweenIn(3, 3, 5); }); assert.doesNotThrow(() => { assert.betweenIn(3, 5, 5); }); }); /* assert.betweenEx tests */ tests.push(function betweenExPassWhenNumberIsBetween() { assert.doesNotThrow(() => { assert.betweenEx(3, 4, 5); }); }); tests.push(function betweenExFailsWhenNumberIsNotBetween() { assert.throws(() => { assert.betweenEx(3, 5, 4); }); }); tests.push(function betweenExFailsWhenNumbersEqual() { assert.throws(() => { assert.betweenEx(3, 3, 5); }); assert.throws(() => { assert.betweenEx(3, 5, 5); }); }); /* main */ tests.forEach((test) => { jsTest.log(`Starting tests '${test.name}'`); test(); }); })();