Adding length() YAQL function
* Switched YAQL to version 0.2.3 * Refactored expressions to use custome YAQL contexts with additional functions * Added unit tests Change-Id: I12f4d56308a011a3a588028df20becb519e2e684
This commit is contained in:
parent
143702e0f0
commit
f779dbaf29
@ -21,6 +21,7 @@ import six
|
|||||||
import yaql
|
import yaql
|
||||||
|
|
||||||
from mistral.openstack.common import log as logging
|
from mistral.openstack.common import log as logging
|
||||||
|
from mistral import yaql_utils
|
||||||
|
|
||||||
LOG = logging.getLogger(__name__)
|
LOG = logging.getLogger(__name__)
|
||||||
|
|
||||||
@ -56,11 +57,14 @@ class Evaluator(object):
|
|||||||
|
|
||||||
class YAQLEvaluator(Evaluator):
|
class YAQLEvaluator(Evaluator):
|
||||||
@classmethod
|
@classmethod
|
||||||
def evaluate(cls, expression, context):
|
def evaluate(cls, expression, data_context):
|
||||||
LOG.debug("Evaluating YAQL expression [expression='%s', context=%s]"
|
LOG.debug("Evaluating YAQL expression [expression='%s', context=%s]"
|
||||||
% (expression, context))
|
% (expression, data_context))
|
||||||
|
|
||||||
return yaql.parse(expression).evaluate(context)
|
return yaql.parse(expression).evaluate(
|
||||||
|
data=data_context,
|
||||||
|
context=yaql_utils.create_yaql_context()
|
||||||
|
)
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def is_expression(cls, s):
|
def is_expression(cls, s):
|
||||||
@ -74,10 +78,10 @@ class InlineYAQLEvaluator(YAQLEvaluator):
|
|||||||
find_expression_pattern = re.compile("\{\$\.*[^\}]*\}")
|
find_expression_pattern = re.compile("\{\$\.*[^\}]*\}")
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def evaluate(cls, expression, context):
|
def evaluate(cls, expression, data_context):
|
||||||
if super(InlineYAQLEvaluator, cls).is_expression(expression):
|
if super(InlineYAQLEvaluator, cls).is_expression(expression):
|
||||||
return super(InlineYAQLEvaluator,
|
return super(InlineYAQLEvaluator,
|
||||||
cls).evaluate(expression, context)
|
cls).evaluate(expression, data_context)
|
||||||
|
|
||||||
result = expression
|
result = expression
|
||||||
found_expressions = cls.find_inline_expressions(expression)
|
found_expressions = cls.find_inline_expressions(expression)
|
||||||
@ -86,7 +90,7 @@ class InlineYAQLEvaluator(YAQLEvaluator):
|
|||||||
for expr in found_expressions:
|
for expr in found_expressions:
|
||||||
trim_expr = expr.strip("{}")
|
trim_expr = expr.strip("{}")
|
||||||
evaluated = super(InlineYAQLEvaluator,
|
evaluated = super(InlineYAQLEvaluator,
|
||||||
cls).evaluate(trim_expr, context)
|
cls).evaluate(trim_expr, data_context)
|
||||||
|
|
||||||
replacement = str(evaluated) if evaluated else expr
|
replacement = str(evaluated) if evaluated else expr
|
||||||
result = result.replace(expr, replacement)
|
result = result.replace(expr, replacement)
|
||||||
|
@ -138,3 +138,11 @@ class YaqlEvaluatorTest(base.BaseTest):
|
|||||||
},
|
},
|
||||||
applied
|
applied
|
||||||
)
|
)
|
||||||
|
|
||||||
|
def test_function_length(self):
|
||||||
|
self.assertEqual(3, expr.evaluate('$.length()', [1, 2, 3]))
|
||||||
|
self.assertEqual(2, expr.evaluate('$.length()', ['one', 'two']))
|
||||||
|
self.assertEqual(4, expr.evaluate(
|
||||||
|
'$.array.length()',
|
||||||
|
{'array': ['1', '2', '3', '4']})
|
||||||
|
)
|
||||||
|
37
mistral/yaql_utils.py
Normal file
37
mistral/yaql_utils.py
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
#
|
||||||
|
# Copyright 2014 - Mirantis, Inc.
|
||||||
|
#
|
||||||
|
# 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.
|
||||||
|
|
||||||
|
import yaql
|
||||||
|
|
||||||
|
|
||||||
|
def create_yaql_context():
|
||||||
|
|
||||||
|
ctx = yaql.create_context()
|
||||||
|
|
||||||
|
_register_functions(ctx)
|
||||||
|
|
||||||
|
return ctx
|
||||||
|
|
||||||
|
|
||||||
|
def _register_functions(yaql_ctx):
|
||||||
|
yaql_ctx.register_function(length, 'length')
|
||||||
|
yaql_ctx.register_function(length, 'size')
|
||||||
|
|
||||||
|
|
||||||
|
# Additional convenience YAQL functions.
|
||||||
|
|
||||||
|
def length(a):
|
||||||
|
return len(a())
|
@ -24,7 +24,7 @@ networkx>=1.8
|
|||||||
six>=1.7.0
|
six>=1.7.0
|
||||||
SQLAlchemy>=0.8.4,<=0.8.99,>=0.9.7,<=0.9.99
|
SQLAlchemy>=0.8.4,<=0.8.99,>=0.9.7,<=0.9.99
|
||||||
stevedore>=1.0.0 # Apache-2.0
|
stevedore>=1.0.0 # Apache-2.0
|
||||||
yaql==0.2.1 # This is not in global requirements
|
yaql==0.2.3 # This is not in global requirements
|
||||||
jsonschema>=2.0.0,<3.0.0
|
jsonschema>=2.0.0,<3.0.0
|
||||||
mock>=1.0
|
mock>=1.0
|
||||||
keystonemiddleware>=1.0.0
|
keystonemiddleware>=1.0.0
|
||||||
|
Loading…
Reference in New Issue
Block a user