More negative tests, pylint work. #175

This commit is contained in:
jevans 2014-02-23 12:37:47 -05:00
commit 16ce2ef883
3 changed files with 72 additions and 27 deletions

View file

@ -124,7 +124,7 @@ class Jp2kBox(object):
fptr.write(struct.pack('>I', end_pos - orig_pos))
fptr.seek(end_pos)
def parse_this_box(self, fptr, box_id, start, num_bytes):
def _parse_this_box(self, fptr, box_id, start, num_bytes):
"""Parse the current box.
Parameters
@ -214,7 +214,7 @@ class Jp2kBox(object):
# The box_length value really is the length of the box!
num_bytes = box_length
box = self.parse_this_box(fptr, box_id, start, num_bytes)
box = self._parse_this_box(fptr, box_id, start, num_bytes)
superbox.append(box)
@ -560,7 +560,8 @@ class ChannelDefinitionBox(Jp2kBox):
def _validate(self):
"""Verify that the box obeys the specifications."""
# channel type and association must be specified.
if not (len(self.index) == len(self.channel_type) == len(self.association)):
if not ((len(self.index) == len(self.channel_type)) and
(len(self.channel_type) == len(self.association))):
msg = "Length of channel definition box inputs must be the same."
raise IOError(msg)
@ -953,10 +954,18 @@ class DataReferenceBox(Jp2kBox):
msg += 'entry URL boxes.'
raise IOError(msg)
def _write_validate(self):
"""Verify that the box obeys the specifications for writing.
"""
if len(self.DR) == 0:
msg = "A data reference box cannot be empty when written to a file."
raise IOError(msg)
self._validate()
def write(self, fptr):
"""Write a Data Reference box to file.
"""
self._validate()
self._write_validate()
# Very similar to the say a superbox is written.
orig_pos = fptr.tell()

View file

@ -1110,6 +1110,10 @@ def _validate_nonzero_image_size(nrows, ncols, component_index):
raise IOError(msg)
JP2_IDS = ['colr', 'cdef', 'cmap', 'jp2c', 'ftyp', 'ihdr', 'jp2h', 'jP ',
'pclr', 'res ', 'resc', 'resd', 'xml ', 'ulst', 'uinf', 'url ',
'uuid']
def _validate_jp2_box_sequence(boxes):
"""Run through series of tests for JP2 box legality.
@ -1118,6 +1122,18 @@ def _validate_jp2_box_sequence(boxes):
_validate_signature_compatibility(boxes)
_validate_jp2h(boxes)
_validate_jp2c(boxes)
if boxes[1].brand == 'jpx ':
_validate_jpx_box_sequence(boxes)
else:
count = _collect_box_count(boxes)
for id in count.keys():
if id not in JP2_IDS:
msg = "The presence of a '{0}' box requires that the file type "
msg += "brand be set to 'jpx '."
raise IOError(msg.format(id))
def _validate_jpx_box_sequence(boxes):
"""Run through series of tests for JPX box legality."""
_validate_association(boxes)
_validate_label(boxes)
_validate_jpx_brand(boxes, boxes[1].brand)
@ -1125,7 +1141,6 @@ def _validate_jp2_box_sequence(boxes):
_validate_singletons(boxes)
_validate_top_level(boxes)
def _validate_signature_compatibility(boxes):
"""Validate the file signature and compatibility status."""
# Check for a bad sequence of boxes.

View file

