wip: still banging against weirdness w/ bson regexps
This commit is contained in:
parent
3e6d3f3cbe
commit
6efb96a893
38
bson.py
38
bson.py
@ -195,6 +195,24 @@ def _get_date(data):
|
||||
def _get_null(data):
|
||||
return (None, data)
|
||||
|
||||
_re_stack = []
|
||||
|
||||
def _get_regex(data):
|
||||
(pattern, data) = _get_c_string(data)
|
||||
print "out %r" % pattern
|
||||
(bson_flags, data) = _get_c_string(data)
|
||||
flags = 0
|
||||
if bson_flags.find("i") > -1:
|
||||
flags |= re.IGNORECASE
|
||||
if bson_flags.find("m") > -1:
|
||||
flags |= re.MULTILINE
|
||||
print "out %r" % flags
|
||||
res = re.compile(pattern, flags)
|
||||
other = _re_stack.pop(0)
|
||||
assert res.pattern == other.pattern, "%r %r" % (res.pattern, other.pattern)
|
||||
assert res == other, "%r %r" % (res.pattern, other.pattern)
|
||||
return (re.compile(pattern, flags), data)
|
||||
|
||||
_element_getter = {
|
||||
"\x01": _get_number,
|
||||
"\x02": _get_string,
|
||||
@ -206,7 +224,7 @@ _element_getter = {
|
||||
"\x08": _get_boolean,
|
||||
"\x09": _get_date,
|
||||
"\x0A": _get_null,
|
||||
# "\x0B": _get_regex,
|
||||
"\x0B": _get_regex,
|
||||
# "\x0C": _get_ref,
|
||||
# "\x0D": _get_code,
|
||||
# "\x0E": _get_symbol,
|
||||
@ -238,6 +256,7 @@ def _int_to_bson(int):
|
||||
def _int_64_to_bson(int):
|
||||
return struct.pack("<q", int)
|
||||
|
||||
_RE_TYPE = type(_valid_array_name)
|
||||
def _value_to_bson(value):
|
||||
if isinstance(value, types.FloatType):
|
||||
return ("\x01", struct.pack("<d", value))
|
||||
@ -261,9 +280,20 @@ def _value_to_bson(value):
|
||||
return ("\x09", _int_64_to_bson(millis))
|
||||
if isinstance(value, types.NoneType):
|
||||
return ("\x0A", "")
|
||||
if isinstance(value, _RE_TYPE):
|
||||
_re_stack.append(value)
|
||||
pattern = value.pattern
|
||||
print "in %r" % pattern
|
||||
print "in %r" % value.flags
|
||||
flags = "g" # TODO should it be global by default?
|
||||
if value.flags & re.IGNORECASE:
|
||||
flags += "i"
|
||||
if value.flags & re.MULTILINE:
|
||||
flags += "m"
|
||||
return ("\x0B", _make_c_string(pattern) + _make_c_string(flags))
|
||||
if isinstance(value, types.IntType):
|
||||
return ("\x10", _int_to_bson(value))
|
||||
raise InvalidDocument("cannot convert value of type %s to bson" % value.__class__)
|
||||
raise InvalidDocument("cannot convert value of type %s to bson" % type(value))
|
||||
|
||||
def _element_to_bson(key, value):
|
||||
if not isinstance(key, types.StringTypes):
|
||||
@ -388,6 +418,8 @@ class TestBSON(unittest.TestCase):
|
||||
"\x0B\x00\x00\x00\x0A\x74\x65\x73\x74\x00\x00")
|
||||
self.assertEqual(BSON.from_dict({"date": datetime.datetime(2007, 1, 7, 19, 30, 11)}),
|
||||
"\x13\x00\x00\x00\x09\x64\x61\x74\x65\x00\x38\xBE\x1C\xFF\x0F\x01\x00\x00\x00")
|
||||
# self.assertEqual(BSON.from_dict({"regex": re.compile("a*b", re.IGNORECASE)}),
|
||||
# "\x13\x00\x00\x00\x0B\x72\x65\x67\x65\x78\x00\x61\x2A\x62\x00\x67\x69\x00\x00")
|
||||
|
||||
def test_from_then_to_dict(self):
|
||||
def helper(dict):
|
||||
@ -401,6 +433,8 @@ class TestBSON(unittest.TestCase):
|
||||
helper({"an array": [1, True, 3.8, u"world"]})
|
||||
helper({"an object": {"test": u"something"}})
|
||||
|
||||
# helper({"re": re.compile(u"", re.MULTILINE)})
|
||||
|
||||
def from_then_to_dict(dict):
|
||||
return dict == (BSON.from_dict(dict)).to_dict()
|
||||
|
||||
|
||||
@ -2,6 +2,7 @@ import random
|
||||
import sys
|
||||
import traceback
|
||||
import datetime
|
||||
import re
|
||||
|
||||
gen_target = 100
|
||||
examples = 5
|
||||
@ -9,6 +10,9 @@ examples = 5
|
||||
def lift(value):
|
||||
return lambda: value
|
||||
|
||||
def choose_lifted(list):
|
||||
return lambda: random.choice(list)
|
||||
|
||||
def choose(list):
|
||||
return lambda: random.choice(list)()
|
||||
|
||||
@ -30,7 +34,7 @@ def gen_printable_char():
|
||||
def gen_printable_string(gen_length):
|
||||
return lambda: "".join(gen_list(gen_printable_char(), gen_length)())
|
||||
|
||||
def gen_char():
|
||||
def gen_char(set=None):
|
||||
return lambda: chr(random.randint(0, 255))
|
||||
|
||||
def gen_string(gen_length):
|
||||
@ -63,6 +67,17 @@ def gen_dict(gen_key, gen_value, gen_length):
|
||||
return result
|
||||
return lambda: a_dict(gen_key, gen_value, gen_length())
|
||||
|
||||
def gen_regexp(gen_length):
|
||||
pattern = lambda: u"".join(gen_list(choose_lifted(u"abc."), gen_length)())
|
||||
def gen_flags():
|
||||
flags = 0
|
||||
if random.random() > 0.5:
|
||||
flags = flags | re.IGNORECASE
|
||||
if random.random() > 0.5:
|
||||
flags = flags | re.MULTILINE
|
||||
return flags
|
||||
return lambda: re.compile(pattern(), gen_flags())
|
||||
|
||||
def gen_mongo_value(depth):
|
||||
choices = [gen_unicode(gen_range(0, 50)),
|
||||
gen_string(gen_range(0, 1000)),
|
||||
@ -70,6 +85,7 @@ def gen_mongo_value(depth):
|
||||
gen_float(),
|
||||
gen_boolean(),
|
||||
gen_datetime(),
|
||||
gen_regexp(gen_range(0, 20)),
|
||||
lift(None),]
|
||||
if depth > 0:
|
||||
choices.append(gen_mongo_list(depth))
|
||||
@ -93,8 +109,10 @@ def check(predicate, generator):
|
||||
case = generator()
|
||||
try:
|
||||
if not predicate(case):
|
||||
print "FAIL"
|
||||
counter_examples.append(repr(case))
|
||||
except:
|
||||
print "FAIL"
|
||||
counter_examples.append("%r : %s" % (case, traceback.format_exc()))
|
||||
return counter_examples
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user