"""Validate light keys without an Unreal installation.""" import importlib.util from pathlib import Path import sys import unittest from unittest.mock import MagicMock, patch class LightKeyTests(unittest.TestCase): def setUp(self): self.unreal = MagicMock() self.unreal.FrameNumber.side_effect = lambda frame: frame path = Path(__file__).resolve().parents[1] / "Content/Python/ue_workshop/sequence.py" spec = importlib.util.spec_from_file_location("ue_workshop._light_key_test", path) module = importlib.util.module_from_spec(spec) with patch.dict(sys.modules, {"unreal": self.unreal}): spec.loader.exec_module(module) self.shot = module.Sequence.__new__(module.Sequence) self.shot.frames = 48 self.shot._light_tracks = {} self.shot.bind = MagicMock() self.track = self.shot.bind.return_value.add_track.return_value self.channels = [MagicMock() for _ in range(4)] self.track.add_section.return_value.get_all_channels.return_value = self.channels self.actor = MagicMock() self.light = self.actor.get_component_by_class.return_value self.light.get_path_name.return_value = "Light" def test_color_keys_rgb_and_leaves_alpha_at_default(self): self.shot.light_key(self.actor, 10, color=(1, 0.5, 0)) self.shot.bind.assert_called_once_with(self.light) self.track.set_property_name_and_path.assert_called_once_with("LightColor", "LightColor") self.assertEqual(self.channels[1].add_key.call_args.args, (10, 0.5)) self.channels[3].set_default.assert_called_once_with(1.0) self.channels[3].add_key.assert_not_called() def test_later_keys_reuse_the_track(self): self.shot.light_key(self.actor, 0, intensity=0) self.shot.light_key(self.actor, 47, intensity=5000) self.track.add_section.assert_called_once() self.track.set_property_name_and_path.assert_called_once_with("Intensity", "Intensity") self.assertEqual(self.channels[0].add_key.call_count, 2) def test_color_and_intensity_use_separate_tracks(self): self.shot.light_key(self.actor, 0, color=(1, 1, 1), intensity=100) self.assertEqual(self.track.add_section.call_count, 2) def test_invalid_arguments_create_no_track(self): for args in [dict(frame=48, color=(1, 1, 1)), dict(frame=0, color=(1, 1)), dict(frame=0, intensity=1, interpolation="smooth")]: with self.assertRaises(ValueError): self.shot.light_key(self.actor, **args) self.shot.bind.assert_not_called() def test_actor_without_light_is_rejected(self): self.actor.get_component_by_class.return_value = None with self.assertRaises(ValueError): self.shot.light_key(self.actor, 0, intensity=1)