Commit 21e6eb76 authored by Romain Courteaud's avatar Romain Courteaud

Accumulate modification_dict on onStateChange error

Resetting the internal gadget state leads to unexpecting errors, and so,
it was a bad idea.
parent 183cb362
......@@ -453,7 +453,6 @@
};
RenderJSGadget.setState = function (state_dict) {
var json_state = JSON.stringify(state_dict);
this.prototype.__json_state = json_state;
return this.ready(function () {
this.state = JSON.parse(json_state);
});
......@@ -584,10 +583,19 @@
.declareMethod('changeState', function (state_dict) {
var key,
modified = false,
modification_dict = {},
previous_cancelled = this.hasOwnProperty('__modification_dict'),
modification_dict,
context = this;
if (previous_cancelled) {
modification_dict = this.__modification_dict;
modified = true;
} else {
modification_dict = {};
this.__modification_dict = modification_dict;
}
for (key in state_dict) {
if (state_dict[key] !== this.state[key]) {
if (state_dict.hasOwnProperty(key) &&
(state_dict[key] !== this.state[key])) {
this.state[key] = state_dict[key];
modification_dict[key] = state_dict[key];
modified = true;
......@@ -598,13 +606,9 @@
.push(function () {
return context.__state_change_callback(modification_dict);
})
.push(undefined, function (error) {
if (context.__json_state !== undefined) {
context.state = JSON.parse(context.__json_state);
} else {
context.state = {};
}
throw error;
.push(function (result) {
delete context.__modification_dict;
return result;
});
}
});
......
......@@ -6,6 +6,7 @@
stop = QUnit.stop,
start = QUnit.start,
ok = QUnit.ok,
expect = QUnit.expect,
equal = QUnit.equal,
throws = QUnit.throws,
deepEqual = QUnit.deepEqual,
......@@ -1327,10 +1328,12 @@
});
});
test('reset state on onStateChange error', function () {
test('accumulate modification_dict on onStateChange error', function () {
var gadget = new RenderJSGadget();
gadget.state = {foo: 'bar', bar: 'foo'};
gadget.__state_change_callback = function () {
expect(13);
gadget.state = {a: 'b', foo: 'bar', bar: 'foo'};
gadget.__state_change_callback = function (modification_dict) {
deepEqual(modification_dict, {bar: 'barbar'});
throw new Error('failure in onStateChange');
};
stop();
......@@ -1340,35 +1343,44 @@
})
.fail(function (error) {
equal(error.message, 'failure in onStateChange');
deepEqual(gadget.state, {});
deepEqual(gadget.state, {a: 'b', foo: 'bar', bar: 'barbar'});
gadget.__state_change_callback = function (modification_dict) {
deepEqual(modification_dict, {bar: 'barbar', foo: 'foofoo'});
throw new Error('failure2 in onStateChange');
};
return gadget.changeState({foo: 'foofoo'});
})
.always(function () {
start();
});
});
.fail(function (error) {
equal(error.message, 'failure2 in onStateChange');
deepEqual(gadget.state, {a: 'b', foo: 'foofoo', bar: 'barbar'});
test('reset to default state on onStateChange error', function () {
// Subclass RenderJSGadget to not pollute its namespace
var Klass = function () {
RenderJSGadget.call(this);
}, gadget;
Klass.prototype = new RenderJSGadget();
Klass.prototype.constructor = Klass;
Klass.prototype.__json_state = JSON.stringify({a: 'b'});
gadget.__state_change_callback = function (modification_dict) {
deepEqual(modification_dict, {bar: 'barbar', foo: 'f'});
throw new Error('failure3 in onStateChange');
};
return gadget.changeState({foo: 'f'});
})
.fail(function (error) {
equal(error.message, 'failure3 in onStateChange');
deepEqual(gadget.state, {a: 'b', foo: 'f', bar: 'barbar'});
gadget = new Klass();
gadget.state = {foo: 'bar', bar: 'foo'};
gadget.__state_change_callback = function () {
throw new Error('failure in onStateChange');
};
stop();
gadget.changeState({bar: 'barbar'})
gadget.__state_change_callback = function (modification_dict) {
deepEqual(modification_dict, {a: 'c', bar: 'barbar', foo: 'f'});
};
return gadget.changeState({a: 'c'});
})
.then(function () {
ok(false, 'Expecting an error');
deepEqual(gadget.state, {a: 'c', foo: 'f', bar: 'barbar'});
gadget.__state_change_callback = function (modification_dict) {
deepEqual(modification_dict, {a: 'd'});
};
return gadget.changeState({a: 'd'});
})
.fail(function (error) {
equal(error.message, 'failure in onStateChange');
deepEqual(gadget.state, {a: 'b'});
.then(function () {
deepEqual(gadget.state, {a: 'd', foo: 'f', bar: 'barbar'});
})
.always(function () {
start();
......@@ -1836,7 +1848,6 @@
Klass.setState({foo: 'bar'});
equal(Klass.__ready_list.length, 1);
equal(Klass.prototype.__json_state, JSON.stringify({foo: 'bar'}));
});
/////////////////////////////////////////////////////////////////
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment