Source code for seqparse.test.test_filesequences

"""Test the FrameSequence class."""

# "Future" Libraries
from __future__ import print_function

# Standard Libraries
import os
import unittest

# Third Party Libraries
import mock
from builtins import range
from future.utils import lrange

from . import mock_os_stat
from ..sequences import FileSequence, FrameChunk, FrameSequence

###############################################################################
# class: TestFileSequences


[docs]class TestFileSequences(unittest.TestCase): """Test basic functionality on the FileSequence class.""" _test_ext = "exr" _test_name = "cat" _test_root = "/pretty/kitty".replace("/", os.sep)
[docs] def setUp(self): """Set up the test instance."""
[docs] def test_file_name_initialization(self): """FileSequence: Test initialization of an instance by file name.""" file_path = os.path.join(self._test_root, self._test_name) chunk = FrameChunk(first=1, last=11, step=2, pad=4) file_name = "{}.{}.{}".format(file_path, chunk, self._test_ext) file_names = set() for frame in chunk: file_names.add("{}.{}.{}".format(file_path, frame, self._test_ext)) fseq = FileSequence(file_name) self.assertEqual(fseq.path, self._test_root) self.assertEqual(fseq.name, self._test_name) self.assertEqual(fseq.pad, 4) self.assertEqual(set(fseq), file_names)
[docs] def test_properties(self): """FileSequence: Test getting/setting simple properties.""" fseq = FileSequence() self.assertIsNone(fseq.ext) self.assertIsNone(fseq.name) self.assertIsNone(fseq.path) fseq.name = self._test_name self.assertEqual(fseq.name, self._test_name) self.assertIsNone(fseq.path) fseq = FileSequence() fseq.path = self._test_root self.assertIsNone(fseq.name) self.assertEqual(fseq.path, self._test_root) fseq = FileSequence() fseq.ext = self._test_ext fseq.name = self._test_name fseq.path = self._test_root self.assertEqual(fseq.ext, self._test_ext) self.assertEqual(fseq.name, self._test_name) self.assertEqual(fseq.path, self._test_root) fseq.path = self._test_root + os.sep self.assertEqual(fseq.path, self._test_root) fseq = FileSequence() fseq.name = os.path.join(self._test_root, self._test_name) self.assertEqual(fseq.name, self._test_name) self.assertEqual(fseq.path, self._test_root)
[docs] def test_output(self): """FileSequence: Test string output.""" file_path = os.path.join(self._test_root, self._test_name) chunk = FrameChunk(first=1, last=11, step=2, pad=4) fseq = FileSequence(name=file_path, ext=self._test_ext, frames=chunk) file_name = "{}.{}.{}".format(file_path, chunk, self._test_ext) self.assertEqual(file_name, str(fseq)) fseq = FileSequence(frames=chunk) with self.assertRaises(AttributeError): str(fseq)
[docs] def test_frame_containment(self): """FileSequence: Test if frames are contained by a sequence.""" file_path = os.path.join(self._test_root, self._test_name) chunk1 = FrameChunk(first=1, last=11, step=1, pad=1) seq1 = FrameSequence(chunk1) frames1 = [str(x) for x in range(1, 12)] for frames in (frames1, chunk1, seq1): fseq = FileSequence( name=file_path, ext=self._test_ext, frames=frames, pad=1) for frame in frames: file_name = "{}.{}.{}".format(file_path, frame, self._test_ext) self.assertIn(frame, fseq) self.assertIn(int(frame), fseq) self.assertIn(file_name, fseq) self.assertNotIn("{:04d}".format(int(frame)), fseq) chunk2 = FrameChunk(first=1, last=11, step=1, pad=4) seq2 = FrameSequence(chunk2) frames2 = ["{:04d}".format(x) for x in range(1, 12)] for frames in (frames2, chunk2, seq2): fseq = FileSequence( name=file_path, ext=self._test_ext, frames=frames, pad=4) for frame in frames: file_name = "{}.{}.{}".format(file_path, frame, self._test_ext) self.assertIn(frame, fseq) self.assertIn(int(frame), fseq) self.assertIn(file_name, fseq) self.assertNotIn(str(int(frame)), fseq)
[docs] def test_file_containment(self): """FileSequence: Test if files are contained by a sequence.""" file_path = os.path.join(self._test_root, self._test_name) frames = lrange(1, 12) seq1 = FrameSequence(frames, pad=1) fseq1 = FileSequence(name=file_path, ext=self._test_ext, frames=seq1) file_names1 = [ "{}.{}.{}".format(file_path, x, self._test_ext) for x in frames ] for file_name in file_names1: self.assertIn(file_name, fseq1) bad_file_names1 = [ "{}.{}.{}".format(file_path, x, self._test_ext) for x in (0, 12) ] for file_name in bad_file_names1: self.assertNotIn(file_name, fseq1) seq2 = FrameSequence(frames, pad=4) fseq2 = FileSequence(name=file_path, ext=self._test_ext, frames=seq2) file_names2 = [ "{}.{:04d}.{}".format(file_path, x, self._test_ext) for x in frames ] for file_name in file_names2: self.assertIn(file_name, fseq2) bad_file_names2 = [ "{}.{:04d}.{}".format(file_path, x, self._test_ext) for x in (0, 12) ] for file_name in bad_file_names2: self.assertNotIn(file_name, fseq2)
[docs] def test_iteration(self): """FileSequence: Test iteration over an instance.""" file_path = os.path.join(self._test_root, self._test_name) data = [(lrange(1, 6), 4), (lrange(1, 21, 2) + lrange(100, 105), 1)] for frames, pad in data: fseq = FileSequence( name=file_path, ext=self._test_ext, frames=frames, pad=pad) file_names = list() for frame in frames: file_name = "{}.{:0{}d}.{}".format(file_path, frame, pad, self._test_ext) file_names.append(file_name) self.assertEqual(set(file_names), set(fseq)) print("\n\n INPUT FILES\n -----------") print("\n".join(" {}".format(x) for x in file_names)) print("\n ITERATION\n ---------") print(" o forward: ") print("\n".join(" - {}".format(x) for x in fseq)) print(" o backward:") print( "\n".join(list(" - {}".format(x) for x in reversed(fseq))))
[docs] def test_inversion(self): """FileSequence: Test frame inversion (ie, report missing frames).""" file_path = os.path.join(self._test_root, self._test_name) chunk_in = FrameChunk(first=1, last=11, step=2, pad=4) fseq = FileSequence( name=file_path, ext=self._test_ext, frames=chunk_in) chunk_out = FrameChunk(first=2, last=10, step=2, pad=4) expected = FileSequence( name=file_path, ext=self._test_ext, frames=chunk_out) inverted = fseq.invert() print("\n\n SEQUENCE\n --------") print(" input files: ", fseq) print(" expected files:", expected) print(" returned files:", inverted) self.assertEqual(str(inverted), str(expected)) chunk1 = FrameChunk(first=1, last=9, step=2, pad=4) chunk2 = FrameChunk(first=10, last=20, step=5, pad=4) seq_in = FrameSequence(chunk1) seq_in.add(chunk2) seq_in.add("0021") fseq = FileSequence(name=file_path, ext=self._test_ext, frames=seq_in) seq_out = FrameSequence(pad=4) seq_out.add(chunk1.invert()) seq_out.add(chunk2.invert()) seq_out.invert() expected = FileSequence( name=file_path, ext=self._test_ext, frames=seq_in.invert()) inverted = fseq.invert() print("\n COMPLEX FRAME\n ------------") print(" input frames: ", fseq) print(" expected frames:", expected) print(" returned frames:", inverted) print("") self.assertEqual(str(inverted), str(expected)) chunk_in = FrameChunk(first=1, last=10, pad=2) fseq = FileSequence( name=file_path, ext=self._test_ext, frames=chunk_in) expected = "" inverted = fseq.invert() print("\n SEQUENCE\n --------") print(" input files: ", fseq) print(" expected files:", expected) print(" returned files:", inverted) self.assertEqual(str(inverted), str(expected))
[docs] def test_equality(self): """FileSequence: Test the equality of instances.""" file_path = os.path.join(self._test_root, self._test_name) fseq0 = FileSequence( name=file_path, ext=self._test_ext, frames=lrange(1, 11), pad=4) fseq1 = FileSequence( name=file_path, ext=self._test_ext, frames=lrange(1, 11), pad=4) fseq2 = FileSequence( name=file_path, ext=self._test_ext, frames="0001-0010") fseq3 = FileSequence( name=file_path, ext=self._test_ext, frames="001-010") fseq4 = FileSequence( name=self._test_name, ext=self._test_ext, frames="0001-0010") seq0 = FrameSequence(lrange(1, 11), pad=4) self.assertEqual(fseq0, fseq1) self.assertEqual(fseq0, fseq2) self.assertNotEqual(fseq0, fseq3) self.assertNotEqual(fseq0, fseq4) self.assertNotEqual(fseq0, seq0)
@mock.patch("seqparse.sequences.os.stat")
[docs] def test_stat_queries(self, mock_api_call): """File: Test stat setting and queries.""" mock_api_call.side_effect = mock_os_stat file_name = "test.0001.py" full_name = os.path.join(self._test_root, file_name) fseq = FileSequence(full_name) self.assertEqual(fseq.stat(), dict()) self.assertIsNone(fseq.stat(1)) self.assertIsNone(fseq.stat("0001")) with self.assertRaises(ValueError): fseq.stat(lazy=True) with self.assertRaises(ValueError): fseq.stat(force=True) # pylint: disable=E1101 stat = fseq.stat(1, lazy=True) self.assertEqual(stat.st_size, 7975) self.assertEqual(stat.st_mtime, 1490908305) self.assertEqual(fseq.size, 7975) self.assertEqual(fseq.mtime, 1490908305) fseq = FileSequence(full_name) stat = fseq.stat(1, force=True) self.assertEqual(fseq.stat(1).st_size, 7975) self.assertEqual(fseq.stat(1).st_mtime, 1490908305) self.assertEqual(fseq.size, 7975) self.assertEqual(fseq.mtime, 1490908305)
# pylint: enable=E1101
[docs] def test_cloning(self): """FileSequence: Test cloning from an existing instance.""" file_name = "test.0001-0005,0010.py" full_name = os.path.join(self._test_root, file_name) parent = FileSequence(full_name) clone = FileSequence(parent) self.assertEqual(str(parent), str(clone)) for attr in ("full_name", "name", "pad", "path"): self.assertEqual(getattr(parent, attr), getattr(clone, attr))
[docs] def test_frame_properties(self): """FileSequence: Test frames, pretty_frames properties.""" frames = FrameSequence(lrange(1, 6), pad=4) full_name = os.path.join(self._test_root, self._test_name) fseq = FileSequence(name=full_name, frames=frames, ext="exr") frames_seq = list(frames) fseq_frames = list(fseq.frames) self.assertEqual(fseq.pretty_frames, str(frames)) self.assertEqual(frames_seq, fseq_frames)
[docs] def test_update(self): """FileSequence: Test the update method.""" full_name1 = os.path.join(self._test_root, "test") full_name3 = os.path.join(self._test_root, "manx") frames1 = [1, 2, 3] frames2 = [4, 6] input_seq1 = FileSequence( ext="py", frames=frames1, name=full_name1, pad=4) input_seq2 = FileSequence( ext="py", frames=frames2, name=full_name1, pad=4) input_seq3 = FileSequence( ext="py", frames=frames2, name=full_name3, pad=4) # Caching disk stats (because mocking os.stat is hard): for seq in (input_seq1, input_seq2): for file_name in seq: frame = seq.file_name_match(file_name, as_dict=True)["frame"] stat = mock_os_stat(file_name) seq.cache_stat(frame, stat) # Invalid base name ... with self.assertRaises(ValueError): input_seq1.update(input_seq3) # Valid base name, testing stat copies as well. raised = False try: input_seq1.update(input_seq2) except ValueError: raised = True blurb = "Unable to update with specified value: {!r}" self.assertFalse(raised, blurb.format(input_seq2))
[docs] def test_discard(self): """FileSequence: Test the discard method.""" full_name = os.path.join(self._test_root, self._test_name) frames = lrange(1, 6) input_seq = FileSequence( ext=self._test_ext, frames=frames, name=full_name) self.assertIn(frames[0], input_seq) input_seq.discard(frames[0]) self.assertNotIn(frames[0], input_seq)