Skip to content

Commit

Permalink
Specs and dummy app
Browse files Browse the repository at this point in the history
  • Loading branch information
rsantamaria committed Aug 15, 2012
1 parent d53d606 commit 4434dfb
Show file tree
Hide file tree
Showing 71 changed files with 1,080 additions and 39 deletions.
10 changes: 10 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1 +1,11 @@
.rvmrc
.sass-cache
*.gem
*.swp
**/*.swp
Gemfile.lock
test_app/.bundle
test_app/Gemfile.lock
test_app/db/*.sqlite3
test_app/log/*.log
test_app/tmp
1 change: 1 addition & 0 deletions .rspec
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
--color
4 changes: 4 additions & 0 deletions Gemfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
source 'http://rubygems.org'

gemspec

11 changes: 8 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,14 +38,19 @@ On the controller you can render a view after user creation, create a simple cro
<%= f.submit 'Save' %>
<% end %>

Both helpers accept a :width option to customize their dimensions. The preview box has width 100 by default but the cropbox is unlimited in size (takes the original image width), so setting the cropbox width is interesting to avoid layout breaking with huge images.
Both helpers accept a :width option to customize their dimensions. The preview box has width 100 by default but the cropbox is unlimited in size (takes the original image width), so setting the cropbox width is interesting to avoid layout breaks with huge images.

<%= form_for @user do |f| %>
<%= f.cropbox :avatar, :width => 500 %>
<%= f.crop_preview :avatar, :width => 150 %>
<%= f.submit 'Save' %>
<% end %>

Regardless of the width passed, the preview box and the cropping area will have the aspect ratio defined in the model (1:1 by default)
Regardless of the width, the preview box and the cropping area will have the aspect ratio defined in the model (1:1 by default)

That's all!
That's all!

#### Credits and resources
* [Thoughtbot's Paperclip](https://github.com/thoughtbot/paperclip/)
* [Deep Liquid's JCrop](http://deepliquid.com/content/Jcrop.html)
* And Ryan Bates' [Railscast#182](http://railscasts.com/episodes/182-cropping-images/), which has inspired this gem
8 changes: 8 additions & 0 deletions Rakefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
require 'bundler'
Bundler::GemHelper.install_tasks

require 'rspec/core'
require 'rspec/core/rake_task'
RSpec::Core::RakeTask.new(:spec)

task :default => :spec
4 changes: 3 additions & 1 deletion lib/assets/javascripts/papercrop.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
var jcrop_api;

(function() {
$(document).ready(function() {
$('div[id$=_cropbox]').each(function() {
Expand Down Expand Up @@ -35,7 +37,7 @@
setSelect : [0, 0, 500, 500],
aspectRatio : aspect,
boxWidth : $("input[id$='_" + attachment + "_box_w']").val()
});
}, function(){ jcrop_api = this; });
});
});
}).call(this);
4 changes: 2 additions & 2 deletions lib/papercrop/active_record_extension.rb
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,6 @@ def crop_attached_file(attachment_name, opts = {})

after_update :"reprocess_to_crop_#{attachment_name}_attachment"
end

end


Expand All @@ -66,6 +65,7 @@ def image_geometry(attachment_name, style = :original)
end


# Uses method missing to reprocess the attachment callback
def method_missing(method, *args)
if method.to_s =~ /(reprocess_to_crop_)(\S{1,})(_attachment)/
reprocess_cropped_attachment(
Expand All @@ -80,7 +80,7 @@ def method_missing(method, *args)

# Reprocess the attachment after cropping
def reprocess_cropped_attachment(attachment_name)
self.send(attachment_name.to_sym).reprocess! if cropping? attachment_name
self.send(attachment_name.to_sym).reprocess! if cropping?(attachment_name)
end

end
Expand Down
29 changes: 0 additions & 29 deletions lib/papercrop/controller_extension.rb

This file was deleted.

15 changes: 11 additions & 4 deletions papercrop.gemspec
Original file line number Diff line number Diff line change
@@ -1,18 +1,25 @@

Gem::Specification.new do |s|
s.name = 'papercrop'
s.version = '0.0.2'
s.version = '0.0.5'
s.date = '2012-08-12'
s.summary = "Paperclip extension for cropping images"
s.description = "Paperclip extension for cropping images"
s.description = "An easy extension for Paperclip to crop your image uploads using jCrop"
s.authors = ["Ruben Santamaria"]
s.email = '[email protected]'
s.homepage = 'https://github.com/rsantamaria/papercrop'

s.files = Dir.glob("{lib,vendor}/**/*") + %w(README.md)
s.test_files = Dir.glob("{spec}/**/*")
s.require_paths = ["lib"]

