imatcher 0.1.0 → 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: b6b74f4cc7e7d048a1bedabf6399d22c1752e029
4
- data.tar.gz: 490720e88565d39e81b8c1c0a6633dbb87a2a079
3
+ metadata.gz: 2ad15eab2eb3ec4656cafb23117199966625e18d
4
+ data.tar.gz: 3d15c721ce46ed7cbca79a0d9d4e310972ebcfc2
5
5
  SHA512:
6
- metadata.gz: 59a52908a3a8b6e03f49e4cff3113a25a8645d2b3c36d47d4f29febedfc7c30082a1d549cc6fd4895e11d1fb7e1cb905c1856056a73c1fba1b394c7d1ddba030
7
- data.tar.gz: f6392bc159c2e6ece9eb474645f763c35a329f4e75f42f53663aa4d25e71d65b52bee1c6971b5e16eb214e75e3342b6f54509e7483caf8a3f5c4fdff659db7cd
6
+ metadata.gz: b098cf87274c56a0089e795e686d6299ea91339d8bff948486ca25ea5a75e993fb1eb50d533416e2eddd18e035d1dc1330eb055e8a23ddb74e49d54c87f6b406
7
+ data.tar.gz: 11c76b5365728cfb495a764e15241d1aea897b8d1cf0642a0dceb870479ce2fc4f3bec87efd1c80ce59b12b8fc28d817cfda79013ec384cba7ed76bf7000635b
data/.gitignore CHANGED
@@ -23,6 +23,7 @@
23
23
  .settings
24
24
  .tmproj
25
25
  Thumbs.db
26
+ *.gem
26
27
 
27
28
  /.bundle/
28
29
  /.yardoc
data/.rubocop.yml CHANGED
@@ -32,9 +32,17 @@ Style/BlockDelimiters:
32
32
  Exclude:
33
33
  - 'spec/**/*.rb'
34
34
 
35
+ Style/ParallelAssignment:
36
+ Enabled: false
37
+
35
38
  Lint/AmbiguousRegexpLiteral:
36
39
  Enabled: false
37
40
 
38
41
  Metrics/MethodLength:
39
42
  Exclude:
40
43
  - 'spec/**/*.rb'
44
+
45
+ Metrics/LineLength:
46
+ max: 100
47
+ Exclude:
48
+ - 'spec/**/*.rb'
data/.travis.yml CHANGED
@@ -1,6 +1,7 @@
1
1
  language: ruby
2
2
  cache: bundler
3
- matrix:
4
- include:
5
- - rvm: 2.2.2
6
- gemfile: gemfiles/rails42.gemfile
3
+ rvm:
4
+ - 2.2
5
+
6
+ notifications:
7
+ email: false
data/Gemfile CHANGED
@@ -2,8 +2,6 @@ source 'https://rubygems.org'
2
2
 
3
3
  gemspec
4
4
 
5
- gem 'pry'
6
-
7
5
  local_gemfile = 'Gemfile.local'
8
6
 
9
7
  if File.exist?(local_gemfile)
