[IMP] port search test to new framework, add handling of web.{submodule} dependencies

bzr revid: xmo@openerp.com-20121026084543-fobkc3ta5q2jc3q6
This commit is contained in:
Xavier Morel 2012-10-26 10:45:43 +02:00
parent 99a2dd3938
commit 04282ff00e
6 changed files with 395 additions and 421 deletions

View File

@ -417,26 +417,49 @@ Actual RPC
Testing API
-----------
.. todo:: implement options on sections
.. js:function:: openerp.testing.section(name[, options], body)
:param String name:
:param TestOptions options:
:param body:
:type body: Function<:js:func:`~openerp.testing.case`, void>
.. js:function:: openerp.testing.case(name[, options], callback)
:param String name:
:param TestOptions options:
:param callback:
:type callback: Function<instance, $, Function<String, Function, void>>
.. js:class:: TestOptions
the various options which can be passed to
:js:func:`~openerp.testing.section` or
:js:func:`~openerp.testing.case`
:js:func:`~openerp.testing.case`. Except for
:js:attr:`~TestOptions.setup` and
:js:attr:`~TestOptions.teardown`, an option on
:js:func:`~openerp.testing.case` will overwrite the corresponding
option on :js:func:`~openerp.testing.section` so
e.g. :js:attr:`~TestOptions.rpc` can be set for a
:js:func:`~openerp.testing.section` and then differently set for
some :js:func:`~openerp.testing.case` of that
:js:func:`~openerp.testing.section`
.. js:attribute:: TestOptions.asserts
An integer, the number of assertions which should run during a
normal execution of the test. Mandatory for asynchronous tests.
.. js:attribute:: TestOptions.setup
.. todo:: implement & document setup (async?)
Test case setup, run right before each test case. A section's
:js:func:`~TestOptions.setup` is run before the case's own, if
both are specified.
.. js:attribute:: TestOptions.teardown
.. todo:: implement & document teardown (async?)
Test case teardown, a case's :js:func:`~TestOptions.teardown`
is run before the corresponding section if both are present.
.. js:attribute:: TestOptions.fail_on_rejection

View File