s.add_dependency "rails", "~> 3.1"
s.add_dependency "rails", ">= 3.1"
s.add_dependency "jquery-rails"
s.add_dependency "paperclip", "~> 3.1"
s.add_dependency "paperclip", ">= 3.1"

s.add_development_dependency "rspec-rails", "~> 2.0"
s.add_development_dependency "capybara", ">= 1.1.1"
s.add_development_dependency "rmagick"
s.add_development_dependency "sass"
s.add_development_dependency "sqlite3"
end
29 changes: 29 additions & 0 deletions spec/integration/papercrop_js_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
require "spec_helper"

describe "Image crop with JS", :js => true do

after do
Landscape.destroy_all
end


it "crops an image with javascript" do
visit landscapes_path

click_link "New Landscape"

fill_in "Name", :with => "Mountains"
find("#landscape_picture").native.send_keys(File.expand_path("../../../test_app/test/fixtures/matterhorn.jpg", __FILE__))
click_button "Create Landscape"

sleep 2
page.execute_script("jcrop_api.setSelect([300, 200, 700, 500])")
page.execute_script('if ($("#picture_crop_y").val() == "199"){$("#picture_crop_y").val("200")}')
page.execute_script('if ($("#picture_crop_w").val() == "399"){$("#picture_crop_w").val("400")}')

click_button "Crop image"

sleep 1
compare_images(CROPPED_IMG_PATH, Landscape.last.picture.path(:medium)).should eq(0.0)
end
end
39 changes: 39 additions & 0 deletions spec/integration/papercrop_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
require "spec_helper"

describe "Image crop" do

after do
Landscape.destroy_all
end


it "crops an image" do
visit landscapes_path

click_link "New Landscape"

fill_in "Name", :with => "Mountains"
attach_file "Picture", "test_app/test/fixtures/matterhorn.jpg"
click_button "Create Landscape"

page.should have_css("#picture_crop_preview_wrapper")
page.should have_css("#picture_crop_preview")
page.should have_css("#picture_cropbox")

page.should have_css("#landscape_picture_original_w")

find("#landscape_picture_original_w").value.should eq("1024.0")
find("#landscape_picture_original_h").value.should eq("768.0")
find("#landscape_picture_box_w").value.should eq("600")
find("#picture_aspect").value.should eq((4.0 / 3.0).to_s)

find("#picture_crop_x").set "300.0"
find("#picture_crop_y").set "200.0"
find("#picture_crop_w").set "400"
find("#picture_crop_h").set "300"

click_button "Crop image"

compare_images(CROPPED_IMG_PATH, Landscape.last.picture.path(:medium)).should eq(0.0)
end
end
64 changes: 64 additions & 0 deletions spec/model_extensions/active_record_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
require "spec_helper"

describe "Active Record Extension" do

before do
@landscape = Landscape.new(:name => "Mountains")
@landscape.picture = open("test_app/test/fixtures/matterhorn.jpg")
@landscape.save
end


after do
@landscape.destroy
end


it "includes accessors to the model" do
%w{crop_x crop_y crop_w crop_h original_w original_h box_w aspect}.each do |m|
@landscape.should respond_to(:"picture_#{m}")
@landscape.should respond_to(:"picture_#{m}=")
end
end


it "registers the post processor" do
@landscape.attachment_definitions[:picture][:processors].should eq([:cropper])
end


it "defines an after update callback" do
@landscape._update_callbacks.map do |e|
e.instance_values['filter'].should eq(:reprocess_to_crop_picture_attachment)
end
end


it "returns image properties" do
@landscape.picture_aspect.should eq(4.0 / 3.0)

