3a2c66702c
Tests on CPU (scheduled) / check-skip (push) Has been cancelled
Tests on CPU (scheduled) / pre-tests (push) Has been cancelled
Tests on CPU (scheduled) / tests-cpu-ubuntu (float32) (push) Has been cancelled
Tests on CPU (scheduled) / tests-cpu-ubuntu (float64) (push) Has been cancelled
Tests on CPU (scheduled) / tests-cpu-windows (3.11, float32, 2.5.1) (push) Has been cancelled
Tests on CPU (scheduled) / tests-cpu-windows (3.11, float32, 2.9.1) (push) Has been cancelled
Tests on CPU (scheduled) / tests-cpu-windows (3.11, float64, 2.5.1) (push) Has been cancelled
Tests on CPU (scheduled) / tests-cpu-windows (3.11, float64, 2.9.1) (push) Has been cancelled
Tests on CPU (scheduled) / tests-cpu-windows (3.12, float32, 2.5.1) (push) Has been cancelled
Tests on CPU (scheduled) / tests-cpu-windows (3.12, float32, 2.9.1) (push) Has been cancelled
Tests on CPU (scheduled) / tests-cpu-windows (3.12, float64, 2.5.1) (push) Has been cancelled
Tests on CPU (scheduled) / tests-cpu-windows (3.12, float64, 2.9.1) (push) Has been cancelled
Tests on CPU (scheduled) / tests-cpu-windows (3.13, float32, 2.9.1) (push) Has been cancelled
Tests on CPU (scheduled) / tests-cpu-windows (3.13, float64, 2.9.1) (push) Has been cancelled
Tests on CPU (scheduled) / tests-cpu-mac (3.11, float32, 2.5.1) (push) Has been cancelled
Tests on CPU (scheduled) / tests-cpu-mac (3.11, float32, 2.9.1) (push) Has been cancelled
Tests on CPU (scheduled) / tests-cpu-mac (3.12, float32, 2.5.1) (push) Has been cancelled
Tests on CPU (scheduled) / tests-cpu-mac (3.12, float32, 2.9.1) (push) Has been cancelled
Tests on CPU (scheduled) / tests-cpu-mac (3.13, float32, 2.9.1) (push) Has been cancelled
Tests on CPU (scheduled) / coverage (push) Has been cancelled
Tests on CPU (scheduled) / typing (push) Has been cancelled
Tests on CPU (scheduled) / tutorials (push) Has been cancelled
Tests on CPU (scheduled) / docs (push) Has been cancelled
Lint / TOML Format (push) Has been cancelled
126 lines
4.7 KiB
Python
126 lines
4.7 KiB
Python
# LICENSE HEADER MANAGED BY add-license-header
|
|
#
|
|
# Copyright 2018 Kornia Team
|
|
#
|
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
# you may not use this file except in compliance with the License.
|
|
# You may obtain a copy of the License at
|
|
#
|
|
# http://www.apache.org/licenses/LICENSE-2.0
|
|
#
|
|
# Unless required by applicable law or agreed to in writing, software
|
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
# See the License for the specific language governing permissions and
|
|
# limitations under the License.
|
|
#
|
|
|
|
from __future__ import annotations
|
|
|
|
import os
|
|
from unittest.mock import patch
|
|
|
|
import pytest
|
|
import torch
|
|
|
|
from kornia.models.base import ModelBaseMixin
|
|
|
|
|
|
class DummyMixin(ModelBaseMixin):
|
|
name = "dummy"
|
|
|
|
|
|
class TestModelBaseMixinTensorToType:
|
|
def test_torch_output_returns_tensor_unchanged(self):
|
|
mixin = DummyMixin()
|
|
t = torch.rand(1, 3, 8, 8)
|
|
out = mixin._tensor_to_type(t, "torch")
|
|
assert out is t
|
|
|
|
def test_torch_output_returns_list_unchanged(self):
|
|
mixin = DummyMixin()
|
|
tensors = [torch.rand(1, 3, 8, 8), torch.rand(1, 3, 8, 8)]
|
|
out = mixin._tensor_to_type(tensors, "torch")
|
|
assert out is tensors
|
|
|
|
def test_pil_output_single_tensor(self):
|
|
mixin = DummyMixin()
|
|
# (C, H, W) tensor in [0, 1]
|
|
t = torch.rand(3, 16, 16)
|
|
out = mixin._tensor_to_type(t, "pil")
|
|
# tensor_to_image returns a PIL Image or ndarray depending on implementation
|
|
assert out is not None
|
|
|
|
def test_pil_output_list_of_tensors(self):
|
|
mixin = DummyMixin()
|
|
tensors = [torch.rand(3, 16, 16), torch.rand(3, 16, 16)]
|
|
out = mixin._tensor_to_type(tensors, "pil")
|
|
assert isinstance(out, list)
|
|
assert len(out) == 2
|
|
|
|
def test_unsupported_output_type_raises(self):
|
|
mixin = DummyMixin()
|
|
t = torch.rand(1, 3, 8, 8)
|
|
with pytest.raises(RuntimeError, match=r"Output type.*is not supported"):
|
|
mixin._tensor_to_type(t, "numpy")
|
|
|
|
|
|
class TestModelBaseMixinSave:
|
|
def test_save_single_tensor_calls_write_image_once(self, tmp_path):
|
|
mixin = DummyMixin()
|
|
t = torch.rand(3, 8, 8)
|
|
with patch("kornia.models.base.write_image") as mock_write:
|
|
mixin.save(t, str(tmp_path))
|
|
assert mock_write.call_count == 1
|
|
# path is the first positional arg (matches write_image(path_file, image, ...))
|
|
saved_path = mock_write.call_args[0][0]
|
|
assert os.path.normcase(str(tmp_path)) in os.path.normcase(saved_path)
|
|
|
|
def test_save_list_of_tensors_calls_write_image_per_item(self, tmp_path):
|
|
mixin = DummyMixin()
|
|
tensors = [torch.rand(3, 8, 8), torch.rand(3, 8, 8), torch.rand(3, 8, 8)]
|
|
with patch("kornia.models.base.write_image") as mock_write:
|
|
mixin.save(tensors, str(tmp_path))
|
|
assert mock_write.call_count == 3
|
|
|
|
def test_save_creates_directory(self, tmp_path):
|
|
mixin = DummyMixin()
|
|
t = torch.rand(3, 8, 8)
|
|
new_dir = str(tmp_path / "new_subdir")
|
|
assert not os.path.exists(new_dir)
|
|
with patch("kornia.models.base.write_image"):
|
|
mixin.save(t, new_dir)
|
|
assert os.path.exists(new_dir)
|
|
|
|
|
|
class TestModelBaseMixinSaveOutputs:
|
|
def test_save_outputs_with_explicit_dir_single_tensor(self, tmp_path):
|
|
mixin = DummyMixin()
|
|
t = torch.rand(3, 8, 8)
|
|
with patch("kornia.models.base.write_image") as mock_write:
|
|
mixin._save_outputs(t, directory=str(tmp_path), suffix="_test")
|
|
assert mock_write.call_count == 1
|
|
# path is the first positional arg; verify suffix appears in filename
|
|
saved_path = mock_write.call_args[0][0]
|
|
assert "_test_" in saved_path
|
|
|
|
def test_save_outputs_with_explicit_dir_list(self, tmp_path):
|
|
mixin = DummyMixin()
|
|
tensors = [torch.rand(3, 8, 8), torch.rand(3, 8, 8)]
|
|
with patch("kornia.models.base.write_image") as mock_write:
|
|
mixin._save_outputs(tensors, directory=str(tmp_path))
|
|
assert mock_write.call_count == 2
|
|
|
|
def test_save_outputs_none_dir_creates_default(self, tmp_path, monkeypatch):
|
|
# Run from tmp_path so we don't pollute the repo
|
|
monkeypatch.chdir(tmp_path)
|
|
mixin = DummyMixin()
|
|
t = torch.rand(3, 8, 8)
|
|
with patch("kornia.models.base.write_image"):
|
|
mixin._save_outputs(t, directory=None)
|
|
kornia_outputs = tmp_path / "kornia_outputs"
|
|
assert kornia_outputs.exists()
|
|
subdirs = list(kornia_outputs.iterdir())
|
|
assert len(subdirs) == 1
|
|
assert subdirs[0].name.startswith("dummy")
|