diff --git a/doc/source/murano_pl/built-in_functions.rst b/doc/source/murano_pl/built-in_functions.rst new file mode 100644 index 00000000..5f9d1ab3 --- /dev/null +++ b/doc/source/murano_pl/built-in_functions.rst @@ -0,0 +1,35 @@ +.. + Copyright 2014 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. + + +================== +Built-In functions +================== + +Murano has built-in functions which allows to do basic operations +with Murano PL objects. + +List operations +==================== + +**list.skip(count)** + +This function returns a sliced subset of initial list. It is equal +to Python a[count:] function. + +**list.take(count)** + +Returns first "count" elements of a list. IT is equal to a[:count] +operation in Python. diff --git a/doc/source/murano_pl/index.rst b/doc/source/murano_pl/index.rst new file mode 100644 index 00000000..8d131c70 --- /dev/null +++ b/doc/source/murano_pl/index.rst @@ -0,0 +1,26 @@ +.. + 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. + +.. _murano_pl: + +========================= +Murano PL Guide +========================= + +.. toctree:: + :maxdepth: 2 + + built-in_functions + diff --git a/murano/engine/system/yaql_functions.py b/murano/engine/system/yaql_functions.py index 7cf02bc6..47d10bba 100644 --- a/murano/engine/system/yaql_functions.py +++ b/murano/engine/system/yaql_functions.py @@ -21,6 +21,7 @@ import string import time import types +import itertools import jsonpatch import jsonpointer import yaql.context @@ -206,7 +207,10 @@ def _int(value): def _pselect(collection, composer): - return helpers.parallel_select(collection(), composer) + if isinstance(collection, types.ListType): + return helpers.parallel_select(collection, composer) + else: + return helpers.parallel_select(collection(), composer) def _patch(obj, patch): @@ -296,6 +300,18 @@ def _merge_with(self, other): return helpers.merge_dicts(self, other) +@yaql.context.EvalArg('collection', types.ListType) +@yaql.context.EvalArg('count', int) +def _skip(collection, count): + return itertools.islice(collection, count, None) + + +@yaql.context.EvalArg('collection', types.ListType) +@yaql.context.EvalArg('count', int) +def _take(collection, count): + return itertools.islice(collection, count) + + def register(context): context.register_function( lambda json, mappings: _transform_json(json(), mappings()), 'bind') @@ -329,3 +345,5 @@ def register(context): context.register_function(_values, 'values') context.register_function(_flatten, 'flatten') context.register_function(_merge_with, 'mergeWith') + context.register_function(_skip, 'skip') + context.register_function(_take, 'take') diff --git a/murano/tests/unit/dsl/meta/TestEngineFunctions.yaml b/murano/tests/unit/dsl/meta/TestEngineFunctions.yaml index 130be9fe..4543c2c0 100644 --- a/murano/tests/unit/dsl/meta/TestEngineFunctions.yaml +++ b/murano/tests/unit/dsl/meta/TestEngineFunctions.yaml @@ -213,3 +213,32 @@ Methods: - $doc: {} - Return: $doc.patch($patches) + testTake: + Arguments: + - list: + Contract: [$.int()] + - count: + Contract: $.int() + Body: + - Return: $list.take($count) + + testSkip: + Arguments: + - list: + Contract: [$.int()] + - count: + Contract: $.int() + Body: + - Return: $list.skip($count) + + testSkipTake: + Arguments: + - list: + Contract: [$.int()] + - start: + Contract: $.int() + - count: + Contract: $.int() + Body: + - $l: $list.skip($start) + - Return: $l.take($count) \ No newline at end of file diff --git a/murano/tests/unit/dsl/test_engine_yaql_functions.py b/murano/tests/unit/dsl/test_engine_yaql_functions.py index 54954da4..1be2c15b 100644 --- a/murano/tests/unit/dsl/test_engine_yaql_functions.py +++ b/murano/tests/unit/dsl/test_engine_yaql_functions.py @@ -197,3 +197,22 @@ class TestEngineYaqlFunctions(test_case.DslTestCase): self.assertEqual( {'foo': 'bar', 'baz': [42]}, self._runner.testPatch()) + + def test_skip(self): + self.assertEqual( + [3, 4, 5, 6], + self._runner.testSkip([1, 2, 3, 4, 5, 6], 2) + ) + + def test_take(self): + self.assertEqual( + [1, 2, 3], + self._runner.testTake([1, 2, 3, 4, 5, 6], 3) + ) + + def test_skip_take(self): + self.assertEqual( + [3, 4, 5], + self._runner.testSkipTake([1, 2, 3, 4, 5, 6, 7, 8], + 2, 3) + )