зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1142515: add utils to compare simple objects to support Loop context in rooms. r=Standard8
This commit is contained in:
Родитель
8e66196893
Коммит
7acc550f67
|
@ -553,6 +553,71 @@ var inChrome = typeof Components != "undefined" && "utils" in Components;
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the difference after comparing two different objects. It compares property
|
||||||
|
* names and their respective values if necessary.
|
||||||
|
* This function does _not_ recurse into object values to keep this functions'
|
||||||
|
* complexity predictable to O(2).
|
||||||
|
*
|
||||||
|
* @param {Object} a Object number 1, the comparator.
|
||||||
|
* @param {Object} b Object number 2, the comparison.
|
||||||
|
* @return {Object} The diff output, which is itself an object structured as:
|
||||||
|
* {
|
||||||
|
* updated: [prop1, prop6],
|
||||||
|
* added: [prop2],
|
||||||
|
* removed: [prop3]
|
||||||
|
* }
|
||||||
|
*/
|
||||||
|
function objectDiff(a, b) {
|
||||||
|
var propsA = a ? Object.getOwnPropertyNames(a) : [];
|
||||||
|
var propsB = b ? Object.getOwnPropertyNames(b) : [];
|
||||||
|
var diff = {
|
||||||
|
updated: [],
|
||||||
|
added: [],
|
||||||
|
removed: []
|
||||||
|
};
|
||||||
|
|
||||||
|
var prop;
|
||||||
|
for (var i = 0, lA = propsA.length; i < lA; ++i) {
|
||||||
|
prop = propsA[i];
|
||||||
|
if (propsB.indexOf(prop) == -1) {
|
||||||
|
diff.removed.push(prop);
|
||||||
|
} else if (a[prop] !== b[prop]) {
|
||||||
|
diff.updated.push(prop);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (var j = 0, lB = propsB.length; j < lB; ++j) {
|
||||||
|
prop = propsB[j];
|
||||||
|
if (propsA.indexOf(prop) == -1) {
|
||||||
|
diff.added.push(prop);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return diff;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* When comparing two object, you sometimes want to ignore falsy values when
|
||||||
|
* they're not persisted on the server, for example.
|
||||||
|
* This function removes all the empty/ falsy properties from the target object.
|
||||||
|
*
|
||||||
|
* @param {Object} obj Target object to strip the falsy properties from
|
||||||
|
* @return {Object}
|
||||||
|
*/
|
||||||
|
function stripFalsyValues(obj) {
|
||||||
|
var props = Object.getOwnPropertyNames(obj);
|
||||||
|
var prop;
|
||||||
|
for (var i = props.length; i >= 0; --i) {
|
||||||
|
prop = props[i];
|
||||||
|
// If the value of the object property evaluates to |false|, delete it.
|
||||||
|
if (!obj[prop]) {
|
||||||
|
delete obj[prop];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return obj;
|
||||||
|
}
|
||||||
|
|
||||||
this.utils = {
|
this.utils = {
|
||||||
CALL_TYPES: CALL_TYPES,
|
CALL_TYPES: CALL_TYPES,
|
||||||
FAILURE_DETAILS: FAILURE_DETAILS,
|
FAILURE_DETAILS: FAILURE_DETAILS,
|
||||||
|
@ -576,6 +641,8 @@ var inChrome = typeof Components != "undefined" && "utils" in Components;
|
||||||
atob: atob,
|
atob: atob,
|
||||||
btoa: btoa,
|
btoa: btoa,
|
||||||
strToUint8Array: strToUint8Array,
|
strToUint8Array: strToUint8Array,
|
||||||
Uint8ArrayToStr: Uint8ArrayToStr
|
Uint8ArrayToStr: Uint8ArrayToStr,
|
||||||
|
objectDiff: objectDiff,
|
||||||
|
stripFalsyValues: stripFalsyValues
|
||||||
};
|
};
|
||||||
}).call(inChrome ? this : loop.shared);
|
}).call(inChrome ? this : loop.shared);
|
||||||
|
|
|
@ -318,4 +318,102 @@ describe("loop.shared.utils", function() {
|
||||||
expect(result).eql({ major: Infinity, minor: 0 });
|
expect(result).eql({ major: Infinity, minor: 0 });
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe("#objectDiff", function() {
|
||||||
|
var a, b, diff;
|
||||||
|
|
||||||
|
afterEach(function() {
|
||||||
|
a = b = diff = null;
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should find object property additions", function() {
|
||||||
|
a = {
|
||||||
|
prop1: null
|
||||||
|
};
|
||||||
|
b = {
|
||||||
|
prop1: null,
|
||||||
|
prop2: null
|
||||||
|
};
|
||||||
|
|
||||||
|
diff = sharedUtils.objectDiff(a, b);
|
||||||
|
expect(diff.updated).to.eql([]);
|
||||||
|
expect(diff.removed).to.eql([]);
|
||||||
|
expect(diff.added).to.eql(["prop2"]);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should find object property value changes", function() {
|
||||||
|
a = {
|
||||||
|
prop1: null
|
||||||
|
};
|
||||||
|
b = {
|
||||||
|
prop1: "null"
|
||||||
|
};
|
||||||
|
|
||||||
|
diff = sharedUtils.objectDiff(a, b);
|
||||||
|
expect(diff.updated).to.eql(["prop1"]);
|
||||||
|
expect(diff.removed).to.eql([]);
|
||||||
|
expect(diff.added).to.eql([]);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should find object property removals", function() {
|
||||||
|
a = {
|
||||||
|
prop1: null
|
||||||
|
};
|
||||||
|
b = {};
|
||||||
|
|
||||||
|
diff = sharedUtils.objectDiff(a, b);
|
||||||
|
expect(diff.updated).to.eql([]);
|
||||||
|
expect(diff.removed).to.eql(["prop1"]);
|
||||||
|
expect(diff.added).to.eql([]);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should report a mix of removed, added and updated properties", function() {
|
||||||
|
a = {
|
||||||
|
prop1: null,
|
||||||
|
prop2: null
|
||||||
|
};
|
||||||
|
b = {
|
||||||
|
prop1: "null",
|
||||||
|
prop3: null
|
||||||
|
};
|
||||||
|
|
||||||
|
diff = sharedUtils.objectDiff(a, b);
|
||||||
|
expect(diff.updated).to.eql(["prop1"]);
|
||||||
|
expect(diff.removed).to.eql(["prop2"]);
|
||||||
|
expect(diff.added).to.eql(["prop3"]);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("#stripFalsyValues", function() {
|
||||||
|
var obj;
|
||||||
|
|
||||||
|
afterEach(function() {
|
||||||
|
obj = null;
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should strip falsy object property values", function() {
|
||||||
|
obj = {
|
||||||
|
prop1: null,
|
||||||
|
prop2: false,
|
||||||
|
prop3: undefined,
|
||||||
|
prop4: void 0,
|
||||||
|
prop5: "",
|
||||||
|
prop6: 0
|
||||||
|
};
|
||||||
|
|
||||||
|
sharedUtils.stripFalsyValues(obj);
|
||||||
|
expect(obj).to.eql({});
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should keep non-falsy values", function() {
|
||||||
|
obj = {
|
||||||
|
prop1: "null",
|
||||||
|
prop2: null,
|
||||||
|
prop3: true
|
||||||
|
};
|
||||||
|
|
||||||
|
sharedUtils.stripFalsyValues(obj);
|
||||||
|
expect(obj).to.eql({ prop1: "null", prop3: true });
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
Загрузка…
Ссылка в новой задаче