[FIX] web: manual update of select2 lib to 3.5.1 version
[odoo/odoo.git] / addons / web / static / test / evals.js
1 openerp.testing.section('eval.types', {
2     dependencies: ['web.core'],
3     setup: function (instance) {
4         instance.session.uid = 42;
5     }
6 }, function (test) {
7     var makeTimeCheck = function (instance) {
8         var context = instance.web.pyeval.context();
9         return function (expr, func, message) {
10             // evaluate expr between two calls to new Date(), and check that
11             // the result is between the transformed dates
12             var d0 = new Date();
13             var result = py.eval(expr, context);
14             var d1 = new Date();
15             ok(func(d0) <= result && result <= func(d1), message);
16         };
17     };
18     test('strftime', function (instance) {
19         var check = makeTimeCheck(instance);
20         check("time.strftime('%Y')", function(d) {
21             return String(d.getFullYear());
22         });
23         check("time.strftime('%Y')+'-01-30'", function(d) {
24             return String(d.getFullYear()) + '-01-30';
25         });
26         check("time.strftime('%Y-%m-%d %H:%M:%S')", function(d) {
27             return _.str.sprintf('%04d-%02d-%02d %02d:%02d:%02d',
28                 d.getUTCFullYear(), d.getUTCMonth() + 1, d.getUTCDate(),
29                 d.getUTCHours(), d.getUTCMinutes(), d.getUTCSeconds());
30         });
31     });
32     test('context_today', function (instance) {
33         var check = makeTimeCheck(instance);
34         check("context_today().strftime('%Y-%m-%d')", function(d) {
35             return String(_.str.sprintf('%04d-%02d-%02d',
36                 d.getFullYear(), d.getMonth() + 1, d.getDate()));
37         });
38     });
39     // Port from pypy/lib_pypy/test_datetime.py
40     var makeEq = function (instance, c2) {
41         var ctx = instance.web.pyeval.context();
42         var c = _.extend({ td: ctx.datetime.timedelta }, c2 || {});
43         return function (a, b, message) {
44             ok(py.eval(a + ' == ' + b, c), message);
45         };
46     };
47     test('timedelta.test_constructor', function (instance) {
48         var eq = makeEq(instance);
49
50         // keyword args to constructor
51         eq('td()', 'td(weeks=0, days=0, hours=0, minutes=0, seconds=0, ' +
52                       'milliseconds=0, microseconds=0)');
53         eq('td(1)', 'td(days=1)');
54         eq('td(0, 1)', 'td(seconds=1)');
55         eq('td(0, 0, 1)', 'td(microseconds=1)');
56         eq('td(weeks=1)', 'td(days=7)');
57         eq('td(days=1)', 'td(hours=24)');
58         eq('td(hours=1)', 'td(minutes=60)');
59         eq('td(minutes=1)', 'td(seconds=60)');
60         eq('td(seconds=1)', 'td(milliseconds=1000)');
61         eq('td(milliseconds=1)', 'td(microseconds=1000)');
62
63         // Check float args to constructor
64         eq('td(weeks=1.0/7)', 'td(days=1)');
65         eq('td(days=1.0/24)', 'td(hours=1)');
66         eq('td(hours=1.0/60)', 'td(minutes=1)');
67         eq('td(minutes=1.0/60)', 'td(seconds=1)');
68         eq('td(seconds=0.001)', 'td(milliseconds=1)');
69         eq('td(milliseconds=0.001)', 'td(microseconds=1)');
70     });
71     test('timedelta.test_computations', function (instance) {
72         var c = instance.web.pyeval.context();
73         var zero = py.float.fromJSON(0);
74         var eq = makeEq(instance, {
75             // one week
76             a: py.PY_call(c.datetime.timedelta, [
77                 py.float.fromJSON(7)]),
78             // one minute
79             b: py.PY_call(c.datetime.timedelta, [
80                 zero, py.float.fromJSON(60)]),
81             // one millisecond
82             c: py.PY_call(c.datetime.timedelta, [
83                 zero, zero, py.float.fromJSON(1000)]),
84         });
85
86         eq('a+b+c', 'td(7, 60, 1000)');
87         eq('a-b', 'td(6, 24*3600 - 60)');
88         eq('-a', 'td(-7)');
89         eq('+a', 'td(7)');
90         eq('-b', 'td(-1, 24*3600 - 60)');
91         eq('-c', 'td(-1, 24*3600 - 1, 999000)');
92 //        eq('abs(a)', 'a');
93 //        eq('abs(-a)', 'a');
94         eq('td(6, 24*3600)', 'a');
95         eq('td(0, 0, 60*1000000)', 'b');
96         eq('a*10', 'td(70)');
97         eq('a*10', '10*a');
98         // eq('a*10L', '10*a');
99         eq('b*10', 'td(0, 600)');
100         eq('10*b', 'td(0, 600)');
101         // eq('b*10L', 'td(0, 600)');
102         eq('c*10', 'td(0, 0, 10000)');
103         eq('10*c', 'td(0, 0, 10000)');
104         // eq('c*10L', 'td(0, 0, 10000)');
105         eq('a*-1', '-a');
106         eq('b*-2', '-b-b');
107         eq('c*-2', '-c+-c');
108         eq('b*(60*24)', '(b*60)*24');
109         eq('b*(60*24)', '(60*b)*24');
110         eq('c*1000', 'td(0, 1)');
111         eq('1000*c', 'td(0, 1)');
112         eq('a//7', 'td(1)');
113         eq('b//10', 'td(0, 6)');
114         eq('c//1000', 'td(0, 0, 1)');
115         eq('a//10', 'td(0, 7*24*360)');
116         eq('a//3600000', 'td(0, 0, 7*24*1000)');
117
118         // Issue #11576
119         eq('td(999999999, 86399, 999999) - td(999999999, 86399, 999998)', 'td(0, 0, 1)');
120         eq('td(999999999, 1, 1) - td(999999999, 1, 0)',
121            'td(0, 0, 1)');
122     });
123     test('timedelta.test_basic_attributes', function (instance) {
124         var ctx = instance.web.pyeval.context();
125         strictEqual(py.eval('datetime.timedelta(1, 7, 31).days', ctx), 1);
126         strictEqual(py.eval('datetime.timedelta(1, 7, 31).seconds', ctx), 7);
127         strictEqual(py.eval('datetime.timedelta(1, 7, 31).microseconds', ctx), 31);
128     });
129     test('timedelta.test_total_seconds', function (instance) {
130         var c = { timedelta: instance.web.pyeval.context().datetime.timedelta };
131         strictEqual(py.eval('timedelta(365).total_seconds()', c), 31536000);
132         strictEqual(
133             py.eval('timedelta(seconds=123456.789012).total_seconds()', c),
134             123456.789012);
135         strictEqual(
136             py.eval('timedelta(seconds=-123456.789012).total_seconds()', c),
137             -123456.789012);
138         strictEqual(
139             py.eval('timedelta(seconds=0.123456).total_seconds()', c), 0.123456);
140         strictEqual(py.eval('timedelta().total_seconds()', c), 0);
141         strictEqual(
142             py.eval('timedelta(seconds=1000000).total_seconds()', c), 1e6);
143     });
144     test('timedelta.test_str', function (instance) {
145         var c = { td: instance.web.pyeval.context().datetime.timedelta };
146
147         strictEqual(py.eval('str(td(1))', c), "1 day, 0:00:00");
148         strictEqual(py.eval('str(td(-1))', c), "-1 day, 0:00:00");
149         strictEqual(py.eval('str(td(2))', c), "2 days, 0:00:00");
150         strictEqual(py.eval('str(td(-2))', c), "-2 days, 0:00:00");
151
152         strictEqual(py.eval('str(td(hours=12, minutes=58, seconds=59))', c),
153                     "12:58:59");
154         strictEqual(py.eval('str(td(hours=2, minutes=3, seconds=4))', c),
155                      "2:03:04");
156         strictEqual(
157             py.eval('str(td(weeks=-30, hours=23, minutes=12, seconds=34))', c),
158             "-210 days, 23:12:34");
159
160         strictEqual(py.eval('str(td(milliseconds=1))', c), "0:00:00.001000");
161         strictEqual(py.eval('str(td(microseconds=3))', c), "0:00:00.000003");
162
163         strictEqual(
164             py.eval('str(td(days=999999999, hours=23, minutes=59, seconds=59, microseconds=999999))', c),
165            "999999999 days, 23:59:59.999999");
166     });
167     test('timedelta.test_massive_normalization', function (instance) {
168         var td = py.PY_call(
169             instance.web.pyeval.context().datetime.timedelta,
170             {microseconds: py.float.fromJSON(-1)});
171         strictEqual(td.days, -1);
172         strictEqual(td.seconds, 24 * 3600 - 1);
173         strictEqual(td.microseconds, 999999);
174     });
175     test('timedelta.test_bool', function (instance) {
176         var c = { td: instance.web.pyeval.context().datetime.timedelta };
177         ok(py.eval('bool(td(1))', c));
178         ok(py.eval('bool(td(0, 1))', c));
179         ok(py.eval('bool(td(0, 0, 1))', c));
180         ok(py.eval('bool(td(microseconds=1))', c));
181         ok(py.eval('bool(not td(0))', c));
182     });
183
184     test('date.test_computations', function (instance) {
185         var d = instance.web.pyeval.context().datetime;
186
187         var a = d.date.fromJSON(2002, 1, 31);
188         var b = d.date.fromJSON(1956, 1, 31);
189         strictEqual(
190             py.eval('(a - b).days', {a: a, b: b}),
191             46 * 365 + 12);
192         strictEqual(py.eval('(a - b).seconds', {a: a, b: b}), 0);
193         strictEqual(py.eval('(a - b).microseconds', {a: a, b: b}), 0);
194
195         var day = py.PY_call(d.timedelta, [py.float.fromJSON(1)]);
196         var week = py.PY_call(d.timedelta, [py.float.fromJSON(7)]);
197         a = d.date.fromJSON(2002, 3, 2);
198         var ctx = {
199             a: a,
200             day: day,
201             week: week,
202             date: d.date
203         };
204         ok(py.eval('a + day == date(2002, 3, 3)', ctx));
205         ok(py.eval('day + a == date(2002, 3, 3)', ctx)); // 5
206         ok(py.eval('a - day == date(2002, 3, 1)', ctx));
207         ok(py.eval('-day + a == date(2002, 3, 1)', ctx));
208         ok(py.eval('a + week == date(2002, 3, 9)', ctx));
209         ok(py.eval('a - week == date(2002, 2, 23)', ctx));
210         ok(py.eval('a + 52*week == date(2003, 3, 1)', ctx)); // 10
211         ok(py.eval('a - 52*week == date(2001, 3, 3)', ctx));
212         ok(py.eval('(a + week) - a == week', ctx));
213         ok(py.eval('(a + day) - a == day', ctx));
214         ok(py.eval('(a - week) - a == -week', ctx));
215         ok(py.eval('(a - day) - a == -day', ctx)); // 15
216         ok(py.eval('a - (a + week) == -week', ctx));
217         ok(py.eval('a - (a + day) == -day', ctx));
218         ok(py.eval('a - (a - week) == week', ctx));
219         ok(py.eval('a - (a - day) == day', ctx));
220
221         raises(function () {
222             py.eval('a + 1', ctx);
223         }, /^Error: TypeError:/); // 20
224         raises(function () {
225             py.eval('a - 1', ctx);
226         }, /^Error: TypeError:/);
227         raises(function () {
228             py.eval('1 + a', ctx);
229         }, /^Error: TypeError:/);
230         raises(function () {
231             py.eval('1 - a', ctx);
232         }, /^Error: TypeError:/);
233
234         // delta - date is senseless.
235         raises(function () {
236             py.eval('day - a', ctx);
237         }, /^Error: TypeError:/);
238         // mixing date and (delta or date) via * or // is senseless
239         raises(function () {
240             py.eval('day * a', ctx);
241         }, /^Error: TypeError:/); // 25
242         raises(function () {
243             py.eval('a * day', ctx);
244         }, /^Error: TypeError:/);
245         raises(function () {
246             py.eval('day // a', ctx);
247         }, /^Error: TypeError:/);
248         raises(function () {
249             py.eval('a // day', ctx);
250         }, /^Error: TypeError:/);
251         raises(function () {
252             py.eval('a * a', ctx);
253         }, /^Error: TypeError:/);
254         raises(function () {
255             py.eval('a // a', ctx);
256         }, /^Error: TypeError:/); // 30
257         // date + date is senseless
258         raises(function () {
259             py.eval('a + a', ctx);
260         }, /^Error: TypeError:/);
261     });
262     test('relastivedelta', function (instance) {
263         strictEqual(
264             py.eval("(datetime.date(2012, 2, 15) + relativedelta(days=-1)).strftime('%Y-%m-%d 23:59:59')",
265                     instance.web.pyeval.context()),
266             "2012-02-14 23:59:59");
267     });
268     test('datetime.tojson', function (instance) {
269         var result = py.eval(
270             'datetime.datetime(2012, 2, 15, 1, 7, 31)',
271             instance.web.pyeval.context());
272         ok(result instanceof Date);
273         equal(result.getFullYear(), 2012);
274         equal(result.getMonth(), 1);
275         equal(result.getDate(), 15);
276         equal(result.getHours(), 1);
277         equal(result.getMinutes(), 7);
278         equal(result.getSeconds(), 31);
279     });
280     test('datetime.combine', function (instance) {
281         var result = py.eval(
282             'datetime.datetime.combine(datetime.date(2012, 2, 15),' +
283             '                          datetime.time(1, 7, 13))' +
284             '   .strftime("%Y-%m-%d %H:%M:%S")',
285             instance.web.pyeval.context());
286         equal(result, "2012-02-15 01:07:13");
287
288         result = py.eval(
289             'datetime.datetime.combine(datetime.date(2012, 2, 15),' +
290             '                          datetime.time())' +
291             '   .strftime("%Y-%m-%d %H:%M:%S")',
292             instance.web.pyeval.context());
293         equal(result, '2012-02-15 00:00:00');
294     });
295     test('datetime.replace', function (instance) {
296         var result = py.eval(
297             'datetime.datetime(2012, 2, 15, 1, 7, 13)' +
298             '   .replace(hour=0, minute=0, second=0)' +
299             '   .strftime("%Y-%m-%d %H:%M:%S")',
300             instance.web.pyeval.context());
301         equal(result, "2012-02-15 00:00:00");
302     });
303 });
304 openerp.testing.section('eval.edc', {
305     dependencies: ['web.data'],
306     rpc: 'mock',
307     setup: function (instance, $fix, mock) {
308         var user = { login: 'admin', id: 1, lang: 'en_US', tz: false };
309         instance.edc = function (domains, contexts) {
310             return instance.web.pyeval.eval_domains_and_contexts({
311                 contexts: contexts || [],
312                 domains: domains || []
313             });
314         };
315         mock('res.lang:load_lang', function () { return true; });
316         mock('res.users:write', function (args) {
317             _.extend(user, args[1]);
318             return true;
319         });
320         mock('/web/session/get_session_info', function () {
321             return {
322                 session_id: 'foobar',
323                 db: '3',
324                 login: user.login,
325                 uid: user.id,
326                 user_context: {
327                     uid: user.id,
328                     lang: user.lang,
329                     tz: user.tz
330                 }
331             };
332         });
333         return instance.session.session_reload();
334     }
335 }, function (test) {
336     test('empty, basic', {asserts: 3}, function (instance) {
337         return instance.edc().then(function (result) {
338             // default values for new db
339             deepEqual(result.context, {
340                 lang: 'en_US',
341                 tz: false,
342                 uid: 1
343             });
344             deepEqual(result.domain, []);
345             deepEqual(result.group_by, []);
346         });
347     });
348     test('empty, context altered', {
349         asserts: 3,
350         setup: function (instance) {
351             var lang = new instance.web.Model('res.lang');
352             var users = new instance.web.Model('res.users');
353             return lang.call('load_lang', ['ru_RU']).then(function () {
354                 return users.call('write', [instance.session.uid, {
355                     lang: 'ru_RU',
356                     tz: 'America/Santarem'
357                 }]);
358             }).then(instance.session.session_reload.bind(instance.session));
359         }
360     }, function (instance) {
361         return instance.edc().then(function (result) {
362             // default values for new db
363             deepEqual(result.context, {
364                 lang: 'ru_RU',
365                 tz: 'America/Santarem',
366                 uid: 1
367             });
368             deepEqual(result.domain, []);
369             deepEqual(result.group_by, []);
370         });
371     });
372     test('context_merge_00', {asserts: 1}, function (instance) {
373         var ctx = [
374             {
375                 "__contexts": [
376                     { "lang": "en_US", "tz": false, "uid": 1 },
377                     {
378                         "active_id": 8,
379                         "active_ids": [ 8 ],
380                         "active_model": "sale.order",
381                         "bin_raw": true,
382                         "default_composition_mode": "comment",
383                         "default_model": "sale.order",
384                         "default_res_id": 8,
385                         "default_template_id": 18,
386                         "default_use_template": true,
387                         "edi_web_url_view": "faaaake",
388                         "lang": "en_US",
389                         "mark_so_as_sent": null,
390                         "show_address": null,
391                         "tz": false,
392                         "uid": null
393                     },
394                     {}
395                 ],
396                 "__eval_context": null,
397                 "__ref": "compound_context"
398             },
399             { "active_id": 9, "active_ids": [ 9 ], "active_model": "mail.compose.message" }
400         ];
401         return instance.edc([], ctx).then(function (result) {
402             deepEqual(result.context, {
403                 active_id: 9,
404                 active_ids: [9],
405                 active_model: 'mail.compose.message',
406                 bin_raw: true,
407                 default_composition_mode: 'comment',
408                 default_model: 'sale.order',
409                 default_res_id: 8,
410                 default_template_id: 18,
411                 default_use_template: true,
412                 edi_web_url_view: "faaaake",
413                 lang: 'en_US',
414                 mark_so_as_sent: null,
415                 show_address: null,
416                 tz: false,
417                 uid: null
418             });
419         });
420     });
421     test('context_merge_01', {asserts: 1}, function (instance) {
422         var ctx = [{
423             "__contexts": [
424                 {
425                     "lang": "en_US",
426                     "tz": false,
427                     "uid": 1
428                 },
429                 {
430                     "default_attachment_ids": [],
431                     "default_body": "",
432                     "default_content_subtype": "html",
433                     "default_model": "res.users",
434                     "default_parent_id": false,
435                     "default_res_id": 1
436                 },
437                 {}
438             ],
439             "__eval_context": null,
440             "__ref": "compound_context"
441         }];
442         return instance.edc([], ctx).then(function (result) {
443             deepEqual(result.context, {
444                 "default_attachment_ids": [],
445                 "default_body": "",
446                 "default_content_subtype": "html",
447                 "default_model": "res.users",
448                 "default_parent_id": false,
449                 "default_res_id": 1,
450                 "lang": "en_US",
451                 "tz": false,
452                 "uid": 1
453             });
454         });
455     });
456 });
457 openerp.testing.section('eval.edc.nonliterals', {
458     dependencies: ['web.data'],
459     setup: function (instance) {
460         instance.session.user_context = {
461             lang: 'en_US',
462             tz: false,
463             uid: 1
464         };
465         _.extend(instance, {
466             edc: function (domains, contexts) {
467                 return instance.web.pyeval.eval_domains_and_contexts({
468                     contexts: contexts || [],
469                     domains: domains || []
470                 });
471             }
472         });
473     }
474 }, function (test) {
475     test('domain with time', {asserts: 1}, function (instance) {
476         return instance.edc([
477             [['type', '=', 'contract']],
478             { "__domains": [["|"], [["state", "in", ["open", "draft"]]], [["state", "=", "pending"]]],
479               "__eval_context": null,
480               "__ref": "compound_domain"
481             },
482             "['|', '&', ('date', '!=', False), ('date', '<=', time.strftime('%Y-%m-%d')), ('is_overdue_quantity', '=', True)]",
483             [['user_id', '=', 1]]
484         ]).then(function (result) {
485             var d = new Date();
486             var today = _.str.sprintf("%04d-%02d-%02d",
487                 d.getUTCFullYear(), d.getUTCMonth() + 1, d.getUTCDate());
488             deepEqual(result.domain, [
489                 ["type", "=", "contract"],
490                 "|", ["state", "in", ["open", "draft"]],
491                      ["state", "=", "pending"],
492                 "|",
493                     "&", ["date", "!=", false],
494                          ["date", "<=", today],
495                     ["is_overdue_quantity", "=", true],
496                 ["user_id", "=", 1]
497             ]);
498         });
499     });
500     test('conditional context', {asserts: 2}, function (instance) {
501         var d = {
502             __ref: 'domain',
503             __debug: "[('company_id', '=', context.get('company_id',False))]"
504         };
505         var e1 = instance.edc([d]).then(function (result) {
506             deepEqual(result.domain, [
507                 ['company_id', '=', false]
508             ]);
509         });
510         var cd = new instance.web.CompoundDomain(d);
511         cd.set_eval_context({company_id: 42});
512         var e2 = instance.edc([cd]).then(function (result) {
513             deepEqual(result.domain, [
514                 ['company_id', '=', 42]
515             ]);
516         });
517
518         return $.when(e1, e2);
519     });
520     test('substitution in context', {asserts: 1}, function (instance) {
521         var c = "{'default_opportunity_id': active_id, 'default_duration': 1.0, 'lng': lang}";
522         var cc = new instance.web.CompoundContext(c);
523         cc.set_eval_context({active_id: 42});
524         return instance.edc([], [cc]).then(function (result) {
525             deepEqual(result.context, {
526                 lang: "en_US",
527                 tz: false,
528                 uid: 1,
529                 default_opportunity_id: 42,
530                 default_duration: 1.0,
531                 lng: "en_US"
532             });
533         });
534     });
535     test('date', {asserts: 1}, function (instance) {
536         var d = "[('state','!=','cancel'),('opening_date','>',context_today().strftime('%Y-%m-%d'))]";
537         return instance.edc([d]).then(function (result) {
538             var d = new Date();
539             var today = _.str.sprintf("%04d-%02d-%02d",
540                 d.getFullYear(), d.getMonth() + 1, d.getDate());
541             deepEqual(result.domain, [
542                 ['state', '!=', 'cancel'],
543                 ['opening_date', '>', today]
544             ]);
545         });
546     });
547     test('delta', {asserts: 1}, function (instance) {
548         var d = "[('type','=','in'),('day','<=', time.strftime('%Y-%m-%d')),('day','>',(context_today()-datetime.timedelta(days=15)).strftime('%Y-%m-%d'))]";
549         return instance.edc([d]).then(function (result) {
550             var d = new Date();
551             var today = _.str.sprintf("%04d-%02d-%02d",
552                 d.getFullYear(), d.getMonth() + 1, d.getDate());
553             d.setDate(d.getDate() - 15);
554             var ago_15_d = _.str.sprintf("%04d-%02d-%02d",
555                 d.getFullYear(), d.getMonth() + 1, d.getDate());
556             deepEqual(result.domain, [
557                 ['type', '=', 'in'],
558                 ['day', '<=', today],
559                 ['day', '>', ago_15_d]
560             ]);
561         });
562     });
563     test('horror from the deep', {asserts: 1}, function (instance) {
564         var cs = [
565             {"__ref": "compound_context",
566                 "__contexts": [
567                     {"__ref": "context", "__debug": "{'k': 'foo,' + str(context.get('test_key', False))}"},
568                     {"__ref": "compound_context",
569                         "__contexts": [
570                             {"lang": "en_US", "tz": false, "uid": 1},
571                             {"lang": "en_US", "tz": false, "uid": 1,
572                                 "active_model": "sale.order", "default_type": "out",
573                                 "show_address": 1, "contact_display": "partner_address",
574                                 "active_ids": [9], "active_id": 9},
575                             {}
576                         ], "__eval_context": null },
577                     {"active_id": 8, "active_ids": [8],
578                         "active_model": "stock.picking.out"},
579                     {"__ref": "context", "__debug": "{'default_ref': 'stock.picking.out,'+str(context.get('active_id', False))}", "__id": "54d6ad1d6c45"}
580                 ], "__eval_context": null}
581         ];
582         return instance.edc([], cs).then(function (result) {
583             deepEqual(result.context, {
584                 k: 'foo,False',
585                 lang: 'en_US',
586                 tz: false,
587                 uid: 1,
588                 active_model: 'stock.picking.out',
589                 active_id: 8,
590                 active_ids: [8],
591                 default_type: 'out',
592                 show_address: 1,
593                 contact_display: 'partner_address',
594                 default_ref: 'stock.picking.out,8'
595             });
596         });
597     });
598 });
599 openerp.testing.section('eval.contexts', {
600     dependencies: ['web.core']
601 }, function (test) {
602     test('context_recursive', function (instance) {
603         var context_to_eval = [{
604             __ref: 'context',
605             __debug: '{"foo": context.get("bar", "qux")}'
606         }];
607         deepEqual(
608             instance.web.pyeval.eval('contexts', context_to_eval, {bar: "ok"}),
609             {foo: 'ok'});
610         deepEqual(
611             instance.web.pyeval.eval('contexts', context_to_eval, {bar: false}),
612             {foo: false});
613         deepEqual(
614             instance.web.pyeval.eval('contexts', context_to_eval),
615             {foo: 'qux'});
616     });
617     test('context_sequences', function (instance) {
618         // Context n should have base evaluation context + all of contexts
619         // 0..n-1 in its own evaluation context
620         var active_id = 4;
621         var result = instance.web.pyeval.eval('contexts', [
622             {
623                 "__contexts": [
624                     {
625                         "department_id": false,
626                         "lang": "en_US",
627                         "project_id": false,
628                         "section_id": false,
629                         "tz": false,
630                         "uid": 1
631                     },
632                     { "search_default_create_uid": 1 },
633                     {}
634                 ],
635                 "__eval_context": null,
636                 "__ref": "compound_context"
637             },
638             {
639                 "active_id": active_id,
640                 "active_ids": [ active_id ],
641                 "active_model": "purchase.requisition"
642             },
643             {
644                 "__debug": "{'record_id' : active_id}",
645                 "__id": "63e8e9bff8a6",
646                 "__ref": "context"
647             }
648         ]);
649
650         deepEqual(result, {
651             department_id: false,
652             lang: 'en_US',
653             project_id: false,
654             section_id: false,
655             tz: false,
656             uid: 1,
657             search_default_create_uid: 1,
658             active_id: active_id,
659             active_ids: [active_id],
660             active_model: 'purchase.requisition',
661             record_id: active_id
662         });
663     });
664     test('non-literal_eval_contexts', function (instance) {
665         var result = instance.web.pyeval.eval('contexts', [{
666             "__ref": "compound_context",
667             "__contexts": [
668                 {"__ref": "context", "__debug": "{'type':parent.type}",
669                  "__id": "462b9dbed42f"}
670             ],
671             "__eval_context": {
672                 "__ref": "compound_context",
673                 "__contexts": [{
674                         "__ref": "compound_context",
675                         "__contexts": [
676                             {"__ref": "context", "__debug": "{'type': type}",
677                              "__id": "16a04ed5a194"}
678                         ],
679                         "__eval_context": {
680                             "__ref": "compound_context",
681                             "__contexts": [
682                                 {"lang": "en_US", "tz": false, "uid": 1,
683                                  "journal_type": "sale", "section_id": false,
684                                  "default_type": "out_invoice",
685                                  "type": "out_invoice", "department_id": false},
686                                 {"id": false, "journal_id": 10,
687                                  "number": false, "type": "out_invoice",
688                                  "currency_id": 1, "partner_id": 4,
689                                  "fiscal_position": false,
690                                  "date_invoice": false, "period_id": false,
691                                  "payment_term": false, "reference_type": "none",
692                                  "reference": false, "account_id": 440,
693                                  "name": false, "invoice_line": [],
694                                  "tax_line": [], "amount_untaxed": 0,
695                                  "amount_tax": 0, "reconciled": false,
696                                  "amount_total": 0, "state": "draft",
697                                  "residual": 0, "company_id": 1,
698                                  "date_due": false, "user_id": 1,
699                                  "partner_bank_id": false, "origin": false,
700                                  "move_id": false, "comment": false,
701                                  "payment_ids": [[6, false, []]],
702                                  "active_id": false, "active_ids": [],
703                                  "active_model": "account.invoice",
704                                  "parent": {}}
705                     ], "__eval_context": null}
706                 }, {
707                     "id": false,
708                     "product_id": 4,
709                     "name": "[PC1] Basic PC",
710                     "quantity": 1,
711                     "uos_id": 1,
712                     "price_unit": 100,
713                     "account_id": 853,
714                     "discount": 0,
715                     "account_analytic_id": false,
716                     "company_id": false,
717                     "note": false,
718                     "invoice_line_tax_id": [[6, false, [1]]],
719                     "active_id": false,
720                     "active_ids": [],
721                     "active_model": "account.invoice.line",
722                     "parent": {
723                         "id": false, "journal_id": 10, "number": false,
724                         "type": "out_invoice", "currency_id": 1,
725                         "partner_id": 4, "fiscal_position": false,
726                         "date_invoice": false, "period_id": false,
727                         "payment_term": false, "reference_type": "none",
728                         "reference": false, "account_id": 440, "name": false,
729                         "tax_line": [], "amount_untaxed": 0, "amount_tax": 0,
730                         "reconciled": false, "amount_total": 0,
731                         "state": "draft", "residual": 0, "company_id": 1,
732                         "date_due": false, "user_id": 1,
733                         "partner_bank_id": false, "origin": false,
734                         "move_id": false, "comment": false,
735                         "payment_ids": [[6, false, []]]}
736                 }],
737                 "__eval_context": null
738             }
739         }]);
740         deepEqual(result, {type: 'out_invoice'});
741     });
742     test('return-input-value', function (instance) {
743         var result = instance.web.pyeval.eval('contexts', [{
744             __ref: 'compound_context',
745             __contexts: ["{'line_id': line_id , 'journal_id': journal_id }"],
746             __eval_context: {
747                 __ref: 'compound_context',
748                 __contexts: [{
749                     __ref: 'compound_context',
750                     __contexts: [
751                         {lang: 'en_US', tz: 'Europe/Paris', uid: 1},
752                         {lang: 'en_US', tz: 'Europe/Paris', uid: 1},
753                         {}
754                     ],
755                     __eval_context: null,
756                 }, {
757                     active_id: false,
758                     active_ids: [],
759                     active_model: 'account.move',
760                     amount: 0,
761                     company_id: 1,
762                     date: '2013-06-21',
763                     id: false,
764                     journal_id: 14,
765                     line_id: [
766                         [0, false, {
767                             account_id: 55,
768                             amount_currency: 0,
769                             analytic_account_id: false,
770                             credit: 0,
771                             currency_id: false,
772                             date_maturity: false,
773                             debit: 0,
774                             name: "dscsd",
775                             partner_id: false,
776                             tax_amount: 0,
777                             tax_code_id: false,
778                         }]
779                     ],
780                     name: '/',
781                     narration: false,
782                     parent: {},
783                     partner_id: false,
784                     period_id: 6,
785                     ref: false,
786                     state: 'draft',
787                     to_check: false,
788                 }],
789                 __eval_context: null,
790             },
791         }]);
792         deepEqual(result, {
793             journal_id: 14,
794             line_id: [[0, false, {
795                 account_id: 55,
796                 amount_currency: 0,
797                 analytic_account_id: false,
798                 credit: 0,
799                 currency_id: false,
800                 date_maturity: false,
801                 debit: 0,
802                 name: "dscsd",
803                 partner_id: false,
804                 tax_amount: 0,
805                 tax_code_id: false,
806             }]],
807         });
808     });
809 });
810 openerp.testing.section('eval.domains', {
811     dependencies: ['web.core', 'web.dates']
812 }, function (test) {
813     test('current_date', function (instance) {
814         var current_date = instance.web.date_to_str(new Date());
815         var result = instance.web.pyeval.eval('domains',
816             [[],{"__ref":"domain","__debug":"[('name','>=',current_date),('name','<=',current_date)]","__id":"5dedcfc96648"}],
817             instance.web.pyeval.context());
818         deepEqual(result, [
819             ['name', '>=', current_date],
820             ['name', '<=', current_date]
821         ]);
822     });
823     test('context_freevar', function (instance) {
824         var domains_to_eval = [{
825             __ref: 'domain',
826             __debug: '[("foo", "=", context.get("bar", "qux"))]'
827         }, [['bar', '>=', 42]]];
828         deepEqual(
829             instance.web.pyeval.eval('domains', domains_to_eval, {bar: "ok"}),
830             [['foo', '=', 'ok'], ['bar', '>=', 42]]);
831         deepEqual(
832             instance.web.pyeval.eval('domains', domains_to_eval, {bar: false}),
833             [['foo', '=', false], ['bar', '>=', 42]]);
834         deepEqual(
835             instance.web.pyeval.eval('domains', domains_to_eval),
836             [['foo', '=', 'qux'], ['bar', '>=', 42]]);
837     });
838 });
839 openerp.testing.section('eval.groupbys', {
840     dependencies: ['web.core']
841 }, function (test) {
842     test('groupbys_00', function (instance) {
843         var result = instance.web.pyeval.eval('groupbys', [
844             {group_by: 'foo'},
845             {group_by: ['bar', 'qux']},
846             {group_by: null},
847             {group_by: 'grault'}
848         ]);
849         deepEqual(result, ['foo', 'bar', 'qux', 'grault']);
850     });
851     test('groupbys_01', function (instance) {
852         var result = instance.web.pyeval.eval('groupbys', [
853             {group_by: 'foo'},
854             { __ref: 'context', __debug: '{"group_by": "bar"}' },
855             {group_by: 'grault'}
856         ]);
857         deepEqual(result, ['foo', 'bar', 'grault']);
858     });
859     test('groupbys_02', function (instance) {
860         var result = instance.web.pyeval.eval('groupbys', [
861             {group_by: 'foo'},
862             {
863                 __ref: 'compound_context',
864                 __contexts: [ {group_by: 'bar'} ],
865                 __eval_context: null
866             },
867             {group_by: 'grault'}
868         ]);
869         deepEqual(result, ['foo', 'bar', 'grault']);
870     });
871     test('groupbys_03', function (instance) {
872         var result = instance.web.pyeval.eval('groupbys', [
873             {group_by: 'foo'},
874             {
875                 __ref: 'compound_context',
876                 __contexts: [
877                     { __ref: 'context', __debug: '{"group_by": value}' }
878                 ],
879                 __eval_context: { value: 'bar' }
880             },
881             {group_by: 'grault'}
882         ]);
883         deepEqual(result, ['foo', 'bar', 'grault']);
884     });
885     test('groupbys_04', function (instance) {
886         var result = instance.web.pyeval.eval('groupbys', [
887             {group_by: 'foo'},
888             {
889                 __ref: 'compound_context',
890                 __contexts: [
891                     { __ref: 'context', __debug: '{"group_by": value}' }
892                 ],
893                 __eval_context: { value: 'bar' }
894             },
895             {group_by: 'grault'}
896         ], { value: 'bar' });
897         deepEqual(result, ['foo', 'bar', 'grault']);
898     });
899     test('groupbys_05', function (instance) {
900         var result = instance.web.pyeval.eval('groupbys', [
901             {group_by: 'foo'},
902             { __ref: 'context', __debug: '{"group_by": value}' },
903             {group_by: 'grault'}
904         ], { value: 'bar' });
905         deepEqual(result, ['foo', 'bar', 'grault']);
906     });
907 });