forked from mirror/yaml-cpp
You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
224 lines
7.2 KiB
Python
224 lines
7.2 KiB
Python
import sys
|
|
import yaml
|
|
import hashlib
|
|
|
|
DEFINE = 'YAML_GEN_TESTS'
|
|
EVENT_COUNT = 5
|
|
|
|
def encode_stream(line):
|
|
for c in line:
|
|
if c == '\n':
|
|
yield '\\n'
|
|
elif c == '"':
|
|
yield '\\"'
|
|
elif c == '\t':
|
|
yield '\\t'
|
|
elif ord(c) < 0x20:
|
|
yield '\\x' + hex(ord(c))
|
|
else:
|
|
yield c
|
|
|
|
def encode(line):
|
|
return ''.join(encode_stream(line))
|
|
|
|
def doc_start(implicit=False):
|
|
if implicit:
|
|
return {'emit': '', 'handle': 'OnDocumentStart(_)'}
|
|
else:
|
|
return {'emit': 'BeginDoc', 'handle': 'OnDocumentStart(_)'}
|
|
|
|
def doc_end(implicit=False):
|
|
if implicit:
|
|
return {'emit': '', 'handle': 'OnDocumentEnd()'}
|
|
else:
|
|
return {'emit': 'EndDoc', 'handle': 'OnDocumentEnd()'}
|
|
|
|
def scalar(value, tag='', anchor='', anchor_id=0):
|
|
emit = []
|
|
handle = []
|
|
if tag:
|
|
emit += ['VerbatimTag("%s")' % encode(tag)]
|
|
if anchor:
|
|
emit += ['Anchor("%s")' % encode(anchor)]
|
|
handle += ['OnAnchor(_, "%s")' % encode(anchor)]
|
|
if tag:
|
|
out_tag = encode(tag)
|
|
else:
|
|
if value == encode(value):
|
|
out_tag = '?'
|
|
else:
|
|
out_tag = '!'
|
|
emit += ['"%s"' % encode(value)]
|
|
handle += ['OnScalar(_, "%s", %s, "%s")' % (out_tag, anchor_id, encode(value))]
|
|
return {'emit': emit, 'handle': handle}
|
|
|
|
def comment(value):
|
|
return {'emit': 'Comment("%s")' % value, 'handle': ''}
|
|
|
|
def seq_start(tag='', anchor='', anchor_id=0, style='_'):
|
|
emit = []
|
|
handle = []
|
|
if tag:
|
|
emit += ['VerbatimTag("%s")' % encode(tag)]
|
|
if anchor:
|
|
emit += ['Anchor("%s")' % encode(anchor)]
|
|
handle += ['OnAnchor(_, "%s")' % encode(anchor)]
|
|
if tag:
|
|
out_tag = encode(tag)
|
|
else:
|
|
out_tag = '?'
|
|
emit += ['BeginSeq']
|
|
handle += ['OnSequenceStart(_, "%s", %s, %s)' % (out_tag, anchor_id, style)]
|
|
return {'emit': emit, 'handle': handle}
|
|
|
|
def seq_end():
|
|
return {'emit': 'EndSeq', 'handle': 'OnSequenceEnd()'}
|
|
|
|
def map_start(tag='', anchor='', anchor_id=0, style='_'):
|
|
emit = []
|
|
handle = []
|
|
if tag:
|
|
emit += ['VerbatimTag("%s")' % encode(tag)]
|
|
if anchor:
|
|
emit += ['Anchor("%s")' % encode(anchor)]
|
|
handle += ['OnAnchor(_, "%s")' % encode(anchor)]
|
|
if tag:
|
|
out_tag = encode(tag)
|
|
else:
|
|
out_tag = '?'
|
|
emit += ['BeginMap']
|
|
handle += ['OnMapStart(_, "%s", %s, %s)' % (out_tag, anchor_id, style)]
|
|
return {'emit': emit, 'handle': handle}
|
|
|
|
def map_end():
|
|
return {'emit': 'EndMap', 'handle': 'OnMapEnd()'}
|
|
|
|
def gen_templates():
|
|
yield [[doc_start(), doc_start(True)],
|
|
[scalar('foo'), scalar('foo\n'), scalar('foo', 'tag'), scalar('foo', '', 'anchor', 1)],
|
|
[doc_end(), doc_end(True)]]
|
|
yield [[doc_start(), doc_start(True)],
|
|
[seq_start()],
|
|
[[], [scalar('foo')], [scalar('foo', 'tag')], [scalar('foo', '', 'anchor', 1)], [scalar('foo', 'tag', 'anchor', 1)], [scalar('foo'), scalar('bar')], [scalar('foo', 'tag', 'anchor', 1), scalar('bar', 'tag', 'other', 2)]],
|
|
[seq_end()],
|
|
[doc_end(), doc_end(True)]]
|
|
yield [[doc_start(), doc_start(True)],
|
|
[map_start()],
|
|
[[], [scalar('foo'), scalar('bar')], [scalar('foo', 'tag', 'anchor', 1), scalar('bar', 'tag', 'other', 2)]],
|
|
[map_end()],
|
|
[doc_end(), doc_end(True)]]
|
|
yield [[doc_start(True)],
|
|
[map_start()],
|
|
[[scalar('foo')], [seq_start(), scalar('foo'), seq_end()], [map_start(), scalar('foo'), scalar('bar'), map_end()]],
|
|
[[scalar('foo')], [seq_start(), scalar('foo'), seq_end()], [map_start(), scalar('foo'), scalar('bar'), map_end()]],
|
|
[map_end()],
|
|
[doc_end(True)]]
|
|
yield [[doc_start(True)],
|
|
[seq_start()],
|
|
[[scalar('foo')], [seq_start(), scalar('foo'), seq_end()], [map_start(), scalar('foo'), scalar('bar'), map_end()]],
|
|
[[scalar('foo')], [seq_start(), scalar('foo'), seq_end()], [map_start(), scalar('foo'), scalar('bar'), map_end()]],
|
|
[seq_end()],
|
|
[doc_end(True)]]
|
|
|
|
def expand(template):
|
|
if len(template) == 0:
|
|
pass
|
|
elif len(template) == 1:
|
|
for item in template[0]:
|
|
if isinstance(item, list):
|
|
yield item
|
|
else:
|
|
yield [item]
|
|
else:
|
|
for car in expand(template[:1]):
|
|
for cdr in expand(template[1:]):
|
|
yield car + cdr
|
|
|
|
|
|
def gen_events():
|
|
for template in gen_templates():
|
|
for events in expand(template):
|
|
base = list(events)
|
|
for i in range(0, len(base)+1):
|
|
cpy = list(base)
|
|
cpy.insert(i, comment('comment'))
|
|
yield cpy
|
|
|
|
def gen_tests():
|
|
for events in gen_events():
|
|
name = 'test' + hashlib.sha1(''.join(yaml.dump(event) for event in events)).hexdigest()[:20]
|
|
yield {'name': name, 'events': events}
|
|
|
|
class Writer(object):
|
|
def __init__(self, out):
|
|
self.out = out
|
|
self.indent = 0
|
|
|
|
def writeln(self, s):
|
|
self.out.write('%s%s\n' % (' ' * self.indent, s))
|
|
|
|
class Scope(object):
|
|
def __init__(self, writer, name, indent):
|
|
self.writer = writer
|
|
self.name = name
|
|
self.indent = indent
|
|
|
|
def __enter__(self):
|
|
self.writer.writeln('%s {' % self.name)
|
|
self.writer.indent += self.indent
|
|
|
|
def __exit__(self, type, value, traceback):
|
|
self.writer.indent -= self.indent
|
|
self.writer.writeln('}')
|
|
|
|
def create_emitter_tests(out):
|
|
out = Writer(out)
|
|
|
|
includes = [
|
|
'handler_test.h',
|
|
'yaml-cpp/yaml.h',
|
|
'gmock/gmock.h',
|
|
'gtest/gtest.h',
|
|
]
|
|
for include in includes:
|
|
out.writeln('#include "%s"' % include)
|
|
out.writeln('')
|
|
|
|
usings = [
|
|
'::testing::_',
|
|
]
|
|
for using in usings:
|
|
out.writeln('using %s;' % using)
|
|
out.writeln('')
|
|
|
|
with Scope(out, 'namespace YAML', 0) as _:
|
|
with Scope(out, 'namespace', 0) as _:
|
|
out.writeln('')
|
|
out.writeln('typedef HandlerTest GenEmitterTest;')
|
|
out.writeln('')
|
|
tests = list(gen_tests())
|
|
|
|
for test in tests:
|
|
with Scope(out, 'TEST_F(%s, %s)' % ('GenEmitterTest', test['name']), 2) as _:
|
|
out.writeln('Emitter out;')
|
|
for event in test['events']:
|
|
emit = event['emit']
|
|
if isinstance(emit, list):
|
|
for e in emit:
|
|
out.writeln('out << %s;' % e)
|
|
elif emit:
|
|
out.writeln('out << %s;' % emit)
|
|
out.writeln('')
|
|
for event in test['events']:
|
|
handle = event['handle']
|
|
if isinstance(handle, list):
|
|
for e in handle:
|
|
out.writeln('EXPECT_CALL(handler, %s);' % e)
|
|
elif handle:
|
|
out.writeln('EXPECT_CALL(handler, %s);' % handle)
|
|
out.writeln('Parse(out.c_str());')
|
|
out.writeln('')
|
|
|
|
if __name__ == '__main__':
|
|
create_emitter_tests(sys.stdout)
|