summaryrefslogtreecommitdiffstats
path: root/tests/test_ipalib/test_util.py
blob: 8069d89b8246e93288c9fe6e8b818dae0905bc6f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
# Authors:
#   Jason Gerard DeRose <jderose@redhat.com>
#
# Copyright (C) 2008  Red Hat
# see file 'COPYING' for use and warranty information
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License as
# published by the Free Software Foundation; version 2 only
#
# This program 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 General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA

"""
Test the `ipalib.util` module.
"""

from xmlrpclib import Binary, dumps, loads
import struct
from tests.util import raises
from ipalib import util


# A string that should have bytes 'x\00' through '\xff':
BINARY_BYTES = ''.join(struct.pack('B', d) for d in xrange(256))
assert '\x00' in BINARY_BYTES and '\xff' in BINARY_BYTES
assert type(BINARY_BYTES) is str and len(BINARY_BYTES) == 256

# A UTF-8 encoded str
UTF8_BYTES = '\xd0\x9f\xd0\xb0\xd0\xb2\xd0\xb5\xd0\xbb'

# The same UTF-8 data decoded (a unicode instance)
UNICODE_CHARS = u'\u041f\u0430\u0432\u0435\u043b'
assert UTF8_BYTES.decode('UTF-8') == UNICODE_CHARS
assert UNICODE_CHARS.encode('UTF-8') == UTF8_BYTES
assert UTF8_BYTES != UNICODE_CHARS


def dump_n_load(value):
    (param, method) = loads(
        dumps((value,))
    )
    return param[0]


def round_trip(value):
    return util.xmlrpc_unwrap(
        dump_n_load(util.xmlrpc_wrap(value))
    )


def test_round_trip():
    """
    Test `ipalib.util.xmlrpc_wrap` and `ipalib.util.xmlrpc_unwrap`.

    This tests the two functions together with ``xmlrpclib.dumps()`` and
    ``xmlrpclib.loads()`` in a full encode/dumps/loads/decode round trip.
    """
    # We first test that our assumptions about xmlrpclib module in the Python
    # standard library are correct:
    assert dump_n_load(UTF8_BYTES) == UNICODE_CHARS
    assert dump_n_load(UNICODE_CHARS) == UNICODE_CHARS
    assert dump_n_load(Binary(BINARY_BYTES)).data == BINARY_BYTES
    assert isinstance(dump_n_load(Binary(BINARY_BYTES)), Binary)
    assert type(dump_n_load('hello')) is str
    assert type(dump_n_load(u'hello')) is str

    # Now we test our wrap and unwrap methods in combination with dumps, loads:
    # All str should come back str (because they get wrapped in
    # xmlrpclib.Binary().  All unicode should come back unicode because str
    # explicity get decoded by util.xmlrpc_unwrap() if they weren't already
    # decoded by xmlrpclib.loads().
    assert round_trip(UTF8_BYTES) == UTF8_BYTES
    assert round_trip(UNICODE_CHARS) == UNICODE_CHARS
    assert round_trip(BINARY_BYTES) == BINARY_BYTES
    assert type(round_trip('hello')) is str
    assert type(round_trip(u'hello')) is unicode
    assert round_trip('') == ''
    assert round_trip(u'') == u''
    compound = [UTF8_BYTES, UNICODE_CHARS, BINARY_BYTES,
        dict(utf8=UTF8_BYTES, chars=UNICODE_CHARS, data=BINARY_BYTES)
    ]
    assert round_trip(compound) == tuple(compound)


def test_xmlrpc_wrap():
    """
    Test the `ipalib.util.xmlrpc_wrap` function.
    """
    f = util.xmlrpc_wrap
    assert f([]) == tuple()
    assert f({}) == dict()
    b = f('hello')
    assert isinstance(b, Binary)
    assert b.data == 'hello'
    u = f(u'hello')
    assert type(u) is unicode
    assert u == u'hello'
    value = f([dict(one=False, two=u'hello'), None, 'hello'])


def test_xmlrpc_unwrap():
    """
    Test the `ipalib.util.xmlrpc_unwrap` function.
    """
    f = util.xmlrpc_unwrap
    assert f([]) == tuple()
    assert f({}) == dict()
    value = f(Binary(UTF8_BYTES))
    assert type(value) is str
    assert value == UTF8_BYTES
    assert f(UTF8_BYTES) == UNICODE_CHARS
    assert f(UNICODE_CHARS) == UNICODE_CHARS
    value = f([True, Binary('hello'), dict(one=1, two=UTF8_BYTES, three=None)])
    assert value == (True, 'hello', dict(one=1, two=UNICODE_CHARS, three=None))
    assert type(value[1]) is str
    assert type(value[2]['two']) is unicode


def test_xmlrpc_marshal():
    """
    Test the `ipalib.util.xmlrpc_marshal` function.
    """
    f = util.xmlrpc_marshal
    assert f() == ({},)
    assert f('one', 'two') == ({}, 'one', 'two')
    assert f(one=1, two=2) == (dict(one=1, two=2),)
    assert f('one', 'two', three=3, four=4) == \
        (dict(three=3, four=4), 'one', 'two')


def test_xmlrpc_unmarshal():
    """
    Test the `ipalib.util.xmlrpc_unmarshal` function.
    """
    f = util.xmlrpc_unmarshal
    assert f() == (tuple(), {})
    assert f({}, 'one', 'two') == (('one', 'two'), {})
    assert f(dict(one=1, two=2)) == (tuple(), dict(one=1, two=2))
    assert f(dict(three=3, four=4), 'one', 'two') == \
        (('one', 'two'), dict(three=3, four=4))


def test_make_repr():
    """
    Test the `ipalib.util.make_repr` function.
    """
    f = util.make_repr
    assert f('my') == 'my()'
    assert f('my', True, u'hello') == "my(True, u'hello')"
    assert f('my', one=1, two='two') == "my(one=1, two='two')"
    assert f('my', None, 3, dog='animal', apple='fruit') == \
        "my(None, 3, apple='fruit', dog='animal')"