data/README.md CHANGED
@@ -1,8 +1,9 @@
1
- # Imatcher
1
+ [![Build Status](https://travis-ci.org/teachbase/imatcher.svg?branch=master)](https://travis-ci.org/teachbase/imatcher)
2
2
 
3
- Welcome to your new gem! In this directory, you'll find the files you need to be able to package up your Ruby library into a gem. Put your Ruby code in the file `lib/imatcher`. To experiment with that code, run `bin/console` for an interactive prompt.
3
+ # Imatcher
4
4
 
5
- TODO: Delete this and the text above, and describe your gem
5
+ Compare PNG images in pure Ruby (uses [ChunkyPNG](https://github.com/wvanbergen/chunky_png)) using different algorithms.
6
+ This is an utility library for image regression testing.
6
7
 
7
8
  ## Installation
8
9
 
@@ -20,20 +21,76 @@ Or install it yourself as:
20
21
 
21
22
  $ gem install imatcher
22
23
 
24
+ ## Modes
25
+
26
+ Imatcher supports different ways (_modes_) of comparing images.
27
+
28
+ Source images used in examples:
29
+
30
+ <img src="https://raw.githubusercontent.com/teachbase/imatcher/master/spec/fixtures/a.png" width="300" />
31
+ <img src="https://raw.githubusercontent.com/teachbase/imatcher/master/spec/fixtures/b.png" width="300" />
32
+
33
+ ### Base (RGB) mode
34
+
35
+ Compare pixels by values, resulting score is a ratio of unequal pixels.
36
+ Resulting diff represents per-channel difference.
37
+
38
+ <img src="https://raw.githubusercontent.com/teachbase/imatcher/master/spec/fixtures/rgb_diff.png" width="300" />
39
+
40
+ ### Grayscale mode
41
+
42
+ Compare pixels as grayscale (by brightness and alpha), resulting score is a ratio of unequal pixels (with respect to provided tolerance).
43
+
44
+ Resulting diff contains grayscale version of the first image with different pixels highlighted in red and red bounding box.
45
+
46
+ <img src="https://raw.githubusercontent.com/teachbase/imatcher/master/spec/fixtures/grayscale_diff.png" width="300" />
47
+
48
+ ### Delta
49
+
50
+ Compare pixels using [Delta E](https://en.wikipedia.org/wiki/Color_difference) distance.
51
+ Resulting diff contains grayscale version of the first image with different pixels highlighted in red (with respect to diff score).
52
+
53
+ <img src="https://raw.githubusercontent.com/teachbase/imatcher/master/spec/fixtures/delta_diff.png" width="300" />
54
+
23
55
  ## Usage
24
56
 
25
- TODO: Write usage instructions here
57
+ ```ruby
58
+ # create new matcher with default threshold equals to 0
59
+ # and base (RGB) mode
60
+ cmp = Imatcher::Matcher.new
61
+ cmp.mode #=> Imatcher::Modes::RGB
26
62
 
27
- ## Development
63
+ # create matcher with specific threshold
64
+ cmp = Imatcher::Matcher.new threshold: 0.05
65
+ cmp.threshold #=> 0.05
28
66
 
29
- After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
67
+ # create zero-tolerance grayscale matcher
68
+ cmp = Imatcher::Matcher.new mode: :grayscale, tolerance: 0
69
+ cmp.mode #=> Imatcher::Modes::Grayscale
30
70
 
31
- To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
71
+ res = cmp.compare(path_1, path_2)
72
+ res #=> Imatcher::Result
32
73
 
33
- ## Contributing
74
+ res.match? #=> true
75
+
76
+ res.score #=> 0.0
77
+
78
+ # Return diff image object
79
+ res.difference_image #=> Imatcher::Image
34
80
 
35
- Bug reports and pull requests are welcome on GitHub at https://github.com/[USERNAME]/imatcher.
81
+ res.difference_image.save(new_path)
82
+
83
+ # without explicit matcher
84
+ res = Imatcher.compare(path_1, path_2, options)
85
+
86
+ # equals to
87
+ res = Imatcher::Matcher.new(options).compare(path_1, path_2)
88
+
89
+ ```
90
+
91
+ ## Contributing
36
92
 
93
+ Bug reports and pull requests are welcome on GitHub at https://github.com/teachbase/imatcher.
37
94
 
38
95
  ## License
39
96
 
data/bin/setup CHANGED
@@ -4,5 +4,3 @@ IFS=$'\n\t'
4
4
  set -vx
5
5
 
6
6
  bundle install
7
-
8
- # Do any other automated setup that you need to do here
data/imatcher.gemspec CHANGED
@@ -15,7 +15,9 @@ Gem::Specification.new do |spec|
15
15
  spec.files = `git ls-files`.split($/)
16
16
  spec.require_paths = ["lib"]
17
17
 
18
- spec.add_development_dependency "bundler", "~> 1.11"
18
+ spec.add_dependency "chunky_png", "~> 1.3.5"
19
+
20
+ spec.add_development_dependency "simplecov", ">= 0.3.8"
19
21
  spec.add_development_dependency "rake", "~> 10.0"
20
22
  spec.add_development_dependency 'pry-byebug'
21
23
  spec.add_development_dependency "rspec", "~> 3.0"
data/lib/imatcher.rb CHANGED
@@ -1,4 +1,14 @@
1
1
  require "imatcher/version"
2
2
 
3
+ # Compare PNG images using different algorithms
3
4
  module Imatcher
5
+ class SizesMismatchError < StandardError
6
+ end
7
+
8
+ require 'imatcher/matcher'
9
+ require 'imatcher/color_methods'
10
+
11
+ def self.compare(path_a, path_b, options = {})
12
+ Matcher.new(options).compare(path_a, path_b)
13
+ end
4
14
  end
@@ -0,0 +1,11 @@
1
+ require 'chunky_png'
2
+
3
+ module Imatcher
4
+ module ColorMethods # :nodoc:
5
+ include ChunkyPNG::Color
6
+
7
+ def brightness(a)
8
+ 0.3 * r(a) + 0.59 * g(a) + 0.11 * b(a)
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,47 @@
1
+ require 'imatcher/color_methods'
2
+
3
+ module Imatcher
4
+ # Extend ChunkyPNG::Image with some methods.
5
+ class Image < ChunkyPNG::Image
6
+ include ColorMethods
7
+
8
+ def each_pixel
9
+ height.times do |y|
10
+ row(y).each_with_index do |pixel, x|
11
+ yield(pixel, x, y)
12
+ end
13
+ end
14
+ end
15
+
16
+ def compare_each_pixel(image)
17
+ height.times do |y|
18
+ next if image.row(y) == row(y)
19
+ row(y).each_with_index do |pixel, x|
20
+ yield(pixel, image[x, y], x, y)
21
+ end
22
+ end
23
+ end
24
+
25
+ def to_grayscale
26
+ each_pixel do |pixel, x, y|
27
+ self[x, y] = grayscale(brightness(pixel).round)
28
+ end
29
+ self
30
+ end
31
+
32
+ def with_alpha(value)
33
+ each_pixel do |pixel, x, y|
34
+ self[x, y] = rgba(r(pixel), g(pixel), b(pixel), value)
35
+ end
36
+ self
37
+ end
38
+
39
+ def sizes_match?(image)
40
+ [width, height] == [image.width, image.height]
41
+ end
42
+
43
+ def render_bounds(left, bot, right, top)
44
+ rect(left, bot, right, top, rgb(255, 0, 0))
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,33 @@
1
+ module Imatcher
2
+ # Matcher contains information about compare mode
3
+ class Matcher
4
+ require 'imatcher/image'
5
+ require 'imatcher/result'
6
+ require 'imatcher/modes'
7
+
8
+ MODES = {
9
+ rgb: 'RGB',
10
+ delta: 'Delta',
11
+ grayscale: 'Grayscale'
12
+ }.freeze
13
+
14
+ attr_reader :threshold, :mode
15
+
16
+ def initialize(options = {})
17
+ mode_type = options.delete(:mode) || :rgb
18
+ @mode = Modes.const_get(MODES[mode_type]).new(options)
19
+ end
20
+
21
+ def compare(path_1, path_2)
22
+ a = Image.from_file(path_1)
23
+ b = Image.from_file(path_2)
24
+ raise SizesMismatchError,
25
+ "Size mismatch: first image size: " \
26
+ "#{a.width}x#{a.height}, " \
27
+ "second image size: " \
28
+ "#{b.width}x#{b.height}" unless a.sizes_match?(b)
29
+
30
+ mode.compare(a, b)
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,7 @@
1
+ module Imatcher
2
+ module Modes # :nodoc:
3
+ require 'imatcher/modes/rgb'
4
+ require 'imatcher/modes/grayscale'
5
+ require 'imatcher/modes/delta'
6
+ end
7
+ end
@@ -0,0 +1,52 @@
1
+ module Imatcher
2
+ module Modes
3
+ class Base # :nodoc:
4
+ include ColorMethods
5
+
6
+ attr_reader :result, :threshold
7
+
8
+ def initialize(threshold: 0.0)
9
+ @threshold = threshold
10
+ @result = Result.new(self, threshold)
11
+ end
12
+
13
+ def compare(a, b)
14
+ result.image = a
15
+
16
+ b.compare_each_pixel(a) do |b_pixel, a_pixel, x, y|
17
+ next if pixels_equal?(b_pixel, a_pixel)
18
+ update_result(b_pixel, a_pixel, x, y)
19
+ end
20
+
21
+ result.score = score
22
+ result
23
+ end
24
+
25
+ def diff(bg, diff)
26
+ diff_image = background(bg)
27
+ diff_image.render_bounds(*calculate_bounds(diff))
28
+ diff.each do |pixels_pair|
29
+ pixels_diff(diff_image, *pixels_pair)
30
+ end
31
+ create_diff_image(bg, diff_image)
32
+ end
33
+
34
+ def score
35
+ @result.diff.length.to_f / @result.image.pixels.length
36
+ end
37
+
38
+ # rubocop:disable Metrics/AbcSize
39
+ def calculate_bounds(diff)
40
+ xmin, xmax, ymin, ymax = result.image.width, 0, result.image.height, 0
41
+ diff.each do |pixels_pair|
42
+ xmin = pixels_pair[2] if pixels_pair[2] < xmin
43
+ xmax = pixels_pair[2] if pixels_pair[2] > xmax
44
+ ymin = pixels_pair[3] if pixels_pair[3] < ymin
45
+ ymax = pixels_pair[3] if pixels_pair[3] > ymax
46
+ end
47
+
48
+ [xmin - 1, ymin - 1, xmax + 1, ymax + 1]
49
+ end
50
+ end
51
+ end
52
+ end
@@ -0,0 +1,50 @@
1
+ module Imatcher
2
+ module Modes # :nodoc:
3
+ require 'imatcher/modes/base'
4
+
5
+ # Compare pixels using Delta E distance.
6
+ class Delta < Base
7
+ def initialize(threshold: 0.0)
8
+ @threshold = threshold
9
+ @result = Result.new(self, threshold)
10
+ @delta_score = 0.0
11
+ end
12
+
13
+ private
14
+
15
+ def pixels_equal?(a, b)
16
+ a == b
17
+ end
18
+
19
+ def update_result(a, b, x, y)
20
+ d = euclid(a, b) / (MAX * Math.sqrt(3))
21
+ @result.diff << [a, b, x, y, d]
22
+ @delta_score += d
23
+ end
24
+
25
+ def background(bg)
26
+ Image.new(bg.width, bg.height, WHITE).with_alpha(0)
27
+ end
28
+
29
+ def euclid(a, b)
30
+ Math.sqrt(
31
+ (r(a) - r(b))**2 +
32
+ (g(a) - g(b))**2 +
33
+ (b(a) - b(b))**2
34
+ )
35
+ end
36
+
37
+ def create_diff_image(bg, diff_image)
38
+ bg.to_grayscale.compose!(diff_image, 0, 0)
39
+ end
40
+
41
+ def pixels_diff(d, *_args, x, y, a)
42
+ d[x, y] = rgba(MAX, 0, 0, (a * MAX).round)
43
+ end
44
+
45
+ def score
46
+ @delta_score / result.image.pixels.length
47
+ end
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,48 @@
1
+ module Imatcher
2
+ module Modes # :nodoc:
3
+ require 'imatcher/modes/base'
4
+
5
+ # Compare pixels by alpha and brightness.
6
+ #
7
+ # Options:
8
+ # - tolerance - defines the maximum allowed difference for alpha/brightness
9
+ # (default value is 16)
10
+ class Grayscale < Base
11
+ DEFAULT_TOLERANCE = 16
12
+
13
+ attr_reader :tolerance
14
+
15
+ def initialize(options)
16
+ @tolerance = options.delete(:tolerance) || DEFAULT_TOLERANCE
17
+ super(options)
18
+ end
19
+
20
+ def pixels_equal?(a, b)
21
+ alpha = color_similar?(a(a), a(b))
22
+ brightness = color_similar?(brightness(a), brightness(b))
23
+ brightness && alpha
24
+ end
25
+
26
+ def update_result(a, b, x, y)
27
+ @result.diff << [a, b, x, y]
28
+ end
29
+
30
+ def background(bg)
31
+ bg.to_grayscale
32
+ end
33
+
34
+ def pixels_diff(d, _a, _b, x, y)
35
+ d[x, y] = rgb(255, 0, 0)
36
+ end
37
+
38
+ def create_diff_image(_bg, diff_image)
39
+ diff_image
40
+ end
41
+
42
+ def color_similar?(a, b)
43
+ d = (a - b).abs
44
+ d <= tolerance
45
+ end
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,33 @@
1
+ module Imatcher
2
+ module Modes # :nodoc:
3
+ require 'imatcher/modes/base'
4
+
5
+ # Compare pixels by values.
6
+ # Resulting image contains per-channel differences.
7
+ class RGB < Base
8
+ def pixels_equal?(a, b)
9
+ a == b
10
+ end
11
+
12
+ def update_result(a, b, x, y)
13
+ @result.diff << [a, b, x, y]
14
+ end
15
+
16
+ def background(bg)
17
+ Image.new(bg.width, bg.height, BLACK)
18
+ end
19
+
20
+ def create_diff_image(bg, diff_image)
21
+ bg.to_grayscale.compose!(diff_image, 0, 0)
22
+ end
23
+
24
+ def pixels_diff(d, a, b, x, y)
25
+ d[x, y] = rgb(
26
+ (r(a) - r(b)).abs,
27
+ (g(a) - g(b)).abs,
28
+ (b(a) - b(b)).abs
29
+ )
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,23 @@
1
+ module Imatcher
2
+ # Object containing comparison score and diff image
3
+ class Result
4
+ attr_accessor :score, :image
5
+ attr_reader :diff, :mode, :threshold
6
+
7
+ def initialize(mode, threshold)
8
+ @score = 0.0
9
+ @diff = []
10
+ @threshold = threshold
11
+ @mode = mode
12
+ end
13
+
14
+ def difference_image
15
+ @diff_image ||= mode.diff(image, diff)
16
+ end
17
+
18
+ # Returns true iff score less or equals to threshold
19
+ def match?
20
+ score <= threshold
21
+ end
22
+ end
23
+ end
@@ -1,3 +1,3 @@
1
1
  module Imatcher # :nodoc:
2
- VERSION = "0.1.0".freeze
2
+ VERSION = "0.1.1".freeze
3
3
  end
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
@@ -4,8 +4,4 @@ describe Imatcher do
4
4
  it 'has a version number' do
5
5
  expect(Imatcher::VERSION).not_to be nil
6
6
  end
7
-
8
- it 'does something useful' do
9
- expect(false).to eq(true)
10
- end
11
7
  end
@@ -0,0 +1,43 @@
1
+ require 'spec_helper'
2
+
3
+ describe Imatcher::Modes::Delta do
4
+ let(:path_1) { image_path "a" }
5
+ let(:path_2) { image_path "darker" }
6
+ subject { Imatcher.compare(path_1, path_2, options) }
7
+
8
+ let(:options) { { mode: :delta } }
9
+
10
+ context "with similar images" do
11
+ it "score around 0.094" do
12
+ expect(subject.score).to be_within(0.0005).of(0.094)
13
+ end
14
+
15
+ context "with custom threshold" do
16
+ subject { Imatcher.compare(path_1, path_2, options).match? }
17
+
18
+ context "below score" do
19
+ let(:options) { { mode: :delta, threshold: 0.01 } }
20
+
21
+ it { expect(subject).to eq false }
22
+ end
23
+
24
+ context "above score" do
25
+ let(:options) { { mode: :delta, threshold: 0.1 } }
26
+
27
+ it { expect(subject).to eq true }
28
+ end
29
+ end
30
+ end
31
+
32
+ context "with different images" do
33
+ let(:path_2) { image_path "b" }
34
+
35
+ it "score around 0.0195" do
36
+ expect(subject.score).to be_within(0.0005).of(0.0195)
37
+ end
38
+
39
+ it "creates correct difference image" do
40
+ expect(subject.difference_image).to eq(Imatcher::Image.from_file(image_path("delta_diff")))
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,71 @@
1
+ require 'spec_helper'
2
+
3
+ describe Imatcher::Modes::Grayscale do
4
+ let(:path_1) { image_path "a" }
5
+ let(:path_2) { image_path "darker" }
6
+ subject { Imatcher.compare(path_1, path_2, options) }
7
+
8
+ let(:options) { { mode: :grayscale } }
9
+
10
+ context "darker image" do
11
+ it "score around 0.7" do
12
+ expect(subject.score).to be_within(0.05).of(0.75)
13
+ end
14
+ end
15
+
16
+ context "different images" do
17
+ let(:path_2) { image_path "b" }
18
+
19
+ it "score around 0.02" do
20
+ expect(subject.score).to be_within(0.0005).of(0.009)
21
+ end
22
+
23
+ it "creates correct difference image" do
24
+ expect(subject.difference_image).to eq(Imatcher::Image.from_file(image_path("grayscale_diff")))
25
+ end
26
+ end
27
+
28
+ context "with zero tolerance" do
29
+ let(:options) { { mode: :grayscale, tolerance: 0 } }
30
+
31
+ context "darker image" do
32
+ it "score equals to 1" do
33
+ expect(subject.score).to eq 1.0
34
+ end
35
+ end
36
+
37
+ context "different image" do
38
+ let(:path_2) { image_path "b" }
39
+
40
+ it "score around 0.97" do
41
+ expect(subject.score).to be_within(0.005).of(0.97)
42
+ end
43
+ end
44
+
45
+ context "equal image" do
46
+ let(:path_2) { image_path "a" }
47
+
48
+ it "score equals to 0" do
49
+ expect(subject.score).to eq 0
50
+ end
51
+ end
52
+ end
53
+
54
+ context "with small tolerance" do
55
+ let(:options) { { mode: :grayscale, tolerance: 8 } }
56
+
57
+ context "darker image" do
58
+ it "score around 0.9" do
59
+ expect(subject.score).to be_within(0.005).of(0.9)
60
+ end
61
+ end
62
+
63
+ context "different image" do
64
+ let(:path_2) { image_path "b" }
65
+
66
+ it "score around 0.027" do
67
+ expect(subject.score).to be_within(0.0005).of(0.027)
68
+ end
69
+ end
70
+ end
71
+ end
@@ -0,0 +1,26 @@
1
+ require 'spec_helper'
2
+
3
+ describe Imatcher::Modes::RGB do
4
+ let(:path_1) { image_path "a" }
5
+ let(:path_2) { image_path "darker" }
6
+ subject { Imatcher.compare(path_1, path_2, options) }
7
+ let(:options) { {} }
8
+
9
+ context "with similar images" do
10
+ it "score equals to 1" do
11
+ expect(subject.score).to eq 1
12
+ end
13
+ end
14
+
15
+ context "with different images" do
16
+ let(:path_2) { image_path "b" }
17
+
18
+ it "score around 0.97" do
19
+ expect(subject.score).to be_within(0.005).of(0.97)
20
+ end
21
+
22
+ it "creates correct difference image" do
23
+ expect(subject.difference_image).to eq(Imatcher::Image.from_file(image_path("rgb_diff")))
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,45 @@
1
+ require 'spec_helper'
2
+
3
+ describe Imatcher::Matcher do
4
+ describe "new" do
5
+ subject { Imatcher::Matcher.new(options) }
6
+
7
+ context "without options" do
8
+ let(:options) { {} }
9
+
10
+ it { expect(subject.mode.threshold).to eq 0 }
11
+ it { expect(subject.mode).to be_a Imatcher::Modes::RGB }
12
+ end
13
+
14
+ context "with custom threshold" do
15
+ let(:options) { { threshold: 0.1 } }
16
+
17
+ it { expect(subject.mode.threshold).to eq 0.1 }
18
+ end
19
+
20
+ context "with custom options" do
21
+ let(:options) { { mode: :grayscale, tolerance: 0 } }
22
+
23
+ it { expect(subject.mode.tolerance).to eq 0 }
24
+ end
25
+
26
+ context "with custom mode" do
27
+ let(:options) { { mode: :delta } }
28
+
29
+ it { expect(subject.mode).to be_a Imatcher::Modes::Delta }
30
+ end
31
+ end
32
+
33
+ describe "compare" do
34
+ let(:path_1) { image_path "very_small" }
35
+ let(:path_2) { image_path "very_small" }
36
+ subject { Imatcher::Matcher.new.compare(path_1, path_2) }
37
+
38
+ it { expect(subject).to be_a Imatcher::Result }
39
+
40
+ context "when sizes mismatch" do
41
+ let(:path_2) { image_path "small" }
42
+ it { expect { subject }.to raise_error(Imatcher::SizesMismatchError) }
43
+ end
44
+ end
45
+ end
data/spec/spec_helper.rb CHANGED
@@ -2,6 +2,13 @@ $LOAD_PATH.unshift File.expand_path('../../lib', __FILE__)
2
2
 
3
3
  require 'rspec'
4
4
  require 'pry-byebug'
5
+
6
+ if ENV['COVER']
7
+ require 'simplecov'
8
+ SimpleCov.root File.join(File.dirname(__FILE__), '..')
9
+ SimpleCov.start
10
+ end
11
+
5
12
  require 'imatcher'
6
13
 
7
14
  Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each { |f| require f }
@@ -9,3 +16,7 @@ Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each { |f| require f }
9
16
  RSpec.configure do |config|
10
17
  config.mock_with :rspec
11
18
  end
19
+
20
+ def image_path(name)
21
+ "#{File.dirname(__FILE__)}/fixtures/#{name}.png"
22
+ end
metadata CHANGED
@@ -1,29 +1,43 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: imatcher
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - palkan
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-02-15 00:00:00.000000000 Z
11
+ date: 2016-02-17 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
- name: bundler
14
+ name: chunky_png
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
17
  - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: '1.11'
20
- type: :development
19
+ version: 1.3.5
20
+ type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
- version: '1.11'
26
+ version: 1.3.5
27
+ - !ruby/object:Gem::Dependency
28
+ name: simplecov
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: 0.3.8
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: 0.3.8
27
41
  - !ruby/object:Gem::Dependency
28
42
  name: rake
29
43
  requirement: !ruby/object:Gem::Requirement
@@ -85,8 +99,29 @@ files:
85
99
  - bin/setup
86
100
  - imatcher.gemspec
87
101
  - lib/imatcher.rb
102
+ - lib/imatcher/color_methods.rb
103
+ - lib/imatcher/image.rb
104
+ - lib/imatcher/matcher.rb
105
+ - lib/imatcher/modes.rb
106
+ - lib/imatcher/modes/base.rb
107
+ - lib/imatcher/modes/delta.rb
108
+ - lib/imatcher/modes/grayscale.rb
109
+ - lib/imatcher/modes/rgb.rb
110
+ - lib/imatcher/result.rb
88
111
  - lib/imatcher/version.rb
112
+ - spec/fixtures/a.png
113
+ - spec/fixtures/b.png
114
+ - spec/fixtures/darker.png
115
+ - spec/fixtures/delta_diff.png
116
+ - spec/fixtures/grayscale_diff.png
117
+ - spec/fixtures/rgb_diff.png
118
+ - spec/fixtures/small.png
119
+ - spec/fixtures/very_small.png
89
120
  - spec/imatcher_spec.rb
121
+ - spec/integrations/delta_spec.rb
122
+ - spec/integrations/grayscale_spec.rb
123
+ - spec/integrations/rgb_spec.rb
124
+ - spec/matcher_spec.rb
90
125
  - spec/spec_helper.rb
91
126
  homepage: http://github.com/teachbase/imatcher
92
127
  licenses: