| Index: core/scripts/make_token_matcher_unittest.py
|
| diff --git a/core/scripts/make_token_matcher_unittest.py b/core/scripts/make_token_matcher_unittest.py
|
| new file mode 100755
|
| index 0000000000000000000000000000000000000000..c0c82863970aa5be5e2e18227ff99ecefe3474c2
|
| --- /dev/null
|
| +++ b/core/scripts/make_token_matcher_unittest.py
|
| @@ -0,0 +1,243 @@
|
| +#!/usr/bin/env python
|
| +# Copyright (C) 2013 Google Inc. All rights reserved.
|
| +#
|
| +# Redistribution and use in source and binary forms, with or without
|
| +# modification, are permitted provided that the following conditions are
|
| +# met:
|
| +#
|
| +# * Redistributions of source code must retain the above copyright
|
| +# notice, this list of conditions and the following disclaimer.
|
| +# * Redistributions in binary form must reproduce the above
|
| +# copyright notice, this list of conditions and the following disclaimer
|
| +# in the documentation and/or other materials provided with the
|
| +# distribution.
|
| +# * Neither the name of Google Inc. nor the names of its
|
| +# contributors may be used to endorse or promote products derived from
|
| +# this software without specific prior written permission.
|
| +#
|
| +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
| +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
| +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
| +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
| +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
| +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
| +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
| +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
| +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
| +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
| +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
| +
|
| +import tempfile
|
| +import unittest
|
| +
|
| +from make_token_matcher import BadInput, CaseLineProcessor, MainLineProcessor, Optimizer, process_file, SwitchCase, SwitchLineProcessor
|
| +
|
| +
|
| +class OptimizerTest(unittest.TestCase):
|
| + def test_nonalphabetic(self):
|
| + optimizer = Optimizer(None, None, None)
|
| + self.assertRaises(
|
| + BadInput,
|
| + optimizer.inspect_array,
|
| + [SwitchCase('-', None), SwitchCase('x', None)],
|
| + [0])
|
| +
|
| +
|
| +class MainLineProcessorTest(unittest.TestCase):
|
| + def test_switch(self):
|
| + processor = MainLineProcessor(None)
|
| + switchLineProcessor = processor.process_line('SWITCH(array, length) {')
|
| + self.assertIsInstance(switchLineProcessor, SwitchLineProcessor)
|
| + self.assertEquals('array', switchLineProcessor.array_variable)
|
| + self.assertEquals('length', switchLineProcessor.length_variable)
|
| +
|
| +
|
| +class SwitchLineProcessorTest(unittest.TestCase):
|
| + def test_case(self):
|
| + processor = SwitchLineProcessor(None, None, None, None)
|
| + caseLineProcessor = processor.process_line('CASE("identifier") {')
|
| + self.assertIsInstance(caseLineProcessor, CaseLineProcessor)
|
| + self.assertEquals('identifier', caseLineProcessor.identifier)
|
| +
|
| + def test_unexpected(self):
|
| + processor = SwitchLineProcessor(None, None, None, None)
|
| + self.assertRaises(
|
| + BadInput,
|
| + processor.process_line,
|
| + 'unexpected')
|
| +
|
| + def test_repeated(self):
|
| + processor = SwitchLineProcessor(None, None, None, None)
|
| + processor.process_line('CASE("x") {').process_line('}')
|
| + caseLineProcessor = processor.process_line('CASE("x") {')
|
| + self.assertRaises(
|
| + BadInput,
|
| + caseLineProcessor.process_line,
|
| + '}')
|
| +
|
| +
|
| +class CaseLineProcessorTest(unittest.TestCase):
|
| + def test_break(self):
|
| + processor = CaseLineProcessor(None, None, None)
|
| + self.assertRaises(
|
| + BadInput,
|
| + processor.process_line,
|
| + 'break;')
|
| +
|
| +
|
| +class ProcessFileTest(unittest.TestCase):
|
| + SOURCE_SMALL = """
|
| + SWITCH(p, q) {
|
| + CASE("a(") {
|
| + X;
|
| + }
|
| + CASE("b(") {
|
| + Y;
|
| + }
|
| + }
|
| + """
|
| +
|
| + EXPECTED_SMALL = """
|
| + if (LIKELY(q == 2)) {
|
| + if (LIKELY(p[1] == '(')) {
|
| + if ((p[0] | 0x20) == 'a') {
|
| + X;
|
| + } else if (LIKELY((p[0] | 0x20) == 'b')) {
|
| + Y;
|
| + }
|
| + }
|
| + }
|
| + """
|
| +
|
| + SOURCE_MEDIUM = """
|
| + SWITCH (p, q) {
|
| + CASE ("ab") {
|
| + X;
|
| + }
|
| + CASE ("cd") {
|
| + Y;
|
| + }
|
| + CASE ("ed") {
|
| + Z;
|
| + }
|
| + }
|
| + """
|
| +
|
| + EXPECTED_MEDIUM = """
|
| + if (LIKELY(q == 2)) {
|
| + if ((p[1] | 0x20) == 'b') {
|
| + if (LIKELY((p[0] | 0x20) == 'a')) {
|
| + X;
|
| + }
|
| + } else if (LIKELY((p[1] | 0x20) == 'd')) {
|
| + if ((p[0] | 0x20) == 'c') {
|
| + Y;
|
| + } else if (LIKELY((p[0] | 0x20) == 'e')) {
|
| + Z;
|
| + }
|
| + }
|
| + }
|
| + """
|
| +
|
| + SOURCE_LARGE = """
|
| + prefix;
|
| + SWITCH(p, q) {
|
| + CASE("hij") {
|
| + R;
|
| + }
|
| + CASE("efg") {
|
| + S;
|
| + }
|
| + CASE("c-") {
|
| + T;
|
| + }
|
| + CASE("klm") {
|
| + U;
|
| + }
|
| +
|
| + CASE("d-") {
|
| + V;
|
| + }
|
| + CASE("a") {
|
| + W;
|
| + X;
|
| + }
|
| + CASE("b-") {
|
| + Y;
|
| + Z;
|
| + }
|
| + }
|
| + suffix;
|
| + """
|
| +
|
| + EXPECTED_LARGE = """
|
| + prefix;
|
| + switch (q) {
|
| + case 1: {
|
| + if (LIKELY((p[0] | 0x20) == 'a')) {
|
| + W;
|
| + X;
|
| + }
|
| + } break;
|
| + case 2: {
|
| + if (LIKELY(p[1] == '-')) {
|
| + switch ((p[0] | 0x20)) {
|
| + case 'b': {
|
| + Y;
|
| + Z;
|
| + } break;
|
| + case 'c': {
|
| + T;
|
| + } break;
|
| + case 'd': {
|
| + V;
|
| + } break;
|
| + }
|
| + }
|
| + } break;
|
| + case 3: {
|
| + switch ((p[0] | 0x20)) {
|
| + case 'e': {
|
| + if (LIKELY((p[1] | 0x20) == 'f' && (p[2] | 0x20) == 'g')) {
|
| + S;
|
| + }
|
| + } break;
|
| + case 'h': {
|
| + if (LIKELY((p[1] | 0x20) == 'i' && (p[2] | 0x20) == 'j')) {
|
| + R;
|
| + }
|
| + } break;
|
| + case 'k': {
|
| + if (LIKELY((p[1] | 0x20) == 'l' && (p[2] | 0x20) == 'm')) {
|
| + U;
|
| + }
|
| + } break;
|
| + }
|
| + } break;
|
| + }
|
| + suffix;
|
| + """
|
| +
|
| + def validate(self, source, expected):
|
| + with tempfile.NamedTemporaryFile() as input_file:
|
| + with tempfile.NamedTemporaryFile() as generated_file:
|
| + input_file.write(source)
|
| + input_file.flush()
|
| + process_file(input_file.name, generated_file.name)
|
| + # Our code generation does not yet implement pretty indentation.
|
| + actual = generated_file.read().replace(' ', '')
|
| + expected = expected.replace(' ', '')
|
| + self.assertEquals(actual, expected)
|
| +
|
| + def test_small(self):
|
| + self.validate(ProcessFileTest.SOURCE_SMALL, ProcessFileTest.EXPECTED_SMALL)
|
| +
|
| + def test_medium(self):
|
| + self.validate(ProcessFileTest.SOURCE_MEDIUM, ProcessFileTest.EXPECTED_MEDIUM)
|
| +
|
| + def test_large(self):
|
| + self.validate(ProcessFileTest.SOURCE_LARGE, ProcessFileTest.EXPECTED_LARGE)
|
| +
|
| +
|
| +if __name__ == "__main__":
|
| + unittest.main()
|
|
|