Skip to content

Commit

Permalink
- This test fails with a TypeError on Python 2.6, so adjust accordingly.
Browse files Browse the repository at this point in the history
  • Loading branch information
sidnei committed Oct 8, 2008
0 parents commit 5c3ddbe
Showing 1 changed file with 326 additions and 0 deletions.
326 changes: 326 additions & 0 deletions tests/testPythonScript.py
@@ -0,0 +1,326 @@
##############################################################################
#
# Copyright (c) 2002 Zope Corporation and Contributors. All Rights Reserved.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE
#
##############################################################################
import os, sys, unittest, warnings

from Products.PythonScripts.PythonScript import PythonScript
from AccessControl.SecurityManagement import newSecurityManager
from AccessControl.SecurityManagement import noSecurityManager
from RestrictedPython.tests.verify import verify


if __name__=='__main__':
here = os.getcwd()
else:
here = os.path.dirname(__file__)
if not here:
here = os.getcwd()

class WarningInterceptor:

_old_stderr = None
_our_stderr_stream = None

def _trap_warning_output( self ):

if self._old_stderr is not None:
return

import sys
from StringIO import StringIO

self._old_stderr = sys.stderr
self._our_stderr_stream = sys.stderr = StringIO()

def _free_warning_output( self ):

if self._old_stderr is None:
return

import sys
sys.stderr = self._old_stderr

# Test Classes

def readf(name):
path = os.path.join(here, 'tscripts', '%s.ps' % name)
return open(path, 'r').read()

class VerifiedPythonScript(PythonScript):

def _newfun(self, code):
verify(code)
return PythonScript._newfun(self, code)


class PythonScriptTestBase(unittest.TestCase):
def setUp(self):
newSecurityManager(None, None)

def tearDown(self):
noSecurityManager()

def _newPS(self, txt, bind=None):
ps = VerifiedPythonScript('ps')
ps.ZBindings_edit(bind or {})
ps.write(txt)
ps._makeFunction()
if ps.errors:
raise SyntaxError, ps.errors[0]
return ps

def _filePS(self, fname, bind=None):
ps = VerifiedPythonScript(fname)
ps.ZBindings_edit(bind or {})
ps.write(readf(fname))
ps._makeFunction()
if ps.errors:
raise SyntaxError, ps.errors[0]
return ps

class TestPythonScriptNoAq(PythonScriptTestBase):

def testEmpty(self):
empty = self._newPS('')()
self.failUnless(empty is None)

def testIndented(self):
# This failed to compile in Zope 2.4.0b2.
res = self._newPS('if 1:\n return 2')()
self.assertEqual(res, 2)

def testReturn(self):
res = self._newPS('return 1')()
self.assertEqual(res, 1)

def testReturnNone(self):
res = self._newPS('return')()
self.failUnless(res is None)

def testParam1(self):
res = self._newPS('##parameters=x\nreturn x')('txt')
self.assertEqual(res, 'txt')

def testParam2(self):
eq = self.assertEqual
one, two = self._newPS('##parameters=x,y\nreturn x,y')('one','two')
eq(one, 'one')
eq(two, 'two')

def testParam26(self):
import string
params = string.letters[:26]
sparams = ','.join(params)
ps = self._newPS('##parameters=%s\nreturn %s' % (sparams, sparams))
res = ps(*params)
self.assertEqual(res, tuple(params))

def testArithmetic(self):
res = self._newPS('return 1 * 5 + 4 / 2 - 6')()
self.assertEqual(res, 1)

def testCollector2295(self):
res = self._newPS('if False:\n pass\n#hi')

def testCollector2295(self):
res = self._newPS('if False:\n pass\n#hi')

def testReduce(self):
res = self._newPS('return reduce(lambda x, y: x + y, [1,3,5,7])')()
self.assertEqual(res, 16)
res = self._newPS('return reduce(lambda x, y: x + y, [1,3,5,7], 1)')()
self.assertEqual(res, 17)

def testImport(self):
eq = self.assertEqual
a, b, c = self._newPS('import string; return string.split("a b c")')()
eq(a, 'a')
eq(b, 'b')
eq(c, 'c')

def testWhileLoop(self):
res = self._filePS('while_loop')()
self.assertEqual(res, 1)

def testForLoop(self):
res = self._filePS('for_loop')()
self.assertEqual(res, 10)

def testMutateLiterals(self):
eq = self.assertEqual
l, d = self._filePS('mutate_literals')()
eq(l, [2])
eq(d, {'b': 2})

def testTupleUnpackAssignment(self):
eq = self.assertEqual
d, x = self._filePS('tuple_unpack_assignment')()
eq(d, {'a': 0, 'b': 1, 'c': 2})
eq(x, 3)

def testDoubleNegation(self):
res = self._newPS('return not not "this"')()
self.assertEqual(res, 1)

def testTryExcept(self):
eq = self.assertEqual
a, b = self._filePS('try_except')()
eq(a, 1)
eq(b, 1)

