Consider in-leaf with a unique value as constrained for domain inversion
Closes #13869
This commit is contained in:
+5
-10
@@ -2418,12 +2418,10 @@
|
||||
(expression.length > 2) &&
|
||||
(typeof expression[1] == 'string'));
|
||||
},
|
||||
constrained_leaf: function(part, boolop) {
|
||||
if (boolop === undefined) {
|
||||
boolop = this.and;
|
||||
}
|
||||
constrained_leaf: function(part) {
|
||||
var operand = part[1];
|
||||
if ((operand === '=') & (boolop === this.and)) {
|
||||
let value = part[2];
|
||||
if ((operand === '=') || ((operand == 'in') && (value.length == 1))) {
|
||||
// We should consider that other domain inversion will set a
|
||||
// correct value to this field
|
||||
return true;
|
||||
@@ -3049,8 +3047,7 @@
|
||||
((field in context) &&
|
||||
(this.domain_inversion.eval_leaf(
|
||||
part, context, this.domain_inversion.and) ||
|
||||
this.domain_inversion.constrained_leaf(
|
||||
part, this.domain_inversion.and)))) {
|
||||
this.domain_inversion.constrained_leaf(part)))) {
|
||||
result.push(true);
|
||||
} else {
|
||||
return false;
|
||||
@@ -3105,9 +3102,7 @@
|
||||
field = this.base(field);
|
||||
if ((field in context) &&
|
||||
(this.domain_inversion.eval_leaf(
|
||||
part, context, this.domain_inversion.or)) ||
|
||||
this.domain_inversion.constrained_leaf(
|
||||
part, this.domain_inversion.or)) {
|
||||
part, context, this.domain_inversion.or))) {
|
||||
return true;
|
||||
} else if ((field in context) &&
|
||||
!this.domain_inversion.eval_leaf(part, context,
|
||||
|
||||
@@ -2494,6 +2494,60 @@
|
||||
'domain_inversion(' + JSON.stringify(domain) + ', \'x\')');
|
||||
});
|
||||
|
||||
QUnit.test('DomainInversion unconstrained_inversion', function() {
|
||||
let domain_inversion = new Sao.common.DomainInversion();
|
||||
domain_inversion = domain_inversion.domain_inversion.bind(
|
||||
domain_inversion);
|
||||
let compare = Sao.common.compare;
|
||||
|
||||
let domain = [['x', '=', 3], ['y', 'in', ['a', 'b']]];
|
||||
QUnit.assert.ok(
|
||||
compare(domain_inversion(domain, 'x'), [['x', '=', 3]]),
|
||||
`domain_inversion(${domain}, 'x')`);
|
||||
QUnit.assert.ok(
|
||||
compare(domain_inversion(domain, 'x', {'y': 'a'}), [['x', '=', 3]]),
|
||||
`domain_inversion(${domain}, 'x', {'y': 'a'})`);
|
||||
QUnit.assert.strictEqual(
|
||||
domain_inversion(domain, 'x', {'y': 'c'}), false,
|
||||
`domain_inversion(${domain}, 'x', {'y': 'c'})`);
|
||||
});
|
||||
|
||||
QUnit.test('DomainInversion constrained_equal_inversion', function() {
|
||||
let domain_inversion = new Sao.common.DomainInversion();
|
||||
domain_inversion = domain_inversion.domain_inversion.bind(
|
||||
domain_inversion);
|
||||
let compare = Sao.common.compare;
|
||||
|
||||
let domain = [['x', '=', 3], ['y', '=', 'a']];
|
||||
QUnit.assert.ok(
|
||||
compare(domain_inversion(domain, 'x'), [['x', '=', 3]]),
|
||||
`domain_inversion(${domain}, 'x')`);
|
||||
QUnit.assert.ok(
|
||||
compare(domain_inversion(domain, 'x', {'y': 'a'}), [['x', '=', 3]]),
|
||||
`domain_inversion(${domain}, 'x', {'y': 'a'})`);
|
||||
QUnit.assert.ok(
|
||||
compare(domain_inversion(domain, 'x', {'y': 'c'}), [['x', '=', 3]]),
|
||||
`domain_inversion(${domain}, 'x', {'y': 'c'})`);
|
||||
});
|
||||
|
||||
QUnit.test('DomainInversion constrained_in_inversion', function() {
|
||||
let domain_inversion = new Sao.common.DomainInversion();
|
||||
domain_inversion = domain_inversion.domain_inversion.bind(
|
||||
domain_inversion);
|
||||
let compare = Sao.common.compare;
|
||||
|
||||
let domain = [['x', '=', 3], ['y', 'in', ['a']]];
|
||||
QUnit.assert.ok(
|
||||
compare(domain_inversion(domain, 'x'), [['x', '=', 3]]),
|
||||
`domain_inversion(${domain}, 'x')`);
|
||||
QUnit.assert.ok(
|
||||
compare(domain_inversion(domain, 'x', {'y': 'a'}), [['x', '=', 3]]),
|
||||
`domain_inversion(${domain}, 'x', {'y': 'a'})`);
|
||||
QUnit.assert.ok(
|
||||
compare(domain_inversion(domain, 'x', {'y': 'c'}), [['x', '=', 3]]),
|
||||
`domain_inversion(${domain}, 'x', {'y': 'c'})`);
|
||||
});
|
||||
|
||||
QUnit.test('DomainInversion and_inversion', function() {
|
||||
var domain_inversion = new Sao.common.DomainInversion();
|
||||
domain_inversion = domain_inversion.domain_inversion.bind(
|
||||
|
||||
@@ -79,9 +79,9 @@ def is_leaf(expression):
|
||||
and isinstance(expression[1], str))
|
||||
|
||||
|
||||
def constrained_leaf(part, boolop=operator.and_):
|
||||
def constrained_leaf(part):
|
||||
field, operand, value = part[:3]
|
||||
if operand == '=' and boolop == operator.and_:
|
||||
if operand == '=' or (operand == 'in' and len(value) == 1):
|
||||
# We should consider that other domain inversion will set a correct
|
||||
# value to this field
|
||||
return True
|
||||
@@ -502,7 +502,7 @@ class And(object):
|
||||
if (field not in context
|
||||
or field in context
|
||||
and (eval_leaf(part, context, operator.and_)
|
||||
or constrained_leaf(part, operator.and_))):
|
||||
or constrained_leaf(part))):
|
||||
result.append(True)
|
||||
else:
|
||||
return False
|
||||
@@ -544,8 +544,7 @@ class Or(And):
|
||||
field = part[0]
|
||||
field = self.base(field)
|
||||
if (field in context
|
||||
and (eval_leaf(part, context, operator.or_)
|
||||
or constrained_leaf(part, operator.or_))):
|
||||
and eval_leaf(part, context, operator.or_)):
|
||||
return True
|
||||
elif (field in context
|
||||
and not eval_leaf(part, context, operator.or_)):
|
||||
|
||||
@@ -596,6 +596,39 @@ class DomainInversionTestCase(TestCase):
|
||||
domain = [['x.id', '>', 5]]
|
||||
self.assertEqual(domain_inversion(domain, 'x'), [['x.id', '>', 5]])
|
||||
|
||||
def test_unconstrained_inversion(self):
|
||||
domain = [['x', '=', 3], ['y', 'in', ['a', 'b']]]
|
||||
|
||||
self.assertEqual(domain_inversion(domain, 'x'), [['x', '=', 3]])
|
||||
self.assertEqual(
|
||||
domain_inversion(domain, 'x', {'y': 'a'}),
|
||||
[['x', '=', 3]])
|
||||
self.assertEqual(
|
||||
domain_inversion(domain, 'x', {'y': 'c'}),
|
||||
False)
|
||||
|
||||
def test_constrained_equal_inversion(self):
|
||||
domain = [['x', '=', 3], ['y', '=', 'a']]
|
||||
|
||||
self.assertEqual(domain_inversion(domain, 'x'), [['x', '=', 3]])
|
||||
self.assertEqual(
|
||||
domain_inversion(domain, 'x', {'y': 'a'}),
|
||||
[['x', '=', 3]])
|
||||
self.assertEqual(
|
||||
domain_inversion(domain, 'x', {'y': 'c'}),
|
||||
[['x', '=', 3]])
|
||||
|
||||
def test_constrained_in_inversion(self):
|
||||
domain = [['x', '=', 3], ['y', 'in', ['a']]]
|
||||
|
||||
self.assertEqual(domain_inversion(domain, 'x'), [['x', '=', 3]])
|
||||
self.assertEqual(
|
||||
domain_inversion(domain, 'x', {'y': 'a'}),
|
||||
[['x', '=', 3]])
|
||||
self.assertEqual(
|
||||
domain_inversion(domain, 'x', {'y': 'c'}),
|
||||
[['x', '=', 3]])
|
||||
|
||||
def test_and_inversion(self):
|
||||
domain = [['x', '=', 3], ['y', '>', 5]]
|
||||
self.assertEqual(domain_inversion(domain, 'x'), [['x', '=', 3]])
|
||||
|
||||
@@ -79,9 +79,9 @@ def is_leaf(expression):
|
||||
and isinstance(expression[1], str))
|
||||
|
||||
|
||||
def constrained_leaf(part, boolop=operator.and_):
|
||||
def constrained_leaf(part):
|
||||
field, operand, value = part[:3]
|
||||
if operand == '=' and boolop == operator.and_:
|
||||
if operand == '=' or (operand == 'in' and len(value) == 1):
|
||||
# We should consider that other domain inversion will set a correct
|
||||
# value to this field
|
||||
return True
|
||||
@@ -502,7 +502,7 @@ class And(object):
|
||||
if (field not in context
|
||||
or field in context
|
||||
and (eval_leaf(part, context, operator.and_)
|
||||
or constrained_leaf(part, operator.and_))):
|
||||
or constrained_leaf(part))):
|
||||
result.append(True)
|
||||
else:
|
||||
return False
|
||||
@@ -544,8 +544,7 @@ class Or(And):
|
||||
field = part[0]
|
||||
field = self.base(field)
|
||||
if (field in context
|
||||
and (eval_leaf(part, context, operator.or_)
|
||||
or constrained_leaf(part, operator.or_))):
|
||||
and eval_leaf(part, context, operator.or_)):
|
||||
return True
|
||||
elif (field in context
|
||||
and not eval_leaf(part, context, operator.or_)):
|
||||
|
||||
Reference in New Issue
Block a user