function mergeCards(c1, c2, parentC) {
if (!parentC) {
if (c1 && c2) throw 'how could two cards get generated with the same id?'
return c1 || c2
}
function cardDiff(c, parent) {
if (!x) return { deleted : true }
var d = {}
if (x.text != parent.text) d.text = true
if (x.createTime != parent.createTime) d.createTime = true
if (x.showTime != parent.showTime) d.showTime = true
if (x.touchTime != parent.touchTime) d.touchTime = true
return _.keys(d).length > 0 ? d : null
}
var d1 = cardDiff(c1, parentC)
var d2 = cardDiff(c2, parentC)
function merge(d1, d2, c1, c2, func) {
if (!d1 && !d2) return c1
if (d1 && !d2) return c1
if (!d1 && d2) return c2
return func(c1, c2)
}
return merge(d1, d2, c1, c2, function (c1, c2) {
if (d1.deleted || d2.deleted) {
if (d1.deleted && d2.deleted) return null
var c = _.deepClone(d1.deleted ? c2 : c1)
c.text = 'CONFLICT----DELETED\n' + c.text
return c
}
return {
id : c1.id,
text : merge(d1.text, d2.text, c1.text, c2.text, function (c1, c2) {
return 'CONFLICT----\n' + c1 + '\nCONFLICT----\n' + c2
},
createTime : merge(d1.createTime, d2.createTime, c1.createTime, c2.createTime, Math.min),
showTime : merge(d1.showTime, d2.showTime, c1.showTime, c2.showTime, function (_, __) {
return c1.text == c2.text ? Math.min(c1.showTime, c2.showTime) : 0
},
touchTime : merge(d1.touchTime, d2.touchTime, c1.touchTime, c2.touchTime, Math.max)
}
})
}
Now I was proud that this code seemed like it would handle lots of merging cases in elegant ways, but I was concerned that it would be hard to test, especially since the most smarts were in the least likely things to happen..
..so I decided to make it less smart, but easier to test — no need to read this either, it's about 33 lines — story concludes after the code:
function mergeCards(c1, c2, parentC) {
if (!parentC) {
if (c1 && c2) throw 'how could two cards get generated with the same id?'
return c1 || c2
}
function dirty(c, parent) {
return !c ||
c.text != parent.text ||
c.createTime != parent.createTime ||
c.showTime != parent.showTime ||
c.touchTime != parent.touchTime
}
var d1 = dirty(c1, parentC)
var d2 = dirty(c2, parentC)
if (!d2) return c1
if (!d1) return c2
if (!c1 || !c2) {
if (!c1 && !c2) return null
var c = _.deepClone(!c1 ? c2 : c1)
c.text = 'CONFLICT----DELETED\n' + c.text
return c
}
return {
id : c1.id,
text : 'CONFLICT----\n' + c1.text + '\nCONFLICT----\n' + c2.text,
createTime : Math.min(c1.createTime, c2.createTime),
showTime : 0,
touchTime : Math.max(c1.touchTime, c2.touchTime)
}
}
Anyway, I find that I do this a lot. I write a bunch of complicated code, and then decide that it would be easier to rewrite the code to do less stuff than to test the code ;)
No comments:
Post a Comment