Commits

Gora Khargosh committed 32dc738

Moving tests into package folder. Helps with integration tests.

Signed-off-by: Gora Khargosh <gora.khargosh@gmail.com>

  • Participants
  • Parent commits 31ba593

Comments (0)

Files changed (50)

File mom/tests/__init__.py

Empty file added.

File mom/tests/constants.py

+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
+from __future__ import absolute_import
+
+from mom._compat import have_python3
+
+if have_python3:
+    from tests.py3kconstants import \
+        unicode_string, unicode_string2, foo, ufoo, \
+        json_foo, json_ufoo, json_unicode_value, unicode_value, x_byte, \
+        utf8_bytes, utf8_bytes2, latin1_bytes
+else:
+    from tests.py2kconstants import \
+        unicode_string, unicode_string2, foo, ufoo, \
+        json_foo, json_ufoo, json_unicode_value, unicode_value, x_byte, \
+        utf8_bytes, utf8_bytes2, latin1_bytes
+
+unicode_string = unicode_string
+unicode_string2 = unicode_string2
+foo = foo
+ufoo = ufoo
+json_foo = json_foo
+json_ufoo = json_ufoo
+json_unicode_value = json_unicode_value
+unicode_value = unicode_value
+x_byte = x_byte
+utf8_bytes = utf8_bytes
+utf8_bytes2 = utf8_bytes2
+latin1_bytes = latin1_bytes

File mom/tests/prime_sieves_speed_test.sh

+#!/bin/sh
+
+PYTHON=python2.7
+
+$PYTHON -mtimeit -s'import primes' 'primes.sieveOfEratosthenes(1000000)'
+$PYTHON -mtimeit -s'import primes' 'primes.ambi_sieve(1000000)'
+$PYTHON -mtimeit -s'import primes' 'primes.ambi_sieve_plain(1000000)'
+$PYTHON -mtimeit -s'import primes' 'primes.sundaram3(1000000)'
+$PYTHON -mtimeit -s'import primes' 'primes.sieve_wheel_30(1000000)'
+$PYTHON -mtimeit -s'import primes' 'primes.primesfrom3to(1000000)'
+$PYTHON -mtimeit -s'import primes' 'primes.primesfrom2to(1000000)'
+$PYTHON -mtimeit -s'import primes' 'primes.rwh_primes(1000000)'
+$PYTHON -mtimeit -s'import primes' 'primes.rwh_primes1(1000000)'
+$PYTHON -mtimeit -s'import primes' 'primes.rwh_primes2(1000000)'
+$PYTHON -mtimeit -s'import primes' 'primes.get_primes_erat(1000000)'
+$PYTHON -mtimeit -s'import primes' 'primes.make_prime_sieve(1000000)'
+$PYTHON -mtimeit -s'import primes' 'primes.primes_upto2_gen3(1000000)'

File mom/tests/primes.py

