react / wstein / node_modules / jest-cli / node_modules / jsdom / node_modules / request / node_modules / hawk / node_modules / hoek / test / index.js
81154 views// Load modules12var Fs = require('fs');3var Path = require('path');4var Code = require('code');5var Hoek = require('../lib');6var Lab = require('lab');789// Declare internals1011var internals = {};121314// Test shortcuts1516var lab = exports.lab = Lab.script();17var describe = lab.experiment;18var it = lab.test;19var expect = Code.expect;202122var nestedObj = {23v: [7, 8, 9],24w: /^something$/igm,25x: {26a: [1, 2, 3],27b: 123456,28c: new Date(),29d: /hi/igm,30e: /hello/31},32y: 'y',33z: new Date(1378775452757)34};3536var dupsArray = [nestedObj, { z: 'z' }, nestedObj];37var reducedDupsArray = [nestedObj, { z: 'z' }];3839describe('clone()', function () {4041it('clones a nested object', function (done) {4243var a = nestedObj;44var b = Hoek.clone(a);4546expect(a).to.deep.equal(b);47expect(a.z.getTime()).to.equal(b.z.getTime());48done();49});5051it('clones a null object', function (done) {5253var b = Hoek.clone(null);5455expect(b).to.equal(null);56done();57});5859it('should not convert undefined properties to null', function (done) {6061var obj = { something: undefined };62var b = Hoek.clone(obj);6364expect(typeof b.something).to.equal('undefined');65done();66});6768it('should not throw on circular reference', function (done) {6970var a = {};71a.x = a;7273var test = function () {7475var b = Hoek.clone(a);76};7778expect(test).to.not.throw();79done();80});8182it('clones circular reference', function (done) {8384var x = {85'z': new Date()86};87x.y = x;8889var b = Hoek.clone(x);90expect(Object.keys(b.y)).to.deep.equal(Object.keys(x));91expect(b.z).to.not.equal(x.z);92expect(b.y).to.not.equal(x.y);93expect(b.y.z).to.not.equal(x.y.z);94expect(b.y).to.equal(b);95expect(b.y.y.y.y).to.equal(b);96done();97});9899it('clones an object with a null prototype', function (done) {100101var obj = Object.create(null);102var b = Hoek.clone(obj);103104expect(b).to.deep.equal(obj);105done();106});107108it('clones deeply nested object', function (done) {109110var a = {111x: {112y: {113a: [1, 2, 3],114b: 123456,115c: new Date(),116d: /hi/igm,117e: /hello/118}119}120};121122var b = Hoek.clone(a);123124expect(a).to.deep.equal(b);125expect(a.x.y.c.getTime()).to.equal(b.x.y.c.getTime());126done();127});128129it('clones arrays', function (done) {130131var a = [1, 2, 3];132133var b = Hoek.clone(a);134135expect(a).to.deep.equal(b);136done();137});138139it('performs actual copy for shallow keys (no pass by reference)', function (done) {140141var x = Hoek.clone(nestedObj);142var y = Hoek.clone(nestedObj);143144// Date145expect(x.z).to.not.equal(nestedObj.z);146expect(x.z).to.not.equal(y.z);147148// Regex149expect(x.w).to.not.equal(nestedObj.w);150expect(x.w).to.not.equal(y.w);151152// Array153expect(x.v).to.not.equal(nestedObj.v);154expect(x.v).to.not.equal(y.v);155156// Immutable(s)157x.y = 5;158expect(x.y).to.not.equal(nestedObj.y);159expect(x.y).to.not.equal(y.y);160161done();162});163164it('performs actual copy for deep keys (no pass by reference)', function (done) {165166var x = Hoek.clone(nestedObj);167var y = Hoek.clone(nestedObj);168169expect(x.x.c).to.not.equal(nestedObj.x.c);170expect(x.x.c).to.not.equal(y.x.c);171172expect(x.x.c.getTime()).to.equal(nestedObj.x.c.getTime());173expect(x.x.c.getTime()).to.equal(y.x.c.getTime());174done();175});176177it('copies functions with properties', function (done) {178179var a = {180x: function () {181182return 1;183},184y: {}185};186a.x.z = 'string in function';187a.x.v = function () {188189return 2;190};191a.y.u = a.x;192193var b = Hoek.clone(a);194expect(b.x()).to.equal(1);195expect(b.x.v()).to.equal(2);196expect(b.y.u).to.equal(b.x);197expect(b.x.z).to.equal('string in function');198done();199});200201it('should copy a buffer', function (done) {202203var tls = {204key: new Buffer([1, 2, 3, 4, 5]),205cert: new Buffer([1, 2, 3, 4, 5, 6, 10])206};207208var copiedTls = Hoek.clone(tls);209expect(Buffer.isBuffer(copiedTls.key)).to.equal(true);210expect(JSON.stringify(copiedTls.key)).to.equal(JSON.stringify(tls.key));211expect(Buffer.isBuffer(copiedTls.cert)).to.equal(true);212expect(JSON.stringify(copiedTls.cert)).to.equal(JSON.stringify(tls.cert));213done();214});215216it('clones an object with a prototype', function (done) {217218var Obj = function () {219220this.a = 5;221};222223Obj.prototype.b = function () {224225return 'c';226};227228var a = new Obj();229var b = Hoek.clone(a);230231expect(b.a).to.equal(5);232expect(b.b()).to.equal('c');233expect(a).to.deep.equal(b);234done();235});236237it('reuses cloned Date object', function (done) {238239var obj = {240a: new Date()241};242243obj.b = obj.a;244245var copy = Hoek.clone(obj);246expect(copy.a).to.equal(copy.b);247done();248});249250it('shallow copies an object with a prototype and isImmutable flag', function (done) {251252var Obj = function () {253254this.value = 5;255};256257Obj.prototype.b = function () {258259return 'c';260};261262Obj.prototype.isImmutable = true;263264var obj = {265a: new Obj()266};267268var copy = Hoek.clone(obj);269270expect(obj.a.value).to.equal(5);271expect(copy.a.value).to.equal(5);272expect(copy.a.b()).to.equal('c');273expect(obj.a).to.equal(copy.a);274done();275});276277it('clones an object with property getter without executing it', function (done) {278279var obj = {};280var value = 1;281var execCount = 0;282283Object.defineProperty(obj, 'test', {284enumerable: true,285configurable: true,286get: function () {287288++execCount;289return value;290}291});292293var copy = Hoek.clone(obj);294expect(execCount).to.equal(0);295expect(copy.test).to.equal(1);296expect(execCount).to.equal(1);297done();298});299300it('clones an object with property getter and setter', function (done) {301302var obj = {303_test: 0304};305306Object.defineProperty(obj, 'test', {307enumerable: true,308configurable: true,309get: function () {310311return this._test;312},313set: function (value) {314315this._test = value - 1;316}317});318319var copy = Hoek.clone(obj);320expect(copy.test).to.equal(0);321copy.test = 5;322expect(copy.test).to.equal(4);323done();324});325326it('clones an object with only property setter', function (done) {327328var obj = {329_test: 0330};331332Object.defineProperty(obj, 'test', {333enumerable: true,334configurable: true,335set: function (value) {336337this._test = value - 1;338}339});340341var copy = Hoek.clone(obj);342expect(copy._test).to.equal(0);343copy.test = 5;344expect(copy._test).to.equal(4);345done();346});347348it('clones an object with non-enumerable properties', function (done) {349350var obj = {351_test: 0352};353354Object.defineProperty(obj, 'test', {355enumerable: false,356configurable: true,357set: function (value) {358359this._test = value - 1;360}361});362363var copy = Hoek.clone(obj);364expect(copy._test).to.equal(0);365copy.test = 5;366expect(copy._test).to.equal(4);367done();368});369});370371describe('merge()', function () {372373it('deep copies source items', function (done) {374375var target = {376b: 3,377d: []378};379380var source = {381c: {382d: 1383},384d: [{ e: 1 }]385};386387Hoek.merge(target, source);388expect(target.c).to.not.equal(source.c);389expect(target.c).to.deep.equal(source.c);390expect(target.d).to.not.equal(source.d);391expect(target.d[0]).to.not.equal(source.d[0]);392expect(target.d).to.deep.equal(source.d);393done();394});395396it('merges array over an object', function (done) {397398var a = {399x: ['n', 'm']400};401402var b = {403x: {404n: '1',405m: '2'406}407};408409Hoek.merge(b, a);410expect(a.x[0]).to.equal('n');411expect(a.x.n).to.not.exist();412done();413});414415it('merges object over an array', function (done) {416417var a = {418x: ['n', 'm']419};420421var b = {422x: {423n: '1',424m: '2'425}426};427428Hoek.merge(a, b);429expect(a.x.n).to.equal('1');430expect(a.x[0]).to.not.exist();431done();432});433434it('does not throw if source is null', function (done) {435436var a = {};437var b = null;438var c = null;439440expect(function () {441442c = Hoek.merge(a, b);443}).to.not.throw();444445expect(c).to.equal(a);446done();447});448449it('does not throw if source is undefined', function (done) {450451var a = {};452var b;453var c = null;454455expect(function () {456457c = Hoek.merge(a, b);458}).to.not.throw();459460expect(c).to.equal(a);461done();462});463464it('throws if source is not an object', function (done) {465466expect(function () {467468var a = {};469var b = 0;470471Hoek.merge(a, b);472}).to.throw('Invalid source value: must be null, undefined, or an object');473done();474});475476it('throws if target is not an object', function (done) {477478expect(function () {479480var a = 0;481var b = {};482483Hoek.merge(a, b);484}).to.throw('Invalid target value: must be an object');485done();486});487488it('throws if target is not an array and source is', function (done) {489490expect(function () {491492var a = {};493var b = [1, 2];494495Hoek.merge(a, b);496}).to.throw('Cannot merge array onto an object');497done();498});499500it('returns the same object when merging arrays', function (done) {501502var a = [];503var b = [1, 2];504505expect(Hoek.merge(a, b)).to.equal(a);506done();507});508509it('combines an empty object with a non-empty object', function (done) {510511var a = {};512var b = nestedObj;513514var c = Hoek.merge(a, b);515expect(a).to.deep.equal(b);516expect(c).to.deep.equal(b);517done();518});519520it('overrides values in target', function (done) {521522var a = { x: 1, y: 2, z: 3, v: 5, t: 'test', m: 'abc' };523var b = { x: null, z: 4, v: 0, t: { u: 6 }, m: '123' };524525var c = Hoek.merge(a, b);526expect(c.x).to.equal(null);527expect(c.y).to.equal(2);528expect(c.z).to.equal(4);529expect(c.v).to.equal(0);530expect(c.m).to.equal('123');531expect(c.t).to.deep.equal({ u: 6 });532done();533});534535it('overrides values in target (flip)', function (done) {536537var a = { x: 1, y: 2, z: 3, v: 5, t: 'test', m: 'abc' };538var b = { x: null, z: 4, v: 0, t: { u: 6 }, m: '123' };539540var d = Hoek.merge(b, a);541expect(d.x).to.equal(1);542expect(d.y).to.equal(2);543expect(d.z).to.equal(3);544expect(d.v).to.equal(5);545expect(d.m).to.equal('abc');546expect(d.t).to.deep.equal('test');547done();548});549550it('retains Date properties', function (done) {551552var a = { x: new Date(1378776452757) };553554var b = Hoek.merge({}, a);555expect(a.x.getTime()).to.equal(b.x.getTime());556done();557});558559it('retains Date properties when merging keys', function (done) {560561var a = { x: new Date(1378776452757) };562563var b = Hoek.merge({ x: {} }, a);564expect(a.x.getTime()).to.equal(b.x.getTime());565done();566});567568it('overrides Buffer', function (done) {569570var a = { x: new Buffer('abc') };571572var b = Hoek.merge({ x: {} }, a);573expect(a.x.toString()).to.equal('abc');574done();575});576});577578describe('applyToDefaults()', function () {579580var defaults = {581a: 1,582b: 2,583c: {584d: 3,585e: [5, 6]586},587f: 6,588g: 'test'589};590591it('throws when target is null', function (done) {592593expect(function () {594595Hoek.applyToDefaults(null, {});596}).to.throw('Invalid defaults value: must be an object');597done();598});599600it('returns null if options is false', function (done) {601602var result = Hoek.applyToDefaults(defaults, false);603expect(result).to.equal(null);604done();605});606607it('returns null if options is null', function (done) {608609var result = Hoek.applyToDefaults(defaults, null);610expect(result).to.equal(null);611done();612});613614it('returns null if options is undefined', function (done) {615616var result = Hoek.applyToDefaults(defaults, undefined);617expect(result).to.equal(null);618done();619});620621it('returns a copy of defaults if options is true', function (done) {622623var result = Hoek.applyToDefaults(defaults, true);624expect(result).to.deep.equal(defaults);625done();626});627628it('applies object to defaults', function (done) {629630var obj = {631a: null,632c: {633e: [4]634},635f: 0,636g: {637h: 5638}639};640641var result = Hoek.applyToDefaults(defaults, obj);642expect(result.c.e).to.deep.equal([4]);643expect(result.a).to.equal(1);644expect(result.b).to.equal(2);645expect(result.f).to.equal(0);646expect(result.g).to.deep.equal({ h: 5 });647done();648});649650it('applies object to defaults with null', function (done) {651652var obj = {653a: null,654c: {655e: [4]656},657f: 0,658g: {659h: 5660}661};662663var result = Hoek.applyToDefaults(defaults, obj, true);664expect(result.c.e).to.deep.equal([4]);665expect(result.a).to.equal(null);666expect(result.b).to.equal(2);667expect(result.f).to.equal(0);668expect(result.g).to.deep.equal({ h: 5 });669done();670});671});672673describe('cloneWithShallow()', function () {674675it('deep clones except for listed keys', function (done) {676677var source = {678a: {679b: 5680},681c: {682d: 6683}684};685686var copy = Hoek.cloneWithShallow(source, ['c']);687expect(copy).to.deep.equal(source);688expect(copy).to.not.equal(source);689expect(copy.a).to.not.equal(source.a);690expect(copy.b).to.equal(source.b);691done();692});693694it('returns immutable value', function (done) {695696expect(Hoek.cloneWithShallow(5)).to.equal(5);697done();698});699700it('returns null value', function (done) {701702expect(Hoek.cloneWithShallow(null)).to.equal(null);703done();704});705706it('returns undefined value', function (done) {707708expect(Hoek.cloneWithShallow(undefined)).to.equal(undefined);709done();710});711712it('deep clones except for listed keys (including missing keys)', function (done) {713714var source = {715a: {716b: 5717},718c: {719d: 6720}721};722723var copy = Hoek.cloneWithShallow(source, ['c', 'v']);724expect(copy).to.deep.equal(source);725expect(copy).to.not.equal(source);726expect(copy.a).to.not.equal(source.a);727expect(copy.b).to.equal(source.b);728done();729});730});731732describe('applyToDefaultsWithShallow()', function () {733734it('shallow copies the listed keys from options without merging', function (done) {735736var defaults = {737a: {738b: 5,739e: 3740},741c: {742d: 7,743g: 1744}745};746747var options = {748a: {749b: 4750},751c: {752d: 6,753f: 7754}755};756757var merged = Hoek.applyToDefaultsWithShallow(defaults, options, ['a']);758expect(merged).to.deep.equal({ a: { b: 4 }, c: { d: 6, g: 1, f: 7 } });759expect(merged.a).to.equal(options.a);760expect(merged.a).to.not.equal(defaults.a);761expect(merged.c).to.not.equal(options.c);762expect(merged.c).to.not.equal(defaults.c);763done();764});765766it('shallow copies the nested keys (override)', function (done) {767768var defaults = {769a: {770b: 5771},772c: {773d: 7,774g: 1775}776};777778var options = {779a: {780b: 4781},782c: {783d: 6,784g: {785h: 8786}787}788};789790var merged = Hoek.applyToDefaultsWithShallow(defaults, options, ['c.g']);791expect(merged).to.deep.equal({ a: { b: 4 }, c: { d: 6, g: { h: 8 } } });792expect(merged.c.g).to.equal(options.c.g);793done();794});795796it('shallow copies the nested keys (missing)', function (done) {797798var defaults = {799a: {800b: 5801}802};803804var options = {805a: {806b: 4807},808c: {809g: {810h: 8811}812}813};814815var merged = Hoek.applyToDefaultsWithShallow(defaults, options, ['c.g']);816expect(merged).to.deep.equal({ a: { b: 4 }, c: { g: { h: 8 } } });817expect(merged.c.g).to.equal(options.c.g);818done();819});820821it('shallow copies the nested keys (override)', function (done) {822823var defaults = {824a: {825b: 5826},827c: {828g: {829d: 7830}831}832};833834var options = {835a: {836b: 4837},838c: {839g: {840h: 8841}842}843};844845var merged = Hoek.applyToDefaultsWithShallow(defaults, options, ['c.g']);846expect(merged).to.deep.equal({ a: { b: 4 }, c: { g: { h: 8 } } });847expect(merged.c.g).to.equal(options.c.g);848done();849});850851it('shallow copies the nested keys (deeper)', function (done) {852853var defaults = {854a: {855b: 5856}857};858859var options = {860a: {861b: 4862},863c: {864g: {865r: {866h: 8867}868}869}870};871872var merged = Hoek.applyToDefaultsWithShallow(defaults, options, ['c.g.r']);873expect(merged).to.deep.equal({ a: { b: 4 }, c: { g: { r: { h: 8 } } } });874expect(merged.c.g.r).to.equal(options.c.g.r);875done();876});877878it('shallow copies the nested keys (not present)', function (done) {879880var defaults = {881a: {882b: 5883}884};885886var options = {887a: {888b: 4889},890c: {891g: {892r: {893h: 8894}895}896}897};898899var merged = Hoek.applyToDefaultsWithShallow(defaults, options, ['x.y']);900expect(merged).to.deep.equal({ a: { b: 4 }, c: { g: { r: { h: 8 } } } });901done();902});903904it('shallow copies the listed keys in the defaults', function (done) {905906var defaults = {907a: {908b: 1909}910};911912var merged = Hoek.applyToDefaultsWithShallow(defaults, {}, ['a']);913expect(merged.a).to.equal(defaults.a);914done();915});916917it('shallow copies the listed keys in the defaults (true)', function (done) {918919var defaults = {920a: {921b: 1922}923};924925var merged = Hoek.applyToDefaultsWithShallow(defaults, true, ['a']);926expect(merged.a).to.equal(defaults.a);927done();928});929930it('returns null on false', function (done) {931932var defaults = {933a: {934b: 1935}936};937938var merged = Hoek.applyToDefaultsWithShallow(defaults, false, ['a']);939expect(merged).to.equal(null);940done();941});942943it('throws on missing defaults', function (done) {944945expect(function () {946947Hoek.applyToDefaultsWithShallow(null, {}, ['a']);948}).to.throw('Invalid defaults value: must be an object');949done();950});951952it('throws on invalid defaults', function (done) {953954expect(function () {955956Hoek.applyToDefaultsWithShallow('abc', {}, ['a']);957}).to.throw('Invalid defaults value: must be an object');958done();959});960961it('throws on invalid options', function (done) {962963expect(function () {964965Hoek.applyToDefaultsWithShallow({}, 'abc', ['a']);966}).to.throw('Invalid options value: must be true, falsy or an object');967done();968});969970it('throws on missing keys', function (done) {971972expect(function () {973974Hoek.applyToDefaultsWithShallow({}, true);975}).to.throw('Invalid keys');976done();977});978979it('throws on invalid keys', function (done) {980981expect(function () {982983Hoek.applyToDefaultsWithShallow({}, true, 'a');984}).to.throw('Invalid keys');985done();986});987});988989describe('deepEqual()', function () {990991it('compares simple values', function (done) {992993expect(Hoek.deepEqual('x', 'x')).to.be.true();994expect(Hoek.deepEqual('x', 'y')).to.be.false();995expect(Hoek.deepEqual('x1', 'x')).to.be.false();996expect(Hoek.deepEqual(-0, +0)).to.be.false();997expect(Hoek.deepEqual(-0, -0)).to.be.true();998expect(Hoek.deepEqual(+0, +0)).to.be.true();999expect(Hoek.deepEqual(+0, -0)).to.be.false();1000expect(Hoek.deepEqual(1, 1)).to.be.true();1001expect(Hoek.deepEqual(0, 0)).to.be.true();1002expect(Hoek.deepEqual(-1, 1)).to.be.false();1003expect(Hoek.deepEqual(NaN, 0)).to.be.false();1004expect(Hoek.deepEqual(NaN, NaN)).to.be.true();1005done();1006});10071008it('compares different types', function (done) {10091010expect(Hoek.deepEqual([], 5)).to.be.false();1011expect(Hoek.deepEqual(5, [])).to.be.false();1012expect(Hoek.deepEqual({}, null)).to.be.false();1013expect(Hoek.deepEqual(null, {})).to.be.false();1014expect(Hoek.deepEqual('abc', {})).to.be.false();1015expect(Hoek.deepEqual({}, 'abc')).to.be.false();1016done();1017});10181019it('compares empty structures', function (done) {10201021expect(Hoek.deepEqual([], [])).to.be.true();1022expect(Hoek.deepEqual({}, {})).to.be.true();1023expect(Hoek.deepEqual([], {})).to.be.false();1024done();1025});10261027it('compares empty arguments object', function (done) {10281029var compare = function () {10301031expect(Hoek.deepEqual([], arguments)).to.be.false();1032};10331034compare();1035done();1036});10371038it('compares empty arguments objects', function (done) {10391040var compare = function () {10411042var arg1 = arguments;10431044var inner = function () {10451046expect(Hoek.deepEqual(arg1, arguments)).to.be.false(); // callee is not the same1047};10481049inner();1050};10511052compare();1053done();1054});10551056it('compares dates', function (done) {10571058expect(Hoek.deepEqual(new Date(2015, 1, 1), new Date(2015, 1, 1))).to.be.true();1059expect(Hoek.deepEqual(new Date(100), new Date(101))).to.be.false();1060expect(Hoek.deepEqual(new Date(), {})).to.be.false();1061done();1062});10631064it('compares regular expressions', function (done) {10651066expect(Hoek.deepEqual(/\s/, new RegExp('\\\s'))).to.be.true();1067expect(Hoek.deepEqual(/\s/g, /\s/g)).to.be.true();1068expect(Hoek.deepEqual(/a/, {})).to.be.false();1069expect(Hoek.deepEqual(/\s/g, /\s/i)).to.be.false();1070expect(Hoek.deepEqual(/a/g, /b/g)).to.be.false();1071done();1072});10731074it('compares arrays', function (done) {10751076expect(Hoek.deepEqual([[1]], [[1]])).to.be.true();1077expect(Hoek.deepEqual([1, 2, 3], [1, 2, 3])).to.be.true();1078expect(Hoek.deepEqual([1, 2, 3], [1, 3, 2])).to.be.false();1079expect(Hoek.deepEqual([1, 2, 3], [1, 2])).to.be.false();1080expect(Hoek.deepEqual([1], [1])).to.be.true();1081done();1082});10831084it('compares buffers', function (done) {10851086expect(Hoek.deepEqual(new Buffer([1, 2, 3]), new Buffer([1, 2, 3]))).to.be.true();1087expect(Hoek.deepEqual(new Buffer([1, 2, 3]), new Buffer([1, 3, 2]))).to.be.false();1088expect(Hoek.deepEqual(new Buffer([1, 2, 3]), new Buffer([1, 2]))).to.be.false();1089expect(Hoek.deepEqual(new Buffer([1, 2, 3]), {})).to.be.false();1090expect(Hoek.deepEqual(new Buffer([1, 2, 3]), [1, 2, 3])).to.be.false();1091done();1092});10931094it('compares objects', function (done) {10951096expect(Hoek.deepEqual({ a: 1, b: 2, c: 3 }, { a: 1, b: 2, c: 3 })).to.be.true();1097expect(Hoek.deepEqual({ foo: 'bar' }, { foo: 'baz' })).to.be.false();1098expect(Hoek.deepEqual({ foo: { bar: 'foo' } }, { foo: { bar: 'baz' } })).to.be.false();1099done();1100});11011102it('handles circular dependency', function (done) {11031104var a = {};1105a.x = a;11061107var b = Hoek.clone(a);1108expect(Hoek.deepEqual(a, b)).to.be.true();1109done();1110});11111112it('compares an object with property getter without executing it', function (done) {11131114var obj = {};1115var value = 1;1116var execCount = 0;11171118Object.defineProperty(obj, 'test', {1119enumerable: true,1120configurable: true,1121get: function () {11221123++execCount;1124return value;1125}1126});11271128var copy = Hoek.clone(obj);1129expect(Hoek.deepEqual(obj, copy)).to.be.true();1130expect(execCount).to.equal(0);1131expect(copy.test).to.equal(1);1132expect(execCount).to.equal(1);1133done();1134});11351136it('compares objects with property getters', function (done) {11371138var obj = {};1139Object.defineProperty(obj, 'test', {1140enumerable: true,1141configurable: true,1142get: function () {11431144return 1;1145}1146});11471148var ref = {};1149Object.defineProperty(ref, 'test', {1150enumerable: true,1151configurable: true,1152get: function () {11531154return 2;1155}1156});11571158expect(Hoek.deepEqual(obj, ref)).to.be.false();1159done();1160});11611162it('compares object prototypes', function (done) {11631164var Obj = function () {11651166this.a = 5;1167};11681169Obj.prototype.b = function () {11701171return this.a;1172};11731174var Ref = function () {11751176this.a = 5;1177};11781179Ref.prototype.b = function () {11801181return this.a;1182};11831184expect(Hoek.deepEqual(new Obj(), new Ref())).to.be.false();1185expect(Hoek.deepEqual(new Obj(), new Obj())).to.be.true();1186expect(Hoek.deepEqual(new Ref(), new Ref())).to.be.true();1187done();1188});11891190it('compares plain objects', function (done) {11911192var a = Object.create(null);1193var b = Object.create(null);11941195a.b = 'c';1196b.b = 'c';11971198expect(Hoek.deepEqual(a, b)).to.be.true();1199expect(Hoek.deepEqual(a, { b: 'c' })).to.be.false();1200done();1201});12021203it('compares an object with an empty object', function (done) {12041205var a = { a: 1, b: 2 };12061207expect(Hoek.deepEqual({}, a)).to.be.false();1208expect(Hoek.deepEqual(a, {})).to.be.false();1209done();1210});12111212it('compares an object ignoring the prototype', function (done) {12131214var a = Object.create(null);1215var b = {};12161217expect(Hoek.deepEqual(a, b, { prototype: false })).to.be.true();1218done();1219});12201221it('compares an object ignoring the prototype recursively', function (done) {12221223var a = [Object.create(null)];1224var b = [{}];12251226expect(Hoek.deepEqual(a, b, { prototype: false })).to.be.true();1227done();1228});1229});12301231describe('unique()', function () {12321233it('ensures uniqueness within array of objects based on subkey', function (done) {12341235var a = Hoek.unique(dupsArray, 'x');1236expect(a).to.deep.equal(reducedDupsArray);1237done();1238});12391240it('removes duplicated without key', function (done) {12411242expect(Hoek.unique([1, 2, 3, 4, 2, 1, 5])).to.deep.equal([1, 2, 3, 4, 5]);1243done();1244});1245});12461247describe('mapToObject()', function () {12481249it('returns null on null array', function (done) {12501251var a = Hoek.mapToObject(null);1252expect(a).to.equal(null);1253done();1254});12551256it('converts basic array to existential object', function (done) {12571258var keys = [1, 2, 3, 4];1259var a = Hoek.mapToObject(keys);1260for (var i in keys) {1261expect(a[keys[i]]).to.equal(true);1262}1263done();1264});12651266it('converts array of objects to existential object', function (done) {12671268var keys = [{ x: 1 }, { x: 2 }, { x: 3 }, { y: 4 }];1269var subkey = 'x';1270var a = Hoek.mapToObject(keys, subkey);1271expect(a).to.deep.equal({ 1: true, 2: true, 3: true });1272done();1273});1274});12751276describe('intersect()', function () {12771278it('returns the common objects of two arrays', function (done) {12791280var array1 = [1, 2, 3, 4, 4, 5, 5];1281var array2 = [5, 4, 5, 6, 7];1282var common = Hoek.intersect(array1, array2);1283expect(common.length).to.equal(2);1284done();1285});12861287it('returns just the first common object of two arrays', function (done) {12881289var array1 = [1, 2, 3, 4, 4, 5, 5];1290var array2 = [5, 4, 5, 6, 7];1291var common = Hoek.intersect(array1, array2, true);1292expect(common).to.equal(5);1293done();1294});12951296it('returns null when no common and returning just the first common object of two arrays', function (done) {12971298var array1 = [1, 2, 3, 4, 4, 5, 5];1299var array2 = [6, 7];1300var common = Hoek.intersect(array1, array2, true);1301expect(common).to.equal(null);1302done();1303});13041305it('returns an empty array if either input is null', function (done) {13061307expect(Hoek.intersect([1], null).length).to.equal(0);1308expect(Hoek.intersect(null, [1]).length).to.equal(0);1309done();1310});13111312it('returns the common objects of object and array', function (done) {13131314var array1 = [1, 2, 3, 4, 4, 5, 5];1315var array2 = [5, 4, 5, 6, 7];1316var common = Hoek.intersect(Hoek.mapToObject(array1), array2);1317expect(common.length).to.equal(2);1318done();1319});1320});13211322describe('contain()', function () {13231324it('tests strings', function (done) {13251326expect(Hoek.contain('abc', 'ab')).to.be.true();1327expect(Hoek.contain('abc', 'abc', { only: true })).to.be.true();1328expect(Hoek.contain('aaa', 'a', { only: true })).to.be.true();1329expect(Hoek.contain('abc', 'b', { once: true })).to.be.true();1330expect(Hoek.contain('abc', ['a', 'c'])).to.be.true();1331expect(Hoek.contain('abc', ['a', 'd'], { part: true })).to.be.true();13321333expect(Hoek.contain('abc', 'ac')).to.be.false();1334expect(Hoek.contain('abcd', 'abc', { only: true })).to.be.false();1335expect(Hoek.contain('aab', 'a', { only: true })).to.be.false();1336expect(Hoek.contain('abb', 'b', { once: true })).to.be.false();1337expect(Hoek.contain('abc', ['a', 'd'])).to.be.false();1338expect(Hoek.contain('abc', ['ab', 'bc'])).to.be.false(); // Overlapping values not supported1339done();1340});13411342it('tests arrays', function (done) {13431344expect(Hoek.contain([1, 2, 3], 1)).to.be.true();1345expect(Hoek.contain([{ a: 1 }], { a: 1 }, { deep: true })).to.be.true();1346expect(Hoek.contain([1, 2, 3], [1, 2])).to.be.true();1347expect(Hoek.contain([{ a: 1 }], [{ a: 1 }], { deep: true })).to.be.true();1348expect(Hoek.contain([1, 1, 2], [1, 2], { only: true })).to.be.true();1349expect(Hoek.contain([1, 2], [1, 2], { once: true })).to.be.true();1350expect(Hoek.contain([1, 2, 3], [1, 4], { part: true })).to.be.true();1351expect(Hoek.contain([[1], [2]], [[1]], { deep: true })).to.be.true();13521353expect(Hoek.contain([1, 2, 3], 4)).to.be.false();1354expect(Hoek.contain([{ a: 1 }], { a: 2 }, { deep: true })).to.be.false();1355expect(Hoek.contain([{ a: 1 }], { a: 1 })).to.be.false();1356expect(Hoek.contain([1, 2, 3], [4, 5])).to.be.false();1357expect(Hoek.contain([[3], [2]], [[1]])).to.be.false();1358expect(Hoek.contain([[1], [2]], [[1]])).to.be.false();1359expect(Hoek.contain([{ a: 1 }], [{ a: 2 }], { deep: true })).to.be.false();1360expect(Hoek.contain([1, 3, 2], [1, 2], { only: true })).to.be.false();1361expect(Hoek.contain([1, 2, 2], [1, 2], { once: true })).to.be.false();1362expect(Hoek.contain([0, 2, 3], [1, 4], { part: true })).to.be.false();1363done();1364});13651366it('tests objects', function (done) {13671368expect(Hoek.contain({ a: 1, b: 2, c: 3 }, 'a')).to.be.true();1369expect(Hoek.contain({ a: 1, b: 2, c: 3 }, ['a', 'c'])).to.be.true();1370expect(Hoek.contain({ a: 1, b: 2, c: 3 }, ['a', 'b', 'c'], { only: true })).to.be.true();1371expect(Hoek.contain({ a: 1, b: 2, c: 3 }, { a: 1 })).to.be.true();1372expect(Hoek.contain({ a: 1, b: 2, c: 3 }, { a: 1, c: 3 })).to.be.true();1373expect(Hoek.contain({ a: 1, b: 2, c: 3 }, { a: 1, d: 4 }, { part: true })).to.be.true();1374expect(Hoek.contain({ a: 1, b: 2, c: 3 }, { a: 1, b: 2, c: 3 }, { only: true })).to.be.true();1375expect(Hoek.contain({ a: [1], b: [2], c: [3] }, { a: [1], c: [3] }, { deep: true })).to.be.true();1376expect(Hoek.contain({ a: [{ b: 1 }, { c: 2 }, { d: 3, e: 4 }] }, { a: [{ b: 1 }, { d: 3 }] }, { deep: true })).to.be.true();1377expect(Hoek.contain({ a: [{ b: 1 }, { c: 2 }, { d: 3, e: 4 }] }, { a: [{ b: 1 }, { d: 3 }] }, { deep: true, part: true })).to.be.true();1378expect(Hoek.contain({ a: [{ b: 1 }, { c: 2 }, { d: 3, e: 4 }] }, { a: [{ b: 1 }, { d: 3 }] }, { deep: true, part: false })).to.be.false();1379expect(Hoek.contain({ a: [{ b: 1 }, { c: 2 }, { d: 3, e: 4 }] }, { a: [{ b: 1 }, { d: 3 }] }, { deep: true, only: true })).to.be.false();1380expect(Hoek.contain({ a: [{ b: 1 }, { c: 2 }, { d: 3, e: 4 }] }, { a: [{ b: 1 }, { d: 3 }] }, { deep: true, only: false })).to.be.true();13811382expect(Hoek.contain({ a: 1, b: 2, c: 3 }, 'd')).to.be.false();1383expect(Hoek.contain({ a: 1, b: 2, c: 3 }, ['a', 'd'])).to.be.false();1384expect(Hoek.contain({ a: 1, b: 2, c: 3, d: 4 }, ['a', 'b', 'c'], { only: true })).to.be.false();1385expect(Hoek.contain({ a: 1, b: 2, c: 3 }, { a: 2 })).to.be.false();1386expect(Hoek.contain({ a: 1, b: 2, c: 3 }, { a: 2, b: 2 }, { part: true })).to.be.false(); // part does not ignore bad value1387expect(Hoek.contain({ a: 1, b: 2, c: 3 }, { a: 1, d: 3 })).to.be.false();1388expect(Hoek.contain({ a: 1, b: 2, c: 3 }, { a: 1, d: 4 })).to.be.false();1389expect(Hoek.contain({ a: 1, b: 2, c: 3 }, { a: 1, b: 2 }, { only: true })).to.be.false();1390expect(Hoek.contain({ a: [1], b: [2], c: [3] }, { a: [1], c: [3] })).to.be.false();1391expect(Hoek.contain({ a: { b: { c: 1, d: 2 } } }, { a: { b: { c: 1 } } })).to.be.false();1392expect(Hoek.contain({ a: { b: { c: 1, d: 2 } } }, { a: { b: { c: 1 } } }, { deep: true })).to.be.true();1393expect(Hoek.contain({ a: { b: { c: 1, d: 2 } } }, { a: { b: { c: 1 } } }, { deep: true, only: true })).to.be.false();1394expect(Hoek.contain({ a: { b: { c: 1, d: 2 } } }, { a: { b: { c: 1 } } }, { deep: true, only: false })).to.be.true();1395expect(Hoek.contain({ a: { b: { c: 1, d: 2 } } }, { a: { b: { c: 1 } } }, { deep: true, part: true })).to.be.true();1396expect(Hoek.contain({ a: { b: { c: 1, d: 2 } } }, { a: { b: { c: 1 } } }, { deep: true, part: false })).to.be.false();13971398// Getter check1399var Foo = function (bar) {14001401this.bar = bar;1402};14031404Object.defineProperty(Foo.prototype, 'baz', {1405enumerable: true,1406get: function () {14071408return this.bar;1409}1410});14111412expect(Hoek.contain({ a: new Foo('b') }, { a: new Foo('b') }, { deep: true })).to.be.true();1413expect(Hoek.contain({ a: new Foo('b') }, { a: new Foo('b') }, { deep: true, part: true })).to.be.true();1414expect(Hoek.contain({ a: new Foo('b') }, { a: { baz: 'b' } }, { deep: true })).to.be.true();1415expect(Hoek.contain({ a: new Foo('b') }, { a: { baz: 'b' } }, { deep: true, only: true })).to.be.false();1416expect(Hoek.contain({ a: new Foo('b') }, { a: { baz: 'b' } }, { deep: true, part: false })).to.be.false();1417expect(Hoek.contain({ a: new Foo('b') }, { a: { baz: 'b' } }, { deep: true, part: true })).to.be.true();14181419done();1420});1421});14221423describe('flatten()', function () {14241425it('returns a flat array', function (done) {14261427var result = Hoek.flatten([1, 2, [3, 4, [5, 6], [7], 8], [9], [10, [11, 12]], 13]);1428expect(result.length).to.equal(13);1429expect(result).to.deep.equal([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13]);1430done();1431});1432});14331434describe('reach()', function () {14351436var obj = {1437a: {1438b: {1439c: {1440d: 1,1441e: 21442},1443f: 'hello'1444},1445g: {1446h: 31447}1448},1449i: function () { },1450j: null,1451k: [4, 8, 9, 1]1452};14531454obj.i.x = 5;14551456it('returns first value of array', function (done) {14571458expect(Hoek.reach(obj, 'k.0')).to.equal(4);1459done();1460});14611462it('returns last value of array using negative index', function (done) {14631464expect(Hoek.reach(obj, 'k.-2')).to.equal(9);1465done();1466});14671468it('returns a valid member', function (done) {14691470expect(Hoek.reach(obj, 'a.b.c.d')).to.equal(1);1471done();1472});14731474it('returns a valid member with separator override', function (done) {14751476expect(Hoek.reach(obj, 'a/b/c/d', '/')).to.equal(1);1477done();1478});14791480it('returns undefined on null object', function (done) {14811482expect(Hoek.reach(null, 'a.b.c.d')).to.equal(undefined);1483done();1484});14851486it('returns undefined on missing object member', function (done) {14871488expect(Hoek.reach(obj, 'a.b.c.d.x')).to.equal(undefined);1489done();1490});14911492it('returns undefined on missing function member', function (done) {14931494expect(Hoek.reach(obj, 'i.y', { functions: true })).to.equal(undefined);1495done();1496});14971498it('throws on missing member in strict mode', function (done) {14991500expect(function () {15011502Hoek.reach(obj, 'a.b.c.o.x', { strict: true });1503}).to.throw('Missing segment o in reach path a.b.c.o.x');15041505done();1506});15071508it('returns undefined on invalid member', function (done) {15091510expect(Hoek.reach(obj, 'a.b.c.d-.x')).to.equal(undefined);1511done();1512});15131514it('returns function member', function (done) {15151516expect(typeof Hoek.reach(obj, 'i')).to.equal('function');1517done();1518});15191520it('returns function property', function (done) {15211522expect(Hoek.reach(obj, 'i.x')).to.equal(5);1523done();1524});15251526it('returns null', function (done) {15271528expect(Hoek.reach(obj, 'j')).to.equal(null);1529done();1530});15311532it('throws on function property when functions not allowed', function (done) {15331534expect(function () {15351536Hoek.reach(obj, 'i.x', { functions: false });1537}).to.throw('Invalid segment x in reach path i.x');15381539done();1540});15411542it('will return a default value if property is not found', function (done) {15431544expect(Hoek.reach(obj, 'a.b.q', { default: 'defaultValue' })).to.equal('defaultValue');1545done();1546});15471548it('will return a default value if path is not found', function (done) {15491550expect(Hoek.reach(obj, 'q', { default: 'defaultValue' })).to.equal('defaultValue');1551done();1552});15531554it('allows a falsey value to be used as the default value', function (done) {15551556expect(Hoek.reach(obj, 'q', { default: '' })).to.equal('');1557done();1558});1559});15601561describe('reachTemplate()', function () {15621563it('applies object to template', function (done) {15641565var obj = {1566a: {1567b: {1568c: {1569d: 11570}1571}1572},1573j: null,1574k: [4, 8, 9, 1]1575};15761577var template = '{k.0}:{k.-2}:{a.b.c.d}:{x.y}:{j}';15781579expect(Hoek.reachTemplate(obj, template)).to.equal('4:9:1::');1580done();1581});15821583it('applies object to template (options)', function (done) {15841585var obj = {1586a: {1587b: {1588c: {1589d: 11590}1591}1592},1593j: null,1594k: [4, 8, 9, 1]1595};15961597var template = '{k/0}:{k/-2}:{a/b/c/d}:{x/y}:{j}';15981599expect(Hoek.reachTemplate(obj, template, '/')).to.equal('4:9:1::');1600done();1601});1602});16031604describe('callStack()', function () {16051606it('returns the full call stack', function (done) {16071608var stack = Hoek.callStack();1609expect(stack[0][0]).to.contain('index.js');1610expect(stack[0][2]).to.equal(26);1611done();1612});1613});16141615describe('displayStack ()', function () {16161617it('returns the full call stack for display', function (done) {16181619var stack = Hoek.displayStack();1620expect(stack[0]).to.contain(Path.normalize('/test/index.js') + ':');1621done();1622});16231624it('includes constructor functions correctly', function (done) {16251626var Something = function (next) {16271628next();1629};16301631var something = new Something(function () {16321633var stack = Hoek.displayStack();1634expect(stack[1]).to.contain('new Something');1635done();1636});1637});1638});16391640describe('abort()', function () {16411642it('exits process when not in test mode', function (done) {16431644var env = process.env.NODE_ENV;1645var write = process.stdout.write;1646var exit = process.exit;16471648process.env.NODE_ENV = 'nottatest';1649process.stdout.write = function () { };1650process.exit = function (state) {16511652process.exit = exit;1653process.env.NODE_ENV = env;1654process.stdout.write = write;16551656expect(state).to.equal(1);1657done();1658};16591660Hoek.abort('Boom');1661});16621663it('throws when not in test mode and abortThrow is true', function (done) {16641665var env = process.env.NODE_ENV;1666process.env.NODE_ENV = 'nottatest';1667Hoek.abortThrow = true;16681669var fn = function () {16701671Hoek.abort('my error message');1672};16731674expect(fn).to.throw('my error message');1675Hoek.abortThrow = false;1676process.env.NODE_ENV = env;16771678done();1679});16801681it('respects hideStack argument', function (done) {16821683var env = process.env.NODE_ENV;1684var write = process.stdout.write;1685var exit = process.exit;1686var output = '';16871688process.exit = function () { };1689process.env.NODE_ENV = '';1690process.stdout.write = function (message) {16911692output = message;1693};16941695Hoek.abort('my error message', true);16961697process.env.NODE_ENV = env;1698process.stdout.write = write;1699process.exit = exit;17001701expect(output).to.equal('ABORT: my error message\n\t\n');17021703done();1704});17051706it('throws in test mode', function (done) {17071708var env = process.env.NODE_ENV;1709process.env.NODE_ENV = 'test';17101711expect(function () {17121713Hoek.abort('my error message', true);1714}).to.throw('my error message');17151716process.env.NODE_ENV = env;1717done();1718});17191720it('throws in test mode with default message', function (done) {17211722var env = process.env.NODE_ENV;1723process.env.NODE_ENV = 'test';17241725expect(function () {17261727Hoek.abort('', true);1728}).to.throw('Unknown error');17291730process.env.NODE_ENV = env;1731done();1732});17331734it('defaults to showing stack', function (done) {17351736var env = process.env.NODE_ENV;1737var write = process.stdout.write;1738var exit = process.exit;1739var output = '';17401741process.exit = function () { };1742process.env.NODE_ENV = '';1743process.stdout.write = function (message) {17441745output = message;1746};17471748Hoek.abort('my error message');17491750process.env.NODE_ENV = env;1751process.stdout.write = write;1752process.exit = exit;17531754expect(output).to.contain('index.js');17551756done();1757});1758});17591760describe('assert()', function () {17611762it('throws an Error when using assert in a test', function (done) {17631764var fn = function () {17651766Hoek.assert(false, 'my error message');1767};17681769expect(fn).to.throw('my error message');1770done();1771});17721773it('throws an Error when using assert in a test with no message', function (done) {17741775var fn = function () {17761777Hoek.assert(false);1778};17791780expect(fn).to.throw('Unknown error');1781done();1782});17831784it('throws an Error when using assert in a test with multipart message', function (done) {17851786var fn = function () {17871788Hoek.assert(false, 'This', 'is', 'my message');1789};17901791expect(fn).to.throw('This is my message');1792done();1793});17941795it('throws an Error when using assert in a test with multipart message (empty)', function (done) {17961797var fn = function () {17981799Hoek.assert(false, 'This', 'is', '', 'my message');1800};18011802expect(fn).to.throw('This is my message');1803done();1804});18051806it('throws an Error when using assert in a test with object message', function (done) {18071808var fn = function () {18091810Hoek.assert(false, 'This', 'is', { spinal: 'tap' });1811};18121813expect(fn).to.throw('This is {"spinal":"tap"}');1814done();1815});18161817it('throws an Error when using assert in a test with multipart string and error messages', function (done) {18181819var fn = function () {18201821Hoek.assert(false, 'This', 'is', new Error('spinal'), new Error('tap'));1822};18231824expect(fn).to.throw('This is spinal tap');1825done();1826});18271828it('throws an Error when using assert in a test with error object message', function (done) {18291830var fn = function () {18311832Hoek.assert(false, new Error('This is spinal tap'));1833};18341835expect(fn).to.throw('This is spinal tap');1836done();1837});18381839it('throws the same Error that is passed to it if there is only one error passed', function (done) {18401841var error = new Error('ruh roh');1842var error2 = new Error('ruh roh');18431844var fn = function () {18451846Hoek.assert(false, error);1847};18481849try {1850fn();1851} catch (err) {1852expect(error).to.equal(error); // should be the same reference1853expect(error).to.not.equal(error2); // error with the same message should not match1854}18551856done();1857});1858});18591860describe('Timer', function () {18611862it('returns time elapsed', function (done) {18631864var timer = new Hoek.Timer();1865setTimeout(function () {18661867expect(timer.elapsed()).to.be.above(9);1868done();1869}, 12);1870});1871});18721873describe('Bench', function () {18741875it('returns time elapsed', function (done) {18761877var timer = new Hoek.Bench();1878setTimeout(function () {18791880expect(timer.elapsed()).to.be.above(9);1881done();1882}, 12);1883});1884});18851886describe('escapeRegex()', function () {18871888it('escapes all special regular expression characters', function (done) {18891890var a = Hoek.escapeRegex('4^f$s.4*5+-_?%=#!:@|~\\/`"(>)[<]d{}s,');1891expect(a).to.equal('4\\^f\\$s\\.4\\*5\\+\\-_\\?%\\=#\\!\\:@\\|~\\\\\\/`"\\(>\\)\\[<\\]d\\{\\}s\\,');1892done();1893});1894});18951896describe('Base64Url', function () {18971898var base64str = 'AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8gISIjJCUmJygpKissLS4vMDEyMzQ1Njc4OTo7PD0-P0BBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWltcXV5fYGFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6e3x9fn-AgYKDhIWGh4iJiouMjY6PkJGSk5SVlpeYmZqbnJ2en6ChoqOkpaanqKmqq6ytrq-wsbKztLW2t7i5uru8vb6_wMHCw8TFxsfIycrLzM3Oz9DR0tPU1dbX2Nna29zd3t_g4eLj5OXm5-jp6uvs7e7v8PHy8_T19vf4-fr7_P3-_w';1899var str = unescape('%00%01%02%03%04%05%06%07%08%09%0A%0B%0C%0D%0E%0F%10%11%12%13%14%15%16%17%18%19%1A%1B%1C%1D%1E%1F%20%21%22%23%24%25%26%27%28%29*+%2C-./0123456789%3A%3B%3C%3D%3E%3F@ABCDEFGHIJKLMNOPQRSTUVWXYZ%5B%5C%5D%5E_%60abcdefghijklmnopqrstuvwxyz%7B%7C%7D%7E%7F%80%81%82%83%84%85%86%87%88%89%8A%8B%8C%8D%8E%8F%90%91%92%93%94%95%96%97%98%99%9A%9B%9C%9D%9E%9F%A0%A1%A2%A3%A4%A5%A6%A7%A8%A9%AA%AB%AC%AD%AE%AF%B0%B1%B2%B3%B4%B5%B6%B7%B8%B9%BA%BB%BC%BD%BE%BF%C0%C1%C2%C3%C4%C5%C6%C7%C8%C9%CA%CB%CC%CD%CE%CF%D0%D1%D2%D3%D4%D5%D6%D7%D8%D9%DA%DB%DC%DD%DE%DF%E0%E1%E2%E3%E4%E5%E6%E7%E8%E9%EA%EB%EC%ED%EE%EF%F0%F1%F2%F3%F4%F5%F6%F7%F8%F9%FA%FB%FC%FD%FE%FF');19001901describe('base64urlEncode()', function () {19021903it('should base64 URL-safe a string', function (done) {19041905expect(Hoek.base64urlEncode(str)).to.equal(base64str);1906done();1907});19081909it('encodes a buffer', function (done) {19101911expect(Hoek.base64urlEncode(new Buffer(str, 'binary'))).to.equal(base64str);1912done();1913});19141915it('should base64 URL-safe a hex string', function (done) {19161917var buffer = new Buffer(str, 'binary');1918expect(Hoek.base64urlEncode(buffer.toString('hex'), 'hex')).to.equal(base64str);1919done();1920});19211922it('works on larger input strings', function (done) {19231924var input = Fs.readFileSync(Path.join(__dirname, 'index.js')).toString();1925var encoded = Hoek.base64urlEncode(input);19261927expect(encoded).to.not.contain('+');1928expect(encoded).to.not.contain('/');19291930var decoded = Hoek.base64urlDecode(encoded);19311932expect(decoded).to.equal(input);1933done();1934});1935});19361937describe('base64urlDecode()', function () {19381939it('should un-base64 URL-safe a string', function (done) {19401941expect(Hoek.base64urlDecode(base64str)).to.equal(str);1942done();1943});19441945it('should un-base64 URL-safe a string into hex', function (done) {19461947expect(Hoek.base64urlDecode(base64str, 'hex')).to.equal(new Buffer(str, 'binary').toString('hex'));1948done();1949});19501951it('should un-base64 URL-safe a string and return a buffer', function (done) {19521953var buf = Hoek.base64urlDecode(base64str, 'buffer');1954expect(buf instanceof Buffer).to.equal(true);1955expect(buf.toString('binary')).to.equal(str);1956done();1957});19581959it('returns error on undefined input', function (done) {19601961expect(Hoek.base64urlDecode().message).to.exist();1962done();1963});19641965it('returns error on invalid input', function (done) {19661967expect(Hoek.base64urlDecode('*').message).to.exist();1968done();1969});1970});1971});19721973describe('escapeHeaderAttribute()', function () {19741975it('should not alter ascii values', function (done) {19761977var a = Hoek.escapeHeaderAttribute('My Value');1978expect(a).to.equal('My Value');1979done();1980});19811982it('escapes all special HTTP header attribute characters', function (done) {19831984var a = Hoek.escapeHeaderAttribute('I said go!!!#"' + String.fromCharCode(92));1985expect(a).to.equal('I said go!!!#\\"\\\\');1986done();1987});19881989it('throws on large unicode characters', function (done) {19901991var fn = function () {19921993Hoek.escapeHeaderAttribute('this is a test' + String.fromCharCode(500) + String.fromCharCode(300));1994};19951996expect(fn).to.throw(Error);1997done();1998});19992000it('throws on CRLF to prevent response splitting', function (done) {20012002var fn = function () {20032004Hoek.escapeHeaderAttribute('this is a test\r\n');2005};20062007expect(fn).to.throw(Error);2008done();2009});2010});20112012describe('escapeHtml()', function () {20132014it('escapes all special HTML characters', function (done) {20152016var a = Hoek.escapeHtml('&<>"\'`');2017expect(a).to.equal('&<>"'`');2018done();2019});20202021it('returns empty string on falsy input', function (done) {20222023var a = Hoek.escapeHtml('');2024expect(a).to.equal('');2025done();2026});20272028it('returns unchanged string on no reserved input', function (done) {20292030var a = Hoek.escapeHtml('abc');2031expect(a).to.equal('abc');2032done();2033});2034});20352036describe('nextTick()', function () {20372038it('calls the provided callback on nextTick', function (done) {20392040var a = 0;20412042var inc = function (step, next) {20432044a += step;2045next();2046};20472048var ticked = Hoek.nextTick(inc);20492050ticked(5, function () {20512052expect(a).to.equal(6);2053done();2054});20552056expect(a).to.equal(0);2057inc(1, function () {20582059expect(a).to.equal(1);2060});2061});2062});20632064describe('once()', function () {20652066it('allows function to only execute once', function (done) {20672068var gen = 0;2069var add = function (x) {20702071gen += x;2072};20732074add(5);2075expect(gen).to.equal(5);2076add = Hoek.once(add);2077add(5);2078expect(gen).to.equal(10);2079add(5);2080expect(gen).to.equal(10);2081done();2082});20832084it('double once wraps one time', function (done) {20852086var method = function () { };2087method = Hoek.once(method);2088method.x = 1;2089method = Hoek.once(method);2090expect(method.x).to.equal(1);2091done();2092});2093});20942095describe('isAbsoltePath()', function () {20962097it('identifies if path is absolute on Unix without node support', { parallel: false }, function (done) {20982099var orig = Path.isAbsolute;2100Path.isAbsolute = undefined;21012102expect(Hoek.isAbsolutePath('')).to.equal(false);2103expect(Hoek.isAbsolutePath('a')).to.equal(false);2104expect(Hoek.isAbsolutePath('./a')).to.equal(false);2105expect(Hoek.isAbsolutePath('/a')).to.equal(true);2106expect(Hoek.isAbsolutePath('/')).to.equal(true);21072108Path.isAbsolute = orig;21092110done();2111});21122113it('identifies if path is absolute with fake node support', { parallel: false }, function (done) {21142115var orig = Path.isAbsolute;2116Path.isAbsolute = function (path) {21172118return path[0] === '/';2119};21202121expect(Hoek.isAbsolutePath('', 'linux')).to.equal(false);2122expect(Hoek.isAbsolutePath('a', 'linux')).to.equal(false);2123expect(Hoek.isAbsolutePath('./a', 'linux')).to.equal(false);2124expect(Hoek.isAbsolutePath('/a', 'linux')).to.equal(true);2125expect(Hoek.isAbsolutePath('/', 'linux')).to.equal(true);21262127Path.isAbsolute = orig;21282129done();2130});21312132it('identifies if path is absolute on Windows without node support', { parallel: false }, function (done) {21332134var orig = Path.isAbsolute;2135Path.isAbsolute = undefined;21362137expect(Hoek.isAbsolutePath('//server/file', 'win32')).to.equal(true);2138expect(Hoek.isAbsolutePath('//server/file', 'win32')).to.equal(true);2139expect(Hoek.isAbsolutePath('\\\\server\\file', 'win32')).to.equal(true);2140expect(Hoek.isAbsolutePath('C:/Users/', 'win32')).to.equal(true);2141expect(Hoek.isAbsolutePath('C:\\Users\\', 'win32')).to.equal(true);2142expect(Hoek.isAbsolutePath('C:cwd/another', 'win32')).to.equal(false);2143expect(Hoek.isAbsolutePath('C:cwd\\another', 'win32')).to.equal(false);2144expect(Hoek.isAbsolutePath('directory/directory', 'win32')).to.equal(false);2145expect(Hoek.isAbsolutePath('directory\\directory', 'win32')).to.equal(false);21462147Path.isAbsolute = orig;21482149done();2150});2151});21522153describe('isInteger()', function () {21542155it('validates integers', function (done) {21562157expect(Hoek.isInteger(0)).to.equal(true);2158expect(Hoek.isInteger(1)).to.equal(true);2159expect(Hoek.isInteger(1394035612500)).to.equal(true);2160expect(Hoek.isInteger('0')).to.equal(false);2161expect(Hoek.isInteger(1.0)).to.equal(true);2162expect(Hoek.isInteger(1.1)).to.equal(false);2163done();2164});2165});21662167describe('ignore()', function () {21682169it('exists', function (done) {21702171expect(Hoek.ignore).to.exist();2172expect(typeof Hoek.ignore).to.equal('function');2173done();2174});2175});21762177describe('inherits()', function () {21782179it('exists', function (done) {21802181expect(Hoek.inherits).to.exist();2182expect(typeof Hoek.inherits).to.equal('function');2183done();2184});2185});21862187describe('format()', function () {21882189it('exists', function (done) {21902191expect(Hoek.format).to.exist();2192expect(typeof Hoek.format).to.equal('function');2193done();2194});21952196it('is a reference to Util.format', function (done) {21972198expect(Hoek.format('hello %s', 'world')).to.equal('hello world');2199done();2200});2201});22022203describe('transform()', function () {22042205var source = {2206address: {2207one: '123 main street',2208two: 'PO Box 1234'2209},2210zip: {2211code: 3321232,2212province: null2213},2214title: 'Warehouse',2215state: 'CA'2216};22172218it('transforms an object based on the input object', function (done) {22192220var result = Hoek.transform(source, {2221'person.address.lineOne': 'address.one',2222'person.address.lineTwo': 'address.two',2223'title': 'title',2224'person.address.region': 'state',2225'person.address.zip': 'zip.code',2226'person.address.location': 'zip.province'2227});22282229expect(result).to.deep.equal({2230person: {2231address: {2232lineOne: '123 main street',2233lineTwo: 'PO Box 1234',2234region: 'CA',2235zip: 3321232,2236location: null2237}2238},2239title: 'Warehouse'2240});22412242done();2243});22442245it('uses the reach options passed into it', function (done) {22462247var schema = {2248'person.address.lineOne': 'address-one',2249'person.address.lineTwo': 'address-two',2250'title': 'title',2251'person.address.region': 'state',2252'person.prefix': 'person-title',2253'person.zip': 'zip-code'2254};2255var options = {2256separator: '-',2257default: 'unknown'2258};2259var result = Hoek.transform(source, schema, options);22602261expect(result).to.deep.equal({2262person: {2263address: {2264lineOne: '123 main street',2265lineTwo: 'PO Box 1234',2266region: 'CA'2267},2268prefix: 'unknown',2269zip: 33212322270},2271title: 'Warehouse'2272});22732274done();2275});22762277it('works to create shallow objects', function (done) {22782279var result = Hoek.transform(source, {2280lineOne: 'address.one',2281lineTwo: 'address.two',2282title: 'title',2283region: 'state',2284province: 'zip.province'2285});22862287expect(result).to.deep.equal({2288lineOne: '123 main street',2289lineTwo: 'PO Box 1234',2290title: 'Warehouse',2291region: 'CA',2292province: null2293});22942295done();2296});22972298it('only allows strings in the map', function (done) {22992300expect(function () {23012302var result = Hoek.transform(source, {2303lineOne: {}2304});2305}).to.throw('All mappings must be "." delineated strings');23062307done();2308});23092310it('throws an error on invalid arguments', function (done) {23112312expect(function () {23132314var result = Hoek.transform(NaN, {});2315}).to.throw('Invalid source object: must be null, undefined, or an object');23162317done();2318});23192320it('is safe to pass null', function (done) {23212322var result = Hoek.transform(null, {});2323expect(result).to.deep.equal({});23242325done();2326});23272328it('is safe to pass undefined', function (done) {23292330var result = Hoek.transform(undefined, {});2331expect(result).to.deep.equal({});23322333done();2334});2335});23362337describe('uniqueFilename()', function () {23382339it('generates a random file path', function (done) {23402341var result = Hoek.uniqueFilename('./test/modules');23422343expect(result).to.exist();2344expect(result).to.be.a.string();2345expect(result).to.contain('test/modules');2346done();2347});23482349it('is random enough to use in fast loops', function (done) {23502351var results = [];23522353for (var i = 0; i < 10; ++i) {2354results[i] = Hoek.uniqueFilename('./test/modules');2355}23562357var filter = results.filter(function (item, index, array) {23582359return array.indexOf(item) === index;2360});23612362expect(filter.length).to.equal(10);2363expect(results.length).to.equal(10);2364done();23652366});23672368it('combines the random elements with a supplied character', function (done) {23692370var result = Hoek.uniqueFilename('./test', 'txt');23712372expect(result).to.contain('test/');2373expect(result).to.contain('.txt');23742375done();2376});23772378it('accepts extensions with a "." in it', function (done) {23792380var result = Hoek.uniqueFilename('./test', '.mp3');23812382expect(result).to.contain('test/');2383expect(result).to.contain('.mp3');23842385done();2386});2387});23882389describe('stringify()', function (done) {23902391it('converts object to string', function (done) {23922393var obj = { a: 1 };2394expect(Hoek.stringify(obj)).to.equal('{"a":1}');2395done();2396});23972398it('returns error in result string', function (done) {23992400var obj = { a: 1 };2401obj.b = obj;2402expect(Hoek.stringify(obj)).to.equal('[Cannot display object: Converting circular structure to JSON]');2403done();2404});2405});24062407describe('shallow()', function (done) {24082409it('shallow copies an object', function (done) {24102411var obj = {2412a: 5,2413b: {2414c: 62415}2416};24172418var shallow = Hoek.shallow(obj);2419expect(shallow).to.not.equal(obj);2420expect(shallow).to.deep.equal(obj);2421expect(shallow.b).to.equal(obj.b);2422done();2423});2424});242524262427