| OLD | NEW | 
|---|
|  | (Empty) | 
| 1 #!/usr/bin/env python |  | 
| 2 # Copyright (C) 2013 Google Inc. All rights reserved. |  | 
| 3 # |  | 
| 4 # Redistribution and use in source and binary forms, with or without |  | 
| 5 # modification, are permitted provided that the following conditions are |  | 
| 6 # met: |  | 
| 7 # |  | 
| 8 #     * Redistributions of source code must retain the above copyright |  | 
| 9 # notice, this list of conditions and the following disclaimer. |  | 
| 10 #     * Redistributions in binary form must reproduce the above |  | 
| 11 # copyright notice, this list of conditions and the following disclaimer |  | 
| 12 # in the documentation and/or other materials provided with the |  | 
| 13 # distribution. |  | 
| 14 #     * Neither the name of Google Inc. nor the names of its |  | 
| 15 # contributors may be used to endorse or promote products derived from |  | 
| 16 # this software without specific prior written permission. |  | 
| 17 # |  | 
| 18 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |  | 
| 19 # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |  | 
| 20 # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |  | 
| 21 # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |  | 
| 22 # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |  | 
| 23 # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |  | 
| 24 # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |  | 
| 25 # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |  | 
| 26 # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |  | 
| 27 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |  | 
| 28 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |  | 
| 29 |  | 
| 30 import tempfile |  | 
| 31 import unittest |  | 
| 32 |  | 
| 33 from make_token_matcher import BadInput, CaseLineProcessor, MainLineProcessor, O
     ptimizer, process_file, SwitchCase, SwitchLineProcessor |  | 
