mirror of
https://github.com/beetbox/beets.git
synced 2025-12-08 01:23:09 +01:00
fix empty function arguments
Previously, an empty argument was treated as "not an argument at all". Now,
every function call always has at least one argument -- i.e., %foo{} is a
function call whose only argument is "" -- and %foo{,bar} is valid syntax.
This commit is contained in:
parent
f1ebc82a55
commit
46a3bde5b5
3 changed files with 11 additions and 10 deletions
|
|
@ -298,13 +298,9 @@ class Parser(object):
|
||||||
# Try to parse a subexpression in a subparser.
|
# Try to parse a subexpression in a subparser.
|
||||||
expressions = []
|
expressions = []
|
||||||
|
|
||||||
while self.pos < len(self.string) and \
|
while self.pos < len(self.string):
|
||||||
self.string[self.pos] != GROUP_CLOSE:
|
|
||||||
subparser = Parser(self.string[self.pos:])
|
subparser = Parser(self.string[self.pos:])
|
||||||
subparser.parse_expression()
|
subparser.parse_expression()
|
||||||
if subparser.pos == 0:
|
|
||||||
# No expression could be parsed.
|
|
||||||
break
|
|
||||||
|
|
||||||
# Extract and advance past the parsed expression.
|
# Extract and advance past the parsed expression.
|
||||||
expressions.append(Expression(subparser.parts))
|
expressions.append(Expression(subparser.parts))
|
||||||
|
|
@ -316,6 +312,7 @@ class Parser(object):
|
||||||
break
|
break
|
||||||
|
|
||||||
# Only other way to terminate an expression is with ,.
|
# Only other way to terminate an expression is with ,.
|
||||||
|
# Continue to the next argument.
|
||||||
assert self.string[self.pos] == ARG_SEP
|
assert self.string[self.pos] == ARG_SEP
|
||||||
self.pos += 1
|
self.pos += 1
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -398,8 +398,8 @@ class DestinationFunctionTest(unittest.TestCase):
|
||||||
self._assert_dest('/base/tle')
|
self._assert_dest('/base/tle')
|
||||||
|
|
||||||
def test_if_false(self):
|
def test_if_false(self):
|
||||||
self._setf(u'%if{,foo}')
|
self._setf(u'x%if{,foo}')
|
||||||
self._assert_dest('/base/')
|
self._assert_dest('/base/x')
|
||||||
|
|
||||||
def test_if_true(self):
|
def test_if_true(self):
|
||||||
self._setf(u'%if{bar,foo}')
|
self._setf(u'%if{bar,foo}')
|
||||||
|
|
|
||||||
|
|
@ -147,10 +147,11 @@ class ParseTest(unittest.TestCase):
|
||||||
self.assertEqual(list(_normparse(u'foo %bar{bar,bar baz')),
|
self.assertEqual(list(_normparse(u'foo %bar{bar,bar baz')),
|
||||||
[u'foo %bar{bar,bar baz'])
|
[u'foo %bar{bar,bar baz'])
|
||||||
|
|
||||||
def test_call_no_args(self):
|
def test_call_empty_arg(self):
|
||||||
parts = list(_normparse(u'%foo{}'))
|
parts = list(_normparse(u'%foo{}'))
|
||||||
self.assertEqual(len(parts), 1)
|
self.assertEqual(len(parts), 1)
|
||||||
self._assert_call(parts[0], u"foo", 0)
|
self._assert_call(parts[0], u"foo", 1)
|
||||||
|
self.assertEqual(list(_normexpr(parts[0].args[0])), [])
|
||||||
|
|
||||||
def test_call_single_arg(self):
|
def test_call_single_arg(self):
|
||||||
parts = list(_normparse(u'%foo{bar}'))
|
parts = list(_normparse(u'%foo{bar}'))
|
||||||
|
|
@ -192,7 +193,7 @@ class ParseTest(unittest.TestCase):
|
||||||
self._assert_call(parts[0], u"foo", 2)
|
self._assert_call(parts[0], u"foo", 2)
|
||||||
arg_parts = list(_normexpr(parts[0].args[0]))
|
arg_parts = list(_normexpr(parts[0].args[0]))
|
||||||
self.assertEqual(len(arg_parts), 1)
|
self.assertEqual(len(arg_parts), 1)
|
||||||
self._assert_call(arg_parts[0], u"bar", 0)
|
self._assert_call(arg_parts[0], u"bar", 1)
|
||||||
self.assertEqual(list(_normexpr(parts[0].args[1])), [u"baz"])
|
self.assertEqual(list(_normexpr(parts[0].args[1])), [u"baz"])
|
||||||
|
|
||||||
def test_nested_call_with_argument(self):
|
def test_nested_call_with_argument(self):
|
||||||
|
|
@ -253,6 +254,9 @@ class EvalTest(unittest.TestCase):
|
||||||
def test_not_subtitute_func_with_no_args(self):
|
def test_not_subtitute_func_with_no_args(self):
|
||||||
self.assertEqual(self._eval(u"%lower"), u"%lower")
|
self.assertEqual(self._eval(u"%lower"), u"%lower")
|
||||||
|
|
||||||
|
def test_function_call_with_empty_arg(self):
|
||||||
|
self.assertEqual(self._eval(u"%len{}"), u"0")
|
||||||
|
|
||||||
def suite():
|
def suite():
|
||||||
return unittest.TestLoader().loadTestsFromName(__name__)
|
return unittest.TestLoader().loadTestsFromName(__name__)
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue