From 0b4b14ce9c5b98c08620c391e841da402134dc69 Mon Sep 17 00:00:00 2001 From: Sophist Date: Thu, 27 Apr 2017 20:02:37 +0100 Subject: [PATCH 01/13] Fix $inmulti as per #623 --- picard/script.py | 30 ++++++++++++++++++++++++++---- test/test_script.py | 33 +++++++++++++++++++++++++++++++++ 2 files changed, 59 insertions(+), 4 deletions(-) diff --git a/picard/script.py b/picard/script.py index e00beb4b0..10399fbed 100644 --- a/picard/script.py +++ b/picard/script.py @@ -388,9 +388,31 @@ def func_in(parser, text, needle): return "" -def func_inmulti(parser, text, value, separator=MULTI_VALUED_JOINER): - """Splits ``text`` by ``separator``, and returns true if the resulting list contains ``value``.""" - return func_in(parser, text.split(separator) if separator else [text], value) +def func_inmulti(parser, haystack, needle, separator=MULTI_VALUED_JOINER): + """Searches for ``needle`` in ``haystack``, supporting a list variable for + ``haystack``. If a string is used instead, then a ``separator`` can be + used to split it. In both cases, it returns true if the resulting list + contains ``needle``.""" + + needle = needle.eval(parser) + if (isinstance(haystack, ScriptExpression) and + len(haystack) == 1 and + isinstance(haystack[0], ScriptVariable)): + haystack = haystack[0] + + if isinstance(haystack, ScriptVariable): + if haystack.name.startswith(u"_"): + name = u"~" + haystack.name[1:] + else: + name = haystack.name + values = parser.context.getall(name) + + return func_in(parser, values, needle) + + haystack = haystack.eval(parser) + return func_in(parser, + haystack.split(separator) if separator else [haystack], + needle) def func_rreplace(parser, text, old, new): @@ -820,7 +842,7 @@ register_script_function(func_lte, "lte") register_script_function(func_gt, "gt") register_script_function(func_gte, "gte") register_script_function(func_in, "in") -register_script_function(func_inmulti, "inmulti") +register_script_function(func_inmulti, "inmulti", eval_args=False) register_script_function(func_copy, "copy") register_script_function(func_copymerge, "copymerge") register_script_function(func_len, "len") diff --git a/test/test_script.py b/test/test_script.py index 1ff305e9e..d0793280a 100644 --- a/test/test_script.py +++ b/test/test_script.py @@ -11,9 +11,12 @@ class ScriptParserTest(unittest.TestCase): config.setting = { 'enabled_plugins': '', } + self.parser = ScriptParser() + def func_noargstest(parser): return "" + register_script_function(func_noargstest, "noargstest") def assertScriptResultEquals(self, script, expected, context=None): @@ -384,3 +387,33 @@ class ScriptParserTest(unittest.TestCase): self.parser.eval("$unset(performer:*)", context) self.assertNotIn('performer:bar', context) self.assertNotIn('performer:foo', context) + + def test_cmd_inmulti(self): + context = Metadata() + context["foo"] = "First; Second; Third" + self.assertEqual( + self.parser.eval("$in(%foo%,Second)", context), "1") + self.assertEqual( + self.parser.eval("$in(%foo%,irst; Second; Thi)", context), "1") + self.assertEqual( + self.parser.eval("$in(%foo%,First; Second; Third)", context), "1") + self.assertEqual( + self.parser.eval("$inmulti(%foo%,Second)", context), "") + self.assertEqual( + self.parser.eval("$inmulti(%foo%,irst; Second; Thi)", context), "") + self.assertEqual( + self.parser.eval("$inmulti(%foo%,First; Second; Third)", context), "1") + + context["foo"] = ["First", "Second", "Third"] + self.assertEqual( + self.parser.eval("$in(%foo%,Second)", context), "1") + self.assertEqual( + self.parser.eval("$in(%foo%,irst; Second; Thi)", context), "1") + self.assertEqual( + self.parser.eval("$in(%foo%,First; Second; Third)", context), "1") + self.assertEqual( + self.parser.eval("$inmulti(%foo%,Second)", context), "1") + self.assertEqual( + self.parser.eval("$inmulti(%foo%,irst; Second; Thi)", context), "") + self.assertEqual( + self.parser.eval("$inmulti(%foo%,First; Second; Third)", context), "") From f2e855771c8f05907aaaf493a051534c617aed3b Mon Sep 17 00:00:00 2001 From: Sophist Date: Sat, 29 Apr 2017 12:59:15 +0100 Subject: [PATCH 02/13] Clarify docstring --- picard/script.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/picard/script.py b/picard/script.py index 10399fbed..78c5dd9b6 100644 --- a/picard/script.py +++ b/picard/script.py @@ -392,7 +392,7 @@ def func_inmulti(parser, haystack, needle, separator=MULTI_VALUED_JOINER): """Searches for ``needle`` in ``haystack``, supporting a list variable for ``haystack``. If a string is used instead, then a ``separator`` can be used to split it. In both cases, it returns true if the resulting list - contains ``needle``.""" + contains exactly ``needle`` as a member.""" needle = needle.eval(parser) if (isinstance(haystack, ScriptExpression) and From 60983a2a228ac0bdc5e2ac25a0df2f0dd41f05fa Mon Sep 17 00:00:00 2001 From: Sophist Date: Sat, 29 Apr 2017 13:27:15 +0100 Subject: [PATCH 03/13] Fix copymerge 1. Newsvals deduped 2. Oldvals in original sequence --- picard/script.py | 9 ++++++++- test/test_script.py | 7 ++++--- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/picard/script.py b/picard/script.py index 78c5dd9b6..dd994642d 100644 --- a/picard/script.py +++ b/picard/script.py @@ -501,7 +501,14 @@ def func_copymerge(parser, new, old): old = "~" + old[1:] newvals = parser.context.getall(new) oldvals = parser.context.getall(old) - parser.context[new] = newvals + list(set(oldvals) - set(newvals)) + result = [] + for x in newvals: + if x not in result: + result.append(x) + for x in oldvals: + if x not in result: + result.append(x) + parser.context[new] = result return "" diff --git a/test/test_script.py b/test/test_script.py index d0793280a..9cc806906 100644 --- a/test/test_script.py +++ b/test/test_script.py @@ -274,7 +274,8 @@ class ScriptParserTest(unittest.TestCase): def _eval_and_check_copymerge(self, context, expected): self.parser.eval("$copymerge(target,source)", context) - self.assertEqual(sorted(self.parser.context.getall("target")), sorted(expected)) + #self.assertEqual(sorted(self.parser.context.getall("target")), sorted(expected)) + self.assertEqual(self.parser.context.getall("target"), expected) def test_cmd_copymerge_notarget(self): context = Metadata() @@ -290,8 +291,8 @@ class ScriptParserTest(unittest.TestCase): def test_cmd_copymerge_removedupes(self): context = Metadata() - context["target"] = ["tag1", "tag2"] - context["source"] = ["tag2", "tag3"] + context["target"] = ["tag1", "tag2", "tag1"] + context["source"] = ["tag2", "tag3", "tag2"] self._eval_and_check_copymerge(context, ["tag1", "tag2", "tag3"]) def test_cmd_copymerge_nonlist(self): From 602dfbb36eb28df29fac301174cdc97f51a5aaba Mon Sep 17 00:00:00 2001 From: Sophist Date: Sat, 29 Apr 2017 13:51:18 +0100 Subject: [PATCH 04/13] Add $lenmulti function --- picard/script.py | 18 ++++++++++++++++++ test/test_script.py | 15 +++++++++++++++ 2 files changed, 33 insertions(+) diff --git a/picard/script.py b/picard/script.py index dd994642d..0b43e3f41 100644 --- a/picard/script.py +++ b/picard/script.py @@ -666,6 +666,23 @@ def func_len(parser, text=""): return string_(len(text)) +def func_lenmulti(parser, multi, separator=MULTI_VALUED_JOINER): + if (isinstance(multi, ScriptExpression) and + len(multi) == 1 and + isinstance(multi[0], ScriptVariable)): + multi = multi[0] + + if isinstance(multi, ScriptVariable): + if multi.name.startswith(u"_"): + name = u"~" + multi.name[1:] + else: + name = multi.name + return func_len(parser, parser.context.getall(name)) + + multi = multi.eval(parser) + return func_len(parser, multi.split(separator) if separator else [multi]) + + def func_performer(parser, pattern="", join=", "): values = [] for name, value in parser.context.items(): @@ -853,6 +870,7 @@ register_script_function(func_inmulti, "inmulti", eval_args=False) register_script_function(func_copy, "copy") register_script_function(func_copymerge, "copymerge") register_script_function(func_len, "len") +register_script_function(func_lenmulti, "lenmulti", eval_args=False) register_script_function(func_performer, "performer") register_script_function(func_matchedtracks, "matchedtracks") register_script_function(func_is_complete, "is_complete") diff --git a/test/test_script.py b/test/test_script.py index 9cc806906..d5761b92c 100644 --- a/test/test_script.py +++ b/test/test_script.py @@ -418,3 +418,18 @@ class ScriptParserTest(unittest.TestCase): self.parser.eval("$inmulti(%foo%,irst; Second; Thi)", context), "") self.assertEqual( self.parser.eval("$inmulti(%foo%,First; Second; Third)", context), "") + + def test_cmd_lenmulti(self): + context = Metadata() + context["foo"] = "First; Second; Third" + context["bar"] = ["First", "Second", "Third"] + self.assertEqual( + self.parser.eval("$len(%foo%)", context), "20") + self.assertEqual( + self.parser.eval("$len(%bar%)", context), "20") + self.assertEqual( + self.parser.eval("$lenmulti(%foo%)", context), "1") + self.assertEqual( + self.parser.eval("$lenmulti(%bar%)", context), "3") + self.assertEqual( + self.parser.eval("$lenmulti(%foo%.)", context), "3") From 23087cf8c3d12c93a94c2f788296533c9fa1023d Mon Sep 17 00:00:00 2001 From: Sophist Date: Sat, 29 Apr 2017 13:52:21 +0100 Subject: [PATCH 05/13] Python3 strings are all unicode --- picard/script.py | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/picard/script.py b/picard/script.py index 0b43e3f41..e4eaa5e45 100644 --- a/picard/script.py +++ b/picard/script.py @@ -66,9 +66,9 @@ class ScriptVariable(object): def eval(self, state): name = self.name - if name.startswith(u"_"): - name = u"~" + name[1:] - return state.context.get(name, u"") + if name.startswith("_"): + name = "~" + name[1:] + return state.context.get(name, "") FunctionRegistryItem = namedtuple("FunctionRegistryItem", @@ -401,8 +401,8 @@ def func_inmulti(parser, haystack, needle, separator=MULTI_VALUED_JOINER): haystack = haystack[0] if isinstance(haystack, ScriptVariable): - if haystack.name.startswith(u"_"): - name = u"~" + haystack.name[1:] + if haystack.name.startswith("_"): + name = "~" + haystack.name[1:] else: name = haystack.name values = parser.context.getall(name) @@ -426,7 +426,7 @@ def func_rsearch(parser, text, pattern): return match.group(1) except IndexError: return match.group(0) - return u"" + return "" def func_num(parser, text, length): @@ -479,7 +479,7 @@ def func_get(parser, name): """Returns the variable ``name`` (equivalent to ``%name%``).""" if name.startswith("_"): name = "~" + name[1:] - return parser.context.get(name, u"") + return parser.context.get(name, "") def func_copy(parser, new, old): @@ -673,8 +673,8 @@ def func_lenmulti(parser, multi, separator=MULTI_VALUED_JOINER): multi = multi[0] if isinstance(multi, ScriptVariable): - if multi.name.startswith(u"_"): - name = u"~" + multi.name[1:] + if multi.name.startswith("_"): + name = "~" + multi.name[1:] else: name = multi.name return func_len(parser, parser.context.getall(name)) From a763a6ce3105d4f339b6ece93783379efd5f3512 Mon Sep 17 00:00:00 2001 From: Sophist Date: Sat, 29 Apr 2017 21:26:49 +0100 Subject: [PATCH 06/13] Use existing behaviour if user overrides separator --- picard/script.py | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/picard/script.py b/picard/script.py index e4eaa5e45..ba77fd571 100644 --- a/picard/script.py +++ b/picard/script.py @@ -395,19 +395,20 @@ def func_inmulti(parser, haystack, needle, separator=MULTI_VALUED_JOINER): contains exactly ``needle`` as a member.""" needle = needle.eval(parser) - if (isinstance(haystack, ScriptExpression) and - len(haystack) == 1 and - isinstance(haystack[0], ScriptVariable)): - haystack = haystack[0] - if isinstance(haystack, ScriptVariable): - if haystack.name.startswith("_"): - name = "~" + haystack.name[1:] - else: - name = haystack.name - values = parser.context.getall(name) + if separator == MULTI_VALUED_JOINER: + if (isinstance(haystack, ScriptExpression) and + len(haystack) == 1 and + isinstance(haystack[0], ScriptVariable)): + haystack = haystack[0] - return func_in(parser, values, needle) + if isinstance(haystack, ScriptVariable): + if haystack.name.startswith("_"): + name = "~" + haystack.name[1:] + else: + name = haystack.name + values = parser.context.getall(name) + return func_in(parser, values, needle) haystack = haystack.eval(parser) return func_in(parser, From 325c7b403b0ad5d4c7f4ee7a453671416cf3c9d4 Mon Sep 17 00:00:00 2001 From: Sophist Date: Sun, 30 Apr 2017 12:55:14 +0100 Subject: [PATCH 07/13] Move multi-value code into worker function --- picard/script.py | 57 ++++++++++++++++++++---------------------------- 1 file changed, 24 insertions(+), 33 deletions(-) diff --git a/picard/script.py b/picard/script.py index ba77fd571..d9c61539d 100644 --- a/picard/script.py +++ b/picard/script.py @@ -317,6 +317,28 @@ def _compute_logic(operation, *args): return operation(args) +def _get_multi_values(parser, multi, separator): + if separator == MULTI_VALUED_JOINER: + # Convert ScriptExpression containing only a single variable into variable + if (isinstance(multi, ScriptExpression) and + len(multi) == 1 and + isinstance(multi[0], ScriptVariable)): + multi = multi[0] + + # If a variable, return multi-values + if isinstance(multi, ScriptVariable): + if multi.name.startswith("_"): + name = "~" + multi.name[1:] + else: + name = multi.name + return parser.context.getall(name) + + # Fall-back to converting to a string and splitting if haystack is an expression + # or user has overridden the separator character. + multi = multi.eval(parser) + return multi.split(separator) if separator else [multi] + + def func_if(parser, _if, _then, _else=None): """If ``if`` is not empty, it returns ``then``, otherwise it returns ``else``.""" if _if.eval(parser): @@ -395,25 +417,7 @@ def func_inmulti(parser, haystack, needle, separator=MULTI_VALUED_JOINER): contains exactly ``needle`` as a member.""" needle = needle.eval(parser) - - if separator == MULTI_VALUED_JOINER: - if (isinstance(haystack, ScriptExpression) and - len(haystack) == 1 and - isinstance(haystack[0], ScriptVariable)): - haystack = haystack[0] - - if isinstance(haystack, ScriptVariable): - if haystack.name.startswith("_"): - name = "~" + haystack.name[1:] - else: - name = haystack.name - values = parser.context.getall(name) - return func_in(parser, values, needle) - - haystack = haystack.eval(parser) - return func_in(parser, - haystack.split(separator) if separator else [haystack], - needle) + return func_in(parser, _get_multi_values(parser, haystack, separator), needle) def func_rreplace(parser, text, old, new): @@ -668,20 +672,7 @@ def func_len(parser, text=""): def func_lenmulti(parser, multi, separator=MULTI_VALUED_JOINER): - if (isinstance(multi, ScriptExpression) and - len(multi) == 1 and - isinstance(multi[0], ScriptVariable)): - multi = multi[0] - - if isinstance(multi, ScriptVariable): - if multi.name.startswith("_"): - name = "~" + multi.name[1:] - else: - name = multi.name - return func_len(parser, parser.context.getall(name)) - - multi = multi.eval(parser) - return func_len(parser, multi.split(separator) if separator else [multi]) + return func_len(parser, _get_multi_values(parser, multi, separator)) def func_performer(parser, pattern="", join=", "): From 764dacd6a2e28ab2dfa478d35754f4258fea641e Mon Sep 17 00:00:00 2001 From: Sophist Date: Sun, 30 Apr 2017 12:59:09 +0100 Subject: [PATCH 08/13] Simplify copymerge --- picard/script.py | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/picard/script.py b/picard/script.py index d9c61539d..0c671c728 100644 --- a/picard/script.py +++ b/picard/script.py @@ -28,6 +28,7 @@ from inspect import getargspec from picard.metadata import Metadata from picard.metadata import MULTI_VALUED_JOINER from picard.plugin import ExtensionPoint +from picard.util import uniqify class ScriptError(Exception): @@ -506,14 +507,7 @@ def func_copymerge(parser, new, old): old = "~" + old[1:] newvals = parser.context.getall(new) oldvals = parser.context.getall(old) - result = [] - for x in newvals: - if x not in result: - result.append(x) - for x in oldvals: - if x not in result: - result.append(x) - parser.context[new] = result + parser.context[new] = uniqify(newvals + oldvals) return "" From 64e3c891806dc773cc493f761c9b0fb06b881483 Mon Sep 17 00:00:00 2001 From: Sophist Date: Mon, 1 May 2017 13:28:56 +0100 Subject: [PATCH 09/13] Fix bug with default separator overridden. --- picard/script.py | 3 +++ test/test_script.py | 57 +++++++++++++++++++++++++++++++++------------ 2 files changed, 45 insertions(+), 15 deletions(-) diff --git a/picard/script.py b/picard/script.py index 0c671c728..3d2643c78 100644 --- a/picard/script.py +++ b/picard/script.py @@ -319,6 +319,9 @@ def _compute_logic(operation, *args): def _get_multi_values(parser, multi, separator): + if isinstance(separator, ScriptExpression): + separator = separator.eval(parser) + if separator == MULTI_VALUED_JOINER: # Convert ScriptExpression containing only a single variable into variable if (isinstance(multi, ScriptExpression) and diff --git a/test/test_script.py b/test/test_script.py index d5761b92c..b7b985564 100644 --- a/test/test_script.py +++ b/test/test_script.py @@ -274,7 +274,6 @@ class ScriptParserTest(unittest.TestCase): def _eval_and_check_copymerge(self, context, expected): self.parser.eval("$copymerge(target,source)", context) - #self.assertEqual(sorted(self.parser.context.getall("target")), sorted(expected)) self.assertEqual(self.parser.context.getall("target"), expected) def test_cmd_copymerge_notarget(self): @@ -391,33 +390,61 @@ class ScriptParserTest(unittest.TestCase): def test_cmd_inmulti(self): context = Metadata() - context["foo"] = "First; Second; Third" + context["foo"] = "First:A; Second:B; Third:C" self.assertEqual( - self.parser.eval("$in(%foo%,Second)", context), "1") + self.parser.eval("$in(%foo%,Second:B)", context), "1") self.assertEqual( - self.parser.eval("$in(%foo%,irst; Second; Thi)", context), "1") + self.parser.eval("$in(%foo%,irst:A; Second:B; Thi)", context), "1") self.assertEqual( - self.parser.eval("$in(%foo%,First; Second; Third)", context), "1") + self.parser.eval("$in(%foo%,First:A; Second:B; Third:C)", context), "1") self.assertEqual( - self.parser.eval("$inmulti(%foo%,Second)", context), "") + self.parser.eval("$inmulti(%foo%,Second:B)", context), "") self.assertEqual( - self.parser.eval("$inmulti(%foo%,irst; Second; Thi)", context), "") + self.parser.eval("$inmulti(%foo%,irst:A; Second:B; Thi)", context), "") self.assertEqual( - self.parser.eval("$inmulti(%foo%,First; Second; Third)", context), "1") + self.parser.eval("$inmulti(%foo%,First:A; Second:B; Third:C)", context), "1") + self.assertEqual( + self.parser.eval("$inmulti(%foo%,First:A,:)", context), "") + self.assertEqual( + self.parser.eval("$inmulti(%foo%,Second:B,:)", context), "") + self.assertEqual( + self.parser.eval("$inmulti(%foo%,Third:C,:)", context), "") + self.assertEqual( + self.parser.eval("$inmulti(%foo%,First,:)", context), "1") + self.assertEqual( + self.parser.eval("$inmulti(%foo%,A; Second,:)", context), "1") + self.assertEqual( + self.parser.eval("$inmulti(%foo%,B; Third,:)", context), "1") + self.assertEqual( + self.parser.eval("$inmulti(%foo%,C,:)", context), "1") - context["foo"] = ["First", "Second", "Third"] + context["foo"] = ["First:A", "Second:B", "Third:C"] self.assertEqual( - self.parser.eval("$in(%foo%,Second)", context), "1") + self.parser.eval("$in(%foo%,Second:B)", context), "1") self.assertEqual( - self.parser.eval("$in(%foo%,irst; Second; Thi)", context), "1") + self.parser.eval("$in(%foo%,irst:A; Second:B; Thi)", context), "1") self.assertEqual( - self.parser.eval("$in(%foo%,First; Second; Third)", context), "1") + self.parser.eval("$in(%foo%,First:A; Second:B; Third:C)", context), "1") self.assertEqual( - self.parser.eval("$inmulti(%foo%,Second)", context), "1") + self.parser.eval("$inmulti(%foo%,Second:B)", context), "1") self.assertEqual( - self.parser.eval("$inmulti(%foo%,irst; Second; Thi)", context), "") + self.parser.eval("$inmulti(%foo%,irst:A; Second:B; Thi)", context), "") self.assertEqual( - self.parser.eval("$inmulti(%foo%,First; Second; Third)", context), "") + self.parser.eval("$inmulti(%foo%,First:A; Second:B; Third:C)", context), "") + self.assertEqual( + self.parser.eval("$inmulti(%foo%,First:A,:)", context), "") + self.assertEqual( + self.parser.eval("$inmulti(%foo%,Second:B,:)", context), "") + self.assertEqual( + self.parser.eval("$inmulti(%foo%,Third:C,:)", context), "") + self.assertEqual( + self.parser.eval("$inmulti(%foo%,First,:)", context), "1") + self.assertEqual( + self.parser.eval("$inmulti(%foo%,A; Second,:)", context), "1") + self.assertEqual( + self.parser.eval("$inmulti(%foo%,B; Third,:)", context), "1") + self.assertEqual( + self.parser.eval("$inmulti(%foo%,C,:)", context), "1") def test_cmd_lenmulti(self): context = Metadata() From fca5061a119c9de60caa7e0a0c050b8fd2ac5ed3 Mon Sep 17 00:00:00 2001 From: Sophist Date: Mon, 1 May 2017 13:36:29 +0100 Subject: [PATCH 10/13] Add seperator override tests for $lenmulti --- test/test_script.py | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/test/test_script.py b/test/test_script.py index b7b985564..6833998c5 100644 --- a/test/test_script.py +++ b/test/test_script.py @@ -448,15 +448,21 @@ class ScriptParserTest(unittest.TestCase): def test_cmd_lenmulti(self): context = Metadata() - context["foo"] = "First; Second; Third" - context["bar"] = ["First", "Second", "Third"] + context["foo"] = "First:A; Second:B; Third:C" + context["bar"] = ["First:A", "Second:B", "Third:C"] self.assertEqual( - self.parser.eval("$len(%foo%)", context), "20") + self.parser.eval("$len(%foo%)", context), "26") self.assertEqual( - self.parser.eval("$len(%bar%)", context), "20") + self.parser.eval("$len(%bar%)", context), "26") self.assertEqual( self.parser.eval("$lenmulti(%foo%)", context), "1") self.assertEqual( self.parser.eval("$lenmulti(%bar%)", context), "3") self.assertEqual( self.parser.eval("$lenmulti(%foo%.)", context), "3") + self.assertEqual( + self.parser.eval("$lenmulti(%foo%,:)", context), "4") + self.assertEqual( + self.parser.eval("$lenmulti(%bar%,:)", context), "4") + self.assertEqual( + self.parser.eval("$lenmulti(%foo%.,:)", context), "4") From f4ce8e2ca61bfe8b562547aa72ffe8946967ac45 Mon Sep 17 00:00:00 2001 From: Sophist Date: Mon, 1 May 2017 13:44:33 +0100 Subject: [PATCH 11/13] Add tests for override with standard sep --- test/test_script.py | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/test/test_script.py b/test/test_script.py index 6833998c5..8dc1c65df 100644 --- a/test/test_script.py +++ b/test/test_script.py @@ -403,6 +403,12 @@ class ScriptParserTest(unittest.TestCase): self.parser.eval("$inmulti(%foo%,irst:A; Second:B; Thi)", context), "") self.assertEqual( self.parser.eval("$inmulti(%foo%,First:A; Second:B; Third:C)", context), "1") + self.assertEqual( + self.parser.eval("$inmulti(%foo%,Second:B,; )", context), "") + self.assertEqual( + self.parser.eval("$inmulti(%foo%,irst:A; Second:B; Thi,; )", context), "") + self.assertEqual( + self.parser.eval("$inmulti(%foo%,First:A; Second:B; Third:C,; )", context), "1") self.assertEqual( self.parser.eval("$inmulti(%foo%,First:A,:)", context), "") self.assertEqual( @@ -431,6 +437,12 @@ class ScriptParserTest(unittest.TestCase): self.parser.eval("$inmulti(%foo%,irst:A; Second:B; Thi)", context), "") self.assertEqual( self.parser.eval("$inmulti(%foo%,First:A; Second:B; Third:C)", context), "") + self.assertEqual( + self.parser.eval("$inmulti(%foo%,Second:B,; )", context), "1") + self.assertEqual( + self.parser.eval("$inmulti(%foo%,irst:A; Second:B; Thi,; )", context), "") + self.assertEqual( + self.parser.eval("$inmulti(%foo%,First:A; Second:B; Third:C,; )", context), "") self.assertEqual( self.parser.eval("$inmulti(%foo%,First:A,:)", context), "") self.assertEqual( @@ -460,6 +472,12 @@ class ScriptParserTest(unittest.TestCase): self.parser.eval("$lenmulti(%bar%)", context), "3") self.assertEqual( self.parser.eval("$lenmulti(%foo%.)", context), "3") + self.assertEqual( + self.parser.eval("$lenmulti(%foo%,; )", context), "1") + self.assertEqual( + self.parser.eval("$lenmulti(%bar%,; )", context), "3") + self.assertEqual( + self.parser.eval("$lenmulti(%foo%.,; )", context), "3") self.assertEqual( self.parser.eval("$lenmulti(%foo%,:)", context), "4") self.assertEqual( From 9bb480214450be395baf82b808b1157613b4f39d Mon Sep 17 00:00:00 2001 From: Sophist Date: Mon, 1 May 2017 13:50:35 +0100 Subject: [PATCH 12/13] Add explanatory comments --- test/test_script.py | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/test/test_script.py b/test/test_script.py index 8dc1c65df..b2a6c0f51 100644 --- a/test/test_script.py +++ b/test/test_script.py @@ -390,25 +390,31 @@ class ScriptParserTest(unittest.TestCase): def test_cmd_inmulti(self): context = Metadata() + + # Test with single-value string context["foo"] = "First:A; Second:B; Third:C" + # Tests with $in for comparison purposes self.assertEqual( self.parser.eval("$in(%foo%,Second:B)", context), "1") self.assertEqual( self.parser.eval("$in(%foo%,irst:A; Second:B; Thi)", context), "1") self.assertEqual( self.parser.eval("$in(%foo%,First:A; Second:B; Third:C)", context), "1") + # Base $inmulti tests self.assertEqual( self.parser.eval("$inmulti(%foo%,Second:B)", context), "") self.assertEqual( self.parser.eval("$inmulti(%foo%,irst:A; Second:B; Thi)", context), "") self.assertEqual( self.parser.eval("$inmulti(%foo%,First:A; Second:B; Third:C)", context), "1") + # Test separator override but with existing separator - results should be same as base self.assertEqual( self.parser.eval("$inmulti(%foo%,Second:B,; )", context), "") self.assertEqual( self.parser.eval("$inmulti(%foo%,irst:A; Second:B; Thi,; )", context), "") self.assertEqual( self.parser.eval("$inmulti(%foo%,First:A; Second:B; Third:C,; )", context), "1") + # Test separator override self.assertEqual( self.parser.eval("$inmulti(%foo%,First:A,:)", context), "") self.assertEqual( @@ -424,25 +430,30 @@ class ScriptParserTest(unittest.TestCase): self.assertEqual( self.parser.eval("$inmulti(%foo%,C,:)", context), "1") + # Test with multi-values context["foo"] = ["First:A", "Second:B", "Third:C"] + # Tests with $in for comparison purposes self.assertEqual( self.parser.eval("$in(%foo%,Second:B)", context), "1") self.assertEqual( self.parser.eval("$in(%foo%,irst:A; Second:B; Thi)", context), "1") self.assertEqual( self.parser.eval("$in(%foo%,First:A; Second:B; Third:C)", context), "1") + # Base $inmulti tests self.assertEqual( self.parser.eval("$inmulti(%foo%,Second:B)", context), "1") self.assertEqual( self.parser.eval("$inmulti(%foo%,irst:A; Second:B; Thi)", context), "") self.assertEqual( self.parser.eval("$inmulti(%foo%,First:A; Second:B; Third:C)", context), "") + # Test separator override but with existing separator - results should be same as base self.assertEqual( self.parser.eval("$inmulti(%foo%,Second:B,; )", context), "1") self.assertEqual( self.parser.eval("$inmulti(%foo%,irst:A; Second:B; Thi,; )", context), "") self.assertEqual( self.parser.eval("$inmulti(%foo%,First:A; Second:B; Third:C,; )", context), "") + # Test separator override self.assertEqual( self.parser.eval("$inmulti(%foo%,First:A,:)", context), "") self.assertEqual( @@ -462,22 +473,26 @@ class ScriptParserTest(unittest.TestCase): context = Metadata() context["foo"] = "First:A; Second:B; Third:C" context["bar"] = ["First:A", "Second:B", "Third:C"] + # Tests with $len for comparison purposes self.assertEqual( self.parser.eval("$len(%foo%)", context), "26") self.assertEqual( self.parser.eval("$len(%bar%)", context), "26") + # Base $lenmulti tests self.assertEqual( self.parser.eval("$lenmulti(%foo%)", context), "1") self.assertEqual( self.parser.eval("$lenmulti(%bar%)", context), "3") self.assertEqual( self.parser.eval("$lenmulti(%foo%.)", context), "3") + # Test separator override but with existing separator - results should be same as base self.assertEqual( self.parser.eval("$lenmulti(%foo%,; )", context), "1") self.assertEqual( self.parser.eval("$lenmulti(%bar%,; )", context), "3") self.assertEqual( self.parser.eval("$lenmulti(%foo%.,; )", context), "3") + # Test separator override self.assertEqual( self.parser.eval("$lenmulti(%foo%,:)", context), "4") self.assertEqual( From 303cf7939067ad0a8ea4f31ed5a112ecda4817ca Mon Sep 17 00:00:00 2001 From: Sophist Date: Wed, 3 May 2017 09:09:27 +0100 Subject: [PATCH 13/13] Use assertScriptResultEquals... ... instead of assertEqual(self.parser.eval --- test/test_script.py | 139 ++++++++++++++------------------------------ 1 file changed, 45 insertions(+), 94 deletions(-) diff --git a/test/test_script.py b/test/test_script.py index b2a6c0f51..6a4ea6447 100644 --- a/test/test_script.py +++ b/test/test_script.py @@ -175,16 +175,10 @@ class ScriptParserTest(unittest.TestCase): self.assertScriptResultEquals("$upper(AbeCeDA)", "ABECEDA") def test_cmd_rreplace(self): - self.assertEqual( - self.parser.eval(r'''$rreplace(test \(disc 1\),\\s\\\(disc \\d+\\\),)'''), - "test" - ) + self.assertScriptResultEquals(r'''$rreplace(test \(disc 1\),\\s\\\(disc \\d+\\\),)''', "test") def test_cmd_rsearch(self): - self.assertEqual( - self.parser.eval(r"$rsearch(test \(disc 1\),\\\(disc \(\\d+\)\\\))"), - "1" - ) + self.assertScriptResultEquals(r"$rsearch(test \(disc 1\),\\\(disc \(\\d+\)\\\))", "1") def test_arguments(self): self.assertTrue( @@ -394,108 +388,65 @@ class ScriptParserTest(unittest.TestCase): # Test with single-value string context["foo"] = "First:A; Second:B; Third:C" # Tests with $in for comparison purposes - self.assertEqual( - self.parser.eval("$in(%foo%,Second:B)", context), "1") - self.assertEqual( - self.parser.eval("$in(%foo%,irst:A; Second:B; Thi)", context), "1") - self.assertEqual( - self.parser.eval("$in(%foo%,First:A; Second:B; Third:C)", context), "1") + self.assertScriptResultEquals("$in(%foo%,Second:B)", "1", context) + self.assertScriptResultEquals("$in(%foo%,irst:A; Second:B; Thi)", "1", context) + self.assertScriptResultEquals("$in(%foo%,First:A; Second:B; Third:C)", "1", context) # Base $inmulti tests - self.assertEqual( - self.parser.eval("$inmulti(%foo%,Second:B)", context), "") - self.assertEqual( - self.parser.eval("$inmulti(%foo%,irst:A; Second:B; Thi)", context), "") - self.assertEqual( - self.parser.eval("$inmulti(%foo%,First:A; Second:B; Third:C)", context), "1") + self.assertScriptResultEquals("$inmulti(%foo%,Second:B)", "", context) + self.assertScriptResultEquals("$inmulti(%foo%,irst:A; Second:B; Thi)", "", context) + self.assertScriptResultEquals("$inmulti(%foo%,First:A; Second:B; Third:C)", "1", context) # Test separator override but with existing separator - results should be same as base - self.assertEqual( - self.parser.eval("$inmulti(%foo%,Second:B,; )", context), "") - self.assertEqual( - self.parser.eval("$inmulti(%foo%,irst:A; Second:B; Thi,; )", context), "") - self.assertEqual( - self.parser.eval("$inmulti(%foo%,First:A; Second:B; Third:C,; )", context), "1") + self.assertScriptResultEquals("$inmulti(%foo%,Second:B,; )", "", context) + self.assertScriptResultEquals("$inmulti(%foo%,irst:A; Second:B; Thi,; )", "", context) + self.assertScriptResultEquals("$inmulti(%foo%,First:A; Second:B; Third:C,; )", "1", context) # Test separator override - self.assertEqual( - self.parser.eval("$inmulti(%foo%,First:A,:)", context), "") - self.assertEqual( - self.parser.eval("$inmulti(%foo%,Second:B,:)", context), "") - self.assertEqual( - self.parser.eval("$inmulti(%foo%,Third:C,:)", context), "") - self.assertEqual( - self.parser.eval("$inmulti(%foo%,First,:)", context), "1") - self.assertEqual( - self.parser.eval("$inmulti(%foo%,A; Second,:)", context), "1") - self.assertEqual( - self.parser.eval("$inmulti(%foo%,B; Third,:)", context), "1") - self.assertEqual( - self.parser.eval("$inmulti(%foo%,C,:)", context), "1") + self.assertScriptResultEquals("$inmulti(%foo%,First:A,:)", "", context) + self.assertScriptResultEquals("$inmulti(%foo%,Second:B,:)", "", context) + self.assertScriptResultEquals("$inmulti(%foo%,Third:C,:)", "", context) + self.assertScriptResultEquals("$inmulti(%foo%,First,:)", "1", context) + self.assertScriptResultEquals("$inmulti(%foo%,A; Second,:)", "1", context) + self.assertScriptResultEquals("$inmulti(%foo%,B; Third,:)", "1", context) + self.assertScriptResultEquals("$inmulti(%foo%,C,:)", "1", context) # Test with multi-values context["foo"] = ["First:A", "Second:B", "Third:C"] # Tests with $in for comparison purposes - self.assertEqual( - self.parser.eval("$in(%foo%,Second:B)", context), "1") - self.assertEqual( - self.parser.eval("$in(%foo%,irst:A; Second:B; Thi)", context), "1") - self.assertEqual( - self.parser.eval("$in(%foo%,First:A; Second:B; Third:C)", context), "1") + self.assertScriptResultEquals("$in(%foo%,Second:B)", "1", context) + self.assertScriptResultEquals("$in(%foo%,irst:A; Second:B; Thi)", "1", context) + self.assertScriptResultEquals("$in(%foo%,First:A; Second:B; Third:C)", "1", context) # Base $inmulti tests - self.assertEqual( - self.parser.eval("$inmulti(%foo%,Second:B)", context), "1") - self.assertEqual( - self.parser.eval("$inmulti(%foo%,irst:A; Second:B; Thi)", context), "") - self.assertEqual( - self.parser.eval("$inmulti(%foo%,First:A; Second:B; Third:C)", context), "") + self.assertScriptResultEquals("$inmulti(%foo%,Second:B)", "1", context) + self.assertScriptResultEquals("$inmulti(%foo%,irst:A; Second:B; Thi)", "", context) + self.assertScriptResultEquals("$inmulti(%foo%,First:A; Second:B; Third:C)", "", context) # Test separator override but with existing separator - results should be same as base - self.assertEqual( - self.parser.eval("$inmulti(%foo%,Second:B,; )", context), "1") - self.assertEqual( - self.parser.eval("$inmulti(%foo%,irst:A; Second:B; Thi,; )", context), "") - self.assertEqual( - self.parser.eval("$inmulti(%foo%,First:A; Second:B; Third:C,; )", context), "") + self.assertScriptResultEquals("$inmulti(%foo%,Second:B,; )", "1", context) + self.assertScriptResultEquals("$inmulti(%foo%,irst:A; Second:B; Thi,; )", "", context) + self.assertScriptResultEquals("$inmulti(%foo%,First:A; Second:B; Third:C,; )", "", context) # Test separator override - self.assertEqual( - self.parser.eval("$inmulti(%foo%,First:A,:)", context), "") - self.assertEqual( - self.parser.eval("$inmulti(%foo%,Second:B,:)", context), "") - self.assertEqual( - self.parser.eval("$inmulti(%foo%,Third:C,:)", context), "") - self.assertEqual( - self.parser.eval("$inmulti(%foo%,First,:)", context), "1") - self.assertEqual( - self.parser.eval("$inmulti(%foo%,A; Second,:)", context), "1") - self.assertEqual( - self.parser.eval("$inmulti(%foo%,B; Third,:)", context), "1") - self.assertEqual( - self.parser.eval("$inmulti(%foo%,C,:)", context), "1") + self.assertScriptResultEquals("$inmulti(%foo%,First:A,:)", "", context) + self.assertScriptResultEquals("$inmulti(%foo%,Second:B,:)", "", context) + self.assertScriptResultEquals("$inmulti(%foo%,Third:C,:)", "", context) + self.assertScriptResultEquals("$inmulti(%foo%,First,:)", "1", context) + self.assertScriptResultEquals("$inmulti(%foo%,A; Second,:)", "1", context) + self.assertScriptResultEquals("$inmulti(%foo%,B; Third,:)", "1", context) + self.assertScriptResultEquals("$inmulti(%foo%,C,:)", "1", context) def test_cmd_lenmulti(self): context = Metadata() context["foo"] = "First:A; Second:B; Third:C" context["bar"] = ["First:A", "Second:B", "Third:C"] # Tests with $len for comparison purposes - self.assertEqual( - self.parser.eval("$len(%foo%)", context), "26") - self.assertEqual( - self.parser.eval("$len(%bar%)", context), "26") + self.assertScriptResultEquals("$len(%foo%)", "26", context) + self.assertScriptResultEquals("$len(%bar%)", "26", context) # Base $lenmulti tests - self.assertEqual( - self.parser.eval("$lenmulti(%foo%)", context), "1") - self.assertEqual( - self.parser.eval("$lenmulti(%bar%)", context), "3") - self.assertEqual( - self.parser.eval("$lenmulti(%foo%.)", context), "3") + self.assertScriptResultEquals("$lenmulti(%foo%)", "1", context) + self.assertScriptResultEquals("$lenmulti(%bar%)", "3", context) + self.assertScriptResultEquals("$lenmulti(%foo%.)", "3", context) # Test separator override but with existing separator - results should be same as base - self.assertEqual( - self.parser.eval("$lenmulti(%foo%,; )", context), "1") - self.assertEqual( - self.parser.eval("$lenmulti(%bar%,; )", context), "3") - self.assertEqual( - self.parser.eval("$lenmulti(%foo%.,; )", context), "3") + self.assertScriptResultEquals("$lenmulti(%foo%,; )", "1", context) + self.assertScriptResultEquals("$lenmulti(%bar%,; )", "3", context) + self.assertScriptResultEquals("$lenmulti(%foo%.,; )", "3", context) # Test separator override - self.assertEqual( - self.parser.eval("$lenmulti(%foo%,:)", context), "4") - self.assertEqual( - self.parser.eval("$lenmulti(%bar%,:)", context), "4") - self.assertEqual( - self.parser.eval("$lenmulti(%foo%.,:)", context), "4") + self.assertScriptResultEquals("$lenmulti(%foo%,:)", "4", context) + self.assertScriptResultEquals("$lenmulti(%bar%,:)", "4", context) + self.assertScriptResultEquals("$lenmulti(%foo%.,:)", "4", context)