Source code for tests.test_spritesheet_mask_generator

# -*- coding: utf-8 -*-
#
# New BSD license
#
# Copyright (c) DR0ID
# This file is part of spritesheetlib
# All rights reserved.
#
# 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 <organization> 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 DR0ID 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.

"""
TODO: module description


Versioning scheme based on: http://en.wikipedia.org/wiki/Versioning#Designating_development_stage

::

      +-- api change, probably incompatible with older versions
      |     +-- enhancements but no api change
      |     |
    major.minor[.build[.revision]]
                   |        |
                   |        +-|* x for x bugfixes
                   |
                   +-|* 0 for alpha (status)
                     |* 1 for beta (status)
                     |* 2 for release candidate
                     |* 3 for (public) release

.. versionchanged:: 0.0.0.0
    initial version

"""
from __future__ import print_function
import logging
import unittest
import sys
sys.path.insert(0, "../bin/")
import warnings
warnings.simplefilter('default')  # make warnings visible for developers

import spritesheet_mask_generator as mut  # module under test
from spritesheetlib import FileInfo, FileMode
from tests.test_spritesheetlib import LoggerMock, get_method_names, FileInfoMock, TestData, remove_file, JsonMock
import tests.datadriventestingdecorators as ddtd

__version__ = '1.0.3.0'

# for easy comparison as in sys.version_info but digits only
__version_info__ = tuple([int(d) for d in __version__.split('.')])

__author__ = "DR0ID"
__email__ = "dr0iddr0id [at] gmail [dot] com"
__copyright__ = "DR0ID @ 2015"
__credits__ = ["DR0ID"]  # list of contributors
__maintainer__ = "DR0ID"
__license__ = "New BSD license"



if mut.__version_info__ != __version_info__:
    raise Exception("version numbers do not match!")  # pragma: no cover


