From 1744ca6e887e54c78b411d8e2584ded3ba2dd688 Mon Sep 17 00:00:00 2001 From: discopatrick Date: Fri, 14 Apr 2017 00:40:06 +0100 Subject: [PATCH 1/9] raises error when dates passed to query as long numbers --- beets/dbcore/query.py | 2 +- test/test_datequery.py | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/beets/dbcore/query.py b/beets/dbcore/query.py index 470ca2ac6e..f1d28a7a85 100644 --- a/beets/dbcore/query.py +++ b/beets/dbcore/query.py @@ -561,7 +561,7 @@ def parse(cls, string): date = datetime.strptime(string, date_format) except ValueError: # Parsing failed. - return None + raise InvalidQueryArgumentTypeError(string, datetime) precision = cls.precisions[ordinal] return cls(date, precision) diff --git a/test/test_datequery.py b/test/test_datequery.py index 1e1625db27..0bb1378a34 100644 --- a/test/test_datequery.py +++ b/test/test_datequery.py @@ -21,7 +21,7 @@ from datetime import datetime import unittest import time -from beets.dbcore.query import _parse_periods, DateInterval, DateQuery +from beets.dbcore.query import _parse_periods, DateInterval, DateQuery, InvalidQueryArgumentTypeError def _date(string): @@ -117,7 +117,8 @@ def test_single_day_nonmatch_fast(self): class DateQueryConstructTest(unittest.TestCase): def test_long_numbers(self): - DateQuery('added', '1409830085..1412422089') + with self.assertRaises(InvalidQueryArgumentTypeError): + DateQuery('added', '1409830085..1412422089') def test_too_many_components(self): DateQuery('added', '12-34-56-78') From a3251ef7c6d3934eb1b0140f36122eaf59a91a5c Mon Sep 17 00:00:00 2001 From: discopatrick Date: Fri, 14 Apr 2017 01:13:02 +0100 Subject: [PATCH 2/9] skips tests for now --- test/test_query.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/test/test_query.py b/test/test_query.py index 41672ab358..fb8d3ac16f 100644 --- a/test/test_query.py +++ b/test/test_query.py @@ -890,6 +890,7 @@ def test_type_boolean(self): self.assert_items_matched(not_results, [u'beets 4 eva']) self.assertNegationProperties(q) + @unittest.skip # skip until I can figure out what this test is doing def test_type_date(self): q = dbcore.query.DateQuery(u'mtime', u'0.0') not_results = self.lib.items(dbcore.query.NotQuery(q)) @@ -992,7 +993,8 @@ def test_fast_vs_slow(self): AttributeError: type object 'NoneQuery' has no attribute 'field' at NoneQuery.match() (due to being @classmethod, and no self?) """ - classes = [(dbcore.query.DateQuery, [u'mtime', u'0.0']), + classes = [#(dbcore.query.DateQuery, [u'mtime', u'0.0']), # skip until I can figure out what this test is doing + # replacing '0.0' with a proper date e.g. '2001-01-01' passes the test (dbcore.query.MatchQuery, [u'artist', u'one']), # (dbcore.query.NoneQuery, ['rg_track_gain']), (dbcore.query.NumericQuery, [u'year', u'2002']), From 3aebb30ad918fdb5d120615828201ce839d85782 Mon Sep 17 00:00:00 2001 From: discopatrick Date: Fri, 14 Apr 2017 01:31:46 +0100 Subject: [PATCH 3/9] improves the exception details --- beets/dbcore/query.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/beets/dbcore/query.py b/beets/dbcore/query.py index f1d28a7a85..46e7562fd8 100644 --- a/beets/dbcore/query.py +++ b/beets/dbcore/query.py @@ -561,7 +561,7 @@ def parse(cls, string): date = datetime.strptime(string, date_format) except ValueError: # Parsing failed. - raise InvalidQueryArgumentTypeError(string, datetime) + raise InvalidQueryArgumentTypeError(string, 'a valid datetime string') precision = cls.precisions[ordinal] return cls(date, precision) From 8e6909bf4b2021e91dba907faa42b0424c49d7bf Mon Sep 17 00:00:00 2001 From: discopatrick Date: Fri, 14 Apr 2017 01:32:18 +0100 Subject: [PATCH 4/9] raises error when date string has too many components --- beets/dbcore/query.py | 2 +- test/test_datequery.py | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/beets/dbcore/query.py b/beets/dbcore/query.py index 46e7562fd8..1169b08d94 100644 --- a/beets/dbcore/query.py +++ b/beets/dbcore/query.py @@ -555,7 +555,7 @@ def parse(cls, string): ordinal = string.count('-') if ordinal >= len(cls.date_formats): # Too many components. - return None + raise InvalidQueryArgumentTypeError(string, 'a valid datetime string') date_format = cls.date_formats[ordinal] try: date = datetime.strptime(string, date_format) diff --git a/test/test_datequery.py b/test/test_datequery.py index 0bb1378a34..7acf192c9e 100644 --- a/test/test_datequery.py +++ b/test/test_datequery.py @@ -121,7 +121,8 @@ def test_long_numbers(self): DateQuery('added', '1409830085..1412422089') def test_too_many_components(self): - DateQuery('added', '12-34-56-78') + with self.assertRaises(InvalidQueryArgumentTypeError): + DateQuery('added', '12-34-56-78') def suite(): From 1ac38722934d57f49c269c711653ec05369744b6 Mon Sep 17 00:00:00 2001 From: discopatrick Date: Fri, 14 Apr 2017 01:40:06 +0100 Subject: [PATCH 5/9] updates documentation --- beets/dbcore/query.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/beets/dbcore/query.py b/beets/dbcore/query.py index 1169b08d94..cf0c137921 100644 --- a/beets/dbcore/query.py +++ b/beets/dbcore/query.py @@ -547,8 +547,9 @@ def __init__(self, date, precision): @classmethod def parse(cls, string): - """Parse a date and return a `Period` object or `None` if the - string is empty. + """Parse a date and return a `Period` object, or `None` if the + string is empty, or raise an InvalidQueryArgumentTypeError if + the string could not be parsed to a date. """ if not string: return None From ed0ea1dee5a8beebbbbdc2b04a7393f938164d09 Mon Sep 17 00:00:00 2001 From: discopatrick Date: Fri, 14 Apr 2017 01:49:58 +0100 Subject: [PATCH 6/9] tests more invalid date queries --- test/test_datequery.py | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/test/test_datequery.py b/test/test_datequery.py index 7acf192c9e..97550ace02 100644 --- a/test/test_datequery.py +++ b/test/test_datequery.py @@ -124,6 +124,21 @@ def test_too_many_components(self): with self.assertRaises(InvalidQueryArgumentTypeError): DateQuery('added', '12-34-56-78') + def test_invalid_date_query(self): + q_list = [ + '2001-01-0a', + '2001-0a', + '200a', + '2001-01-01..2001-01-0a', + '2001-0a..2001-01', + '200a..2002', + '20aa..', + '..2aa' + ] + for q in q_list: + with self.assertRaises(InvalidQueryArgumentTypeError): + DateQuery('added', q) + def suite(): return unittest.TestLoader().loadTestsFromName(__name__) From ff4c0abcf132ee21e76789613e4a4f5e98a063f5 Mon Sep 17 00:00:00 2001 From: discopatrick Date: Fri, 14 Apr 2017 13:04:45 +0100 Subject: [PATCH 7/9] =?UTF-8?q?tests=20=E2=80=98added=E2=80=99=20instead?= =?UTF-8?q?=20of=20=E2=80=98mtime=E2=80=99=20,=20and=20uses=20a=20correct?= =?UTF-8?q?=20date=20format?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- test/test_query.py | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/test/test_query.py b/test/test_query.py index fb8d3ac16f..3216c6f129 100644 --- a/test/test_query.py +++ b/test/test_query.py @@ -890,11 +890,11 @@ def test_type_boolean(self): self.assert_items_matched(not_results, [u'beets 4 eva']) self.assertNegationProperties(q) - @unittest.skip # skip until I can figure out what this test is doing def test_type_date(self): - q = dbcore.query.DateQuery(u'mtime', u'0.0') + q = dbcore.query.DateQuery(u'added', u'2000-01-01') not_results = self.lib.items(dbcore.query.NotQuery(q)) - self.assert_items_matched(not_results, []) + # query date is in the past, thus the 'not' results should contain all items + self.assert_items_matched(not_results, [u'foo bar', u'baz qux', u'beets 4 eva']) self.assertNegationProperties(q) def test_type_false(self): @@ -993,8 +993,7 @@ def test_fast_vs_slow(self): AttributeError: type object 'NoneQuery' has no attribute 'field' at NoneQuery.match() (due to being @classmethod, and no self?) """ - classes = [#(dbcore.query.DateQuery, [u'mtime', u'0.0']), # skip until I can figure out what this test is doing - # replacing '0.0' with a proper date e.g. '2001-01-01' passes the test + classes = [(dbcore.query.DateQuery, [u'added', u'2001-01-01']), (dbcore.query.MatchQuery, [u'artist', u'one']), # (dbcore.query.NoneQuery, ['rg_track_gain']), (dbcore.query.NumericQuery, [u'year', u'2002']), From d466f8802c94404a9256ebf55308db83d43fcf42 Mon Sep 17 00:00:00 2001 From: discopatrick Date: Fri, 14 Apr 2017 14:45:51 +0100 Subject: [PATCH 8/9] passes flake8 --- test/test_datequery.py | 3 ++- test/test_query.py | 6 ++++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/test/test_datequery.py b/test/test_datequery.py index 97550ace02..e81544aaad 100644 --- a/test/test_datequery.py +++ b/test/test_datequery.py @@ -21,7 +21,8 @@ from datetime import datetime import unittest import time -from beets.dbcore.query import _parse_periods, DateInterval, DateQuery, InvalidQueryArgumentTypeError +from beets.dbcore.query import _parse_periods, DateInterval, DateQuery,\ + InvalidQueryArgumentTypeError def _date(string): diff --git a/test/test_query.py b/test/test_query.py index 3216c6f129..3538c15a88 100644 --- a/test/test_query.py +++ b/test/test_query.py @@ -893,8 +893,10 @@ def test_type_boolean(self): def test_type_date(self): q = dbcore.query.DateQuery(u'added', u'2000-01-01') not_results = self.lib.items(dbcore.query.NotQuery(q)) - # query date is in the past, thus the 'not' results should contain all items - self.assert_items_matched(not_results, [u'foo bar', u'baz qux', u'beets 4 eva']) + # query date is in the past, thus the 'not' results should contain all + # items + self.assert_items_matched(not_results, [u'foo bar', u'baz qux', + u'beets 4 eva']) self.assertNegationProperties(q) def test_type_false(self): From 18c512893eeb2cb9d734ca1c5b3e4df5fba1a1ba Mon Sep 17 00:00:00 2001 From: discopatrick Date: Wed, 19 Apr 2017 14:10:04 +0100 Subject: [PATCH 9/9] more flake8 updates --- beets/dbcore/query.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/beets/dbcore/query.py b/beets/dbcore/query.py index cf0c137921..aa8aa4af88 100644 --- a/beets/dbcore/query.py +++ b/beets/dbcore/query.py @@ -556,13 +556,15 @@ def parse(cls, string): ordinal = string.count('-') if ordinal >= len(cls.date_formats): # Too many components. - raise InvalidQueryArgumentTypeError(string, 'a valid datetime string') + raise InvalidQueryArgumentTypeError(string, + 'a valid datetime string') date_format = cls.date_formats[ordinal] try: date = datetime.strptime(string, date_format) except ValueError: # Parsing failed. - raise InvalidQueryArgumentTypeError(string, 'a valid datetime string') + raise InvalidQueryArgumentTypeError(string, + 'a valid datetime string') precision = cls.precisions[ordinal] return cls(date, precision)