import pytest from dimensions import compute_output_dimensions, MAX_OUTPUT_DIM def aspect_ratio_error(w_in, h_in, w_out, h_out): return abs(w_out / h_out - w_in / h_in) # --- output constraints --- @pytest.mark.parametrize("w, h", [ (1920, 1080), (1080, 1920), (1000, 1000), (1000, 381), (381, 1000), (3840, 2160), (1, 1), ]) def test_output_is_multiple_of_8(w, h): nw, nh = compute_output_dimensions(w, h) assert nw % 8 == 0 assert nh % 8 == 0 @pytest.mark.parametrize("w, h", [ (1920, 1080), (1000, 381), (3840, 2160), ]) def test_landscape_long_side_is_max_dim(w, h): nw, nh = compute_output_dimensions(w, h) assert nw == MAX_OUTPUT_DIM @pytest.mark.parametrize("w, h", [ (1080, 1920), (381, 1000), ]) def test_portrait_long_side_is_max_dim(w, h): nw, nh = compute_output_dimensions(w, h) assert nh == MAX_OUTPUT_DIM def test_square_stays_square(): nw, nh = compute_output_dimensions(1000, 1000) assert nw == nh == MAX_OUTPUT_DIM # --- aspect ratio preservation --- @pytest.mark.parametrize("w, h", [ (1920, 1080), (1080, 1920), (1000, 381), (381, 1000), (3840, 2160), ]) def test_aspect_ratio_error_within_one_step(w, h): nw, nh = compute_output_dimensions(w, h) # Rounding to nearest-8 introduces at most 4px error on the short side. # Ratio error = long * delta_short / short^2, so max = long * 4 / short^2. max_allowed = max(nw, nh) * 4 / min(nw, nh) ** 2 assert aspect_ratio_error(w, h, nw, nh) <= max_allowed @pytest.mark.parametrize("w, h", [ (1000, 381), (381, 1000), ]) def test_round_beats_floor_on_tricky_ratio(w, h): """Cases where floor-to-8 and round-to-8 disagree: round must be at least as accurate.""" nw, nh = compute_output_dimensions(w, h) # Reproduce floor-to-8 result for comparison if w > h: nh_floor = (int(MAX_OUTPUT_DIM * h / w) // 8) * 8 nw_floor = MAX_OUTPUT_DIM else: nw_floor = (int(MAX_OUTPUT_DIM * w / h) // 8) * 8 nh_floor = MAX_OUTPUT_DIM assert aspect_ratio_error(w, h, nw, nh) <= aspect_ratio_error(w, h, nw_floor, nh_floor) # --- exact known values --- def test_16_9_landscape(): nw, nh = compute_output_dimensions(1920, 1080) assert (nw, nh) == (2048, 1152) def test_16_9_portrait(): nw, nh = compute_output_dimensions(1080, 1920) assert (nw, nh) == (1152, 2048) def test_custom_max_dim(): nw, nh = compute_output_dimensions(1920, 1080, max_dim=1024) assert nw == 1024 assert nh % 8 == 0