#!/usr/bin/env python
#
# Copyright 2017 Google Inc. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

"""Write-only protobuf C++ code generator for a minimal runtime

This script uses a descriptor proto generated by protoc and the descriptor_pb2
distributed with python protobuf to iterate through the fields in a proto
and write out simple C++ data objects with serialization methods.  The generated
files depend on a tiny runtime implemented in src/proto.h and src/proto.cc.
"""

from __future__ import print_function

import unittest

try:
    from StringIO import StringIO
except ImportError:
    from io import StringIO

import generate_proto_header

class TestWriteLines(unittest.TestCase):
    def setUp(self):
        self.out = StringIO()
        self.w = generate_proto_header.Writer(self.out)

    def test_single_line(self):
        self.w.writelines('abc')
        self.assertEqual(self.out.getvalue(), 'abc\n')

    def test_multi_line(self):
        self.w.writelines("""
            abc
            def
        """)
        self.assertEqual(self.out.getvalue(), 'abc\ndef\n')

    def test_multi_line_with_indent(self):
        self.w.writelines("""
            abc
              def
        """)
        self.assertEqual(self.out.getvalue(), 'abc\n  def\n')

    def test_string_writer(self):
        w = self.w.stringwriter()
        w.writelines("""
            abc
              def
        """)
        self.w.writelines(w.string())
        self.assertEqual(self.out.getvalue(), 'abc\n  def\n')

    def test_string_writer_prefix(self):
        w = self.w.stringwriter(
            prefix="""
                abc
                  def
            """,
            suffix="""
                lmnop
            """)
        w.writelines("""
            ghi
              jk
        """)
        self.w.writelines(w.string())
        self.assertEqual(self.out.getvalue(),
                         'abc\n  def\n  ghi\n    jk\nlmnop\n')

if __name__ == '__main__':
    unittest.main()
