diff --git a/libraries/metrics/.nvmrc b/libraries/metrics/.nvmrc new file mode 100644 index 0000000000..12e4141293 --- /dev/null +++ b/libraries/metrics/.nvmrc @@ -0,0 +1 @@ +6.9 diff --git a/libraries/metrics/Gruntfile.coffee b/libraries/metrics/Gruntfile.coffee new file mode 100644 index 0000000000..47f126fa70 --- /dev/null +++ b/libraries/metrics/Gruntfile.coffee @@ -0,0 +1,29 @@ +module.exports = (grunt) -> + grunt.initConfig + coffee: + unit_tests: + expand: true + cwd: "test/unit/coffee" + src: ["**/*.coffee"] + dest: "test/unit/js/" + ext: ".js" + + clean: + unit_tests: ["test/unit/js"] + + mochaTest: + unit: + options: + reporter: grunt.option('reporter') or 'spec' + grep: grunt.option("grep") + + src: ["test/unit/js/**/*.js"] + + grunt.loadNpmTasks 'grunt-contrib-coffee' + grunt.loadNpmTasks 'grunt-contrib-clean' + grunt.loadNpmTasks 'grunt-mocha-test' + grunt.loadNpmTasks 'grunt-execute' + grunt.loadNpmTasks 'grunt-bunyan' + + grunt.registerTask 'compile:unit_tests', ['clean:unit_tests', 'coffee:unit_tests'] + grunt.registerTask 'test:unit', ['compile:unit_tests', 'mochaTest:unit'] diff --git a/libraries/metrics/package.json b/libraries/metrics/package.json index 02b1f05837..cf987853e7 100644 --- a/libraries/metrics/package.json +++ b/libraries/metrics/package.json @@ -10,5 +10,17 @@ "lynx": "~0.1.1", "coffee-script": "1.6.0", "underscore": "~1.6.0" + }, + "devDependencies": { + "bunyan": "^1.0.0", + "chai": "", + "grunt": "^0.4.5", + "grunt-bunyan": "^0.5.0", + "grunt-contrib-clean": "^0.6.0", + "grunt-contrib-coffee": "^0.11.0", + "grunt-execute": "^0.2.2", + "grunt-mocha-test": "^0.11.0", + "sandboxed-module": "", + "sinon": "" } } diff --git a/libraries/metrics/test/unit/coffee/timeAsyncMethodTests.coffee b/libraries/metrics/test/unit/coffee/timeAsyncMethodTests.coffee new file mode 100644 index 0000000000..69fbf2cb0f --- /dev/null +++ b/libraries/metrics/test/unit/coffee/timeAsyncMethodTests.coffee @@ -0,0 +1,49 @@ +require('coffee-script') +chai = require('chai') +should = chai.should() +expect = chai.expect +path = require('path') +modulePath = path.join __dirname, '../../../timeAsyncMethod.coffee' +SandboxedModule = require('sandboxed-module') +sinon = require("sinon") + + +describe 'timeAsyncMethod', -> + + beforeEach -> + @Timer = {done: sinon.stub()} + @TimerConstructor = sinon.stub().returns(@Timer) + @metrics = { + Timer: @TimerConstructor + } + @timeAsyncMethod = SandboxedModule.require modulePath, requires: + './metrics': @metrics + + @testObject = { + nextNumber: (n, callback=(err, result)->) -> + setTimeout( + () -> + callback(null, n+1) + , 100 + ) + } + + it 'should have the testObject behave correctly before wrapping', (done) -> + @testObject.nextNumber 2, (err, result) -> + expect(err).to.not.exist + expect(result).to.equal 3 + done() + + it 'should wrap method without error', (done) -> + @timeAsyncMethod @testObject, 'nextNumber', 'test.nextNumber' + done() + + it 'should transparently wrap method invocation in timer', (done) -> + @timeAsyncMethod @testObject, 'nextNumber', 'test.nextNumber' + @testObject.nextNumber 2, (err, result) => + expect(err).to.not.exist + expect(result).to.equal 3 + expect(@TimerConstructor.callCount).to.equal 1 + expect(@Timer.done.callCount).to.equal 1 + done() + diff --git a/libraries/metrics/test/unit/js/timeAsyncMethodTests.js b/libraries/metrics/test/unit/js/timeAsyncMethodTests.js new file mode 100644 index 0000000000..479de4eb4f --- /dev/null +++ b/libraries/metrics/test/unit/js/timeAsyncMethodTests.js @@ -0,0 +1,70 @@ +(function() { + var SandboxedModule, chai, expect, modulePath, path, should, sinon; + + require('coffee-script'); + + chai = require('chai'); + + should = chai.should(); + + expect = chai.expect; + + path = require('path'); + + modulePath = path.join(__dirname, '../../../timeAsyncMethod.coffee'); + + SandboxedModule = require('sandboxed-module'); + + sinon = require("sinon"); + + describe('timeAsyncMethod', function() { + beforeEach(function() { + this.Timer = { + done: sinon.stub() + }; + this.TimerConstructor = sinon.stub().returns(this.Timer); + this.metrics = { + Timer: this.TimerConstructor + }; + this.timeAsyncMethod = SandboxedModule.require(modulePath, { + requires: { + './metrics': this.metrics + } + }); + return this.testObject = { + nextNumber: function(n, callback) { + if (callback == null) { + callback = function(err, result) {}; + } + return setTimeout(function() { + return callback(null, n + 1); + }, 100); + } + }; + }); + it('should have the testObject behave correctly before wrapping', function(done) { + return this.testObject.nextNumber(2, function(err, result) { + expect(err).to.not.exist; + expect(result).to.equal(3); + return done(); + }); + }); + it('should wrap method without error', function(done) { + this.timeAsyncMethod(this.testObject, 'nextNumber', 'test.nextNumber'); + return done(); + }); + return it('should work', function(done) { + this.timeAsyncMethod(this.testObject, 'nextNumber', 'test.nextNumber'); + return this.testObject.nextNumber(2, (function(_this) { + return function(err, result) { + expect(err).to.not.exist; + expect(result).to.equal(3); + expect(_this.TimerConstructor.callCount).to.equal(1); + expect(_this.Timer.done.callCount).to.equal(1); + return done(); + }; + })(this)); + }); + }); + +}).call(this);