def function_call(self, items) -> lark.Token: """Look up the function call, and call it with the given argument values. :param list[lark.Token] items: A function name token and zero or more argument tokens. """ func_name = items[0].value args = [tok.value for tok in items[1:]] try: func = functions.get_plugin(func_name) except pavilion.expression_functions.common.FunctionPluginError: raise ParserValueError( token=items[0], message="No such function '{}'".format(func_name)) try: result = func(*args) except pavilion.expression_functions.common.FunctionArgError as err: raise ParserValueError(self._merge_tokens(items, None), "Invalid arguments: {}".format(err)) except pavilion.expression_functions.common.FunctionPluginError as err: # The function plugins give a reasonable message. raise ParserValueError(self._merge_tokens(items, None), err.args[0]) return self._merge_tokens(items, result)
def test_function_plugins(self): """Make sure each of the core function plugins work.""" plugins.initialize_plugins(self.pav_cfg) tests = { 'int': ('0x123', 16), 'floor': (1.2,), 'ceil': (1.3,), 'round': (1.4,), 'sum': ([1, 2, 3, 2.4],), 'avg': ([1, 2, 3, 2.4],), 'len': ([1, 2, 3, 2.4],), 'random': tuple(), } for func_name, args in tests.items(): func = expression_functions.get_plugin(func_name) # Make sure this doesn't throw errors func(*args) # Make sure we have a test for all core plugins. for plugin in plugins.list_plugins()['function']: if plugin.priority == expression_functions.FunctionPlugin.PRIO_CORE: self.assertIn(plugin.name, tests) plugins._reset_plugins()
def test_core_functions(self): """Check core expression functions.""" # Every core function must have at lest one test. # Each test is a list of (args, answer). An answer of None isn't # checked. tests = { 'int': [(("1234", 8), 668)], 'round': [((1.234, ), 1)], 'floor': [((1.234, ), 1)], 'ceil': [((1.234, ), 2)], 'sum': [(([1, 2, 3, 4.5], ), 10.5), (([1, 2, 3, 4], ), 10)], 'avg': [(([1, 2, 3, 4.5], ), 2.625), (([1, 2, 3, 4, 5], ), 3.0)], 'len': [(([1, 2, "foo"], ), 3)], 'random': [(tuple(), None)], 'keys': [(({ 'a': 1, 'b': 2 }, ), ['a', 'b']), (({ 'b': 1, 'a': 2 }, ), ['a', 'b'])], 'all': [(([True, 1, 2], ), True), (([True, 0, 3], ), False)], 'any': [(([False, 1, 0], ), True), (([False, 0], ), False)], 're_search': [((r'hello (\w+)', 'hello world'), 'world'), ((r'\d+', 'apples, 14, bananas'), '14')], 'replace': [(('I am a banana! ', ' ', '_'), 'I_am_a_banana!_')], 'outliers': [(([1, 2, 3, 4, 5, 6, 7, 99, 108], ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i'], 1.5), { 'h': 1.7581382586345833, 'i': 1.9752254521550119 })] } exp_funcs = expression_functions.list_plugins() for func_name in exp_funcs: func = expression_functions.get_plugin(func_name) # Only check core functions if not func.core: continue self.assertIn(func_name, tests, msg='You must provide tests for all core expression ' 'functions.') if func_name not in tests or len(tests[func_name]) == 0: self.fail( msg='You must provide at least one test for each ' 'core expression function. Missing {}'.format(func_name)) for args, answer in tests[func_name]: result = func(*args) if answer is None: continue self.assertEqual(result, answer) self.assertEqual(type(result), type(answer))
def _functions_cmd(self, _, args): """List all of the known function plugins.""" if args.detail: func = expression_functions.get_plugin(args.detail) output.fprint(func.signature, color=output.CYAN, file=self.outfile) output.fprint('-' * len(func.signature), file=self.outfile) output.fprint(func.long_description, file=self.outfile) else: rows = [] for func_name in sorted(expression_functions.list_plugins()): func = expression_functions.get_plugin(func_name) rows.append({ 'name': func.name, 'signature': func.signature, 'description': func.description }) output.draw_table(self.outfile, fields=['name', 'signature', 'description'], rows=rows, title="Available Expression Functions")