Much better data object change detection

Replace Z.DataObjects::diff() with Z.DataObjectUtilities.diff(). Instead
of just returning two objects with the differing fields, the new diff()
generates a changeset with operations to apply with applyChanges(),
including at the array member level for collections and tags. This,
combined with cached pristine copies of objects, will allow for vastly
better conflict resolution, with automatic merging of non-conflicting
changes.

Creators currently don't show granular changes, and ordering might make
it too tough to do so. Relations diffing isn't yet implemented.
This commit is contained in:
Dan Stillman 2015-05-19 01:05:05 -04:00
parent daad18c1b5
commit abaa4da5ab
6 changed files with 670 additions and 253 deletions

View file

@ -1,110 +0,0 @@
"use strict";
describe("Zotero.DataObjects", function() {
var types = ['collection', 'item', 'search'];
describe("#diff()", function () {
it("should not show empty items as different", function* () {
var id1, id2, json1, json2;
yield Zotero.DB.executeTransaction(function* () {
var item = new Zotero.Item('book');
id1 = yield item.save();
item = yield Zotero.Items.getAsync(id1);
json1 = yield item.toJSON();
var item = new Zotero.Item('book');
id2 = yield item.save();
item = yield Zotero.Items.getAsync(id2);
json2 = yield item.toJSON();
});
var diff = Zotero.Items.diff(json1, json2);
assert.isFalse(diff);
yield Zotero.Items.erase(id1, id2);
})
it("should not show empty strings as different", function* () {
var json1 = {
title: ""
};
var json2 = {
title: ""
};
var diff = Zotero.Items.diff(json1, json2);
assert.isFalse(diff);
})
it("should not show empty string and undefined as different", function* () {
var json1 = {
title: ""
};
var json2 = {
place: ""
};
var diff = Zotero.Items.diff(json1, json2);
assert.isFalse(diff);
})
it("should not show identical creators as different", function* () {
var json1 = {
creators: [
{
name: "Center for History and New Media",
creatorType: "author"
}
]
};
var json2 = {
creators: [
{
creatorType: "author",
name: "Center for History and New Media"
}
]
};
var diff = Zotero.Items.diff(json1, json2);
assert.isFalse(diff);
})
it("should show tags of different types as different", function* () {
var json1 = {
tags: [
{
tag: "Foo"
}
]
};
var json2 = {
tags: [
{
tag: "Foo",
type: 1
}
]
};
var diff = Zotero.Items.diff(json1, json2);
assert.isFalse(diff);
})
it("should not show manual tags as different without 'type' property", function* () {
var json1 = {
tags: [
{
tag: "Foo"
}
]
};
var json2 = {
tags: [
{
tag: "Foo",
type: 0
}
]
};
var diff = Zotero.Items.diff(json1, json2);
assert.isFalse(diff);
})
})
})