[system_tracking] Fix nested fact compare with one empty side

This commit is contained in:
Joe Fiorini 2015-07-06 14:34:16 -04:00
parent 7bedaf1ad7
commit fc2ed6fd83
3 changed files with 208 additions and 2 deletions

View File

@ -130,12 +130,33 @@ export function findFacts(factData) {
var leftData = factData[0].facts;
var rightData = factData[1].facts;
// For value types (boolean, number) or complex objects use the value
// as is. For collection types, return 'absent' if it's empty
// otherwise, use the value as is.
//
function factValueOrAbsent(value) {
if (_.isBoolean(value) ||
_.isNumber(value)) {
return value;
}
if (_.isNull(value) || _.isEmpty(value)) {
return 'absent';
}
return value;
}
function factObject(keyPath, key, leftValue, rightValue) {
var obj =
{ keyPath: keyPath,
keyName: key
};
leftValue = factValueOrAbsent(leftValue);
rightValue = factValueOrAbsent(rightValue);
if (factData[0].position === 'left') {
obj.value1 = leftValue;
obj.value2 = rightValue;
@ -155,10 +176,10 @@ export function findFacts(factData) {
}, []);
} else {
// default value in _.get ('absent') only hits if it's undefined, so we need to handle other falsey cases with ||
var rightValue =
_.get(rightData,
parentKeys,
'absent');
parentKeys);
return factObject(
// TODO: Currently parentKeys is getting passed with the final key

View File

@ -8,6 +8,12 @@ import {formatFacts, findFacts} from './nested-helpers';
export default function nestedCompare(basisFacts, comparatorFacts) {
if (_.isEmpty(basisFacts.facts)) {
var tmp = _.merge({}, basisFacts);
basisFacts = _.merge({}, comparatorFacts);
comparatorFacts = tmp;
}
var factsList = [basisFacts, comparatorFacts];
factsList = findFacts(factsList);
factsList = compareFacts(factsList);

View File

@ -0,0 +1,179 @@
import compareFacts from 'tower/system-tracking/compare-facts/nested';
/* jshint node: true */
/* globals -expect, -_ */
var _, expect;
// This makes this test runnable in node OR karma. The sheer
// number of times I had to run this test made the karma
// workflow just too dang slow for me. Maybe this can
// be a pattern going forward? Not sure...
//
(function(global) {
var chai = global.chai || require('chai');
if (typeof window === 'undefined') {
var chaiThings = global.chaiThings || require('chai-things');
chai.use(chaiThings);
}
_ = global._ || require('lodash');
expect = global.expect || chai.expect;
global.expect = expect;
global._ = _;
})(typeof window === 'undefined' ? global : window);
describe('CompareFacts.Nested', function() {
it('returns empty array with no fact data', function() {
var result = compareFacts({ facts: [] }, { facts: [] });
expect(result).to.deep.equal([]);
});
it('returns empty array when no differences', function() {
var result = compareFacts(
{ facts:
{ 'testing_facts':
{ 'foo': 'bar'
}
}
},
{ facts:
{ 'testing_facts':
{ 'foo': 'bar'
}
}
});
expect(result).to.deep.equal([]);
});
context('when only left set has data', function() {
it('returns values with data for value1 and "absent" for value2', function() {
var result = compareFacts(
{ position: 'left',
facts:
{ 'testing_facts':
{ 'foo': 'bar'
}
}
},
{ position: 'right',
facts:
{}
});
expect(result[0].facts).to.contain
.an.item
.with.property('value1', 'bar');
expect(result[0].facts).to.contain
.an.item
.with.property('value2', 'absent');
});
});
context('when only right set has data', function() {
it('returns values with data for value2 and "absent" for value1', function() {
var result = compareFacts(
{ position: 'left',
facts:
{}
},
{ position: 'right',
facts:
{ 'testing_facts':
{ 'foo': 'bar'
}
}
});
expect(result).not.to.be.empty;
expect(result[0].facts).to.contain
.an.item
.with.property('value1', 'absent');
expect(result[0].facts).to.contain
.an.item
.with.property('value2', 'bar');
});
});
context('when both sets have fact data and differences exist', function() {
it('does not consider false values "absent"', function() {
var result = compareFacts(
{ position: 'left',
facts:
{ 'testing_facts':
{ 'foo': false
}
}
},
{ position: 'right',
facts:
{ 'testing_facts':
{ 'foo': true
}
}
});
expect(result[0].facts).to.contain
.an.item
.with.property('value1', false);
expect(result[0].facts).to.contain
.an.item
.with.property('value2', true);
});
it('uses "absent" for both values when neither has data', function() {
var result = compareFacts(
{ position: 'left',
facts:
{ 'testing_facts':
{ 'foo': 'baz',
'blah': null
}
}
},
{ position: 'right',
facts:
{ 'testing_facts':
{ 'foo': 'bar',
'blah': null
}
}
});
expect(result[0].facts).to.contain
.an.item
.with.property('value1', 'absent');
expect(result[0].facts).to.contain
.an.item
.with.property('value2', 'absent');
});
});
});