Skip to content

Commit

Permalink
feat(diff): detailed comparison via verbose output flag (#61)
Browse files Browse the repository at this point in the history
  • Loading branch information
ta2edchimp authored and sarbbottam committed Apr 22, 2016
1 parent 9dca832 commit 0becf21
Show file tree
Hide file tree
Showing 6 changed files with 173 additions and 9 deletions.
50 changes: 42 additions & 8 deletions src/bin/diff.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,41 +3,66 @@
'use strict'

var path = require('path')
var argv = require('yargs')
.boolean('verbose')
.alias('v', 'verbose')
.argv

var cli = require('../lib/cli-util')

var getRuleFinder = require('../lib/rule-finder')
var difference = require('../lib/array-diff')
var arrayDifference = require('../lib/array-diff')
var objectDifference = require('../lib/object-diff')
var getSortedRules = require('../lib/sort-rules')
var flattenRulesDiff = require('../lib/flatten-rules-diff')
var stringifyRuleConfig = require('../lib/stringify-rule-config')

var files = [process.argv[2], process.argv[3]]
var files = [argv._[0], argv._[1]]
var collectedRules = getFilesToCompare(files).map(compareConfigs)

var rulesCount = collectedRules.reduce(
function getLength(prev, curr) {
return prev + (curr && curr.rules ? curr.rules.length : /* istanbul ignore next */ 0)
}, 0)

/* istanbul ignore next */
/* istanbul ignore else */
if (argv.verbose || rulesCount) {
cli.push('\ndiff rules\n' + rulesCount + ' rules differ\n')
}

/* istanbul ignore else */
if (rulesCount) {
cli.push('\ndiff rules\n')
collectedRules.forEach(function displayConfigs(diff) {
var rules = diff.rules

/* istanbul ignore if */
if (!rules.length) {
return
}

cli.push('\nin ' + diff.config1 + ' but not in ' + diff.config2 + ':\n')
cli.push(rules)
if (argv.verbose) {
rules = flattenRulesDiff(rules).map(stringifyRuleConfig)
rules.unshift([], diff.config1, diff.config2)
} else {
cli.push('\nin ' + diff.config1 + ' but not in ' + diff.config2 + ':\n')
}

cli.push(rules, argv.verbose ? 3 : 0)
})
}

cli.write()

function getFilesToCompare(allFiles) {
var filesToCompare = [allFiles]
filesToCompare.push([].concat(allFiles).reverse())

if (!argv.verbose) {
// in non-verbose output mode, compare a to b
// and b to a afterwards, to obtain ALL differences
// accross those files, but grouped
filesToCompare.push([].concat(allFiles).reverse())
}

return filesToCompare
}

Expand All @@ -53,8 +78,17 @@ function compareConfigs(currentFiles) {
}

function rulesDifference(a, b) {
if (argv.verbose) {
return getSortedRules(
objectDifference(
a.getCurrentRulesDetailed(),
b.getCurrentRulesDetailed()
)
)
}

return getSortedRules(
difference(
arrayDifference(
a.getCurrentRules(),
b.getCurrentRules()
)
Expand Down
38 changes: 38 additions & 0 deletions src/lib/flatten-rules-diff.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
function flattenRulesDiff(diff) {
if (Array.isArray(diff)) {
return flattenRulesDiffArray(diff)
} else if (typeof diff === 'object') {
return flattenRulesDiffObject(diff)
}

return []
}

function flattenRulesDiffObject(diffObject) {
var flattened = []

Object.keys(diffObject).forEach(function flattenEachRuleDiff(ruleName) {
var ruleRow = [ruleName]
var diff = diffObject[ruleName]

Object.keys(diff).forEach(function flattenEachChildProp(configName) {
ruleRow.push(diff[configName])
})

flattened.push.apply(flattened, ruleRow)
})

return flattened
}

function flattenRulesDiffArray(diffArray) {
var flattened = []

diffArray.forEach(function flattenEachDiff(diff) {
flattened.push.apply(flattened, flattenRulesDiff(diff))
})

return flattened
}

module.exports = flattenRulesDiff
11 changes: 11 additions & 0 deletions src/lib/stringify-rule-config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
function stringifyRuleConfig(rule) {
if (typeof rule === 'string') {
return rule
} else if (typeof rule === 'undefined') {
return '-'
}

return JSON.stringify(rule)
}

module.exports = stringifyRuleConfig
20 changes: 19 additions & 1 deletion test/bin/diff.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,11 @@ var stub = {
'../lib/rule-finder': function() {
return {
getCurrentRules: function noop() {},
getCurrentRulesDetailed: function noop() {},
}
},
'../lib/array-diff': sinon.stub().returns(['diff']),
'../lib/object-diff': sinon.stub().returns([{'test-rule': {config1: 'foo-config', config2: 'bar-config'}}]),
}

describe('diff', function() {
Expand All @@ -27,9 +29,11 @@ describe('diff', function() {

afterEach(function() {
console.log.restore() // eslint-disable-line no-console
// purge yargs cache
delete require.cache[require.resolve('yargs')]
})

it('log diff', function() {
it('logs diff', function() {
process.argv[2] = './foo'
process.argv[3] = './bar'
proxyquire('../../src/bin/diff', stub)
Expand All @@ -41,4 +45,18 @@ describe('diff', function() {
)
)
})

it('logs diff verbosely', function() {
process.argv[2] = '--verbose'
process.argv[3] = './foo'
process.argv[4] = './bar'
proxyquire('../../src/bin/diff', stub)
assert.ok(
console.log.calledWith( // eslint-disable-line no-console
sinon.match(
/diff rules[^]*foo[^]*bar[^]*test-rule[^]*foo-config[^]*bar-config/
)
)
)
})
})
38 changes: 38 additions & 0 deletions test/lib/flatten-rules-diff.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
var assert = require('assert')
var flattenRulesDiff = require('../../src/lib/flatten-rules-diff')

describe('flatten rules diff', function() {
it('should return flat array from diff-object with single rule', function() {
assert.deepEqual(
flattenRulesDiff({'foo-rule': {config1: [2, 'foo'], config2: [2, 'bar']}}),
['foo-rule', [2, 'foo'], [2, 'bar']]
)
})

it('should return flat array from diff-object with multiple rules', function() {
assert.deepEqual(
flattenRulesDiff({
'foo-rule': {config1: [2, 'foo'], config2: [2, 'bar']},
'bar-rule': {config1: undefined, config2: [1, 'bar']},
}),
['foo-rule', [2, 'foo'], [2, 'bar'], 'bar-rule', undefined, [1, 'bar']]
)
})

it('should return flat array from an array of diff-objects', function() {
assert.deepEqual(
flattenRulesDiff([
{'foo-rule': {config1: [2, 'foo'], config2: [2, 'bar']}},
{'bar-rule': {config1: undefined, config2: [1, 'bar']}},
]),
['foo-rule', [2, 'foo'], [2, 'bar'], 'bar-rule', undefined, [1, 'bar']]
)
})

it('should return empty array on anything else', function() {
assert.deepEqual(
flattenRulesDiff(undefined),
[]
)
})
})
25 changes: 25 additions & 0 deletions test/lib/stringify-rule-config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
var assert = require('assert')
var stringifyRuleConfig = require('../../src/lib/stringify-rule-config')

describe('stringify rule config', function() {
it('should return a string', function() {
assert.equal(
stringifyRuleConfig('A simple string'),
'A simple string'
)
})

it('should return \'-\' for "undefined"', function() {
assert.equal(
stringifyRuleConfig(undefined),
'-'
)
})

it('should return a JSON.stringify\'ed result for any object', function() {
assert.deepEqual(
stringifyRuleConfig([2, 'foo', {bar: true}]),
JSON.stringify([2, 'foo', {bar: true}])
)
})
})

0 comments on commit 0becf21

Please sign in to comment.