# Copyright (c) 2011, Thomas Paviot ([email protected])
# All rights reserved.
# This file is part of the STEPCODE project.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
#
# Redistributions of source code must retain the above copyright notice,
# this list of conditions and the following disclaimer.
#
# Redistributions in binary form must reproduce the above copyright notice,
# this list of conditions and the following disclaimer in the documentation
# and/or other materials provided with the distribution.
#
# Neither the name of the nor the names of its contributors may
# be used to endorse or promote products derived from this software without
# specific prior written permission.
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED.
# IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
import sys
import unittest
from stepcode.SimpleDataTypes import *
from stepcode.TypeChecker import *
from stepcode.ConstructedDataTypes import *
from stepcode.AggregationDataTypes import *
#
# Simple data types
#
class TestINTEGER(unittest.TestCase):
'''
INTEGER test
'''
def test_create_from_int(self):
a = INTEGER(1)
self.assertEqual(a,1)
b = REAL(0)
self.assertEqual(b,0)
def test_create_from_string(self):
a = REAL("10")
self.assertEqual(a,10)
b = REAL("0")
self.assertEqual(b,0)
def test_type(self):
a = INTEGER(5)
self.assertTrue(isinstance(a, INTEGER))
def test_inherit_from_NUMBER(self):
a = INTEGER(6)
self.assertTrue(isinstance(a,INTEGER))
self.assertTrue(isinstance(a,NUMBER))
def test_INTEGER_ops(self):
a = INTEGER(2)
b = INTEGER(3)
c = a*b
self.assertEqual(c,6)
self.assertTrue(isinstance(c, int))
def test_create_from_string_exception(self):
'''
INT cannot be constructed from an ascii string
'''
try:
INTEGER("c")
except ValueError:
pass
except e:
self.fail('Unexpected exception thrown:', e)
else:
self.fail('ExpectedException not thrown')
class TestREAL(unittest.TestCase):
'''
REAL test
'''
def test_create_from_float(self):
a = REAL(1.5)
self.assertEqual(a,1.5)
b = REAL(0)
self.assertEqual(b,0)
def test_create_from_string(self):
a = REAL("1.5")
self.assertEqual(a,1.5)
b = REAL("0")
self.assertEqual(b,0)
def test_type(self):
a = REAL(5)
self.assertTrue(isinstance(a, REAL))
def test_inherit_from_NUMBER(self):
a = REAL(4.5)
self.assertTrue(isinstance(a,REAL))
self.assertTrue(isinstance(a,NUMBER))
def test_REAL_ops(self):
a = REAL(1.5)
b = REAL(2)
c = a*b
self.assertEqual(c,3)
self.assertTrue(isinstance(c, float))
def test_REAL_INTEGER_ops(self):
a = REAL(5.5)
b = INTEGER(3)
self.assertEqual(a+b,8.5)
self.assertTrue(isinstance(a+b, float))
def test_create_from_string_exception(self):
'''
REAL cannot be constructed from an ascii string
'''
try:
REAL("c")
except ValueError:
pass
except e:
self.fail('Unexpected exception thrown:', e)
else:
self.fail('ExpectedException not thrown')
class TestBOOLEAN(unittest.TestCase):
'''
BOOLEAN test
'''
def test_create_from_bool(self):
a = BOOLEAN(True)
self.assertTrue(a)
b = BOOLEAN(False)
self.assertFalse(b)
#
# AggregationDataType
#
class TestARRAY(unittest.TestCase):
'''
ARRAY test
'''
def test_create_array(self):
ARRAY(1,7,REAL)
#upper and lower bounds can be negative
ARRAY(-1,5,INTEGER)
ARRAY(-4,-3,INTEGER)
# they even can be both 0
ARRAY(0,0,REAL)
ARRAY(1,1,BOOLEAN)
# lower bound should be less or equal than upper bound
try:
ARRAY(3,2,REAL)
except AssertionError:
pass
except e:
self.fail('Unexpected exception thrown:', e)
else:
self.fail('ExpectedException not thrown')
def test_create_array_from_type_string(self):
# the scope is the current module
scp = sys.modules[__name__]
a = ARRAY(1,7,'REAL',scope = scp)
a[2] = REAL(2.3)
def test_array_bounds(self):
a = ARRAY(3,8,REAL)
try:
a[2]
except IndexError:
pass
except e:
self.fail('Unexpected exception thrown:', e)
else:
self.fail('ExpectedException not thrown')
try:
a[9]
except IndexError:
pass
except e:
self.fail('Unexpected exception thrown:', e)
else:
self.fail('ExpectedException not thrown')
def test_array_unique(self):
# if UNIQUE is not set to True (False by default),
# the array may contain the same instance at different
# positions
a = ARRAY(1,4,REAL)
a[3] = REAL(4)
a[4] = REAL(4)
# however, if UNIQUE, then every instances in the
# array must be different
a = ARRAY(1,4,REAL,UNIQUE=True)
a[3] = REAL(4)
try:
a[4] = REAL(4)
except AssertionError:
pass
except e:
self.fail('Unexpected exception thrown:', e)
else:
self.fail('ExpectedException not thrown')
def test_array_optional(self):
# if OPTIONAL is not set explicitly to True
# then each value must be set
a = ARRAY(1,3,REAL)
try:
a[1]
except AssertionError:
pass
except e:
self.fail('Unexpected exception thrown:', e)
else:
self.fail('ExpectedException not thrown')
# if OPTIONAL is set to True, then values
# can be indeterminated
b = ARRAY(1,3,REAL,OPTIONAL=True)
b[2] = REAL(5)
b[3] = REAL(5)
def test_array_of_array_of_real(self):
'''
create a 3*3 identify matrix
'''
my_matrix = ARRAY(1,3,ARRAY(1,3,REAL))
my_matrix[1] = ARRAY(1,3,REAL)
my_matrix[2] = ARRAY(1,3,REAL)
my_matrix[3] = ARRAY(1,3,REAL)
my_matrix[1][1] = REAL(1.0)
my_matrix[2][2] = REAL(1.0)
my_matrix[3][3] = REAL(1.0)
my_matrix[1][2] = my_matrix[1][2] = REAL(0.0)
my_matrix[1][3] = my_matrix[3][1] = REAL(0.0)
my_matrix[2][3] = my_matrix[3][2] = REAL(0.0)
class TestLIST(unittest.TestCase):
'''
LIST test
'''
def test_create_bounded_list(self):
LIST(1,7,REAL)
#upper and lower bounds can be negative
LIST(1,5,INTEGER)
# they even can be both 0
LIST(0,0,REAL)
LIST(1,1,BOOLEAN)
# lower bound should be less or equal than upper bound
try:
LIST(3,2,REAL)
except AssertionError:
pass
except e:
self.fail('Unexpected exception thrown:', e)
else:
self.fail('ExpectedException not thrown')
# lower bound should be greater or equal than zero
try:
LIST(-1,2,REAL)
except AssertionError:
pass
except e:
self.fail('Unexpected exception thrown:', e)
else:
self.fail('ExpectedException not thrown')
def test_create_unbounded_list(self):
a = LIST(0,None,REAL)
a[6] = REAL(6)
self.assertEqual(a[6],6)
b = LIST(10,None,REAL)
a[10] = REAL(7)
self.assertEqual(a[10],7)
def test_list_bounds(self):
a = LIST(3,8,REAL)
try:
a[2]
except IndexError:
pass
except e:
self.fail('Unexpected exception thrown:', e)
else:
self.fail('ExpectedException not thrown')
try:
a[9]
except IndexError:
pass
except e:
self.fail('Unexpected exception thrown:', e)
else:
self.fail('ExpectedException not thrown')
def test_list_unique(self):
# if UNIQUE is not set to True (False by default),
# the array may contain the same instance at different
# positions
a = LIST(1,4,REAL)
a[3] = REAL(4)
a[4] = REAL(4)
# however, if UNIQUE, then every instances in the
# array must be different
a = LIST(1,4,REAL,UNIQUE=True)
a[3] = REAL(4)
try:
a[3] = REAL(4)
except AssertionError:
pass
except e:
self.fail('Unexpected exception thrown:', e)
else:
self.fail('ExpectedException not thrown')
class TestBAG(unittest.TestCase):
'''
BAG test
'''
def test_create_bounded_bag(self):
BAG(1,7,REAL)
BAG(1,5,INTEGER)
BAG(0,0,REAL)
def test_create_unbounded_bag(self):
a = BAG(0,None,REAL)
def test_fill_bounded_bag(self):
b = BAG(1,3,REAL)
b.add(REAL(1.0))
b.add(REAL(2.0))
b.add(REAL(3.0))
# the bag is full, trying to add other item
# will raise an exception
try:
b.add(REAL(4.0))
except AssertionError:
pass
except e:
self.fail('Unexpected exception thrown:', e)
else:
self.fail('ExpectedException not thrown')
def test_fill_unbounded_bag(self):
'''
Fill an unbounded bag with one thousand reals
This should not raise any exception
'''
b = BAG(0,None,REAL)
for i in range(1000):
b.add(REAL(1.0))
class TestSET(unittest.TestCase):
'''
SET test
'''
def test_create_bounded_set(self):
SET(1,7,REAL)
SET(1,5,INTEGER)
SET(0,0,REAL)
def test_create_unbounded_set(self):
a = SET(0,None,REAL)
def test_fill_bounded_set(self):
b = SET(1,3,REAL)
b.add(REAL(1.0))
b.add(REAL(2.0))
b.add(REAL(3.0))
# the bag is full, trying to add other item
# will raise an exception
try:
b.add(REAL(4.0))
except AssertionError:
pass
except e:
self.fail('Unexpected exception thrown:', e)
else:
self.fail('ExpectedException not thrown')
def test_fill_bounded_set(self):
# create a set with one value allowed
c = SET(0,0,REAL)
# fill in with the same value n times
# the total size of the set should not increase
for i in range(1000):
c.add(REAL(1.0))
#
# Constructed Data Types
#
class TestENUMERATION(unittest.TestCase):
def test_simple_enum(self):
ahead_or_behind = ENUMERATION('ahead_or_behind', 'ahead behind', module=__name__)
check_type(ahead_or_behind.ahead,ahead_or_behind)
check_type(ahead_or_behind.behind,ahead_or_behind)
try:
check_type("some string",ahead_or_behind)
except TypeError:
pass
except e:
self.fail('Unexpected exception thrown:', e)
else:
self.fail('ExpectedException not thrown')
class ob1:
pass
class ob2:
pass
class TestSELECT(unittest.TestCase):
def test_select(self):
scp = sys.modules[__name__]
select_typedef = SELECT('ob1','ob2',scope = scp)
ob1_instance = ob1()
ob2_instance = ob2()
# test that line_instance is in enum type
check_type(ob1_instance, select_typedef)
check_type(ob2_instance,select_typedef)
# this one should raise an exception:
try:
check_type(REAL(3.4),select_typedef)
except TypeError:
pass
except e:
self.fail('Unexpected exception thrown:', e)
else:
self.fail('ExpectedException not thrown')
def suite():
suite = unittest.TestSuite()
suite.addTest(unittest.makeSuite(TestINTEGER))
suite.addTest(unittest.makeSuite(TestREAL))
suite.addTest(unittest.makeSuite(TestARRAY))
suite.addTest(unittest.makeSuite(TestLIST))
suite.addTest(unittest.makeSuite(TestBAG))
suite.addTest(unittest.makeSuite(TestSET))
suite.addTest(unittest.makeSuite(TestENUMERATION))
suite.addTest(unittest.makeSuite(TestSELECT))
return suite
if __name__ == '__main__':
unittest.main()