@@ -36,6 +36,16 @@ class FakeManager(base.RESTManager):
3636 _path = "/tests"
3737
3838
39+ class FakeParent :
40+ id = 42
41+
42+
43+ class FakeManagerWithParent (base .RESTManager ):
44+ _path = "/tests/{test_id}/cases"
45+ _obj_cls = FakeObject
46+ _from_parent_attrs = {"test_id" : "id" }
47+
48+
3949@pytest .fixture
4050def fake_gitlab ():
4151 return FakeGitlab ()
@@ -46,6 +56,21 @@ def fake_manager(fake_gitlab):
4656 return FakeManager (fake_gitlab )
4757
4858
59+ @pytest .fixture
60+ def fake_manager_with_parent (fake_gitlab ):
61+ return FakeManagerWithParent (fake_gitlab , parent = FakeParent )
62+
63+
64+ @pytest .fixture
65+ def fake_object (fake_manager ):
66+ return FakeObject (fake_manager , {"attr1" : "foo" , "alist" : [1 , 2 , 3 ]})
67+
68+
69+ @pytest .fixture
70+ def fake_object_with_parent (fake_manager_with_parent ):
71+ return FakeObject (fake_manager_with_parent , {"attr1" : "foo" , "alist" : [1 , 2 , 3 ]})
72+
73+
4974class TestRESTManager :
5075 def test_computed_path_simple (self ):
5176 class MGR (base .RESTManager ):
@@ -306,3 +331,75 @@ def test_repr(self, fake_manager):
306331
307332 FakeObject ._id_attr = None
308333 assert repr (obj ) == "<FakeObject>"
334+
335+ def test_attributes_get (self , fake_object ):
336+ assert fake_object .attr1 == "foo"
337+ result = fake_object .attributes
338+ assert result == {"attr1" : "foo" , "alist" : [1 , 2 , 3 ]}
339+
340+ def test_attributes_shows_updates (self , fake_object ):
341+ # Updated attribute value is reflected in `attributes`
342+ fake_object .attr1 = "hello"
343+ assert fake_object .attributes == {"attr1" : "hello" , "alist" : [1 , 2 , 3 ]}
344+ assert fake_object .attr1 == "hello"
345+ # New attribute is in `attributes`
346+ fake_object .new_attrib = "spam"
347+ assert fake_object .attributes == {
348+ "attr1" : "hello" ,
349+ "new_attrib" : "spam" ,
350+ "alist" : [1 , 2 , 3 ],
351+ }
352+
353+ def test_attributes_is_copy (self , fake_object ):
354+ # Modifying the dictionary does not cause modifications to the object
355+ result = fake_object .attributes
356+ result ["alist" ].append (10 )
357+ assert result == {"attr1" : "foo" , "alist" : [1 , 2 , 3 , 10 ]}
358+ assert fake_object .attributes == {"attr1" : "foo" , "alist" : [1 , 2 , 3 ]}
359+
360+ def test_attributes_has_parent_attrs (self , fake_object_with_parent ):
361+ assert fake_object_with_parent .attr1 == "foo"
362+ result = fake_object_with_parent .attributes
363+ assert result == {"attr1" : "foo" , "alist" : [1 , 2 , 3 ], "test_id" : "42" }
364+
365+ def test_asdict (self , fake_object ):
366+ assert fake_object .attr1 == "foo"
367+ result = fake_object .asdict ()
368+ assert result == {"attr1" : "foo" , "alist" : [1 , 2 , 3 ]}
369+
370+ def test_asdict_no_parent_attrs (self , fake_object_with_parent ):
371+ assert fake_object_with_parent .attr1 == "foo"
372+ result = fake_object_with_parent .asdict ()
373+ assert result == {"attr1" : "foo" , "alist" : [1 , 2 , 3 ]}
374+ assert "test_id" not in fake_object_with_parent .asdict ()
375+ assert "test_id" not in fake_object_with_parent .asdict (with_parent_attrs = False )
376+ assert "test_id" in fake_object_with_parent .asdict (with_parent_attrs = True )
377+
378+ def test_asdict_modify_dict_does_not_change_object (self , fake_object ):
379+ result = fake_object .asdict ()
380+ # Demonstrate modifying the dictionary does not modify the object
381+ result ["attr1" ] = "testing"
382+ result ["alist" ].append (4 )
383+ assert result == {"attr1" : "testing" , "alist" : [1 , 2 , 3 , 4 ]}
384+ assert fake_object .attr1 == "foo"
385+ assert fake_object .alist == [1 , 2 , 3 ]
386+
387+ def test_asdict_modify_dict_does_not_change_object2 (self , fake_object ):
388+ # Modify attribute and then ensure modifying a list in the returned dict won't
389+ # modify the list in the object.
390+ fake_object .attr1 = [9 , 7 , 8 ]
391+ assert fake_object .asdict () == {
392+ "attr1" : [9 , 7 , 8 ],
393+ "alist" : [1 , 2 , 3 ],
394+ }
395+ result = fake_object .asdict ()
396+ result ["attr1" ].append (1 )
397+ assert fake_object .asdict () == {
398+ "attr1" : [9 , 7 , 8 ],
399+ "alist" : [1 , 2 , 3 ],
400+ }
401+
402+ def test_asdict_modify_object (self , fake_object ):
403+ # asdict() returns the updated value
404+ fake_object .attr1 = "spam"
405+ assert fake_object .asdict () == {"attr1" : "spam" , "alist" : [1 , 2 , 3 ]}
0 commit comments