1#! /usr/bin/env python
2# -*- coding: utf-8 -*-
3# vi:ts=4:et
4
5import pycurl
6import pytest
7import unittest
8
9class ExplicitConstructionCurlObjectTest(unittest.TestCase):
10    def test_close(self):
11        c = pycurl.Curl()
12        c.close()
13
14    def test_close_twice(self):
15        c = pycurl.Curl()
16        c.close()
17        c.close()
18
19    # positional arguments are rejected
20    def test_positional_arguments(self):
21        with pytest.raises(TypeError):
22           pycurl.Curl(1)
23
24    # keyword arguments are rejected
25    def test_keyword_arguments(self):
26        with pytest.raises(TypeError):
27            pycurl.Curl(a=1)
28
29class CurlObjectTest(unittest.TestCase):
30    def setUp(self):
31        self.curl = pycurl.Curl()
32
33    def tearDown(self):
34        self.curl.close()
35
36    def test_set_attribute_curl(self):
37        self.instantiate_and_check(self.check_set_attribute, 'Curl')
38
39    def test_get_attribute_curl(self):
40        self.instantiate_and_check(self.check_get_attribute, 'Curl')
41
42    def test_get_missing_attribute_curl(self):
43        self.instantiate_and_check(self.check_get_missing_attribute, 'Curl')
44
45    def test_delete_attribute_curl(self):
46        self.instantiate_and_check(self.check_delete_attribute, 'Curl')
47
48    def test_delete_missing_attribute_curl(self):
49        self.instantiate_and_check(self.check_delete_missing_attribute, 'Curl')
50
51    def test_set_attribute_multi(self):
52        self.instantiate_and_check(self.check_set_attribute, 'CurlMulti')
53
54    def test_get_attribute_multi(self):
55        self.instantiate_and_check(self.check_get_attribute, 'CurlMulti')
56
57    def test_get_missing_attribute_curl_multi(self):
58        self.instantiate_and_check(self.check_get_missing_attribute, 'CurlMulti')
59
60    def test_delete_attribute_multi(self):
61        self.instantiate_and_check(self.check_delete_attribute, 'CurlMulti')
62
63    def test_delete_missing_attribute_curl_multi(self):
64        self.instantiate_and_check(self.check_delete_missing_attribute, 'CurlMulti')
65
66    def test_set_attribute_share(self):
67        self.instantiate_and_check(self.check_set_attribute, 'CurlShare')
68
69    def test_get_attribute_share(self):
70        self.instantiate_and_check(self.check_get_attribute, 'CurlShare')
71
72    def test_get_missing_attribute_curl_share(self):
73        self.instantiate_and_check(self.check_get_missing_attribute, 'CurlShare')
74
75    def test_delete_attribute_share(self):
76        self.instantiate_and_check(self.check_delete_attribute, 'CurlShare')
77
78    def test_delete_missing_attribute_curl_share(self):
79        self.instantiate_and_check(self.check_delete_missing_attribute, 'CurlShare')
80
81    def instantiate_and_check(self, fn, cls_name):
82        cls = getattr(pycurl, cls_name)
83        instance = cls()
84        try:
85            fn(instance)
86        finally:
87            instance.close()
88
89    def check_set_attribute(self, pycurl_obj):
90        assert not hasattr(pycurl_obj, 'attr')
91        pycurl_obj.attr = 1
92        assert hasattr(pycurl_obj, 'attr')
93
94    def check_get_attribute(self, pycurl_obj):
95        assert not hasattr(pycurl_obj, 'attr')
96        pycurl_obj.attr = 1
97        self.assertEqual(1, pycurl_obj.attr)
98
99    def check_get_missing_attribute(self, pycurl_obj):
100        try:
101            getattr(pycurl_obj, 'doesnotexist')
102            self.fail('Expected an AttributeError exception to be raised')
103        except AttributeError:
104            pass
105
106    def check_delete_attribute(self, pycurl_obj):
107        assert not hasattr(pycurl_obj, 'attr')
108        pycurl_obj.attr = 1
109        self.assertEqual(1, pycurl_obj.attr)
110        assert hasattr(pycurl_obj, 'attr')
111        del pycurl_obj.attr
112        assert not hasattr(pycurl_obj, 'attr')
113
114    def check_delete_missing_attribute(self, pycurl_obj):
115        try:
116            del pycurl_obj.doesnotexist
117            self.fail('Expected an AttributeError exception to be raised')
118        except AttributeError:
119            pass
120
121    def test_modify_attribute_curl(self):
122        self.check_modify_attribute(pycurl.Curl, 'READFUNC_PAUSE')
123
124    def test_modify_attribute_multi(self):
125        self.check_modify_attribute(pycurl.CurlMulti, 'E_MULTI_OK')
126
127    def test_modify_attribute_share(self):
128        self.check_modify_attribute(pycurl.CurlShare, 'SH_SHARE')
129
130    def check_modify_attribute(self, cls, name):
131        obj1 = cls()
132        obj2 = cls()
133        old_value = getattr(obj1, name)
134        self.assertNotEqual('helloworld', old_value)
135        # value should be identical to pycurl global
136        self.assertEqual(old_value, getattr(pycurl, name))
137        setattr(obj1, name, 'helloworld')
138        self.assertEqual('helloworld', getattr(obj1, name))
139
140        # change does not affect other existing objects
141        self.assertEqual(old_value, getattr(obj2, name))
142
143        # change does not affect objects created later
144        obj3 = cls()
145        self.assertEqual(old_value, getattr(obj3, name))
146
147    def test_bogus_attribute_access(self):
148        with pytest.raises(AttributeError, match='trying to obtain.*'):
149           self.curl.foo
150
151    def test_bogus_attribute_delete(self):
152        with pytest.raises(AttributeError, match='trying to delete.*'):
153            del self.curl.foo
154