%PDF- %PDF-
Direktori : /lib/python3/dist-packages/launchpadlib/testing/tests/ |
Current File : //lib/python3/dist-packages/launchpadlib/testing/tests/test_launchpad.py |
# Copyright 2008 Canonical Ltd. # This file is part of launchpadlib. # # launchpadlib is free software: you can redistribute it and/or modify # it under the terms of the GNU Lesser General Public License as # published by the Free Software Foundation, either version 3 of the # License, or (at your option) any later version. # # launchpadlib is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # Lesser General Public License for more details. # # You should have received a copy of the GNU Lesser General Public # License along with launchpadlib. If not, see # <http://www.gnu.org/licenses/>. from datetime import datetime from testresources import ResourcedTestCase from launchpadlib.testing.launchpad import ( FakeLaunchpad, FakeResource, FakeRoot, IntegrityError, ) from launchpadlib.testing.resources import ( FakeLaunchpadResource, get_application, ) class FakeRootTest(ResourcedTestCase): def test_create_root_resource(self): root_resource = FakeRoot(get_application()) self.assertTrue(isinstance(root_resource, FakeResource)) class FakeResourceTest(ResourcedTestCase): resources = [("launchpad", FakeLaunchpadResource())] def test_repr_entry(self): """A custom C{__repr__} is provided for L{FakeEntry}s.""" bug = dict() self.launchpad.bugs = dict(entries=[bug]) [bug] = list(self.launchpad.bugs) self.assertEqual( "<FakeEntry bug object at %s>" % hex(id(bug)), repr(bug) ) def test_repr_collection(self): """A custom C{__repr__} is provided for L{FakeCollection}s.""" branches = dict(total_size="test-branch") self.launchpad.me = dict(getBranches=lambda statuses: branches) branches = self.launchpad.me.getBranches([]) obj_id = hex(id(branches)) self.assertEqual( "<FakeCollection branch-page-resource object at %s>" % obj_id, repr(branches), ) def test_repr_with_name(self): """ If the fake has a C{name} property it's included in the repr string to make it easier to figure out what it is. """ self.launchpad.me = dict(name="foo") person = self.launchpad.me self.assertEqual( "<FakeEntry person foo at %s>" % hex(id(person)), repr(person) ) def test_repr_with_id(self): """ If the fake has an C{id} property it's included in the repr string to make it easier to figure out what it is. """ bug = dict(id="1", title="Bug #1") self.launchpad.bugs = dict(entries=[bug]) [bug] = list(self.launchpad.bugs) self.assertEqual("<FakeEntry bug 1 at %s>" % hex(id(bug)), repr(bug)) class FakeLaunchpadTest(ResourcedTestCase): resources = [("launchpad", FakeLaunchpadResource())] def test_wb_instantiate_without_application(self): """ The builtin WADL definition is used if the C{application} is not provided during instantiation. """ credentials = object() launchpad = FakeLaunchpad(credentials) self.assertEqual(credentials, launchpad.credentials) self.assertEqual(get_application(), launchpad._application) def test_instantiate_with_everything(self): """ L{FakeLaunchpad} takes the same parameters as L{Launchpad} during instantiation, with the addition of an C{application} parameter. The optional parameters are discarded when the object is instantiated. """ credentials = object() launchpad = FakeLaunchpad( credentials, service_root=None, cache=None, timeout=None, proxy_info=None, application=get_application(), ) self.assertEqual(credentials, launchpad.credentials) def test_instantiate_with_credentials(self): """A L{FakeLaunchpad} can be instantiated with credentials.""" credentials = object() launchpad = FakeLaunchpad(credentials, application=get_application()) self.assertEqual(credentials, launchpad.credentials) def test_instantiate_without_credentials(self): """ A L{FakeLaunchpad} instantiated without credentials has its C{credentials} attribute set to C{None}. """ self.assertIsNone(self.launchpad.credentials) def test_set_undefined_property(self): """ An L{IntegrityError} is raised if an attribute is set on a L{FakeLaunchpad} instance that isn't present in the WADL definition. """ self.assertRaises( IntegrityError, setattr, self.launchpad, "foo", "bar" ) def test_get_undefined_resource(self): """ An L{AttributeError} is raised if an attribute is accessed on a L{FakeLaunchpad} instance that doesn't exist. """ self.launchpad.me = dict(display_name="Foo") self.assertRaises(AttributeError, getattr, self.launchpad.me, "name") def test_string_property(self): """ Sample data can be created by setting L{FakeLaunchpad} attributes with dicts that represent objects. Plain string values can be represented as C{str} values. """ self.launchpad.me = dict(name="foo") self.assertEqual("foo", self.launchpad.me.name) def test_unicode_property(self): """ Sample data can be created by setting L{FakeLaunchpad} attributes with dicts that represent objects. Plain string values can be represented as C{unicode} strings. """ self.launchpad.me = dict(name=u"foo") self.assertEqual(u"foo", self.launchpad.me.name) def test_datetime_property(self): """ Attributes that represent dates are set with C{datetime} instances. """ now = datetime.utcnow() self.launchpad.me = dict(date_created=now) self.assertEqual(now, self.launchpad.me.date_created) def test_invalid_datetime_property(self): """ Only C{datetime} values can be set on L{FakeLaunchpad} instances for attributes that represent dates. """ self.assertRaises( IntegrityError, setattr, self.launchpad, "me", dict(date_created="now"), ) def test_multiple_string_properties(self): """ Sample data can be created by setting L{FakeLaunchpad} attributes with dicts that represent objects. """ self.launchpad.me = dict(name="foo", display_name="Foo") self.assertEqual("foo", self.launchpad.me.name) self.assertEqual("Foo", self.launchpad.me.display_name) def test_invalid_property_name(self): """ Sample data set on a L{FakeLaunchpad} instance is validated against the WADL definition. If a key is defined on a resource that doesn't match a related parameter, an L{IntegrityError} is raised. """ self.assertRaises( IntegrityError, setattr, self.launchpad, "me", dict(foo="bar") ) def test_invalid_property_value(self): """ The types of sample data values set on L{FakeLaunchpad} instances are validated against types defined in the WADL definition. """ self.assertRaises( IntegrityError, setattr, self.launchpad, "me", dict(name=102) ) def test_callable(self): """ A callable set on a L{FakeLaunchpad} instance is validated against the WADL definition, to make sure a matching method exists. """ branches = dict(total_size="test-branch") self.launchpad.me = dict(getBranches=lambda statuses: branches) self.assertNotEqual(None, self.launchpad.me.getBranches([])) def test_invalid_callable_name(self): """ An L{IntegrityError} is raised if a method is defined on a resource that doesn't match a method defined in the WADL definition. """ self.assertRaises( IntegrityError, setattr, self.launchpad, "me", dict(foo=lambda: None), ) def test_callable_object_return_type(self): """ The result of a fake method is a L{FakeResource}, automatically created from the object used to define the return object. """ branches = dict(total_size="8") self.launchpad.me = dict(getBranches=lambda statuses: branches) branches = self.launchpad.me.getBranches([]) self.assertTrue(isinstance(branches, FakeResource)) self.assertEqual("8", branches.total_size) def test_invalid_callable_object_return_type(self): """ An L{IntegrityError} is raised if a method returns an invalid result. """ branches = dict(total_size=8) self.launchpad.me = dict(getBranches=lambda statuses: branches) self.assertRaises(IntegrityError, self.launchpad.me.getBranches, []) def test_callable_object_return_None(self): """ A fake method passes through a return value of None rather than trying to create a L{FakeResource}. """ self.launchpad.branches = dict(getByUniqueName=lambda name: None) self.assertIsNone(self.launchpad.branches.getByUniqueName("foo")) def test_callable_object_no_response_representation(self): """ If the WADL definition of a method does not include a response representation, then fake versions of that method just pass through the return value. """ branch = dict(canBeDeleted=lambda: True) self.launchpad.branches = dict(getByUniqueName=lambda name: branch) branch = self.launchpad.branches.getByUniqueName("foo") self.assertTrue(branch.canBeDeleted()) def test_entry_property(self): """ Attributes that represent links to other objects are set using a dict representing the object. """ bug = dict(owner=dict(name="test-person")) self.launchpad.bugs = dict(entries=[bug]) bug = self.launchpad.bugs[0] self.assertEqual("test-person", bug.owner.name) def test_invalid_entry_property(self): """ Sample data for linked entries is validated. """ bug = dict(owner=dict(foo="bar")) self.assertRaises( IntegrityError, setattr, self.launchpad, "bugs", dict(entries=[bug]), ) def test_top_level_collection_property(self): """ Sample top-level collections can be set on L{FakeLaunchpad} instances. They are validated the same way other sample data is validated. """ branch = dict(name="foo") self.launchpad.branches = dict(getByUniqueName=lambda name: branch) branch = self.launchpad.branches.getByUniqueName("foo") self.assertEqual("foo", branch.name) def test_collection_property(self): """ Attributes that represent links to collections of other objects are set using a dict representing the collection. """ bug = dict(id="1") branch = dict(linked_bugs=dict(entries=[bug])) self.launchpad.branches = dict(getByUniqueName=lambda name: branch) branch = self.launchpad.branches.getByUniqueName("foo") [bug] = list(branch.linked_bugs) self.assertEqual("1", bug.id) def test_iterate_collection(self): """ Data for a sample collection set on a L{FakeLaunchpad} instance can be iterated over if an C{entries} key is defined. """ bug = dict(id="1", title="Bug #1") self.launchpad.bugs = dict(entries=[bug]) bugs = list(self.launchpad.bugs) self.assertEqual(1, len(bugs)) bug = bugs[0] self.assertEqual("1", bug.id) self.assertEqual("Bug #1", bug.title) def test_top_level_collection_with_invalid_entries(self): """ Sample data for each entry in a collection is validated when it's set on a L{FakeLaunchpad} instance. """ bug = dict(foo="bar") self.assertRaises( IntegrityError, setattr, self.launchpad, "bugs", dict(entries=[bug]), ) def test_collection_with_invalid_entries(self): """ Sample data for each entry in a collection is validated when it's set on an attribute representing a link to a collection of objects. """ bug = dict(foo="bar") branch = dict(linked_bugs=dict(entries=[bug])) self.launchpad.branches = dict(getByUniqueName=lambda name: branch) self.assertRaises( IntegrityError, self.launchpad.branches.getByUniqueName, "foo", ) def test_slice_collection(self): """ Data for a sample collection set on a L{FakeLaunchpad} instance can be sliced if an C{entries} key is defined. """ bug1 = dict(id="1", title="Bug #1") bug2 = dict(id="2", title="Bug #2") bug3 = dict(id="3", title="Bug #3") self.launchpad.bugs = dict(entries=[bug1, bug2, bug3]) bugs = self.launchpad.bugs[1:3] self.assertEqual(2, len(bugs)) self.assertEqual("2", bugs[0].id) self.assertEqual("3", bugs[1].id) def test_slice_collection_with_negative_start(self): """ A C{ValueError} is raised if a negative start value is used when slicing a sample collection set on a L{FakeLaunchpad} instance. """ bug1 = dict(id="1", title="Bug #1") bug2 = dict(id="2", title="Bug #2") self.launchpad.bugs = dict(entries=[bug1, bug2]) self.assertRaises(ValueError, lambda: self.launchpad.bugs[-1:]) self.assertRaises(ValueError, lambda: self.launchpad.bugs[-1:2]) def test_slice_collection_with_negative_stop(self): """ A C{ValueError} is raised if a negative stop value is used when slicing a sample collection set on a L{FakeLaunchpad} instance. """ bug1 = dict(id="1", title="Bug #1") bug2 = dict(id="2", title="Bug #2") self.launchpad.bugs = dict(entries=[bug1, bug2]) self.assertRaises(ValueError, lambda: self.launchpad.bugs[:-1]) self.assertRaises(ValueError, lambda: self.launchpad.bugs[0:-1]) def test_subscript_operator_out_of_range(self): """ An C{IndexError} is raised if an invalid index is used when retrieving data from a sample collection. """ bug1 = dict(id="1", title="Bug #1") self.launchpad.bugs = dict(entries=[bug1]) self.assertRaises(IndexError, lambda: self.launchpad.bugs[2]) def test_replace_property(self): """Values already set on fake resource objects can be replaced.""" self.launchpad.me = dict(name="foo") person = self.launchpad.me self.assertEqual("foo", person.name) person.name = "bar" self.assertEqual("bar", person.name) self.assertEqual("bar", self.launchpad.me.name) def test_replace_method(self): """Methods already set on fake resource objects can be replaced.""" branch1 = dict(name="foo", bzr_identity="lp:~user/project/branch1") branch2 = dict(name="foo", bzr_identity="lp:~user/project/branch2") self.launchpad.branches = dict(getByUniqueName=lambda name: branch1) self.launchpad.branches.getByUniqueName = lambda name: branch2 branch = self.launchpad.branches.getByUniqueName("foo") self.assertEqual("lp:~user/project/branch2", branch.bzr_identity) def test_replace_property_with_invalid_value(self): """Values set on fake resource objects are validated.""" self.launchpad.me = dict(name="foo") person = self.launchpad.me self.assertRaises(IntegrityError, setattr, person, "name", 1) def test_replace_resource(self): """Resources already set on L{FakeLaunchpad} can be replaced.""" self.launchpad.me = dict(name="foo") self.assertEqual("foo", self.launchpad.me.name) self.launchpad.me = dict(name="bar") self.assertEqual("bar", self.launchpad.me.name) def test_add_property(self): """Sample data set on a L{FakeLaunchpad} instance can be added to.""" self.launchpad.me = dict(name="foo") person = self.launchpad.me person.display_name = "Foo" self.assertEqual("foo", person.name) self.assertEqual("Foo", person.display_name) self.assertEqual("foo", self.launchpad.me.name) self.assertEqual("Foo", self.launchpad.me.display_name) def test_add_property_to_empty_object(self): """An empty object can be used when creating sample data.""" self.launchpad.me = dict() self.assertRaises(AttributeError, getattr, self.launchpad.me, "name") self.launchpad.me.name = "foo" self.assertEqual("foo", self.launchpad.me.name) def test_login(self): """ L{FakeLaunchpad.login} ignores all parameters and returns a new instance using the builtin WADL definition. """ launchpad = FakeLaunchpad.login("name", "token", "secret") self.assertTrue(isinstance(launchpad, FakeLaunchpad)) def test_get_token_and_login(self): """ L{FakeLaunchpad.get_token_and_login} ignores all parameters and returns a new instance using the builtin WADL definition. """ launchpad = FakeLaunchpad.get_token_and_login("name") self.assertTrue(isinstance(launchpad, FakeLaunchpad)) def test_login_with(self): """ L{FakeLaunchpad.login_with} ignores all parameters and returns a new instance using the builtin WADL definition. """ launchpad = FakeLaunchpad.login_with("name") self.assertTrue(isinstance(launchpad, FakeLaunchpad)) def test_lp_save(self): """ Sample object have an C{lp_save} method that is a no-op by default. """ self.launchpad.me = dict(name="foo") self.assertTrue(self.launchpad.me.lp_save()) def test_custom_lp_save(self): """A custom C{lp_save} method can be set on a L{FakeResource}.""" self.launchpad.me = dict(name="foo", lp_save=lambda: "custom") self.assertEqual("custom", self.launchpad.me.lp_save()) def test_set_custom_lp_save(self): """ A custom C{lp_save} method can be set on a L{FakeResource} after its been created. """ self.launchpad.me = dict(name="foo") self.launchpad.me.lp_save = lambda: "custom" self.assertEqual("custom", self.launchpad.me.lp_save())