diff --git a/lib/polyfill.js b/lib/polyfill.js index b49c460..8a05ea3 100644 --- a/lib/polyfill.js +++ b/lib/polyfill.js @@ -1,45 +1,41 @@ +/*jslint regexp: true, evil: true, node: true*/ /*globals Gun, console*/ +'use strict'; -Object.keys = Object.keys || function (obj) { - 'use strict'; - var key, keys = []; + +if (typeof Gun === 'undefined') { + var Gun = require('gun/gun'); +} + +function keys(obj) { + var key, all = []; for (key in obj) { if (obj.hasOwnProperty(key)) { - keys.push(key); + all.push(key); } } - return keys; -}; -Object.values = Object.values || function (obj) { - 'use strict'; - return Object.keys(obj).map(function (key) { + return all; +} + +function values(obj) { + return keys(obj).map(function (key) { return obj[key]; }); -}; -var setImmediate = setImmediate || function (cb) { - 'use strict'; - setTimeout(cb, Infinity); -}; -console.log = (function () { - 'use strict'; - var peersError, log = console.log; - peersError = 'Warning! You have no peers to connect to!'; - return function (msg) { - if (msg === peersError) { - return; - } - log.apply(console, arguments); - }; -}()); +} + +Object.keys = Object.keys || keys; +Object.values = Object.values || values; + +console.log = console.log.bind(console); Gun.log.squelch = true; Gun.chain.each = function (cb, end) { - 'use strict'; - var n = function () {}, - count = 0, - props = [], - gun = this; + var count, props, gun, n = function () {}; + count = 0; + props = []; + gun = this; + cb = cb || n; end = end || n; @@ -61,3 +57,24 @@ Gun.chain.each = function (cb, end) { }); return gun; }; + +Function.prototype.toJSON = function () { + var declaration, name = 'A' + Gun.text.random(9); + declaration = 'function ' + name + '('; + return this.toString().replace(/^function\s*\w*\(/, declaration); +}; + + +Function.parse = function (string) { + var val; + eval('val = ' + string); + return val; +}; + +if (typeof module !== 'undefined') { + // export for jasmine tests + module.exports = { + keys: keys, + values: values + }; +} diff --git a/spec/polyfill.spec.js b/spec/polyfill.spec.js new file mode 100644 index 0000000..5e95b95 --- /dev/null +++ b/spec/polyfill.spec.js @@ -0,0 +1,127 @@ +/*global jasmine, describe, it, expect, beforeAll*/ +/*jslint node: true*/ +'use strict'; +jasmine.DEFAULT_TIMEOUT_INTERVAL = 500; + +describe('Polyfill.js', function () { + var polyfill = require('../lib/polyfill'); + describe('Object.keys', function () { + // cannot delete Object.keys for testing + // node internals depend on it + var keys = polyfill.keys; + + it('should be a function', function () { + expect(polyfill.keys).toEqual(jasmine.any(Function)); + }); + + it('should return an array', function () { + expect(keys({})).toEqual(jasmine.any(Array)); + }); + + // more specifically, it will replace it if it doesn't exist + it('should return an array', function () { + expect(keys({ + 1: 1 + }).length).toBe(1); + }); + + it('should not fail without input', function () { + expect(keys).not.toThrow(); + }); + + it('should survive bad inputs', function () { + keys(null); // shouldn't throw + keys(undefined); // shouldn't throw + keys(0); // shouldn't throw + keys(NaN); // shouldn't throw + keys(Infinity); // shouldn't throw + }); + + it('should return a list of keys', function () { + expect(keys({ + name: true + })[0]).toBe('name'); + }); + }); + + describe('values', function () { + var values = polyfill.values; + it('should be a function', function () { + expect(values).toEqual(jasmine.any(Function)); + }); + + it('should return an array', function () { + expect(values({})).toEqual(jasmine.any(Array)); + }); + + it('should return a list of object values', function () { + expect(values({ + 1: 5 + })[0]).toBe(5); + }); + + it('should be able to handle no input', function () { + expect(values).not.toThrow(); + }); + + it('should be able to handle bad input', function () { + values(null); // shouldn't throw + values(undefined); // shouldn't throw + values(NaN); // shouldn't throw + values(Infinity); // shouldn't throw + values(0); // shouldn't throw + }); + }); + + describe('JSON function support', function () { + it('should allow you to stringify functions', function () { + var result = JSON.stringify(function () {}); + expect(result.length > 0).toBe(true); + }); + + it('should provide a toJSON method', function () { + expect(Function.prototype.toJSON).toEqual(jasmine.any(Function)); + }); + + it('should not be picky about where you put the functions', function () { + var result = JSON.stringify({ + cb: function () { + // do stuff + } + }); + result = JSON.parse(result); + expect(result.cb).toBeTruthy(); + }); + + it('should name a function when anonymous', function () { + var result = JSON.stringify(function () {}); + expect(result).toMatch(/function \w+\(/); + }); + + it('should always start a function name with a letter', function () { + var result = JSON.stringify(function () {}); + expect(result).toMatch(/function \D/); + }); + }); + + describe('Function.parse', function () { + it('should be a function', function () { + expect(Function.parse).toEqual(jasmine.any(Function)); + }); + + it('should parse stringified functions', function (done) { + var string = JSON.parse(JSON.stringify(function (finished) { + finished(); + })); + Function.parse(string)(done); + }); + }); + + describe('gun.each', function () { + var Gun = require('gun/gun'); + + it('should be a function', function () { + expect(Gun.chain.each).toEqual(jasmine.any(Function)); + }); + }); +}); diff --git a/spec/support/jasmine.json b/spec/support/jasmine.json new file mode 100644 index 0000000..a5f2932 --- /dev/null +++ b/spec/support/jasmine.json @@ -0,0 +1,9 @@ +{ + "spec_dir": "spec", + "spec_files": [ + "**/*[sS]pec.js" + ], + "helpers": [ + "helpers/**/*.js" + ] +}