Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

test: add specs for non-rgb image processing #32

Merged
merged 7 commits into from
Nov 14, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion .rspec
Original file line number Diff line number Diff line change
@@ -1,3 +1,2 @@
--color
--format progress
--require spec_helper
2 changes: 1 addition & 1 deletion bin/benchmark-full
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ inputs = [
{
path: 'tmp/high-res-small-size-16000x11000px.jpg',
options: { 'crop' => '815,850,14909,10005', 'straighten' => 0.5, 'gamma' => 0.85 },
description: 'Huge, pixelised grayscale gradient'
description: 'Huge, pixelised greyscale gradient'
},
{
path: 'tmp/spider-8288816.jpg',
Expand Down
38 changes: 19 additions & 19 deletions spec/colour_helper.rb
Original file line number Diff line number Diff line change
@@ -1,27 +1,27 @@
# frozen_string_literal: true

module ColourHelper
def generate_test_image(at_file_path, width = 600, height = 300)
system(
'convert',
'-size',
"#{width}x#{height}",
'-seed',
'5432',
'plasma:red-blue',
'pattern:checkerboard', '-gravity', 'center', '-geometry', "+#{width * 3 / 4},+0", '-composite',
at_file_path
)
def generate_test_image_plasma_checkers(at_file_path, width: 600, height: 300)
fill = [
['plasma:red-blue'],
['pattern:checkerboard', '-gravity', 'center', '-geometry', "+#{width * 3 / 4},+0", '-composite']
]
generate_test_image(at_file_path, fill: fill, width: width, height: height)
end

def solid_colour_image(width, height, colour = 0x000000ff)
pb = GdkPixbuf::Pixbuf.new(colorspace: GdkPixbuf::Colorspace::RGB,
has_alpha: false,
bits_per_sample: 8,
width: width,
height: height)
pb.fill!(colour)
pb
def generate_test_image_greyscale(at_file_path, width: 600, height: 300)
generate_test_image(at_file_path, fill: 'gradient:white-black', width: width, height: height)
end

def generate_test_image(at_file_path, fill:, width: 600, height: 300)
fill = Array(fill).flatten

generate_image_options = ['convert', '-size', "#{width}x#{height}", '-seed', '5432', *fill, at_file_path]
system(*generate_image_options) || raise("Failed to generate image.\nCommand: #{generate_image_options.join(' ')}")
end

def generate_test_image_solid(at_file_path, width: 600, height: 300, colour: '#000000')
generate_test_image(at_file_path, width: width, height: height, fill: "canvas:#{colour}")
end

def crude_average_colour(pixbuf)
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
52 changes: 43 additions & 9 deletions spec/morandi_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@
let(:processed_image_type) { processed_image_info[0].name }
let(:processed_image_width) { processed_image_info[1] }
let(:processed_image_height) { processed_image_info[2] }
let(:generate_image) do
generate_test_image_plasma_checkers(file_in, width: original_image_width, height: original_image_height)
end

before(:all) do
FileUtils.mkdir_p('sample')
Expand All @@ -27,12 +30,15 @@
end

before do
generate_test_image(file_in, original_image_width, original_image_height) unless File.exist?(file_in)
next if File.exist?(file_in)

generate_image
end

after do |ex|
add_to_visual_report(ex, files = Dir['sample/*'])
FileUtils.rm_rf(files)
test_files = Dir['sample/*']
add_to_visual_report(ex, (test_files + [file_in]).uniq)
FileUtils.rm_rf(test_files)
end

after(:all) do
Expand Down Expand Up @@ -453,6 +459,31 @@
end
end
end

context 'with a non-rgb image' do
let(:generate_image) do
generate_test_image_greyscale(file_in, width: original_image_width, height: original_image_height)
end

it 'changes greyscale image to srgb' do
expect(file_in).to match_colourspace('gray') # Testing a setup to protect from a hidden regression
process_image

expect(file_out).to match_colourspace('srgb')
end

# Colour filters implementation operates on RGB-based constants, thus a dedicated test
context 'with colour filter' do
let(:options) { super().merge('fx' => 'sepia') }

it 'creates a valid, srgb image' do
process_image

expect(file_out).to match_reference_image('greyscale-with-sepia')
expect(file_out).to match_colourspace('srgb')
end
end
end
end

context 'pixbuf processor' do
Expand Down Expand Up @@ -486,7 +517,7 @@
let(:icc_height) { 400 }

before do
generate_test_image(icc_path, icc_width, icc_height)
generate_test_image_plasma_checkers(icc_path, width: icc_width, height: icc_height)
end

it 'should use a file at this location as the input' do
Expand Down Expand Up @@ -516,7 +547,7 @@
let(:icc_height) { 400 }

before do
generate_test_image(icc_path, icc_width, icc_height)
generate_test_image_plasma_checkers(icc_path, width: icc_width, height: icc_height)
end

it 'should ignore the file at this path' do
Expand Down Expand Up @@ -547,7 +578,10 @@
end

context 'with a gray image and invalid spots' do
let(:file_arg) { solid_colour_image(800, 800, 0x666666ff) }
let(:file_in) { 'sample/sample.jpg' }
let(:original_image_width) { 800 }
let(:original_image_height) { 800 }
let(:generate_image) { generate_test_image_solid(file_in, width: 800, height: 800, colour: '#666666') }
let(:options) { { 'redeye' => [[540, 650], [-100, 100]] } }

it 'should not break or corrupt the image' do
Expand All @@ -556,9 +590,9 @@
expect(File).to exist(file_out)
expect(processed_image_type).to eq('jpeg')

expect(crude_average_colour(file_arg.subpixbuf(505, 605, 100, 100))).to be_greyish
expect(crude_average_colour(GdkPixbuf::Pixbuf.new(file: file_out).subpixbuf(505, 605, 100,
100))).to be_greyish
expect(crude_average_colour(GdkPixbuf::Pixbuf.new(file: file_in).subpixbuf(505, 605, 100, 100))).to be_greyish
expect(crude_average_colour(GdkPixbuf::Pixbuf.new(file: file_out).subpixbuf(505, 605, 100, 100)))
.to be_greyish
end
end
end
Expand Down
13 changes: 12 additions & 1 deletion spec/spec_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -19,14 +19,25 @@
require 'super_diff/rspec'
require 'pry'

require 'support/match_reference_image'
Dir['spec/support/**/*.rb'].each { |f| require "./#{f}" }

require_relative 'visual_report_helper'
require_relative 'colour_helper'

RSpec.configure do |config|
config.run_all_when_everything_filtered = true
config.filter_run :focus

# Many RSpec users commonly either run the entire suite or an individual
# file, and it's useful to allow more verbose output when running an
# individual spec file.
if config.files_to_run.one?
# Use the documentation formatter for detailed output,
# unless a formatter has already been configured
# (e.g. via a command-line flag).
config.default_formatter = 'doc'
end

# Run specs in random order to surface order dependencies. If you find an
# order dependency and want to debug it, you can fix the order by providing
# the seed, which is printed after each run.
Expand Down
21 changes: 21 additions & 0 deletions spec/support/match_colourspace.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# frozen_string_literal: true

require 'open3'

# For testing that under a given path resides an image with desired colourspace.
# The colourspace is currently extracted using imagemagick's `identify`, resulting in values like 'gray' or 'srgb'
# According to docs (https://www.imagemagick.org/script/escape.php), it may include number of channels and meta channels
RSpec::Matchers.define :match_colourspace do |expected_colourspace|
match do |tested_path|
raise(ArgumentError, "path #{tested_path} is not a file") unless File.file?(tested_path)

@colourspace, status = Open3.capture2('identify', '-format', '%[channels]', tested_path)
raise "Failed to read colorspace of #{tested_path}" unless status.success?

@colourspace == expected_colourspace
end

failure_message do
"Colourspaces don't match. Expected: #{expected_colourspace}, got: #{@colourspace}"
end
end
4 changes: 3 additions & 1 deletion spec/support/match_reference_image.rb
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,9 @@ def debug_data
end

match do |tested_path|
if File.file?(tested_path) && !File.file?(reference_path)
raise ArgumentError, "Provided path is not a file: #{tested_path}" unless File.file?(tested_path)

unless File.file?(reference_path)
debug_data.expose_from(tested_path: tested_path, file_type: file_type)
return false
end
Expand Down