1# -*- coding: iso-8859-1 -*-
2import unittest
3import shlex
4
5from test import test_support
6
7try:
8    from cStringIO import StringIO
9except ImportError:
10    from StringIO import StringIO
11
12
13# The original test data set was from shellwords, by Hartmut Goebel.
14
15data = r"""x|x|
16foo bar|foo|bar|
17 foo bar|foo|bar|
18 foo bar |foo|bar|
19foo   bar    bla     fasel|foo|bar|bla|fasel|
20x y  z              xxxx|x|y|z|xxxx|
21\x bar|\|x|bar|
22\ x bar|\|x|bar|
23\ bar|\|bar|
24foo \x bar|foo|\|x|bar|
25foo \ x bar|foo|\|x|bar|
26foo \ bar|foo|\|bar|
27foo "bar" bla|foo|"bar"|bla|
28"foo" "bar" "bla"|"foo"|"bar"|"bla"|
29"foo" bar "bla"|"foo"|bar|"bla"|
30"foo" bar bla|"foo"|bar|bla|
31foo 'bar' bla|foo|'bar'|bla|
32'foo' 'bar' 'bla'|'foo'|'bar'|'bla'|
33'foo' bar 'bla'|'foo'|bar|'bla'|
34'foo' bar bla|'foo'|bar|bla|
35blurb foo"bar"bar"fasel" baz|blurb|foo"bar"bar"fasel"|baz|
36blurb foo'bar'bar'fasel' baz|blurb|foo'bar'bar'fasel'|baz|
37""|""|
38''|''|
39foo "" bar|foo|""|bar|
40foo '' bar|foo|''|bar|
41foo "" "" "" bar|foo|""|""|""|bar|
42foo '' '' '' bar|foo|''|''|''|bar|
43\""|\|""|
44"\"|"\"|
45"foo\ bar"|"foo\ bar"|
46"foo\\ bar"|"foo\\ bar"|
47"foo\\ bar\"|"foo\\ bar\"|
48"foo\\" bar\""|"foo\\"|bar|\|""|
49"foo\\ bar\" dfadf"|"foo\\ bar\"|dfadf"|
50"foo\\\ bar\" dfadf"|"foo\\\ bar\"|dfadf"|
51"foo\\\x bar\" dfadf"|"foo\\\x bar\"|dfadf"|
52"foo\x bar\" dfadf"|"foo\x bar\"|dfadf"|
53\''|\|''|
54'foo\ bar'|'foo\ bar'|
55'foo\\ bar'|'foo\\ bar'|
56"foo\\\x bar\" df'a\ 'df'|"foo\\\x bar\"|df'a|\|'df'|
57\"foo"|\|"foo"|
58\"foo"\x|\|"foo"|\|x|
59"foo\x"|"foo\x"|
60"foo\ "|"foo\ "|
61foo\ xx|foo|\|xx|
62foo\ x\x|foo|\|x|\|x|
63foo\ x\x\""|foo|\|x|\|x|\|""|
64"foo\ x\x"|"foo\ x\x"|
65"foo\ x\x\\"|"foo\ x\x\\"|
66"foo\ x\x\\""foobar"|"foo\ x\x\\"|"foobar"|
67"foo\ x\x\\"\''"foobar"|"foo\ x\x\\"|\|''|"foobar"|
68"foo\ x\x\\"\'"fo'obar"|"foo\ x\x\\"|\|'"fo'|obar"|
69"foo\ x\x\\"\'"fo'obar" 'don'\''t'|"foo\ x\x\\"|\|'"fo'|obar"|'don'|\|''|t'|
70'foo\ bar'|'foo\ bar'|
71'foo\\ bar'|'foo\\ bar'|
72foo\ bar|foo|\|bar|
73foo#bar\nbaz|foobaz|
74:-) ;-)|:|-|)|;|-|)|
75�����|�|�|�|�|�|
76"""
77
78posix_data = r"""x|x|
79foo bar|foo|bar|
80 foo bar|foo|bar|
81 foo bar |foo|bar|
82foo   bar    bla     fasel|foo|bar|bla|fasel|
83x y  z              xxxx|x|y|z|xxxx|
84\x bar|x|bar|
85\ x bar| x|bar|
86\ bar| bar|
87foo \x bar|foo|x|bar|
88foo \ x bar|foo| x|bar|
89foo \ bar|foo| bar|
90foo "bar" bla|foo|bar|bla|
91"foo" "bar" "bla"|foo|bar|bla|
92"foo" bar "bla"|foo|bar|bla|
93"foo" bar bla|foo|bar|bla|
94foo 'bar' bla|foo|bar|bla|
95'foo' 'bar' 'bla'|foo|bar|bla|
96'foo' bar 'bla'|foo|bar|bla|
97'foo' bar bla|foo|bar|bla|
98blurb foo"bar"bar"fasel" baz|blurb|foobarbarfasel|baz|
99blurb foo'bar'bar'fasel' baz|blurb|foobarbarfasel|baz|
100""||
101''||
102foo "" bar|foo||bar|
103foo '' bar|foo||bar|
104foo "" "" "" bar|foo||||bar|
105foo '' '' '' bar|foo||||bar|
106\"|"|
107"\""|"|
108"foo\ bar"|foo\ bar|
109"foo\\ bar"|foo\ bar|
110"foo\\ bar\""|foo\ bar"|
111"foo\\" bar\"|foo\|bar"|
112"foo\\ bar\" dfadf"|foo\ bar" dfadf|
113"foo\\\ bar\" dfadf"|foo\\ bar" dfadf|
114"foo\\\x bar\" dfadf"|foo\\x bar" dfadf|
115"foo\x bar\" dfadf"|foo\x bar" dfadf|
116\'|'|
117'foo\ bar'|foo\ bar|
118'foo\\ bar'|foo\\ bar|
119"foo\\\x bar\" df'a\ 'df"|foo\\x bar" df'a\ 'df|
120\"foo|"foo|
121\"foo\x|"foox|
122"foo\x"|foo\x|
123"foo\ "|foo\ |
124foo\ xx|foo xx|
125foo\ x\x|foo xx|
126foo\ x\x\"|foo xx"|
127"foo\ x\x"|foo\ x\x|
128"foo\ x\x\\"|foo\ x\x\|
129"foo\ x\x\\""foobar"|foo\ x\x\foobar|
130"foo\ x\x\\"\'"foobar"|foo\ x\x\'foobar|
131"foo\ x\x\\"\'"fo'obar"|foo\ x\x\'fo'obar|
132"foo\ x\x\\"\'"fo'obar" 'don'\''t'|foo\ x\x\'fo'obar|don't|
133"foo\ x\x\\"\'"fo'obar" 'don'\''t' \\|foo\ x\x\'fo'obar|don't|\|
134'foo\ bar'|foo\ bar|
135'foo\\ bar'|foo\\ bar|
136foo\ bar|foo bar|
137foo#bar\nbaz|foo|baz|
138:-) ;-)|:-)|;-)|
139�����|�����|
140"""
141
142class ShlexTest(unittest.TestCase):
143    def setUp(self):
144        self.data = [x.split("|")[:-1]
145                     for x in data.splitlines()]
146        self.posix_data = [x.split("|")[:-1]
147                           for x in posix_data.splitlines()]
148        for item in self.data:
149            item[0] = item[0].replace(r"\n", "\n")
150        for item in self.posix_data:
151            item[0] = item[0].replace(r"\n", "\n")
152
153    def splitTest(self, data, comments):
154        for i in range(len(data)):
155            l = shlex.split(data[i][0], comments=comments)
156            self.assertEqual(l, data[i][1:],
157                             "%s: %s != %s" %
158                             (data[i][0], l, data[i][1:]))
159
160    def oldSplit(self, s):
161        ret = []
162        lex = shlex.shlex(StringIO(s))
163        tok = lex.get_token()
164        while tok:
165            ret.append(tok)
166            tok = lex.get_token()
167        return ret
168
169    def testSplitPosix(self):
170        """Test data splitting with posix parser"""
171        self.splitTest(self.posix_data, comments=True)
172
173    def testCompat(self):
174        """Test compatibility interface"""
175        for i in range(len(self.data)):
176            l = self.oldSplit(self.data[i][0])
177            self.assertEqual(l, self.data[i][1:],
178                             "%s: %s != %s" %
179                             (self.data[i][0], l, self.data[i][1:]))
180
181    def testEmptyStringHandling(self):
182        """Test that parsing of empty strings is correctly handled."""
183        # see Issue #21999
184        expected = ['', ')', 'abc']
185
186        s = shlex.shlex("'')abc", posix=True)
187        slist = list(s)
188        self.assertEqual(slist, expected)
189        expected = ["''", ')', 'abc']
190        s = shlex.shlex("'')abc")
191        self.assertEqual(list(s), expected)
192
193
194# Allow this test to be used with old shlex.py
195if not getattr(shlex, "split", None):
196    for methname in dir(ShlexTest):
197        if methname.startswith("test") and methname != "testCompat":
198            delattr(ShlexTest, methname)
199
200def test_main():
201    test_support.run_unittest(ShlexTest)
202
203if __name__ == "__main__":
204    test_main()
205