+#!/usr/bin/env python
+#import psyco; psyco.full()
+from math import sqrt, ceil
+import numpy as np
+
+import itertools
+
+def make_prime_sieve(size):
+    """
+    Pre-calculate a sieve of the ~100 primes < 1000.
+
+    :param size:
+        Count
+    :returns:
+        Prime sieve.
+    """
+    sieve = range(size)
+    for count in range(2, int(sqrt(size))):
+        if not sieve[count]:
+            continue
+        x = sieve[count] * 2
+        while x < len(sieve):
+            sieve[x] = 0
+            x += sieve[count]
+    sieve = [x for x in sieve[2:] if x]
+    return sieve
+
+def erat2():
+    # Cookbook
+    D = {}
+    yield 2
+    for q in itertools.islice(itertools.count(3), 0, None, 2):
+        p = D.pop(q, None)
+        if p is None:
+            D[q*q] = q
+            yield q
+        else:
+            x = p + q
+            while x in D or not (x&1):
+                x += p
+            D[x] = p
+
+def get_primes_erat(n):
+  return list(itertools.takewhile(lambda p: p<n, erat2()))
+
+def rwh_primes(n):
+    # http://stackoverflow.com/questions/2068372/fastest-way-to-list-all-primes-below-n-in-python/3035188#3035188
+    """ Returns  a list of primes < n """
+    sieve = [True] * n
+    for i in xrange(3,int(n**0.5)+1,2):
+        if sieve[i]:
+            sieve[i*i::2*i]=[False]*((n-i*i-1)/(2*i)+1)
+    return [2] + [i for i in xrange(3,n,2) if sieve[i]]
+
+def rwh_primes1(n):
+    # http://stackoverflow.com/questions/2068372/fastest-way-to-list-all-primes-below-n-in-python/3035188#3035188
+    """ Returns  a list of primes < n """
+    sieve = [True] * (n/2)
+    for i in xrange(3,int(n**0.5)+1,2):
+        if sieve[i/2]:
+            sieve[i*i/2::i] = [False] * ((n-i*i-1)/(2*i)+1)
+    return [2] + [2*i+1 for i in xrange(1,n/2) if sieve[i]]
+
+def rwh_primes2(n):
+    # http://stackoverflow.com/questions/2068372/fastest-way-to-list-all-primes-below-n-in-python/3035188#3035188
+    """ Input n>=6, Returns a list of primes, 2 <= p < n """
+    correction = (n%6>1)
+    n = {0:n,1:n-1,2:n+4,3:n+3,4:n+2,5:n+1}[n%6]
+    sieve = [True] * (n/3)
+    sieve[0] = False
+    for i in xrange(int(n**0.5)/3+1):
+      if sieve[i]:
+        k=3*i+1|1
+        sieve[      ((k*k)/3)      ::2*k]=[False]*((n/6-(k*k)/6-1)/k+1)
+        sieve[(k*k+4*k-2*k*(i&1))/3::2*k]=[False]*((n/6-(k*k+4*k-2*k*(i&1))/6-1)/k+1)
+    return [2,3] + [3*i+1|1 for i in xrange(1,n/3-correction) if sieve[i]]
+
+def sieve_wheel_30(N):
+    # http://zerovolt.com/?p=88
+    ''' Returns a list of primes <= N using wheel criterion 2*3*5 = 30
+
+Copyright 2009 by zerovolt.com
+This code is free for non-commercial purposes, in which case you can just leave this comment as a credit for my work.
+If you need this code for commercial purposes, please contact me by sending an email to: info [at] zerovolt [dot] com.'''
+    __smallp = ( 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59,
+    61, 67, 71, 73, 79, 83, 89, 97, 101, 103, 107, 109, 113, 127, 131, 137, 139,
+    149, 151, 157, 163, 167, 173, 179, 181, 191, 193, 197, 199, 211, 223, 227,
+    229, 233, 239, 241, 251, 257, 263, 269, 271, 277, 281, 283, 293, 307, 311,
+    313, 317, 331, 337, 347, 349, 353, 359, 367, 373, 379, 383, 389, 397, 401,
+    409, 419, 421, 431, 433, 439, 443, 449, 457, 461, 463, 467, 479, 487, 491,
+    499, 503, 509, 521, 523, 541, 547, 557, 563, 569, 571, 577, 587, 593, 599,
+    601, 607, 613, 617, 619, 631, 641, 643, 647, 653, 659, 661, 673, 677, 683,
+    691, 701, 709, 719, 727, 733, 739, 743, 751, 757, 761, 769, 773, 787, 797,
+    809, 811, 821, 823, 827, 829, 839, 853, 857, 859, 863, 877, 881, 883, 887,
+    907, 911, 919, 929, 937, 941, 947, 953, 967, 971, 977, 983, 991, 997)
+
+    wheel = (2, 3, 5)
+    const = 30
+    if N < 2:
+        return []
+    if N <= const:
+        pos = 0
+        while __smallp[pos] <= N:
+            pos += 1
+        return list(__smallp[:pos])
+    # make the offsets list
+    offsets = (7, 11, 13, 17, 19, 23, 29, 1)
+    # prepare the list
+    p = [2, 3, 5]
+    dim = 2 + N // const
+    tk1  = [True] * dim
+    tk7  = [True] * dim
+    tk11 = [True] * dim
+    tk13 = [True] * dim
+    tk17 = [True] * dim
+    tk19 = [True] * dim
+    tk23 = [True] * dim
+    tk29 = [True] * dim
+    tk1[0] = False
+    # help dictionary d
+    # d[a , b] = c  ==> if I want to find the smallest useful multiple of (30*pos)+a
+    # on tkc, then I need the index given by the product of [(30*pos)+a][(30*pos)+b]
+    # in general. If b < a, I need [(30*pos)+a][(30*(pos+1))+b]
+    d = {}
+    for x in offsets:
+        for y in offsets:
+            res = (x*y) % const
+            if res in offsets:
+                d[(x, res)] = y
+    # another help dictionary: gives tkx calling tmptk[x]
+    tmptk = {1:tk1, 7:tk7, 11:tk11, 13:tk13, 17:tk17, 19:tk19, 23:tk23, 29:tk29}
+    pos, prime, lastadded, stop = 0, 0, 0, int(ceil(sqrt(N)))
+    # inner functions definition
+    def del_mult(tk, start, step):
+        for k in xrange(start, len(tk), step):
+            tk[k] = False
+    # end of inner functions definition
+    cpos = const * pos
+    while prime < stop:
+        # 30k + 7
+        if tk7[pos]:
+            prime = cpos + 7
+            p.append(prime)
+            lastadded = 7
+            for off in offsets:
+                tmp = d[(7, off)]
+                start = (pos + prime) if off == 7 else (prime * (const * (pos + 1 if tmp < 7 else 0) + tmp) )//const
+                del_mult(tmptk[off], start, prime)
+        # 30k + 11
+        if tk11[pos]:
+            prime = cpos + 11
+            p.append(prime)
+            lastadded = 11
+            for off in offsets:
+                tmp = d[(11, off)]
+                start = (pos + prime) if off == 11 else (prime * (const * (pos + 1 if tmp < 11 else 0) + tmp) )//const
+                del_mult(tmptk[off], start, prime)
+        # 30k + 13
+        if tk13[pos]:
+            prime = cpos + 13
+            p.append(prime)
+            lastadded = 13
+            for off in offsets:
+                tmp = d[(13, off)]
+                start = (pos + prime) if off == 13 else (prime * (const * (pos + 1 if tmp < 13 else 0) + tmp) )//const
+                del_mult(tmptk[off], start, prime)
+        # 30k + 17
+        if tk17[pos]:
+            prime = cpos + 17
+            p.append(prime)
+            lastadded = 17
+            for off in offsets:
+                tmp = d[(17, off)]
+                start = (pos + prime) if off == 17 else (prime * (const * (pos + 1 if tmp < 17 else 0) + tmp) )//const
+                del_mult(tmptk[off], start, prime)
+        # 30k + 19
+        if tk19[pos]:
+            prime = cpos + 19
+            p.append(prime)
+            lastadded = 19
+            for off in offsets:
+                tmp = d[(19, off)]
+                start = (pos + prime) if off == 19 else (prime * (const * (pos + 1 if tmp < 19 else 0) + tmp) )//const
+                del_mult(tmptk[off], start, prime)
+        # 30k + 23
+        if tk23[pos]:
+            prime = cpos + 23
+            p.append(prime)
+            lastadded = 23
+            for off in offsets:
+                tmp = d[(23, off)]
+                start = (pos + prime) if off == 23 else (prime * (const * (pos + 1 if tmp < 23 else 0) + tmp) )//const
+                del_mult(tmptk[off], start, prime)
+        # 30k + 29
+        if tk29[pos]:
+            prime = cpos + 29
+            p.append(prime)
+            lastadded = 29
+            for off in offsets:
+                tmp = d[(29, off)]
+                start = (pos + prime) if off == 29 else (prime * (const * (pos + 1 if tmp < 29 else 0) + tmp) )//const
+                del_mult(tmptk[off], start, prime)
+        # now we go back to top tk1, so we need to increase pos by 1
+        pos += 1
+        cpos = const * pos
+        # 30k + 1
+        if tk1[pos]:
+            prime = cpos + 1
+            p.append(prime)
+            lastadded = 1
+            for off in offsets:
+                tmp = d[(1, off)]
+                start = (pos + prime) if off == 1 else (prime * (const * pos + tmp) )//const
+                del_mult(tmptk[off], start, prime)
+    # time to add remaining primes
+    # if lastadded == 1, remove last element and start adding them from tk1
+    # this way we don't need an "if" within the last while
+    if lastadded == 1:
+        p.pop()
+    # now complete for every other possible prime
+    while pos < len(tk1):
+        cpos = const * pos
+        if tk1[pos]: p.append(cpos + 1)
+        if tk7[pos]: p.append(cpos + 7)
+        if tk11[pos]: p.append(cpos + 11)
+        if tk13[pos]: p.append(cpos + 13)
+        if tk17[pos]: p.append(cpos + 17)
+        if tk19[pos]: p.append(cpos + 19)
+        if tk23[pos]: p.append(cpos + 23)
+        if tk29[pos]: p.append(cpos + 29)
+        pos += 1
+    # remove exceeding if present
+    pos = len(p) - 1
+    while p[pos] > N:
+        pos -= 1
+    if pos < len(p) - 1:
+        del p[pos+1:]
+    # return p list
+    return p
+
+def sieveOfEratosthenes(n):
+    """sieveOfEratosthenes(n): return the list of the primes < n."""
+    # Code from: <dickinsm@gmail.com>, Nov 30 2006
+    # http://groups.google.com/group/comp.lang.python/msg/f1f10ced88c68c2d
+    if n <= 2:
+        return []
+    sieve = range(3, n, 2)
+    top = len(sieve)
+    for si in sieve:
+        if si:
+            bottom = (si*si - 3) // 2
+            if bottom >= top:
+                break
+            sieve[bottom::si] = [0] * -((bottom - top) // si)
+    return [2] + [el for el in sieve if el]
+
+def sieveOfAtkin(end):
+    """sieveOfAtkin(end): return a list of all the prime numbers <end
+    using the Sieve of Atkin."""
+    # Code by Steve Krenzel, <Sgk284@gmail.com>, improved
+    # Code: http://krenzel.info/?p=83
+    # Info: http://en.wikipedia.org/wiki/Sieve_of_Atkin
+    assert end > 0
+    lng = ((end-1) // 2)
+    sieve = [False] * (lng + 1)
+
+    x_max, x2, xd = int(sqrt((end-1)/4.0)), 0, 4
+    for xd in xrange(4, 8*x_max + 2, 8):
+        x2 += xd
+        y_max = int(sqrt(end-x2))
+        n, n_diff = x2 + y_max*y_max, (y_max << 1) - 1
+        if not (n & 1):
+            n -= n_diff
+            n_diff -= 2
+        for d in xrange((n_diff - 1) << 1, -1, -8):
+            m = n % 12
+            if m == 1 or m == 5:
+                m = n >> 1
+                sieve[m] = not sieve[m]
+            n -= d
+
+    x_max, x2, xd = int(sqrt((end-1) / 3.0)), 0, 3
+    for xd in xrange(3, 6 * x_max + 2, 6):
+        x2 += xd
+        y_max = int(sqrt(end-x2))
+        n, n_diff = x2 + y_max*y_max, (y_max << 1) - 1
+        if not(n & 1):
+            n -= n_diff
+            n_diff -= 2
+        for d in xrange((n_diff - 1) << 1, -1, -8):
+            if n % 12 == 7:
+                m = n >> 1
+                sieve[m] = not sieve[m]
+            n -= d
+
+    x_max, y_min, x2, xd = int((2 + sqrt(4-8*(1-end)))/4), -1, 0, 3
+    for x in xrange(1, x_max + 1):
+        x2 += xd
+        xd += 6
+        if x2 >= end: y_min = (((int(ceil(sqrt(x2 - end))) - 1) << 1) - 2) << 1
+        n, n_diff = ((x*x + x) << 1) - 1, (((x-1) << 1) - 2) << 1
+        for d in xrange(n_diff, y_min, -8):
+            if n % 12 == 11:
+                m = n >> 1
+                sieve[m] = not sieve[m]
+            n += d
+
+    primes = [2, 3]
+    if end <= 3:
+        return primes[:max(0,end-2)]
+
+    for n in xrange(5 >> 1, (int(sqrt(end))+1) >> 1):
+        if sieve[n]:
+            primes.append((n << 1) + 1)
+            aux = (n << 1) + 1
+            aux *= aux
+            for k in xrange(aux, end, 2 * aux):
+                sieve[k >> 1] = False
+
+    s  = int(sqrt(end)) + 1
+    if s  % 2 == 0:
+        s += 1
+    primes.extend([i for i in xrange(s, end, 2) if sieve[i >> 1]])
+
+    return primes
+
+def ambi_sieve_plain(n):
+    s = range(3, n, 2)
+    for m in xrange(3, int(n**0.5)+1, 2):
+        if s[(m-3)/2]:
+            for t in xrange((m*m-3)/2,(n>>1)-1,m):
+                s[t]=0
+    return [2]+[t for t in s if t>0]
+
+def sundaram3(max_n):
+    # http://stackoverflow.com/questions/2068372/fastest-way-to-list-all-primes-below-n-in-python/2073279#2073279
+    numbers = range(3, max_n+1, 2)
+    half = (max_n)//2
+    initial = 4
+
+    for step in xrange(3, max_n+1, 2):
+        for i in xrange(initial, half, step):
+            numbers[i-1] = 0
+        initial += 2*(step+1)
+
+        if initial > half:
+            return [2] + filter(None, numbers)
+
+################################################################################
+# Using Numpy:
+def ambi_sieve(n):
+    # http://tommih.blogspot.com/2009/04/fast-prime-number-generator.html
+    s = np.arange(3, n, 2)
+    for m in xrange(3, int(n ** 0.5)+1, 2):
+        if s[(m-3)/2]:
+            s[(m*m-3)/2::m]=0
+    return np.r_[2, s[s>0]]
+
+def primesfrom3to(n):
+    # http://stackoverflow.com/questions/2068372/fastest-way-to-list-all-primes-below-n-in-python/3035188#3035188
+    """ Returns a array of primes, p < n """
+    assert n>=2
+    sieve = np.ones(n/2, dtype=np.bool)
+    for i in xrange(3,int(n**0.5)+1,2):
+        if sieve[i/2]:
+            sieve[i*i/2::i] = False
+    return np.r_[2, 2*np.nonzero(sieve)[0][1::]+1]
+
+def primesfrom2to(n):
+    # http://stackoverflow.com/questions/2068372/fastest-way-to-list-all-primes-below-n-in-python/3035188#3035188
+    """ Input n>=6, Returns a array of primes, 2 <= p < n """
+    sieve = np.ones(n/3 + (n%6==2), dtype=np.bool)
+    sieve[0] = False
+    for i in xrange(int(n**0.5)/3+1):
+        if sieve[i]:
+            k=3*i+1|1
+            sieve[      ((k*k)/3)      ::2*k] = False
+            sieve[(k*k+4*k-2*k*(i&1))/3::2*k] = False
+    return np.r_[2,3,((3*np.nonzero(sieve)[0]+1)|1)]
+
+def primes_upto2_gen3(limit):
+    """Generate prime numbers less than limit.
+
+    Use Sieve of Eratosthenes. Assume limit > 2
+    """
+    yield 2
+    is_prime = np.ones(limit, dtype=np.bool)
+    for n in xrange(3, int(limit**.5)+1, 2):
+        if is_prime[n]:
+            yield n
+            is_prime[n*n::2*n] = False
+    for n in xrange(n+2, limit, 2):
+        if is_prime[n]:
+            yield n
+
+
+if __name__=='__main__':
+    import itertools
+    import sys
+
+    def test(f1,f2,num):
+        print('Testing {f1} and {f2} return same results'.format(
+            f1=f1.func_name,
+            f2=f2.func_name))
+        if not all([a==b for a,b in itertools.izip_longest(f1(num),f2(num))]):
+            sys.exit("Error: %s(%s) != %s(%s)"%(f1.func_name,num,f2.func_name,num))
+
+    n=1000000
+    test(sieveOfAtkin,sieveOfEratosthenes,n)
+    test(sieveOfAtkin,ambi_sieve,n)
+    test(sieveOfAtkin,ambi_sieve_plain,n)
+    test(sieveOfAtkin,sundaram3,n)
+    test(sieveOfAtkin,sieve_wheel_30,n)
+    test(sieveOfAtkin,primesfrom3to,n)
+    test(sieveOfAtkin,primesfrom2to,n)
+    test(sieveOfAtkin,rwh_primes,n)
+    test(sieveOfAtkin,rwh_primes1,n)
+    test(sieveOfAtkin,rwh_primes2,n)
+    test(sieveOfAtkin,get_primes_erat,n)
+    test(sieveOfAtkin,make_prime_sieve,n)
+    test(sieveOfAtkin,primes_upto2_gen3,n)

File mom/tests/py2kconstants.py

+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
+unicode_string = u'\u00ae'
+unicode_string2 = u'深入 Python'
+foo = 'foo'
+ufoo = u'foo'
+json_foo = '"foo"'
+json_ufoo = u'"foo"'
+json_unicode_value = u'"\u00e9"'
+unicode_value = u'\u00e9'
+x_byte = "\xe9"
+utf8_bytes = '\xc2\xae'
+utf8_bytes2 = '\xe6\xb7\xb1\xe5\x85\xa5 Python'
+latin1_bytes = "\xe9"

File mom/tests/py3kconstants.py

+#!/usr/bin/env python3
+# -*- coding: utf-8 -*-
+
+unicode_string = '\u00ae'
+unicode_string2 = '深入 Python'
+foo = b'foo'
+ufoo = 'foo'
+json_foo = b'"foo"'
+json_ufoo = '"foo"'
+json_unicode_value = '"\u00e9"'
+unicode_value = '\u00e9'
+x_byte = b"\xe9"
+utf8_bytes = b'\xc2\xae'
+utf8_bytes2 = b'\xe6\xb7\xb1\xe5\x85\xa5 Python'
+latin1_bytes = b"\xe9"

File mom/tests/speed.py

+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+# Timeit based speed reporter.
+# Taken directly from the Python source code for timeit.
+
+from __future__ import absolute_import
+
+import sys
+import os
+from timeit import Timer, default_timer, default_repeat
+
+sys.path.insert(0, os.curdir)
+
+def report(stmt, setup, number=0, verbose=0, precision=3,
+           repeat=default_repeat, timer=default_timer):
+    sys.stdout.write("%50s -- " % stmt)
+    t = Timer(stmt, setup, timer)
+    if number == 0:
+        # determine number so that 0.2 <= total time < 2.0
+        for i in range(1, 10):
+            number = 10**i
+            try:
+                x = t.timeit(number)
+            except Exception:
+                t.print_exc()
+                return 1
+            if verbose:
+                print("%d loops -> %.*g secs" % (number, precision, x))
+            if x >= 0.2:
+                break
+    try:
+        r = t.repeat(repeat, number)
+    except Exception:
+        t.print_exc()
+        return 1
+    best = min(r)
+    if verbose:
+        print("raw times:", " ".join(["%.*g" % (precision, x) for x in r]))
+    sys.stdout.write("%d loops, " % number)
+    usec = best * 1e6 / number
+    if usec < 1000:
+        print("best of %d: %.*g usec per loop" % (repeat, precision, usec))
+    else:
+        msec = usec / 1000
+        if msec < 1000:
+            print("best of %d: %.*g msec per loop" % (repeat, precision, msec))
+        else:
+            sec = msec / 1000
+            print("best of %d: %.*g sec per loop" % (repeat, precision, sec))

File mom/tests/test_mom_builtins.py

+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
+from __future__ import absolute_import
+
+import unittest2
+import math
+import struct
+from mom._alt_builtins import integer_byte_length_shift_counting, integer_byte_length_word_aligned, integer_bit_length_shift_counting, integer_bit_length_word_aligned
+from mom._compat import get_word_alignment, MACHINE_WORD_SIZE, UINT64_MAX, UINT32_MAX, UINT16_MAX, UINT8_MAX, ZERO_BYTE
+from mom.functional import leading, trailing
+from mom.security.random import generate_random_bytes
+from mom.builtins import \
+    is_unicode, \
+    is_bytes, \
+    is_bytes_or_unicode, \
+    bin, \
+    hex, \
+    integer_byte_length, \
+    integer_bit_length, \
+    is_sequence,\
+\
+    is_odd, \
+    is_even, \
+    is_negative, \
+    is_positive, byte, bytes_leading, bytes_trailing, b
+
+try:
+    unicode
+    from tests.constants import unicode_string, unicode_string2, \
+        utf8_bytes, utf8_bytes2, latin1_bytes
+except NameError:
+    from tests.py3kconstants import unicode_string, unicode_string2, \
+        utf8_bytes, utf8_bytes2, latin1_bytes
+
+unicode_string = unicode_string
+unicode_string2 = unicode_string2
+utf8_bytes = utf8_bytes
+utf8_bytes2 = utf8_bytes2
+latin1_bytes = latin1_bytes
+
+random_bytes = generate_random_bytes(100)
+
+class Test_byte(unittest2.TestCase):
+    def test_byte(self):
+        for i in range(256):
+            byt = byte(i)
+            self.assertTrue(is_bytes(byt))
+            self.assertEqual(ord(byt), i)
+
+    def test_raises_Error_on_overflow(self):
+        self.assertRaises(struct.error, byte, 256)
+        self.assertRaises(struct.error, byte, -1)
+
+
+class Test_bytes_leading_and_trailing(unittest2.TestCase):
+    def test_leading(self):
+        self.assertEqual(bytes_leading(b('\x00\x00\x00\x00')), 4)
+        self.assertEqual(bytes_leading(b('\x00\x00\x00')), 3)
+        self.assertEqual(bytes_leading(b('\x00\x00\xff')), 2)
+        self.assertEqual(bytes_leading(b('\xff')), 0)
+        self.assertEqual(bytes_leading(b('\x00\xff')), 1)
+        self.assertEqual(bytes_leading(b('\x00')), 1)
+        self.assertEqual(bytes_leading(b('\x00\x00\x00\xff')), 3)
+        self.assertEqual(bytes_leading(b('')), 0)
+
+    def test_trailing(self):
+        self.assertEqual(bytes_trailing(b('\x00\x00\x00\x00')), 4)
+        self.assertEqual(bytes_trailing(b('\x00\x00\x00')), 3)
+        self.assertEqual(bytes_trailing(b('\xff\x00\x00')), 2)
+        self.assertEqual(bytes_trailing(b('\xff')), 0)
+        self.assertEqual(bytes_trailing(b('\x00')), 1)
+        self.assertEqual(bytes_trailing(b('\xff\x00\x00\x00')), 3)
+        self.assertEqual(bytes_trailing(b('')), 0)
+
+            
+class Test_bin(unittest2.TestCase):
+    def test_binary_0_1_and_minus_1(self):
+        self.assertEqual(bin(0), '0b0')
+        self.assertEqual(bin(1), '0b1')
+        self.assertEqual(bin(-1), '-0b1')
+
+    def test_binary_value(self):
+        self.assertEqual(bin(12), '0b1100')
+        self.assertEqual(bin(2**32), '0b100000000000000000000000000000000')
+
+    def test_binary_negative_value(self):
+        self.assertEqual(bin(-1200), '-0b10010110000')
+
+    def test_binary_default_prefix(self):
+        self.assertEqual(bin(0), '0b0')
+        self.assertEqual(bin(1), '0b1')
+        self.assertEqual(bin(12), '0b1100')
+        self.assertEqual(bin(2**32), '0b100000000000000000000000000000000')
+        self.assertEqual(bin(-1200), '-0b10010110000')
+
+    def test_binary_custom_prefix(self):
+        self.assertEqual(bin(0, 'B'), 'B0')
+        self.assertEqual(bin(1, 'B'), 'B1')
+        self.assertEqual(bin(12, 'B'), 'B1100')
+        self.assertEqual(bin(2**32, 'B'), 'B100000000000000000000000000000000')
+        self.assertEqual(bin(-1200, 'B'), '-B10010110000')
+
+    def test_binary_no_prefix(self):
+        self.assertEqual(bin(0, None), '0')
+        self.assertEqual(bin(1, ''), '1')
+        self.assertEqual(bin(12, None), '1100')
+        self.assertEqual(bin(2**32, None), '100000000000000000000000000000000')
+        self.assertEqual(bin(-1200, None), '-10010110000')
+
+    def test_raises_TypeError_when_invalid_argument(self):
+        self.assertRaises(TypeError, bin, None, None)
+        self.assertRaises(TypeError, bin, "error")
+        self.assertRaises(TypeError, bin, 2.0)
+        self.assertRaises(TypeError, bin, object)
+
+class Test_hex(unittest2.TestCase):
+    def test_hex_0_1_and_minus_1(self):
+        self.assertEqual(hex(0), '0x0')
+        self.assertEqual(hex(1), '0x1')
+        self.assertEqual(hex(-1), '-0x1')
+
+    def test_hex_value(self):
+        self.assertEqual(hex(12), '0xc')
+        self.assertEqual(hex(2**32), '0x100000000')
+
+    def test_hex_negative_value(self):
+        self.assertEqual(hex(-1200), '-0x4b0')
+
+    def test_hex_default_prefix(self):
+        self.assertEqual(hex(0), '0x0')
+        self.assertEqual(hex(1), '0x1')
+        self.assertEqual(hex(12), '0xc')
+        self.assertEqual(hex(2**32), '0x100000000')
+
+    def test_hex_custom_prefix(self):
+        self.assertEqual(hex(0, 'X'), 'X0')
+        self.assertEqual(hex(1, 'X'), 'X1')
+        self.assertEqual(hex(12, 'X'), 'Xc')
+        self.assertEqual(hex(2**32, 'X'), 'X100000000')
+
+    def test_hex_lower_case(self):
+        self.assertEqual(hex(12), '0xc')
+
+    def test_hex_no_prefix(self):
+        self.assertEqual(hex(0, None), '0')
+        self.assertEqual(hex(1, ''), '1')
+        self.assertEqual(hex(12, None), 'c')
+        self.assertEqual(hex(2**32, None), '100000000')
+
+    def test_raises_TypeError_when_invalid_argument(self):
+        self.assertRaises(TypeError, hex, None, None)
+        self.assertRaises(TypeError, hex, "error")
+        self.assertRaises(TypeError, hex, 2.0)
+        self.assertRaises(TypeError, hex, object)
+
+
+class Test_integer_byte_count(unittest2.TestCase):
+    def test_byte_count_zero_if_zero(self):
+        self.assertEqual(integer_byte_length(0), 0)
+        self.assertEqual(integer_byte_length_shift_counting(0), 0)
+        self.assertEqual(integer_byte_length_word_aligned(0), 0)
+
+    def test_byte_count_correct(self):
+        numbers = [-12, 12, 1200, 120091, 123456789]
+        for num in numbers:
+            if num < 0:
+                bit_length = len(bin(num, None)) - 1
+            else:
+                bit_length = len(bin(num, None))
+            count = int(math.ceil(bit_length / 8.0))
+            self.assertEqual(integer_byte_length(num), count,
+                             "Boom. for number %d, expected %d" % (num, count))
+            self.assertEqual(integer_byte_length_shift_counting(num), count)
+            self.assertEqual(integer_byte_length_word_aligned(num), count)
+
+        self.assertEqual(integer_byte_length(1 << 1023), 128)
+        self.assertEqual(integer_byte_length((1 << 1024) - 1), 128)
+        self.assertEqual(integer_byte_length(1 << 1024), 129)
+
+        self.assertEqual(integer_byte_length_shift_counting(1 << 1023), 128)
+        self.assertEqual(integer_byte_length_shift_counting((1 << 1024) - 1), 128)
+        self.assertEqual(integer_byte_length_shift_counting(1 << 1024), 129)
+
+        self.assertEqual(integer_byte_length_shift_counting(1 << 1023), 128)
+        self.assertEqual(integer_byte_length_shift_counting((1 << 1024) - 1), 128)
+        self.assertEqual(integer_byte_length_word_aligned(1 << 1024), 129)
+
+
+    def test_raises_TypeError_when_invalid_argument(self):
+        self.assertRaises(TypeError, integer_byte_length, None)
+        self.assertRaises(TypeError, integer_byte_length, object)
+
+        self.assertRaises(TypeError, integer_byte_length_shift_counting, None)
+        self.assertRaises(TypeError, integer_byte_length_shift_counting, object)
+
+        #self.assertRaises(TypeError, _integer_byte_length_1, None)
+        self.assertRaises(TypeError, integer_byte_length_word_aligned, object)
+
+
+class Test_long_bit_length(unittest2.TestCase):
+    def test_bit_length_1_if_zero(self):
+        self.assertEqual(integer_bit_length(0), 0)
+        self.assertEqual(integer_bit_length_shift_counting(0), 0)
+        self.assertEqual(integer_bit_length_word_aligned(0), 0)
+
+    def test_bit_length_correct(self):
+        numbers = [
+            -12,
+            12,
+            1200,
+            120091,
+            123456789,
+        ]
+        for num in numbers:
+            if num < 0:
+                length = len(bin(num, None)) - 1
+            else:
+                length = len(bin(num, None))
+            self.assertEqual(integer_bit_length(num), length)
+            self.assertEqual(integer_bit_length_shift_counting(num), length)
+            self.assertEqual(integer_bit_length_word_aligned(num), length)
+
+        self.assertEqual(integer_bit_length(1023), 10)
+        self.assertEqual(integer_bit_length(1024), 11)
+        self.assertEqual(integer_bit_length(1025), 11)
+        self.assertEqual(integer_bit_length(1 << 1024), 1025)
+        self.assertEqual(integer_bit_length((1 << 1024) + 1), 1025)
+        self.assertEqual(integer_bit_length((1 << 1024) - 1), 1024)
+        self.assertEqual(integer_bit_length((1<<32)-1), 32)
+        self.assertEqual(integer_bit_length((1<<64)-1), 64)
+
+        self.assertEqual(integer_bit_length_shift_counting(1023), 10)
+        self.assertEqual(integer_bit_length_shift_counting(1024), 11)
+        self.assertEqual(integer_bit_length_shift_counting(1025), 11)
+        self.assertEqual(integer_bit_length_shift_counting(1 << 1024), 1025)
+        self.assertEqual(integer_bit_length_shift_counting((1 << 1024) + 1), 1025)
+        self.assertEqual(integer_bit_length_shift_counting((1 << 1024) - 1), 1024)
+        self.assertEqual(integer_bit_length_shift_counting((1<<32)-1), 32)
+        self.assertEqual(integer_bit_length_shift_counting((1<<64)-1), 64)
+
+        self.assertEqual(integer_bit_length_word_aligned(1023), 10)
+        self.assertEqual(integer_bit_length_word_aligned(1024), 11)
+        self.assertEqual(integer_bit_length_word_aligned(1025), 11)
+        self.assertEqual(integer_bit_length_word_aligned(1 << 1024), 1025)
+        self.assertEqual(integer_bit_length_word_aligned((1 << 1024) + 1), 1025)
+        self.assertEqual(integer_bit_length_word_aligned((1 << 1024) - 1), 1024)
+        self.assertEqual(integer_bit_length_word_aligned((1<<32)-1), 32)
+        self.assertEqual(integer_bit_length_word_aligned((1<<64)-1), 64)
+
+    def test_raises_TypeError_when_invalid_argument(self):
+        self.assertRaises(TypeError, integer_bit_length, None)
+        self.assertRaises(TypeError, integer_bit_length, object)
+
+        self.assertRaises(TypeError, integer_bit_length_shift_counting, None)
+        self.assertRaises(TypeError, integer_bit_length_shift_counting, object)
+
+        self.assertRaises(TypeError, integer_bit_length_word_aligned, None)
+        self.assertRaises(TypeError, integer_bit_length_word_aligned, object)
+
+
+class Test_is_bytes(unittest2.TestCase):
+    def test_accepts_bytes(self):
+        # Must accept any type of bytes.
+        self.assertTrue(is_bytes(random_bytes))
+        self.assertTrue(is_bytes(utf8_bytes))
+        self.assertTrue(is_bytes(utf8_bytes2))
+        self.assertTrue(is_bytes(latin1_bytes))
+
+    def test_rejects_non_bytes(self):
+        self.assertFalse(is_bytes(unicode_string))
+        self.assertFalse(is_bytes(unicode_string2))
+        self.assertFalse(is_bytes(False))
+        self.assertFalse(is_bytes(5))
+        self.assertFalse(is_bytes(None))
+        self.assertFalse(is_bytes([]))
+        self.assertFalse(is_bytes(()))
+        self.assertFalse(is_bytes([]))
+        self.assertFalse(is_bytes(object))
+
+
+class Test_is_unicode(unittest2.TestCase):
+
+    def test_accepts_unicode(self):
+        self.assertTrue(is_unicode(unicode_string))
+        self.assertTrue(is_unicode(unicode_string2))
+
+    def test_rejects_non_unicode(self):
+        self.assertFalse(is_unicode(random_bytes))
+        self.assertFalse(is_unicode(utf8_bytes))
+        self.assertFalse(is_unicode(utf8_bytes2))
+        self.assertFalse(is_unicode(False))
+        self.assertFalse(is_unicode(5))
+        self.assertFalse(is_unicode(None))
+        self.assertFalse(is_unicode([]))
+        self.assertFalse(is_unicode(()))
+        self.assertFalse(is_unicode({}))
+        self.assertFalse(is_unicode(object))
+
+
+class Test_is_bytes_or_unicode(unittest2.TestCase):
+    def test_accepts_any_string(self):
+        self.assertTrue(is_bytes_or_unicode(random_bytes))
+        self.assertTrue(is_bytes_or_unicode(utf8_bytes))
+        self.assertTrue(is_bytes_or_unicode(utf8_bytes2))
+        self.assertTrue(is_bytes_or_unicode(unicode_string))
+        self.assertTrue(is_bytes_or_unicode(unicode_string2))
+
+    def test_rejects_non_string(self):
+        self.assertFalse(is_bytes_or_unicode(False))
+        self.assertFalse(is_bytes_or_unicode(5))
+        self.assertFalse(is_bytes_or_unicode(None))
+        self.assertFalse(is_bytes_or_unicode([]))
+        self.assertFalse(is_bytes_or_unicode(()))
+        self.assertFalse(is_bytes_or_unicode({}))
+        self.assertFalse(is_bytes_or_unicode(object))
+
+
+class Test_is_sequence(unittest2.TestCase):
+    def test_detects_sequences(self):
+        self.assertTrue(is_sequence([1,]))
+        self.assertTrue(is_sequence((1,)))
+        self.assertTrue(is_sequence(""))
+        self.assertTrue(is_sequence({}))
+        self.assertTrue(is_sequence(dict()))
+        self.assertTrue(is_sequence(set([1, 2])))
+        self.assertTrue(is_sequence(frozenset([1, 2])))
+
+    def test_rejects_non_sequences(self):
+        self.assertFalse(is_sequence(False))
+        self.assertFalse(is_sequence(True))
+        self.assertFalse(is_sequence(None))
+        self.assertFalse(is_sequence(5))
+        self.assertFalse(is_sequence(Test_is_sequence))
+
+class Test_is_even(unittest2.TestCase):
+    def test_parity(self):
+        self.assertTrue(is_even(2))
+        self.assertFalse(is_even(1))
+        self.assertTrue(is_even(-2))
+        self.assertFalse(is_even(-1))
+
+        self.assertTrue(is_even(0))
+
+    def test_boolean(self):
+        # Python 2.x legacy. Ew.
+        self.assertFalse(is_even(True))
+        self.assertTrue(is_even(False))
+
+    def test_TypeError_when_invalid_type(self):
+        self.assertRaises(TypeError, is_even, 2.0)
+        self.assertRaises(TypeError, is_even, None)
+        self.assertRaises(TypeError, is_even, object)
+
+
+class Test_is_odd(unittest2.TestCase):
+    def test_parity(self):
+        self.assertTrue(is_odd(1))
+        self.assertFalse(is_odd(2))
+        self.assertTrue(is_odd(-1))
+        self.assertFalse(is_odd(-2))
+        self.assertFalse(is_odd(0))
+
+    def test_boolean(self):
+        # Python 2.x legacy. Ew.
+        self.assertFalse(is_odd(False))
+        self.assertTrue(is_odd(True))
+
+    def test_TypeError_when_invalid_type(self):
+        self.assertRaises(TypeError, is_odd, 2.0)
+        self.assertRaises(TypeError, is_odd, None)
+        self.assertRaises(TypeError, is_odd, object)
+
+
+class Test_is_positive(unittest2.TestCase):
+    def test_positive(self):
+        self.assertTrue(is_positive(4))
+        self.assertFalse(is_positive(-1))
+        self.assertFalse(is_positive(0))
+
+    def test_floats(self):
+        self.assertTrue(is_positive(4.2))
+        self.assertFalse(is_positive(0.0))
+        self.assertFalse(is_positive(-1.4))
+
+    def test_boolean(self):
+        self.assertTrue(is_positive(True))
+        self.assertFalse(is_positive(False))
+
+    def test_wtf(self):
+        self.assertRaises(TypeError, is_positive, None)
+        self.assertRaises(TypeError, is_positive, "")
+        self.assertRaises(TypeError, is_positive, {})
+        self.assertRaises(TypeError, is_positive, object)
+
+
+class Test_is_negative(unittest2.TestCase):
+    def test_negative(self):
+        self.assertFalse(is_negative(4))
+        self.assertTrue(is_negative(-1))
+        self.assertFalse(is_negative(0))
+
+    def test_floats(self):
+        self.assertFalse(is_negative(4.2))
+        self.assertFalse(is_negative(0.0))
+        self.assertTrue(is_negative(-1.4))
+
+    def test_boolean(self):
+        self.assertFalse(is_negative(True))
+        self.assertFalse(is_negative(False))
+
+    def test_wtf(self):
+        self.assertRaises(TypeError, is_negative, None)
+        self.assertRaises(TypeError, is_negative, "")
+        self.assertRaises(TypeError, is_negative, {})
+        self.assertRaises(TypeError, is_negative, object)
+
+
+class Test_get_machine_alignment(unittest2.TestCase):
+    def test_values(self):
+        if MACHINE_WORD_SIZE == 32:
+            self.assertEqual(get_word_alignment(1 << 64), (32, 4, UINT32_MAX, 'L'))
+            self.assertEqual(get_word_alignment(1 << 32), (32, 4, UINT32_MAX, 'L'))
+        elif MACHINE_WORD_SIZE == 64:
+            self.assertEqual(get_word_alignment(1 << 64), (64, 8, UINT64_MAX, 'Q'))
+            self.assertEqual(get_word_alignment(1 << 32), (64, 8, UINT64_MAX, 'Q'))
+        else:
+            raise NotImplementedError("Do we support other than 32/64-bit?")
+        # Anything 32-bit or below:
+        values = [
+            (1 << 31, (32, 4, UINT32_MAX, 'L')),
+            (1 << 16, (32, 4, UINT32_MAX, 'L')),
+            (1 << 15, (16, 2, UINT16_MAX, 'H')),
+            (1 << 8, (16, 2, UINT16_MAX, 'H')),
+            (1 << 7, (8, 1, UINT8_MAX, 'B'))
+        ]
+        for num, tup  in values:
+            self.assertEqual(get_word_alignment(num), tup, "%d, %r" % (num, tup))
+
+if __name__ == "__main__":
+    unittest2.main()
+

File mom/tests/test_mom_codec.py

+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
+from __future__ import absolute_import
+
+import unittest2
+from mom.builtins import b
+from mom.security.random import \
+    generate_random_bytes, generate_random_uint_between
+from mom.codec import \
+    base64_encode, \
+    base64_decode, \
+    hex_decode, \
+    hex_encode, \
+    decimal_decode, \
+    decimal_encode, \
+    bin_encode, \
+    bin_decode, \
+    base85_encode, base85_decode, base58_encode, base58_decode, \
+    base64_urlsafe_encode, base64_urlsafe_decode
+from mom.codec._alt_integer import \
+    uint_to_bytes_naive_array_based, \
+    uint_to_bytes_naive, \
+    uint_to_bytes_pycrypto, \
+    uint_to_bytes_array_based, \
+    bytes_to_uint_naive
+from mom.codec.integer import \
+    bytes_to_uint, \
+    uint_to_bytes
+from mom.prime_sieve import sieve
+from tests.test_mom_builtins import unicode_string
+
+# Generates a 1024-bit strength random byte string.
+random_bytes_1024 = generate_random_bytes(1024 >> 3)
+# Generates a 2048-bit strength random byte string.
+random_bytes_2048 = generate_random_bytes(2048 >> 3)
+# Generates a 4093 byte length random byte string.
+random_bytes_len_4093 = generate_random_bytes(4093)
+
+zero_bytes = b('\x00\x00\x00\x00')
+one_zero_byte = b('\x00')
+
+random_long_value = generate_random_uint_between(0, 99999999999999999)
+zero_long = 0
+negative_long_value = -1
+
+long_value = 71671831749689734735896910666236152091910950933161125188784836897624039426313152092699961904060141667369
+expected_blocksize_bytes = b('''\
+\x00\x01\xff\xff\xff\xff\xff\xff\xff\xff\x000 0\x0c\x06\x08*\x86H\x86\
+\xf7\r\x02\x05\x05\x00\x04\x10\xd6\xc7\xde\x19\xf6}\xb3#\xbdhI\xafDL\x04)''')
+long_value_blocksize = 45
+expected_bytes = b('''\
+\x01\xff\xff\xff\xff\xff\xff\xff\xff\x000 0\x0c\x06\x08*\x86H\x86\
+\xf7\r\x02\x05\x05\x00\x04\x10\xd6\xc7\xde\x19\xf6}\xb3#\xbdhI\xafDL\x04)''')
+
+
+base85_raw = b("""Man is distinguished, not only by his reason, but by this
+singular passion from other animals, which is a lust of the
+mind, that by a perseverance of delight in the continued and
+indefatigable generation of knowledge, exceeds the short
+vehemence of any carnal pleasure.""").replace(b('\n'), b(' '))
+
+base85_encoded = b("""\
+9jqo^BlbD-BleB1DJ+*+F(f,q/0JhKF<GL>Cj@.4Gp$d7F!,L7@<6@)/0JDEF<G%<+EV:2F!,\
+O<DJ+*.@<*K0@<6L(Df-\\0Ec5e;DffZ(EZee.Bl.9pF"AGXBPCsi+DGm>@3BB/F*&OCAfu2/AKY\
+i(DIb:@FD,*)+C]U=@3BN#EcYf8ATD3s@q?d$AftVqCh[NqF<G:8+EV:.+Cf>-FD5W8ARlolDIa\
+l(DId<j@<?3r@:F%a+D58'ATD4$Bl@l3De:,-DJs`8ARoFb/0JMK@qB4^F!,R<AKZ&-DfTqBG%G\
+>uD.RTpAKYo'+CT/5+Cei#DII?(E,9)oF*2M7/c""")
+
+
+# Base64 encoding this sequence of bytes using the standard Base-64 alphabet
+# produces a "/", "+", and "=" in the encoded sequence.
+url_safety_test_bytes = b('''\
+G\x81Y\x9aK\x9d\xf2\xe9\x81\x06\xc6\xbe6\xa5\x0e\xc0k\x91I\x05\xde\xd8\
+\xdc\xd6\xa7\xf2\x9f\t\x8c\xa1\xa6\xf3\x19\xc7\x0b\xfd=z\x02Z\xbeR\xc0\
+\xc6~`\xddfzA''')
+url_safety_test_standard_encoded = \
+    b('R4FZmkud8umBBsa+NqUOwGuRSQXe2NzWp/KfCYyhpvMZxwv9PXoCWr5SwMZ+YN1mekE=')
+url_safety_test_safe_encoded = \
+    b('R4FZmkud8umBBsa-NqUOwGuRSQXe2NzWp_KfCYyhpvMZxwv9PXoCWr5SwMZ-YN1mekE')
+
+class Test_base85_codec(unittest2.TestCase):
+    def test_codec_identity(self):
+        self.assertEqual(base85_decode(base85_encode(base85_raw)), base85_raw)
+
+    def test_encoding_and_decoding(self):
+        self.assertEqual(base85_encode(base85_raw), base85_encoded)
+        self.assertEqual(base85_decode(base85_encoded), base85_raw)
+
+    def test_raises_KeyError_when_invalid_charset(self):
+        self.assertRaises(ValueError,
+                          base85_encode, base85_raw, "BADCHARSET")
+        self.assertRaises(ValueError,
+                          base85_decode, base85_encoded, "BADCHARSET")
+        
+class Test_base58_codec(unittest2.TestCase):
+    def test_codec_identity(self):
+        self.assertEqual(base58_decode(base58_encode(random_bytes_1024)),
+                         random_bytes_1024)
+        self.assertEqual(base58_decode(base58_encode(random_bytes_len_4093)),
+                         random_bytes_len_4093)
+
+    def test_raises_TypeError_when_invalid_argument(self):
+        self.assertRaises(TypeError, base58_encode, unicode_string)
+        self.assertRaises(TypeError, base58_encode, None)
+        self.assertRaises(TypeError, base58_decode, unicode_string)
+        self.assertRaises(TypeError, base58_decode, None)
+
+class Test_base64_codec(unittest2.TestCase):
+    def test_encodes_without_trailing_newline(self):
+        self.assertFalse(base64_encode(zero_bytes).endswith(b("\n")))
+        self.assertFalse(base64_encode(random_bytes_1024).endswith(b("\n")))
+        self.assertFalse(base64_encode(random_bytes_2048).endswith(b("\n")))
+        self.assertFalse(base64_encode(random_bytes_len_4093).endswith(
+            b("\n")))
+
+    def test_codec_identity(self):
+        # Not zero-destructive.
+        self.assertEqual(base64_decode(base64_encode(zero_bytes)), zero_bytes)
+        self.assertEqual(base64_decode(base64_encode(random_bytes_1024)),
+                         random_bytes_1024)
+        self.assertEqual(base64_decode(base64_encode(random_bytes_2048)),
+                         random_bytes_2048)
+        self.assertEqual(base64_decode(base64_encode(random_bytes_len_4093)),
+                         random_bytes_len_4093)
+
+    def test_TypeError_non_bytes_argument(self):
+        self.assertRaises(TypeError, base64_encode, unicode_string)
+        self.assertRaises(TypeError, base64_encode, None)
+
+        self.assertRaises(TypeError, base64_decode, unicode_string)
+        self.assertRaises(TypeError, base64_decode, None)
+
+        
+class Test_base64_urlsafe_codec(unittest2.TestCase):
+    def test_encodes_without_trailing_newline(self):
+        self.assertFalse(base64_urlsafe_encode(zero_bytes).endswith(b("\n")))
+        self.assertFalse(
+            base64_urlsafe_encode(random_bytes_1024).endswith(b("\n")))
+
+
+    def test_codec_identity(self):
+        # Not zero-destructive.
+        self.assertEqual(
+            base64_urlsafe_decode(base64_urlsafe_encode(zero_bytes)),
+            zero_bytes
+        )
+        self.assertEqual(
+            base64_urlsafe_decode(base64_urlsafe_encode(random_bytes_1024)),
+            random_bytes_1024
+        )
+
+    def test_correctness(self):
+        self.assertEqual(base64_urlsafe_encode(url_safety_test_bytes),
+                         url_safety_test_safe_encoded)
+        self.assertEqual(base64_encode(url_safety_test_bytes),
+                         url_safety_test_standard_encoded)
+        self.assertEqual(base64_urlsafe_decode(url_safety_test_safe_encoded),
+                         url_safety_test_bytes)
+        self.assertEqual(base64_decode(url_safety_test_standard_encoded),
+                         url_safety_test_bytes)
+
+        # Tests whether this decoder can decode standard encoded base64
+        # representation too.
+        self.assertEqual(
+            base64_urlsafe_decode(url_safety_test_standard_encoded),
+            url_safety_test_bytes
+        )
+        
+    def test_TypeError_non_bytes_argument(self):
+        self.assertRaises(TypeError, base64_urlsafe_encode, unicode_string)
+        self.assertRaises(TypeError, base64_urlsafe_encode, None)
+
+        self.assertRaises(TypeError, base64_urlsafe_decode, unicode_string)
+        self.assertRaises(TypeError, base64_urlsafe_decode, None)
+
+
+class Test_hex_codec(unittest2.TestCase):
+    def test_codec_identity(self):
+        # Not zero-destructive
+        self.assertEqual(hex_decode(hex_encode(zero_bytes)), zero_bytes)
+        self.assertEqual(hex_decode(hex_encode(random_bytes_1024)),
+                         random_bytes_1024)
+        self.assertEqual(hex_decode(hex_encode(random_bytes_2048)),
+                         random_bytes_2048)
+        self.assertEqual(
+            hex_decode(hex_encode(random_bytes_len_4093)),
+                         random_bytes_len_4093)
+
+    def test_TypeError_non_bytes_argument(self):
+        self.assertRaises(TypeError, hex_encode, unicode_string)
+        self.assertRaises(TypeError, hex_encode, None)
+
+        self.assertRaises(TypeError, hex_decode, unicode_string)
+        self.assertRaises(TypeError, hex_decode, None)
+
+
+class Test_decimal_codec(unittest2.TestCase):
+    def test_codec_identity(self):
+        self.assertEqual(
+            decimal_decode(decimal_encode(zero_bytes)),
+            zero_bytes)
+        self.assertEqual(
+            decimal_decode(decimal_encode(random_bytes_1024)),
+            random_bytes_1024)
+        self.assertEqual(
+            decimal_decode(decimal_encode(random_bytes_2048)),
+            random_bytes_2048)
+        self.assertEqual(
+            decimal_decode(decimal_encode(random_bytes_len_4093)),
+            random_bytes_len_4093)
+
+    def test_TypeError_non_bytes_argument(self):
+        self.assertRaises(TypeError, decimal_encode, unicode_string)
+        self.assertRaises(TypeError, decimal_encode, None)
+
+        self.assertRaises(TypeError, decimal_decode, unicode_string)
+        self.assertRaises(TypeError, decimal_decode, None)
+
+
+class Test_bin_codec(unittest2.TestCase):
+    def test_codec_identity(self):
+        self.assertEqual(bin_decode(bin_encode(zero_bytes)), zero_bytes)
+        self.assertEqual(
+            bin_decode(bin_encode(random_bytes_1024)), random_bytes_1024)
+        self.assertEqual(
+            bin_decode(bin_encode(random_bytes_2048)), random_bytes_2048)
+        self.assertEqual(
+            bin_decode(bin_encode(random_bytes_len_4093)),
+            random_bytes_len_4093)
+
+    def test_TypeError_non_bytes_argument(self):
+        self.assertRaises(TypeError, bin_encode, unicode_string)
+        self.assertRaises(TypeError, bin_encode, None)
+
+        self.assertRaises(TypeError, bin_decode, unicode_string)
+        self.assertRaises(TypeError, bin_decode, None)
+
+
+class Test_bytes_uint_codec(unittest2.TestCase):
+    def test_codec_equivalence(self):
+        # Padding bytes are not preserved (it is acceptable here).
+        random_bytes = b("\x00\xbcE\x9a\xda]")
+        expected_bytes = b("\xbcE\x9a\xda]")
+        self.assertEqual(uint_to_bytes(bytes_to_uint(zero_bytes)),
+                         one_zero_byte)
+        self.assertEqual(uint_to_bytes(bytes_to_uint(random_bytes)),
+                         expected_bytes)
+
+        self.assertEqual(uint_to_bytes(bytes_to_uint_naive(zero_bytes)),
+                         one_zero_byte)
+        self.assertEqual(uint_to_bytes(bytes_to_uint_naive(random_bytes)),
+                         expected_bytes)
+
+    def test_TypeError_non_bytes_argument(self):
+        self.assertRaises(TypeError, bytes_to_uint, unicode_string)
+        self.assertRaises(TypeError, bytes_to_uint, None)
+
+        self.assertRaises(TypeError, bytes_to_uint_naive, unicode_string)
+        self.assertRaises(TypeError, bytes_to_uint_naive, None)
+
+
+class Test_uint_to_bytes(unittest2.TestCase):
+    def test_accuracy(self):
+        self.assertEqual(uint_to_bytes(123456789), b('\x07[\xcd\x15'))
+        self.assertEqual(uint_to_bytes_pycrypto(123456789),
+                         b('\x07[\xcd\x15'))
+        self.assertEqual(uint_to_bytes_array_based(123456789),
+                         b('\x07[\xcd\x15'))
+        self.assertEqual(uint_to_bytes_naive(123456789), b('\x07[\xcd\x15'))
+        self.assertEqual(uint_to_bytes_naive_array_based(123456789),
+                         b('\x07[\xcd\x15'))
+
+        self.assertEqual(uint_to_bytes(long_value),
+                         expected_bytes)
+        self.assertEqual(uint_to_bytes_pycrypto(long_value),
+                         expected_bytes)
+        self.assertEqual(uint_to_bytes_array_based(long_value),
+                         expected_bytes)
+        self.assertEqual(uint_to_bytes_naive(long_value),
+                         expected_bytes)
+        self.assertEqual(uint_to_bytes_naive_array_based(long_value),
+                         expected_bytes)
+
+    def test_chunk_size(self):
+        self.assertEqual(uint_to_bytes(long_value,
+                                       long_value_blocksize),
+                         expected_blocksize_bytes)
+        self.assertEqual(uint_to_bytes_pycrypto(long_value,
+                                                long_value_blocksize),
+                         expected_blocksize_bytes)
+        self.assertEqual(uint_to_bytes_array_based(long_value,
+                                                   long_value_blocksize),
+                         expected_blocksize_bytes)
+        self.assertEqual(uint_to_bytes_naive(long_value,
+                                             long_value_blocksize),
+                         expected_blocksize_bytes)
+        self.assertEqual(uint_to_bytes_naive_array_based(long_value,
+                                                         long_value_blocksize),
+                         expected_blocksize_bytes)
+
+
+        self.assertEqual(uint_to_bytes(123456789, 6),
+                         b('\x00\x00\x07[\xcd\x15'))
+        self.assertEqual(uint_to_bytes(123456789, 7),
+                         b('\x00\x00\x00\x07[\xcd\x15'))
+
+        self.assertEqual(uint_to_bytes_pycrypto(123456789, 6),
+                         b('\x00\x00\x07[\xcd\x15'))
+        self.assertEqual(uint_to_bytes_pycrypto(123456789, 7),
+                         b('\x00\x00\x00\x07[\xcd\x15'))
+        
+        self.assertEqual(uint_to_bytes_array_based(123456789, 6),
+                         b('\x00\x00\x07[\xcd\x15'))
+        self.assertEqual(uint_to_bytes_array_based(123456789, 7),
+                         b('\x00\x00\x00\x07[\xcd\x15'))
+
+        self.assertEqual(uint_to_bytes_naive(123456789, 6),
+                         b('\x00\x00\x07[\xcd\x15'))
+        self.assertEqual(uint_to_bytes_naive(123456789, 7),
+                         b('\x00\x00\x00\x07[\xcd\x15'))
+
+        self.assertEqual(uint_to_bytes_naive_array_based(123456789, 6),
+                         b('\x00\x00\x07[\xcd\x15'))
+        self.assertEqual(uint_to_bytes_naive_array_based(123456789, 7),
+                         b('\x00\x00\x00\x07[\xcd\x15'))
+
+    def test_zero(self):
+        self.assertEqual(uint_to_bytes(0, 4), b('\x00') * 4)
+        self.assertEqual(uint_to_bytes_array_based(0, 4), b('\x00') * 4)
+        self.assertEqual(uint_to_bytes_naive(0, 4), b('\x00') * 4)
+        self.assertEqual(uint_to_bytes_naive_array_based(0, 4), b('\x00') * 4)
+        self.assertEqual(uint_to_bytes_pycrypto(0, 4), b('\x00') * 4)
+
+        self.assertEqual(uint_to_bytes(0, 7), b('\x00') * 7)
+        self.assertEqual(uint_to_bytes_naive(0, 7), b('\x00') * 7)
+        self.assertEqual(uint_to_bytes_array_based(0, 7), b('\x00') * 7)
+        self.assertEqual(uint_to_bytes_naive_array_based(0, 7), b('\x00') * 7)
+        self.assertEqual(uint_to_bytes_pycrypto(0, 7), b('\x00') * 7)
+
+        self.assertEqual(uint_to_bytes(0), b('\x00'))
+        self.assertEqual(uint_to_bytes_naive(0), b('\x00'))
+        self.assertEqual(uint_to_bytes_array_based(0), b('\x00'))
+        self.assertEqual(uint_to_bytes_naive_array_based(0), b('\x00'))
+        self.assertEqual(uint_to_bytes_pycrypto(0), b('\x00'))
+
+    def test_correctness_against_base_implementation(self):
+        # Slow test.
+        values = [
+            1 << 512,
+            1 << 8192,
+            1 << 77,
+        ]
+        for value in values:
+            self.assertEqual(uint_to_bytes(value), uint_to_bytes_naive(value),
+                             "Boom %d" % value)
+            self.assertEqual(uint_to_bytes_array_based(value),
+                             uint_to_bytes_naive(value),
+                             "Boom %d" % value)
+            self.assertEqual(uint_to_bytes(value),
+                             uint_to_bytes_naive_array_based(value),
+                             "Boom %d" % value)
+            self.assertEqual(uint_to_bytes_pycrypto(value),
+                             uint_to_bytes_naive(value),
+                             "Boom %d" % value)
+            self.assertEqual(bytes_to_uint(uint_to_bytes(value)),
+                             value,
+                             "Boom %d" % value)
+
+    def test_correctness_for_primes(self):
+        for prime in sieve:
+            self.assertEqual(uint_to_bytes(prime), uint_to_bytes_naive(prime),
+                             "Boom %d" % prime)
+            self.assertEqual(uint_to_bytes_array_based(prime),
+                             uint_to_bytes_naive(prime),
+                             "Boom %d" % prime)
+            self.assertEqual(uint_to_bytes_pycrypto(prime),
+                             uint_to_bytes_naive(prime),
+                             "Boom %d" % prime)
+
+    def test_raises_OverflowError_when_chunk_size_is_insufficient(self):
+        self.assertRaises(OverflowError, uint_to_bytes, 123456789, 3)
+        self.assertRaises(OverflowError, uint_to_bytes, 299999999999, 4)
+
+        self.assertRaises(OverflowError,
+                          uint_to_bytes_array_based, 123456789, 3)
+        self.assertRaises(OverflowError,
+                          uint_to_bytes_array_based, 299999999999, 4)
+
+        self.assertRaises(OverflowError, uint_to_bytes_naive, 123456789, 3)
+        self.assertRaises(OverflowError, uint_to_bytes_naive, 299999999999, 4)
+
+        self.assertRaises(OverflowError,
+                          uint_to_bytes_naive_array_based, 123456789, 3)
+        self.assertRaises(OverflowError,
+                          uint_to_bytes_naive_array_based, 299999999999, 4)
+
+    def test_raises_ValueError_when_negative_integer(self):
+        self.assertRaises(ValueError, uint_to_bytes, -1)
+        self.assertRaises(ValueError, uint_to_bytes_array_based, -1)
+        self.assertRaises(ValueError, uint_to_bytes_naive, -1)
+        self.assertRaises(ValueError, uint_to_bytes_naive_array_based, -1)
+
+    def test_raises_TypeError_when_not_integer(self):
+        self.assertRaises(TypeError, uint_to_bytes, None)
+        self.assertRaises(TypeError, uint_to_bytes_array_based, None)
+        self.assertRaises(TypeError, uint_to_bytes_naive, None)
+        self.assertRaises(TypeError, uint_to_bytes_naive_array_based, None)

File mom/tests/test_mom_codec_base58.py

+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
+import unittest2
+from mom.builtins import b
+from mom.codec import hex_decode, base58_decode, base58_encode
+from mom.codec._alt_base import b58decode_naive
+from mom.codec.base58 import b58encode, b58decode, ALT58_BYTES, ASCII58_BYTES
+from mom.security.random import generate_random_bytes
+
+random_bytes = generate_random_bytes(384)
+
+zero_bytes = b('\x00\x00\x00\x00')
+one_zero_byte = b('\x00')
+raw_data = hex_decode(b('005cc87f4a3fdfe3a2346b6953267ca867282630d3f9b78e64'))
+encoded = b('19TbMSWwHvnxAKy12iNm3KdbGfzfaMFViT')
+encoded_with_whitespace = b('''
+19TbMSWwHvnxAKy12iN
+m3KdbGfzfaMFViT
+''')
+
+padding_raw = b('''\
+\x00\x00\xa4\x97\xf2\x10\xfc\x9c]\x02\xfc}\xc7\xbd!\x1c\xb0\xc7M\xa0\xae\x16\
+''')
+
+class Test_base58_codec(unittest2.TestCase):
+    def test_ensure_charset_length(self):
+        self.assertEqual(len(ASCII58_BYTES), 58)
+        self.assertEqual(len(ALT58_BYTES), 58)
+
+    def test_codec_identity(self):
+        self.assertEqual(b58decode(b58encode(random_bytes)), random_bytes)
+        self.assertEqual(b58decode_naive(b58encode(random_bytes)), random_bytes)
+        self.assertEqual(base58_decode(base58_encode(random_bytes)),
+                         random_bytes)
+
+    def test_encodes_zero_prefixed_padding(self):
+        self.assertEqual(b58decode(b58encode(padding_raw)), padding_raw)
+        self.assertEqual(b58decode_naive(b58encode(padding_raw)), padding_raw)
+        self.assertEqual(base58_decode(base58_encode(padding_raw)), padding_raw)
+
+    def test_zero_bytes(self):
+        self.assertEqual(b58encode(zero_bytes), b('1111'))
+        self.assertEqual(b58decode(b('1111')), zero_bytes)
+        self.assertEqual(b58decode_naive(b('1111')), zero_bytes)
+        self.assertEqual(b58encode(one_zero_byte), b('1'))
+        self.assertEqual(b58decode(b('1')), one_zero_byte)
+        self.assertEqual(b58decode_naive(b('1')), one_zero_byte)
+
+        self.assertEqual(base58_encode(zero_bytes), b('1111'))
+        self.assertEqual(base58_decode(b('1111')), zero_bytes)
+        self.assertEqual(base58_encode(one_zero_byte), b('1'))
+        self.assertEqual(base58_decode(b('1')), one_zero_byte)
+
+    def test_encoding_and_decoding(self):
+        hello_world = b('\x48\x65\x6c\x6c\x6f\x20\x77\x6f\x72\x6c\x64')
+
+        self.assertEqual(b58encode(hello_world), b("JxF12TrwUP45BMd"))
+        self.assertEqual(b58decode(b("JxF12TrwUP45BMd")), hello_world)
+
+#        self.assertEqual(bytes_to_integer(b58decode(b("16Ho7Hs"))), 3471844090)
+#        self.assertEqual(b58encode(integer_to_bytes(3471844090)), b("16Ho7Hs"))
+
+#        self.assertEqual(_b58encode(b("Hello World")), b("JxF12TrwUP45BMd"))
+#        self.assertEqual(_b58decode(b("JxF12TrwUP45BMd")), b("Hello World"))
+#        self.assertEqual(bytes_to_integer(_b58decode(b("16Ho7Hs"))), 3471844090)
+#        self.assertEqual(_b58encode(integer_to_bytes(3471844090)), b("16Ho7Hs"))
+
+        self.assertEqual(b58encode(raw_data), encoded)
+        self.assertEqual(b58decode(encoded), raw_data)
+        self.assertEqual(b58decode(encoded_with_whitespace), raw_data)
+        self.assertEqual(b58decode_naive(encoded), raw_data)
+        self.assertEqual(b58decode_naive(encoded_with_whitespace), raw_data)
+
+        self.assertEqual(base58_encode(raw_data), encoded)
+        self.assertEqual(base58_decode(encoded), raw_data)
+        self.assertEqual(base58_decode(encoded_with_whitespace), raw_data)

File mom/tests/test_mom_codec_base62.py

+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
+import unittest2
+from mom.builtins import b
+from mom.codec import hex_decode, base62_decode, base62_encode
+from mom.codec._alt_base import b62decode_naive
+from mom.codec.base62 import b62encode, b62decode, ASCII62_BYTES, ALT62_BYTES
+from mom.security.random import generate_random_bytes
+
+random_bytes_len_512 = generate_random_bytes(512)
+
+zero_bytes = b('\x00\x00\x00\x00')
+one_zero_byte = b('\x00')
+raw_data = hex_decode(b('005cc87f4a3fdfe3a2346b6953267ca867282630d3f9b78e64'))
+encoded = b('01041W9weGIezvwKmSO0kaL8BGx4qp64Q8')
+encoded_with_whitespace = b('''
+01041W9weGIezvwKmS
+O0kaL8BGx4qp64Q8
+''')
+
+padding_raw = b('''\
+\x00\x00\xa4\x97\xf2\x10\xfc\x9c]\x02\xfc}\xc7\xbd!\x1c\xb0\xc7M\xa0\xae\x16\
+''')
+
+class Test_base62_codec(unittest2.TestCase):
+    def test_ensure_charset_length(self):
+        self.assertEqual(len(ASCII62_BYTES), 62)
+        self.assertEqual(len(ALT62_BYTES), 62)
+
+    def test_codec_identity(self):
+        self.assertEqual(
+            b62decode(b62encode(random_bytes_len_512)),
+            random_bytes_len_512
+        )
+        self.assertEqual(
+            b62decode_naive(b62encode(random_bytes_len_512)),
+            random_bytes_len_512
+        )
+        self.assertEqual(
+            base62_decode(base62_encode(random_bytes_len_512)),
+            random_bytes_len_512
+        )
+
+    def test_encodes_zero_prefixed_padding(self):
+        self.assertEqual(b62decode(b62encode(padding_raw)), padding_raw)
+        self.assertEqual(b62decode_naive(b62encode(padding_raw)), padding_raw)
+        self.assertEqual(base62_decode(base62_encode(padding_raw)), padding_raw)
+
+    def test_zero_bytes(self):
+        self.assertEqual(b62encode(zero_bytes), b('0000'))
+        self.assertEqual(b62decode(b('0000')), zero_bytes)
+        self.assertEqual(b62decode_naive(b('0000')), zero_bytes)
+        self.assertEqual(b62encode(one_zero_byte), b('0'))
+        self.assertEqual(b62decode(b('0')), one_zero_byte)
+        self.assertEqual(b62decode_naive(b('0')), one_zero_byte)
+
+        self.assertEqual(base62_encode(zero_bytes), b('0000'))
+        self.assertEqual(base62_decode(b('0000')), zero_bytes)
+        self.assertEqual(base62_encode(one_zero_byte), b('0'))
+        self.assertEqual(base62_decode(b('0')), one_zero_byte)
+
+    def test_encoding_and_decoding(self):
+        self.assertEqual(b62encode(raw_data), encoded)
+        self.assertEqual(b62decode(encoded), raw_data)
+        self.assertEqual(b62decode(encoded_with_whitespace), raw_data)
+        self.assertEqual(b62decode_naive(encoded), raw_data)
+        self.assertEqual(b62decode_naive(encoded_with_whitespace), raw_data)
+
+        self.assertEqual(base62_encode(raw_data), encoded)
+        self.assertEqual(base62_decode(encoded), raw_data)
+        self.assertEqual(base62_decode(encoded_with_whitespace), raw_data)

File mom/tests/test_mom_codec_base85.py

+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
+import os
+import unittest2
+from mom.builtins import b
+from tests.constants import unicode_string
+from tests.test_mom_builtins import unicode_string2
+
+from mom.codec.base85 import b85decode, b85encode, ipv6_b85encode, \
+    ipv6_b85decode, ASCII85_PREFIX, ASCII85_SUFFIX, rfc1924_b85encode, \
+    rfc1924_b85decode, _check_compact_char_occurrence
+
+raw = b("""Man is distinguished, not only by his reason, but by this
+singular passion from other animals, which is a lust of the
+mind, that by a perseverance of delight in the continued and
+indefatigable generation of knowledge, exceeds the short
+vehemence of any carnal pleasure.""").replace(b('\n'), b(' '))
+
+encoded = b("""\
+9jqo^BlbD-BleB1DJ+*+F(f,q/0JhKF<GL>Cj@.4Gp$d7F!,L7@<6@)/0JDEF<G%<+EV:2F!,\
+O<DJ+*.@<*K0@<6L(Df-\\0Ec5e;DffZ(EZee.Bl.9pF"AGXBPCsi+DGm>@3BB/F*&OCAfu2/AKY\
+i(DIb:@FD,*)+C]U=@3BN#EcYf8ATD3s@q?d$AftVqCh[NqF<G:8+EV:.+Cf>-FD5W8ARlolDIa\
+l(DId<j@<?3r@:F%a+D58'ATD4$Bl@l3De:,-DJs`8ARoFb/0JMK@qB4^F!,R<AKZ&-DfTqBG%G\
+>uD.RTpAKYo'+CT/5+Cei#DII?(E,9)oF*2M7/c""")
+
+encoded_with_ends = b("""\
+<~9jqo^BlbD-BleB1DJ+*+F(f,q/0JhKF<GL>Cj@.4Gp$d7F!,L7@<6@)/0JDEF<G%<+EV:2F!,\
+O<DJ+*.@<*K0@<6L(Df-\\0Ec5e;DffZ(EZee.Bl.9pF"AGXBPCsi+DGm>@3BB/F*&OCAfu2/AKY\
+i(DIb:@FD,*)+C]U=@3BN#EcYf8ATD3s@q?d$AftVqCh[NqF<G:8+EV:.+Cf>-FD5W8ARlolDIa\
+l(DId<j@<?3r@:F%a+D58'ATD4$Bl@l3De:,-DJs`8ARoFb/0JMK@qB4^F!,R<AKZ&-DfTqBG%G\
+>uD.RTpAKYo'+CT/5+Cei#DII?(E,9)oF*2M7/c~>""")
+
+encoded_with_whitespace = b("""
+9jqo^BlbD-BleB1DJ+*+F(f,q/0JhKF<GL>Cj@.4Gp$d7F!,L7@<6@)/0JDEF<G%<+EV:2F!,
+O<DJ+*.@<*K0@<6L(Df-\\0Ec5e;DffZ(EZee.Bl.9pF"AGXBPCsi+DGm>@3BB/F*&OCAfu2/AKY
+i(DIb:@FD,*)+C]U=@3BN#EcYf8ATD3s@q?d$AftVqCh[NqF<G:8+EV:.+Cf>-FD5W8ARlolDIa
+l(DId<j@<?3r@:F%a+D58'ATD4$Bl@l3De:,-DJs`8ARoFb/0JMK@qB4^F!,R<AKZ&-DfTqBG%G
+>uD.RTpAKYo'+CT/5+Cei#DII?(E,9)oF*2M7/c""")
+
+encoded_with_ends_and_whitespace = b("""
+<~9jqo^BlbD-BleB1DJ+*+F(f,q/0JhKF<GL>Cj@.4Gp$d7F!,L7@<6@)/0JDEF<G%<+EV:2F!,
+O<DJ+*.@<*K0@<6L(Df-\\0Ec5e;DffZ(EZee.Bl.9pF"AGXBPCsi+DGm>@3BB/F*&OCAfu2/AKY
+i(DIb:@FD,*)+C]U=@3BN#EcYf8ATD3s@q?d$AftVqCh[NqF<G:8+EV:.+Cf>-FD5W8ARlolDIa
+l(DId<j@<?3r@:F%a+D58'ATD4$Bl@l3De:,-DJs`8ARoFb/0JMK@qB4^F!,R<AKZ&-DfTqBG%G
+>uD.RTpAKYo'+CT/5+Cei#DII?(E,9)oF*2M7/c~>""")
+
+
+#ipv6_address = '1080:0:0:0:8:800:200C:417A'
+ipv6_number = 21932261930451111902915077091070067066
+ipv6_raw_bytes = b('\x10\x80\x00\x00\x00\x00\x00\x00\x00\x08\x08\x00 \x0cAz')
+ipv6_encoded = b('4)+k&C#VzJ4br>0wv%Yp')
+
+# Wikipedia example.
+#ipv6_number_2 = 2**128 - 1  # 340282366920938463463374607431768211455L
+ipv6_number_2 = (1 << 128) - 1
+ipv6_encoded_2 = b('=r54lj&NUUO~Hi%c2ym0')
+
+#ipv6_address_3 = '2607:f8f0:610:4000:214:38ff:feee:b65a'
+ipv6_number_3 = 50552058972053811105097158630017250906
+ipv6_encoded_3 = b('B7RDhRib#Y+VwlwuPBOG')
+
+
+# Mercurial uses RFC1924 character set, but does not encode it like
+# IPv6.
+mercurial_bytes = b('\t\x91{W\xa80\xb1')
+mercurial_encoded = b('36XnOs4%e')
+
+random_256_bytes = b('''U\x94<Q\x1d\xad\xe4\xe3\xd1\xd1\xddR\xfb d\
+\x01R6\xadj\xa2\x03\xa4\xc1\xc7\x92\xa1U\x18\x19\xaep\r\xfe\xaa\
+\xd4\x11ob\xb2yV\x00\xb1\xb1\x98<O\x15\xf7?7\xbf\xc8\x0b\xbdR\
+\xe7\xf1rd\xe0:4\xe2\x9d\xd9I&v\x1cvN$\xb6\xca\xff\xc2?1\xa2\
+\xc1d\x0b\rUpM\xfdh\x81\xd3st\x04\xd4.\x9d\x03<\xe3}\xdck\\\x01\
+\x7fg\xec\x80*{P\xdfG,\x08\x08w\x86.\x89L\xe7~\xfd\xa5\xc8x\x85\
+\x07\xcfG\x80\xf0\xd3\x93(\xbbA\x07\xa1\x0ed\x14-\x88\xa3\x15\
+\xc2\n\xed\xfb\x13\x02\x1ba~\x944J\xa0{<o_(07\x81J\x8e\x8d\xd9x\
+\x86\xa1`v&\xee\xe1\x85\x06\x9c\xf1\xb0\xd2Bp\xf8\x0f+\xcc\xb0r2\
+\xc7\xaaH\r_\xeeqq;\xaf\x10\x15\x83\xb8?Y)\xb2\x94\xe5Us~\x11\
+\x1fBX\x8cF\xc9\x88\x99[\\\xc4\xb1a\x80P\xe1\xa1\x9b\xd8\xe5j\
+\x817\x1a\xb58\x01\xfc\x80\xc5\x9e3\x80\xa4*''')
+
+random_256_mercurial = b('''\
+Rg^qY9j)Z!(b3&f`ygZiQZ}t>q64JC$C9B{7#Xf`4gRXs5pQC$c~$_iv6wth756_kzsL)\
+{Qs?n<WZ*h9;+@$^CUzWlP9(O<|H3~pqQPVf4OMVW{b+&Hb94mME}a8B<9*y~TmgS)?0_\
+nJP~S%^2nctEE{RO%e*LA$c!dYgM}Y9tlPJ4E2cZsR6fKCO6~YSb`x62iVSbb}N}zi@Z(\
+k@dH-SoyjoEmHp<s3<?%{<7obj;ILU8yGE6lKRGRLY&4PWkYaXYUN6@$1xSt+uV<yCWj5\
+g$TWj7G_bnOj`Mv0;Ev;h~$@<!XU98nrk9{D8%tGk~Nj''')
+
+random_odd_bytes = os.urandom(3333)
+
+# 31 bytes each.
+random_bytes_list = [
+    b('a)X\xfb$$\xd1Q\xbe\xad\xb7\n\xf9\x99_\xc9\x90\xaf\rT\
+\xcf\x8d\xaaF\x0cz\xa8\xf2\x11\xd0\x1e'),
+    b('Ep\xf7a&\xbd\xce.\x16BV~N;\xbe|\x80\xadZ\xc9\xbc\xf1\
+\xf7\xec\x15>\x1c\xb0\xd9\xcd&')
+]
+rfc_encoded_bytes_list = [
+    b('VJTSqBqY&MzOA<k`I%qIkgp9?&yA`^40@>Y5zrn'),
+    b('MR50FCcVxs7D85jPCLGQfUR1|yz%$!6+RrW+07;'),
+]
+
+
+class Test_check_compact_char_occurrence(unittest2.TestCase):
+    def test_valid(self):
+        self.assertEqual(
+            _check_compact_char_occurrence(b('z12345z12345zz123!'),
+                                           b('z'),
+                                           5), None
+        )
+
+    def test_ValueError_when_invalid_index(self):
+        self.assertRaises(ValueError, _check_compact_char_occurrence,
+                          b('z12345z12345zz123z!'), b('z'), 5)
+
+class Test_base85_encode(unittest2.TestCase):
+    def test_encoding(self):
+        self.assertEqual(b85encode(raw), encoded)
+
+    def test_encoding_wikipedia(self):
+        self.assertEqual(b85encode(b("Man ")), b("9jqo^"))
+        self.assertEqual(b85encode(b("sure")), b("F*2M7"))
+
+    def test_check_padding(self):
+        self.assertEqual(b85encode(b("."), _padding=True), b("/cYkO"))
+        self.assertEqual(b85encode(b(".")), b("/c"))
+
+    def test_TypeError_on_unicode(self):
+        self.assertRaises(TypeError, b85encode, unicode_string2)
+
+class Test_base85_decode(unittest2.TestCase):
+    def test_decoder(self):
+        self.assertEqual(b85decode(encoded, ASCII85_PREFIX, ASCII85_SUFFIX),
+                         raw)
+
+    def test_TypeError_on_unicode(self):
+        self.assertRaises(TypeError, b85decode, unicode_string2)
+
+    def test_decoder_ignores_whitespace_by_default(self):
+        self.assertEqual(b85decode(encoded_with_whitespace), raw)
+
+    def test_decoder_ignores_ends_by_default(self):
+        self.assertEqual(b85decode(encoded_with_ends_and_whitespace,
+                                   ASCII85_PREFIX, ASCII85_SUFFIX), raw)
+
+    def test_encoding_wikipedia(self):
+        self.assertEqual(b85decode(b("9jqo^")), b("Man "))
+        self.assertEqual(b85decode(b("F*2M7")), b("sure"))
+
+    def test_check_padding(self):
+        self.assertEqual(b85decode(b("/c")), b("."))
+
+    def test_decode_boundary(self):
+        self.assertEqual(b85decode(b("s8W-!")), b("\xff\xff\xff\xff"))
+
+    def test_OverflowError_when_invalid_base85_byte_found(self):
+        self.assertRaises(OverflowError, b85decode, b('xy!!!'))
+
+    def test_decodes_z_into_zero_bytes(self):
+        self.assertEqual(b85decode(b('zzz')), b('\x00') * 4 * 3)
+
+    def test_decode_zero_groups(self):
+        self.assertEqual(b85decode(b('!!!!!')), b('\x00') * 4)
+
+    def test_ValueError_when_zero_char_in_middle_of_chunk(self):
+        self.assertRaises(ValueError, b85decode, b('zaz'))
+
+
+
+
+class Test_codec(unittest2.TestCase):
+    def test_identity(self):
+        zero_bytes = b('\x00\x00\x00\x00\x00')
+        self.assertEqual(b85decode(b85encode(zero_bytes)), zero_bytes)
+        self.assertEqual(b85decode(b85encode(random_256_bytes)),
+                         random_256_bytes)
+        self.assertEqual(b85decode(b85encode(random_odd_bytes)),
+                         random_odd_bytes)
+
+    def test_raises_TypeError_when_invalid_argument(self):
+        self.assertRaises(TypeError, b85encode, unicode_string)
+        self.assertRaises(TypeError, b85encode, None)
+        self.assertRaises(TypeError, b85decode, unicode_string)
+        self.assertRaises(TypeError, b85decode, None)
+
+    def test_raises_TypeError_when_bad_arg_types(self):
+        # Prefix/suffix.
+        self.assertRaises(TypeError, b85encode, b('foo'), unicode_string, None)
+        self.assertRaises(TypeError, b85encode, b('foo'), None, unicode_string)
+        self.assertRaises(TypeError, b85decode, b('foo'), unicode_string, None)
+        self.assertRaises(TypeError, b85decode, b('foo'), None, unicode_string)
+
+        # Compact char.
+        self.assertRaises(TypeError, b85encode, b('foo'),
+                          _compact_char=unicode_string)
+        self.assertRaises(TypeError, b85decode, b('foo'),
+                          _compact_char=unicode_string)
+
+
+class Test_rfc1924_base85_encoding(unittest2.TestCase):
+    def test_encoding(self):
+        self.assertEqual(rfc1924_b85encode(mercurial_bytes), mercurial_encoded)
+        self.assertEqual(rfc1924_b85encode(random_256_bytes),
+                         random_256_mercurial)
+        for a, e in zip(random_bytes_list, rfc_encoded_bytes_list):
+            self.assertEqual(rfc1924_b85encode(a), e)
+        
+    def test_decoding(self):
+        self.assertEqual(rfc1924_b85decode(mercurial_encoded), mercurial_bytes)
+        self.assertEqual(rfc1924_b85decode(random_256_mercurial),
+                         random_256_bytes)
+        self.assertEqual(rfc1924_b85decode(b('|NsC0')), b('\xff\xff\xff\xff'))
+        for a, e in zip(random_bytes_list, rfc_encoded_bytes_list):
+            self.assertEqual(rfc1924_b85decode(e), a)
+
+    def test_OverflowError_when_invalid_base85_byte_found(self):
+        self.assertRaises(OverflowError, rfc1924_b85decode, b(']]]]]'))
+
+    def test_OverflowError_when_not_decodable_chunk_found(self):
+        self.assertRaises(OverflowError, rfc1924_b85decode,
+                          b('|NsC')) # 0x03030303
+
+    def test_codec_identity(self):
+        self.assertEqual(
+            rfc1924_b85decode(rfc1924_b85encode(mercurial_bytes)),
+            mercurial_bytes)
+        self.assertEqual(
+            rfc1924_b85decode(rfc1924_b85encode(random_256_bytes)),
+            random_256_bytes)
+        self.assertEqual(
+            rfc1924_b85decode(rfc1924_b85encode(random_odd_bytes)),
+            random_odd_bytes)
+
+class Test_base85_ipv6_encoding(unittest2.TestCase):
+    def test_encoding(self):
+        self.assertEqual(ipv6_b85encode(ipv6_number), ipv6_encoded)
+        self.assertEqual(ipv6_b85encode(ipv6_number_2), ipv6_encoded_2)
+        self.assertEqual(ipv6_b85encode(ipv6_number_3), ipv6_encoded_3)
+
+    def test_decoding(self):
+        self.assertEqual(ipv6_b85decode(ipv6_encoded), ipv6_number)
+        self.assertEqual(ipv6_b85decode(ipv6_encoded_2), ipv6_number_2)
+        self.assertEqual(ipv6_b85decode(ipv6_encoded_3), ipv6_number_3)
+
+    def test_TypeError_when_unicode(self):
+        self.assertRaises(TypeError, ipv6_b85decode, unicode_string2)
+
+    def test_codec_identity(self):
+        self.assertEqual(ipv6_b85decode(ipv6_b85encode(ipv6_number)),
+                         ipv6_number)
+        self.assertEqual(ipv6_b85decode(ipv6_b85encode(ipv6_number_2)),
+                         ipv6_number_2)
+        self.assertEqual(ipv6_b85decode(ipv6_b85encode(ipv6_number_3)),
+                         ipv6_number_3)
+
+    def test_ValueError_when_negative(self):
+        self.assertRaises(ValueError, ipv6_b85encode, -1)
+
+    def test_OverflowError_when_greater_than_128_bit(self):
+        self.assertRaises(OverflowError, ipv6_b85encode, 1 << 128)
+
+    def test_ValueError_when_encoded_length_not_20(self):
+        self.assertRaises(ValueError, ipv6_b85decode,
+                          b('=r54lj&NUUO~Hi%c2ym0='))
+        self.assertRaises(ValueError, ipv6_b85decode,
+                          b('=r54lj&NUUO='))
+
+    def test_TypeError_when_not_number(self):
+        self.assertRaises(TypeError, ipv6_b85encode, None)
+
+    def test_ignores_whitespace(self):
+        self.assertEqual(ipv6_b85decode(b('=r5\t4lj&\nNUUO~   Hi%c2ym \x0b 0')),
+                         ipv6_number_2)
+
+    def test_OverflowError_when_stray_characters_found(self):
+        self.assertRaises(OverflowError, ipv6_b85decode,
+                          b('=r54lj&NUUO~Hi,./:[]'))

File mom/tests/test_mom_codec_integer.py

+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
+
+import unittest2
+from mom.builtins import b
+from mom.codec._alt_integer import uint_to_bytes_naive
+from mom.codec.integer import uint_to_bytes
+from mom.prime_sieve import sieve
+
+# Long value from Python-RSA.
+long_value = 71671831749689734735896910666236152091910950933161125188784836897624039426313152092699961904060141667369
+expected_fill_bytes = b('''\
+\x00\x01\xff\xff\xff\xff\xff\xff\xff\xff\x000 0\x0c\x06\x08*\x86H\x86\
+\xf7\r\x02\x05\x05\x00\x04\x10\xd6\xc7\xde\x19\xf6}\xb3#\xbdhI\xafDL\x04)''')
+expected_bytes = b('''\
+\x01\xff\xff\xff\xff\xff\xff\xff\xff\x000 0\x0c\x06\x08*\x86H\x86\
+\xf7\r\x02\x05\x05\x00\x04\x10\xd6\xc7\xde\x19\xf6}\xb3#\xbdhI\xafDL\x04)''')
+
+
+class Test_unsigned_integer_to_bytes(unittest2.TestCase):
+    def test_long_value(self):
+        self.assertEqual(uint_to_bytes(long_value),
+                         expected_bytes)
+        self.assertEqual(uint_to_bytes(long_value, fill_size=45),
+                         expected_fill_bytes)
+
+    def test_fill_size(self):
+        self.assertEqual(uint_to_bytes(0xc0ff, fill_size=4),
+                         b('\x00\x00\xc0\xff'))
+        self.assertEqual(uint_to_bytes(0xc0ffee, fill_size=6),
+                         b('\x00\x00\x00\xc0\xff\xee'))
+        self.assertEqual(uint_to_bytes(123456789, fill_size=6),
+                         b('\x00\x00\x07[\xcd\x15'))
+        self.assertEqual(uint_to_bytes(123456789, fill_size=7),
+                         b('\x00\x00\x00\x07[\xcd\x15'))
+
+    def test_overflow_allowed(self):
+        self.assertEqual(uint_to_bytes(0xc0ff, fill_size=1, overflow=True),
+                         b('\xc0\xff'))
+        self.assertEqual(uint_to_bytes(123456789, fill_size=3, overflow=True),
+                         b('\x07\x5b\xcd\x15'))
+        self.assertEqual(uint_to_bytes(0xf00dc0ffee, fill_size=4,
+                                       overflow=True),
+                         b('\xf0\x0d\xc0\xff\xee'))
+
+    def test_OverflowError_when_fill_size_insufficient(self):
+        self.assertRaises(OverflowError, uint_to_bytes, 0xffff,
+                          fill_size=1)
+        self.assertRaises(OverflowError, uint_to_bytes,
+                          123456789, fill_size=3)
+        self.assertRaises(OverflowError, uint_to_bytes,
+                          0xf00dc0ffee, fill_size=4)
+
+    def test_chunk_size(self):
+        self.assertEqual(uint_to_bytes(0xffffeeeeaa, chunk_size=4),
+                         b('\x00\x00\x00\xff\xff\xee\xee\xaa'))
+
+    def test_ValueError_when_both_fill_size_and_chunk_size_specified(self):
+        self.assertRaises(ValueError, uint_to_bytes, 0xff, 1, 1)
+
+    def test_TypeError_when_fill_size_is_not_an_integer(self):
+        self.assertRaises(TypeError, uint_to_bytes, 0xff, '', 0)
+
+    def test_TypeError_when_chunk_size_is_not_an_integer(self):
+        self.assertRaises(TypeError, uint_to_bytes, 0xff, 0, '')
+
+    def test_correctness(self):
+        self.assertEqual(uint_to_bytes(0xeeeeffff),
+                         b('\xee\xee\xff\xff'))
+        self.assertEqual(uint_to_bytes(0xeeeeff),
+                         b('\xee\xee\xff'))
+
+    def test_correctness_against_base_implementation(self):
+        # Slow test.
+        values = [
+            1 << 512,
+            1 << 8192,
+            1 << 77,
+        ]
+        for value in values:
+            self.assertEqual(uint_to_bytes(value),
+                             uint_to_bytes_naive(value),
+                             "Boom %d" % value)
+
+    def test_correctness_for_primes(self):
+        for prime in sieve:
+            self.assertEqual(uint_to_bytes(prime),
+                             uint_to_bytes_naive(prime),
+                             "Boom %d" % prime)
+
+    def test_zero(self):
+        self.assertEqual(uint_to_bytes(0), b('\x00'))
+        self.assertEqual(uint_to_bytes(0, 4), b('\x00') * 4)
+        self.assertEqual(uint_to_bytes(0, 7), b('\x00') * 7)
+        self.assertEqual(uint_to_bytes(0, 0, 1), b('\x00'))
+        self.assertEqual(uint_to_bytes(0, 0, 4), b('\x00') * 4)
+        self.assertEqual(uint_to_bytes(0, 0, 7), b('\x00') * 7)
+
+    def test_ValueError_when_not_unsigned_integer(self):
+        self.assertRaises(ValueError, uint_to_bytes, -1)
+
+    def test_TypeError_when_not_integer(self):
+        self.assertRaises(TypeError, uint_to_bytes, 2.4)
+        self.assertRaises(TypeError, uint_to_bytes, "")
+        self.assertRaises(TypeError, uint_to_bytes, b(''))
+        self.assertRaises(TypeError, uint_to_bytes, object)
+        self.assertRaises(TypeError, uint_to_bytes, dict())
+        self.assertRaises(TypeError, uint_to_bytes, set([]))
+        self.assertRaises(TypeError, uint_to_bytes, [])
+        self.assertRaises(TypeError, uint_to_bytes, ())

File mom/tests/test_mom_codec_json.py

+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
+from __future__ import absolute_import
+
+import unittest2
+from mom.codec.json import json_encode, json_decode
+from mom.codec.text import utf8_encode
+try:
+    unicode
+    from tests.constants import ufoo, json_ufoo, json_foo, \
+        json_unicode_value, unicode_value, x_byte
+except NameError:
+    from tests.py3kconstants import ufoo, json_ufoo, json_foo, \
+        json_unicode_value, unicode_value, x_byte
+
+
+class Test_decode(unittest2.TestCase):
+    def test_decode(self):
+        # decode accepts unicode only.
+        self.assertEqual(json_decode(json_ufoo), ufoo)
+
+    def test_raises_error_when_invalid_type(self):
+        self.assertRaises(TypeError, json_decode, json_foo)
+
+