blob: c66bf2f65854b9eaa4e9b2e0c34b4304d0c9f5ee [file] [log] [blame]
# 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_data
from compiler.util import parser_types
class PositionTest(unittest.TestCase):
"""Tests for SourcePosition-related functions in parser_types."""
def test_position_str(self):
self.assertEqual("1:2", str(parser_types.SourcePosition(line=1, column=2)))
def test_position_bool(self):
self.assertFalse(parser_types.SourcePosition())
self.assertFalse(parser_types.SourcePosition(0, 0))
self.assertTrue(parser_types.SourcePosition(1, 1))
def test_position_from_str(self):
self.assertEqual(
parser_types.SourcePosition(1, 2),
parser_types.SourcePosition.from_str("1:2"),
)
self.assertEqual(
parser_types.SourcePosition(0, 0),
parser_types.SourcePosition.from_str("0:0"),
)
self.assertRaises(ValueError, parser_types.SourcePosition.from_str, "0xa:9")
self.assertRaises(ValueError, parser_types.SourcePosition.from_str, "9")
if __debug__:
self.assertRaises(ValueError, parser_types.SourcePosition.from_str, "0:-1")
self.assertRaises(ValueError, parser_types.SourcePosition.from_str, "-1:0")
def test_position_new(self):
self.assertEqual(
parser_types.SourcePosition(1, 2),
parser_types.SourcePosition(line=1, column=2),
)
if __debug__:
self.assertRaises(AssertionError, parser_types.SourcePosition, -1, 1)
self.assertRaises(AssertionError, parser_types.SourcePosition, 1, -1)
self.assertRaises(AssertionError, parser_types.SourcePosition, None, 1)
self.assertRaises(AssertionError, parser_types.SourcePosition, 1, None)
self.assertRaises(AssertionError, parser_types.SourcePosition, 1.1, 1)
self.assertRaises(AssertionError, parser_types.SourcePosition, 1, 1.1)
self.assertRaises(AssertionError, parser_types.SourcePosition, 0, 1)
self.assertRaises(AssertionError, parser_types.SourcePosition, 1, 0)
def test_position_attributes(self):
self.assertEqual(1, parser_types.SourcePosition(1, 2).line)
self.assertEqual(2, parser_types.SourcePosition(1, 2).column)
def test_position_order(self):
self.assertTrue(
parser_types.SourcePosition(1, 2) < parser_types.SourcePosition(2, 2)
)
self.assertTrue(
parser_types.SourcePosition(2, 1) < parser_types.SourcePosition(2, 2)
)
self.assertFalse(
parser_types.SourcePosition(2, 1) < parser_types.SourcePosition(2, 1)
)
self.assertFalse(
parser_types.SourcePosition(2, 2) < parser_types.SourcePosition(2, 1)
)
class LocationTest(unittest.TestCase):
"""Tests for SourceLocation-related functions in parser_types."""
def test_location_new(self):
self.assertEqual(
parser_types.SourceLocation(
start=parser_types.SourcePosition(line=1, column=2),
end=parser_types.SourcePosition(line=3, column=4),
is_synthetic=False,
is_disjoint_from_parent=False,
),
parser_types.SourceLocation((1, 2), (3, 4)),
)
self.assertFalse(parser_types.SourceLocation(is_synthetic=False).is_synthetic)
self.assertTrue(parser_types.SourceLocation(is_synthetic=True).is_synthetic)
self.assertFalse(
parser_types.SourceLocation(
is_disjoint_from_parent=False
).is_disjoint_from_parent
)
self.assertTrue(
parser_types.SourceLocation(
is_disjoint_from_parent=True
).is_disjoint_from_parent
)
self.assertRaises(TypeError, parser_types.SourceLocation, None, (3, 4))
self.assertRaises(TypeError, parser_types.SourceLocation, (1, 2), None)
if __debug__:
self.assertRaises(
AssertionError, parser_types.SourceLocation, (3, 4), (1, 2)
)
self.assertRaises(
AssertionError, parser_types.SourceLocation, (3, 4), (3, 2)
)
self.assertRaises(
AssertionError,
parser_types.SourceLocation,
parser_types.SourcePosition(),
(1, 2),
)
self.assertRaises(
AssertionError,
parser_types.SourceLocation,
(1, 2),
parser_types.SourcePosition(),
)
def test_location_str(self):
self.assertEqual(
"1:2-3:4",
str(parser_types.SourceLocation((1, 2), (3, 4))),
)
self.assertEqual(
"1:2-3:4^",
str(
parser_types.SourceLocation(
(1, 2), (3, 4), is_disjoint_from_parent=True
)
),
)
self.assertEqual(
"1:2-3:4*",
str(parser_types.SourceLocation((1, 2), (3, 4), is_synthetic=True)),
)
self.assertEqual(
"1:2-3:4^*",
str(
parser_types.SourceLocation(
(1, 2), (3, 4), is_synthetic=True, is_disjoint_from_parent=True
)
),
)
def test_location_from_str(self):
self.assertEqual(
parser_types.SourceLocation((1, 2), (3, 4)),
parser_types.SourceLocation.from_str("1:2-3:4"),
)
self.assertEqual(
parser_types.SourceLocation((1, 2), (3, 4)),
parser_types.SourceLocation.from_str(" 1 : 2 - 3 : 4 "),
)
self.assertEqual(
parser_types.SourceLocation((1, 2), (3, 4), is_disjoint_from_parent=True),
parser_types.SourceLocation.from_str("1:2-3:4^"),
)
self.assertEqual(
parser_types.SourceLocation((1, 2), (3, 4), is_synthetic=True),
parser_types.SourceLocation.from_str("1:2-3:4*"),
)
self.assertEqual(
parser_types.SourceLocation(
(1, 2), (3, 4), is_disjoint_from_parent=True, is_synthetic=True
),
parser_types.SourceLocation.from_str("1:2-3:4^*"),
)
self.assertRaises(ValueError, parser_types.SourceLocation.from_str, "1:2-3:")
if __debug__:
self.assertRaises(
ValueError, parser_types.SourceLocation.from_str, "1:2-3:-1"
)
self.assertRaises(ValueError, parser_types.SourceLocation.from_str, "1:2-3:1%")
def test_location_attributes(self):
self.assertEqual(
parser_types.SourceLocation((1, 2), (3, 4)).start,
parser_types.SourcePosition(1, 2),
)
self.assertEqual(
parser_types.SourceLocation((1, 2), (3, 4)).end,
parser_types.SourcePosition(3, 4),
)
self.assertFalse(parser_types.SourceLocation((1, 2), (3, 4)).is_synthetic)
self.assertFalse(
parser_types.SourceLocation((1, 2), (3, 4)).is_disjoint_from_parent
)
self.assertTrue(
parser_types.SourceLocation((1, 2), (3, 4), is_synthetic=True).is_synthetic
)
self.assertTrue(
parser_types.SourceLocation(
(1, 2), (3, 4), is_disjoint_from_parent=True
).is_disjoint_from_parent
)
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.SourceLocation((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()