Spaces:
Build error
Build error
File size: 4,771 Bytes
64772a4 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 |
from __future__ import unicode_literals
import unittest
from io import StringIO
import string
from .. import Scanning
from ..Symtab import ModuleScope
from ..TreeFragment import StringParseContext
from ..Errors import init_thread
# generate some fake code - just a bunch of lines of the form "a0 a1 ..."
code = []
for ch in string.ascii_lowercase:
line = " ".join(["%s%s" % (ch, n) for n in range(10)])
code.append(line)
code = "\n".join(code)
init_thread()
class TestScanning(unittest.TestCase):
def make_scanner(self):
source = Scanning.StringSourceDescriptor("fake code", code)
buf = StringIO(code)
context = StringParseContext("fake context")
scope = ModuleScope("fake_module", None, None)
return Scanning.PyrexScanner(buf, source, scope=scope, context=context)
def test_put_back_positions(self):
scanner = self.make_scanner()
self.assertEqual(scanner.sy, "IDENT")
self.assertEqual(scanner.systring, "a0")
scanner.next()
self.assertEqual(scanner.sy, "IDENT")
self.assertEqual(scanner.systring, "a1")
a1pos = scanner.position()
self.assertEqual(a1pos[1:], (1, 3))
a2peek = scanner.peek() # shouldn't mess up the position
self.assertEqual(a1pos, scanner.position())
scanner.next()
self.assertEqual(a2peek, (scanner.sy, scanner.systring))
# find next line
while scanner.sy != "NEWLINE":
scanner.next()
line_sy = []
line_systring = []
line_pos = []
scanner.next()
while scanner.sy != "NEWLINE":
line_sy.append(scanner.sy)
line_systring.append(scanner.systring)
line_pos.append(scanner.position())
scanner.next()
for sy, systring, pos in zip(
line_sy[::-1], line_systring[::-1], line_pos[::-1]
):
scanner.put_back(sy, systring, pos)
n = 0
while scanner.sy != "NEWLINE":
self.assertEqual(scanner.sy, line_sy[n])
self.assertEqual(scanner.systring, line_systring[n])
self.assertEqual(scanner.position(), line_pos[n])
scanner.next()
n += 1
self.assertEqual(n, len(line_pos))
def test_tentatively_scan(self):
scanner = self.make_scanner()
with Scanning.tentatively_scan(scanner) as errors:
while scanner.sy != "NEWLINE":
scanner.next()
self.assertFalse(errors)
scanner.next()
self.assertEqual(scanner.systring, "b0")
pos = scanner.position()
with Scanning.tentatively_scan(scanner) as errors:
while scanner.sy != "NEWLINE":
scanner.next()
if scanner.systring == "b7":
scanner.error("Oh no not b7!")
break
self.assertTrue(errors)
self.assertEqual(scanner.systring, "b0") # state has been restored
self.assertEqual(scanner.position(), pos)
scanner.next()
self.assertEqual(scanner.systring, "b1") # and we can keep going again
scanner.next()
self.assertEqual(scanner.systring, "b2") # and we can keep going again
with Scanning.tentatively_scan(scanner) as error:
scanner.error("Something has gone wrong with the current symbol")
self.assertEqual(scanner.systring, "b2")
scanner.next()
self.assertEqual(scanner.systring, "b3")
# test a few combinations of nested scanning
sy1, systring1 = scanner.sy, scanner.systring
pos1 = scanner.position()
with Scanning.tentatively_scan(scanner):
scanner.next()
sy2, systring2 = scanner.sy, scanner.systring
pos2 = scanner.position()
with Scanning.tentatively_scan(scanner):
with Scanning.tentatively_scan(scanner):
scanner.next()
scanner.next()
scanner.error("Ooops")
self.assertEqual((scanner.sy, scanner.systring), (sy2, systring2))
self.assertEqual((scanner.sy, scanner.systring), (sy2, systring2))
scanner.error("eee")
self.assertEqual((scanner.sy, scanner.systring), (sy1, systring1))
with Scanning.tentatively_scan(scanner):
scanner.next()
scanner.next()
with Scanning.tentatively_scan(scanner):
scanner.next()
# no error - but this block should be unwound by the outer block too
scanner.next()
scanner.error("Oooops")
self.assertEqual((scanner.sy, scanner.systring), (sy1, systring1))
if __name__ == "__main__":
unittest.main()
|