Commit 53cfcd0b authored by Romain Courteaud's avatar Romain Courteaud

Reset gadget state in case of error.

In case of onStateChange cancellation/error, reset the internal gadget state.
It will simplify the code of each onStateChange function, as developpers will
not have to handle such issue.
parent fb92d31a
......@@ -453,6 +453,7 @@
};
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);
});
......@@ -583,7 +584,8 @@
.declareMethod('changeState', function (state_dict) {
var key,
modified = false,
modification_dict = {};
modification_dict = {},
context = this;
for (key in state_dict) {
if (state_dict[key] !== this.state[key]) {
this.state[key] = state_dict[key];
......@@ -592,7 +594,18 @@
}
}
if (modified && this.__state_change_callback !== undefined) {
return this.__state_change_callback(modification_dict);
return new RSVP.Queue()
.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;
});
}
});
......
......@@ -1327,6 +1327,54 @@
});
});
test('reset state on onStateChange error', function () {
var gadget = new RenderJSGadget();
gadget.state = {foo: 'bar', bar: 'foo'};
gadget.__state_change_callback = function () {
throw new Error('failure in onStateChange');
};
stop();
gadget.changeState({bar: 'barbar'})
.then(function () {
ok(false, 'Expecting an error');
})
.fail(function (error) {
equal(error.message, 'failure in onStateChange');
deepEqual(gadget.state, {});
})
.always(function () {
start();
});
});
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 = new Klass();
gadget.state = {foo: 'bar', bar: 'foo'};
gadget.__state_change_callback = function () {
throw new Error('failure in onStateChange');
};
stop();
gadget.changeState({bar: 'barbar'})
.then(function () {
ok(false, 'Expecting an error');
})
.fail(function (error) {
equal(error.message, 'failure in onStateChange');
deepEqual(gadget.state, {a: 'b'});
})
.always(function () {
start();
});
});
/////////////////////////////////////////////////////////////////
// RenderJSGadgetKlass.declareAcquiredMethod
/////////////////////////////////////////////////////////////////
......@@ -1786,8 +1834,9 @@
Klass.ready = RenderJSGadget.ready;
Klass.setState = RenderJSGadget.setState;
Klass.setState({});
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