mirror of
https://github.com/evennia/evennia.git
synced 2026-03-16 21:06:30 +01:00
Fix inconsistent filtering on AttributeProperties across typeclasses. Resolve #3194
This commit is contained in:
parent
0dd2b595a0
commit
8b21527a8c
4 changed files with 94 additions and 3 deletions
|
|
@ -37,6 +37,7 @@
|
|||
- [Fix][issue3649]: The `:j` command in EvEditor would squash empty lines (Griatch)
|
||||
- [Fix][issue3560]: Tutorial QuestHandler failed to load after server restart (Griatch)
|
||||
- [Fix][issue3601]: `CmdSet.add(..., allow_duplicates=True)` didn't allow duplicate cmd keys (Griatch)
|
||||
- [Fix][issue3194]: Make filtering on AttributeProperties consistent across typeclasses (Griatch)
|
||||
- [Doc][pull3801]: Move Evennia doc build system to latest Sphinx/myST
|
||||
(PowershellNinja, also honorary mention to electroglyph)
|
||||
- [Doc][pull3800]: Describe support for Telnet SSH in HAProxy documentation (holl0wstar)
|
||||
|
|
@ -69,6 +70,7 @@
|
|||
[issue3649]: https://github.com/evennia/evennia/issues/3649
|
||||
[issue3560]: https://github.com/evennia/evennia/issues/3560
|
||||
[issue3601]: https://github.com/evennia/evennia/issues/3601
|
||||
[issue3194]: https://github.com/evennia/evennia/issues/3194
|
||||
|
||||
|
||||
## Evennia 5.0.1
|
||||
|
|
|
|||
|
|
@ -1,5 +1,3 @@
|
|||
from unittest import skip
|
||||
|
||||
from evennia.objects.models import ObjectDB
|
||||
from evennia.objects.objects import (
|
||||
DefaultCharacter,
|
||||
|
|
@ -656,7 +654,6 @@ class TestProperties(EvenniaTestCase):
|
|||
self.assertEqual(obj.cusattr, 5)
|
||||
self.assertEqual(obj.settest, 5)
|
||||
|
||||
@skip("TODO: Needs more research")
|
||||
def test_stored_object_queries(self):
|
||||
""",
|
||||
Test https://github.com/evennia/evennia/issues/3155, where AttributeProperties
|
||||
|
|
@ -690,6 +687,42 @@ class TestProperties(EvenniaTestCase):
|
|||
obj1.delete()
|
||||
obj2.delete()
|
||||
|
||||
def test_stored_object_queries__self_reference(self):
|
||||
"""
|
||||
Regression test for querying on a stored self-reference.
|
||||
|
||||
Related to https://github.com/evennia/evennia/issues/3194 comments.
|
||||
"""
|
||||
obj = create.create_object(TestObjectPropertiesClass, key="selfref")
|
||||
try:
|
||||
obj.attr1 = obj
|
||||
query = TestObjectPropertiesClass.objects.filter(
|
||||
db_attributes__db_key="attr1", db_attributes__db_value=obj
|
||||
)
|
||||
self.assertEqual(list(query), [obj])
|
||||
finally:
|
||||
obj.delete()
|
||||
|
||||
def test_stored_object_queries__filter_family(self):
|
||||
"""
|
||||
Regression test for object-valued attribute filtering via filter_family.
|
||||
|
||||
Related to https://github.com/evennia/evennia/issues/3194 comments.
|
||||
"""
|
||||
holder = create.create_object(DefaultObject, key="holder")
|
||||
leg = create.create_object(DefaultObject, key="leg")
|
||||
try:
|
||||
holder.attributes.add("attached", leg, category="systems")
|
||||
query = DefaultObject.objects.filter_family(
|
||||
db_attributes__db_key="attached",
|
||||
db_attributes__db_category="systems",
|
||||
db_attributes__db_value=leg,
|
||||
)
|
||||
self.assertIn(holder, query)
|
||||
finally:
|
||||
holder.delete()
|
||||
leg.delete()
|
||||
|
||||
def test_not_create_attribute_with_autocreate_false(self):
|
||||
"""
|
||||
Test that AttributeProperty with autocreate=False does not create an attribute in the database.
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@ from evennia.scripts.monitorhandler import MonitorHandler
|
|||
from evennia.scripts.ondemandhandler import OnDemandHandler, OnDemandTask
|
||||
from evennia.scripts.scripts import DoNothing, ExtendedLoopingCall
|
||||
from evennia.scripts.tickerhandler import TickerHandler
|
||||
from evennia.typeclasses.attributes import AttributeProperty
|
||||
from evennia.utils.create import create_script
|
||||
from evennia.utils.dbserialize import dbserialize
|
||||
from evennia.utils.test_resources import BaseEvenniaTest, EvenniaTest
|
||||
|
|
@ -86,6 +87,10 @@ class TestingListIntervalScript(DefaultScript):
|
|||
self.repeats = 1
|
||||
|
||||
|
||||
class ScriptWithStoredRef(DefaultScript):
|
||||
linked = AttributeProperty(default=None, autocreate=False)
|
||||
|
||||
|
||||
class TestScriptHandler(BaseEvenniaTest):
|
||||
"""
|
||||
Test the ScriptHandler class.
|
||||
|
|
@ -162,6 +167,47 @@ class TestScriptDB(TestCase):
|
|||
self.assertFalse(self.scr in ScriptDB.objects.get_all_scripts())
|
||||
|
||||
|
||||
class TestIssue3194(BaseEvenniaTest):
|
||||
"""
|
||||
Regression test for inconsistent filtering of Script AttributeProperty refs.
|
||||
https://github.com/evennia/evennia/issues/3194
|
||||
"""
|
||||
|
||||
def test_script_attributeproperty_filtering_stored_dbobjs(self):
|
||||
script_a = create_script(ScriptWithStoredRef, key="issue3194-script-a")
|
||||
script_b = create_script(ScriptWithStoredRef, key="issue3194-script-b")
|
||||
script_c = create_script(ScriptWithStoredRef, key="issue3194-script-c")
|
||||
|
||||
try:
|
||||
script_a.linked = script_b
|
||||
script_c.linked = self.room1
|
||||
|
||||
self.assertEqual(
|
||||
list(ScriptWithStoredRef.objects.get_by_attribute("linked", value=script_b)),
|
||||
[script_a],
|
||||
)
|
||||
self.assertEqual(
|
||||
list(
|
||||
ScriptWithStoredRef.objects.filter(
|
||||
db_attributes__db_key="linked", db_attributes__db_value=script_b
|
||||
)
|
||||
),
|
||||
[script_a],
|
||||
)
|
||||
self.assertEqual(
|
||||
list(
|
||||
ScriptWithStoredRef.objects.filter(
|
||||
db_attributes__db_key="linked", db_attributes__db_value=self.room1
|
||||
)
|
||||
),
|
||||
[script_c],
|
||||
)
|
||||
finally:
|
||||
script_a.delete()
|
||||
script_b.delete()
|
||||
script_c.delete()
|
||||
|
||||
|
||||
class TestExtendedLoopingCall(TestCase):
|
||||
"""
|
||||
Test the ExtendedLoopingCall class.
|
||||
|
|
|
|||
|
|
@ -92,6 +92,16 @@ def dbsafe_encode(value, compress_object=False, pickle_protocol=DEFAULT_PROTOCOL
|
|||
# simple string matches, thus the character streams must be the same
|
||||
# for the lookups to work properly. See tests.py for more information.
|
||||
try:
|
||||
if isinstance(value, _ObjectWrapper):
|
||||
# Keep conflict wrappers for regular values, but still normalize wrapped
|
||||
# db objects to the same packed representation as Attribute storage.
|
||||
packed = pack_dbobj(value._obj)
|
||||
if packed is not value._obj:
|
||||
value = packed
|
||||
else:
|
||||
# Make sure database objects are normalized before pickling for lookups.
|
||||
value = pack_dbobj(value)
|
||||
|
||||
value = deepcopy(value)
|
||||
except CopyError:
|
||||
# this can happen on a manager query where the search query string is a
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue