| 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) |