Documentation of RequestArgument test cases.

This commit is contained in:
s3lph 2018-06-29 18:11:26 +02:00
parent ab9e470c35
commit 73c7dbe89f
2 changed files with 145 additions and 5 deletions

View file

@ -250,7 +250,7 @@ class RequestArgument(object):
if index == 0: if index == 0:
# Return an immutable view of the single scalar value # Return an immutable view of the single scalar value
return _View(self.__name, self.__value) return _View(self.__name, self.__value)
raise ValueError('Scalar RequestArgument only indexable with 0') raise IndexError('Scalar RequestArgument only indexable with 0')
# Pass the index or slice through to the array, packing the result in an immutable view # Pass the index or slice through to the array, packing the result in an immutable view
return _View(self.__name, self.__value[index]) return _View(self.__name, self.__value[index])

View file

@ -9,196 +9,336 @@ from matemat.webserver.requestargs import _View
class TestRequestArguments(unittest.TestCase): class TestRequestArguments(unittest.TestCase):
"""
Test cases for the RequestArgument class.
"""
def test_create_default(self): def test_create_default(self):
"""
Test creation of an empty RequestArgument
"""
ra = RequestArgument('foo') ra = RequestArgument('foo')
# Name must be set to 1st argument
self.assertEqual('foo', ra.name) self.assertEqual('foo', ra.name)
# Must be a 0-length array
self.assertEqual(0, len(ra)) self.assertEqual(0, len(ra))
self.assertFalse(ra.is_scalar) self.assertFalse(ra.is_scalar)
self.assertTrue(ra.is_array) self.assertTrue(ra.is_array)
# Must not be a view
self.assertFalse(ra.is_view) self.assertFalse(ra.is_view)
def test_create_str_scalar(self): def test_create_str_scalar(self):
"""
Test creation of a scalar RequestArgument with string value.
"""
ra = RequestArgument('foo', ('text/plain', 'bar')) ra = RequestArgument('foo', ('text/plain', 'bar'))
# Name must be set to 1st argument
self.assertEqual('foo', ra.name) self.assertEqual('foo', ra.name)
# Must be a scalar, length 1
self.assertEqual(1, len(ra)) self.assertEqual(1, len(ra))
self.assertTrue(ra.is_scalar) self.assertTrue(ra.is_scalar)
self.assertFalse(ra.is_array) self.assertFalse(ra.is_array)
# Scalar value must be representable both as str and bytes
self.assertEqual('bar', ra.get_str()) self.assertEqual('bar', ra.get_str())
self.assertEqual(b'bar', ra.get_bytes()) self.assertEqual(b'bar', ra.get_bytes())
# Content-Type must be set correctly
self.assertEqual('text/plain', ra.get_content_type()) self.assertEqual('text/plain', ra.get_content_type())
# Using indices must result in an error
with self.assertRaises(ValueError): with self.assertRaises(ValueError):
self.assertEqual('bar', ra.get_str(0)) self.assertEqual('bar', ra.get_str(0))
with self.assertRaises(ValueError): with self.assertRaises(ValueError):
self.assertEqual('bar', ra.get_bytes(0)) self.assertEqual('bar', ra.get_bytes(0))
with self.assertRaises(ValueError): with self.assertRaises(ValueError):
self.assertEqual('bar', ra.get_content_type(0)) self.assertEqual('bar', ra.get_content_type(0))
# Must not be a view
self.assertFalse(ra.is_view) self.assertFalse(ra.is_view)
def test_create_str_scalar_array(self): def test_create_str_scalar_array(self):
"""
Test creation of a scalar RequestArgument with string value, passing an array instead of a single tuple.
"""
ra = RequestArgument('foo', [('text/plain', 'bar')]) ra = RequestArgument('foo', [('text/plain', 'bar')])
# Name must be set to 1st argument
self.assertEqual('foo', ra.name) self.assertEqual('foo', ra.name)
# Must be a scalar, length 1
self.assertEqual(1, len(ra)) self.assertEqual(1, len(ra))
self.assertTrue(ra.is_scalar) self.assertTrue(ra.is_scalar)
self.assertFalse(ra.is_array) self.assertFalse(ra.is_array)
# Scalar value must be representable both as str and bytes
self.assertEqual('bar', ra.get_str()) self.assertEqual('bar', ra.get_str())
self.assertEqual(b'bar', ra.get_bytes()) self.assertEqual(b'bar', ra.get_bytes())
# Content-Type must be set correctly
self.assertEqual('text/plain', ra.get_content_type()) self.assertEqual('text/plain', ra.get_content_type())
# Using indices must result in an error
with self.assertRaises(ValueError): with self.assertRaises(ValueError):
self.assertEqual('bar', ra.get_str(0)) self.assertEqual('bar', ra.get_str(0))
with self.assertRaises(ValueError): with self.assertRaises(ValueError):
self.assertEqual('bar', ra.get_bytes(0)) self.assertEqual('bar', ra.get_bytes(0))
with self.assertRaises(ValueError): with self.assertRaises(ValueError):
self.assertEqual('bar', ra.get_content_type(0)) self.assertEqual('bar', ra.get_content_type(0))
# Must not be a view
self.assertFalse(ra.is_view) self.assertFalse(ra.is_view)
def test_create_bytes_scalar(self): def test_create_bytes_scalar(self):
"""
Test creation of a scalar RequestArgument with bytes value.
"""
ra = RequestArgument('foo', ('application/octet-stream', b'\x00\x80\xff\xfe')) ra = RequestArgument('foo', ('application/octet-stream', b'\x00\x80\xff\xfe'))
# Name must be set to 1st argument
self.assertEqual('foo', ra.name) self.assertEqual('foo', ra.name)
# Must be a scalar, length 1
self.assertEqual(1, len(ra)) self.assertEqual(1, len(ra))
self.assertTrue(ra.is_scalar) self.assertTrue(ra.is_scalar)
self.assertFalse(ra.is_array) self.assertFalse(ra.is_array)
# Conversion to UTF-8 string must fail; bytes representation must work
with self.assertRaises(UnicodeDecodeError): with self.assertRaises(UnicodeDecodeError):
ra.get_str() ra.get_str()
self.assertEqual(b'\x00\x80\xff\xfe', ra.get_bytes()) self.assertEqual(b'\x00\x80\xff\xfe', ra.get_bytes())
# Content-Type must be set correctly
self.assertEqual('application/octet-stream', ra.get_content_type()) self.assertEqual('application/octet-stream', ra.get_content_type())
# Using indices must result in an error
with self.assertRaises(ValueError): with self.assertRaises(ValueError):
self.assertEqual('bar', ra.get_str(0)) self.assertEqual('bar', ra.get_str(0))
with self.assertRaises(ValueError): with self.assertRaises(ValueError):
self.assertEqual('bar', ra.get_bytes(0)) self.assertEqual('bar', ra.get_bytes(0))
with self.assertRaises(ValueError): with self.assertRaises(ValueError):
self.assertEqual('bar', ra.get_content_type(0)) self.assertEqual('bar', ra.get_content_type(0))
# Must not be a view
self.assertFalse(ra.is_view) self.assertFalse(ra.is_view)
def test_create_array(self): def test_create_array(self):
"""
Test creation of an array RequestArgument with mixed str and bytes initial value.
"""
ra = RequestArgument('foo', [ ra = RequestArgument('foo', [
('text/plain', 'bar'), ('text/plain', 'bar'),
('application/octet-stream', b'\x00\x80\xff\xfe') ('application/octet-stream', b'\x00\x80\xff\xfe')
]) ])
# Name must be set to 1st argument
self.assertEqual('foo', ra.name) self.assertEqual('foo', ra.name)
# Must be an array, length 2
self.assertEqual(2, len(ra)) self.assertEqual(2, len(ra))
self.assertFalse(ra.is_scalar) self.assertFalse(ra.is_scalar)
self.assertTrue(ra.is_array) self.assertTrue(ra.is_array)
# Retrieving values without an index must fail
with self.assertRaises(ValueError): with self.assertRaises(ValueError):
ra.get_str() ra.get_str()
with self.assertRaises(ValueError): with self.assertRaises(ValueError):
ra.get_bytes() ra.get_bytes()
with self.assertRaises(ValueError): with self.assertRaises(ValueError):
ra.get_content_type() ra.get_content_type()
# The first value must be representable both as str and bytes, and have ctype text/plain
self.assertEqual('bar', ra.get_str(0)) self.assertEqual('bar', ra.get_str(0))
self.assertEqual(b'bar', ra.get_bytes(0)) self.assertEqual(b'bar', ra.get_bytes(0))
self.assertEqual('text/plain', ra.get_content_type(0)) self.assertEqual('text/plain', ra.get_content_type(0))
# Conversion of the second value to UTF-8 string must fail; bytes representation must work
with self.assertRaises(UnicodeDecodeError): with self.assertRaises(UnicodeDecodeError):
ra.get_str(1) ra.get_str(1)
self.assertEqual(b'\x00\x80\xff\xfe', ra.get_bytes(1)) self.assertEqual(b'\x00\x80\xff\xfe', ra.get_bytes(1))
# The second value's ctype must be correct
self.assertEqual('application/octet-stream', ra.get_content_type(1)) self.assertEqual('application/octet-stream', ra.get_content_type(1))
# Must not be a view
self.assertFalse(ra.is_view) self.assertFalse(ra.is_view)
def test_append_empty_str(self): def test_append_empty_str(self):
"""
Test appending a str value to an empty RequestArgument.
"""
# Initialize the empty RequestArgument
ra = RequestArgument('foo') ra = RequestArgument('foo')
self.assertEqual(0, len(ra)) self.assertEqual(0, len(ra))
self.assertFalse(ra.is_scalar) self.assertFalse(ra.is_scalar)
# Append a string value
ra.append('text/plain', 'bar') ra.append('text/plain', 'bar')
# New length must be 1, empty array must be converted to scalar
self.assertEqual(1, len(ra)) self.assertEqual(1, len(ra))
self.assertTrue(ra.is_scalar) self.assertTrue(ra.is_scalar)
# Retrieval of the new value must work both in str and bytes representation
self.assertEqual('bar', ra.get_str()) self.assertEqual('bar', ra.get_str())
self.assertEqual(b'bar', ra.get_bytes()) self.assertEqual(b'bar', ra.get_bytes())
# Content type of the new value must be correct
self.assertEqual('text/plain', ra.get_content_type()) self.assertEqual('text/plain', ra.get_content_type())
# Must not be a view
self.assertFalse(ra.is_view) self.assertFalse(ra.is_view)
def test_append_empty_bytes(self): def test_append_empty_bytes(self):
"""
Test appending a bytes value to an empty RequestArgument.
"""
# Initialize the empty RequestArgument
ra = RequestArgument('foo') ra = RequestArgument('foo')
self.assertEqual(0, len(ra)) self.assertEqual(0, len(ra))
self.assertFalse(ra.is_scalar) self.assertFalse(ra.is_scalar)
# Append a bytes value
ra.append('application/octet-stream', b'\x00\x80\xff\xfe') ra.append('application/octet-stream', b'\x00\x80\xff\xfe')
# New length must be 1, empty array must be converted to scalar
self.assertEqual(1, len(ra)) self.assertEqual(1, len(ra))
self.assertTrue(ra.is_scalar) self.assertTrue(ra.is_scalar)
# Conversion of the new value to UTF-8 string must fail; bytes representation must work
with self.assertRaises(UnicodeDecodeError): with self.assertRaises(UnicodeDecodeError):
ra.get_str() ra.get_str()
self.assertEqual(b'\x00\x80\xff\xfe', ra.get_bytes()) self.assertEqual(b'\x00\x80\xff\xfe', ra.get_bytes())
# Content type of the new value must be correct
self.assertEqual('application/octet-stream', ra.get_content_type()) self.assertEqual('application/octet-stream', ra.get_content_type())
# Must not be a view
self.assertFalse(ra.is_view) self.assertFalse(ra.is_view)
def test_append_multiple(self): def test_append_multiple(self):
"""
Test appending multiple values to an empty RequestArgument.
"""
# Initialize the empty RequestArgument
ra = RequestArgument('foo') ra = RequestArgument('foo')
self.assertEqual(0, len(ra)) self.assertEqual(0, len(ra))
self.assertFalse(ra.is_scalar) self.assertFalse(ra.is_scalar)
# Append a first value
ra.append('text/plain', 'bar') ra.append('text/plain', 'bar')
# New length must be 1, empty array must be converted to scalar
self.assertEqual(1, len(ra)) self.assertEqual(1, len(ra))
self.assertTrue(ra.is_scalar) self.assertTrue(ra.is_scalar)
self.assertEqual(b'bar', ra.get_bytes())
# Append a second value
ra.append('application/octet-stream', b'\x00\x80\xff\xfe') ra.append('application/octet-stream', b'\x00\x80\xff\xfe')
# New length must be 2, scalar must be converted to array
self.assertEqual(2, len(ra)) self.assertEqual(2, len(ra))
self.assertFalse(ra.is_scalar) self.assertFalse(ra.is_scalar)
self.assertEqual(b'bar', ra.get_bytes(0))
self.assertEqual(b'\x00\x80\xff\xfe', ra.get_bytes(1))
# Append a third value
ra.append('text/plain', 'Hello, World!') ra.append('text/plain', 'Hello, World!')
# New length must be 3, array must remain array
self.assertEqual(3, len(ra)) self.assertEqual(3, len(ra))
self.assertFalse(ra.is_scalar) self.assertFalse(ra.is_scalar)
self.assertEqual(b'bar', ra.get_bytes(0))
self.assertEqual(b'\x00\x80\xff\xfe', ra.get_bytes(1))
self.assertEqual(b'Hello, World!', ra.get_bytes(2))
def test_iterate_empty(self): def test_iterate_empty(self):
"""
Test iterating an empty RequestArgument.
"""
ra = RequestArgument('foo') ra = RequestArgument('foo')
self.assertEqual(0, len(ra)) self.assertEqual(0, len(ra))
# No value must be yielded from iterating an empty instance
for _ in ra: for _ in ra:
self.fail() self.fail()
def test_iterate_scalar(self): def test_iterate_scalar(self):
"""
Test iterating a scalar RequestArgument.
"""
ra = RequestArgument('foo', ('text/plain', 'bar')) ra = RequestArgument('foo', ('text/plain', 'bar'))
self.assertTrue(ra.is_scalar) self.assertTrue(ra.is_scalar)
# Counter for the number of iterations
count: int = 0 count: int = 0
for it in ra: for it in ra:
# Make sure the yielded value is a scalar view and has the same name as the original instance
self.assertIsInstance(it, _View) self.assertIsInstance(it, _View)
self.assertEqual('foo', it.name)
self.assertTrue(it.is_view) self.assertTrue(it.is_view)
self.assertEqual('foo', it.name)
self.assertTrue(it.is_scalar) self.assertTrue(it.is_scalar)
count += 1 count += 1
# Only one value must be yielded from iterating a scalar instance
self.assertEqual(1, count) self.assertEqual(1, count)
def test_iterate_array(self): def test_iterate_array(self):
"""
Test iterating an array RequestArgument.
"""
ra = RequestArgument('foo', [('text/plain', 'bar'), ('abc', b'def'), ('xyz', '1337')]) ra = RequestArgument('foo', [('text/plain', 'bar'), ('abc', b'def'), ('xyz', '1337')])
self.assertFalse(ra.is_scalar) self.assertFalse(ra.is_scalar)
# Container to put the iterated ctypes into
items: List[str] = list() items: List[str] = list()
for it in ra: for it in ra:
# Make sure the yielded values are scalar views and have the same name as the original instance
self.assertIsInstance(it, _View) self.assertIsInstance(it, _View)
self.assertTrue(it.is_view) self.assertTrue(it.is_view)
self.assertTrue(it.is_scalar) self.assertTrue(it.is_scalar)
# Collect the value's ctype
items.append(it.get_content_type()) items.append(it.get_content_type())
# Compare collected ctypes with expected result
self.assertEqual(['text/plain', 'abc', 'xyz'], items) self.assertEqual(['text/plain', 'abc', 'xyz'], items)
def test_iterate_sliced(self): def test_slice(self):
"""
Test slicing an array RequestArgument.
"""
ra = RequestArgument('foo', [('a', 'b'), ('c', 'd'), ('e', 'f'), ('g', 'h'), ('i', 'j'), ('k', 'l')]) ra = RequestArgument('foo', [('a', 'b'), ('c', 'd'), ('e', 'f'), ('g', 'h'), ('i', 'j'), ('k', 'l')])
self.assertFalse(ra.is_scalar) # Create the sliced view
sliced = ra[1:4:2]
# Make sure the sliced value is a view
self.assertIsInstance(sliced, _View)
self.assertTrue(sliced.is_view)
# Make sure the slice has the same name
self.assertEqual('foo', sliced.name)
# Make sure the slice has the expected shape (array of the 2nd and 4th scalar in the original)
self.assertTrue(sliced.is_array)
self.assertEqual(2, len(sliced))
self.assertEqual('d', sliced.get_str(0))
self.assertEqual('h', sliced.get_str(1))
def test_iterate_sliced(self):
"""
Test iterating a sliced array RequestArgument.
"""
ra = RequestArgument('foo', [('a', 'b'), ('c', 'd'), ('e', 'f'), ('g', 'h'), ('i', 'j'), ('k', 'l')])
# Container to put the iterated ctypes into
items: List[str] = list() items: List[str] = list()
# Iterate the sliced view
for it in ra[1:4:2]: for it in ra[1:4:2]:
# Make sure the yielded values are scalar views and have the same name as the original instance
self.assertIsInstance(it, _View) self.assertIsInstance(it, _View)
self.assertTrue(it.is_view) self.assertTrue(it.is_view)
self.assertEqual('foo', it.name)
self.assertTrue(it.is_scalar) self.assertTrue(it.is_scalar)
items.append(it.get_content_type()) items.append(it.get_content_type())
# Make sure the expected values are collected (array of the 2nd and 4th scalar in the original)
self.assertEqual(['c', 'g'], items) self.assertEqual(['c', 'g'], items)
def test_index_scalar(self): def test_index_scalar(self):
"""
Test indexing of a scalar RequestArgument.
"""
ra = RequestArgument('foo', ('bar', 'baz')) ra = RequestArgument('foo', ('bar', 'baz'))
# Index the scalar RequestArgument instance, obtaining an immutable view
it = ra[0] it = ra[0]
# Make sure the value is a scalar view with the same properties as the original instance
self.assertIsInstance(it, _View) self.assertIsInstance(it, _View)
self.assertTrue(it.is_scalar)
self.assertEqual('foo', it.name) self.assertEqual('foo', it.name)
self.assertEqual('bar', it.get_content_type()) self.assertEqual('bar', it.get_content_type())
self.assertEqual('baz', it.get_str()) self.assertEqual('baz', it.get_str())
with self.assertRaises(ValueError): # Make sure other indices don't work
with self.assertRaises(IndexError):
_ = ra[1] _ = ra[1]
def test_index_array(self): def test_index_array(self):
"""
Test indexing of an array RequestArgument.
"""
ra = RequestArgument('foo', [('a', 'b'), ('c', 'd')]) ra = RequestArgument('foo', [('a', 'b'), ('c', 'd')])
# Index the array RequestArgument instance, obtaining an immutable view
it = ra[1] it = ra[1]
# Make sure the value is a scalar view with the same properties as the value in the original instance
self.assertIsInstance(it, _View) self.assertIsInstance(it, _View)
self.assertEqual('foo', it.name) self.assertEqual('foo', it.name)
self.assertEqual('c', it.get_content_type()) self.assertEqual('c', it.get_content_type())
self.assertEqual('d', it.get_str()) self.assertEqual('d', it.get_str())
def test_view_immutable(self): def test_view_immutable(self):
"""
Test immutability of views.
"""
ra = RequestArgument('foo', ('bar', 'baz')) ra = RequestArgument('foo', ('bar', 'baz'))
# Index the scalar RequestArgument instance, obtaining an immutable view
it = ra[0] it = ra[0]
# Make sure the returned value is a view
self.assertIsInstance(it, _View) self.assertIsInstance(it, _View)
# Make sure the returned value is immutable
with self.assertRaises(TypeError): with self.assertRaises(TypeError):
it.append('foo', 'bar') it.append('foo', 'bar')