Commit 07d8ddc6 authored by Romain Courteaud's avatar Romain Courteaud

trigger onStateChange when previous calls is finished

parent 95726c33
...@@ -598,36 +598,53 @@ ...@@ -598,36 +598,53 @@
return this.element; return this.element;
}) })
.declareMethod('changeState', function (state_dict) { .declareMethod('changeState', function (state_dict) {
var key, var next_onStateChange = new RSVP.Queue(),
modified = false, previous_onStateCHange,
previous_cancelled = this.hasOwnProperty('__modification_dict'),
modification_dict,
context = this; context = this;
if (previous_cancelled) { if (context.hasOwnProperty('__previous_onStateChange')) {
modification_dict = this.__modification_dict; previous_onStateCHange = context.__previous_onStateChange;
modified = true; next_onStateChange
} else {
modification_dict = {};
}
for (key in state_dict) {
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;
}
}
if (modified && this.__state_change_callback !== undefined) {
this.__modification_dict = modification_dict;
return new RSVP.Queue()
.push(function () { .push(function () {
return context.__state_change_callback(modification_dict); return previous_onStateCHange;
}) })
.push(function (result) { .push(undefined, function () {
delete context.__modification_dict; // Run callback even if previous failed
return result; return;
}); });
} }
context.__previous_onStateChange = next_onStateChange;
return next_onStateChange
.push(function () {
var key,
modified = false,
previous_cancelled = context.hasOwnProperty('__modification_dict'),
modification_dict;
if (previous_cancelled) {
modification_dict = context.__modification_dict;
modified = true;
} else {
modification_dict = {};
}
for (key in state_dict) {
if (state_dict.hasOwnProperty(key) &&
(state_dict[key] !== context.state[key])) {
context.state[key] = state_dict[key];
modification_dict[key] = state_dict[key];
modified = true;
}
}
if (modified && context.__state_change_callback !== undefined) {
context.__modification_dict = modification_dict;
return new RSVP.Queue()
.push(function () {
return context.__state_change_callback(modification_dict);
})
.push(function (result) {
delete context.__modification_dict;
return result;
});
}
});
}); });
///////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////
......
...@@ -1352,6 +1352,96 @@ ...@@ -1352,6 +1352,96 @@
}); });
}); });
test('trigger onStateChange when previous is resolved', function () {
var gadget = new RenderJSGadget(),
callback_count = 0;
gadget.state = {};
expect(6);
gadget.__state_change_callback = function (modification_dict) {
if (callback_count === 0) {
callback_count += 1;
deepEqual(modification_dict, {first: true});
return new RSVP.Queue()
.push(function () {
return RSVP.delay();
})
.push(function () {
deepEqual(gadget.state, {first: true});
callback_count += 1;
});
}
if (callback_count === 2) {
deepEqual(modification_dict, {second: true});
deepEqual(gadget.state, {first: true, second: true});
callback_count += 1;
} else {
throw new Error('Unexpected callback_count ' + callback_count);
}
};
stop();
return new RSVP.all([
gadget.changeState({first: true}),
gadget.changeState({second: true})
])
.then(function () {
equal(callback_count, 3);
deepEqual(gadget.state, {first: true, second: true});
})
.fail(function (error) {
ok(false, error);
})
.always(function () {
start();
});
});
test('trigger onStateChange when previous is rejected', function () {
var gadget = new RenderJSGadget(),
callback_count = 0;
gadget.state = {};
expect(7);
gadget.__state_change_callback = function (modification_dict) {
if (callback_count === 0) {
callback_count += 1;
deepEqual(modification_dict, {first: true});
return new RSVP.Queue()
.push(function () {
return RSVP.delay();
})
.push(function () {
deepEqual(gadget.state, {first: true});
callback_count += 1;
throw new Error('manually reject first callback');
});
}
if (callback_count === 2) {
deepEqual(modification_dict, {first: true, second: true});
deepEqual(gadget.state, {first: true, second: true});
callback_count += 1;
} else {
throw new Error('Unexpected callback_count ' + callback_count);
}
};
stop();
return new RSVP.all([
gadget.changeState({first: true})
.fail(function (error) {
equal(error.message, 'manually reject first callback');
}),
gadget.changeState({second: true})
])
.then(function () {
equal(callback_count, 3);
deepEqual(gadget.state, {first: true, second: true});
})
.fail(function (error) {
ok(false, error);
})
.always(function () {
start();
});
});
test('accumulate modification_dict on onStateChange error', function () { test('accumulate modification_dict on onStateChange error', function () {
var gadget = new RenderJSGadget(); var gadget = new RenderJSGadget();
expect(13); expect(13);
......
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