Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(diff): detailed comparison via verbose output flag #61

Merged
merged 1 commit into from
Apr 22, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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}])
)
})
})