[docs]class SpritesheetLib10Mock(mut.SpritesheetLib10): """ This is a mock object for the SpritesheetLib10 class. :param logger_instance: The logger instance to use. """ def __init__(self, logger_instance): mut.SpritesheetLib10.__init__(self, logger_instance) self.logger = logger_instance self.method_calls = [] # [(method_name, (args)), ]
[docs] def create_grid(self, *args): # import inspect """ Mocked method, just stores the call with arguments for later checks. :param args: The passed in arguments. """ self.method_calls.append((self.create_grid.__name__, args)) # number_of_args = len(inspect.getargspec(mut.SpritesheetLib.create_grid).args) - 1 # remove 'self' # if number_of_args == len(args) or number_of_args - 1 == len(args): # return SpritesheetLib.create_grid(self, *args) return TestData.SDEF_GRID_2X2
[docs] def load_sdef_from_file(self, *args): """ Mocked method, just stores the call with arguments for later checks. :param args: The passed in arguments. """ self.method_calls.append((self.load_sdef_from_file.__name__, args)) return TestData.SDEF_GRID_2X2
[docs] def adjust_spacing(self, *args): """ Mocked method, just stores the call with arguments for later checks. :param args: The passed in arguments. """ self.method_calls.append((self.adjust_spacing.__name__, args))
[docs] def adjust_margin(self, *args): """ Mocked method, just stores the call with arguments for later checks. :param args: The passed in arguments. """ self.method_calls.append((self.adjust_margin.__name__, args))
[docs] def create_image(self, *args): """ Mocked method, just stores the call with arguments for later checks. :param args: The passed in arguments. """ self.method_calls.append((self.create_image.__name__, args))
[docs] def save_sprite_definition_to_disk(self, *args): """ Mocked method, just stores the call with arguments for later checks. :param args: The passed in arguments. """ self.method_calls.append((self.save_sprite_definition_to_disk.__name__, args))
[docs] def save_image_to_disk(self, *args): """ Mocked method, just stores the call with arguments for later checks. :param args: The passed in arguments. """ self.method_calls.append((self.save_image_to_disk.__name__, args))
[docs] def is_sprite_def_valid(self, *args): """ Mocked method, just stores the call with arguments for later checks. :param args: The passed in arguments. :return: Returns always True. """ self.method_calls.append((self.is_sprite_def_valid.__name__, args)) return True
[docs] def update_sprite_properties(self, *args): """ Updates the properties of the sprites. :param args: The passed in arguments. """ self.method_calls.append((self.update_sprite_properties.__name__, args))
@ddtd.use_data_driven_testing_decorators
[docs]class TestSpritesheetLib10Mock(unittest.TestCase): @ddtd.test_case_from_generator(get_method_names, SpritesheetLib10Mock(LoggerMock())) def test_method_call_is_logged(self, method_name): # arrange logger_mock = LoggerMock() sut = SpritesheetLib10Mock(logger_mock) arg = 1 # act getattr(sut, method_name)(arg) # verify self.assertEqual((method_name, (arg,)), sut.method_calls[0])
class _SpriteSheetMaskGeneratorCommandsMock(mut.SpriteSheetMaskGenerator): """ This is a mock object that only mocks the call to save_to_disk (see its doc string for details). """ def __init__(self, spritesheet_lib, logger, json_module=None): """ The _SpriteSheetMaskGeneratorCommandsMock. :param spritesheet_lib: The spritesheetlib instance to use. :param logger: The logger instance to use. :param json_module: The json module to use. Only used to mock json module. """ mut.SpriteSheetMaskGenerator.__init__(self, spritesheet_lib, logger, json_module) self.method_calls = [] def save_to_disk(self, *args): """ The save_to_disk mocked method. It will store the method call and if the number of arguments are equal, call the save_to_disk method of SpriteSheetMaskGenerator. :param args: The passed arguments """ import inspect self.method_calls.append((self.save_to_disk.__name__, args)) number_of_args = len(inspect.getargspec(mut.SpriteSheetMaskGenerator.save_to_disk).args) - 1 # remove 'self' if number_of_args == len(args) or number_of_args - 1 == len(args): mut.SpriteSheetMaskGenerator.save_to_disk(self, *args) @ddtd.use_data_driven_testing_decorators
[docs]class SSMGCommandsMockTests(unittest.TestCase): @ddtd.test_case_from_generator(get_method_names, _SpriteSheetMaskGeneratorCommandsMock(SpritesheetLib10Mock(LoggerMock()), LoggerMock())) def test_method_call_is_logged(self, method_name): # arrange logger_mock = LoggerMock() sut = _SpriteSheetMaskGeneratorCommandsMock(SpritesheetLib10Mock(logger_mock), logger_mock) arg = 1 # act getattr(sut, method_name)(arg) # verify self.assertEqual((method_name, (arg,)), sut.method_calls[0]) # class SpritesheetMaskGeneratorMock(mut.SpriteSheetMaskGenerator): # """ # The SpritesheetMaskGeneratorMock. # :param lib: # :param logger: # """ # # def __init__(self, lib, logger): # mut.SpriteSheetMaskGenerator.__init__(self, lib, logger) # self.recorded_method_calls = [] # # # def save_image_to_disk(self, sprite_sheet_mask, file_info): # # self.recorded_method_calls.append((self.save_image_to_disk.__name__, (sprite_sheet_mask, file_info))) # # # def save_sprite_definition_to_disk(self, sprite_definition, file_info): # # self.recorded_method_calls.append( # # (self.save_sprite_definition_to_disk.__name__, (sprite_definition, file_info)))
@ddtd.use_data_driven_testing_decorators
[docs]class ArgumentParsingTests(unittest.TestCase):
[docs] def setUp(self): self.logger_mock = LoggerMock()
[docs] def test_main(self): # arrange args = "-h".split() # act / verify self.assertRaises(SystemExit, mut.main, args)
@ddtd.test_case(list("create_grid 2 2 out.png.sdef".split()), (SpritesheetLib10Mock.create_grid.__name__, (2, 2, 32, 32, FileInfo("out.png.sdef")))) @ddtd.test_case(list("create_grid 2 2 --tile_width=10 --tile_height=10 out.png.sdef".split()), (SpritesheetLib10Mock.create_grid.__name__, (2, 2, 10, 10, FileInfo("out.png.sdef")))) def test_grid_command_arguments(self, args, expected): # arrange lib_mock = SpritesheetLib10Mock(self.logger_mock) sut = _SpriteSheetMaskGeneratorCommandsMock(lib_mock, self.logger_mock) # act sut.main(args) # verify self.assertEqual(expected, lib_mock.method_calls[0])
[docs] def test_create_from_file_command(self): # arrange lib_mock = SpritesheetLib10Mock(self.logger_mock) sut = _SpriteSheetMaskGeneratorCommandsMock(lib_mock, self.logger_mock) # act sut.main("create_from_file in.png.sdef out.png.sdef".split()) # verify self.assertEqual( (lib_mock.load_sdef_from_file.__name__, (FileInfo("in.png.sdef"),)), lib_mock.method_calls[0])
[docs] def test_v_argument_set_log_level(self): # arrange self.logger_mock.level = logging.INFO sut = _SpriteSheetMaskGeneratorCommandsMock(SpritesheetLib10Mock(self.logger_mock), self.logger_mock) # act sut.main("create_grid 2 2 out.png.sdef -vvv".split()) # verify self.assertEqual(logging.DEBUG, self.logger_mock.level)
[docs] def test_v_count_argument_set_log_level_debug(self): # arrange self.logger_mock.level = logging.INFO sut = _SpriteSheetMaskGeneratorCommandsMock(SpritesheetLib10Mock(self.logger_mock), self.logger_mock) # act sut.main("create_grid 2 2 out.png.sdef -vvvvvv".split()) # verify self.assertEqual(logging.DEBUG, self.logger_mock.level)
[docs] def test_verbose_argument_set_log_level(self): # arrange self.logger_mock.level = logging.INFO sut = _SpriteSheetMaskGeneratorCommandsMock(SpritesheetLib10Mock(self.logger_mock), self.logger_mock) # act sut.main("create_grid 2 2 out.png.sdef --verbose".split()) # verify self.assertEqual(logging.WARN, self.logger_mock.level)
[docs] def test_q_argument_set_log_level(self): # arrange self.logger_mock.level = logging.DEBUG sut = _SpriteSheetMaskGeneratorCommandsMock(SpritesheetLib10Mock(self.logger_mock), self.logger_mock) # act sut.main("create_grid 2 2 out.png.sdef -q".split()) # verify self.assertEqual(logging.WARN, self.logger_mock.level)
[docs] def test_no_log_level_argument(self): # arrange self.logger_mock.level = logging.INFO sut = _SpriteSheetMaskGeneratorCommandsMock(SpritesheetLib10Mock(self.logger_mock), self.logger_mock) # act sut.main("create_grid 2 2 out.png.sdef".split()) # verify self.assertEqual(logging.ERROR, self.logger_mock.level)
[docs] def test_log_level_arguments_are_exclusive(self): # arrange sut = mut.SpriteSheetMaskGenerator(SpritesheetLib10Mock(self.logger_mock), self.logger_mock) # act / verify self.assertRaises(SystemExit, sut.main, "create_grid 2 2 out.png.sdef -v -q".split())
[docs] def test_dry_run_and_force_are_exclusive(self): # arrange sut = mut.SpriteSheetMaskGenerator(SpritesheetLib10Mock(self.logger_mock), self.logger_mock) # act / verify self.assertRaises(SystemExit, sut.main, "create_grid 2 2 out.png.sdef -f --dry-run".split())
[docs] def test_wrong_command(self): # arrange class _ArgParseWrong(mut.SpriteSheetMaskGenerator): def __init__(self, logger): mut.SpriteSheetMaskGenerator.__init__(self, SpritesheetLib10Mock(logger), logger) def _parse_arguments(self, commandline_args=None): class _ArgParseFaultyResult(object): def __init__(self): self.command = "bla" self.filename = "out.png.sdef" self.properties = None return _ArgParseFaultyResult() sut = _ArgParseWrong(self.logger_mock) # act / verify self.assertRaises(SystemExit, sut.main, "")
@ddtd.test_case((SpritesheetLib10Mock.adjust_spacing.__name__, (TestData.SDEF_GRID_2X2, None)), "create_grid 2 2 out.png.sdef".split()) @ddtd.test_case((SpritesheetLib10Mock.adjust_spacing.__name__, (TestData.SDEF_GRID_2X2, 0)), "create_grid 2 2 out.png.sdef -s=0".split()) @ddtd.test_case((SpritesheetLib10Mock.adjust_spacing.__name__, (TestData.SDEF_GRID_2X2, 3)), "create_grid 2 2 out.png.sdef -s=3".split()) @ddtd.test_case((SpritesheetLib10Mock.adjust_spacing.__name__, (TestData.SDEF_GRID_2X2, 3)), "create_grid 2 2 out.png.sdef -s=3 -m=3".split()) def test_create_sprite_definition_is_called_after_grid_command(self, expected, args): # arrange lib_mock = SpritesheetLib10Mock(self.logger_mock) sut = _SpriteSheetMaskGeneratorCommandsMock(lib_mock, self.logger_mock) # act sut.main(args) # verify self.maxDiff = None self.assertEqual(expected, lib_mock.method_calls[3])
[docs] def test_save_sprite_definition_to_disk_arguments(self): # arrange lib_mock = SpritesheetLib10Mock(self.logger_mock) sut = _SpriteSheetMaskGeneratorCommandsMock(lib_mock, self.logger_mock) # act sut.main("create_grid 2 2 out.png.sdef -i".split()) # verify self.maxDiff = None self.assertEqual( (SpritesheetLib10Mock.save_sprite_definition_to_disk.__name__, (None, FileInfo("out.png.sdef"))), lib_mock.method_calls[7])
[docs] def test_save_image_to_disk_arguments(self): # arrange lib_mock = SpritesheetLib10Mock(self.logger_mock) sut = _SpriteSheetMaskGeneratorCommandsMock(lib_mock, self.logger_mock) # act sut.main("-i create_grid 2 2 out.png.sdef".split()) # verify self.maxDiff = None self.assertEqual( (SpritesheetLib10Mock.save_image_to_disk.__name__, (None, FileInfo("out.png"))), lib_mock.method_calls[8])
[docs] def test_save_to_disk_arguments_dry_run_save_image_to_disk(self): # arrange sut = _SpriteSheetMaskGeneratorCommandsMock(SpritesheetLib10Mock(self.logger_mock), self.logger_mock) # act sut.main("create_grid 2 2 out.png.sdef --dry-run -i".split()) # verify self.maxDiff = None self.assertEqual((_SpriteSheetMaskGeneratorCommandsMock.save_to_disk.__name__, (FileInfo("out.png"), None, FileInfo("out.png.sdef"), None, True, False, True)), sut.method_calls[0])
[docs] def test_save_to_disk_arguments_dry_run_no_save_image(self): # arrange sut = _SpriteSheetMaskGeneratorCommandsMock(SpritesheetLib10Mock(self.logger_mock), self.logger_mock) # act sut.main("create_grid 2 2 out.png.sdef --dry-run".split()) # verify self.maxDiff = None self.assertEqual((_SpriteSheetMaskGeneratorCommandsMock.save_to_disk.__name__, (FileInfo("out.png"), None, FileInfo("out.png.sdef"), None, True, False, False)), sut.method_calls[0])
@ddtd.test_case("create_grid 2 2 out.png.sdef -s=-1".split()) @ddtd.test_case("create_grid 2 2 out.png.sdef -s=-3 -m=3".split()) @ddtd.test_case("create_grid 2 2 out.png.sdef -s=3 -m=-1".split()) @ddtd.test_case("create_grid 2 2 out.png.sdef -s=3 -m=-3".split()) def test_create_sprite_definition_is_called_with_invalid_values_after_grid_command(self, args): # arrange sut = mut.SpriteSheetMaskGenerator(mut.SpritesheetLib10(self.logger_mock), self.logger_mock) # act / verify self.assertRaises(ValueError, sut.main, args)
[docs] def test_create_image_is_called_after_grid_command(self): # arrange lib_mock = SpritesheetLib10Mock(self.logger_mock) sut = _SpriteSheetMaskGeneratorCommandsMock(lib_mock, self.logger_mock) # act sut.main("create_grid 2 2 out.png.sdef -i".split()) # verify self.assertEqual((lib_mock.create_image.__name__, (None, )), lib_mock.method_calls[6])
[docs] def test_create_sprite_definition_is_called_after_from_file_command(self): # arrange lib_mock = SpritesheetLib10Mock(self.logger_mock) sut = _SpriteSheetMaskGeneratorCommandsMock(lib_mock, self.logger_mock) # act sut.main("create_from_file in.png.sdef out.png.sdef".split()) # verify self.assertEqual(lib_mock.adjust_spacing.__name__, lib_mock.method_calls[3][0])
[docs] def test_create_image_is_called_after_from_file_command(self): # arrange lib_mock = SpritesheetLib10Mock(self.logger_mock) sut = _SpriteSheetMaskGeneratorCommandsMock(lib_mock, self.logger_mock) # act sut.main("create_from_file in.png.sdef out.png.sdef -i".split()) # verify self.assertEqual((lib_mock.create_image.__name__, (None, )), lib_mock.method_calls[6])
[docs] def test_method_sequence_save_image_to_disk(self): # arrange lib_mock = SpritesheetLib10Mock(self.logger_mock) sut = _SpriteSheetMaskGeneratorCommandsMock(lib_mock, self.logger_mock) # act sut.main("create_grid 2 2 out.png.sdef -i".split()) # verify # print("method calls({0}: {1}".format(len(sut.method_calls), sut.method_calls)) self.assertEqual(sut.save_to_disk.__name__, sut.method_calls[0][0]) self.assertEqual(lib_mock.create_grid.__name__, lib_mock.method_calls[0][0]) self.assertEqual(lib_mock.update_sprite_properties.__name__, lib_mock.method_calls[1][0]) self.assertEqual(lib_mock.is_sprite_def_valid.__name__, lib_mock.method_calls[2][0]) self.assertEqual(lib_mock.adjust_spacing.__name__, lib_mock.method_calls[3][0]) self.assertEqual(lib_mock.adjust_margin.__name__, lib_mock.method_calls[4][0]) self.assertEqual(lib_mock.is_sprite_def_valid.__name__, lib_mock.method_calls[5][0]) self.assertEqual(lib_mock.create_image.__name__, lib_mock.method_calls[6][0]) self.assertEqual(lib_mock.save_sprite_definition_to_disk.__name__, lib_mock.method_calls[7][0], "method calls({0}: {1}".format(len(lib_mock.method_calls), lib_mock.method_calls)) self.assertEqual(lib_mock.save_image_to_disk.__name__, lib_mock.method_calls[8][0])
[docs] def test_method_sequence_no_image(self): # arrange lib_mock = SpritesheetLib10Mock(self.logger_mock) sut = _SpriteSheetMaskGeneratorCommandsMock(lib_mock, self.logger_mock) # act sut.main("create_grid 2 2 out.png.sdef".split()) # verify # print("method calls({0}: {1}".format(len(sut.method_calls), sut.method_calls)) self.assertEqual(sut.save_to_disk.__name__, sut.method_calls[0][0]) self.assertEqual(lib_mock.create_grid.__name__, lib_mock.method_calls[0][0]) self.assertEqual(lib_mock.update_sprite_properties.__name__, lib_mock.method_calls[1][0]) self.assertEqual(lib_mock.is_sprite_def_valid.__name__, lib_mock.method_calls[2][0]) self.assertEqual(lib_mock.adjust_spacing.__name__, lib_mock.method_calls[3][0]) self.assertEqual(lib_mock.adjust_margin.__name__, lib_mock.method_calls[4][0]) self.assertEqual(lib_mock.is_sprite_def_valid.__name__, lib_mock.method_calls[5][0]) self.assertEqual(lib_mock.save_sprite_definition_to_disk.__name__, lib_mock.method_calls[6][0], "method calls({0}: {1}".format(len(lib_mock.method_calls), lib_mock.method_calls))
[docs] def test_version(self): # act / verify self.assertRaises(SystemExit, mut.main, "--version".split())
@ddtd.use_data_driven_testing_decorators
[docs]class TestPropertyParsing(unittest.TestCase):
[docs] def setUp(self): self.logger_mock = LoggerMock()
[docs] def test_p_arg_is_accepted(self): # arrange lib_mock = SpritesheetLib10Mock(self.logger_mock) sut = _SpriteSheetMaskGeneratorCommandsMock(lib_mock, self.logger_mock) # act sut.main("-p {} create_grid 2 2 out.png.sdef".split()) # verify self.assertEqual(SpritesheetLib10Mock.update_sprite_properties.__name__, lib_mock.method_calls[1][0]) self.assertEqual({}, lib_mock.method_calls[1][1][-1])
[docs] def test_properties_arg_is_accepted(self): # arrange lib_mock = SpritesheetLib10Mock(self.logger_mock) sut = _SpriteSheetMaskGeneratorCommandsMock(lib_mock, self.logger_mock) # act sut.main("--properties {} create_grid 2 2 out.png.sdef".split()) # verify self.assertEqual(SpritesheetLib10Mock.update_sprite_properties.__name__, lib_mock.method_calls[1][0]) self.assertEqual({}, lib_mock.method_calls[1][1][-1])
[docs] def test_no_properties(self): # arrange lib_mock = SpritesheetLib10Mock(self.logger_mock) sut = _SpriteSheetMaskGeneratorCommandsMock(lib_mock, self.logger_mock) # act sut.main("create_grid 2 2 out.png.sdef".split()) # verify self.assertEqual(SpritesheetLib10Mock.update_sprite_properties.__name__, lib_mock.method_calls[1][0]) self.assertEqual(None, lib_mock.method_calls[1][1][-1])
[docs] def test_properties_arg_is_empty_dict(self): # arrange lib_mock = SpritesheetLib10Mock(self.logger_mock) sut = _SpriteSheetMaskGeneratorCommandsMock(lib_mock, self.logger_mock) # act sut.main("--properties {} create_grid 2 2 out.png.sdef".split()) # verify self.assertEqual(SpritesheetLib10Mock.update_sprite_properties.__name__, lib_mock.method_calls[1][0]) self.assertDictEqual({}, lib_mock.method_calls[1][1][-1])
[docs] def test_properties_arg_passes_keys(self): # arrange lib_mock = SpritesheetLib10Mock(self.logger_mock) sut = _SpriteSheetMaskGeneratorCommandsMock(lib_mock, self.logger_mock) expected = {'resolution': 'keep'} # act sut.main("--properties {'resolution':'keep'} create_grid 2 2 out.png.sdef".split()) # verify self.assertEqual(SpritesheetLib10Mock.update_sprite_properties.__name__, lib_mock.method_calls[1][0]) self.assertDictEqual(expected, lib_mock.method_calls[1][1][-1])
[docs] def test_properties_same_key_raises(self): # arrange lib_mock = SpritesheetLib10Mock(self.logger_mock) sut = _SpriteSheetMaskGeneratorCommandsMock(lib_mock, self.logger_mock) # act / verify args = "--properties {'0:':{'keep':true},'2:':{'other':false,'keep':true}} create_grid 2 2 out.png.sdef".split() self.assertRaises(mut.DictParseError, sut.main, args)
[docs] def test_properties_same_key_single_raises(self): # arrange lib_mock = SpritesheetLib10Mock(self.logger_mock) sut = _SpriteSheetMaskGeneratorCommandsMock(lib_mock, self.logger_mock) # act / verify args = "--properties {'0:':{'keep':true,'other':false},'1':{'other':false}} create_grid 2 2 out.png.sdef".split() self.assertRaises(mut.DictParseError, sut.main, args)
[docs] def test_properties_merge_same_duplicate_keys_raises(self): # arrange lib_mock = SpritesheetLib10Mock(self.logger_mock) sut = _SpriteSheetMaskGeneratorCommandsMock(lib_mock, self.logger_mock) # act / verify # 'keep' is the error args = "--properties {'bla':{'keep':true},'bla':{'other':false,'keep':false}} create_grid 2 2 out.png.sdef".split() self.assertRaises(mut.DictParseError, sut.main, args)
[docs] def test_properties_same_duplicate_keys_raises(self): # arrange lib_mock = SpritesheetLib10Mock(self.logger_mock) sut = _SpriteSheetMaskGeneratorCommandsMock(lib_mock, self.logger_mock) # act / verify # 'keep' is the error args = "--properties {'bla':{'keep':true,'keep':false}} create_grid 2 2 out.png.sdef".split() self.assertRaises(mut.DictParseError, sut.main, args)
[docs] def test_properties_same_empty_key_raises(self): # arrange lib_mock = SpritesheetLib10Mock(self.logger_mock) sut = _SpriteSheetMaskGeneratorCommandsMock(lib_mock, self.logger_mock) # act / verify args = "--properties {'':'keep','bla':'other'} create_grid 2 2 out.png.sdef".split() self.assertRaises(mut.DictParseError, sut.main, args)
[docs] def test_properties_same_malformed_slice_key_raises(self): # arrange lib_mock = SpritesheetLib10Mock(self.logger_mock) sut = _SpriteSheetMaskGeneratorCommandsMock(lib_mock, self.logger_mock) # act / verify args = "--properties {'0:bla':'keep'} create_grid 2 2 out.png.sdef".split() self.assertRaises(mut.DictParseError, sut.main, args)
[docs] def test_properties_negative_step_key_raises(self): # arrange lib_mock = SpritesheetLib10Mock(self.logger_mock) sut = _SpriteSheetMaskGeneratorCommandsMock(lib_mock, self.logger_mock) # act / verify args = "--properties {'10:0:-2':'keep'} create_grid 2 2 out.png.sdef".split() self.assertRaises(mut.DictParseError, sut.main, args)
[docs] def test_properties_malformed_key_raises(self): # arrange lib_mock = SpritesheetLib10Mock(self.logger_mock) sut = _SpriteSheetMaskGeneratorCommandsMock(lib_mock, self.logger_mock) # act / verify args = "--properties {'10:0:-2:3':'keep'} create_grid 2 2 out.png.sdef".split() self.assertRaises(mut.DictParseError, sut.main, args)
[docs] def test_load_dict_from_file_mocked(self): # arrange lib_mock = SpritesheetLib10Mock(self.logger_mock) # following would be returned by json.load(...) json_module = JsonMock(loads_value={'0': {'facing': 'up'}}) sut = _SpriteSheetMaskGeneratorCommandsMock(lib_mock, self.logger_mock, json_module) expected = {0: {'facing': 'up'}} # act / verify sut.main("--properties not-existent.json create_from_file in.png.sdef out.png.sdef".split()) # verify self.assertEqual(SpritesheetLib10Mock.update_sprite_properties.__name__, lib_mock.method_calls[1][0]) self.assertDictEqual(expected, lib_mock.method_calls[1][1][-1])
[docs] def test_load_dict_from_file(self): # arrange lib_mock = SpritesheetLib10Mock(self.logger_mock) # following would be returned by json.load(...) # json_module = JsonMock(loads_value={'0': {'facing': 'up'}}) expected = {0: {'facing': 'up'}} import json dict_file_name = "prop-dict.json" try: json.dump(expected, FileInfo(dict_file_name).open(FileMode.WriteText)) sut = _SpriteSheetMaskGeneratorCommandsMock(lib_mock, self.logger_mock) # act / verify sut.main("--properties {0} create_from_file in.png.sdef out.png.sdef".format(dict_file_name).split()) # verify self.assertEqual(SpritesheetLib10Mock.update_sprite_properties.__name__, lib_mock.method_calls[1][0]) self.assertDictEqual(expected, lib_mock.method_calls[1][1][-1]) finally: FileInfo(dict_file_name).delete()
_up_str = 'up' _down_str = 'down' @ddtd.test_case("{'0':{'facing':'up'}}", {0: {SpritesheetLib10Mock.PROPERTIES.FACING: _up_str}}, test_name='single_sprite') @ddtd.test_case("{'0:':{'facing':'up'}}", { 0: {SpritesheetLib10Mock.PROPERTIES.FACING: _up_str}, 1: {SpritesheetLib10Mock.PROPERTIES.FACING: _up_str}, 2: {SpritesheetLib10Mock.PROPERTIES.FACING: _up_str}, 3: {SpritesheetLib10Mock.PROPERTIES.FACING: _up_str}, }, test_name='all_from_zero') @ddtd.test_case("{':':{'facing':'up'}}", { 0: {SpritesheetLib10Mock.PROPERTIES.FACING: _up_str}, 1: {SpritesheetLib10Mock.PROPERTIES.FACING: _up_str}, 2: {SpritesheetLib10Mock.PROPERTIES.FACING: _up_str}, 3: {SpritesheetLib10Mock.PROPERTIES.FACING: _up_str}, }, test_name='all') @ddtd.test_case("{'::':{'facing':'up'}}", { 0: {SpritesheetLib10Mock.PROPERTIES.FACING: _up_str}, 1: {SpritesheetLib10Mock.PROPERTIES.FACING: _up_str}, 2: {SpritesheetLib10Mock.PROPERTIES.FACING: _up_str}, 3: {SpritesheetLib10Mock.PROPERTIES.FACING: _up_str}, }, test_name='all_double') @ddtd.test_case("{'::2':{'facing':'up'}}", { 0: {SpritesheetLib10Mock.PROPERTIES.FACING: _up_str}, 2: {SpritesheetLib10Mock.PROPERTIES.FACING: _up_str}, }, test_name='even') @ddtd.test_case("{'1::2':{'facing':'up'}}", { 1: {SpritesheetLib10Mock.PROPERTIES.FACING: _up_str}, 3: {SpritesheetLib10Mock.PROPERTIES.FACING: _up_str}, }, test_name='odd') @ddtd.test_case("{'1:3':{'facing':'up'}}", { 1: {SpritesheetLib10Mock.PROPERTIES.FACING: _up_str}, 2: {SpritesheetLib10Mock.PROPERTIES.FACING: _up_str}, }, test_name='slice') @ddtd.test_case("{'1:3:2':{'facing':'up'}}", { 1: {SpritesheetLib10Mock.PROPERTIES.FACING: _up_str}, }, test_name='slice_stepped') @ddtd.test_case("{'0::2':{'facing':'up'},'1::2':{'facing':'down'}}", { 0: {SpritesheetLib10Mock.PROPERTIES.FACING: _up_str}, 1: {SpritesheetLib10Mock.PROPERTIES.FACING: _down_str}, 2: {SpritesheetLib10Mock.PROPERTIES.FACING: _up_str}, 3: {SpritesheetLib10Mock.PROPERTIES.FACING: _down_str}, }, test_name='slice_column') @ddtd.test_case("{'-1':{'facing':'up'}}", { 3: {SpritesheetLib10Mock.PROPERTIES.FACING: _up_str}, }, test_name='last') @ddtd.test_case("{'1':{'facing':'up'},'resolution':'bla'}", { 1: {SpritesheetLib10Mock.PROPERTIES.FACING: _up_str}, 'resolution': 'bla', }, test_name='additional_non_slice_key') @ddtd.test_case("{'10:12':{'facing':'up'}}", { 10: {SpritesheetLib10Mock.PROPERTIES.FACING: _up_str}, 11: {SpritesheetLib10Mock.PROPERTIES.FACING: _up_str}, }, test_name='out_of_range') @ddtd.test_case("{'0':{'facing':'up'},'0':{'other':'x'}}", { 0: {SpritesheetLib10Mock.PROPERTIES.FACING: _up_str, 'other': 'x'}, }, test_name='merge') @ddtd.test_case("{'0:2':{'facing':'up'},'0':{'other':'x'}}", { 0: {SpritesheetLib10Mock.PROPERTIES.FACING: _up_str, 'other': 'x'}, 1: {SpritesheetLib10Mock.PROPERTIES.FACING: _up_str, }, }, test_name='merge_range_and_single') @ddtd.test_case("{'0:2':{'facing':'up'},'0:3':{'other':'x'}}", { 0: {SpritesheetLib10Mock.PROPERTIES.FACING: _up_str, 'other': 'x'}, 1: {SpritesheetLib10Mock.PROPERTIES.FACING: _up_str, 'other': 'x'}, 2: {'other': 'x'}, }, test_name='merge_range') def test_properties_gid_keys(self, properties_string, expected): # arrange lib_mock = SpritesheetLib10Mock(self.logger_mock) sut = _SpriteSheetMaskGeneratorCommandsMock(lib_mock, self.logger_mock) # act sut.main(("--properties " + properties_string + " create_grid 2 2 out.png.sdef").split()) # verify self.assertEqual(SpritesheetLib10Mock.update_sprite_properties.__name__, lib_mock.method_calls[1][0]) self.assertDictEqual(expected, lib_mock.method_calls[1][1][-1])
@ddtd.use_data_driven_testing_decorators
[docs]class SaveToFileTests(unittest.TestCase):
[docs] def setUp(self): self.logger_mock = LoggerMock() self.file_name_sdef = "temp_out.png.sdef" self.file_name_image = self.file_name_sdef remove_file(FileInfo(self.file_name_sdef)) remove_file(FileInfo(self.file_name_image))
[docs] def tearDown(self): remove_file(FileInfo(self.file_name_sdef)) remove_file(FileInfo(self.file_name_image))
[docs] def test_dry_run_does_not_call_save_methods(self): # arrange lib_mock = SpritesheetLib10Mock(self.logger_mock) sut = mut.SpriteSheetMaskGenerator(lib_mock, self.logger_mock) # act cmd_line = "create_grid 2 2 " + self.file_name_sdef + " --dry-run" sut.main(cmd_line.split()) # verify called_method_names = [x[0] for x in lib_mock.method_calls] self.assertFalse(lib_mock.save_image_to_disk.__name__ in called_method_names) self.assertFalse(lib_mock.save_sprite_definition_to_disk.__name__ in called_method_names)
[docs] def test_dry_run_logs_messages(self): # arrange sut = mut.SpriteSheetMaskGenerator(mut.SpritesheetLib10(self.logger_mock), self.logger_mock) # act cmd_line = "create_grid 2 2 " + self.file_name_sdef + " --dry-run" sut.main(cmd_line.split()) # verify self.assertTrue(5 < len(self.logger_mock.messages)) self.assertEqual(logging.WARN, self.logger_mock.messages[-1][0])
[docs] def test_dry_run_not_set_logs_no_messages(self): # TODO: what does this test test exactly??? # arrange sut = mut.SpriteSheetMaskGenerator(SpritesheetLib10Mock(self.logger_mock), self.logger_mock) # act cmd_line = "create_grid 2 2 " + self.file_name_sdef sut.main(cmd_line.split()) # verify self.assertFalse(7 < len(self.logger_mock.messages), "should not be bigger than 7, but was {0}".format(str(len(self.logger_mock.messages))))
@ddtd.test_case(True, True, False, True, True, logging.INFO, 1) @ddtd.test_case(True, False, False, True, True, logging.INFO, 1) @ddtd.test_case(False, True, False, True, True, logging.INFO, 1) @ddtd.test_case(False, False, False, True, True, logging.DEBUG, 1) @ddtd.test_case(True, True, False, False, True, logging.ERROR, 1) @ddtd.test_case(True, False, False, False, True, logging.ERROR, 1) @ddtd.test_case(False, True, False, False, True, logging.ERROR, 1) @ddtd.test_case(False, False, False, False, True, logging.DEBUG, 1) @ddtd.test_case(True, True, False, True, False, logging.INFO, 2) @ddtd.test_case(True, False, False, True, False, logging.INFO, 2) @ddtd.test_case(False, True, False, True, False, logging.INFO, 2) @ddtd.test_case(False, False, False, True, False, logging.DEBUG, 2) @ddtd.test_case(True, True, False, False, False, logging.ERROR, 1) @ddtd.test_case(True, False, False, False, False, logging.ERROR, 1) @ddtd.test_case(False, True, False, False, False, logging.ERROR, 1) @ddtd.test_case(False, False, False, False, False, logging.DEBUG, 2) # dry run @ddtd.test_case(False, False, True, False, True, logging.WARN, 1) # dry run @ddtd.test_case(False, False, True, False, False, logging.WARN, 1) # dry run @ddtd.test_case(False, False, True, True, True, logging.WARN, 1) # dry run @ddtd.test_case(False, False, True, True, False, logging.WARN, 1) # dry run @ddtd.test_case(False, True, True, False, True, logging.WARN, 1) # dry run @ddtd.test_case(False, True, True, False, False, logging.WARN, 1) # dry run @ddtd.test_case(False, True, True, True, True, logging.WARN, 1) # dry run @ddtd.test_case(False, True, True, True, False, logging.WARN, 1) # dry run @ddtd.test_case(True, False, True, False, True, logging.WARN, 1) # dry run @ddtd.test_case(True, False, True, False, False, logging.WARN, 1) # dry run @ddtd.test_case(True, False, True, True, True, logging.WARN, 1) # dry run @ddtd.test_case(True, False, True, True, False, logging.WARN, 1) # dry run @ddtd.test_case(True, True, True, False, True, logging.WARN, 1) # dry run @ddtd.test_case(True, True, True, False, False, logging.WARN, 1) # dry run @ddtd.test_case(True, True, True, True, True, logging.WARN, 1) # dry run @ddtd.test_case(True, True, True, True, False, logging.WARN, 1) # dry run def test_log_messages_written_when_saving_depending_on_vars(self, img_exists, sdef_exists, dry_run, force, save_image, expected, msg_count): # arrange sut = _SpriteSheetMaskGeneratorCommandsMock(SpritesheetLib10Mock(self.logger_mock), self.logger_mock) img = object() img_fi = FileInfoMock(self.file_name_sdef, img_exists) sdef = {} sdef_fi = FileInfoMock(self.file_name_image, sdef_exists) # act sut.save_to_disk(img_fi, img, sdef_fi, sdef, dry_run, force, save_image) # verify self.assertEqual(msg_count, len(self.logger_mock.messages), "should be {0}, but is {1}".format(msg_count, len(self.logger_mock.messages))) if self.logger_mock.messages: self.assertEqual(expected, self.logger_mock.messages[0][0])
[docs] def test_force_argument_if_sdef_file_exists(self): # arrange lib_mock = SpritesheetLib10Mock(self.logger_mock) sut = mut.SpriteSheetMaskGenerator(lib_mock, self.logger_mock) image_fi_exists = FileInfoMock(self.file_name_sdef, True) img = object() sdef_fi_exists = FileInfoMock(self.file_name_image, True) sdef = object() # act sut.save_to_disk(image_fi_exists, img, sdef_fi_exists, sdef, False, True, True) # verify self.assertEqual(2, len(lib_mock.method_calls))
[docs] def test_no_file_is_overridden_if_exists(self): # arrange lib_mock = SpritesheetLib10Mock(self.logger_mock) sut = mut.SpriteSheetMaskGenerator(lib_mock, self.logger_mock) image_fi_exists = FileInfoMock(self.file_name_sdef, True) img = object() sdef_fi_exists = FileInfoMock(self.file_name_image, True) sdef = object() # act sut.save_to_disk(image_fi_exists, img, sdef_fi_exists, sdef, False, False, False) # verify called_method_names = [x[0] for x in lib_mock.method_calls] self.assertFalse(lib_mock.save_image_to_disk.__name__ in called_method_names) self.assertFalse(lib_mock.save_sprite_definition_to_disk.__name__ in called_method_names)
[docs] def test_no_file_is_overridden_if_dry_run_force_false(self): # arrange lib_mock = SpritesheetLib10Mock(self.logger_mock) sut = mut.SpriteSheetMaskGenerator(lib_mock, self.logger_mock) image_fi_exists = FileInfoMock(self.file_name_sdef, True) img = object() sdef_fi_exists = FileInfoMock(self.file_name_image, True) sdef = object() # act sut.save_to_disk(image_fi_exists, img, sdef_fi_exists, sdef, True, False, False) # verify called_method_names = [x[0] for x in lib_mock.method_calls] self.assertFalse(lib_mock.save_image_to_disk.__name__ in called_method_names) self.assertFalse(lib_mock.save_sprite_definition_to_disk.__name__ in called_method_names)
[docs] def test_no_file_is_overridden_if_dry_run_force_true(self): # arrange lib_mock = SpritesheetLib10Mock(self.logger_mock) sut = mut.SpriteSheetMaskGenerator(lib_mock, self.logger_mock) image_fi_exists = FileInfoMock(self.file_name_sdef, True) img = object() sdef_fi_exists = FileInfoMock(self.file_name_image, True) sdef = object() # act sut.save_to_disk(image_fi_exists, img, sdef_fi_exists, sdef, True, True, False) # verify called_method_names = [x[0] for x in lib_mock.method_calls] self.assertFalse(lib_mock.save_image_to_disk.__name__ in called_method_names) self.assertFalse(lib_mock.save_sprite_definition_to_disk.__name__ in called_method_names)
[docs] def test_force_argument_if_sdef_file_exists_no_image(self): # arrange lib_mock = SpritesheetLib10Mock(self.logger_mock) sut = mut.SpriteSheetMaskGenerator(lib_mock, self.logger_mock) image_fi_exists = FileInfoMock(self.file_name_sdef, True) img = object() sdef_fi_exists = FileInfoMock(self.file_name_image, True) sdef = object() # act sut.save_to_disk(image_fi_exists, img, sdef_fi_exists, sdef, False, True, False) # verify self.assertEqual(1, len(lib_mock.method_calls))
[docs] def test_no_file_is_overridden_if_exists_save_image(self): # arrange lib_mock = SpritesheetLib10Mock(self.logger_mock) sut = mut.SpriteSheetMaskGenerator(lib_mock, self.logger_mock) image_fi_exists = FileInfoMock(self.file_name_sdef, True) img = object() sdef_fi_exists = FileInfoMock(self.file_name_image, True) sdef = object() # act sut.save_to_disk(image_fi_exists, img, sdef_fi_exists, sdef, False, False, True) # verify called_method_names = [x[0] for x in lib_mock.method_calls] self.assertFalse(lib_mock.save_image_to_disk.__name__ in called_method_names) self.assertFalse(lib_mock.save_sprite_definition_to_disk.__name__ in called_method_names)
[docs] def test_no_file_is_overridden_if_dry_run_force_false_omit_true(self): # arrange lib_mock = SpritesheetLib10Mock(self.logger_mock) sut = mut.SpriteSheetMaskGenerator(lib_mock, self.logger_mock) image_fi_exists = FileInfoMock(self.file_name_sdef, True) img = object() sdef_fi_exists = FileInfoMock(self.file_name_image, True) sdef = object() # act sut.save_to_disk(image_fi_exists, img, sdef_fi_exists, sdef, True, False, True) # verify called_method_names = [x[0] for x in lib_mock.method_calls] self.assertFalse(lib_mock.save_image_to_disk.__name__ in called_method_names) self.assertFalse(lib_mock.save_sprite_definition_to_disk.__name__ in called_method_names)
[docs] def test_no_file_is_overridden_if_dry_run_force_true_omit_true(self): # arrange lib_mock = SpritesheetLib10Mock(self.logger_mock) sut = mut.SpriteSheetMaskGenerator(lib_mock, self.logger_mock) image_fi_exists = FileInfoMock(self.file_name_sdef, True) img = object() sdef_fi_exists = FileInfoMock(self.file_name_image, True) sdef = object() # act sut.save_to_disk(image_fi_exists, img, sdef_fi_exists, sdef, True, True, True) # verify called_method_names = [x[0] for x in lib_mock.method_calls] self.assertFalse(lib_mock.save_image_to_disk.__name__ in called_method_names) self.assertFalse(lib_mock.save_sprite_definition_to_disk.__name__ in called_method_names)
@ddtd.use_data_driven_testing_decorators
[docs]class SpriteDefinitionValidationTests(unittest.TestCase):
[docs] def setUp(self): # arrange self.logger_mock = LoggerMock() self.sut = mut.SpriteSheetMaskGenerator(SpritesheetLib10Mock(self.logger_mock), self.logger_mock)
[docs] def test_invalid_sprite_definition_from_grid_command(self): # arrange class _TestMock(mut.SpritesheetLib10): # noinspection PyDocstring def create_grid(self, num_tiles_x, num_tiles_y, tile_width, tile_height, file_info): return TestData.SDEF_INVALID_DUPLICATE_NAMES sut = mut.SpriteSheetMaskGenerator(_TestMock(self.logger_mock), self.logger_mock) # act / verify self.assertRaises(SystemExit, sut.main, "create_grid 2 2 out.png.sdef".split())
[docs] def test_invalid_sprite_definition_from_from_file_command(self): # arrange class _TestMock(mut.SpritesheetLib10): # noinspection PyDocstring def load_sdef_from_file(self, file_info, json_module=None): return TestData.SDEF_INVALID_DUPLICATE_NAMES sut = mut.SpriteSheetMaskGenerator(_TestMock(self.logger_mock), self.logger_mock) # act / verify self.assertRaises(SystemExit, sut.main, "create_from_file in.png out.png.sdef".split())
[docs] def test_invalid_sprite_definition_after_convert_sprite_definition(self): # arrange class _TestMock(mut.SpritesheetLib10): # noinspection PyDocstring def adjust_spacing(self, source_sprite_def, spacing): return TestData.SDEF_INVALID_DUPLICATE_NAMES sut = mut.SpriteSheetMaskGenerator(_TestMock(self.logger_mock), self.logger_mock) # act / verify self.assertRaises(SystemExit, sut.main, "create_grid 2 2 out.png.sdef".split())
if __name__ == '__main__': # pragma: no cover unittest.main()