[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:
parent
99a2dd3938
commit
04282ff00e
|
@ -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
|
||||
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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# */ {
|
||||
|
|
|
@ -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
Loading…
Reference in New Issue