CliRunner: - --batch / --config <file> flags trigger batch mode with directory scanning - collect_files() with recursive support and case-insensitive extension matching - build_pipeline() respects AppConfig conversion flags (invert toggle) - Progress output to stderr: "[1/42] Processing DSC09246.ARW..." Tests (test_pipeline.cpp): - AppConfig: load/save roundtrip, missing file error, extension parsing, format mapping, write_default - CropProcessor: levels adjustment, sharpening no-clip, empty image error - ColorCorrector: AWB preserves neutral grey, skips B&W film - Inverter: color negative changes values, B&W inversion, positive passthrough - Preprocessor: 8-bit→16-bit conversion test_rawloader.cpp: added missing <fstream> include Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
104 lines
3.5 KiB
C++
104 lines
3.5 KiB
C++
#include <gtest/gtest.h>
|
|
|
|
#include "converter/rawloader/RawLoader.h"
|
|
|
|
#include <filesystem>
|
|
#include <fstream>
|
|
|
|
using namespace photoconv;
|
|
|
|
#ifndef TEST_DATA_DIR
|
|
#define TEST_DATA_DIR "import"
|
|
#endif
|
|
|
|
static const std::filesystem::path kTestDataDir{TEST_DATA_DIR};
|
|
|
|
// ──────────────────────────────────────────────
|
|
// File validation tests
|
|
// ──────────────────────────────────────────────
|
|
|
|
TEST(RawLoaderTest, RejectsNonexistentFile) {
|
|
RawLoader loader;
|
|
auto result = loader.load("/nonexistent/file.arw");
|
|
|
|
ASSERT_FALSE(result.has_value());
|
|
EXPECT_EQ(result.error().code, ErrorCode::FileNotFound);
|
|
}
|
|
|
|
TEST(RawLoaderTest, RejectsUnsupportedFormat) {
|
|
// Create a temporary file with unsupported extension
|
|
auto temp = std::filesystem::temp_directory_path() / "test.xyz";
|
|
{
|
|
std::ofstream f{temp};
|
|
f << "dummy";
|
|
}
|
|
|
|
RawLoader loader;
|
|
auto result = loader.load(temp);
|
|
|
|
ASSERT_FALSE(result.has_value());
|
|
EXPECT_EQ(result.error().code, ErrorCode::UnsupportedFormat);
|
|
|
|
std::filesystem::remove(temp);
|
|
}
|
|
|
|
// ──────────────────────────────────────────────
|
|
// RAW loading integration tests (require test data)
|
|
// ──────────────────────────────────────────────
|
|
|
|
TEST(RawLoaderTest, LoadsArwFile) {
|
|
auto arw_path = kTestDataDir / "DSC09246.ARW";
|
|
if (!std::filesystem::exists(arw_path)) {
|
|
GTEST_SKIP() << "Test data not available: " << arw_path;
|
|
}
|
|
|
|
RawLoader loader;
|
|
auto result = loader.load(arw_path);
|
|
|
|
ASSERT_TRUE(result.has_value()) << result.error().format();
|
|
|
|
// Verify 16-bit BGR output
|
|
EXPECT_EQ(result->rgb.type(), CV_16UC3);
|
|
EXPECT_GT(result->rgb.cols, 0);
|
|
EXPECT_GT(result->rgb.rows, 0);
|
|
|
|
// Verify metadata was populated
|
|
EXPECT_FALSE(result->metadata.camera_make.empty());
|
|
EXPECT_GT(result->metadata.raw_width, 0);
|
|
EXPECT_GT(result->metadata.raw_height, 0);
|
|
}
|
|
|
|
TEST(RawLoaderTest, MetadataContainsSonyMake) {
|
|
auto arw_path = kTestDataDir / "DSC09246.ARW";
|
|
if (!std::filesystem::exists(arw_path)) {
|
|
GTEST_SKIP() << "Test data not available: " << arw_path;
|
|
}
|
|
|
|
RawLoader loader;
|
|
auto result = loader.load(arw_path);
|
|
ASSERT_TRUE(result.has_value());
|
|
|
|
// Sony ARW files should have "Sony" as make
|
|
EXPECT_EQ(result->metadata.camera_make, "Sony");
|
|
}
|
|
|
|
// ──────────────────────────────────────────────
|
|
// Pixel integrity tests
|
|
// ──────────────────────────────────────────────
|
|
|
|
TEST(RawLoaderTest, OutputIsNonTrivial) {
|
|
auto arw_path = kTestDataDir / "DSC09246.ARW";
|
|
if (!std::filesystem::exists(arw_path)) {
|
|
GTEST_SKIP() << "Test data not available: " << arw_path;
|
|
}
|
|
|
|
RawLoader loader;
|
|
auto result = loader.load(arw_path);
|
|
ASSERT_TRUE(result.has_value());
|
|
|
|
// Image should have non-zero content (not all black or all white)
|
|
cv::Scalar mean_val = cv::mean(result->rgb);
|
|
EXPECT_GT(mean_val[0], 100.0); // Not all black
|
|
EXPECT_LT(mean_val[0], 65000.0); // Not all white
|
|
}
|