def test_list_with_pattern(): data = [ [1, 2], [1, 2, 3], [1, 2, 3, 4], ] pattern = List(data, content=[Int(Counter(j for i in data for j in i))]) assert pattern.lengths.min == 2 assert pattern.lengths.max == 4 assert pattern.content is not None assert str(pattern) == '[int range=1..4]' assert iselement(xml(pattern).find('content')) assert iselement(xml(pattern).find('content').find('int'))
def test_bool_strrepr(): pattern = Bool.from_strings(Counter(('f', 't')), 'f|t') assert pattern == StrRepr(Bool(Counter((False, True))), pattern='f|t') assert pattern.size == 1 assert xml(pattern).tag == 'strof' assert iselement(xml(pattern).find('bool')) assert pattern + pattern == pattern with pytest.raises(TypeError): pattern + 100 pattern.validate('t') with pytest.raises(ValueError): pattern.validate('true') with pytest.raises(TypeError): pattern.validate(True)
def test_list_with_long_pattern(): data = [ [ {'num': 1, 'label': 'foo', 'active': 't'}, {'num': 2, 'label': 'bar', 'active': 't'}, {'num': 3, 'label': 'baz'}, {'num': 4, 'label': 'quux', 'active': 'f'}, {'num': 5, 'label': 'xyzzy', 'active': 'f'}, {'num': 6, 'label': 'six', 'active': 'f'}, {'num': 7, 'label': 'seven'}, {'num': 8, 'label': 'eight'}, {'num': 9, 'label': 'nine'}, {'num': 10, 'label': 'foo'}, ] ] pattern = List(data, content=[Dict( data[0], content=[ DictField( Field('active', count=5, optional=True), StrRepr(Bool(Counter({False, True})), pattern="f|t")), DictField( Field('label', count=9, optional=False), Str(Counter([ 'foo', 'bar', 'baz', 'quux', 'xyzzy', 'six', 'seven', 'eight', 'nine', 'foo', ]), pattern=None)), DictField( Field('num', count=10, optional=False), Int(Counter(range(1, 11)))), ])]) assert pattern.lengths.min == pattern.lengths.max == 10 assert str(pattern) == """\ [ { 'active'*: str of bool pattern=f|t, 'label': str, 'num': int range=1..10 } ]""" assert iselement(xml(pattern).find('content')) assert iselement(xml(pattern).find('content/dict')) assert iselement(xml(pattern).find( 'content/dict/content/field/str/values/sample/more')) assert pattern + pattern == pattern assert pattern == pattern + pattern assert pattern != Int(Counter((1, 2, 3)))
def test_float_strrepr(): data = {0.0, 1.0, 1000.0} pattern = Float.from_strings(Counter(str(f) for f in data), 'f', 1) assert pattern == StrRepr(Float(Counter(data)), pattern='f') assert str(pattern) == 'str of float range=0..1000 pattern=f' assert xml(pattern).tag == 'strof' assert iselement(xml(pattern).find('float')) assert pattern + pattern == pattern assert pattern == pattern + pattern assert pattern != Str(Counter(('a', 'b', 'c'))) with pytest.raises(TypeError): pattern + 100 pattern.validate('1.0') with pytest.raises(TypeError): pattern.validate(1.0) with pytest.raises(ValueError): pattern.validate('2000.0')
def test_num_repr(): pattern = NumRepr(DateTime(Counter(( dt.datetime.utcfromtimestamp(0), dt.datetime.utcfromtimestamp(1), dt.datetime.utcfromtimestamp(86400), ))), pattern=Int) assert str(pattern) == 'int of datetime range=1970-01-01 00:00:00..1970-01-02 00:00:00' assert xml(pattern).tag == 'intof' pattern = NumRepr(DateTime(Counter(( dt.datetime.utcfromtimestamp(0.0), dt.datetime.utcfromtimestamp(1.0), dt.datetime.utcfromtimestamp(86400.0), ))), pattern=Float) assert str(pattern) == 'float of datetime range=1970-01-01 00:00:00..1970-01-02 00:00:00' assert xml(pattern).tag == 'floatof' assert pattern == pattern + pattern assert pattern + pattern == pattern assert pattern != Int(Counter((1, 2, 3)))
def test_int_strrepr(): data = {1, 2, 3, 1000} pattern = Int.from_strings(Counter(str(i) for i in data), 'd', 1) assert pattern == StrRepr(Int(Counter(data)), pattern='d') assert pattern.size == 1 assert str(pattern) == 'str of int range=1..1.0K pattern=d' assert xml(pattern).tag == 'strof' assert iselement(xml(pattern).find('int')) assert pattern + pattern == pattern assert pattern == pattern + pattern assert pattern != Str(Counter(('a', 'b', 'c'))) with pytest.raises(TypeError): pattern + 100 pattern.validate('5') with pytest.raises(TypeError): pattern.validate(1) with pytest.raises(ValueError): pattern.validate('2000')
def test_dict_with_pattern(): data = [ {}, {'a': 1}, {'a': 1, 'b': 2}, ] pattern = Dict(data, content=[ DictField( Str(FrozenCounter(('a', 'a', 'b')), pattern=[any_char]), Int(FrozenCounter((1, 1, 2))) )]) assert pattern.size == 3 assert pattern.lengths.min == 0 assert pattern.lengths.max == 2 assert str(pattern) == '{str pattern=.: int range=1..2}' assert repr(pattern) == ( 'Dict(content=[DictField(key=Str(pattern=[AnyChar()], values=...), ' 'value=Int(values=...))])') assert iselement(xml(pattern).find('content')) assert iselement(xml(pattern).find('content').find('field')) assert iselement(xml(pattern).find('content').find('field').find('str'))
def test_bool(): pattern = Bool(Counter((False, True))) assert pattern.size == 1 assert xml(pattern).tag == 'bool' assert pattern + pattern == pattern with pytest.raises(TypeError): pattern + 100 pattern.validate(True) pattern.validate(1) with pytest.raises(ValueError): pattern.validate(2) with pytest.raises(TypeError): pattern.validate('true')
def test_tuple_with_pattern(): data = [ ('foo', 1), ('bar', 2), ('baz', 3), ] pattern = Tuple(data, content=[ TupleField( Field(0, count=3, optional=False), Str([t[0] for t in data], pattern=[any_char, any_char, any_char])), TupleField(Field(1, count=3, optional=False), Int([t[1] for t in data])), ]) assert pattern.size == 5 assert pattern.lengths.min == 2 assert pattern.lengths.max == 2 assert str(pattern) == '(str pattern=..., int range=1..3)' assert repr(pattern) == ( "Tuple(content=[" "TupleField(value=Str(pattern=[AnyChar(), AnyChar(), AnyChar()], values=...)), " "TupleField(value=Int(values=...))])") assert iselement(xml(pattern).find('content')) assert iselement(xml(pattern).find('content').find('str'))
def test_datetime_strrepr(): iso_fmt = '%Y-%m-%d %H:%M:%S' data = { dt.datetime.strptime('1970-01-01 00:00:00', iso_fmt), dt.datetime.strptime('1970-01-01 00:00:01', iso_fmt), dt.datetime.strptime('1970-01-02 00:00:00', iso_fmt), dt.datetime.strptime('1970-02-01 00:00:00', iso_fmt), } pattern = DateTime.from_strings( Counter(d.strftime(iso_fmt) for d in data), iso_fmt) assert pattern == StrRepr(DateTime(Counter(data)), pattern=iso_fmt) assert pattern.size == 1 assert str(pattern) == 'str of datetime range=1970-01-01 00:00:00..1970-02-01 00:00:00 pattern=%Y-%m-%d %H:%M:%S' assert xml(pattern).tag == 'strof' assert iselement(xml(pattern).find('datetime')) assert pattern + pattern == pattern assert pattern == pattern + pattern assert pattern != Str(Counter(('a', 'b', 'c'))) pattern.validate('1970-01-01 00:30:00') with pytest.raises(TypeError): pattern.validate(86400) with pytest.raises(ValueError): pattern.validate('1980-01-01 00:00:00')
def test_str_repr(): pattern = StrRepr(Int(Counter({1, 2, 3, 4})), pattern='d') assert str(pattern) == 'str of int range=1..4 pattern=d' assert xml(pattern).tag == 'strof' assert pattern.values.unique assert pattern + pattern == pattern assert pattern == pattern + pattern pattern2 = StrRepr(DateTime(Counter((dt.datetime.now(),))), pattern='%Y-%m-%dT%H:%M:%S') assert pattern != pattern2 pattern.validate('1') with pytest.raises(TypeError): pattern.validate(1) with pytest.raises(ValueError): pattern.validate('a')
def test_float(): data = {0.0, 1.0, 1000.0} pattern = Float(Counter(data)) assert str(pattern) == 'float range=0..1000' assert xml(pattern).tag == 'float' assert pattern + pattern == pattern assert pattern == pattern + pattern assert pattern != Str(Counter(('a', 'b', 'c'))) with pytest.raises(TypeError): pattern + 100 pattern.validate(1.0) with pytest.raises(TypeError): pattern.validate('1.0') with pytest.raises(ValueError): pattern.validate(2000.0)
def test_list(): data = [ [], [1], [1, 2, 3], ] pattern = List(data) assert pattern.lengths.min == 0 assert pattern.lengths.max == 3 assert pattern.content is None assert str(pattern) == '[]' assert xml(pattern).tag == 'list' pattern.validate([]) with pytest.raises(TypeError): pattern.validate('foo')
def test_int(): data = {1, 2, 3, 1000} pattern = Int(Counter(data)) assert pattern.size == 1 assert str(pattern) == 'int range=1..1.0K' assert xml(pattern).tag == 'int' assert pattern + pattern == pattern assert pattern == pattern + pattern with pytest.raises(TypeError): pattern + 100 pattern.validate(5) with pytest.raises(TypeError): pattern.validate('1') with pytest.raises(ValueError): pattern.validate(2000)
def test_dict(): data = [ {}, {'a': 1}, {'a': 1, 'b': 2}, ] pattern = Dict(data) assert pattern.lengths.min == 0 assert pattern.lengths.max == 2 assert pattern.content is None assert str(pattern) == '{}' assert repr(pattern) == 'Dict(content=None)' assert xml(pattern).tag == 'dict' pattern.validate({}) with pytest.raises(TypeError): pattern.validate('foo')
def test_value(): pattern = Value(sample=[]) assert str(pattern) == 'value' assert repr(pattern) == 'Value()' assert pattern.size == 1 assert xml(pattern).tag == 'value' assert Value(sample=[]) == Value(sample=[1, 'foo']) assert Value(sample=[]) == Empty() assert Value(sample=[]) == Int(Counter((1, 2, 3))) assert Int(Counter((1, 2, 3))) == Value(sample=[]) assert Value(sample=[]) != 'foo' assert Value(sample=[]) + Empty() == Value(sample=[]) with pytest.raises(TypeError): Value(sample=[]) + 1 pattern.validate(None) pattern.validate(1) pattern.validate('foo')
def test_tuple(): data = [ (), (1,), (1, 2, 3), ] pattern = Tuple(data) assert pattern.lengths.min == 0 assert pattern.lengths.max == 3 assert str(pattern) == '()' assert repr(pattern) == 'Tuple(content=None)' assert xml(pattern).tag == 'tuple' pattern.validate(()) with pytest.raises(TypeError): pattern.validate('foo') with pytest.raises(ValueError): pattern.validate((1, 2, 3, 4))
def test_url(): data = [ 'http://localhost', 'https://structa.readthedocs.io/', ] pattern = URL(Counter(data), pattern=[ CharClass(c) for c in 'http'] + [ AnyChar() for c in 's://structa.readthedocs.io/']) assert str(pattern) == 'URL' assert xml(pattern).tag == 'url' pattern.validate('http://localhost.local') with pytest.raises(ValueError): pattern.validate('foo') with pytest.raises(ValueError): pattern.validate('httpf://localhost') with pytest.raises(TypeError): pattern.validate(100)
def test_str(): data = ['foo', 'bar', 'baz', 'quux'] pattern = Str(Counter(data)) assert pattern.lengths.min == 3 assert pattern.lengths.max == 4 assert pattern.pattern is None assert pattern.values.unique assert pattern.size == 1 assert Counter(pattern.sample) == Counter(data) assert str(pattern) == 'str' assert xml(pattern).tag == 'str' assert pattern + pattern == pattern assert pattern == pattern + pattern assert pattern != Int(Counter((1, 2, 3))) with pytest.raises(TypeError): pattern + 100 pattern.validate('blah') with pytest.raises(ValueError): pattern.validate('')
def test_stats_xml(): s1 = Stats.from_sample(Counter(range(10))) x1 = xml(s1) x2 = fromstring( '<stats>' '<summary values="10" count="10" unique="unique">' '<min>0</min><q1>2</q1><q2>5</q2><q3>7</q3><max>9</max>' '<graph>' '<fill>..</fill>' '<lit>1</lit>' '<fill>..</fill>' '<lit>2</lit>' '<fill>.</fill>' '<lit>3</lit>' '<fill>..</fill>' '</graph>' '</summary>' '</stats>' ) assert compare_etree(x1, x2)
def test_datetime(): iso_fmt = '%Y-%m-%d %H:%M:%S' data = { dt.datetime.strptime('1970-01-01 00:00:00', iso_fmt), dt.datetime.strptime('1970-01-01 00:00:01', iso_fmt), dt.datetime.strptime('1970-01-02 00:00:00', iso_fmt), dt.datetime.strptime('1970-02-01 00:00:00', iso_fmt), } pattern = DateTime(Counter(data)) assert pattern.size == 1 assert str(pattern) == 'datetime range=1970-01-01 00:00:00..1970-02-01 00:00:00' assert xml(pattern).tag == 'datetime' assert pattern + pattern == pattern assert pattern == pattern + pattern assert pattern != Str(Counter(('a', 'b', 'c'))) pattern.validate(datetime.strptime('1970-01-01 00:30:00', iso_fmt)) with pytest.raises(TypeError): pattern.validate(86400) with pytest.raises(ValueError): pattern.validate(datetime.strptime('1980-01-01 00:00:00', iso_fmt))
def test_empty(): pattern = Empty() assert str(pattern) == '' assert repr(pattern) == 'Empty()' assert pattern.size == 0 assert xml(pattern).tag == 'empty' assert Empty() == Empty() assert Empty() == Value(sample=[]) assert Empty() == Int(Counter((1, 2, 3))) assert Int(Counter((1, 2, 3))) == Empty() assert Empty() != 'foo' assert Empty() + Value(sample=[]) == Value(sample=[]) f = Field(value='foo', count=5, optional=False) assert Empty() + f == f assert (Empty() + f).optional f = Field(value='foo', count=5, optional=True) assert Empty() + f == f assert (Empty() + f).optional with pytest.raises(TypeError): Empty() + 1 pattern.validate(None) pattern.validate(1) pattern.validate('foo')
def test_any_char_xml(): assert tostring(xml(AnyChar())) == b'<pat>.</pat>'
def test_pattern(): assert Type() != None assert tostring(xml(Type())) == b'<type/>'
def test_char_class_xml(): assert tostring(xml(CharClass(''))) == b'<pat/>' assert tostring(xml(CharClass('a'))) == b'<lit>a</lit>' assert tostring(xml(CharClass('abcd'))) == b'<pat>[a-d]</pat>' assert tostring(xml(CharClass('0123456789'))) == b'<pat>d</pat>'