Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix script parser tests #17

Merged
merged 1 commit into from
May 10, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions picard/script/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@
DEFAULT_FILE_NAMING_FORMAT,
DEFAULT_NAMING_PRESET_ID,
)
from picard.extension_points.script_functions import ext_point_script_functions
from picard.extension_points import script_functions
from picard.i18n import (
N_,
gettext as _,
Expand Down Expand Up @@ -72,7 +72,7 @@ class ScriptFunctionDocError(Exception):

def script_function_documentation(name, fmt, functions=None, postprocessor=None):
if functions is None:
functions = dict(ext_point_script_functions)
functions = dict(script_functions.ext_point_script_functions)
if name not in functions:
raise ScriptFunctionDocError("no such function: %s (known functions: %r)" % (name, [name for name in functions]))

Expand All @@ -86,13 +86,13 @@ def script_function_documentation(name, fmt, functions=None, postprocessor=None)

def script_function_names(functions=None):
if functions is None:
functions = dict(ext_point_script_functions)
functions = dict(script_functions.ext_point_script_functions)
yield from sorted(functions)


def script_function_documentation_all(fmt='markdown', pre='',
post='', postprocessor=None):
functions = dict(ext_point_script_functions)
functions = dict(script_functions.ext_point_script_functions)
doc_elements = []
for name in script_function_names(functions):
doc_element = script_function_documentation(name, fmt,
Expand Down
4 changes: 2 additions & 2 deletions picard/script/parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@
from collections.abc import MutableSequence
from queue import LifoQueue

from picard.extension_points.script_functions import ext_point_script_functions
from picard.extension_points import script_functions
from picard.metadata import (
MULTI_VALUED_JOINER,
Metadata,
Expand Down Expand Up @@ -361,7 +361,7 @@ def parse_expression(self, top):
return (tokens, ch)

def load_functions(self):
self.functions = dict(ext_point_script_functions)
self.functions = dict(script_functions.ext_point_script_functions)

def parse(self, script, functions=False):
"""Parse the script."""
Expand Down
213 changes: 105 additions & 108 deletions test/test_script.py
Original file line number Diff line number Diff line change
Expand Up @@ -172,77 +172,77 @@ def test_script_unicode_char_err(self):
with self.assertRaisesRegex(ScriptUnicodeError, areg):
self.parser.eval("\\ufffg")

@patch('picard.extension_points.script_functions.ext_point_script_functions', ExtensionPoint())
def test_script_function_decorator_default(self):
# test default decorator and default prefix
with patch.object(ScriptParser, '_function_registry', ExtensionPoint()):
@script_function()
def func_somefunc(parser):
return "x"
self.assertScriptResultEquals("$somefunc()", "x")
@script_function()
def func_somefunc(parser):
return "x"
self.assertScriptResultEquals("$somefunc()", "x")

@patch('picard.extension_points.script_functions.ext_point_script_functions', ExtensionPoint())
def test_script_function_decorator_no_prefix(self):
# function without prefix
with patch.object(ScriptParser, '_function_registry', ExtensionPoint()):
@script_function()
def somefunc(parser):
return "x"
self.assertScriptResultEquals("$somefunc()", "x")
@script_function()
def somefunc(parser):
return "x"
self.assertScriptResultEquals("$somefunc()", "x")

@patch('picard.extension_points.script_functions.ext_point_script_functions', ExtensionPoint())
def test_script_function_decorator_arg(self):
# function with argument
with patch.object(ScriptParser, '_function_registry', ExtensionPoint()):
@script_function()
def somefunc(parser, arg):
return arg
@script_function()
def somefunc(parser, arg):
return arg

@script_function()
def title(parser, arg):
return arg.upper()
@script_function()
def title(parser, arg):
return arg.upper()

self.assertScriptResultEquals("$somefunc($title(x))", "X")
areg = r"^\d+:\d+:\$somefunc: Wrong number of arguments for \$somefunc: Expected exactly 1"
with self.assertRaisesRegex(ScriptError, areg):
self.parser.eval("$somefunc()")
self.assertScriptResultEquals("$somefunc($title(x))", "X")
areg = r"^\d+:\d+:\$somefunc: Wrong number of arguments for \$somefunc: Expected exactly 1"
with self.assertRaisesRegex(ScriptError, areg):
self.parser.eval("$somefunc()")

@patch('picard.extension_points.script_functions.ext_point_script_functions', ExtensionPoint())
def test_script_function_decorator_argcount(self):
# ignore argument count
with patch.object(ScriptParser, '_function_registry', ExtensionPoint()):
@script_function(check_argcount=False)
def somefunc(parser, *arg):
return str(len(arg))
self.assertScriptResultEquals("$somefunc(a,b,c)", "3")
@script_function(check_argcount=False)
def somefunc(parser, *arg):
return str(len(arg))
self.assertScriptResultEquals("$somefunc(a,b,c)", "3")

@patch('picard.extension_points.script_functions.ext_point_script_functions', ExtensionPoint())
def test_script_function_decorator_altname(self):
# alternative name
with patch.object(ScriptParser, '_function_registry', ExtensionPoint()):
@script_function(name="otherfunc")
def somefunc4(parser):
return "x"
self.assertScriptResultEquals("$otherfunc()", "x")
areg = r"^\d+:\d+:\$somefunc: Unknown function '\$somefunc'"
with self.assertRaisesRegex(ScriptError, areg):
self.parser.eval("$somefunc()")
@script_function(name="otherfunc")
def somefunc4(parser):
return "x"
self.assertScriptResultEquals("$otherfunc()", "x")
areg = r"^\d+:\d+:\$somefunc: Unknown function '\$somefunc'"
with self.assertRaisesRegex(ScriptError, areg):
self.parser.eval("$somefunc()")

@patch('picard.extension_points.script_functions.ext_point_script_functions', ExtensionPoint())
def test_script_function_decorator_altprefix(self):
# alternative prefix
with patch.object(ScriptParser, '_function_registry', ExtensionPoint()):
@script_function(prefix='theprefix_')
def theprefix_somefunc(parser):
return "x"
self.assertScriptResultEquals("$somefunc()", "x")
@script_function(prefix='theprefix_')
def theprefix_somefunc(parser):
return "x"
self.assertScriptResultEquals("$somefunc()", "x")

@patch('picard.extension_points.script_functions.ext_point_script_functions', ExtensionPoint())
def test_script_function_decorator_eval_args(self):
# disable argument evaluation
with patch.object(ScriptParser, '_function_registry', ExtensionPoint()):
@script_function(eval_args=False)
def somefunc(parser, arg):
return arg.eval(parser)
@script_function(eval_args=False)
def somefunc(parser, arg):
return arg.eval(parser)

@script_function()
def title(parser, arg):
return arg.upper()
@script_function()
def title(parser, arg):
return arg.upper()

self.assertScriptResultEquals("$somefunc($title(x))", "X")
self.assertScriptResultEquals("$somefunc($title(x))", "X")

@staticmethod
def assertStartswith(text, expect):
Expand All @@ -254,98 +254,95 @@ def assertEndswith(text, expect):
if not text.endswith(expect):
raise AssertionError("do not end with %r but with %r" % (expect, text[-len(expect):]))

@patch('picard.extension_points.script_functions.ext_point_script_functions', ExtensionPoint())
def test_script_function_documentation_nodoc(self):
"""test script_function_documentation() with a function without documentation"""
with patch.object(ScriptParser, '_function_registry', ExtensionPoint()):

@script_function()
def func_nodocfunc(parser):
return ""
@script_function()
def func_nodocfunc(parser):
return ""

doc = script_function_documentation('nodocfunc', 'markdown')
self.assertEqual(doc, '')
doc = script_function_documentation('nodocfunc', 'html')
self.assertEqual(doc, '')
doc = script_function_documentation('nodocfunc', 'markdown')
self.assertEqual(doc, '')
doc = script_function_documentation('nodocfunc', 'html')
self.assertEqual(doc, '')

@patch('picard.extension_points.script_functions.ext_point_script_functions', ExtensionPoint())
def test_script_function_documentation(self):
"""test script_function_documentation() with a function with documentation"""
with patch.object(ScriptParser, '_function_registry', ExtensionPoint()):
# the documentation used to test includes backquotes
testdoc = '`$somefunc()`'
# the documentation used to test includes backquotes
testdoc = '`$somefunc()`'

@script_function(documentation=testdoc)
def func_somefunc(parser):
return "x"
@script_function(documentation=testdoc)
def func_somefunc(parser):
return "x"

doc = script_function_documentation('somefunc', 'markdown')
self.assertEqual(doc, testdoc)
areg = r"^no such documentation format: unknownformat"
with self.assertRaisesRegex(ScriptFunctionDocError, areg):
script_function_documentation('somefunc', 'unknownformat')
doc = script_function_documentation('somefunc', 'markdown')
self.assertEqual(doc, testdoc)
areg = r"^no such documentation format: unknownformat"
with self.assertRaisesRegex(ScriptFunctionDocError, areg):
script_function_documentation('somefunc', 'unknownformat')

@unittest.skipUnless(markdown, "markdown module missing")
@patch('picard.extension_points.script_functions.ext_point_script_functions', ExtensionPoint())
def test_script_function_documentation_html(self):
"""test script_function_documentation() with a function with documentation"""
with patch.object(ScriptParser, '_function_registry', ExtensionPoint()):
# get html code as generated by markdown
pre, post = markdown('`XXX`').split('XXX')
# get html code as generated by markdown
pre, post = markdown('`XXX`').split('XXX')

# the documentation used to test includes backquotes
testdoc = '`$somefunc()`'
# the documentation used to test includes backquotes
testdoc = '`$somefunc()`'

@script_function(documentation=testdoc)
def func_somefunc(parser):
return "x"
@script_function(documentation=testdoc)
def func_somefunc(parser):
return "x"

doc = script_function_documentation('somefunc', 'html')
self.assertEqual(doc, pre + '$somefunc()' + post)
doc = script_function_documentation('somefunc', 'html')
self.assertEqual(doc, pre + '$somefunc()' + post)

@patch('picard.extension_points.script_functions.ext_point_script_functions', ExtensionPoint())
def test_script_function_documentation_unknown_function(self):
"""test script_function_documentation() with an unknown function"""
with patch.object(ScriptParser, '_function_registry', ExtensionPoint()):
areg = r"^no such function: unknownfunc"
with self.assertRaisesRegex(ScriptFunctionDocError, areg):
script_function_documentation('unknownfunc', 'html')
areg = r"^no such function: unknownfunc"
with self.assertRaisesRegex(ScriptFunctionDocError, areg):
script_function_documentation('unknownfunc', 'html')

@patch('picard.extension_points.script_functions.ext_point_script_functions', ExtensionPoint())
def test_script_function_documentation_all(self):
"""test script_function_documentation_all() with markdown format"""
with patch.object(ScriptParser, '_function_registry', ExtensionPoint()):

@script_function(documentation='somedoc2')
def func_somefunc2(parser):
return "x"
@script_function(documentation='somedoc2')
def func_somefunc2(parser):
return "x"

@script_function(documentation='somedoc1')
def func_somefunc1(parser):
return "x"
@script_function(documentation='somedoc1')
def func_somefunc1(parser):
return "x"

docall = script_function_documentation_all()
self.assertEqual(docall, 'somedoc1\nsomedoc2')
docall = script_function_documentation_all()
self.assertEqual(docall, 'somedoc1\nsomedoc2')

@unittest.skipUnless(markdown, "markdown module missing")
@patch('picard.extension_points.script_functions.ext_point_script_functions', ExtensionPoint())
def test_script_function_documentation_all_html(self):
"""test script_function_documentation_all() with html format"""
with patch.object(ScriptParser, '_function_registry', ExtensionPoint()):
# get html code as generated by markdown
pre, post = markdown('XXX').split('XXX')

# get html code as generated by markdown
pre, post = markdown('XXX').split('XXX')
@script_function(documentation='somedoc')
def func_somefunc(parser):
return "x"

@script_function(documentation='somedoc')
def func_somefunc(parser):
return "x"
def postprocessor(data, function):
return 'w' + data + function.name + 'y'

def postprocessor(data, function):
return 'w' + data + function.name + 'y'

docall = script_function_documentation_all(
fmt='html',
pre='<div id="test">',
post="</div>\n",
postprocessor=postprocessor,
)
docall = script_function_documentation_all(
fmt='html',
pre='<div id="test">',
post="</div>\n",
postprocessor=postprocessor,
)

self.assertStartswith(docall, '<div id="test">w' + pre)
self.assertEndswith(docall, post + 'somefuncy</div>\n')
self.assertStartswith(docall, '<div id="test">w' + pre)
self.assertEndswith(docall, post + 'somefuncy</div>\n')

def test_unknown_function(self):
areg = r"^\d+:\d+:\$unknownfunction: Unknown function '\$unknownfunction'"
Expand Down
Loading