(mirror, obj, patches, path, invertible)
| 111 | } |
| 112 | // Dirty check if obj is different from mirror, generate patches and update mirror |
| 113 | function _generate(mirror, obj, patches, path, invertible) { |
| 114 | if (obj === mirror) { |
| 115 | return; |
| 116 | } |
| 117 | if (typeof obj.toJSON === "function") { |
| 118 | obj = obj.toJSON(); |
| 119 | } |
| 120 | var newKeys = _objectKeys(obj); |
| 121 | var oldKeys = _objectKeys(mirror); |
| 122 | var changed = false; |
| 123 | var deleted = false; |
| 124 | //if ever "move" operation is implemented here, make sure this test runs OK: "should not generate the same patch twice (move)" |
| 125 | for (var t = oldKeys.length - 1; t >= 0; t--) { |
| 126 | var key = oldKeys[t]; |
| 127 | var oldVal = mirror[key]; |
| 128 | if (hasOwnProperty(obj, key) && !(obj[key] === undefined && oldVal !== undefined && Array.isArray(obj) === false)) { |
| 129 | var newVal = obj[key]; |
| 130 | if (typeof oldVal == "object" && oldVal != null && typeof newVal == "object" && newVal != null && Array.isArray(oldVal) === Array.isArray(newVal)) { |
| 131 | _generate(oldVal, newVal, patches, path + "/" + escapePathComponent(key), invertible); |
| 132 | } |
| 133 | else { |
| 134 | if (oldVal !== newVal) { |
| 135 | changed = true; |
| 136 | if (invertible) { |
| 137 | patches.push({ op: "test", path: path + "/" + escapePathComponent(key), value: _deepClone(oldVal) }); |
| 138 | } |
| 139 | patches.push({ op: "replace", path: path + "/" + escapePathComponent(key), value: _deepClone(newVal) }); |
| 140 | } |
| 141 | } |
| 142 | } |
| 143 | else if (Array.isArray(mirror) === Array.isArray(obj)) { |
| 144 | if (invertible) { |
| 145 | patches.push({ op: "test", path: path + "/" + escapePathComponent(key), value: _deepClone(oldVal) }); |
| 146 | } |
| 147 | patches.push({ op: "remove", path: path + "/" + escapePathComponent(key) }); |
| 148 | deleted = true; // property has been deleted |
| 149 | } |
| 150 | else { |
| 151 | if (invertible) { |
| 152 | patches.push({ op: "test", path: path, value: mirror }); |
| 153 | } |
| 154 | patches.push({ op: "replace", path: path, value: obj }); |
| 155 | changed = true; |
| 156 | } |
| 157 | } |
| 158 | if (!deleted && newKeys.length == oldKeys.length) { |
| 159 | return; |
| 160 | } |
| 161 | for (var t = 0; t < newKeys.length; t++) { |
| 162 | var key = newKeys[t]; |
| 163 | if (!hasOwnProperty(mirror, key) && obj[key] !== undefined) { |
| 164 | patches.push({ op: "add", path: path + "/" + escapePathComponent(key), value: _deepClone(obj[key]) }); |
| 165 | } |
| 166 | } |
| 167 | } |
| 168 | /** |
| 169 | * Create an array of patches from the differences in two objects |
| 170 | */ |
no test coverage detected
searching dependent graphs…