From b4383a180c939063b2d9696da925ca5f859dc76b Mon Sep 17 00:00:00 2001 From: ChrisLR Date: Sat, 3 Oct 2020 13:00:07 -0400 Subject: [PATCH 1/5] Added has method on TagHandler with a few tests --- evennia/typeclasses/tags.py | 25 +++++++++++++++++++++++++ evennia/typeclasses/tests.py | 24 ++++++++++++++++++++++++ 2 files changed, 49 insertions(+) diff --git a/evennia/typeclasses/tags.py b/evennia/typeclasses/tags.py index c8f121d17d..0bb2e994e1 100644 --- a/evennia/typeclasses/tags.py +++ b/evennia/typeclasses/tags.py @@ -319,6 +319,31 @@ class TagHandler(object): getattr(self.obj, self._m2m_fieldname).add(tagobj) self._setcache(tagstr, category, tagobj) + def has(self, key=None, category=None, return_list=False): + """ + Checks if the given Tag (or list of Tags) exists on the object. + + Args: + key (str or iterable): The Tag key or keys to check for. + If `None`, search by category. + category (str or None): Limit the check to Tags with this + category (note, that `None` is the default category). + + Returns: + has_tag (bool or list): If the Tag exists on this object or not. + If `key` was given as an iterable then the return is a list of booleans. + + """ + ret = [] + category = category.strip().lower() if category is not None else None + for key_str in make_iter(key): + key_str = key_str.strip().lower() + ret.extend(bool(tag) for tag in self._getcache(key_str, category)) + + if return_list: + return ret + return ret[0] if len(ret) == 1 else ret + def get(self, key=None, default=None, category=None, return_tagobj=False, return_list=False): """ Get the tag for the given key, category or combination of the two. diff --git a/evennia/typeclasses/tests.py b/evennia/typeclasses/tests.py index c6986541f0..3d239d9143 100644 --- a/evennia/typeclasses/tests.py +++ b/evennia/typeclasses/tests.py @@ -145,3 +145,27 @@ class TestTypedObjectManager(EvenniaTest): self.assertEqual(tagobj.db_key, "tag4") self.assertEqual(tagobj.db_category, "category4") self.assertEqual(tagobj.db_data, "data4") + + def test_has_tag_key_only(self): + self.obj1.tags.add("tagC", "categoryC") + self.assertTrue(self.obj1.tags.has("tagC")) + + def test_has_tag_key_with_category(self): + self.obj1.tags.add("tagC", "categoryC") + self.assertTrue(self.obj1.tags.has("tagC", "categoryC")) + + def test_does_not_have_tag_key_only(self): + self.obj1.tags.add("tagC") + self.assertFalse(self.obj1.tags.has("tagD")) + + def test_does_not_have_tag_key_with_category(self): + self.obj1.tags.add("tagC", "categoryC") + self.assertFalse(self.obj1.tags.has("tagD", "categoryD")) + + def test_has_tag_category_only(self): + self.obj1.tags.add("tagC", "categoryC") + self.assertTrue(self.obj1.tags.has(category="categoryC")) + + def test_does_not_have_tag_category_only(self): + self.obj1.tags.add("tagC", "categoryC") + self.assertTrue(self.obj1.tags.has(category="categoryD")) From 2f724fb41609e6385bf32b080eac3f978f6de4b5 Mon Sep 17 00:00:00 2001 From: ChrisLR Date: Sat, 3 Oct 2020 13:02:54 -0400 Subject: [PATCH 2/5] Renamed key to tag --- evennia/typeclasses/tags.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/evennia/typeclasses/tags.py b/evennia/typeclasses/tags.py index 0bb2e994e1..f3c3d6d15e 100644 --- a/evennia/typeclasses/tags.py +++ b/evennia/typeclasses/tags.py @@ -319,26 +319,26 @@ class TagHandler(object): getattr(self.obj, self._m2m_fieldname).add(tagobj) self._setcache(tagstr, category, tagobj) - def has(self, key=None, category=None, return_list=False): + def has(self, tag=None, category=None, return_list=False): """ Checks if the given Tag (or list of Tags) exists on the object. Args: - key (str or iterable): The Tag key or keys to check for. + tag (str or iterable): The Tag key or tags to check for. If `None`, search by category. category (str or None): Limit the check to Tags with this category (note, that `None` is the default category). Returns: has_tag (bool or list): If the Tag exists on this object or not. - If `key` was given as an iterable then the return is a list of booleans. + If `tag` was given as an iterable then the return is a list of booleans. """ ret = [] category = category.strip().lower() if category is not None else None - for key_str in make_iter(key): - key_str = key_str.strip().lower() - ret.extend(bool(tag) for tag in self._getcache(key_str, category)) + for tag_str in make_iter(tag): + tag_str = tag_str.strip().lower() + ret.extend(bool(tag) for tag in self._getcache(tag_str, category)) if return_list: return ret From 27d41cab8ba4908612656bcb8adbefd7784c1201 Mon Sep 17 00:00:00 2001 From: ChrisLR Date: Sat, 3 Oct 2020 13:12:54 -0400 Subject: [PATCH 3/5] Fixed wrong assert --- evennia/typeclasses/tests.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/evennia/typeclasses/tests.py b/evennia/typeclasses/tests.py index 3d239d9143..f970e1af17 100644 --- a/evennia/typeclasses/tests.py +++ b/evennia/typeclasses/tests.py @@ -168,4 +168,4 @@ class TestTypedObjectManager(EvenniaTest): def test_does_not_have_tag_category_only(self): self.obj1.tags.add("tagC", "categoryC") - self.assertTrue(self.obj1.tags.has(category="categoryD")) + self.assertFalse(self.obj1.tags.has(category="categoryD")) From 8cce8e4da4d97a0b9d809298791f88fc80fa86e8 Mon Sep 17 00:00:00 2001 From: ChrisLR Date: Sat, 3 Oct 2020 13:21:53 -0400 Subject: [PATCH 4/5] Handle the case where tag is not provided and raise a ValueError if neither are provided. --- evennia/typeclasses/tags.py | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/evennia/typeclasses/tags.py b/evennia/typeclasses/tags.py index f3c3d6d15e..d6e58fbee3 100644 --- a/evennia/typeclasses/tags.py +++ b/evennia/typeclasses/tags.py @@ -336,12 +336,18 @@ class TagHandler(object): """ ret = [] category = category.strip().lower() if category is not None else None - for tag_str in make_iter(tag): - tag_str = tag_str.strip().lower() - ret.extend(bool(tag) for tag in self._getcache(tag_str, category)) + if tag: + for tag_str in make_iter(tag): + tag_str = tag_str.strip().lower() + ret.extend(bool(tag) for tag in self._getcache(tag_str, category)) + elif category: + ret.extend(bool(tag) for tag in self._getcache(category=category)) + else: + raise ValueError("Either tag or category must be provided.") if return_list: return ret + return ret[0] if len(ret) == 1 else ret def get(self, key=None, default=None, category=None, return_tagobj=False, return_list=False): From 10139185e11de254007772d582352e31a72d1d10 Mon Sep 17 00:00:00 2001 From: ChrisLR Date: Sat, 3 Oct 2020 14:21:22 -0400 Subject: [PATCH 5/5] Placed tags tests in their own TestClass --- evennia/typeclasses/tests.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/evennia/typeclasses/tests.py b/evennia/typeclasses/tests.py index f970e1af17..c04f5fa3fd 100644 --- a/evennia/typeclasses/tests.py +++ b/evennia/typeclasses/tests.py @@ -146,8 +146,10 @@ class TestTypedObjectManager(EvenniaTest): self.assertEqual(tagobj.db_category, "category4") self.assertEqual(tagobj.db_data, "data4") + +class TestTags(EvenniaTest): def test_has_tag_key_only(self): - self.obj1.tags.add("tagC", "categoryC") + self.obj1.tags.add("tagC") self.assertTrue(self.obj1.tags.has("tagC")) def test_has_tag_key_with_category(self):