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 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174
|
from openid import kvform
from openid import oidutil
import unittest
class KVBaseTest(unittest.TestCase):
def shortDescription(self):
return '%s test for %r' % (self.__class__.__name__, self.kvform)
def log(self, message, unused_priority=None):
self.warnings.append(message)
def checkWarnings(self, num_warnings):
self.failUnlessEqual(num_warnings, len(self.warnings), repr(self.warnings))
def setUp(self):
self.warnings = []
self.old_log = oidutil.log
self.log_func = oidutil.log = self.log
self.failUnless(self.log_func is oidutil.log,
(oidutil.log, self.log_func))
def tearDown(self):
oidutil.log = self.old_log
class KVDictTest(KVBaseTest):
def __init__(self, kv, dct, warnings):
unittest.TestCase.__init__(self)
self.kvform = kv
self.dict = dct
self.expected_warnings = warnings
def runTest(self):
# Convert KVForm to dict
d = kvform.kvToDict(self.kvform)
# make sure it parses to expected dict
self.failUnlessEqual(self.dict, d)
# Check to make sure we got the expected number of warnings
self.checkWarnings(self.expected_warnings)
# Convert back to KVForm and round-trip back to dict to make
# sure that *** dict -> kv -> dict is identity. ***
kv = kvform.dictToKV(d)
d2 = kvform.kvToDict(kv)
self.failUnlessEqual(d, d2)
class KVSeqTest(KVBaseTest):
def __init__(self, seq, kv, expected_warnings):
unittest.TestCase.__init__(self)
self.kvform = kv
self.seq = seq
self.expected_warnings = expected_warnings
def cleanSeq(self, seq):
"""Create a new sequence by stripping whitespace from start
and end of each value of each pair"""
clean = []
for k, v in self.seq:
if type(k) is str:
k = k.decode('utf8')
if type(v) is str:
v = v.decode('utf8')
clean.append((k.strip(), v.strip()))
return clean
def runTest(self):
# seq serializes to expected kvform
actual = kvform.seqToKV(self.seq)
self.failUnlessEqual(self.kvform, actual)
self.failUnless(type(actual) is str)
# Parse back to sequence. Expected to be unchanged, except
# stripping whitespace from start and end of values
# (i. e. ordering, case, and internal whitespace is preserved)
seq = kvform.kvToSeq(actual)
clean_seq = self.cleanSeq(seq)
self.failUnlessEqual(seq, clean_seq)
self.checkWarnings(self.expected_warnings)
kvdict_cases = [
# (kvform, parsed dictionary, expected warnings)
('', {}, 0),
('college:harvey mudd\n', {'college':'harvey mudd'}, 0),
('city:claremont\nstate:CA\n',
{'city':'claremont', 'state':'CA'}, 0),
('is_valid:true\ninvalidate_handle:{HMAC-SHA1:2398410938412093}\n',
{'is_valid':'true',
'invalidate_handle':'{HMAC-SHA1:2398410938412093}'}, 0),
# Warnings from lines with no colon:
('x\n', {}, 1),
('x\nx\n', {}, 2),
('East is least\n', {}, 1),
# But not from blank lines (because LJ generates them)
('x\n\n', {}, 1),
# Warning from empty key
(':\n', {'':''}, 1),
(':missing key\n', {'':'missing key'}, 1),
# Warnings from leading or trailing whitespace in key or value
(' street:foothill blvd\n', {'street':'foothill blvd'}, 1),
('major: computer science\n', {'major':'computer science'}, 1),
(' dorm : east \n', {'dorm':'east'}, 2),
# Warnings from missing trailing newline
('e^(i*pi)+1:0', {'e^(i*pi)+1':'0'}, 1),
('east:west\nnorth:south', {'east':'west', 'north':'south'}, 1),
]
kvseq_cases = [
([], '', 0),
# Make sure that we handle non-ascii characters (also wider than 8 bits)
([(u'\u03bbx', u'x')], '\xce\xbbx:x\n', 0),
# If it's a UTF-8 str, make sure that it's equivalent to the same
# string, decoded.
([('\xce\xbbx', 'x')], '\xce\xbbx:x\n', 0),
([('openid', 'useful'), ('a', 'b')], 'openid:useful\na:b\n', 0),
# Warnings about leading whitespace
([(' openid', 'useful'), ('a', 'b')], ' openid:useful\na:b\n', 2),
# Warnings about leading and trailing whitespace
([(' openid ', ' useful '),
(' a ', ' b ')], ' openid : useful \n a : b \n', 8),
# warnings about leading and trailing whitespace, but not about
# internal whitespace.
([(' open id ', ' use ful '),
(' a ', ' b ')], ' open id : use ful \n a : b \n', 8),
([(u'foo', 'bar')], 'foo:bar\n', 0),
]
kvexc_cases = [
[('openid', 'use\nful')],
[('open\nid', 'useful')],
[('open\nid', 'use\nful')],
[('open:id', 'useful')],
[('foo', 'bar'), ('ba\n d', 'seed')],
[('foo', 'bar'), ('bad:', 'seed')],
]
class KVExcTest(unittest.TestCase):
def __init__(self, seq):
unittest.TestCase.__init__(self)
self.seq = seq
def shortDescription(self):
return 'KVExcTest for %r' % (self.seq,)
def runTest(self):
self.failUnlessRaises(ValueError, kvform.seqToKV, self.seq)
class GeneralTest(KVBaseTest):
kvform = '<None>'
def test_convert(self):
result = kvform.seqToKV([(1,1)])
self.failUnlessEqual(result, '1:1\n')
self.checkWarnings(2)
def pyUnitTests():
tests = [KVDictTest(*case) for case in kvdict_cases]
tests.extend([KVSeqTest(*case) for case in kvseq_cases])
tests.extend([KVExcTest(case) for case in kvexc_cases])
tests.append(unittest.defaultTestLoader.loadTestsFromTestCase(GeneralTest))
return unittest.TestSuite(tests)
|