def testBigBoolean(self):
res = self._filePS('big_boolean')()
self.failUnless(res)

def testFibonacci(self):
res = self._filePS('fibonacci')()
self.assertEqual(
res, [1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377,
610, 987, 1597, 2584, 4181, 6765, 10946, 17711, 28657,
46368, 75025, 121393, 196418, 317811, 514229, 832040,
1346269, 2178309, 3524578, 5702887, 9227465, 14930352,
24157817, 39088169, 63245986])

def testSimplePrint(self):
res = self._filePS('simple_print')()
self.assertEqual(res, 'a 1 []\n')

def testComplexPrint(self):
res = self._filePS('complex_print')()
self.assertEqual(res, 'double\ndouble\nx: 1\ny: 0 1 2\n\n')

def testNSBind(self):
f = self._filePS('ns_bind', bind={'name_ns': '_'})
bound = f.__render_with_namespace__({'yes': 1, 'no': self.fail})
self.assertEqual(bound, 1)

def testNSBindInvalidHeader(self):
self.assertRaises(SyntaxError, self._filePS, 'ns_bind_invalid')

def testBooleanMap(self):
res = self._filePS('boolean_map')()
self.failUnless(res)

def testGetSize(self):
f = self._filePS('complex_print')
self.assertEqual(f.get_size(), len(f.read()))

def testSet(self):
res = self._newPS('from sets import Set; return len(Set([1,2,3]))')()
self.assertEqual(res, 3)

def testDateTime(self):
res = self._newPS("return DateTime('2007/12/10').strftime('%d.%m.%Y')")()
self.assertEqual(res, '10.12.2007')


class TestPythonScriptErrors(PythonScriptTestBase):

def assertPSRaises(self, error, path=None, body=None):
assert not (path and body) and (path or body)
if body is None:
body = readf(path)
if error is SyntaxError:
self.assertRaises(SyntaxError, self._newPS, body)
else:
ps = self._newPS(body)
self.assertRaises(error, ps)

def testSubversiveExcept(self):
self.assertPSRaises(SyntaxError, path='subversive_except')

def testBadImports(self):
self.assertPSRaises(ImportError, body="from string import *")
self.assertPSRaises(ImportError, body="from datetime import datetime")
#self.assertPSRaises(ImportError, body="import mmap")

def testAttributeAssignment(self):
# It's illegal to assign to attributes of anything that
# doesn't has enabling security declared.
# Classes (and their instances) defined by restricted code
# are an exception -- they are fully readable and writable.
cases = [("import string", "string"),
("def f(): pass", "f"),
]
assigns = ["%s.splat = 'spam'",
"setattr(%s, '_getattr_', lambda x, y: True)",
"del %s.splat",
]

for defn, name in cases:
for asn in assigns:
f = self._newPS(defn + "\n" + asn % name)
self.assertRaises(TypeError, f)

class TestPythonScriptGlobals(PythonScriptTestBase, WarningInterceptor):

def setUp(self):
PythonScriptTestBase.setUp(self)

def tearDown(self):
self._free_warning_output()
PythonScriptTestBase.tearDown(self)

def _exec(self, script, bound_names=None, args=None, kws=None):
if args is None:
args = ()
if kws is None:
kws = {}
bindings = {'name_container': 'container'}
f = self._filePS(script, bindings)
return f._exec(bound_names, args, kws)

def testGlobalIsDeclaration(self):
bindings = {'container': 7}
results = self._exec('global_is_declaration', bindings)
self.assertEqual(results, 8)

def test__name__(self):
f = self._filePS('class.__name__')
self.assertEqual(f(), ("'foo'>", "'string'"))

if sys.version_info < (2, 6):
def test_filepath(self):
# This test is meant to raise a deprecation warning.
# It used to fail mysteriously instead.
self._trap_warning_output()
f = self._filePS('filepath')
self.assertEqual(f(), [0])
self._free_warning_output()
else:
def test_filepath(self):
# On Python 2.6, this now raises a TypeError.
f = self._filePS('filepath')
self.assertRaises(TypeError, f)

class PythonScriptInterfaceConformanceTests(unittest.TestCase):

def test_class_conforms_to_IWriteLock(self):
from zope.interface.verify import verifyClass
from webdav.interfaces import IWriteLock
verifyClass(IWriteLock, PythonScript)

def test_suite():
suite = unittest.TestSuite()
suite.addTest(unittest.makeSuite(TestPythonScriptNoAq))
suite.addTest(unittest.makeSuite(TestPythonScriptErrors))
suite.addTest(unittest.makeSuite(TestPythonScriptGlobals))
suite.addTest(unittest.makeSuite(PythonScriptInterfaceConformanceTests))
return suite


def main():
unittest.TextTestRunner().run(test_suite())


if __name__ == '__main__':
main()

0 comments on commit 5c3ddbe

Please sign in to comment.