# -*- coding: utf-8 -*- # This file is part of Tryton. The COPYRIGHT file at the top level of # this repository contains the full copyright notices and license terms. import datetime as dt import unittest import doctest import sys import sql import sql.operators from trytond.tools import ( reduce_ids, reduce_domain, decimal_, is_instance_method, file_open, strip_wildcard, lstrip_wildcard, rstrip_wildcard, slugify, sortable_values, escape_wildcard, firstline) from trytond.tools.string_ import StringPartitioned, LazyString from trytond.tools.domain_inversion import ( domain_inversion, parse, simplify, merge, concat, unique_value, eval_domain, localize_domain, prepare_reference_domain, extract_reference_models) class ToolsTestCase(unittest.TestCase): 'Test tools' table = sql.Table('test') def test_reduce_ids_empty(self): 'Test reduce_ids empty list' self.assertEqual(reduce_ids(self.table.id, []), sql.Literal(False)) def test_reduce_ids_continue(self): 'Test reduce_ids continue list' self.assertEqual(reduce_ids(self.table.id, list(range(10))), sql.operators.Or(((self.table.id >= 0) & (self.table.id <= 9),))) def test_reduce_ids_one_hole(self): 'Test reduce_ids continue list with one hole' self.assertEqual(reduce_ids( self.table.id, list(range(10)) + list(range(20, 30))), ((self.table.id >= 0) & (self.table.id <= 9)) | ((self.table.id >= 20) & (self.table.id <= 29))) def test_reduce_ids_short_continue(self): 'Test reduce_ids short continue list' self.assertEqual(reduce_ids(self.table.id, list(range(4))), sql.operators.Or((self.table.id.in_(list(range(4))),))) def test_reduce_ids_complex(self): 'Test reduce_ids complex list' self.assertEqual(reduce_ids(self.table.id, list(range(10)) + list(range(25, 30)) + list(range(15, 20))), (((self.table.id >= 0) & (self.table.id <= 14)) | (self.table.id.in_(list(range(25, 30)))))) def test_reduce_ids_complex_small_continue(self): 'Test reduce_ids complex list with small continue' self.assertEqual(reduce_ids(self.table.id, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 15, 18, 19, 21]), (((self.table.id >= 1) & (self.table.id <= 12)) | (self.table.id.in_([15, 18, 19, 21])))) @unittest.skipIf(sys.flags.optimize, "assert removed by optimization") def test_reduce_ids_float(self): 'Test reduce_ids with integer as float' self.assertEqual(reduce_ids(self.table.id, [1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0, 15.0, 18.0, 19.0, 21.0]), (((self.table.id >= 1.0) & (self.table.id <= 12.0)) | (self.table.id.in_([15.0, 18.0, 19.0, 21.0])))) self.assertRaises(AssertionError, reduce_ids, self.table.id, [1.1]) def test_reduce_domain(self): 'Test reduce_domain' clause = ('x', '=', 'x') tests = ( ([clause], ['AND', clause]), ([clause, [clause]], ['AND', clause, clause]), (['AND', clause, [clause]], ['AND', clause, clause]), ([clause, ['AND', clause]], ['AND', clause, clause]), ([clause, ['AND', clause, clause]], ['AND', clause, clause, clause]), (['AND', clause, ['AND', clause]], ['AND', clause, clause]), ([[[clause]]], ['AND', clause]), (['OR', clause], ['OR', clause]), (['OR', clause, [clause]], ['OR', clause, ['AND', clause]]), (['OR', clause, [clause, clause]], ['OR', clause, ['AND', clause, clause]]), (['OR', clause, ['OR', clause]], ['OR', clause, clause]), (['OR', clause, [clause, ['OR', clause, clause]]], ['OR', clause, ['AND', clause, ['OR', clause, clause]]]), (['OR', [clause]], ['OR', ['AND', clause]]), ([], []), (['OR', clause, []], ['OR', clause, []]), (['AND', clause, []], ['AND', clause, []]), ) for i, j in tests: self.assertEqual(reduce_domain(i), j, '%s -> %s != %s' % (i, reduce_domain(i), j)) def test_is_instance_method(self): 'Test is_instance_method' class Foo(object): @staticmethod def static(): pass @classmethod def klass(cls): pass def instance(self): pass self.assertFalse(is_instance_method(Foo, 'static')) self.assertFalse(is_instance_method(Foo, 'klass')) self.assertTrue(is_instance_method(Foo, 'instance')) def test_file_open(self): "Test file_open" with file_open('__init__.py', subdir=None) as fp: self.assertTrue(fp) with file_open('ir/__init__.py') as fp: self.assertTrue(fp) with self.assertRaisesRegex(IOError, "File not found :"): with file_open('ir/noexist'): pass with self.assertRaisesRegex(IOError, "Permission denied:"): with file_open('/etc/passwd'): pass with self.assertRaisesRegex(IOError, "Permission denied:"): with file_open('../../foo'): pass def test_file_open_suffix(self): "Test file_open from same root name but with a suffix" with self.assertRaisesRegex(IOError, "Permission denied:"): file_open('../trytond_suffix', subdir=None) def test_strip_wildcard(self): 'Test strip wildcard' for clause, result in [ ('%a%', 'a'), ('%%%%a%%%', 'a'), ('\\%a%', '\\%a'), ('\\%a\\%', '\\%a\\%'), ('a', 'a'), ('', ''), (None, None), ]: self.assertEqual( strip_wildcard(clause), result, msg=clause) def test_strip_wildcard_different_wildcard(self): 'Test strip wildcard with different wildcard' self.assertEqual(strip_wildcard('___a___', '_'), 'a') def test_lstrip_wildcard(self): 'Test lstrip wildcard' for clause, result in [ ('%a', 'a'), ('%a%', 'a%'), ('%%%%a%', 'a%'), ('\\%a%', '\\%a%'), ('a', 'a'), ('', ''), (None, None), ]: self.assertEqual( lstrip_wildcard(clause), result, msg=clause) def test_lstrip_wildcard_different_wildcard(self): 'Test lstrip wildcard with different wildcard' self.assertEqual(lstrip_wildcard('___a', '_'), 'a') def test_rstrip_wildcard(self): 'Test rstrip wildcard' for clause, result in [ ('a%', 'a'), ('%a%', '%a'), ('%a%%%%%', '%a'), ('%a\\%', '%a\\%'), ('a', 'a'), ('', ''), (None, None), ]: self.assertEqual( rstrip_wildcard(clause), result, msg=clause) def test_rstrip_wildcard_diferent_wildcard(self): self.assertEqual(rstrip_wildcard('a___', '_'), 'a') def test_escape_wildcard(self): self.assertEqual( escape_wildcard('foo%bar_baz\\'), 'foo\\%bar\\_baz\\\\') def test_slugify(self): "Test slugify" self.assertEqual(slugify('unicode ♥ is ☢'), 'unicode-is') def test_slugify_hyphenate(self): "Test hyphenate in slugify" self.assertEqual(slugify('foo bar', hyphenate='_'), 'foo_bar') class StringPartitionedTestCase(unittest.TestCase): "Test StringPartitioned" def test_init(self): s = StringPartitioned('foo') self.assertEqual(s, 'foo') self.assertEqual(s._parts, ('foo',)) def test_init_partitioned(self): s = StringPartitioned( StringPartitioned('foo') + StringPartitioned('bar')) self.assertEqual(s, 'foobar') self.assertEqual(s._parts, ('foo', 'bar')) def test_iter(self): s = StringPartitioned('foo') self.assertEqual(list(s), ['foo']) def test_len(self): s = StringPartitioned('foo') self.assertEqual(len(s), 3) def test_str(self): s = StringPartitioned('foo') s = str(s) self.assertEqual(s, 'foo') self.assertIsInstance(s, str) self.assertNotIsInstance(s, StringPartitioned) def test_add(self): s = StringPartitioned('foo') s = s + 'bar' self.assertEqual(s, 'foobar') self.assertEqual(list(s), ['foo', 'bar']) def test_radd(self): s = StringPartitioned('foo') s = 'bar' + s self.assertEqual(s, 'barfoo') self.assertEqual(list(s), ['bar', 'foo']) class LazyStringTestCase(unittest.TestCase): "Test LazyString" def test_init(self): s = LazyString(lambda: 'foo') self.assertIsInstance(s, LazyString) self.assertEqual(str(s), 'foo') def test_init_args(self): s = LazyString(lambda a: a, 'foo') self.assertIsInstance(s, LazyString) self.assertEqual(str(s), 'foo') def test_add(self): s = LazyString(lambda: 'foo') s = s + 'bar' self.assertEqual(s, 'foobar') def test_radd(self): s = LazyString(lambda: 'foo') s = 'bar' + s self.assertEqual(s, 'barfoo') class DomainInversionTestCase(unittest.TestCase): "Test domain_inversion" def test_simple_inversion(self): domain = [['x', '=', 3]] self.assertEqual(domain_inversion(domain, 'x'), [['x', '=', 3]]) domain = [] self.assertEqual(domain_inversion(domain, 'x'), True) self.assertEqual(domain_inversion(domain, 'x', {'x': 5}), True) self.assertEqual(domain_inversion(domain, 'z', {'x': 7}), True) domain = [['x.id', '>', 5]] self.assertEqual(domain_inversion(domain, 'x'), [['x.id', '>', 5]]) def test_and_inversion(self): domain = [['x', '=', 3], ['y', '>', 5]] self.assertEqual(domain_inversion(domain, 'x'), [['x', '=', 3]]) self.assertEqual(domain_inversion(domain, 'x', {'y': 4}), False) self.assertEqual( domain_inversion(domain, 'x', {'y': 6}), [['x', '=', 3]]) domain = [['x', '=', 3], ['y', '=', 5]] self.assertEqual(domain_inversion(domain, 'z'), True) self.assertEqual(domain_inversion(domain, 'z', {'x': 2, 'y': 7}), True) self.assertEqual( domain_inversion(domain, 'x', {'y': None}), [['x', '=', 3]]) domain = [['x.id', '>', 5], ['y', '<', 3]] self.assertEqual(domain_inversion(domain, 'y'), [['y', '<', 3]]) self.assertEqual( domain_inversion(domain, 'y', {'x': 3}), [['y', '<', 3]]) self.assertEqual(domain_inversion(domain, 'x'), [['x.id', '>', 5]]) def test_or_inversion(self): domain = ['OR', ['x', '=', 3], ['y', '>', 5], ['z', '=', 'abc']] self.assertEqual(domain_inversion(domain, 'x'), True) self.assertEqual(domain_inversion(domain, 'x', {'y': 4}), True) self.assertEqual( domain_inversion(domain, 'x', {'y': 4, 'z': 'ab'}), [['x', '=', 3]]) self.assertEqual(domain_inversion(domain, 'x', {'y': 7}), True) self.assertEqual( domain_inversion(domain, 'x', {'y': 7, 'z': 'b'}), True) self.assertEqual(domain_inversion(domain, 'x', {'z': 'abc'}), True) self.assertEqual( domain_inversion(domain, 'x', {'y': 4, 'z': 'abc'}), True) domain = ['OR', ['x', '=', 3], ['y', '=', 5]] self.assertEqual( domain_inversion(domain, 'x', {'y': None}), [['x', '=', 3]]) domain = ['OR', ['x', '=', 3], ['y', '>', 5]] self.assertEqual(domain_inversion(domain, 'z'), True) domain = ['OR', ['x.id', '>', 5], ['y', '<', 3]] self.assertEqual(domain_inversion(domain, 'y'), True) self.assertEqual(domain_inversion(domain, 'y', {'z': 4}), True) self.assertEqual(domain_inversion(domain, 'y', {'x': 3}), True) domain = ['OR', ['length', '>', 5], ['language.code', '=', 'de_DE']] self.assertEqual( domain_inversion(domain, 'length', {'length': 0, 'name': 'n'}), True) def test_orand_inversion(self): domain = ['OR', [['x', '=', 3], ['y', '>', 5], ['z', '=', 'abc']], [['x', '=', 4]], [['y', '>', 6]]] self.assertEqual(domain_inversion(domain, 'x'), True) self.assertEqual(domain_inversion(domain, 'x', {'y': 4}), True) self.assertEqual( domain_inversion(domain, 'x', {'z': 'abc', 'y': 7}), True) self.assertEqual(domain_inversion(domain, 'x', {'y': 7}), True) self.assertEqual(domain_inversion(domain, 'x', {'z': 'ab'}), True) def test_andor_inversion(self): domain = [['OR', ['x', '=', 4], ['y', '>', 6]], ['z', '=', 3]] self.assertEqual(domain_inversion(domain, 'z'), [['z', '=', 3]]) self.assertEqual( domain_inversion(domain, 'z', {'x': 5}), [['z', '=', 3]]) self.assertEqual( domain_inversion(domain, 'z', {'x': 5, 'y': 5}), [['z', '=', 3]]) self.assertEqual( domain_inversion(domain, 'z', {'x': 5, 'y': 7}), [['z', '=', 3]]) def test_andand_inversion(self): domain = [[['x', '=', 4], ['y', '>', 6]], ['z', '=', 3]] self.assertEqual(domain_inversion(domain, 'z'), [['z', '=', 3]]) self.assertEqual( domain_inversion(domain, 'z', {'x': 5}), [['z', '=', 3]]) self.assertEqual( domain_inversion(domain, 'z', {'y': 5}), [['z', '=', 3]]) self.assertEqual( domain_inversion(domain, 'z', {'x': 4, 'y': 7}), [['z', '=', 3]]) domain = [ [['x', '=', 4], ['y', '>', 6], ['z', '=', 2]], [['w', '=', 2]]] self.assertEqual( domain_inversion(domain, 'z', {'x': 4}), [['z', '=', 2]]) def test_oror_inversion(self): domain = ['OR', ['OR', ['x', '=', 3], ['y', '>', 5]], ['OR', ['x', '=', 2], ['z', '=', 'abc']], ['OR', ['y', '=', 8], ['z', '=', 'y']]] self.assertEqual(domain_inversion(domain, 'x'), True) self.assertEqual(domain_inversion(domain, 'x', {'y': 4}), True) self.assertEqual(domain_inversion(domain, 'x', {'z': 'ab'}), True) self.assertEqual(domain_inversion(domain, 'x', {'y': 7}), True) self.assertEqual(domain_inversion(domain, 'x', {'z': 'abc'}), True) self.assertEqual(domain_inversion(domain, 'x', {'z': 'y'}), True) self.assertEqual(domain_inversion(domain, 'x', {'y': 8}), True) self.assertEqual( domain_inversion(domain, 'x', {'y': 8, 'z': 'b'}), True) self.assertEqual( domain_inversion(domain, 'x', {'y': 4, 'z': 'y'}), True) self.assertEqual( domain_inversion(domain, 'x', {'y': 7, 'z': 'abc'}), True) self.assertEqual( domain_inversion(domain, 'x', {'y': 4, 'z': 'b'}), ['OR', [['x', '=', 3]], [['x', '=', 2]]]) def test_parse(self): domain = parse([['x', '=', 5]]) self.assertEqual(domain.variables, set('x')) domain = parse(['OR', ['x', '=', 4], ['y', '>', 6]]) self.assertEqual(domain.variables, set('xy')) domain = parse([['OR', ['x', '=', 4], ['y', '>', 6]], ['z', '=', 3]]) self.assertEqual(domain.variables, set('xyz')) domain = parse([[['x', '=', 4], ['y', '>', 6]], ['z', '=', 3]]) self.assertEqual(domain.variables, set('xyz')) def test_simplify(self): domain = [['x', '=', 3]] self.assertEqual(simplify(domain), [['x', '=', 3]]) domain = [[['x', '=', 3]]] self.assertEqual(simplify(domain), [['x', '=', 3]]) domain = ['OR', ['x', '=', 3]] self.assertEqual(simplify(domain), [['x', '=', 3]]) domain = ['OR', [['x', '=', 3]], [['y', '=', 5]]] self.assertEqual( simplify(domain), ['OR', [['x', '=', 3]], [['y', '=', 5]]]) domain = ['OR', ['x', '=', 3], ['AND', ['y', '=', 5]]] self.assertEqual( simplify(domain), ['OR', ['x', '=', 3], [['y', '=', 5]]]) domain = ['AND'] self.assertEqual(simplify(domain), []) domain = ['OR'] self.assertEqual(simplify(domain), []) def test_merge(self): domain = [['x', '=', 6], ['y', '=', 7]] self.assertEqual(merge(domain), ['AND', ['x', '=', 6], ['y', '=', 7]]) domain = ['AND', ['x', '=', 6], ['y', '=', 7]] self.assertEqual(merge(domain), ['AND', ['x', '=', 6], ['y', '=', 7]]) domain = [['z', '=', 8], ['AND', ['x', '=', 6], ['y', '=', 7]]] self.assertEqual( merge(domain), ['AND', ['z', '=', 8], ['x', '=', 6], ['y', '=', 7]]) domain = ['OR', ['x', '=', 1], ['y', '=', 2], ['z', '=', 3]] self.assertEqual( merge(domain), ['OR', ['x', '=', 1], ['y', '=', 2], ['z', '=', 3]]) domain = ['OR', ['x', '=', 1], ['OR', ['y', '=', 2], ['z', '=', 3]]] self.assertEqual( merge(domain), ['OR', ['x', '=', 1], ['y', '=', 2], ['z', '=', 3]]) domain = ['OR', ['x', '=', 1], ['AND', ['y', '=', 2], ['z', '=', 3]]] self.assertEqual( merge(domain), ['OR', ['x', '=', 1], ['AND', ['y', '=', 2], ['z', '=', 3]]]) domain = [['z', '=', 8], ['OR', ['x', '=', 6], ['y', '=', 7]]] self.assertEqual( merge(domain), ['AND', ['z', '=', 8], ['OR', ['x', '=', 6], ['y', '=', 7]]]) domain = ['AND', ['OR', ['a', '=', 1], ['b', '=', 2]], ['OR', ['c', '=', 3], ['AND', ['d', '=', 4], ['d2', '=', 6]]], ['AND', ['d', '=', 5], ['e', '=', 6]], ['f', '=', 7]] self.assertEqual( merge(domain), ['AND', ['OR', ['a', '=', 1], ['b', '=', 2]], ['OR', ['c', '=', 3], ['AND', ['d', '=', 4], ['d2', '=', 6]]], ['d', '=', 5], ['e', '=', 6], ['f', '=', 7]]) def test_concat(self): domain1 = [['a', '=', 1]] domain2 = [['b', '=', 2]] self.assertEqual( concat(domain1, domain2), ['AND', ['a', '=', 1], ['b', '=', 2]]) self.assertEqual(concat([], domain1), domain1) self.assertEqual(concat(domain2, []), domain2) self.assertEqual(concat([], []), []) self.assertEqual( concat(domain1, domain2, domoperator='OR'), ['OR', [['a', '=', 1]], [['b', '=', 2]]]) def test_unique_value(self): domain = [['a', '=', 1]] self.assertEqual(unique_value(domain), (True, '=', 1)) domain = [['a', '!=', 1]] self.assertFalse(unique_value(domain)[0]) domain = [['a', '=', 1], ['a', '=', 2]] self.assertFalse(unique_value(domain)[0]) domain = [['a.b', '=', 1]] self.assertFalse(unique_value(domain)[0]) domain = [['a.id', '=', 1, 'model']] self.assertEqual(unique_value(domain), (True, '=', ['model', 1])) domain = [['a.b.id', '=', 1, 'model']] self.assertEqual(unique_value(domain), (False, None, None)) def test_evaldomain(self): domain = [['x', '>', 5]] self.assertTrue(eval_domain(domain, {'x': 6})) self.assertFalse(eval_domain(domain, {'x': 4})) domain = [['x', '>', None]] self.assertFalse(eval_domain(domain, {'x': dt.date.today()})) self.assertFalse(eval_domain(domain, {'x': dt.datetime.now()})) domain = [['x', '<', dt.date.today()]] self.assertFalse(eval_domain(domain, {'x': None})) domain = [['x', '<', dt.datetime.now()]] self.assertFalse(eval_domain(domain, {'x': None})) domain = [['x', 'in', [3, 5]]] self.assertTrue(eval_domain(domain, {'x': 3})) self.assertFalse(eval_domain(domain, {'x': 4})) self.assertTrue(eval_domain(domain, {'x': [3]})) self.assertTrue(eval_domain(domain, {'x': [3, 4]})) self.assertFalse(eval_domain(domain, {'x': [1, 2]})) domain = [['x', 'not in', [3, 5]]] self.assertFalse(eval_domain(domain, {'x': 3})) self.assertTrue(eval_domain(domain, {'x': 4})) self.assertFalse(eval_domain(domain, {'x': [3]})) self.assertFalse(eval_domain(domain, {'x': [3, 4]})) self.assertTrue(eval_domain(domain, {'x': [1, 2]})) domain = [['x', 'like', 'abc']] self.assertTrue(eval_domain(domain, {'x': 'abc'})) self.assertFalse(eval_domain(domain, {'x': ''})) self.assertFalse(eval_domain(domain, {'x': 'xyz'})) self.assertFalse(eval_domain(domain, {'x': 'abcd'})) domain = [['x', 'not like', 'abc']] self.assertTrue(eval_domain(domain, {'x': 'xyz'})) self.assertTrue(eval_domain(domain, {'x': 'ABC'})) self.assertFalse(eval_domain(domain, {'x': 'abc'})) domain = [['x', 'not ilike', 'abc']] self.assertTrue(eval_domain(domain, {'x': 'xyz'})) self.assertFalse(eval_domain(domain, {'x': 'ABC'})) self.assertFalse(eval_domain(domain, {'x': 'abc'})) domain = [['x', 'like', 'a%']] self.assertTrue(eval_domain(domain, {'x': 'a'})) self.assertTrue(eval_domain(domain, {'x': 'abcde'})) self.assertFalse(eval_domain(domain, {'x': ''})) self.assertFalse(eval_domain(domain, {'x': 'ABCDE'})) self.assertFalse(eval_domain(domain, {'x': 'xyz'})) domain = [['x', 'ilike', 'a%']] self.assertTrue(eval_domain(domain, {'x': 'a'})) self.assertTrue(eval_domain(domain, {'x': 'A'})) self.assertFalse(eval_domain(domain, {'x': ''})) self.assertFalse(eval_domain(domain, {'x': 'xyz'})) domain = [['x', 'like', 'a_']] self.assertTrue(eval_domain(domain, {'x': 'ab'})) self.assertFalse(eval_domain(domain, {'x': 'a'})) self.assertFalse(eval_domain(domain, {'x': 'abc'})) domain = [['x', 'like', 'a\\%b']] self.assertTrue(eval_domain(domain, {'x': 'a%b'})) self.assertFalse(eval_domain(domain, {'x': 'ab'})) self.assertFalse(eval_domain(domain, {'x': 'a123b'})) domain = [['x', 'like', '\\%b']] self.assertTrue(eval_domain(domain, {'x': '%b'})) self.assertFalse(eval_domain(domain, {'x': 'b'})) self.assertFalse(eval_domain(domain, {'x': '123b'})) domain = [['x', 'like', 'a\\_c']] self.assertTrue(eval_domain(domain, {'x': 'a_c'})) self.assertFalse(eval_domain(domain, {'x': 'abc'})) self.assertFalse(eval_domain(domain, {'x': 'ac'})) domain = [['x', 'like', 'a\\\\_c']] self.assertTrue(eval_domain(domain, {'x': 'a\\bc'})) self.assertFalse(eval_domain(domain, {'x': 'abc'})) domain = ['OR', ['x', '>', 10], ['x', '<', 0]] self.assertTrue(eval_domain(domain, {'x': 11})) self.assertTrue(eval_domain(domain, {'x': -4})) self.assertFalse(eval_domain(domain, {'x': 5})) domain = ['OR', ['x', '>', 0], ['x', '=', None]] self.assertTrue(eval_domain(domain, {'x': 1})) self.assertTrue(eval_domain(domain, {'x': None})) self.assertFalse(eval_domain(domain, {'x': -1})) self.assertFalse(eval_domain(domain, {'x': 0})) domain = [['x', '>', 0], ['OR', ['x', '=', 3], ['x', '=', 2]]] self.assertFalse(eval_domain(domain, {'x': 1})) self.assertTrue(eval_domain(domain, {'x': 3})) self.assertTrue(eval_domain(domain, {'x': 2})) self.assertFalse(eval_domain(domain, {'x': 4})) self.assertFalse(eval_domain(domain, {'x': 5})) self.assertFalse(eval_domain(domain, {'x': 6})) domain = ['OR', ['x', '=', 4], [['x', '>', 6], ['x', '<', 10]]] self.assertTrue(eval_domain(domain, {'x': 4})) self.assertTrue(eval_domain(domain, {'x': 7})) self.assertFalse(eval_domain(domain, {'x': 3})) self.assertFalse(eval_domain(domain, {'x': 5})) self.assertFalse(eval_domain(domain, {'x': 11})) domain = [['x', '=', 'test,1']] self.assertTrue(eval_domain(domain, {'x': ('test', 1)})) self.assertTrue(eval_domain(domain, {'x': 'test,1'})) self.assertFalse(eval_domain(domain, {'x': ('test', 2)})) self.assertFalse(eval_domain(domain, {'x': 'test,2'})) domain = [['x', '=', ('test', 1)]] self.assertTrue(eval_domain(domain, {'x': ('test', 1)})) self.assertTrue(eval_domain(domain, {'x': 'test,1'})) self.assertFalse(eval_domain(domain, {'x': ('test', 2)})) self.assertFalse(eval_domain(domain, {'x': 'test,2'})) domain = [['x', '=', 1]] self.assertTrue(eval_domain(domain, {'x': [1, 2]})) self.assertFalse(eval_domain(domain, {'x': [2]})) domain = [['x', '=', None]] self.assertTrue(eval_domain(domain, {'x': []})) domain = [['x', '=', ['foo', 1]]] self.assertTrue(eval_domain(domain, {'x': 'foo,1'})) self.assertTrue(eval_domain(domain, {'x': ('foo', 1)})) self.assertTrue(eval_domain(domain, {'x': ['foo', 1]})) domain = [['x', '=', ('foo', 1)]] self.assertTrue(eval_domain(domain, {'x': 'foo,1'})) self.assertTrue(eval_domain(domain, {'x': ('foo', 1)})) self.assertTrue(eval_domain(domain, {'x': ['foo', 1]})) domain = [['x', '=', 'foo,1']] self.assertTrue(eval_domain(domain, {'x': ['foo', 1]})) self.assertTrue(eval_domain(domain, {'x': ('foo', 1)})) def test_localize(self): domain = [['x', '=', 5]] self.assertEqual(localize_domain(domain), [['x', '=', 5]]) domain = [['x', '=', 5], ['x.code', '=', 7]] self.assertEqual( localize_domain(domain, 'x'), [['id', '=', 5], ['code', '=', 7]]) domain = [['x', 'ilike', 'foo%'], ['x.code', '=', 'test']] self.assertEqual( localize_domain(domain, 'x'), [['rec_name', 'ilike', 'foo%'], ['code', '=', 'test']]) domain = ['OR', ['AND', ['x', '>', 7], ['x', '<', 15]], ['x.code', '=', 8]] self.assertEqual( localize_domain(domain, 'x'), ['OR', ['AND', ['id', '>', 7], ['id', '<', 15]], ['code', '=', 8]]) domain = [['x', 'child_of', [1]]] self.assertEqual( localize_domain(domain, 'x'), [['x', 'child_of', [1]]]) domain = [['x', 'child_of', [1], 'y']] self.assertEqual( localize_domain(domain, 'x'), [['y', 'child_of', [1]]]) domain = [['x.y', 'child_of', [1], 'parent']] self.assertEqual( localize_domain(domain, 'x'), [['y', 'child_of', [1], 'parent']]) domain = [['x.y.z', 'child_of', [1], 'parent', 'model']] self.assertEqual( localize_domain(domain, 'x'), [['y.z', 'child_of', [1], 'parent', 'model']]) domain = [['x.id', '=', 1, 'y']] self.assertEqual( localize_domain(domain, 'x', False), [['id', '=', 1, 'y']]) self.assertEqual(localize_domain(domain, 'x', True), [['id', '=', 1]]) domain = [['a.b.c', '=', 1, 'y', 'z']] self.assertEqual( localize_domain(domain, 'x', False), [['b.c', '=', 1, 'y', 'z']]) self.assertEqual( localize_domain(domain, 'x', True), [['b.c', '=', 1, 'z']]) def test_prepare_reference_domain(self): domain = [['x', 'like', 'A%']] self.assertEqual( prepare_reference_domain(domain, 'x'), [['x', 'like', 'A%']]) domain = [['x.y', 'like', 'A%', 'model']] self.assertEqual( prepare_reference_domain(domain, 'x'), [['y', 'like', 'A%']]) domain = [['x.y', 'child_of', [1], 'model', 'parent']] self.assertEqual( prepare_reference_domain(domain, 'x'), [['y', 'child_of', [1], 'parent']]) def test_extract_models(self): domain = [['x', 'like', 'A%']] self.assertEqual(extract_reference_models(domain, 'x'), set()) self.assertEqual(extract_reference_models(domain, 'y'), set()) domain = [['x', 'like', 'A%', 'model']] self.assertEqual(extract_reference_models(domain, 'x'), {'model'}) self.assertEqual(extract_reference_models(domain, 'y'), set()) domain = ['OR', ['x.y', 'like', 'A%', 'model_A'], ['x.z', 'like', 'B%', 'model_B']] self.assertEqual( extract_reference_models(domain, 'x'), {'model_A', 'model_B'}) self.assertEqual(extract_reference_models(domain, 'y'), set()) def test_sortable_values(self): def key(values): return values values = [ (('a', 1), ('b', None)), (('a', 1), ('b', 3)), (('a', 1), ('b', 2)), ] with self.assertRaises(TypeError): sorted(values, key=key) self.assertEqual( sorted(values, key=sortable_values(key)), [ (('a', 1), ('b', 2)), (('a', 1), ('b', 3)), (('a', 1), ('b', None)), ]) def test_firstline(self): "Test firstline" for text, result in [ ("", ""), ("first line\nsecond line", "first line"), ("\nsecond line", "second line"), ("\n\nthird line", "third line"), (" \nsecond line", "second line"), ]: with self.subTest(text=text, result=result): self.assertEqual(firstline(text), result) def suite(): func = unittest.TestLoader().loadTestsFromTestCase suite = unittest.TestSuite() for testcase in [ToolsTestCase, StringPartitionedTestCase, DomainInversionTestCase]: suite.addTests(func(testcase)) suite.addTest(doctest.DocTestSuite(decimal_)) return suite