diff --git a/lib/utils/monkey-patches.js b/lib/utils/monkey-patches.js index 5d1080e..3ace2ab 100644 --- a/lib/utils/monkey-patches.js +++ b/lib/utils/monkey-patches.js @@ -6,13 +6,30 @@ * Licensed under the Apache 2.0 license. */ -/* eslint no-extend-native: 0 */ +/* eslint no-extend-native: 0 key-spacing: 0 */ "use strict"; var max = Math.max, min = Math.min; +var originals = { + seconds: Number.prototype.seconds, + second: Number.prototype.second, + fromScale: Number.prototype.fromScale, + toScale: Number.prototype.toScale +}; + +module.exports.uninstall = function() { + for (var opt in originals) { + if (originals[opt] == null) { + Number.prototype[opt] = originals[opt]; + } else { + delete Number.prototype[opt]; + } + } +}; + module.exports.install = function() { // Public: Monkey-patches Number to have Rails-like //seconds() function. // Warning, due to the way the Javascript parser works, applying functions on diff --git a/spec/lib/utils.spec.js b/spec/lib/utils.spec.js index 441b7a3..cceaf5c 100644 --- a/spec/lib/utils.spec.js +++ b/spec/lib/utils.spec.js @@ -3,72 +3,6 @@ var utils = lib("utils"); describe("Utils", function() { - describe("Monkey-patches", function() { - describe("Number", function() { - describe("#seconds", function() { - it("allows for expressing time in seconds", function() { - expect((5).seconds()).to.be.eql(5000); - }); - }); - - describe("#second", function() { - it("allows for expressing time in seconds", function() { - expect((1).second()).to.be.eql(1000); - }); - }); - - describe("#fromScale", function() { - it("converts a value from one scale to 0-1 scale", function() { - expect((5).fromScale(0, 10)).to.be.eql(0.5); - }); - - it("converts floats", function() { - expect((2.5).fromScale(0, 10)).to.be.eql(0.25); - }); - - context("if the number goes above the top of the scale", function() { - it("should return 1", function() { - expect((15).fromScale(0, 10)).to.be.eql(1); - }); - }); - - context("if the number goes below the bottom of the scale", function() { - it("should return 0", function() { - expect((15).fromScale(0, 10)).to.be.eql(1); - expect((5).fromScale(10, 20)).to.be.eql(0); - }); - }); - }); - - describe("#toScale", function() { - it("converts a value from 0-1 scale to another", function() { - expect((0.5).toScale(0, 10)).to.be.eql(5); - }); - - context("when value goes below bottom of scale", function() { - it("returns the bottom of the scale", function() { - expect((-5).toScale(0, 10)).to.be.eql(0); - }); - }); - - context("when value goes above top of scale", function() { - it("returns the top of the scale", function() { - expect((15).toScale(0, 10)).to.be.eql(10); - }); - }); - - it("converts to floats", function() { - expect((0.25).toScale(0, 10)).to.be.eql(2.5); - }); - - it("can be chained with #fromScale", function() { - var num = (5).fromScale(0, 20).toScale(0, 10); - expect(num).to.be.eql(2.5); - }); - }); - }); - }); - describe("#makeUnique", function() { it("returns the original name if it's not a conflict", function() { var res = utils.makeUnique("hello", ["world"]); diff --git a/spec/lib/utils/monkey-patches.spec.js b/spec/lib/utils/monkey-patches.spec.js new file mode 100644 index 0000000..10db257 --- /dev/null +++ b/spec/lib/utils/monkey-patches.spec.js @@ -0,0 +1,112 @@ +// jshint expr:true +"use strict"; + +var patches = lib("utils/monkey-patches"); + +describe("monkey-patches", function() { + beforeEach(function() { + patches.uninstall(); + }); + + afterEach(function() { + patches.install(); + }); + + describe("#install", function() { + it("monkey-patches methods onto global classes", function() { + var proto = Number.prototype; + + expect(proto.seconds).to.be.undefined; + expect(proto.second).to.be.undefined; + + patches.install(); + + expect(proto.seconds).to.be.a("function"); + expect(proto.second).to.be.a("function"); + }); + }); + + describe("#uninstall", function() { + it("removes existing monkey-patching", function() { + var proto = Number.prototype; + + patches.install(); + + expect(proto.seconds).to.be.a("function"); + expect(proto.second).to.be.a("function"); + + patches.uninstall(); + + expect(proto.seconds).to.be.undefined; + expect(proto.second).to.be.undefined; + }); + }); + + describe("Number", function() { + beforeEach(function() { + patches.install(); + }); + + describe("#seconds", function() { + it("allows for expressing time in seconds", function() { + expect((5).seconds()).to.be.eql(5000); + }); + }); + + describe("#second", function() { + it("allows for expressing time in seconds", function() { + expect((1).second()).to.be.eql(1000); + }); + }); + + describe("#fromScale", function() { + it("converts a value from one scale to 0-1 scale", function() { + expect((5).fromScale(0, 10)).to.be.eql(0.5); + }); + + it("converts floats", function() { + expect((2.5).fromScale(0, 10)).to.be.eql(0.25); + }); + + context("if the number goes above the top of the scale", function() { + it("should return 1", function() { + expect((15).fromScale(0, 10)).to.be.eql(1); + }); + }); + + context("if the number goes below the bottom of the scale", function() { + it("should return 0", function() { + expect((15).fromScale(0, 10)).to.be.eql(1); + expect((5).fromScale(10, 20)).to.be.eql(0); + }); + }); + }); + + describe("#toScale", function() { + it("converts a value from 0-1 scale to another", function() { + expect((0.5).toScale(0, 10)).to.be.eql(5); + }); + + context("when value goes below bottom of scale", function() { + it("returns the bottom of the scale", function() { + expect((-5).toScale(0, 10)).to.be.eql(0); + }); + }); + + context("when value goes above top of scale", function() { + it("returns the top of the scale", function() { + expect((15).toScale(0, 10)).to.be.eql(10); + }); + }); + + it("converts to floats", function() { + expect((0.25).toScale(0, 10)).to.be.eql(2.5); + }); + + it("can be chained with #fromScale", function() { + var num = (5).fromScale(0, 20).toScale(0, 10); + expect(num).to.be.eql(2.5); + }); + }); + }); +});