summaryrefslogtreecommitdiff
path: root/addons/web/static
diff options
context:
space:
mode:
authorAaron Bohy <aab@odoo.com>2020-07-10 16:54:22 +0000
committerAaron Bohy <aab@odoo.com>2020-07-16 07:03:05 +0000
commit12cc5fd0ccd7ae2981d07a59d5ccc6451b3d0d52 (patch)
tree8f6da61d301c1a1c6caa66a2313831cf0af494cb /addons/web/static
parent6f47bfd91677a2ad58e11d67418cc76ab566609c (diff)
[IMP] web: benchmark: revive benchmark suite
The benchmark suite has been broken for a while, by several refactorings (e.g. use of native Promise). This commit makes it work again. We do not use it much, but maybe we should as it can be useful to track changes (mostly in view renderers) that impact performances.
Diffstat (limited to 'addons/web/static')
-rw-r--r--addons/web/static/tests/views/form_benchmarks.js168
-rw-r--r--addons/web/static/tests/views/kanban_benchmarks.js155
-rw-r--r--addons/web/static/tests/views/list_benchmarks.js196
3 files changed, 266 insertions, 253 deletions
diff --git a/addons/web/static/tests/views/form_benchmarks.js b/addons/web/static/tests/views/form_benchmarks.js
index efd12741d66..b65e8a4ccce 100644
--- a/addons/web/static/tests/views/form_benchmarks.js
+++ b/addons/web/static/tests/views/form_benchmarks.js
@@ -1,94 +1,98 @@
odoo.define('web.form_benchmarks', function (require) {
-"use strict";
+ "use strict";
-var FormView = require('web.FormView');
-var testUtils = require('web.test_utils');
+ const FormView = require('web.FormView');
+ const testUtils = require('web.test_utils');
-var createView = testUtils.createView;
+ const { createView } = testUtils;
-QUnit.module('Form View', {
- beforeEach: function () {
- this.data = {
- foo: {
- fields: {
- many2many: { string: "bar", type: "many2many", relation: 'bar'},
+ QUnit.module('Form View', {
+ beforeEach: function () {
+ this.data = {
+ foo: {
+ fields: {
+ foo: {string: "Foo", type: "char"},
+ many2many: { string: "bar", type: "many2many", relation: 'bar'},
+ },
+ records: [
+ { id: 1, foo: "bar", many2many: []},
+ ],
+ onchanges: {}
},
- records: [
- { id: 1, many2many: []},
- ],
- onchanges: {}
- },
- bar: {
- fields: {
- char: {string: "char", type: "char"},
- many2many: { string: "pokemon", type: "many2many", relation: 'pokemon'},
+ bar: {
+ fields: {
+ char: {string: "char", type: "char"},
+ many2many: { string: "pokemon", type: "many2many", relation: 'pokemon'},
+ },
+ records: [],
+ onchanges: {}
},
- records: [],
- onchanges: {}
- },
- pokemon: {
- fields: {
- name: {string: "Name", type: "char"},
+ pokemon: {
+ fields: {
+ name: {string: "Name", type: "char"},
+ },
+ records: [],
+ onchanges: {}
},
- records: [],
- onchanges: {}
- },
- };
- this.arch = null;
- this.run = function (assert, done, cb) {
- var data = this.data;
- var arch = this.arch;
- new Benchmark.Suite({})
- .add('form', function () {
- var list = createView({
- View: FormView,
- model: 'foo',
- data: data,
- arch: arch,
- res_id: 1,
- });
- if (cb) {
- cb(list);
- }
- list.destroy();
- })
- .on('cycle', function(event) {
- assert.ok(true, String(event.target));
- })
- .on('complete', done)
- .run({ 'async': true });
- };
- }
-}, function () {
- QUnit.test('x2many with 250 rows, 2 fields (with many2many_tags, and modifiers), onchanges, and edition', function (assert) {
- var done = assert.async();
- assert.expect(1);
+ };
+ this.arch = null;
+ this.run = function (assert, viewParams, cb) {
+ const data = this.data;
+ const arch = this.arch;
+ return new Promise(resolve => {
+ new Benchmark.Suite({})
+ .add('form', {
+ defer: true,
+ fn: async (deferred) => {
+ const form = await createView(Object.assign({
+ View: FormView,
+ model: 'foo',
+ data,
+ arch,
+ }, viewParams));
+ if (cb) {
+ await cb(form);
+ }
+ form.destroy();
+ deferred.resolve();
+ },
+ })
+ .on('cycle', event => {
+ assert.ok(true, String(event.target));
+ })
+ .on('complete', resolve)
+ .run({ async: true });
+ });
+ };
+ }
+ }, function () {
+ QUnit.test('x2many with 250 rows, 2 fields (with many2many_tags, and modifiers), onchanges, and edition', function (assert) {
+ assert.expect(1);
- this.data.foo.onchanges.many2many = function (obj) {
- obj.many2many = [5].concat(obj.many2many);
- };
- for (var i = 2; i < 500; i) {
- this.data.bar.records.push({
- id: i,
- char: "automated data",
+ this.data.foo.onchanges.many2many = function (obj) {
+ obj.many2many = [5].concat(obj.many2many);
+ };
+ for (let i = 2; i < 500; i++) {
+ this.data.bar.records.push({
+ id: i,
+ char: "automated data",
+ });
+ this.data.foo.records[0].many2many.push(i);
+ }
+ this.arch = `
+ <form>
+ <field name="many2many">
+ <tree editable="top" limit="250">
+ <field name="char"/>
+ <field name="many2many" widget="many2many_tags" attrs="{'readonly': [('char', '==', 'toto')]}"/>
+ </tree>
+ </field>
+ </form>`;
+ return this.run(assert, { res_id: 1 }, async form => {
+ await testUtils.form.clickEdit(form);
+ await testUtils.dom.click(form.$('.o_data_cell:first'));
+ await testUtils.fields.editInput(form.$('input:first'), "tralala");
});
- this.data.foo.records[0].many2many.push(i);
- }
- this.arch =
- '<form string="Partners">' +
- '<field name="many2many">' +
- '<tree editable="top" limit="250">' +
- '<field name="char"/>' +
- '<field name="many2many" widget="many2many_tags" attrs="{\'readonly\': [(\'char\', \'==\', \'toto\')]}"/>' +
- '</tree>' +
- '</field>' +
- '</form>';
- this.run(assert, done, function (form) {
- testUtils.form.clickEdit(form);
- form.$('.o_data_cell:first').click();
- form.$('input:first').val("tralala").trigger('input');
});
});
});
-
-}); \ No newline at end of file
diff --git a/addons/web/static/tests/views/kanban_benchmarks.js b/addons/web/static/tests/views/kanban_benchmarks.js
index d0df270089f..020067cb45c 100644
--- a/addons/web/static/tests/views/kanban_benchmarks.js
+++ b/addons/web/static/tests/views/kanban_benchmarks.js
@@ -1,83 +1,92 @@
odoo.define('web.kanban_benchmarks', function (require) {
-"use strict";
+ "use strict";
-var KanbanView = require('web.KanbanView');
-var testUtils = require('web.test_utils');
+ const KanbanView = require('web.KanbanView');
+ const { createView } = require('web.test_utils');
-var createView = testUtils.createView;
-
-QUnit.module('Kanban View', {
- beforeEach: function () {
- this.data = {
- foo: {
- fields: {
- foo: {string: "Foo", type: "char"},
- bar: {string: "Bar", type: "boolean"},
- int_field: {string: "int_field", type: "integer", sortable: true},
- qux: {string: "my float", type: "float"},
+ QUnit.module('Kanban View', {
+ beforeEach: function () {
+ this.data = {
+ foo: {
+ fields: {
+ foo: {string: "Foo", type: "char"},
+ bar: {string: "Bar", type: "boolean"},
+ int_field: {string: "int_field", type: "integer", sortable: true},
+ qux: {string: "my float", type: "float"},
+ },
+ records: [
+ { id: 1, bar: true, foo: "yop", int_field: 10, qux: 0.4},
+ {id: 2, bar: true, foo: "blip", int_field: 9, qux: 13},
+ ]
},
- records: [
- { id: 1, bar: true, foo: "yop", int_field: 10, qux: 0.4},
- {id: 2, bar: true, foo: "blip", int_field: 9, qux: 13},
- ]
- },
- };
- this.arch = null;
- this.run = function (assert, done) {
- var data = this.data;
- var arch = this.arch;
- new Benchmark.Suite({})
- .add('kanban', function () {
- var kanban = createView({
- View: KanbanView,
- model: 'foo',
- data: data,
- arch: arch,
- });
- kanban.destroy();
- })
- .on('cycle', function(event) {
- assert.ok(true, String(event.target));
- })
- .on('complete', done)
- .run({ 'async': true });
- };
- }
-}, function () {
- QUnit.test('simple kanban view with 2 records', function (assert) {
- var done = assert.async();
- assert.expect(1);
-
- this.arch = '<kanban class="o_kanban_test"><templates><t t-name="kanban-box">' +
- '<div>' +
- '<t t-esc="record.foo.value"/>' +
- '<field name="foo"/>' +
- '</div>' +
- '</t></templates></kanban>';
-
- this.run(assert, done);
- });
+ };
+ this.arch = null;
+ this.run = function (assert) {
+ const data = this.data;
+ const arch = this.arch;
+ return new Promise(resolve => {
+ new Benchmark.Suite({})
+ .add('kanban', {
+ defer: true,
+ fn: async (deferred) => {
+ const kanban = await createView({
+ View: KanbanView,
+ model: 'foo',
+ data,
+ arch,
+ });
+ kanban.destroy();
+ deferred.resolve();
+ },
+ })
+ .on('cycle', event => {
+ assert.ok(true, String(event.target));
+ })
+ .on('complete', resolve)
+ .run({ async: true });
+ });
+ };
+ }
+ }, function () {
+ QUnit.test('simple kanban view with 2 records', function (assert) {
+ assert.expect(1);
- QUnit.test('simple kanban view with 200 records', function (assert) {
- var done = assert.async();
- assert.expect(1);
+ this.arch = `
+ <kanban>
+ <templates>
+ <t t-name="kanban-box">
+ <div>
+ <t t-esc="record.foo.value"/>
+ <field name="foo"/>
+ </div>
+ </t>
+ </templates>
+ </kanban>`;
+ return this.run(assert);
+ });
- for (var i = 2; i < 200; i++) {
- this.data.foo.records.push({
- id: i,
- foo: "automated data" + i,
- });
- }
+ QUnit.test('simple kanban view with 200 records', function (assert) {
+ assert.expect(1);
- this.arch = '<kanban class="o_kanban_test"><templates><t t-name="kanban-box">' +
- '<div>' +
- '<t t-esc="record.foo.value"/>' +
- '<field name="foo"/>' +
- '</div>' +
- '</t></templates></kanban>';
+ for (let i = 2; i < 200; i++) {
+ this.data.foo.records.push({
+ id: i,
+ foo: `automated data ${i}`,
+ });
+ }
- this.run(assert, done);
+ this.arch = `
+ <kanban>
+ <templates>
+ <t t-name="kanban-box">
+ <div>
+ <t t-esc="record.foo.value"/>
+ <field name="foo"/>
+ </div>
+ </t>
+ </templates>
+ </kanban>`;
+ return this.run(assert);
+ });
});
-
-});
});
diff --git a/addons/web/static/tests/views/list_benchmarks.js b/addons/web/static/tests/views/list_benchmarks.js
index 4dadbcb47bd..92d70054945 100644
--- a/addons/web/static/tests/views/list_benchmarks.js
+++ b/addons/web/static/tests/views/list_benchmarks.js
@@ -1,113 +1,113 @@
odoo.define('web.list_benchmarks', function (require) {
-"use strict";
+ "use strict";
-var ListView = require('web.ListView');
-var testUtils = require('web.test_utils');
+ const ListView = require('web.ListView');
+ const { createView } = require('web.test_utils');
-var createView = testUtils.createView;
-
-QUnit.module('List View', {
- beforeEach: function () {
- this.data = {
- foo: {
- fields: {
- foo: {string: "Foo", type: "char"},
- bar: {string: "Bar", type: "boolean"},
- int_field: {string: "int_field", type: "integer", sortable: true},
- qux: {string: "my float", type: "float"},
+ QUnit.module('List View', {
+ beforeEach: function () {
+ this.data = {
+ foo: {
+ fields: {
+ foo: {string: "Foo", type: "char"},
+ bar: {string: "Bar", type: "boolean"},
+ int_field: {string: "int_field", type: "integer", sortable: true},
+ qux: {string: "my float", type: "float"},
+ },
+ records: [
+ {id: 1, bar: true, foo: "yop", int_field: 10, qux: 0.4},
+ {id: 2, bar: true, foo: "blip", int_field: 9, qux: 13},
+ ]
},
- records: [
- { id: 1, bar: true, foo: "yop", int_field: 10, qux: 0.4},
- {id: 2, bar: true, foo: "blip", int_field: 9, qux: 13},
- ]
- },
- };
- this.arch = null;
- this.run = function (assert, done, cb) {
- var data = this.data;
- var arch = this.arch;
- new Benchmark.Suite({})
- .add('list', function () {
- var list = createView({
- View: ListView,
- model: 'foo',
- data: data,
- arch: arch,
- });
- if (cb) {
- cb(list);
- }
- list.destroy();
- })
- .on('cycle', function(event) {
- assert.ok(true, String(event.target));
- })
- .on('complete', done)
- .run({ 'async': true });
- };
- }
-}, function () {
- QUnit.test('simple readonly list with 2 rows and 2 fields', function (assert) {
- var done = assert.async();
- assert.expect(1);
+ };
+ this.arch = null;
+ this.run = function (assert, cb) {
+ const data = this.data;
+ const arch = this.arch;
+ return new Promise(resolve => {
+ new Benchmark.Suite({})
+ .add('list', {
+ defer: true,
+ fn: async (deferred) => {
+ const list = await createView({
+ View: ListView,
+ model: 'foo',
+ data,
+ arch,
+ });
+ if (cb) {
+ cb(list);
+ }
+ list.destroy();
+ deferred.resolve();
+ },
+ })
+ .on('cycle', event => {
+ assert.ok(true, String(event.target));
+ })
+ .on('complete', resolve)
+ .run({ async: true });
+ });
+ };
+ }
+ }, function () {
+ QUnit.test('simple readonly list with 2 rows and 2 fields', function (assert) {
+ assert.expect(1);
- this.arch ='<tree><field name="foo"/><field name="int_field"/></tree>';
- this.run(assert, done);
- });
+ this.arch = '<tree><field name="foo"/><field name="int_field"/></tree>';
+ return this.run(assert);
+ });
- QUnit.test('simple readonly list with 200 rows and 2 fields', function (assert) {
- var done = assert.async();
- assert.expect(1);
+ QUnit.test('simple readonly list with 200 rows and 2 fields', function (assert) {
+ assert.expect(1);
- for (var i = 2; i < 200; i++) {
- this.data.foo.records.push({
- id: i,
- foo: "automated data",
- int_field: 10 * i,
- });
- }
- this.arch ='<tree><field name="foo"/><field name="int_field"/></tree>';
- this.run(assert, done);
- });
+ for (let i = 2; i < 200; i++) {
+ this.data.foo.records.push({
+ id: i,
+ foo: "automated data",
+ int_field: 10 * i,
+ });
+ }
+ this.arch = '<tree><field name="foo"/><field name="int_field"/></tree>';
+ return this.run(assert);
+ });
- QUnit.test('simple readonly list with 200 rows and 2 fields (with widgets)', function (assert) {
- var done = assert.async();
- assert.expect(1);
+ QUnit.test('simple readonly list with 200 rows and 2 fields (with widgets)', function (assert) {
+ assert.expect(1);
- for (var i = 2; i < 200; i++) {
- this.data.foo.records.push({
- id: i,
- foo: "automated data",
- int_field: 10 * i,
- });
- }
- this.arch = '<tree><field name="foo" widget="char"/><field name="int_field" widget="integer"/></tree>';
- this.run(assert, done);
- });
+ for (let i = 2; i < 200; i++) {
+ this.data.foo.records.push({
+ id: i,
+ foo: "automated data",
+ int_field: 10 * i,
+ });
+ }
+ this.arch = '<tree><field name="foo" widget="char"/><field name="int_field" widget="integer"/></tree>';
+ return this.run(assert);
+ });
- QUnit.test('editable list with 200 rows 4 fields', function (assert) {
- var done = assert.async();
- assert.expect(1);
+ QUnit.test('editable list with 200 rows 4 fields', function (assert) {
+ assert.expect(1);
- for (var i = 2; i < 200; i++) {
- this.data.foo.records.push({
- id: i,
- foo: "automated data",
- int_field: 10 * i,
- bar: i % 2 === 0,
+ for (let i = 2; i < 200; i++) {
+ this.data.foo.records.push({
+ id: i,
+ foo: "automated data",
+ int_field: 10 * i,
+ bar: i % 2 === 0,
+ });
+ }
+ this.arch = `
+ <tree editable="bottom">
+ <field name="foo" attrs="{'readonly': [['bar', '=', True]]}"/>
+ <field name="int_field"/>
+ <field name="bar"/>
+ <field name="qux"/>
+ </tree>`;
+ return this.run(assert, list => {
+ list.$('.o_list_button_add').click();
+ list.$('.o_list_button_discard').click();
});
- }
- this.arch = '<tree editable="bottom">' +
- '<field name="foo" attrs="{\'readonly\': [[\'bar\', \'=\', True]]}"/>' +
- '<field name="int_field"/>' +
- '<field name="bar"/>' +
- '<field name="qux"/>' +
- '</tree>';
- this.run(assert, done, function (list) {
- list.$buttons.find('.o_list_button_add').click();
- list.$buttons.find('.o_list_button_discard').click();
});
});
-
-});
});