@ -19,12 +19,14 @@
/**
* OpenERP instance constructor
*
* @param {Array} modules list of modules to initialize
* @param {Array|String} modules list of modules to initialize
*/
init: function(modules) {
// By default only web will be loaded, the rest will be by loaded
// by openerp.web.Session on the first session_authenticate
modules = _.union(['web'], modules || []);
if (modules === "fuck your shit, don't load anything you cunt") {
modules = [];
} else {
modules = _.union(['web'], modules || []);
}
var new_instance = {
// links to the global openerp
_openerp: openerp,

View File

@ -85,23 +85,17 @@ openerp.testing = {};
};
};
var _load = function (instance, module, loaded) {
if (!loaded) { loaded = []; }
var deps = dependencies[module];
if (!deps) { throw new Error("Unknown dependencies for " + module); }
var to_load = _.difference(deps, loaded);
while (!_.isEmpty(to_load)) {
_load(instance, to_load[0], loaded);
to_load = _.difference(deps, loaded);
testing.section = function (name, options, body) {
if (_.isFunction(options)) {
body = options;
options = {};
}
openerp.web[module](instance);
loaded.push(module);
};
_.defaults(options, {
setup: testing.noop,
teardown: testing.noop
});
testing.section = function (name, body) {
QUnit.module(testing.current_module + '.' + name);
QUnit.module(testing.current_module + '.' + name, {_oe: options});
body(testing.case);
};
testing.case = function (name, options, callback) {
@ -109,6 +103,10 @@ openerp.testing = {};
callback = options;
options = {};
}
_.defaults(options, {
setup: testing.noop,
teardown: testing.noop
});
var module = testing.current_module;
var module_index = _.indexOf(testing.dependencies, module);
@ -117,13 +115,66 @@ openerp.testing = {};
// returns -1 -> index becomes 0 -> replace with ``undefined`` so
// Array#slice returns a full copy
0, module_index + 1 || undefined);
QUnit.test(name, function (env) {
var instance = openerp.init(module_deps);
if (_.isNumber(options.asserts)) {
expect(options.asserts)
QUnit.test(name, function () {
// module testing environment
var self = this;
var opts = _.defaults({
// section setup
// case setup
// test
// case teardown
// section teardown
setup: function () {
if (self._oe.setup.apply(null, arguments)) {
throw new Error("Asynchronous setup not implemented");
}
if (options.setup.apply(null, arguments)) {
throw new Error("Asynchronous setup not implemented");
}
},
teardown: function () {
if (options.teardown.apply(null, arguments)) {
throw new Error("Asynchronous teardown not implemented");
}
if (self._oe.teardown(null, arguments)) {
throw new Error("Asynchronous teardown not implemented");
}
}
}, options, this._oe);
var instance;
if (!opts.dependencies) {
instance = openerp.init(module_deps);
} else {
// empty-but-specified dependencies actually allow running
// without loading any module into the instance
// TODO: clean up this mess
var d = opts.dependencies.slice();
var di = 0;
while (di < d.length) {
var m = /^web\.(\w+)$/.exec(d[di]);
if (m) {
d[di] = m[1];
}
d.splice.apply(d, [di+1, 0].concat(
_(dependencies[d[di]]).reverse()));
++di;
}
instance = openerp.init("fuck your shit, don't load anything you cunt");
_(d).chain()
.reverse()
.uniq()
.each(function (module) {
openerp.web[module](instance);
});
}
if (_.isNumber(opts.asserts)) {
expect(opts.asserts);
}
if (options.templates) {
if (opts.templates) {
for(var i=0; i<module_deps.length; ++i) {
var dep = module_deps[i];
var templates = testing.templates[dep];
@ -135,8 +186,10 @@ openerp.testing = {};
}
}
var $fixture = $('#qunit-fixture');
var mock, async = false;
switch (options.rpc) {
switch (opts.rpc) {
case 'mock':
async = true;
testing.mockifyRPC(instance);
@ -148,25 +201,29 @@ openerp.testing = {};
async = true;
}
// TODO: explicit dependencies options for web sub-modules (will deprecate _load/instanceFor)
var result = callback(instance, $('#qunit-fixture'), mock);
// TODO: async setup/teardown
opts.setup(instance, $fixture, mock);
var result = callback(instance, $fixture, mock);
// TODO: cleanup which works on errors
if (!(result && _.isFunction(result.then))) {
if (async) {
ok(false, "asynchronous test cases must return a promise");
}
opts.teardown(instance, $fixture, mock);
return;
}
stop();
if (!_.isNumber(options.asserts)) {
if (!_.isNumber(opts.asserts)) {
ok(false, "asynchronous test cases must specify the "
+ "number of assertions they expect");
}
result.then(function () {
start();
}, function (error) {
result.always(function () {
start();
opts.teardown(instance, $fixture, mock);
}).fail(function (error) {
if (options.fail_on_rejection === false) {
return;
}

View File

@ -1,6 +1,6 @@
openerp.web.list = function (instance) {
var _t = instance.web._t,
_lt = instance.web._lt;
_lt = instance.web._lt;
var QWeb = instance.web.qweb;
instance.web.views.add('list', 'instance.web.ListView');
instance.web.ListView = instance.web.View.extend( /** @lends instance.web.ListView# */ {

View File

@ -495,7 +495,7 @@ instance.web.ViewManager = instance.web.Widget.extend({
.find('.oe_view_manager_switch a').filter('[data-view-type="' + view_type + '"]')
.parent().addClass('active');
r = $.when(view_promise).then(function () {
return $.when(view_promise).then(function () {
_.each(_.keys(self.views), function(view_name) {
var controller = self.views[view_name].controller;
if (controller) {
@ -511,7 +511,6 @@ instance.web.ViewManager = instance.web.Widget.extend({
});
self.trigger('switch_mode', view_type, no_store, view_options);
});
return r;
},
do_create_view: function(view_type) {
// Lazy loading of views

File diff suppressed because it is too large Load Diff