@landscape.image_geometry(:picture).width.should eq(1024.0)
@landscape.image_geometry(:picture).height.should eq(768.0)
end


it "knows when to crop" do
@landscape.cropping?(:picture).should be(false)
@landscape.picture_crop_x = 0.0
@landscape.picture_crop_y = 0.0
@landscape.picture_crop_w = 400
@landscape.picture_crop_h = 300
@landscape.cropping?(:picture).should be(true)
end


it "crops images" do
@landscape.picture_crop_x = 300.0
@landscape.picture_crop_y = 200.0
@landscape.picture_crop_w = 400
@landscape.picture_crop_h = 300
@landscape.save

compare_images(CROPPED_IMG_PATH, @landscape.picture.path(:medium)).should eq(0.0)
end
end
41 changes: 41 additions & 0 deletions spec/spec_helper.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
# This file is copied to spec/ when you run 'rails generate rspec:install'
ENV["RAILS_ENV"] = 'test'
require File.expand_path("../../test_app/config/environment", __FILE__)
require 'rspec/rails'
require 'rspec/autorun'

# Requires supporting ruby files with custom matchers and macros, etc,
# in spec/support/ and its subdirectories.
Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each {|f| require f}

# Previously cropped image. Used for comparing test cropped images with RMagick
CROPPED_IMG_PATH = "test_app/test/fixtures/test_img.jpg"

RSpec.configure do |config|
# ## Mock Framework
#
# If you prefer to use mocha, flexmock or RR, uncomment the appropriate line:
#
# config.mock_with :mocha
# config.mock_with :flexmock
# config.mock_with :rr

# Remove this line if you're not using ActiveRecord or ActiveRecord fixtures
config.fixture_path = "#{::Rails.root}/spec/fixtures"

# If you're not using ActiveRecord, or you'd prefer not to run each of your
# examples within a transaction, remove the following line or assign false
# instead of true.
config.use_transactional_fixtures = true

# If true, the base class of anonymous controllers will be inferred
# automatically. This will be the default behavior in future versions of
# rspec-rails.
config.infer_base_class_for_anonymous_controllers = false

# 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.
# --seed 1234
config.order = "random"
end
8 changes: 8 additions & 0 deletions spec/support/compare_images.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
require "RMagick"

def compare_images(test_image_path, cropped_image_path)
test_img = Magick::Image::read(test_image_path).first
target_img = Magick::Image::read(cropped_image_path).first

test_img.compare_channel(target_img, Magick::MeanAbsoluteErrorMetric).second
end
17 changes: 17 additions & 0 deletions test_app/Gemfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
source 'https://rubygems.org'

gem 'rails', '3.2.8'

gem 'jquery-rails'
gem 'execjs'
gem 'therubyracer'
gem 'sqlite3'
gem 'paperclip'

gem 'papercrop', :path => ".."

group :assets do
gem 'sass-rails', '~> 3.2.3'
gem 'coffee-rails', '~> 3.2.1'
gem 'uglifier', '>= 1.0.3'
end
7 changes: 7 additions & 0 deletions test_app/Rakefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
#!/usr/bin/env rake
# Add your own tasks in files placed in lib/tasks ending in .rake,
# for example lib/tasks/capistrano.rake, and they will automatically be available to Rake.

require File.expand_path('../config/application', __FILE__)

TestApp::Application.load_tasks
Empty file.
17 changes: 17 additions & 0 deletions test_app/app/assets/javascripts/application.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
// This is a manifest file that'll be compiled into application.js, which will include all the files
// listed below.
//
// Any JavaScript/Coffee file within this directory, lib/assets/javascripts, vendor/assets/javascripts,
// or vendor/assets/javascripts of plugins, if any, can be referenced here using a relative path.
//
// It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the
// the compiled file.
//
// WARNING: THE FIRST BLANK LINE MARKS THE END OF WHAT'S TO BE PROCESSED, ANY BLANK LINE SHOULD
// GO AFTER THE REQUIRES BELOW.
//
//= require jquery
//= require jquery_ujs
//= require jquery.jcrop
//= require papercrop
//= require_tree .
Loading

0 comments on commit 4434dfb

Please sign in to comment.