Merge "Add OneOf smart type"
This commit is contained in:
commit
5c14f29f9b
@ -15,6 +15,7 @@
|
|||||||
import inspect
|
import inspect
|
||||||
import os.path
|
import os.path
|
||||||
|
|
||||||
|
from yaql.language import exceptions as yaql_exc
|
||||||
from yaql.language import expressions as yaql_expressions
|
from yaql.language import expressions as yaql_expressions
|
||||||
from yaql.language import utils
|
from yaql.language import utils
|
||||||
from yaql.language import yaqltypes
|
from yaql.language import yaqltypes
|
||||||
@ -324,3 +325,56 @@ def to_mutable(obj, yaql_engine):
|
|||||||
|
|
||||||
limiter = lambda it: utils.limit_iterable(it, constants.ITERATORS_LIMIT)
|
limiter = lambda it: utils.limit_iterable(it, constants.ITERATORS_LIMIT)
|
||||||
return converter(obj, limiter, yaql_engine, converter)
|
return converter(obj, limiter, yaql_engine, converter)
|
||||||
|
|
||||||
|
|
||||||
|
class OneOf(yaqltypes.SmartType):
|
||||||
|
def __init__(self, *args, **kwargs):
|
||||||
|
self.nullable = kwargs.pop('nullable', False)
|
||||||
|
super(OneOf, self).__init__(self.nullable)
|
||||||
|
|
||||||
|
self.choices = []
|
||||||
|
for item in args:
|
||||||
|
if isinstance(item, type):
|
||||||
|
item = yaqltypes.PythonType(item)
|
||||||
|
self.choices.append(item)
|
||||||
|
|
||||||
|
def _check_match(self, value, context, engine, *args, **kwargs):
|
||||||
|
for type_to_check in self.choices:
|
||||||
|
check_result = type_to_check.check(value, context, engine,
|
||||||
|
*args, **kwargs)
|
||||||
|
if check_result:
|
||||||
|
return type_to_check
|
||||||
|
|
||||||
|
def check(self, value, context, engine, *args, **kwargs):
|
||||||
|
if isinstance(value, yaql_expressions.Constant):
|
||||||
|
if value.value is None:
|
||||||
|
value = None
|
||||||
|
if value is None:
|
||||||
|
return self.nullable
|
||||||
|
|
||||||
|
check_result = self._check_match(value, context, engine,
|
||||||
|
*args, **kwargs)
|
||||||
|
if check_result:
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
|
def convert(self, value, receiver, context, function_spec, engine,
|
||||||
|
*args, **kwargs):
|
||||||
|
if isinstance(value, yaql_expressions.Constant):
|
||||||
|
if value.value is None:
|
||||||
|
value = None
|
||||||
|
if value is None:
|
||||||
|
if self.nullable:
|
||||||
|
return None
|
||||||
|
else:
|
||||||
|
suitable_type = False
|
||||||
|
|
||||||
|
else:
|
||||||
|
suitable_type = self._check_match(value, context, engine,
|
||||||
|
*args, **kwargs)
|
||||||
|
if suitable_type:
|
||||||
|
converted_value = suitable_type.convert(value, receiver, context,
|
||||||
|
function_spec, engine,
|
||||||
|
*args, **kwargs)
|
||||||
|
return converted_value
|
||||||
|
raise yaql_exc.ArgumentValueException()
|
||||||
|
39
murano/tests/unit/dsl/meta/OneOfSmartType.yaml
Normal file
39
murano/tests/unit/dsl/meta/OneOfSmartType.yaml
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
Name: OneOfSmartType
|
||||||
|
|
||||||
|
Namespaces:
|
||||||
|
sys: io.murano.system
|
||||||
|
|
||||||
|
Methods:
|
||||||
|
testNegative1:
|
||||||
|
Body:
|
||||||
|
- testOneOf(1, 'test')
|
||||||
|
|
||||||
|
testNegative2:
|
||||||
|
Body:
|
||||||
|
- testOneOf('test', 1)
|
||||||
|
|
||||||
|
testNegative3:
|
||||||
|
Body:
|
||||||
|
- testOneOf()
|
||||||
|
|
||||||
|
testNegative4:
|
||||||
|
Body:
|
||||||
|
- testOneOf(null, null)
|
||||||
|
|
||||||
|
testNullable:
|
||||||
|
Body:
|
||||||
|
- trace(testOneOf('io.murano.system.AgentListener', null))
|
||||||
|
|
||||||
|
testPositive1:
|
||||||
|
Body:
|
||||||
|
- trace(testOneOf(sys:AgentListener, 2))
|
||||||
|
|
||||||
|
testPositive2:
|
||||||
|
Body:
|
||||||
|
- $agentListener: new(sys:AgentListener)
|
||||||
|
- trace(testOneOf($agentListener, 2))
|
||||||
|
|
||||||
|
testPositive3:
|
||||||
|
Body:
|
||||||
|
- $agentListener: new(sys:AgentListener)
|
||||||
|
- trace(testOneOf($agentListener, true))
|
56
murano/tests/unit/dsl/test_dsl.py
Normal file
56
murano/tests/unit/dsl/test_dsl.py
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||||
|
# not use this file except in compliance with the License. You may obtain
|
||||||
|
# a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
|
# License for the specific language governing permissions and limitations
|
||||||
|
# under the License.
|
||||||
|
|
||||||
|
from yaql.language import exceptions as yaql_exc
|
||||||
|
from yaql.language import specs
|
||||||
|
from yaql.language import yaqltypes
|
||||||
|
|
||||||
|
from murano.dsl import dsl
|
||||||
|
from murano.dsl import dsl_types
|
||||||
|
from murano.dsl import exceptions as dsl_exc
|
||||||
|
from murano.tests.unit.dsl.foundation import object_model as om
|
||||||
|
from murano.tests.unit.dsl.foundation import test_case
|
||||||
|
|
||||||
|
|
||||||
|
@specs.parameter('param1', dsl.OneOf(dsl.MuranoTypeName(),
|
||||||
|
dsl_types.MuranoObject))
|
||||||
|
@specs.parameter('param2', dsl.OneOf(yaqltypes.NumericConstant(),
|
||||||
|
yaqltypes.BooleanConstant(),
|
||||||
|
nullable=True))
|
||||||
|
def test_one_of(param1, param2):
|
||||||
|
return 'Passed'
|
||||||
|
|
||||||
|
|
||||||
|
class TestOneOf(test_case.DslTestCase):
|
||||||
|
def setUp(self):
|
||||||
|
super(TestOneOf, self).setUp()
|
||||||
|
|
||||||
|
self.register_function(test_one_of, 'testOneOf')
|
||||||
|
self.runner = self.new_runner(om.Object('OneOfSmartType'))
|
||||||
|
|
||||||
|
def test_negative(self):
|
||||||
|
self.assertRaises(yaql_exc.NoMatchingFunctionException,
|
||||||
|
self.runner.testNegative1)
|
||||||
|
self.assertRaises(dsl_exc.NoClassFound, self.runner.testNegative2)
|
||||||
|
self.assertRaises(yaql_exc.NoMatchingFunctionException,
|
||||||
|
self.runner.testNegative3)
|
||||||
|
|
||||||
|
def test_nullable(self):
|
||||||
|
self.runner.testNullable()
|
||||||
|
self.assertEqual(['Passed'], self.traces)
|
||||||
|
|
||||||
|
def test_positive(self):
|
||||||
|
self.runner.testPositive1()
|
||||||
|
self.runner.testPositive2()
|
||||||
|
self.runner.testPositive3()
|
||||||
|
|
||||||
|
self.assertEqual(['Passed', 'Passed', 'Passed'], self.traces)
|
Loading…
Reference in New Issue
Block a user