1 | #!/usr/bin/env python2
|
2 | """
|
3 | split.test.py: Tests for split.py
|
4 | """
|
5 |
|
6 | import unittest
|
7 |
|
8 | from core import test_lib
|
9 | from osh import split # module under test
|
10 |
|
11 |
|
12 | def _RunSplitCases(test, sp, cases):
|
13 | for expected_parts, s, allow_escape in cases:
|
14 | spans = sp.Split(s, allow_escape)
|
15 | if 0:
|
16 | print('%r: %s' % (s, spans))
|
17 | else:
|
18 | # Verbose for debugging
|
19 | print(repr(s))
|
20 | for span in spans:
|
21 | print(' %s %s' % span)
|
22 |
|
23 | parts = split._SpansToParts(s, spans)
|
24 | print('PARTS %s' % parts)
|
25 |
|
26 | test.assertEqual(expected_parts, parts,
|
27 | '%r: %s != %s' % (s, expected_parts, parts))
|
28 |
|
29 |
|
30 | class SplitTest(unittest.TestCase):
|
31 |
|
32 | def testSpansToParts(self):
|
33 | sp = split.IfsSplitter(split.DEFAULT_IFS, '')
|
34 |
|
35 | s = 'one\\ two'
|
36 | spans = sp.Split(s, False)
|
37 | print(spans)
|
38 |
|
39 | parts = split._SpansToParts(s, spans)
|
40 | self.assertEqual(['one\\', 'two'], parts)
|
41 |
|
42 | spans = sp.Split(s, True) # allow_escape
|
43 | parts = split._SpansToParts(s, spans)
|
44 | self.assertEqual(['one two'], parts)
|
45 |
|
46 | # NOTE: Only read builtin supports max_results
|
47 | return
|
48 |
|
49 | parts = split._SpansToParts(s, spans, max_results=1)
|
50 | self.assertEqual(['one\\ two'], parts)
|
51 |
|
52 | print(spans)
|
53 |
|
54 | parts = split._SpansToParts(s, spans, max_results=1)
|
55 | self.assertEqual(['one two'], parts)
|
56 |
|
57 | def testTrailingWhitespaceBug(self):
|
58 | # Bug: these differed
|
59 | CASES = [
|
60 | (['x y'], r' x\ y', True),
|
61 | (['ab '], r' ab\ ', True),
|
62 | (['ab '], r' ab\ ', True),
|
63 | ]
|
64 | sp = split.IfsSplitter(split.DEFAULT_IFS, '')
|
65 | _RunSplitCases(self, sp, CASES)
|
66 |
|
67 | def testDefaultIfs(self):
|
68 | CASES = [
|
69 | ([], '', True),
|
70 | (['a'], 'a', True),
|
71 | (['a'], ' a ', True),
|
72 | (['ab'], '\tab\n', True),
|
73 | (['a', 'b'], 'a b\n', True),
|
74 | (['a b'], r'a\ b', True),
|
75 | (['a\\', 'b'], r'a\ b', False),
|
76 | ([r'\*.sh'], r'\\*.sh', True),
|
77 | (['Aa', 'b', ' a b'], 'Aa b \\ a\\ b', True),
|
78 | ]
|
79 |
|
80 | sp = split.IfsSplitter(split.DEFAULT_IFS, '')
|
81 | _RunSplitCases(self, sp, CASES)
|
82 |
|
83 | self.assertEqual(r'a\ _b', sp.Escape('a _b'))
|
84 |
|
85 | def testMixedIfs(self):
|
86 | CASES = [
|
87 | ([], '', True),
|
88 | (['a', 'b'], 'a_b', True),
|
89 | (['a', 'b'], ' a b ', True),
|
90 | (['a', 'b'], 'a _ b', True),
|
91 | (['a', 'b'], ' a _ b ', True),
|
92 | (['a', '', 'b'], 'a _ _ b', True),
|
93 | (['a', '', 'b'], 'a __ b', True),
|
94 | (['a', '', '', 'b'], 'a _ _ _ b', True),
|
95 | (['a'], ' a _ ', True),
|
96 |
|
97 | # NOTES:
|
98 | # - This cases REQUIRES ignoring leading whitespace. The state machine
|
99 | # can't handle it. Contrast with the case above.
|
100 | # - We get three spans with index 1 because of the initial rule to
|
101 | # ignore whitespace, and then EMIT_EMPTY. Seems harmless for now?
|
102 | (['', 'a'], ' _ a _ ', True),
|
103 |
|
104 | # Backslash escape
|
105 | (['a b'], r'a\ b', True),
|
106 | (['a\\', 'b'], r'a\ b', False),
|
107 | ]
|
108 |
|
109 | # IFS='_ '
|
110 | sp = split.IfsSplitter(' ', '_')
|
111 | _RunSplitCases(self, sp, CASES)
|
112 |
|
113 | self.assertEqual('a\ \_b', sp.Escape('a _b'))
|
114 |
|
115 | def testWhitespaceOnly(self):
|
116 | CASES = [
|
117 | ([], '', True),
|
118 | ([], '\t', True),
|
119 | (['a'], 'a\t', True),
|
120 | (['a', 'b'], '\t\ta\tb\t', True),
|
121 |
|
122 | # Backslash escape
|
123 | (['a\tb'], 'a\\\tb', True),
|
124 | (['a\\', 'b'], 'a\\\tb', False),
|
125 | ]
|
126 |
|
127 | # IFS='_ '
|
128 | sp = split.IfsSplitter('\t', '')
|
129 | _RunSplitCases(self, sp, CASES)
|
130 |
|
131 | self.assertEqual('a b', sp.Escape('a b'))
|
132 | self.assertEqual('a\\\tb', sp.Escape('a\tb'))
|
133 |
|
134 | def testOtherOnly(self):
|
135 | CASES = [
|
136 | ([], '', True),
|
137 | ([''], '_', True),
|
138 | (['a'], 'a_', True),
|
139 | (['', '', 'a', 'b'], '__a_b_', True),
|
140 |
|
141 | # Backslash escape
|
142 | (['a_b'], r'a\_b', True),
|
143 | (['a\\', 'b'], r'a\_b', False),
|
144 | ]
|
145 |
|
146 | # IFS='_ '
|
147 | sp = split.IfsSplitter('', '_')
|
148 | _RunSplitCases(self, sp, CASES)
|
149 |
|
150 | def testTwoOther(self):
|
151 | CASES = [
|
152 | (['a', '', 'b', '', '', 'c', 'd'], 'a__b---c_d', True),
|
153 |
|
154 | # Backslash escape
|
155 | (['a_-b'], r'a\_\-b', True),
|
156 | (['a\\', '\\', 'b'], r'a\_\-b', False),
|
157 | ]
|
158 |
|
159 | # IFS='_ '
|
160 | sp = split.IfsSplitter('', '_-')
|
161 | _RunSplitCases(self, sp, CASES)
|
162 |
|
163 |
|
164 | class SplitContextTest(unittest.TestCase):
|
165 |
|
166 | def testSplitForWordEval(self):
|
167 | arena = test_lib.MakeArena('<SplitContextTest>')
|
168 | mem = test_lib.MakeMem(arena)
|
169 | # This is the default
|
170 | #state.SetGlobalString(mem, 'IFS', split.DEFAULT_IFS)
|
171 |
|
172 | splitter = split.SplitContext(mem)
|
173 |
|
174 | # Can pass allow_escape=False
|
175 | for s in ['', ' foo bar ', '\\']:
|
176 | result = splitter.SplitForWordEval(s)
|
177 | print(result)
|
178 |
|
179 |
|
180 | if __name__ == '__main__':
|
181 | unittest.main()
|