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