ecart 0.0.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.
@@ -0,0 +1,6 @@
1
+ *.gem
2
+ .bundle
3
+ Gemfile.lock
4
+ pkg/*
5
+ .DS_Store
6
+ lib/.DS_Store
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --color
2
+ --format progress
@@ -0,0 +1,5 @@
1
+ language: ruby
2
+ rvm:
3
+ - 1.8.7
4
+ - 1.9.2
5
+ - 1.9.3
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in ecart.gemspec
4
+ gemspec
@@ -0,0 +1,102 @@
1
+ # Ecart for Rails 3.0 - An e-commerce cart
2
+ Ecart is a simple solution for integrating a cart when you are building
3
+ an online store from scratch, and want to add this functionality
4
+
5
+ Ecart project integrates a cart to a rails app
6
+
7
+ [![Build Status](https://secure.travis-ci.org/kurenn/ecart.png?branch=master)](http://travis-ci.org/kurenn/ecart)
8
+
9
+ ## Installing Gem
10
+
11
+ Include Ecart in Gemfile;
12
+
13
+ ```ruby
14
+ gem "ecart"
15
+ ```
16
+
17
+ or you can install from latest build;
18
+
19
+ ```ruby
20
+ gem 'ecart', :git => 'git@github.com:kurenn/ecart.git'
21
+ ```
22
+
23
+ You can run bundle from command line
24
+
25
+ bundle install
26
+
27
+ ## Before installing
28
+
29
+ I'm assuming you have a Product model on your rails app, but don't worry
30
+ if that's not the case you can customize it as you like
31
+
32
+ ## Installing to App (using Generators)
33
+
34
+ You can run following generators to get started with Ecart quickly.
35
+
36
+
37
+ Install
38
+
39
+
40
+ Usage:
41
+
42
+
43
+ rails g ecart:install
44
+
45
+ This will generate several files that will handle all the cart logic
46
+ (which you can customize later)
47
+
48
+ ## Don't forget to let know rails to load the lib directory
49
+
50
+ You can do so in the config/application.rb file
51
+
52
+ ```ruby
53
+ config.autoload_paths += Dir["#{config.root}/lib", "#{config.root}/lib/**/"]
54
+ ```
55
+
56
+ ## Changelog
57
+ <ul>
58
+ <li>Current gem v.0.0.1</li>
59
+ </ul>
60
+
61
+
62
+ ## Contributors & Patches & Forks
63
+ <ul>
64
+ <li>Abraham Kuri Vargas (@kurenn)</li>
65
+ </ul>
66
+
67
+
68
+ ## Future
69
+ <ul>
70
+ <li>Add dinamic association with a model</li>
71
+ <li>Update the price by fetching from DB</li>
72
+ <li>Provide views for the cart</li>
73
+ </ul>
74
+
75
+
76
+ ## Credits
77
+ Abraham Kuri - kurenn@icalialabs.com
78
+
79
+ [Add Me On Twitter](http://twitter.com/kurenn "Follow me")
80
+
81
+ [Add Me On Linkedin](http://www.linkedin.com/pub/abraham-kuri/26/a21/b41 "Add Me On Linkedin")
82
+
83
+ [Add Me On Facebook](https://www.facebook.com/kurenn "Add Me On Facebook")
84
+
85
+
86
+ ## Score me
87
+ <img src="https://addons.opera.com/media/extensions/55/14355/1.0.1-rev1/icons/icon_64x64.png"></img>
88
+
89
+ You can +K my influence in Ruby on Rails on @klout
90
+
91
+ http://klout.com/#/kurenn
92
+
93
+
94
+ ## License
95
+ Copyright (c) 2011 Abraham Kuri Vargas
96
+
97
+ This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
98
+
99
+ This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
100
+
101
+ You should have received a copy of the GNU General Public License along with this program. If not, see http://www.gnu.org/licenses/gpl.html.
102
+
@@ -0,0 +1,17 @@
1
+ #!/usr/bin/env rake
2
+ require "bundler"
3
+
4
+ Bundler::GemHelper.install_tasks
5
+
6
+ desc "Bundle the gem"
7
+
8
+ task :bundle do
9
+ sh('bundle install')
10
+ sh 'gem build *.gemspec'
11
+ sh 'gem install *.gem'
12
+ sh 'rm *.gem'
13
+ end
14
+
15
+ task(:default).clear
16
+ task :default => :bundle
17
+
@@ -0,0 +1,25 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "ecart/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "ecart"
7
+ s.version = Ecart::VERSION
8
+ s.authors = ["Abraham Kuri"]
9
+ s.email = ["kurenn@icalialabs.com"]
10
+ s.homepage = "https://github.com/kurenn/ecart"
11
+ s.summary = %q{E-commerce cart with rails}
12
+ s.description = %q{Setup a fully functional e-commerce cart}
13
+
14
+ s.rubyforge_project = "ecart"
15
+
16
+ s.files = `git ls-files`.split("\n")
17
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
18
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
19
+ s.require_paths = ["lib"]
20
+
21
+ # specify any dependencies here; for example:
22
+ s.add_development_dependency 'rails', '>= 3.1'
23
+ s.add_development_dependency "rspec"
24
+ # s.add_runtime_dependency "rest-client"
25
+ end
@@ -0,0 +1,55 @@
1
+ class Cart
2
+ attr_reader :cart_items
3
+
4
+ def initialize
5
+ @cart_items = []
6
+ end
7
+
8
+ def add_item(item)
9
+ cart_item = find_item(item)
10
+ if !cart_item.nil?
11
+ cart_item.increment_quantity
12
+ else
13
+ @cart_items << CartItem.new(item)
14
+ end
15
+ end
16
+
17
+ def items
18
+ @cart_items.map(&:item)
19
+ end
20
+
21
+ def find_item(item)
22
+ @cart_items.find {|cart_item| cart_item.item.id == item.id }
23
+ end
24
+
25
+ def total
26
+ total = 0.0
27
+ @cart_items.each do |cart_item|
28
+ total += (cart_item.item.price * cart_item.quantity)
29
+ end
30
+ total
31
+ end
32
+
33
+ def total_items
34
+ @cart_items.map(&:quantity).inject{|sum, q| sum + q}.to_i
35
+ end
36
+
37
+ def remove_item(item)
38
+ cart_item = find_item(item)
39
+ if cart_item.quantity > 1
40
+ cart_item.decrease_quantity
41
+ else
42
+ @cart_items.delete_if {|ci| ci == cart_item}
43
+ end
44
+ end
45
+
46
+ def remove_item!(item)
47
+ cart_item = find_item(item)
48
+ @cart_items.delete_if { |ci| ci == cart_item }
49
+ end
50
+
51
+ def empty?
52
+ self.total_items.zero?
53
+ end
54
+
55
+ end
@@ -0,0 +1,16 @@
1
+ class CartItem
2
+ attr_reader :item, :quantity
3
+
4
+ def initialize(item)
5
+ @item = item
6
+ @quantity = 1
7
+ end
8
+
9
+ def increment_quantity
10
+ @quantity += 1
11
+ end
12
+
13
+ def decrease_quantity
14
+ @quantity -= 1
15
+ end
16
+ end
@@ -0,0 +1,4 @@
1
+ require "ecart/version"
2
+
3
+ module Ecart
4
+ end
@@ -0,0 +1,3 @@
1
+ module Ecart
2
+ VERSION = "0.0.1"
3
+ end
@@ -0,0 +1,34 @@
1
+ require 'rails/generators'
2
+
3
+ module Ecart
4
+ module Generators
5
+ class InstallGenerator < ::Rails::Generators::Base
6
+ source_root File.expand_path("../../../../../lib", __FILE__)
7
+
8
+ desc 'This generator install the class cart and cartitem to the lib directory of a rails app'
9
+
10
+ def add_ecart
11
+ copy_file 'cart.rb', 'lib/cart.rb'
12
+ copy_file 'cart_item.rb', 'lib/cart_item.rb'
13
+ copy_file 'generators/templates/cart_helper.rb', 'app/helpers/cart_helper.rb'
14
+ copy_file 'generators/templates/cart_controller.rb', 'app/controllers/cart_controller.rb'
15
+ end
16
+
17
+ def add_ecart_routes
18
+ app = ::Rails.application
19
+ @app_name = app.class.to_s.split("::").first
20
+ insert_into_file 'config/routes.rb', routes, :after => "#{@app_name}::Application.routes.draw do"
21
+ insert_into_file 'app/controllers/application_controller.rb', "\n\tinclude CartHelper", :after => 'protect_from_forgery'
22
+ end
23
+
24
+ def routes
25
+ <<CONTENT
26
+
27
+ match 'add_to_cart/:id' => 'cart#add_to_cart', :as => :add_to_cart
28
+ match 'remove_from_cart/:id' => 'cart#remove_from_cart', :as => :remove_from_cart
29
+ match 'empty_cart' => 'cart#empty', :as => :empty_cart
30
+ CONTENT
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,21 @@
1
+ class CartController < ApplicationController
2
+
3
+ def add_to_cart
4
+ product = Product.find(params[:id])
5
+ @cart = find_cart
6
+ @cart.add_item(product)
7
+ redirect_to :back
8
+ end
9
+
10
+ def remove_from_cart
11
+ product = Product.find(params[:id])
12
+ @cart = find_cart
13
+ @cart.remove_item(product)
14
+ redirect_to :back
15
+ end
16
+
17
+ def empty
18
+ empty_cart
19
+ end
20
+
21
+ end
@@ -0,0 +1,35 @@
1
+ module CartHelper
2
+
3
+ #Find the cart
4
+ def find_cart
5
+ session[:cart] ||= Cart.new
6
+ end
7
+
8
+ #Cleans up the cart
9
+ def empty_cart
10
+ session[:cart] = nil
11
+ flash[:notice] = "Your cart is empty"
12
+ redirect_to :back
13
+ end
14
+
15
+ #Link to empty the cart
16
+ def link_to_empty_cart
17
+ link_to "Empty the car", empty_cart_path
18
+ end
19
+
20
+ #Link to add to cart
21
+ def link_to_add_to_cart(product)
22
+ link_to "Add to cart", add_to_cart_path(product.id)
23
+ end
24
+
25
+ #Link to remove from cart
26
+ def link_to_remove_from_cart(product)
27
+ link_to "Remove from cart", remove_from_cart_path(product.id) if find_cart.find_item(product)
28
+ end
29
+
30
+ #Returns the cart
31
+ def cart
32
+ find_cart
33
+ end
34
+ end
35
+
@@ -0,0 +1,10 @@
1
+ class Item
2
+ attr_accessor :id, :name, :price
3
+
4
+ def initialize(attr = {})
5
+ @id = attr[:id]
6
+ @price = attr[:price]
7
+ @name = attr[:name]
8
+ end
9
+ end
10
+
@@ -0,0 +1,127 @@
1
+ require 'spec_helper'
2
+ require 'cart'
3
+ require 'item'
4
+ require 'cart_item'
5
+
6
+
7
+ describe Cart do
8
+ let(:cart) { Cart.new }
9
+
10
+ it 'should initialize with an empty array of items' do
11
+ cart.items.should == []
12
+ end
13
+
14
+ describe '#add_item' do
15
+ it 'should add the id of the item to the cart' do
16
+ item = Item.new({:id => 1})
17
+ cart.add_item(item)
18
+ cart.items.should include(item)
19
+ end
20
+
21
+ it 'should increment the quantity of the item if it exists' do
22
+ item = Item.new({:id => 1})
23
+ other_item = Item.new({:id => 1})
24
+ cart.add_item(item)
25
+ cart.add_item(other_item)
26
+ cart.cart_items.first.quantity.should == 2
27
+ end
28
+ end
29
+
30
+ describe '#find_item' do
31
+ it 'should return nil if no object found' do
32
+ item = Item.new({:id => 1})
33
+ cart.find_item(item).should be_nil
34
+ end
35
+
36
+ it 'should return the cart item when item is found' do
37
+ item = Item.new({:id => 1})
38
+ cart.add_item(item)
39
+ cart.find_item(item).should_not be_nil
40
+ end
41
+ end
42
+
43
+ describe '#total' do
44
+ it 'should return 0.0 when no cart items' do
45
+ cart.total.should == 0.0
46
+ end
47
+
48
+ it 'should return the total of the cart' do
49
+ cart.add_item(Item.new({:id => 1, :price => 12.5, :name => "Ball"}))
50
+ cart.add_item(Item.new({:id => 2, :price => 10, :name => "Soccer ball"}))
51
+ cart.add_item(Item.new({:id => 2}))
52
+ cart.total.should == 32.5
53
+ end
54
+ end
55
+
56
+ describe '#remove_item' do
57
+ it 'removes the item from the cart' do
58
+ item = Item.new({:id => 1})
59
+ cart.add_item(item)
60
+ cart.remove_item(item)
61
+ cart.items.should_not include(item)
62
+ end
63
+
64
+ it 'should decrease the quantity of the cart_item' do
65
+ item = Item.new({:id => 2, :price => 10, :name => "Soccer ball"})
66
+ cart.add_item(item)
67
+ cart.add_item(item)
68
+ cart.remove_item(item)
69
+ cart.items.should include(item)
70
+ cart.find_item(item).quantity.should == 1
71
+ end
72
+
73
+ it 'should delete the item when there is just one' do
74
+ item = Item.new({:id => 2, :price => 10, :name => "Soccer ball"})
75
+ cart.add_item(item)
76
+ cart.remove_item(item)
77
+ cart.items.should_not include(item)
78
+ end
79
+ end
80
+
81
+ describe '#remove_item!' do
82
+
83
+ it 'should remove the item no matter what' do
84
+ item = Item.new({:id => 1})
85
+ cart.add_item(item)
86
+ cart.add_item(item)
87
+ cart.remove_item!(item)
88
+ cart.items.should_not include(item)
89
+ end
90
+
91
+ it 'should remove only if the cart item is in the cart' do
92
+ item = Item.new({:id => 1})
93
+ cart.remove_item!(item).should be_empty
94
+ end
95
+ end
96
+
97
+ describe '#total_items' do
98
+
99
+ it 'should return the total number of items in the cart' do
100
+ item = Item.new({:id => 1})
101
+ other_item = Item.new({:id => 2})
102
+ cart.add_item(item)
103
+ cart.add_item(other_item)
104
+ cart.add_item(item)
105
+ cart.total_items.should == 3
106
+ end
107
+
108
+ it 'should return 0 if no items in the cart' do
109
+ cart.total_items.should == 0
110
+ end
111
+ end
112
+
113
+ describe '#empty?' do
114
+
115
+ it 'should return true if cart is empty' do
116
+ cart.should be_empty
117
+ end
118
+
119
+ it 'should return false if the cart is not empty' do
120
+ item = Item.new({:id => 1})
121
+ cart.add_item(item)
122
+ cart.should_not be_empty
123
+ end
124
+ end
125
+
126
+ end
127
+
@@ -0,0 +1,17 @@
1
+ # This file was generated by the `rspec --init` command. Conventionally, all
2
+ # specs live under a `spec` directory, which RSpec adds to the `$LOAD_PATH`.
3
+ # Require this file using `require "spec_helper"` to ensure that it is only
4
+ # loaded once.
5
+ #
6
+ # See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
7
+ RSpec.configure do |config|
8
+ config.treat_symbols_as_metadata_keys_with_true_values = true
9
+ config.run_all_when_everything_filtered = true
10
+ config.filter_run :focus
11
+
12
+ # Run specs in random order to surface order dependencies. If you find an
13
+ # order dependency and want to debug it, you can fix the order by providing
14
+ # the seed, which is printed after each run.
15
+ # --seed 1234
16
+ config.order = 'random'
17
+ end
metadata ADDED
@@ -0,0 +1,86 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: ecart
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Abraham Kuri
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-07-09 00:00:00.000000000Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: rails
16
+ requirement: &70212394340520 !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '3.1'
22
+ type: :development
23
+ prerelease: false
24
+ version_requirements: *70212394340520
25
+ - !ruby/object:Gem::Dependency
26
+ name: rspec
27
+ requirement: &70212394339800 !ruby/object:Gem::Requirement
28
+ none: false
29
+ requirements:
30
+ - - ! '>='
31
+ - !ruby/object:Gem::Version
32
+ version: '0'
33
+ type: :development
34
+ prerelease: false
35
+ version_requirements: *70212394339800
36
+ description: Setup a fully functional e-commerce cart
37
+ email:
38
+ - kurenn@icalialabs.com
39
+ executables: []
40
+ extensions: []
41
+ extra_rdoc_files: []
42
+ files:
43
+ - .gitignore
44
+ - .rspec
45
+ - .travis.yml
46
+ - Gemfile
47
+ - README.md
48
+ - Rakefile
49
+ - ecart.gemspec
50
+ - lib/cart.rb
51
+ - lib/cart_item.rb
52
+ - lib/ecart.rb
53
+ - lib/ecart/version.rb
54
+ - lib/generators/ecart/install/install_generator.rb
55
+ - lib/generators/templates/cart_controller.rb
56
+ - lib/generators/templates/cart_helper.rb
57
+ - lib/item.rb
58
+ - spec/cart_spec.rb
59
+ - spec/spec_helper.rb
60
+ homepage: https://github.com/kurenn/ecart
61
+ licenses: []
62
+ post_install_message:
63
+ rdoc_options: []
64
+ require_paths:
65
+ - lib
66
+ required_ruby_version: !ruby/object:Gem::Requirement
67
+ none: false
68
+ requirements:
69
+ - - ! '>='
70
+ - !ruby/object:Gem::Version
71
+ version: '0'
72
+ required_rubygems_version: !ruby/object:Gem::Requirement
73
+ none: false
74
+ requirements:
75
+ - - ! '>='
76
+ - !ruby/object:Gem::Version
77
+ version: '0'
78
+ requirements: []
79
+ rubyforge_project: ecart
80
+ rubygems_version: 1.8.12
81
+ signing_key:
82
+ specification_version: 3
83
+ summary: E-commerce cart with rails
84
+ test_files:
85
+ - spec/cart_spec.rb
86
+ - spec/spec_helper.rb