PageRenderTime 43ms CodeModel.GetById 17ms RepoModel.GetById 0ms app.codeStats 0ms

/tests/test-interp.py

https://bitbucket.org/pmezard/pysh
Python | 196 lines | 175 code | 9 blank | 12 comment | 9 complexity | 7a11f4df5725806341fe81984bd5c669 MD5 | raw file
Possible License(s): GPL-2.0
  1. # test-interp.py - shell interpreter unit tests
  2. #
  3. # Copyright 2007 Patrick Mezard
  4. #
  5. # This software may be used and distributed according to the terms
  6. # of the GNU General Public License, incorporated herein by reference.
  7. import unittest
  8. from pysh.interp import *
  9. def remove_empty_parts(wtree):
  10. """Perform word tree cleanup by removing empty elements which are semantically
  11. useless.
  12. """
  13. result = []
  14. for part in wtree:
  15. if isinstance(part, list):
  16. part = remove_empty_parts(part)
  17. result.append(part)
  18. result[1:-1] =[s for s in result[1:-1] if s]
  19. if len(result)==2:
  20. result = []
  21. if len(result)==3 and isinstance(result[1], list):
  22. return result[1]
  23. return result
  24. class TestInterpreter(unittest.TestCase):
  25. def setUp(self):
  26. if not getattr(self, 'cwd', None):
  27. self.cwd = os.getcwd()
  28. open('test.py', 'w').close()
  29. def tearDown(self):
  30. os.chdir(self.cwd)
  31. os.remove('test.py')
  32. def test_env(self):
  33. env = Environment('.')
  34. # Check get method availability
  35. env.get('PWD', 'default')
  36. # Test positional arguments
  37. tests = [
  38. [],
  39. ['p1'],
  40. ['p1', 'p2', 'p3'],
  41. ]
  42. for args in tests:
  43. env.set_positional_args(args)
  44. self.assertEqual(env.get_positional_args(), args)
  45. def test_splitfields(self):
  46. ip = Interpreter('/')
  47. env = ip.get_env()
  48. self.assertEqual(env.split_fields('['), ['['])
  49. tests = [
  50. # No split
  51. (['', 'foo', ''], [['', 'foo', '']]),
  52. (['', '[', ''], [['', '[', '']]),
  53. # Basic split + leading/trailing whitespaces removal
  54. (['', ' foo bar ', ''], [['', 'foo', ''], ['', 'bar', '']]),
  55. # Ignore escaped blanks
  56. (['', 'foo', ['\\', ' ', ''], 'bar', ''], [['', 'foo', ['\\', ' ', ''], 'bar', '']]),
  57. # Test with some quote
  58. (['', 'foo bar ', ['"', 'quoted blank', '"'], ''], [['', 'foo', ''], ['', 'bar', ''], ['"', 'quoted blank', '"']]),
  59. (['', 'fii', 'BAR BAZ', '-baz', ''], [['', 'fiiBAR', ''], ['', 'BAZ-baz', '']]),
  60. # Double-quotes
  61. (['"', 'a b', 'c ', 'd', '"'], [['"', 'a b', 'c ', 'd', '"']]),
  62. # Positional arguments
  63. (['"', 'foo', ['@', 'p1', 'p2', 'p3', ''], 'bar', '"'], [['"', 'foo', 'p1', '"'], ['"', 'p2', '"'], ['"', 'p3', 'bar', '"']]),
  64. (['', 'fuu', ['"', 'foo', ['@', 'p1', 'p2', 'p3', ''], 'bar', '"'], 'baz', ''], [['', 'fuu', ['"', 'foo', 'p1', '"'], ''], ['"', 'p2', '"'], ['', ['"', 'p3', 'bar', '"'], 'baz', '']]),
  65. ]
  66. for test, expected in tests:
  67. result = ip._split_fields(test)
  68. result = map(remove_empty_parts, result)
  69. self.assertEqual(result, expected)
  70. def test_expandparameter(self):
  71. self.assert_(is_name('FOO'))
  72. ip = Interpreter('/')
  73. self.assertEqual(ip.expand_token(('WORD', '`echo foo`')), ['foo'])
  74. ip.get_env()['FOO'] = 'BAR'
  75. self.assertEqual(ip.expand_token(('WORD', 'fii$FOO-baz')), ['fiiBAR-baz'])
  76. # Handle non-parameter expansion
  77. self.assertEqual(ip.expand_token(('WORD', '$.')), ['$.'])
  78. # Parameter expansion + field splitting
  79. ip.get_env()['FOO'] = 'BAR BAZ'
  80. self.assertEqual(ip.expand_token(('WORD', 'fii$FOO-baz')), ['fiiBAR', 'BAZ-baz'])
  81. self.assertEqual(ip.expand_token(('WORD', 'a')), ['a'])
  82. # Positional arguments
  83. ip.get_env()['FOO'] = 'BAR BAZ'
  84. ip.get_env().set_positional_args(['p1', 'p2', 'p3'])
  85. self.assertEqual(ip.expand_token(('WORD', '$@')), ['p1', 'p2', 'p3'])
  86. self.assertEqual(ip.expand_token(('WORD', 'foo$@bar')), ['foop1', 'p2', 'p3bar'])
  87. self.assertEqual(ip.expand_token(('WORD', 'fuu"foo$@bar"baz')), ['fuufoop1', 'p2', 'p3barbaz'])
  88. self.assertEqual(ip.expand_token(('WORD', '$*')), ['p1', 'p2', 'p3'])
  89. self.assertEqual(ip.expand_token(('WORD', 'foo$*bar')), ['foop1', 'p2', 'p3bar'])
  90. self.assertEqual(ip.expand_token(('WORD', 'fuu"foo$*bar"baz')), ['fuufoop1 p2 p3barbaz'])
  91. # With no arguments
  92. ip.get_env().set_positional_args([])
  93. self.assertEqual(ip.expand_token(('WORD', '$@')), [])
  94. self.assertEqual(ip.expand_token(('WORD', '"$@"')), [])
  95. self.assertEqual(ip.expand_token(('WORD', 'foo$@bar')), ['foobar'])
  96. self.assertEqual(ip.expand_token(('WORD', 'fuu"foo$@bar"baz')), ['fuufoobarbaz'])
  97. self.assertEqual(ip.expand_token(('WORD', '[')), ['['])
  98. # Empty arguments
  99. self.assertEqual(ip.expand_token(('WORD', '""')), [''])
  100. def test_expandheredocument(self):
  101. ip = Interpreter('/')
  102. ip.get_env()['FOO'] = 'BAR'
  103. word = "try to expand this: '\\${FOO}=$FOO' \\\non the same line"
  104. self.assertEqual(ip.expand_here_document(('WORD', word)), "try to expand this: '${FOO}=BAR' on the same line")
  105. word = "\\n";
  106. self.assertEqual(ip.expand_here_document(('WORD', word)), "\\n")
  107. def test_expandpathnames(self):
  108. ip = Interpreter(os.path.abspath('.'))
  109. #FIX: find a more generic 'other' location
  110. os.chdir(tempfile.gettempdir())
  111. res1 = ip._expand_pathname(['', 'te*', '.py', ''])
  112. self.assert_(len(res1)>0)
  113. # Test quoting on literal values (no effect)
  114. res2 = ip._expand_pathname(['', 'te*', ['"', '.py', '"'], ''])
  115. self.assert_(len(res2)>0)
  116. self.assertEqual(res1, res2)
  117. # No expansion
  118. res = ip._expand_pathname(['', 'foo', 'bar', ''])
  119. self.assertEqual(res, [['', 'foo', 'bar', '']])
  120. # Test quoting on special characters
  121. wtree = ['', 'te', ['"', '*.py', '"'], '']
  122. res = ip._expand_pathname(wtree)
  123. self.assertEqual(res, [wtree])
  124. def test_removequotes(self):
  125. ip = Interpreter('/')
  126. tests = [
  127. (['', 'a', ''], ['', 'a', '']),
  128. # Unquoted
  129. (['', 'foo', 'bar', ''], ['', 'foobar', '']),
  130. # Quotes in quotes
  131. (['', 'foo', ['"', 'ba', ['\\', 'r', ''], '"'], 'baz', ''], ['', 'foobarbaz', '']),
  132. # Quoted backslashes
  133. (['"', 'foo', ['\\', '\\', ''], 'nbaz', '"'], ['', 'foo\\nbaz', '']),
  134. ]
  135. for test, expected in tests:
  136. self.assertEqual(ip._remove_quotes(test), expected)
  137. def test_redirs(self):
  138. def checkopened(path):
  139. try:
  140. os.remove(path)
  141. return False
  142. except:
  143. return True
  144. # Test simple open/close sequence
  145. tmpfd, tmppath = tempfile.mkstemp()
  146. f = os.fdopen(tmpfd, 'w')
  147. w = FileWrapper('w', f, True)
  148. dup = w.dup()
  149. dup.close()
  150. self.assert_(checkopened(tmppath))
  151. w.close()
  152. os.remove(tmppath)
  153. # Test redirection clone
  154. tmpfd, tmppath = tempfile.mkstemp()
  155. f = os.fdopen(tmpfd, 'w')
  156. w = FileWrapper('w', f, True)
  157. r = Redirections(w, w.dup(), w.dup())
  158. self.assert_(checkopened(tmppath))
  159. # Duplicate one descriptor into another
  160. r.add(None, '>&', '2', '1')
  161. self.assert_(checkopened(tmppath))
  162. r.close()
  163. os.remove(tmppath)
  164. if __name__=='__main__':
  165. unittest.main()