source: trunk/tests/test_classic_functions.py @ 774

Last change on this file since 774 was 774, checked in by cito, 4 years ago

Add support for JSON and JSONB to pg and pgdb

This adds all necessary functions to make PyGreSQL automatically
convert between JSON columns and Python objects representing them.

The documentation has also been updated, see there for the details.

Also, tuples automatically bind to ROW expressions in pgdb now.

  • Property svn:executable set to *
  • Property svn:keywords set to Id
File size: 8.5 KB
Line 
1#! /usr/bin/python
2# -*- coding: utf-8 -*-
3
4"""Test the classic PyGreSQL interface.
5
6Sub-tests for the module functions and constants.
7
8Contributed by Christoph Zwerschke.
9
10These tests do not need a database to test against.
11"""
12
13try:
14    import unittest2 as unittest  # for Python < 2.7
15except ImportError:
16    import unittest
17
18import json
19import re
20
21import pg  # the module under test
22
23try:
24    long
25except NameError:  # Python >= 3.0
26    long = int
27
28try:
29    unicode
30except NameError:  # Python >= 3.0
31    unicode = str
32
33
34class TestHasConnect(unittest.TestCase):
35    """Test existence of basic pg module functions."""
36
37    def testhasPgError(self):
38        self.assertTrue(issubclass(pg.Error, Exception))
39
40    def testhasPgWarning(self):
41        self.assertTrue(issubclass(pg.Warning, Exception))
42
43    def testhasPgInterfaceError(self):
44        self.assertTrue(issubclass(pg.InterfaceError, pg.Error))
45
46    def testhasPgDatabaseError(self):
47        self.assertTrue(issubclass(pg.DatabaseError, pg.Error))
48
49    def testhasPgInternalError(self):
50        self.assertTrue(issubclass(pg.InternalError, pg.DatabaseError))
51
52    def testhasPgOperationalError(self):
53        self.assertTrue(issubclass(pg.OperationalError, pg.DatabaseError))
54
55    def testhasPgProgrammingError(self):
56        self.assertTrue(issubclass(pg.ProgrammingError, pg.DatabaseError))
57
58    def testhasPgIntegrityError(self):
59        self.assertTrue(issubclass(pg.IntegrityError, pg.DatabaseError))
60
61    def testhasPgDataError(self):
62        self.assertTrue(issubclass(pg.DataError, pg.DatabaseError))
63
64    def testhasPgNotSupportedError(self):
65        self.assertTrue(issubclass(pg.NotSupportedError, pg.DatabaseError))
66
67    def testhasConnect(self):
68        self.assertTrue(callable(pg.connect))
69
70    def testhasEscapeString(self):
71        self.assertTrue(callable(pg.escape_string))
72
73    def testhasEscapeBytea(self):
74        self.assertTrue(callable(pg.escape_bytea))
75
76    def testhasUnescapeBytea(self):
77        self.assertTrue(callable(pg.unescape_bytea))
78
79    def testDefHost(self):
80        d0 = pg.get_defhost()
81        d1 = 'pgtesthost'
82        pg.set_defhost(d1)
83        self.assertEqual(pg.get_defhost(), d1)
84        pg.set_defhost(d0)
85        self.assertEqual(pg.get_defhost(), d0)
86
87    def testDefPort(self):
88        d0 = pg.get_defport()
89        d1 = 1234
90        pg.set_defport(d1)
91        self.assertEqual(pg.get_defport(), d1)
92        if d0 is None:
93            d0 = -1
94        pg.set_defport(d0)
95        if d0 == -1:
96            d0 = None
97        self.assertEqual(pg.get_defport(), d0)
98
99    def testDefOpt(self):
100        d0 = pg.get_defopt()
101        d1 = '-h pgtesthost -p 1234'
102        pg.set_defopt(d1)
103        self.assertEqual(pg.get_defopt(), d1)
104        pg.set_defopt(d0)
105        self.assertEqual(pg.get_defopt(), d0)
106
107    def testDefBase(self):
108        d0 = pg.get_defbase()
109        d1 = 'pgtestdb'
110        pg.set_defbase(d1)
111        self.assertEqual(pg.get_defbase(), d1)
112        pg.set_defbase(d0)
113        self.assertEqual(pg.get_defbase(), d0)
114
115
116class TestEscapeFunctions(unittest.TestCase):
117    """Test pg escape and unescape functions.
118
119    The libpq interface memorizes some parameters of the last opened
120    connection that influence the result of these functions.
121    Therefore we cannot do rigid tests of these functions here.
122    We leave this for the test module that runs with a database.
123
124    """
125
126    def testEscapeString(self):
127        f = pg.escape_string
128        r = f(b'plain')
129        self.assertIsInstance(r, bytes)
130        self.assertEqual(r, b'plain')
131        r = f(u'plain')
132        self.assertIsInstance(r, unicode)
133        self.assertEqual(r, u'plain')
134        r = f("that's cheese")
135        self.assertIsInstance(r, str)
136        self.assertEqual(r, "that''s cheese")
137
138    def testEscapeBytea(self):
139        f = pg.escape_bytea
140        r = f(b'plain')
141        self.assertIsInstance(r, bytes)
142        self.assertEqual(r, b'plain')
143        r = f(u'plain')
144        self.assertIsInstance(r, unicode)
145        self.assertEqual(r, u'plain')
146        r = f("that's cheese")
147        self.assertIsInstance(r, str)
148        self.assertEqual(r, "that''s cheese")
149
150    def testUnescapeBytea(self):
151        f = pg.unescape_bytea
152        r = f(b'plain')
153        self.assertIsInstance(r, bytes)
154        self.assertEqual(r, b'plain')
155        r = f(u'plain')
156        self.assertIsInstance(r, bytes)
157        self.assertEqual(r, b'plain')
158        r = f(b"das is' k\\303\\244se")
159        self.assertIsInstance(r, bytes)
160        self.assertEqual(r, u"das is' kÀse".encode('utf-8'))
161        r = f(u"das is' k\\303\\244se")
162        self.assertIsInstance(r, bytes)
163        self.assertEqual(r, u"das is' kÀse".encode('utf-8'))
164        r = f(b'O\\000ps\\377!')
165        self.assertEqual(r, b'O\x00ps\xff!')
166        r = f(u'O\\000ps\\377!')
167        self.assertEqual(r, b'O\x00ps\xff!')
168
169
170class TestConfigFunctions(unittest.TestCase):
171    """Test the functions for changing default settings.
172
173    The effect of most of these cannot be tested here, because that
174    needs a database connection.  So we merely test their existence here.
175
176    """
177
178    def testGetDecimalPoint(self):
179        r = pg.get_decimal_point()
180        self.assertIsInstance(r, str)
181        self.assertEqual(r, '.')
182
183    def testSetDecimalPoint(self):
184        point = pg.get_decimal_point()
185        try:
186            pg.set_decimal_point('*')
187            r = pg.get_decimal_point()
188            self.assertIsInstance(r, str)
189            self.assertEqual(r, '*')
190        finally:
191            pg.set_decimal_point(point)
192        r = pg.get_decimal_point()
193        self.assertIsInstance(r, str)
194        self.assertEqual(r, point)
195
196    def testGetDecimal(self):
197        r = pg.get_decimal()
198        self.assertIs(r, pg.Decimal)
199
200    def testSetDecimal(self):
201        decimal_class = pg.Decimal
202        try:
203            pg.set_decimal(int)
204            r = pg.get_decimal()
205            self.assertIs(r, int)
206        finally:
207            pg.set_decimal(decimal_class)
208        r = pg.get_decimal()
209        self.assertIs(r, decimal_class)
210
211    def testGetBool(self):
212        r = pg.get_bool()
213        self.assertIsInstance(r, bool)
214        self.assertIs(r, False)
215
216    def testSetBool(self):
217        use_bool = pg.get_bool()
218        try:
219            pg.set_bool(True)
220            r = pg.get_bool()
221            pg.set_bool(use_bool)
222            self.assertIsInstance(r, bool)
223            self.assertIs(r, True)
224            pg.set_bool(False)
225            r = pg.get_bool()
226            self.assertIsInstance(r, bool)
227            self.assertIs(r, False)
228        finally:
229            pg.set_bool(use_bool)
230        r = pg.get_bool()
231        self.assertIsInstance(r, bool)
232        self.assertIs(r, use_bool)
233
234    def testGetNamedresult(self):
235        r = pg.get_namedresult()
236        self.assertTrue(callable(r))
237        self.assertIs(r, pg._namedresult)
238
239    def testSetNamedresult(self):
240        namedresult = pg.get_namedresult()
241        try:
242            pg.set_namedresult(None)
243            r = pg.get_namedresult()
244            self.assertIsNone(r)
245            f = lambda q: q.getresult()
246            pg.set_namedresult(f)
247            r = pg.get_namedresult()
248            self.assertIs(r, f)
249            self.assertRaises(TypeError, pg.set_namedresult, 'invalid')
250        finally:
251            pg.set_namedresult(namedresult)
252        r = pg.get_namedresult()
253        self.assertIs(r, namedresult)
254
255    def testGetJsondecode(self):
256        r = pg.get_jsondecode()
257        self.assertTrue(callable(r))
258        self.assertIs(r, json.loads)
259
260    def testSetJsondecode(self):
261        jsondecode = pg.get_jsondecode()
262        try:
263            pg.set_jsondecode(None)
264            r = pg.get_jsondecode()
265            self.assertIsNone(r)
266            pg.set_jsondecode(str)
267            r = pg.get_jsondecode()
268            self.assertIs(r, str)
269            self.assertRaises(TypeError, pg.set_jsondecode, 'invalid')
270        finally:
271            pg.set_jsondecode(jsondecode)
272        r = pg.get_jsondecode()
273        self.assertIs(r, jsondecode)
274
275
276class TestModuleConstants(unittest.TestCase):
277    """Test the existence of the documented module constants."""
278
279    def testVersion(self):
280        v = pg.version
281        self.assertIsInstance(v, str)
282        # make sure the version conforms to PEP440
283        re_version = r"""^
284            (\d[\.\d]*(?<= \d))
285            ((?:[abc]|rc)\d+)?
286            (?:(\.post\d+))?
287            (?:(\.dev\d+))?
288            (?:(\+(?![.])[a-zA-Z0-9\.]*[a-zA-Z0-9]))?
289            $"""
290        match = re.match(re_version, v, re.X)
291        self.assertIsNotNone(match)
292
293
294if __name__ == '__main__':
295    unittest.main()
Note: See TracBrowser for help on using the repository browser.