Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Loading…

Refactoring #1

Merged
merged 6 commits into from

2 participants

@tomeric
Owner

Mr Martins,

I have split up the rendering of the image into several components that are easier to test. I have not yet added tests for these classes, but am planning to do so. Can you take a look at this code and decide if this is the direction we should pursue?

Thank!

@maarf

I give my blessing!

@tomeric tomeric merged commit e698239 into from
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
This page is out of date. Refresh to see the latest.
View
2  .rspec
@@ -0,0 +1,2 @@
+--color
+--format documentation
View
48 .rvmrc
@@ -0,0 +1,48 @@
+#!/usr/bin/env bash
+
+# This is an RVM Project .rvmrc file, used to automatically load the ruby
+# development environment upon cd'ing into the directory
+
+# First we specify our desired <ruby>[@<gemset>], the @gemset name is optional,
+# Only full ruby name is supported here, for short names use:
+# echo "rvm use 1.9.3" > .rvmrc
+environment_id="ruby-1.9.3-p125@cheers"
+
+# Uncomment the following lines if you want to verify rvm version per project
+# rvmrc_rvm_version="1.10.3" # 1.10.1 seams as a safe start
+# eval "$(echo ${rvm_version}.${rvmrc_rvm_version} | awk -F. '{print "[[ "$1*65536+$2*256+$3" -ge "$4*65536+$5*256+$6" ]]"}' )" || {
+# echo "This .rvmrc file requires at least RVM ${rvmrc_rvm_version}, aborting loading."
+# return 1
+# }
+
+# First we attempt to load the desired environment directly from the environment
+# file. This is very fast and efficient compared to running through the entire
+# CLI and selector. If you want feedback on which environment was used then
+# insert the word 'use' after --create as this triggers verbose mode.
+if [[ -d "${rvm_path:-$HOME/.rvm}/environments"
+ && -s "${rvm_path:-$HOME/.rvm}/environments/$environment_id" ]]
+then
+ \. "${rvm_path:-$HOME/.rvm}/environments/$environment_id"
+ [[ -s "${rvm_path:-$HOME/.rvm}/hooks/after_use" ]] &&
+ \. "${rvm_path:-$HOME/.rvm}/hooks/after_use" || true
+else
+ # If the environment file has not yet been created, use the RVM CLI to select.
+ rvm --create "$environment_id" || {
+ echo "Failed to create RVM environment '${environment_id}'."
+ return 1
+ }
+fi
+
+# If you use bundler, this might be useful to you:
+if [[ -s Gemfile ]] && {
+ ! builtin command -v bundle >/dev/null ||
+ builtin command -v bundle | grep $rvm_path/bin/bundle >/dev/null
+}
+then
+ printf "%b" "The rubygem 'bundler' is not installed. Installing it now.\n"
+ gem install bundler
+fi
+if [[ -s Gemfile ]] && builtin command -v bundle >/dev/null
+then
+ bundle install | grep -vE '^Using|Your bundle is complete'
+fi
View
26 Gemfile
@@ -1,4 +1,26 @@
-source 'https://rubygems.org'
+source :rubygems
-# Specify your gem's dependencies in cheers.gemspec
+# Specify the project's dependencies in the gemspec:
gemspec
+
+# Specifiy the development dependencies here:
+group :development do
+ gem 'rake'
+
+ # Documentation:
+ gem 'yard'
+
+ # Testing libraries:
+ gem 'rspec'
+
+ # Colorful messages:
+ gem 'rainbow'
+
+ # Support for guard:
+ gem 'guard'
+ gem 'guard-bundler'
+ gem 'guard-rspec'
+ gem 'rb-fsevent'
+ gem 'rb-readline'
+ gem 'fuubar'
+end
View
13 Guardfile
@@ -0,0 +1,13 @@
+require 'rb-readline'
+
+guard 'bundler' do
+ watch('Gemfile')
+ watch('cheers.gemspec')
+end
+
+guard 'rspec', version: 2, cli: '--format Fuubar --colour' do
+ watch(%r{^spec/.+_spec\.rb})
+ watch(%r{^lib/(.+)\.rb}) { |m| "spec/#{m[1]}_spec.rb" }
+ watch(%r{lib/.+\.rb}) { "spec" }
+ watch('spec/spec_helper.rb') { "spec" }
+end
View
14 bin/cheers
@@ -0,0 +1,14 @@
+#!/usr/bin/env ruby
+
+$LOAD_PATH.push './lib'
+require 'cheers'
+
+filename = ARGV[0]
+
+unless filename
+ puts "Usage: cheers <filename>"
+ exit
+end
+
+avatar = Cheers::Avatar.new(rand(1000_000).to_s)
+avatar.avatar_file(filename)
View
20 lib/cheers.rb
@@ -2,6 +2,22 @@
module Cheers
autoload :VERSION, 'cheers/version'
- autoload :Color, 'cheers/color'
- autoload :Avatar, 'cheers/avatar'
+
+ autoload :Avatar, 'cheers/avatar'
+ autoload :Background, 'cheers/background'
+ autoload :Color, 'cheers/color'
+ autoload :Component, 'cheers/component'
+ autoload :ContrastingColorPicker, 'cheers/contrasting_color_picker'
+ autoload :Decoration, 'cheers/decoration'
+ autoload :Eyes, 'cheers/eyes'
+ autoload :Face, 'cheers/face'
+ autoload :ImageComponent, 'cheers/image_component'
+ autoload :LowerGlow, 'cheers/lower_glow'
+ autoload :Mouth, 'cheers/mouth'
+ autoload :Texture, 'cheers/texture'
+ autoload :UpperGlow, 'cheers/upper_glow'
+
+ def self.root
+ File.expand_path('../../', __FILE__)
+ end
end
View
140 lib/cheers/avatar.rb
@@ -4,39 +4,13 @@
module Cheers
class Avatar
- GEM_ROOT = File.expand_path('../../../', __FILE__)
- BACKGROUND_COLORS = ['#cccccc', '#dddddd', '#bbbbbb', '#F1A800', '#FEF0CC', '#fd4238', '#fff0f0', '#14899d', '#c3ecee', '#42991a', '#f0fff0']
- # SMILE_COLORS = ['#333', '#666', '#9e005d', '#ef8200', '#d8a129', '#db4640', '#0e788b', '#239340']
- SMILE_COLORS = ['#333333', '#666666', '#9e005d', '#ef8200', '#db4640', '#0e788b', '#239340']
- IMAGES = {
-
- smiles: [
- { smile: 'components/mouths/1-smile.png',
- smile_glow: 'components/mouths/1-smile-glow.png',
- bg_mask: 'components/mouths/1-bgmask.png',
- texture: 'components/texture.png' },
- { smile: 'components/mouths/2-smile.png',
- smile_glow: 'components/mouths/2-smile-glow.png',
- bg_mask: 'components/mouths/2-bgmask.png',
- texture: 'components/texture.png' },
- { smile: 'components/mouths/3-smile.png',
- smile_glow: 'components/mouths/3-smile-glow.png',
- bg_mask: 'components/mouths/3-bgmask.png',
- texture: 'components/texture.png' }
- ],
- eyes: [
- { eyes: 'components/eyes/1.png' },
- { eyes: 'components/eyes/2.png' },
- { eyes: 'components/eyes/3.png' },
- { eyes: 'components/eyes/4.png' },
- { eyes: 'components/eyes/5.png' }
- ],
- decorations: [
- { id: 1, decoration: 'components/decorations/1.png' },
- { id: 2, decoration: 'components/decorations/2.png' }
- ]
- }
+ BACKGROUND_COLORS = %w(#cccccc #dddddd #bbbbbb #f1a800 #fef0cc
+ #fd4238 #fff0f0 #14899d #c3ecee #42991a
+ #f0fff0)
+
+ COMPONENT_COLORS = %w(#333333 #666666 #9e005d #ef8200 #db4640
+ #0e788b #239340)
# Creates a new avatar from the seed string
def initialize(seed)
@@ -55,107 +29,15 @@ def avatar_file(file_path)
private
def compose_avatar #:nodoc:
- random_generator = Random.new(@seed)
-
- # 0. Let's get some random colors
- # We shoudn't change the order we call #rand to keep version changes minimal
- avatar_bg_color = BACKGROUND_COLORS.sample(random: random_generator)
- smile_components = IMAGES[:smiles].sample(random: random_generator)
- smile_bg_color = BACKGROUND_COLORS.sample(random: random_generator)
- # smile_color = SMILE_COLORS.sample(random: random_generator)
- # eyes_color = SMILE_COLORS.sample(random: random_generator)
- eyes_components = IMAGES[:eyes].sample(random: random_generator)
- smile_upper_glow_color = SMILE_COLORS.sample(random: random_generator)
- smile_lower_glow_color = SMILE_COLORS.sample(random: random_generator)
- has_decoration = [true, true, false].sample(random: random_generator)
- decoration_component = IMAGES[:decorations].sample(random: random_generator)
- decoration_color = BACKGROUND_COLORS.sample(random: random_generator)
-
- # Lets test if the color behind eyes is very similar to the eye color.
- # Generate a new eye color if that's the case.
- eyes_contrasting_color = if has_decoration and decoration_component[:id] == 1
- decoration_color
- else
- avatar_bg_color
- end
-
- # Lets not use the same random generator for generating unknown amount of new colors
- rng = Random.new(random_generator.rand(10000))
- begin
- eyes_color = SMILE_COLORS.sample(random: rng)
- end while Color.new(eyes_color).similar?(eyes_contrasting_color, 0.2)
-
- # Lets test if the background colors are very similar to the smile color.
- # Change the smile color if that's the case, right?
- rng = Random.new(random_generator.rand(10000))
- begin
- smile_color = SMILE_COLORS.sample(random: rng)
- the_smile_color = Color.new(smile_color)
- end while the_smile_color.similar?(avatar_bg_color, 0.2) or the_smile_color.similar?(smile_bg_color, 0.2)
-
-
- # 1. Lets create upper background
- upper_background = Magick::Image.new(512, 512) { self.background_color = avatar_bg_color }
-
- # This is smile glow mask
- smile_glow_image = Magick::Image.read(component_path(smile_components[:smile_glow]))[0]
-
- # Create smile glow layer and put it on upper background
- smile_upper_glow = Magick::Image.new(512, 512) { self.background_color = smile_upper_glow_color }
- upper_background.add_compose_mask(smile_glow_image)
- upper_background.composite!(smile_upper_glow, 0, 0, Magick::OverCompositeOp)
- upper_background.delete_compose_mask
+ generator = Random.new(@seed)
+ @avatar = Magick::Image.new(512, 512)
- # 2. Lets create lower background
- lower_background = Magick::Image.new(512, 512) { self.background_color = smile_bg_color }
-
- # Create another smile glow layer but put it on lower background
- smile_lower_glow = Magick::Image.new(512, 512) { self.background_color = smile_lower_glow_color }
- lower_background.add_compose_mask(smile_glow_image)
- lower_background.composite!(smile_lower_glow, 0, 0, Magick::OverCompositeOp)
- lower_background.delete_compose_mask
-
-
- # 3. Lets compose both backgrounds together
-
- # This will be the final avatar image.
- # Because we will draw the lower background over the upper background,
- # we can use the upper background as the starting image.
- avatar = upper_background
-
- # Lets mask and put the lower background on top of the image
- avatar.add_compose_mask(Magick::Image.read(component_path(smile_components[:bg_mask]))[0])
- avatar.composite!(lower_background, 0, 0, Magick::OverCompositeOp)
- avatar.delete_compose_mask
-
- # 4. Add decorations
- if has_decoration
- decoration = Magick::Image.new(512, 512) { self.background_color = decoration_color }
- avatar.add_compose_mask(Magick::Image.read(component_path(decoration_component[:decoration]))[0])
- avatar.composite!(decoration, 0, 0, Magick::OverCompositeOp)
- avatar.delete_compose_mask
+ [Background, Face, Decoration, Eyes].each do |klass|
+ klass.new(@avatar, generator).apply
end
- # 5. Add the texture
- texture = Magick::Image.read(component_path(smile_components[:texture]))[0]
- avatar.composite!(texture, 0, 0, Magick::OverCompositeOp)
-
- smile = Magick::Image.new(512, 512) { self.background_color = smile_color }
- avatar.add_compose_mask(Magick::Image.read(component_path(smile_components[:smile]))[0])
- avatar.composite!(smile, 0, 0, Magick::OverCompositeOp)
- avatar.delete_compose_mask
-
- eyes = Magick::Image.new(512, 512) { self.background_color = eyes_color }
- avatar.add_compose_mask(Magick::Image.read(component_path(eyes_components[:eyes]))[0])
- avatar.composite!(eyes, 0, 0, Magick::OverCompositeOp)
- avatar.delete_compose_mask
-
- @avatar = avatar
- end
-
- def component_path(asset) #:nodoc:
- [GEM_ROOT, asset].join('/')
+ @avatar
end
end
end
View
23 lib/cheers/background.rb
@@ -0,0 +1,23 @@
+module Cheers
+ class Background < Component
+
+ attr_reader :color
+
+ def initialize(canvas, randomizer)
+ super
+
+ @color = Avatar::BACKGROUND_COLORS.sample(random: randomizer)
+ end
+
+ def apply
+ # Work around instance_eval wonkiness by declaring local variables:
+ color = self.color
+
+ background = Magick::Image.new(512, 512) do
+ self.background_color = color
+ end
+
+ canvas.composite!(background, 0, 0, Magick::OverCompositeOp)
+ end
+ end
+end
View
8 lib/cheers/color.rb
@@ -14,7 +14,9 @@ def initialize(color = '#000000')
#
def to_s
- return '#' + r.to_s(16) + g.to_s(16) + b.to_s(16)
+ return '#' + r.to_s(16).rjust(2, '0') +
+ g.to_s(16).rjust(2, '0') +
+ b.to_s(16).rjust(2, '0')
end
def to_hsv
@@ -36,7 +38,7 @@ def to_hsv
[hue % 360, saturation, max]
end
- def similar?(other_color, threshold)
+ def similar?(other_color, threshold = 0.1)
other_color = Color.new(other_color) unless other_color.is_a? Color
color_hsv = to_hsv
@@ -54,4 +56,4 @@ def similar?(other_color, threshold)
end
end
-end
+end
View
12 lib/cheers/component.rb
@@ -0,0 +1,12 @@
+module Cheers
+ class Component
+
+ attr_reader :canvas, :randomizer
+
+ def initialize(canvas, randomizer)
+ @canvas = canvas
+ @randomizer = randomizer
+ end
+
+ end
+end
View
25 lib/cheers/contrasting_color_picker.rb
@@ -0,0 +1,25 @@
+module Cheers
+ class ContrastingColorPicker
+
+ MAX_RETRIES = 10
+
+ attr_reader :palette, :colors
+
+ def initialize(palette, *colors)
+ @palette = palette.map { |c| Color.new(c) }
+ @colors = colors.map { |c| Color.new(c) }
+ end
+
+ def pick(randomizer = Random.new)
+ pick = palette.sample(random: randomizer)
+
+ try = 0
+ while colors.any? { |c| c.similar?(pick) } && try <= MAX_RETRIES
+ try += 1
+ pick = palette.sample(random: randomizer)
+ end
+
+ pick.to_s
+ end
+ end
+end
View
35 lib/cheers/decoration.rb
@@ -0,0 +1,35 @@
+module Cheers
+ class Decoration < ImageComponent
+
+ IMAGES = %w( decorations/1.png
+ decorations/2.png )
+
+ attr_reader :color, :image
+
+ def initialize(canvas, color_randomizer, image_randomizer = nil)
+ super
+
+ @color = ContrastingColorPicker.new(Avatar::BACKGROUND_COLORS, canvas.background_color).pick
+ @image = IMAGES.sample random: self.image_randomizer
+ end
+
+ def apply?
+ [true, true, false].sample(random: image_randomizer)
+ end
+
+ def apply
+ return unless apply?
+
+ mask = Magick::Image.read(image_path(image))[0]
+ color = self.color
+
+ decoration = Magick::Image.new(512, 512) do
+ self.background_color = color
+ end
+
+ canvas.add_compose_mask(mask)
+ canvas.composite!(decoration, 0, 0, Magick::OverCompositeOp)
+ canvas.delete_compose_mask
+ end
+ end
+end
View
32 lib/cheers/eyes.rb
@@ -0,0 +1,32 @@
+module Cheers
+ class Eyes < ImageComponent
+
+ IMAGES = %w( eyes/1.png
+ eyes/2.png
+ eyes/3.png
+ eyes/4.png
+ eyes/5.png )
+
+ attr_reader :color, :image
+
+ def initialize(canvas, color_randomizer, image_randomizer = nil)
+ super
+
+ @color = ContrastingColorPicker.new(Avatar::COMPONENT_COLORS, canvas.background_color).pick
+ @image = IMAGES.sample random: self.image_randomizer
+ end
+
+ def apply
+ mask = Magick::Image.read(image_path(image))[0]
+ color = self.color
+
+ eyes = Magick::Image.new(512, 512) do
+ self.background_color = color
+ end
+
+ canvas.add_compose_mask(mask)
+ canvas.composite!(eyes, 0, 0, Magick::OverCompositeOp)
+ canvas.delete_compose_mask
+ end
+ end
+end
View
11 lib/cheers/face.rb
@@ -0,0 +1,11 @@
+module Cheers
+ class Face < ImageComponent
+
+ def apply
+ [UpperGlow, LowerGlow, Texture, Mouth].each do |klass|
+ klass.new(canvas, color_randomizer, image_randomizer.dup).apply
+ end
+ end
+
+ end
+end
View
18 lib/cheers/image_component.rb
@@ -0,0 +1,18 @@
+module Cheers
+ class ImageComponent
+
+ attr_reader :canvas, :color_randomizer, :image_randomizer
+
+ def initialize(canvas, color_randomizer, image_randomizer = nil)
+ @canvas = canvas
+ @color_randomizer = color_randomizer
+ @image_randomizer = image_randomizer || color_randomizer
+ end
+
+ private
+
+ def image_path(component)
+ [Cheers.root, 'components', component].join '/'
+ end
+ end
+end
View
50 lib/cheers/lower_glow.rb
@@ -0,0 +1,50 @@
+module Cheers
+ class LowerGlow < ImageComponent
+
+ GLOW_IMAGES = %w( mouths/1-smile-glow.png
+ mouths/2-smile-glow.png
+ mouths/3-smile-glow.png )
+
+ MASK_IMAGES = %w( mouths/1-bgmask.png
+ mouths/2-bgmask.png
+ mouths/3-bgmask.png )
+
+ attr_reader :background_color, :glow_color, :glow_image, :mask_image
+
+ def initialize(canvas, color_randomizer, element_randomizer = nil)
+ super
+
+ @background_color = ContrastingColorPicker.new(Avatar::BACKGROUND_COLORS, canvas.background_color).pick
+ @glow_color = ContrastingColorPicker.new(Avatar::COMPONENT_COLORS, canvas.background_color, background_color).pick
+ @glow_image = GLOW_IMAGES.sample random: element_randomizer.dup
+ @mask_image = MASK_IMAGES.sample random: element_randomizer.dup
+ end
+
+ def apply
+ glow = Magick::Image.read(image_path(glow_image))[0]
+ mask = Magick::Image.read(image_path(mask_image))[0]
+
+ # Work around instance_eval wonkiness by declaring local variables:
+ glow_color = self.glow_color
+ background_color = self.background_color
+
+ # 2. Lets create lower background
+ background = Magick::Image.new(512, 512) do
+ self.background_color = background_color
+ end
+
+ # Create another smile glow layer but put it on lower background
+ glow_background = Magick::Image.new(512, 512) do
+ self.background_color = glow_color
+ end
+
+ background.add_compose_mask(glow)
+ background.composite!(glow_background, 0, 0, Magick::OverCompositeOp)
+ background.delete_compose_mask
+
+ canvas.add_compose_mask(mask)
+ canvas.composite!(background, 0, 0, Magick::OverCompositeOp)
+ canvas.delete_compose_mask
+ end
+ end
+end
View
30 lib/cheers/mouth.rb
@@ -0,0 +1,30 @@
+module Cheers
+ class Mouth < ImageComponent
+
+ IMAGES = %w( mouths/1-smile.png
+ mouths/2-smile.png
+ mouths/3-smile.png )
+
+ attr_reader :color, :image
+
+ def initialize(canvas, color_randomizer, element_randomizer = nil)
+ super
+
+ @color = ContrastingColorPicker.new(Avatar::COMPONENT_COLORS, canvas.background_color).pick
+ @image = IMAGES.sample random: element_randomizer
+ end
+
+ def apply
+ color = self.color
+ smile = Magick::Image.new(512, 512) do
+ self.background_color = color
+ end
+
+ mask = Magick::Image.read(image_path(image))[0]
+
+ canvas.add_compose_mask(mask)
+ canvas.composite!(smile, 0, 0, Magick::OverCompositeOp)
+ canvas.delete_compose_mask
+ end
+ end
+end
View
19 lib/cheers/texture.rb
@@ -0,0 +1,19 @@
+module Cheers
+ class Texture < ImageComponent
+
+ IMAGES = %w( texture.png )
+
+ attr_reader :color, :image
+
+ def initialize(canvas, color_randomizer, element_randomizer = nil)
+ super
+
+ @image = IMAGES.sample random: element_randomizer
+ end
+
+ def apply
+ texture = Magick::Image.read(image_path(image))[0]
+ canvas.composite!(texture, 0, 0, Magick::OverCompositeOp)
+ end
+ end
+end
View
30 lib/cheers/upper_glow.rb
@@ -0,0 +1,30 @@
+module Cheers
+ class UpperGlow < ImageComponent
+
+ IMAGES = %w( mouths/1-smile-glow.png
+ mouths/2-smile-glow.png
+ mouths/3-smile-glow.png )
+
+ attr_reader :color, :image
+
+ def initialize(canvas, color_randomizer, element_randomizer = nil)
+ super
+
+ @color = ContrastingColorPicker.new(Avatar::COMPONENT_COLORS, canvas.background_color).pick
+ @image = IMAGES.sample random: element_randomizer
+ end
+
+ def apply
+ color = self.color
+ glow = Magick::Image.new(512, 512) do
+ self.background_color = color
+ end
+
+ mask = Magick::Image.read(image_path(image))[0]
+
+ canvas.add_compose_mask(mask)
+ canvas.composite!(glow, 0, 0, Magick::OverCompositeOp)
+ canvas.delete_compose_mask
+ end
+ end
+end
View
96 spec/cheers/color_spec.rb
@@ -0,0 +1,96 @@
+require 'spec_helper'
+
+describe Cheers::Color do
+ describe '#initialize' do
+ it 'converts 32 bit hexadecimal color values to RGB' do
+ color = Cheers::Color.new('#7d7d7d')
+ [color.r, color.g, color.b].should == [125, 125, 125]
+ end
+ end
+
+ describe '#r' do
+ it 'returns the intensity of the red component of the color' do
+ black = Cheers::Color.new '#000000'
+ black.r.should == 0
+
+
+ white = Cheers::Color.new '#ffffff'
+ white.r.should == 255
+
+ red = Cheers::Color.new '#7d0000'
+ red.r.should == 125
+ end
+ end
+
+ describe '#g' do
+ it 'returns the intensity of the green component of the color' do
+ black = Cheers::Color.new '#000000'
+ black.g.should == 0
+
+
+ white = Cheers::Color.new '#ffffff'
+ white.g.should == 255
+
+ green = Cheers::Color.new '#007d00'
+ green.g.should == 125
+ end
+ end
+
+ describe '#b' do
+ it 'returns the intensity of the blue component of the color' do
+ black = Cheers::Color.new '#000000'
+ black.b.should == 0
+
+
+ white = Cheers::Color.new '#ffffff'
+ white.b.should == 255
+
+ blue = Cheers::Color.new '#00007d'
+ blue.b.should == 125
+ end
+ end
+
+ describe '#to_hsv' do
+ it 'returns the HSV values for the color' do
+ orange = Cheers::Color.new '#d97621'
+ h, s, v = orange.to_hsv
+
+ h.should be_within(0.001).of 27.717
+ s.should be_within(0.001).of 0.848
+ v.should be_within(0.001).of 0.851
+ end
+ end
+
+ describe '#to_s' do
+ it 'returns a hexadecimal representation of the color' do
+ color = Cheers::Color.new('#00007d')
+ color.to_s.should == '#00007d'
+ end
+ end
+
+ describe '#similar?' do
+ it 'returns true if the colors are similar' do
+ bright_white = Cheers::Color.new '#ffffff'
+ broken_white = Cheers::Color.new '#eeeeee'
+
+ bright_white.similar?(broken_white).should be_true
+ broken_white.similar?(bright_white).should be_true
+ end
+
+ it 'returns false if the colors are not similar' do
+ white = Cheers::Color.new '#ffffff'
+ black = Cheers::Color.new '#000000'
+
+ white.similar?(black).should be_false
+ black.similar?(white).should be_false
+ end
+
+ it 'returns true if the color is too similar for the given treshold' do
+ orange_1 = Cheers::Color.new '#f1a800'
+ orange_2 = Cheers::Color.new '#ef8200'
+
+ orange_1.similar?(orange_2, 0.02).should be_false
+ orange_1.similar?(orange_2, 0.03).should be_true
+ end
+ end
+end
View
15 spec/spec_helper.rb
@@ -0,0 +1,15 @@
+require 'rubygems'
+require 'bundler/setup'
+
+require File.expand_path('../../lib/cheers', __FILE__)
+
+# Requires supporting files with custom matchers and macros, etc,
+# in ./support/ and its subdirectories.
+Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each { |f| require f }
+
+RSpec.configure do |config|
+ config.treat_symbols_as_metadata_keys_with_true_values = true
+ config.run_all_when_everything_filtered = true
+ config.filter_run :focus
+ config.mock_with :rspec
+end
Something went wrong with that request. Please try again.