# Copyright 2019 Google LLC
#
# 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
#
#     https://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.

"""Tests for parser_types."""

import unittest
from compiler.util import ir_pb2
from compiler.util import parser_types


class PositionTest(unittest.TestCase):
  """Tests for Position-related functions in parser_types."""

  def test_format_position(self):
    self.assertEqual(
        "1:2", parser_types.format_position(ir_pb2.Position(line=1, column=2)))


class LocationTest(unittest.TestCase):
  """Tests for Location-related functions in parser_types."""

  def test_make_location(self):
    self.assertEqual(ir_pb2.Location(start=ir_pb2.Position(line=1,
                                                           column=2),
                                     end=ir_pb2.Position(line=3,
                                                         column=4),
                                     is_synthetic=False),
                     parser_types.make_location((1, 2), (3, 4)))
    self.assertEqual(
        ir_pb2.Location(start=ir_pb2.Position(line=1,
                                              column=2),
                        end=ir_pb2.Position(line=3,
                                            column=4),
                        is_synthetic=False),
        parser_types.make_location(ir_pb2.Position(line=1,
                                                   column=2),
                                   ir_pb2.Position(line=3,
                                                   column=4)))

  def test_make_synthetic_location(self):
    self.assertEqual(
        ir_pb2.Location(start=ir_pb2.Position(line=1, column=2),
                        end=ir_pb2.Position(line=3, column=4),
                        is_synthetic=True),
        parser_types.make_location((1, 2), (3, 4), True))
    self.assertEqual(
        ir_pb2.Location(start=ir_pb2.Position(line=1, column=2),
                        end=ir_pb2.Position(line=3, column=4),
                        is_synthetic=True),
        parser_types.make_location(ir_pb2.Position(line=1, column=2),
                                   ir_pb2.Position(line=3, column=4),
                                   True))

  def test_make_location_type_checks(self):
    self.assertRaises(ValueError, parser_types.make_location, [1, 2], (1, 2))
    self.assertRaises(ValueError, parser_types.make_location, (1, 2), [1, 2])

  def test_make_location_logic_checks(self):
    self.assertRaises(ValueError, parser_types.make_location, (3, 4), (1, 2))
    self.assertRaises(ValueError, parser_types.make_location, (1, 3), (1, 2))
    self.assertTrue(parser_types.make_location((1, 2), (1, 2)))

  def test_format_location(self):
    self.assertEqual("1:2-3:4",
                     parser_types.format_location(parser_types.make_location(
                         (1, 2), (3, 4))))

  def test_parse_location(self):
    self.assertEqual(parser_types.make_location((1, 2), (3, 4)),
                     parser_types.parse_location("1:2-3:4"))
    self.assertEqual(parser_types.make_location((1, 2), (3, 4)),
                     parser_types.parse_location("  1  :  2  -    3 :   4  "))


class TokenTest(unittest.TestCase):
  """Tests for parser_types.Token."""

  def test_str(self):
    self.assertEqual("FOO 'bar' 1:2-3:4", str(parser_types.Token(
        "FOO", "bar", parser_types.make_location((1, 2), (3, 4)))))


class ProductionTest(unittest.TestCase):
  """Tests for parser_types.Production."""

  def test_parse(self):
    self.assertEqual(parser_types.Production(lhs="A",
                                             rhs=("B", "C")),
                     parser_types.Production.parse("A -> B C"))
    self.assertEqual(parser_types.Production(lhs="A",
                                             rhs=("B",)),
                     parser_types.Production.parse("A -> B"))
    self.assertEqual(parser_types.Production(lhs="A",
                                             rhs=("B", "C")),
                     parser_types.Production.parse("  A   ->   B   C  "))
    self.assertEqual(parser_types.Production(lhs="A",
                                             rhs=tuple()),
                     parser_types.Production.parse("A ->"))
    self.assertEqual(parser_types.Production(lhs="A",
                                             rhs=tuple()),
                     parser_types.Production.parse("A ->  "))
    self.assertEqual(parser_types.Production(lhs="FOO",
                                             rhs=('"B"', "x*")),
                     parser_types.Production.parse('FOO -> "B" x*'))
    self.assertRaises(SyntaxError, parser_types.Production.parse, "F-> A B")
    self.assertRaises(SyntaxError, parser_types.Production.parse, "F B -> A B")
    self.assertRaises(SyntaxError, parser_types.Production.parse, "-> A B")

  def test_str(self):
    self.assertEqual(str(parser_types.Production(lhs="A",
                                                 rhs=("B", "C"))), "A -> B C")
    self.assertEqual(str(parser_types.Production(lhs="A",
                                                 rhs=("B",))), "A -> B")
    self.assertEqual(str(parser_types.Production(lhs="A",
                                                 rhs=tuple())), "A -> ")
    self.assertEqual(str(parser_types.Production(lhs="FOO",
                                                 rhs=('"B"', "x*"))),
                     'FOO -> "B" x*')


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