| 34 |  | 
| 35 |  | 
| 36 class OptimizerTest(unittest.TestCase): |  | 
| 37     def test_nonalphabetic(self): |  | 
| 38         optimizer = Optimizer(None, None, None) |  | 
| 39         self.assertRaises( |  | 
| 40             BadInput, |  | 
| 41             optimizer.inspect_array, |  | 
| 42             [SwitchCase('-', None), SwitchCase('x', None)], |  | 
| 43             [0]) |  | 
| 44 |  | 
| 45 |  | 
| 46 class MainLineProcessorTest(unittest.TestCase): |  | 
| 47     def test_switch(self): |  | 
| 48         processor = MainLineProcessor(None) |  | 
| 49         switchLineProcessor = processor.process_line('SWITCH(array, length) {') |  | 
| 50         self.assertIsInstance(switchLineProcessor, SwitchLineProcessor) |  | 
| 51         self.assertEquals('array', switchLineProcessor.array_variable) |  | 
| 52         self.assertEquals('length', switchLineProcessor.length_variable) |  | 
| 53 |  | 
| 54 |  | 
| 55 class SwitchLineProcessorTest(unittest.TestCase): |  | 
| 56     def test_case(self): |  | 
| 57         processor = SwitchLineProcessor(None, None, None, None) |  | 
| 58         caseLineProcessor = processor.process_line('CASE("identifier") {') |  | 
| 59         self.assertIsInstance(caseLineProcessor, CaseLineProcessor) |  | 
| 60         self.assertEquals('identifier', caseLineProcessor.identifier) |  | 
| 61 |  | 
| 62     def test_unexpected(self): |  | 
| 63         processor = SwitchLineProcessor(None, None, None, None) |  | 
| 64         self.assertRaises( |  | 
| 65             BadInput, |  | 
| 66             processor.process_line, |  | 
| 67             'unexpected') |  | 
| 68 |  | 
| 69     def test_repeated(self): |  | 
| 70         processor = SwitchLineProcessor(None, None, None, None) |  | 
| 71         processor.process_line('CASE("x") {').process_line('}') |  | 
| 72         caseLineProcessor = processor.process_line('CASE("x") {') |  | 
| 73         self.assertRaises( |  | 
| 74             BadInput, |  | 
| 75             caseLineProcessor.process_line, |  | 
| 76             '}') |  | 
| 77 |  | 
| 78 |  | 
| 79 class CaseLineProcessorTest(unittest.TestCase): |  | 
| 80     def test_break(self): |  | 
| 81         processor = CaseLineProcessor(None, None, None) |  | 
| 82         self.assertRaises( |  | 
| 83             BadInput, |  | 
| 84             processor.process_line, |  | 
| 85             'break;') |  | 
| 86 |  | 
| 87 |  | 
| 88 class ProcessFileTest(unittest.TestCase): |  | 
| 89     SOURCE_SMALL = """ |  | 
| 90         SWITCH(p, q) { |  | 
| 91             CASE("a(") { |  | 
| 92                 X; |  | 
| 93             } |  | 
| 94             CASE("b(") { |  | 
| 95                 Y; |  | 
| 96             } |  | 
| 97         } |  | 
| 98         """ |  | 
| 99 |  | 
| 100     EXPECTED_SMALL = """ |  | 
| 101         if (LIKELY(q == 2)) { |  | 
| 102             if (LIKELY(p[1] == '(')) { |  | 
| 103                 if ((p[0] | 0x20) == 'a') { |  | 
| 104                     X; |  | 
| 105                 } else if (LIKELY((p[0] | 0x20) == 'b')) { |  | 
| 106                     Y; |  | 
| 107                 } |  | 
| 108             } |  | 
| 109         } |  | 
| 110         """ |  | 
| 111 |  | 
| 112     SOURCE_MEDIUM = """ |  | 
| 113         SWITCH (p, q) { |  | 
| 114             CASE ("ab") { |  | 
| 115                 X; |  | 
| 116             } |  | 
| 117             CASE ("cd") { |  | 
| 118                 Y; |  | 
| 119             } |  | 
| 120             CASE ("ed") { |  | 
| 121                 Z; |  | 
| 122             } |  | 
| 123         } |  | 
| 124         """ |  | 
| 125 |  | 
| 126     EXPECTED_MEDIUM = """ |  | 
| 127         if (LIKELY(q == 2)) { |  | 
| 128             if ((p[1] | 0x20) == 'b') { |  | 
| 129                 if (LIKELY((p[0] | 0x20) == 'a')) { |  | 
| 130                     X; |  | 
| 131                 } |  | 
| 132             } else if (LIKELY((p[1] | 0x20) == 'd')) { |  | 
| 133                 if ((p[0] | 0x20) == 'c') { |  | 
| 134                     Y; |  | 
| 135                 } else if (LIKELY((p[0] | 0x20) == 'e')) { |  | 
| 136                     Z; |  | 
| 137                 } |  | 
| 138             } |  | 
| 139         } |  | 
| 140         """ |  | 
| 141 |  | 
| 142     SOURCE_LARGE = """ |  | 
| 143         prefix; |  | 
| 144         SWITCH(p, q) { |  | 
| 145             CASE("hij") { |  | 
| 146                 R; |  | 
| 147             } |  | 
| 148             CASE("efg") { |  | 
| 149                 S; |  | 
| 150             } |  | 
| 151             CASE("c-") { |  | 
| 152                 T; |  | 
| 153             } |  | 
| 154             CASE("klm") { |  | 
| 155                 U; |  | 
| 156             } |  | 
| 157 |  | 
| 158             CASE("d-") { |  | 
| 159                 V; |  | 
| 160             } |  | 
| 161             CASE("a") { |  | 
| 162                 W; |  | 
| 163                 X; |  | 
| 164             } |  | 
| 165             CASE("b-") { |  | 
| 166                 Y; |  | 
| 167                 Z; |  | 
| 168             } |  | 
| 169         } |  | 
| 170         suffix; |  | 
| 171         """ |  | 
| 172 |  | 
| 173     EXPECTED_LARGE = """ |  | 
| 174         prefix; |  | 
| 175         switch (q) { |  | 
| 176         case 1: { |  | 
| 177             if (LIKELY((p[0] | 0x20) == 'a')) { |  | 
| 178                 W; |  | 
| 179                 X; |  | 
| 180             } |  | 
| 181         } break; |  | 
| 182         case 2: { |  | 
| 183             if (LIKELY(p[1] == '-')) { |  | 
| 184                 switch ((p[0] | 0x20)) { |  | 
| 185                 case 'b': { |  | 
| 186                     Y; |  | 
| 187                     Z; |  | 
| 188                 } break; |  | 
| 189                 case 'c': { |  | 
| 190                     T; |  | 
| 191                 } break; |  | 
| 192                 case 'd': { |  | 
| 193                     V; |  | 
| 194                 } break; |  | 
| 195                 } |  | 
| 196             } |  | 
| 197         } break; |  | 
| 198         case 3: { |  | 
| 199             switch ((p[0] | 0x20)) { |  | 
| 200             case 'e': { |  | 
| 201                 if (LIKELY((p[1] | 0x20) == 'f' && (p[2] | 0x20) == 'g')) { |  | 
| 202                     S; |  | 
| 203                 } |  | 
| 204             } break; |  | 
| 205             case 'h': { |  | 
| 206                 if (LIKELY((p[1] | 0x20) == 'i' && (p[2] | 0x20) == 'j')) { |  | 
| 207                     R; |  | 
| 208                 } |  | 
| 209             } break; |  | 
| 210             case 'k': { |  | 
| 211                 if (LIKELY((p[1] | 0x20) == 'l' && (p[2] | 0x20) == 'm')) { |  | 
| 212                     U; |  | 
| 213                 } |  | 
| 214             } break; |  | 
| 215             } |  | 
| 216         } break; |  | 
| 217         } |  | 
| 218         suffix; |  | 
| 219         """ |  | 
| 220 |  | 
| 221     def validate(self, source, expected): |  | 
| 222         with tempfile.NamedTemporaryFile() as input_file: |  | 
| 223             with tempfile.NamedTemporaryFile() as generated_file: |  | 
| 224                 input_file.write(source) |  | 
| 225                 input_file.flush() |  | 
| 226                 process_file(input_file.name, generated_file.name) |  | 
| 227                 # Our code generation does not yet implement pretty indentation. |  | 
| 228                 actual = generated_file.read().replace('    ', '') |  | 
| 229                 expected = expected.replace('    ', '') |  | 
| 230                 self.assertEquals(actual, expected) |  | 
| 231 |  | 
| 232     def test_small(self): |  | 
| 233         self.validate(ProcessFileTest.SOURCE_SMALL, ProcessFileTest.EXPECTED_SMA
     LL) |  | 
| 234 |  | 
| 235     def test_medium(self): |  | 
| 236         self.validate(ProcessFileTest.SOURCE_MEDIUM, ProcessFileTest.EXPECTED_ME
     DIUM) |  | 
| 237 |  | 
| 238     def test_large(self): |  | 
| 239         self.validate(ProcessFileTest.SOURCE_LARGE, ProcessFileTest.EXPECTED_LAR
     GE) |  | 
| 240 |  | 
| 241 |  | 
| 242 if __name__ == "__main__": |  | 
| 243     unittest.main() |  | 
| OLD | NEW | 
|---|