From 53a913ef09d810a4303d0a131409076181c224d6 Mon Sep 17 00:00:00 2001 From: "Thai Pangsakulyanont @ Taskworld" Date: Mon, 30 Nov 2015 16:51:00 +0700 Subject: [PATCH] Allow duplications to be identified by a hash key This allows automated scripts to parse the resulting JSON/XML file and detect new/removed duplications. --- lib/inspector.js | 2 +- lib/match.js | 5 ++++- lib/reporters/json.js | 2 +- lib/reporters/pmd.js | 2 +- spec/helpers.js | 8 ++++++++ spec/matchSpec.js | 17 +++++++++++++++-- spec/reporters/jsonSpec.js | 4 ++++ spec/reporters/pmdSpec.js | 10 ++++++---- 8 files changed, 40 insertions(+), 10 deletions(-) diff --git a/lib/inspector.js b/lib/inspector.js index e4c5054..c8afd73 100644 --- a/lib/inspector.js +++ b/lib/inspector.js @@ -133,7 +133,7 @@ Inspector.prototype._analyze = function() { for (i = 0; i < nodes.length; i++) { if (nodes[i].length < 2) continue; - match = new Match(nodes[i]); + match = new Match(nodes[i], key); if (this._diff) { match.generateDiffs(this._fileContents); } diff --git a/lib/match.js b/lib/match.js index ff223d2..7b1ba83 100644 --- a/lib/match.js +++ b/lib/match.js @@ -1,5 +1,6 @@ var jsdiff = require('diff'); var strip = require('strip-indent'); +var crypto = require('crypto'); /** * Creates a new Match, consisting of an array of nodes. If generated, an @@ -9,9 +10,11 @@ var strip = require('strip-indent'); * * @param {Node[]} nodes An array of matching nodes */ -function Match(nodes) { +function Match(nodes, key) { this.nodes = nodes; this.diffs = []; + this._key = key || ''; + this.hash = crypto.createHash('sha1').update(this._key).digest('hex'); } module.exports = Match; diff --git a/lib/reporters/json.js b/lib/reporters/json.js index 300d2ac..dcc5438 100644 --- a/lib/reporters/json.js +++ b/lib/reporters/json.js @@ -54,7 +54,7 @@ JSONReporter.prototype._getOutput = function(match) { self = this; output = ''; - formatted = {instances: []}; + formatted = {id: match.hash, instances: []}; nodes = match.nodes; nodes.forEach(function(node) { diff --git a/lib/reporters/pmd.js b/lib/reporters/pmd.js index a4dbcf3..58e937f 100644 --- a/lib/reporters/pmd.js +++ b/lib/reporters/pmd.js @@ -62,7 +62,7 @@ PMDReporter.prototype._getOutput = function(match) { output += '\n'; } - output += '\n'; + output += '\n'; nodes.forEach(function(node) { output += self._getFile(node); }); diff --git a/spec/helpers.js b/spec/helpers.js index 8ef0307..cff7e52 100644 --- a/spec/helpers.js +++ b/spec/helpers.js @@ -19,6 +19,14 @@ module.exports = { }; }, + collectMatches: function(inspector) { + var array = []; + inspector.on('match', function(match) { + array.push(match); + }); + return array; + }, + getOutput: function() { return output; }, diff --git a/spec/matchSpec.js b/spec/matchSpec.js index a1d250c..f1422c9 100644 --- a/spec/matchSpec.js +++ b/spec/matchSpec.js @@ -12,16 +12,29 @@ describe('Match', function() { {type: 'Literal'} ]; - var match = new Match(mockNodes); + var match = new Match(mockNodes, 'key'); expect(match.nodes).to.be(mockNodes); }); it('initializes the object with an empty array for match.diffs', function() { - var match = new Match([]); + var match = new Match([], ''); expect(match.diffs).to.eql([]); }); }); + describe('hash', function() { + it('returns a different hash for different key', function() { + var match1 = new Match([], 'a'); + var match2 = new Match([], 'b'); + expect(match1.hash).not.to.equal(match2.hash); + }); + it('returns a same hash for same key', function() { + var match1 = new Match([], 'a'); + var match2 = new Match([], 'a'); + expect(match1.hash).to.equal(match2.hash); + }); + }); + function getFixture(fixtureName){ var ast, contents, content; diff --git a/spec/reporters/jsonSpec.js b/spec/reporters/jsonSpec.js index e88c739..a5f8067 100644 --- a/spec/reporters/jsonSpec.js +++ b/spec/reporters/jsonSpec.js @@ -39,6 +39,7 @@ describe('JSONReporter', function() { threshold: 1 }); var reporter = new JSONReporter(inspector); + var matches = helpers.collectMatches(inspector); inspector.removeAllListeners('start'); inspector.removeAllListeners('end'); @@ -48,6 +49,7 @@ describe('JSONReporter', function() { var parsedOutput = JSON.parse(helpers.getOutput()); expect(parsedOutput).to.eql({ + id: matches[0].hash, instances: [ {path: 'spec/fixtures/smallDiffs.js', lines: [1,1]}, {path: 'spec/fixtures/smallDiffs.js', lines: [2,2]}, @@ -97,11 +99,13 @@ describe('JSONReporter', function() { var reporter = new JSONReporter(inspector, { writableStream: concatStream }); + var matches = helpers.collectMatches(inspector); inspector.run(); function onFinish(data) { expect(JSON.parse(data)).to.eql([{ + id: matches[0].hash, instances: [ {path: 'spec/fixtures/smallDiffs.js', lines: [1,1]}, {path: 'spec/fixtures/smallDiffs.js', lines: [2,2]}, diff --git a/spec/reporters/pmdSpec.js b/spec/reporters/pmdSpec.js index b87c7e0..3909d17 100644 --- a/spec/reporters/pmdSpec.js +++ b/spec/reporters/pmdSpec.js @@ -23,10 +23,11 @@ describe('PMDReporter', function() { }); it('prints paths and line numbers in a duplication element', function() { - var inspector, reporter; + var inspector, reporter, matches; inspector = new Inspector([fixtures.smallDiffs], {threshold: 1}); reporter = new PMDReporter(inspector); + matches = helpers.collectMatches(inspector); inspector.removeAllListeners('start'); inspector.removeAllListeners('end'); @@ -35,7 +36,7 @@ describe('PMDReporter', function() { helpers.restoreOutput(); expect(helpers.getOutput()).to.eql( - '\n' + + '\n' + '\n' + '\n' + '\n' + @@ -45,13 +46,14 @@ describe('PMDReporter', function() { }); it('prints diffs if enabled, within a codefragment element', function() { - var inspector, reporter, absolutePath; + var inspector, reporter, absolutePath, matches; inspector = new Inspector([fixtures.smallDiffs], { diff: true, threshold: 1 }); reporter = new PMDReporter(inspector, {diff: true}); + matches = helpers.collectMatches(inspector); inspector.removeAllListeners('start'); inspector.removeAllListeners('end'); @@ -60,7 +62,7 @@ describe('PMDReporter', function() { helpers.restoreOutput(); expect(helpers.getOutput()).to.eql( - '\n' + + '\n' + '\n' + '\n' + '\n' +