@ -4,12 +4,10 @@ Test suite specifically targeting JPX box layout.
"""
import os
import shutil
import struct
import sys
import tempfile
import unittest
import warnings
import xml.etree.cElementTree as ET
import glymur
@ -41,6 +39,18 @@ class TestJPXWrap(unittest.TestCase):
def tearDown(self):
os.unlink(self.xmlfile)
def test_jp2_with_jpx_box(self):
"""If the brand is jp2, then no jpx boxes are allowed."""
jp2 = Jp2k(self.jp2file)
boxes = [jp2.box[idx] for idx in [0, 1, 2, 4]]
boxes = jp2.box
boxes.append(glymur.jp2box.AssociationBox())
with tempfile.NamedTemporaryFile(suffix=".jpx") as tfile:
with self.assertRaises(IOError):
jp2.wrap(tfile.name, boxes=boxes)
def test_ftbl(self):
"""Write a fragment table box."""
# Add a negative test where offset < 0
@ -128,17 +138,18 @@ class TestJPXWrap(unittest.TestCase):
self.assertEqual(jpx.box[-1].box[2].label, label)
def test_empty_data_reference(self):
"""Data reference boxes can be empty."""
"""Empty data reference boxes can be created, but not written."""
jp2 = Jp2k(self.jp2file)
boxes = [jp2.box[idx] for idx in [0, 1, 2, 4]]
boxes[1].brand = 'jpx '
dref = glymur.jp2box.DataReferenceBox()
boxes.append(dref)
with tempfile.NamedTemporaryFile(suffix=".jpx") as tfile:
jpx = jp2.wrap(tfile.name, boxes=boxes)
self.assertEqual(jpx.box[-1].box_id, 'dtbl')
self.assertEqual(len(jpx.box[-1].box), 0)
with self.assertRaises(IOError):
jp2.wrap(tfile.name, boxes=boxes)
def test_deurl_child_of_dtbl(self):
"""Data reference boxes can only contain data entry url boxes."""
@ -157,13 +168,16 @@ class TestJPXWrap(unittest.TestCase):
with tempfile.NamedTemporaryFile(suffix=".jpx") as tfile:
with self.assertRaises(IOError):
jpx = jp2.wrap(tfile.name, boxes=boxes)
jp2.wrap(tfile.name, boxes=boxes)
def test_only_one_data_reference(self):
"""Data reference boxes cannot be inside a superbox ."""
jp2 = Jp2k(self.jp2file)
boxes = [jp2.box[idx] for idx in [0, 1, 2, 4]]
# Have to make the ftyp brand jpx.
boxes[1].brand = 'jpx '
flag = 0
version = (0, 0, 0)
url = 'file:////usr/local/bin'
@ -174,16 +188,16 @@ class TestJPXWrap(unittest.TestCase):
with tempfile.NamedTemporaryFile(suffix=".jpx") as tfile:
with self.assertRaises(IOError):
jpx = jp2.wrap(tfile.name, boxes=boxes)
jp2.wrap(tfile.name, boxes=boxes)
def test_lbl_at_top_level(self):
"""Label boxes can only be inside a asoc box ."""
jp2 = Jp2k(self.jp2file)
boxes = [jp2.box[idx] for idx in [0, 1, 2, 4]]
flag = 0
version = (0, 0, 0)
url = 'file:////usr/local/bin'
# Have to make the ftyp brand jpx.
boxes[1].brand = 'jpx '
lblb = glymur.jp2box.LabelBox('hi there')
# Put it inside the jp2 header box.
@ -191,13 +205,16 @@ class TestJPXWrap(unittest.TestCase):
with tempfile.NamedTemporaryFile(suffix=".jpx") as tfile:
with self.assertRaises(IOError):
jpx = jp2.wrap(tfile.name, boxes=boxes)
jp2.wrap(tfile.name, boxes=boxes)
def test_data_reference_not_at_top_level(self):
def test_data_reference_in_subbox(self):
"""Data reference boxes cannot be inside a superbox ."""
jp2 = Jp2k(self.jp2file)
boxes = [jp2.box[idx] for idx in [0, 1, 2, 4]]
# Have to make the ftyp brand jpx.
boxes[1].brand = 'jpx '
flag = 0
version = (0, 0, 0)
url = 'file:////usr/local/bin'
@ -209,13 +226,17 @@ class TestJPXWrap(unittest.TestCase):
with tempfile.NamedTemporaryFile(suffix=".jpx") as tfile:
with self.assertRaises(IOError):
jpx = jp2.wrap(tfile.name, boxes=boxes)
jp2.wrap(tfile.name, boxes=boxes)
def test_jp2_to_jpx_sans_jp2_compatibility(self):
"""jp2 wrapped to jpx not including jp2 compatibility is wrong."""
jp2 = Jp2k(self.jp2file)
boxes = [jp2.box[idx] for idx in [0, 1, 2, 4]]
# Have to make the ftyp brand jpx.
boxes[1].brand = 'jpx '
boxes[1].compatibility_list.append('jp2 ')
numbers = [0, 1]
nlst = glymur.jp2box.NumberListBox(numbers)
the_xml = ET.fromstring('<?xml version="1.0"?><data>0</data>')
@ -225,7 +246,7 @@ class TestJPXWrap(unittest.TestCase):
with tempfile.NamedTemporaryFile(suffix=".jpx") as tfile:
with self.assertRaises(RuntimeError):
jpx = jp2.wrap(tfile.name, boxes=boxes)
jp2.wrap(tfile.name, boxes=boxes)
def test_jp2_to_jpx_sans_jpx_brand(self):
"""Verify error when jp2 wrapped to jpx does not include jpx brand."""
@ -241,7 +262,7 @@ class TestJPXWrap(unittest.TestCase):
with tempfile.NamedTemporaryFile(suffix=".jpx") as tfile:
with self.assertRaises(RuntimeError):
jpx = jp2.wrap(tfile.name, boxes=boxes)
jp2.wrap(tfile.name, boxes=boxes)
@unittest.skipIf(os.name == "nt", "Temporary file issue on window.")
@ -262,7 +283,7 @@ class TestJPX(unittest.TestCase):
flst = glymur.jp2box.FragmentListBox(offset, length, reference)
with self.assertRaises(IOError):
with tempfile.TemporaryFile() as tfile:
flst.write(tfile)
flst.write(tfile)
def test_flst_offsets_not_positive(self):
"""A fragment list box offsets must be positive."""
@ -272,7 +293,7 @@ class TestJPX(unittest.TestCase):
flst = glymur.jp2box.FragmentListBox(offset, length, reference)
with self.assertRaises(IOError):
with tempfile.TemporaryFile() as tfile:
flst.write(tfile)
flst.write(tfile)
def test_flst_lengths_not_positive(self):
"""A fragment list box lengths must be positive."""
@ -282,14 +303,14 @@ class TestJPX(unittest.TestCase):
flst = glymur.jp2box.FragmentListBox(offset, length, reference)
with self.assertRaises(IOError):
with tempfile.TemporaryFile() as tfile:
flst.write(tfile)
flst.write(tfile)
def test_ftbl_boxes_empty(self):
"""A fragment table box must have at least one child box."""
ftbl = glymur.jp2box.FragmentTableBox()
with self.assertRaises(IOError):
with tempfile.TemporaryFile() as tfile:
ftbl.write(tfile)
ftbl.write(tfile)
def test_ftbl_child_not_flst(self):
"""A fragment table box can only contain a fragment list."""
@ -297,7 +318,7 @@ class TestJPX(unittest.TestCase):
ftbl = glymur.jp2box.FragmentTableBox(box=[free])
with self.assertRaises(IOError):
with tempfile.TemporaryFile() as tfile:
ftbl.write(tfile)
ftbl.write(tfile)
def test_jpx_rreq_mask_length_3(self):
"""There are some JPX files with rreq mask length of 3."""
@ -314,7 +335,7 @@ class TestJPX(unittest.TestCase):
with tempfile.NamedTemporaryFile(suffix='.jpx') as tfile:
with open(self.jpxfile, 'rb') as ifile:
tfile.write(ifile.read())
# Add the header for an unknwon superbox.
write_buffer = struct.pack('>I4s', 20, 'grp '.encode())
tfile.write(write_buffer)