active_cart 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore ADDED
@@ -0,0 +1,3 @@
1
+ active-cart.gemspec
2
+ pkg
3
+ rdoc
data/README.rdoc ADDED
@@ -0,0 +1,24 @@
1
+ == ActiveCart
2
+
3
+ ActiveCart is a Shopping Cart framework, it's not a fullyfledged cart, so you will need to do some stuff to get it to work.
4
+
5
+ The cart system has a storage engine, which means you aren't bound to a particular database (Eventually there will be different engines already built to get you started
6
+
7
+ == Installation
8
+ gem install active_cart
9
+
10
+ require 'rubygems'
11
+ require 'active_cart'
12
+
13
+ @cart = ActiveCart::Cart.setup(MyStorageEngine.new) do |t|
14
+ t << ShippingOrderTotal.new
15
+ t << GstOrderTotal.new
16
+ end
17
+
18
+ In this example the ShippingOrderTotal and GstOrderTotal have been created by the developer and follow the OrderTotal interface.
19
+
20
+ == Todo
21
+
22
+ Write some actual Storage Engines and OrderTotal examples.
23
+
24
+ Copyright (c) 2010 Myles Eftos (myles@madpilot.com.au), released under the MIT license
data/Rakefile ADDED
@@ -0,0 +1,55 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+ require 'rake/testtask'
4
+ require 'rake/rdoctask'
5
+
6
+ begin
7
+ require 'jeweler'
8
+
9
+ Jeweler::Tasks.new do |gem|
10
+ gem.name = "active_cart"
11
+ gem.summary = "Shopping Cart framework gem. Supports 'storage engines' and order total plugins"
12
+ gem.description = "You can use active-cart as the basis of a shopping cart system. It's definately not complete, you need to build a website around it."
13
+ gem.email = "myles@madpilot.com.au"
14
+ gem.homepage = "http://gemcutter.org/gems/active-cart"
15
+ gem.authors = ["Myles Eftos"]
16
+ gem.version = File.exist?('VERSION') ? File.read('VERSION') : ""
17
+ end
18
+ Jeweler::GemcutterTasks.new
19
+ rescue LoadError
20
+ puts "Jeweler (or a dependency) not available. Install it with: sudo gem install jeweler"
21
+ end
22
+
23
+ require 'rake/testtask'
24
+ Rake::TestTask.new(:test) do |test|
25
+ test.libs << 'lib' << 'test'
26
+ test.pattern = 'test/unit/*_test.rb'
27
+ test.verbose = true
28
+ end
29
+
30
+ begin
31
+ require 'rcov/rcovtask'
32
+ Rcov::RcovTask.new do |test|
33
+ test.libs << 'test'
34
+ test.pattern = 'test/unit/*_test.rb'
35
+ test.verbose = true
36
+ end
37
+ rescue LoadError
38
+ task :rcov do
39
+ abort "RCov is not available. In order to run rcov, you must: sudo gem install spicycode-rcov"
40
+ end
41
+ end
42
+
43
+ task :test => :check_dependencies
44
+
45
+ task :default => :test
46
+
47
+ require 'rake/rdoctask'
48
+ Rake::RDocTask.new do |rdoc|
49
+ version = File.exist?('VERSION') ? File.read('VERSION') : ""
50
+
51
+ rdoc.rdoc_dir = 'rdoc'
52
+ rdoc.title = "active_cart #{version}"
53
+ rdoc.rdoc_files.include('README*')
54
+ rdoc.rdoc_files.include('lib/**/*.rb')
55
+ end
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.0.1
@@ -0,0 +1,11 @@
1
+ class SchwacmsGalleryGenerator < Rails::Generator::NamedBase
2
+ def initialize(runtime_args, runtime_options = {})
3
+ super
4
+ end
5
+
6
+ def manifest
7
+ record do |m|
8
+ m.migration_template 'schwacms_gallery_migration.rb', 'db/migrate', :migration_file_name => 'create_schwacms_gallery'
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,26 @@
1
+ class CreateSchwacmsGallery < ActiveRecord::Migration
2
+ def self.up
3
+ create_table "galleries", :force => true do |t|
4
+ t.integer "width"
5
+ t.integer "height"
6
+ t.integer "thumbnail_width"
7
+ t.integer "thumbnail_height"
8
+ t.datetime "created_at"
9
+ t.datetime "updated_at"
10
+ end
11
+
12
+ create_table "gallery_images", :force => true do |t|
13
+ t.string "path"
14
+ t.text "description"
15
+ t.integer "gallery_id"
16
+ t.integer "position"
17
+ t.datetime "created_at"
18
+ t.datetime "updated_at"
19
+ end
20
+ end
21
+
22
+ def self.down
23
+ drop_table "gallery_images"
24
+ drop_table "galleries"
25
+ end
26
+ end
data/install.rb ADDED
@@ -0,0 +1 @@
1
+ # Install hook code here
@@ -0,0 +1,96 @@
1
+ module ActiveCart
2
+ # The Cart class is the core class in ActiveCart. It is a singleton (so you can only have one cart per application), that gets setup initially by passing in
3
+ # a storage engine instance. Storage engines abstract away the storage of the cart, and is left as an exercise to the user. See the Storage engine docs
4
+ # for details.
5
+ #
6
+ # The Cart class also takes order_total objects, which will calculate order totals. it may include thinkgs like shipping, or gift vouchers etc. See the Order Total
7
+ # docs for details.
8
+ #
9
+ # The Cart object delegates a number of Array methods:
10
+ # :[], :<<, :[]=, :at, :clear, :collect, :map, :delete, :delete_at, :each, :each_index, :empty?, :eql?, :first, :include?, :index, :inject, :last, :length, :pop, :push, :shift, :size, :unshift
11
+ #
12
+ class Cart
13
+ attr_accessor :storage_engine, :order_total_calculators, :customer
14
+ include Enumerable
15
+
16
+ # The method MUST be called before you call instance, otherwise you will receive and StandardError
17
+ # You need to supply a storage engine. An optional block can be given which allows you to add order total items.
18
+ #
19
+ # A typical initialization block might look like this
20
+ #
21
+ # @cart = Cart.new(MyAwesomeStorageEngine.new) do |o|
22
+ # o << ShippingOrderTotal.new
23
+ # o << GstOrderTotal.new
24
+ # end
25
+ #
26
+ def initialize(storage_engine, &block)
27
+ @storage_engine = storage_engine
28
+ @order_total_calculators = OrderTotalCollection.new(self)
29
+
30
+ if block_given?
31
+ yield order_total_calculators
32
+ end
33
+ end
34
+
35
+ extend Forwardable
36
+ # Storage Engine Array delegators
37
+ def_delegators :@storage_engine, :[], :<<, :[]=, :at, :clear, :collect, :map, :delete, :delete_at, :each, :each_index, :empty?, :eql?, :first, :include?, :index, :inject, :last, :length, :pop, :push, :shift, :size, :unshift
38
+
39
+ # Returns a unique id for the invoice. It's upto the storage engine to generate and track these numbers
40
+ #
41
+ def invoice_id
42
+ @storage_engine.invoice_id
43
+ end
44
+
45
+ # Returns the sub-total of all the items in the cart. Usually returns a float.
46
+ #
47
+ # @cart.sub_total # => 100.00
48
+ #
49
+ def quantity
50
+ @storage_engine.quantity
51
+ end
52
+
53
+ # Returns the subtotal of cart, which is effectively the total of all the items multiplied by their quantites. Does NOT include order_totals
54
+ def sub_total
55
+ @storage_engine.sub_total
56
+ end
57
+
58
+ # Adds an item to the cart. If the item already exists in the cart (identified by the id of the item), then the quantity will be increased but the supplied quantity (default: 1)
59
+ #
60
+ # @cart.add_to_cart(item, 5)
61
+ # @cart.quantity # => 5
62
+ #
63
+ # @cart.add_to_cart(item, 2)
64
+ # @cart.quantity # => 7
65
+ # @cart[0].size # => 7
66
+ # @cart[1] # => nil
67
+ #
68
+ # @cart.add_to_cart(item_2, 4)
69
+ # @cart.quantity => 100
70
+ # @cart[0].size # => 7
71
+ # @cart[1].size # => 4
72
+ #
73
+ def add_to_cart(item, quantity = 1)
74
+ @storage_engine.add_to_cart(item, quantity)
75
+ end
76
+
77
+ # Removes an item from the cart (identified by the id of the item). If the supplied quantity is greater than equal to the number in the cart, the item will be removed, otherwise the quantity will simply be decremented by the supplied amount
78
+ #
79
+ # @cart.add_to_cart(item, 5)
80
+ # @cart[0].quantity # => 5
81
+ # @cart.remove_from_cart(item, 3)
82
+ # @cart[0].quantity # => 2
83
+ # @cart.remove_from_cart(item, 2)
84
+ # @cart[0] # => nil
85
+ #
86
+ def remove_from_cart(item, quantity = 1)
87
+ @storage_engine.remove_from_cart(item, quantity)
88
+ end
89
+
90
+ # Returns the total of the cart. This includes all the order_total calculations
91
+ #
92
+ def total
93
+ sub_total + order_total_calculators.total
94
+ end
95
+ end
96
+ end
@@ -0,0 +1,71 @@
1
+ # Mixin this module into the class you want to user as your storage class. Remember to override the invoice_id method
2
+ #
3
+ module ActiveCart
4
+ module CartStorage
5
+ # Returns the unique invoice_id for this cart instance. This MUST be overriden by the concrete class this module is mixed into, otherwise you
6
+ # will get a NotImplementedError
7
+ #
8
+ def invoice_id
9
+ raise NotImplementedError
10
+ end
11
+
12
+ # Returns the sub-total of all the items in the cart. Usually returns a float.
13
+ #
14
+ # @cart.sub_total # => 100.00
15
+ #
16
+ def sub_total
17
+ inject(0) { |t, item| t + (item.quantity * item.price) }
18
+ end
19
+
20
+ # Returns the number of items in the cart. It takes into account the individual quantities of each item, eg if there are 3 items in the cart, each with a quantity of 2, this will return 6
21
+ #
22
+ def quantity
23
+ inject(0) { |t, item| t + item.quantity }
24
+ end
25
+
26
+ # Adds an item to the cart. If the item already exists in the cart (identified by the id of the item), then the quantity will be increased but the supplied quantity (default: 1)
27
+ #
28
+ # @cart.add_to_cart(item, 5)
29
+ # @cart.quantity # => 5
30
+ #
31
+ # @cart.add_to_cart(item, 2)
32
+ # @cart.quantity # => 7
33
+ # @cart[0].quantity # => 7
34
+ # @cart[1] # => nil
35
+ #
36
+ # @cart.add_to_cart(item_2, 4)
37
+ # @cart.quantity => 100
38
+ # @cart[0].quantity # => 7
39
+ # @cart[1].quantity # => 4
40
+ #
41
+ def add_to_cart(item, quantity = 1)
42
+ if self.include?(item)
43
+ index = self.index(item)
44
+ self.at(index).quantity += quantity
45
+ else
46
+ item.quantity += quantity
47
+ self << item
48
+ end
49
+ end
50
+
51
+ # Removes an item from the cart (identified by the id of the item). If the supplied quantity is greater than equal to the number in the cart, the item will be removed, otherwise the quantity will simply be decremented by the supplied amount
52
+ #
53
+ # @cart.add_to_cart(item, 5)
54
+ # @cart[0].quantity # => 5
55
+ # @cart.remove_from_cart(item, 3)
56
+ # @cart[0].quantity # => 2
57
+ # @cart.remove_from_cart(item, 2)
58
+ # @cart[0] # => nil
59
+ #
60
+ def remove_from_cart(item, quantity = 1)
61
+ if self.include?(item)
62
+ index = self.index(item)
63
+ if (existing = self.at(index)).quantity - quantity > 0
64
+ existing.quantity = existing.quantity - quantity
65
+ else
66
+ self.delete_at(index)
67
+ end
68
+ end
69
+ end
70
+ end
71
+ end
@@ -0,0 +1,58 @@
1
+ # Mixin this module into any classes that act as an order_total.
2
+ #
3
+ # You need to overwrite the price, name and description methods
4
+ #
5
+ module ActiveCart
6
+ module OrderTotal
7
+
8
+ # Returns a boolean depending if the order total is active in this particular cart
9
+ #
10
+ # @order_total.active? # => true
11
+ #
12
+ def active?
13
+ @active || false
14
+ end
15
+
16
+ # Make a particular order_total active
17
+ #
18
+ # @order_total.active = true
19
+ # @order_total.active? # => true
20
+ #
21
+ # @order_total.active = false
22
+ # @order_total.active? # => falese
23
+ #
24
+ def active=(active)
25
+ @active = active
26
+ end
27
+
28
+ # Returns the adjustment caused by this order_total object. Takes a cart object as a parameter, allowing the object to interrogate the items in the cart.
29
+ #
30
+ # This must be overriden in the mixee class, otherwise it will throw a NotImplementedError
31
+ #
32
+ # @order.price(@cart) => 2
33
+ #
34
+ def price(cart)
35
+ raise NotImplementedError
36
+ end
37
+
38
+ # Returns the friendly name of the order total. Can be used for display (Such as on an invoices etc)
39
+ #
40
+ # This must be overriden in the mixee class, otherwise it will throw a NotImplementedError
41
+ #
42
+ # @order.name # => 'My awesome order total class'
43
+ #
44
+ def name
45
+ raise NotImplementedError
46
+ end
47
+
48
+ # Returns a short description of the order total. Can be used for display (Such as on an invoices etc)
49
+ #
50
+ # This must be overriden in the mixee class, otherwise it will throw a NotImplementedError
51
+ #
52
+ # @order.description # => "This example order class doesn't do much"
53
+ #
54
+ def description
55
+ raise NotImplementedError
56
+ end
57
+ end
58
+ end
@@ -0,0 +1,75 @@
1
+ module ActiveCart
2
+ class OrderTotalCollection < Array
3
+ # Returns a new OrderTotalCollection
4
+ #
5
+ # You must pass in an cart object.
6
+ #
7
+ # collection = OrderTotalCollection.new(@cart)
8
+ #
9
+ # You can also pass in an array of order_total objects
10
+ #
11
+ # cart = ActiveCart::Cart.instance
12
+ # collection = OrderTotalCollection.new(cart, order_total_1, order_total_2) # => [ order_total_1, order_total_2 ]
13
+ #
14
+ def initialize(cart, *seed)
15
+ @cart = cart
16
+ seed.each do |s|
17
+ self.push(s)
18
+ end
19
+ end
20
+
21
+ # Concatenation.Returns a new OrderTotalCollection built by concatenating the two OrderTotalCollections together to produce a third OrderTotalCollection. (The supplied collection can be a regular array)
22
+ #
23
+ # [ order_total_1, order_total_2, order_total_3 ] + [ order_total_4, order_total_5 ] #=> [ order_total_1, order_total_2, order_total_3, order_total_4, order_total_5 ]
24
+ #
25
+ def +(order_total_collection)
26
+ tmp = OrderTotalCollection.new(@cart)
27
+ self.each { |s| tmp << s }
28
+ order_total_collection.each { |s| tmp << s }
29
+ tmp
30
+ end
31
+
32
+ # Inserts the items before the item that is currently at the supplied index
33
+ #
34
+ # items = [ order_total_1, order_total_2 ]
35
+ # items.insert_before(1, order_total_2) #=> [ order_total_1, order_total_3, order_total_2 ]
36
+ #
37
+ def insert_before(index, *items)
38
+ items.reverse.each do |item|
39
+ self.insert(index, item)
40
+ end
41
+ self
42
+ end
43
+
44
+ # Inserts the items after the item that is currently at the supplied index
45
+ #
46
+ # items = [ order_total_1, order_total_2 ]
47
+ # items.insert_after(0, order_total_2) #=> [ order_total_1, order_total_3, order_total_2 ]
48
+ #
49
+ def insert_after(index, *items)
50
+ items.each_with_index do |item, i|
51
+ self.insert(index + i + 1, item)
52
+ end
53
+ self
54
+ end
55
+
56
+ # Allows you to reorder the order totals. Moves the item at index <em>from</em> to index <em>to</em>
57
+ #
58
+ # items = [ order_total_1, order_total_2 ]
59
+ # items.move(0, 1) #=> [ order_total_2, order_total_1 ]
60
+ #
61
+ def move(from, to)
62
+ index = self.delete_at(from)
63
+ self.insert(to, index)
64
+ end
65
+
66
+ # Calculates the total price applied by all the order_total objects.
67
+ #
68
+ # order_total_collection = OrderTotalCollection.new(nil, order_total_1, order_total_2)
69
+ # order_total_collection.total # => 10
70
+ #
71
+ def total
72
+ self.inject(0) { |t, calculator| t + (calculator.active? ? calculator.price(@cart) : 0) }
73
+ end
74
+ end
75
+ end
@@ -0,0 +1,12 @@
1
+ $:.unshift(File.join(File.dirname(__FILE__), 'active_cart'))
2
+
3
+ require 'singleton'
4
+ require 'forwardable'
5
+ require 'active_cart/cart_storage'
6
+ require 'active_cart/order_total'
7
+ require 'active_cart/order_total_collection'
8
+ require 'active_cart/cart'
9
+
10
+ module ActiveCart
11
+ VERSION = File.exist?('VERSION') ? File.read('VERSION') : ""
12
+ end
@@ -0,0 +1,7 @@
1
+ class TestCartStorage < Array
2
+ include ActiveCart::CartStorage
3
+
4
+ def invoice_id
5
+ 'Invoice #1'
6
+ end
7
+ end
@@ -0,0 +1,20 @@
1
+ class TestItem
2
+ attr_accessor :id, :price, :quantity
3
+
4
+ def ==(item)
5
+ self.id == item.id
6
+ end
7
+
8
+ def initialize(id = 1)
9
+ self.id = id
10
+ self.quantity = 0
11
+ end
12
+
13
+ def price
14
+ @price || 2
15
+ end
16
+
17
+ def inspect
18
+ "TestItem: #{self.id}: #{self.quantity}x$#{self.price}"
19
+ end
20
+ end
@@ -0,0 +1,15 @@
1
+ class TestOrderTotal
2
+ attr_accessor :price, :active
3
+ def initialize(price, active = true)
4
+ @price = price
5
+ @active = active
6
+ end
7
+
8
+ def price(cart)
9
+ @price
10
+ end
11
+
12
+ def active?
13
+ @active
14
+ end
15
+ end
@@ -0,0 +1,9 @@
1
+ require 'test_helper'
2
+ require 'performance_test_help'
3
+
4
+ # Profiling results for each test method are written to tmp/performance.
5
+ class BrowsingTest < ActionController::PerformanceTest
6
+ def test_homepage
7
+ get '/'
8
+ end
9
+ end
@@ -0,0 +1,16 @@
1
+ $:.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
2
+ $:.unshift(File.join(File.dirname(__FILE__)))
3
+
4
+ require 'rubygems'
5
+ require 'redgreen'
6
+ require 'test/unit'
7
+ require 'shoulda'
8
+ require 'mocha'
9
+
10
+ require 'active_cart'
11
+ require 'mocks/test_cart_storage'
12
+ require 'mocks/test_item'
13
+ require 'mocks/test_order_total'
14
+
15
+ class Test::Unit::TestCase
16
+ end
@@ -0,0 +1,137 @@
1
+ require 'test_helper'
2
+
3
+ class CartStorageTest < Test::Unit::TestCase
4
+ context '' do
5
+ setup do
6
+ @cart_storage_engine = TestCartStorage.new
7
+ @cart = ActiveCart::Cart.new(@cart_storage_engine)
8
+ end
9
+
10
+ context 'sub_total' do
11
+ setup do
12
+ @item_1 = TestItem.new(1)
13
+ @item_2 = TestItem.new(2)
14
+ @item_3 = TestItem.new(3)
15
+ @item_1.price = 10
16
+ @item_2.price = 12
17
+ @item_3.price = 9
18
+ end
19
+
20
+
21
+ should 'return the price of a single item in the cart' do
22
+ @cart.add_to_cart(@item_1)
23
+ assert_equal 10, @cart.sub_total
24
+ end
25
+
26
+ should 'return the price of a single item with a quantity' do
27
+ @cart.add_to_cart(@item_2, 3)
28
+ assert_equal 36, @cart.sub_total
29
+ end
30
+
31
+ should 'return the sum of all the items in the cart' do
32
+ @cart.add_to_cart(@item_1)
33
+ @cart.add_to_cart(@item_2, 3)
34
+ assert_equal 46, @cart.sub_total
35
+ end
36
+ end
37
+
38
+ context 'add to cart' do
39
+ should 'add an item to the cart if the cart is empty' do
40
+ assert @cart.empty?
41
+ item = TestItem.new
42
+ @cart.add_to_cart(item)
43
+ assert_equal 1, @cart.size
44
+ assert_equal 1, @cart[0].quantity
45
+ assert_equal 1, @cart.quantity
46
+ end
47
+
48
+ should 'increase the item quantity if the same item is added to the cart again' do
49
+ assert @cart.empty?
50
+ item = TestItem.new(1)
51
+ @cart.add_to_cart(item)
52
+ assert_equal 1, @cart.size
53
+ assert_equal 1, @cart[0].quantity
54
+
55
+ item_2 = TestItem.new(1) # Has the same id, is the same as item
56
+ @cart.add_to_cart(item_2)
57
+ assert_equal 1, @cart.size
58
+ assert_equal 2, @cart[0].quantity
59
+ assert_equal 2, @cart.quantity
60
+ end
61
+
62
+ should 'increase the item quantity by the supplied number if the same item is add to the cart again and a quantity is supplied' do
63
+ assert @cart.empty?
64
+ item = TestItem.new(1)
65
+ @cart.add_to_cart(item)
66
+ assert_equal 1, @cart.size
67
+ assert_equal 1, @cart[0].quantity
68
+
69
+ item_2 = TestItem.new(1) # Has the same id, is the same as item
70
+ @cart.add_to_cart(item_2, 10)
71
+ assert_equal 1, @cart.size
72
+ assert_equal 11, @cart[0].quantity
73
+ assert_equal 11, @cart.quantity
74
+ end
75
+
76
+ should 'add another item to the cart' do
77
+ assert @cart.empty?
78
+ item = TestItem.new(1)
79
+ @cart.add_to_cart(item)
80
+ assert_equal 1, @cart.size
81
+ assert_equal 1, @cart[0].quantity
82
+
83
+ item_2 = TestItem.new(2)
84
+ @cart.add_to_cart(item_2, 10)
85
+ assert_equal 2, @cart.size
86
+ assert_equal 1, @cart[0].quantity
87
+ assert_equal 10, @cart[1].quantity
88
+ assert_equal 11, @cart.quantity
89
+ end
90
+ end
91
+
92
+ context 'remove_from_cart' do
93
+ should 'remove the quantity supplied from the cart' do
94
+ item = TestItem.new(1)
95
+ @cart.add_to_cart(item, 10)
96
+ assert_equal 1, @cart.size
97
+ assert_equal 10, @cart.quantity
98
+
99
+ @cart.remove_from_cart(item)
100
+ assert_equal 1, @cart.size
101
+ assert_equal 9, @cart.quantity
102
+ end
103
+
104
+ should 'remove the item from the cart if the quantity to be removed is equal to the number in cart' do
105
+ item = TestItem.new(1)
106
+ @cart.add_to_cart(item, 10)
107
+ assert_equal 1, @cart.size
108
+ assert_equal 10, @cart.quantity
109
+
110
+ @cart.remove_from_cart(item, 10)
111
+ assert_equal 0, @cart.size
112
+ end
113
+
114
+ should 'remove the item from the cart if the quantity to be removed is greater than the number in cart' do
115
+ item = TestItem.new(1)
116
+ @cart.add_to_cart(item, 10)
117
+ assert_equal 1, @cart.size
118
+ assert_equal 10, @cart.quantity
119
+
120
+ @cart.remove_from_cart(item, 11)
121
+ assert_equal 0, @cart.size
122
+ end
123
+
124
+ should "simply return if the item doesn't exist in the cart" do
125
+ item = TestItem.new(1)
126
+ @cart.add_to_cart(item, 10)
127
+ assert_equal 1, @cart.size
128
+ assert_equal 10, @cart.quantity
129
+
130
+ item_2 = TestItem.new(2)
131
+ @cart.remove_from_cart(item_2, 10)
132
+ assert_equal 1, @cart.size
133
+ assert_equal 10, @cart.quantity
134
+ end
135
+ end
136
+ end
137
+ end
@@ -0,0 +1,181 @@
1
+ require 'test_helper'
2
+
3
+ class CartTest < Test::Unit::TestCase
4
+ context '' do
5
+ context 'after setup' do
6
+ setup do
7
+ @cart_storage_engine = TestCartStorage.new
8
+ @cart = ActiveCart::Cart.new(@cart_storage_engine)
9
+ end
10
+
11
+ context 'delegate to cart storage' do
12
+ should 'delegate []' do
13
+ @cart_storage_engine.expects(:[]).with(0)
14
+ @cart[0]
15
+ end
16
+
17
+ should 'delegate <<' do
18
+ test = TestItem.new
19
+ @cart_storage_engine.expects(:<<).with(test)
20
+ @cart << test
21
+ end
22
+
23
+ should 'delegate []=' do
24
+ test = TestItem.new
25
+ @cart_storage_engine.expects(:[]=).with(0, test)
26
+ @cart[0] = test
27
+ end
28
+
29
+ should 'delegate :at' do
30
+ @cart_storage_engine.expects(:at).with(1)
31
+ @cart.at(1)
32
+ end
33
+
34
+ should 'delegate :clear' do
35
+ @cart_storage_engine.expects(:clear)
36
+ @cart.clear
37
+ end
38
+
39
+ should 'delegate :collect' do
40
+ @cart_storage_engine.expects(:collect)
41
+ @cart.collect
42
+ end
43
+
44
+ should 'delegate :map' do
45
+ @cart_storage_engine.expects(:map)
46
+ @cart.map
47
+ end
48
+
49
+ should 'delegate :delete' do
50
+ test = TestItem.new
51
+ @cart_storage_engine.expects(:delete).with(test)
52
+ @cart.delete(test)
53
+ end
54
+
55
+ should 'delegate :delete_at' do
56
+ @cart_storage_engine.expects(:delete_at).with(3)
57
+ @cart.delete_at(3)
58
+ end
59
+
60
+ should 'delegate :each' do
61
+ @cart_storage_engine.expects(:each)
62
+ @cart.each
63
+ end
64
+
65
+ should 'delegate :each_index' do
66
+ @cart_storage_engine.expects(:each_index)
67
+ @cart.each_index
68
+ end
69
+
70
+ should 'delegate :empty' do
71
+ @cart_storage_engine.expects(:empty?)
72
+ @cart.empty?
73
+ end
74
+
75
+ should 'delegate :eql?' do
76
+ @cart_storage_engine.expects(:eql?)
77
+ @cart.eql?
78
+ end
79
+
80
+ should 'delegate :first' do
81
+ @cart_storage_engine.expects(:first)
82
+ @cart.first
83
+ end
84
+
85
+ should 'delegate :include?' do
86
+ @cart_storage_engine.expects(:include?)
87
+ @cart.include?
88
+ end
89
+
90
+ should 'delegate :index' do
91
+ @cart_storage_engine.expects(:index)
92
+ @cart.index
93
+ end
94
+
95
+ should 'delegate :inject' do
96
+ @cart_storage_engine.expects(:inject)
97
+ @cart.inject
98
+ end
99
+
100
+ should 'delegate :last' do
101
+ @cart_storage_engine.expects(:last)
102
+ @cart.last
103
+ end
104
+
105
+ should 'delegate :length' do
106
+ @cart_storage_engine.expects(:length)
107
+ @cart.length
108
+ end
109
+
110
+ should 'delegate :pop' do
111
+ @cart_storage_engine.expects(:pop)
112
+ @cart.pop
113
+ end
114
+
115
+ should 'delegate :push' do
116
+ @cart_storage_engine.expects(:push)
117
+ @cart.push
118
+ end
119
+
120
+ should 'delegate :shift' do
121
+ @cart_storage_engine.expects(:shift)
122
+ @cart.shift
123
+ end
124
+
125
+ should 'delegate :size' do
126
+ @cart_storage_engine.expects(:size)
127
+ @cart.size
128
+ end
129
+
130
+ should 'delegate :unshift' do
131
+ @cart_storage_engine.expects(:unshift)
132
+ @cart.unshift
133
+ end
134
+
135
+ should 'delegate :invoice_id' do
136
+ @cart_storage_engine.expects(:invoice_id)
137
+ @cart.invoice_id
138
+ end
139
+
140
+ should 'delegate :sub_total' do
141
+ @cart_storage_engine.expects(:sub_total)
142
+ @cart.sub_total
143
+ end
144
+ end
145
+
146
+ context 'setup' do
147
+ should 'take a block to add order_totals' do
148
+ @total_1 = TestOrderTotal.new(10, true)
149
+ @total_2 = TestOrderTotal.new(20, true)
150
+
151
+ @cart_storage_engine = TestCartStorage.new
152
+ @cart = ActiveCart::Cart.new(@cart_storage_engine) do |o|
153
+ o << @total_1
154
+ o << @total_2
155
+ end
156
+ assert_equal [ @total_1, @total_2 ], @cart.order_total_calculators
157
+ end
158
+ end
159
+
160
+ context 'total' do
161
+ should 'sum all the items in the cart with order totals' do
162
+ @item_1 = TestItem.new(1)
163
+ @item_1.price = 10
164
+ @item_2 = TestItem.new(2)
165
+ @item_2.price = 20
166
+ @item_3 = TestItem.new(3)
167
+ @item_3.price = 30
168
+ @total_1 = TestOrderTotal.new(10, true)
169
+ @total_2 = TestOrderTotal.new(20, true)
170
+
171
+ @cart.order_total_calculators += [ @total_1, @total_2 ]
172
+ @cart.add_to_cart(@item_1)
173
+ @cart.add_to_cart(@item_2)
174
+ @cart.add_to_cart(@item_3)
175
+
176
+ assert_equal 90, @cart.total
177
+ end
178
+ end
179
+ end
180
+ end
181
+ end
@@ -0,0 +1,87 @@
1
+ require 'test_helper'
2
+
3
+ class OrderTotalCollectionTest < Test::Unit::TestCase
4
+ context '' do
5
+ setup do
6
+ @cart_storage_engine = TestCartStorage.new
7
+ @cart = ActiveCart::Cart.new(@cart_storage_engine)
8
+ @collection = ActiveCart::OrderTotalCollection.new(@cart)
9
+ end
10
+
11
+ context 'insert_before' do
12
+ should 'insert an object before the item at the supplied index' do
13
+ @collection << '0'
14
+ @collection << '1'
15
+ @collection << '2'
16
+ @collection << '3'
17
+ @collection << '4'
18
+
19
+ @collection.insert_before(3, '5')
20
+ assert_equal [ '0', '1', '2', '5', '3', '4' ], @collection
21
+ end
22
+
23
+ should 'insert all the objects before the item at the supplied index' do
24
+ @collection << '0'
25
+ @collection << '1'
26
+ @collection << '2'
27
+ @collection << '3'
28
+ @collection << '4'
29
+
30
+ @collection.insert_before(3, '5', '6', '7', '8')
31
+ assert_equal [ '0', '1', '2', '5', '6', '7', '8', '3', '4' ], @collection
32
+ end
33
+
34
+ end
35
+
36
+ context 'insert_after' do
37
+ should 'insert an object after the item at the supplied index' do
38
+ @collection << '0'
39
+ @collection << '1'
40
+ @collection << '2'
41
+ @collection << '3'
42
+ @collection << '4'
43
+
44
+ @collection.insert_after(3, '5')
45
+ assert_equal [ '0', '1', '2', '3', '5', '4' ], @collection
46
+ end
47
+
48
+ should 'insert all the objects after the item at the supplied index' do
49
+ @collection << '0'
50
+ @collection << '1'
51
+ @collection << '2'
52
+ @collection << '3'
53
+ @collection << '4'
54
+
55
+ @collection.insert_after(3, '5', '6', '7', '8')
56
+ assert_equal [ '0', '1', '2', '3', '5', '6', '7', '8', '4' ], @collection
57
+ end
58
+ end
59
+
60
+ context 'move' do
61
+ should 'move the item at the from index to the to index' do
62
+ @collection << '0'
63
+ @collection << '1'
64
+ @collection << '2'
65
+ @collection << '3'
66
+ @collection << '4'
67
+
68
+ @collection.move(3, 0)
69
+ assert_equal [ '3', '0', '1', '2', '4' ], @collection
70
+ end
71
+ end
72
+
73
+ context 'total' do
74
+ setup do
75
+ @total_1 = TestOrderTotal.new(10, true)
76
+ @total_2 = TestOrderTotal.new(5, false)
77
+ @total_3 = TestOrderTotal.new(2, true)
78
+ @total_4 = TestOrderTotal.new(14, true)
79
+ end
80
+
81
+ should 'call price on each order_total item that are active' do
82
+ @collection += [ @total_1, @total_2, @total_3, @total_4 ]
83
+ assert_equal 26, @collection.total
84
+ end
85
+ end
86
+ end
87
+ end
data/uninstall.rb ADDED
@@ -0,0 +1 @@
1
+ # Uninstall hook code here
metadata ADDED
@@ -0,0 +1,82 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: active_cart
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Myles Eftos
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2010-02-27 00:00:00 +08:00
13
+ default_executable:
14
+ dependencies: []
15
+
16
+ description: You can use active-cart as the basis of a shopping cart system. It's definately not complete, you need to build a website around it.
17
+ email: myles@madpilot.com.au
18
+ executables: []
19
+
20
+ extensions: []
21
+
22
+ extra_rdoc_files:
23
+ - README.rdoc
24
+ files:
25
+ - .gitignore
26
+ - README.rdoc
27
+ - Rakefile
28
+ - VERSION
29
+ - generators/schwacms-gallery/schwacms_gallery_generator.rb
30
+ - generators/schwacms-gallery/templates/schwacms_gallery_migration.rb
31
+ - install.rb
32
+ - lib/active_cart.rb
33
+ - lib/active_cart/cart.rb
34
+ - lib/active_cart/cart_storage.rb
35
+ - lib/active_cart/order_total.rb
36
+ - lib/active_cart/order_total_collection.rb
37
+ - test/mocks/test_cart_storage.rb
38
+ - test/mocks/test_item.rb
39
+ - test/mocks/test_order_total.rb
40
+ - test/performance/browsing_test.rb
41
+ - test/test_helper.rb
42
+ - test/unit/cart_storage_test.rb
43
+ - test/unit/cart_test.rb
44
+ - test/unit/order_total_collection_test.rb
45
+ - uninstall.rb
46
+ has_rdoc: true
47
+ homepage: http://gemcutter.org/gems/active-cart
48
+ licenses: []
49
+
50
+ post_install_message:
51
+ rdoc_options:
52
+ - --charset=UTF-8
53
+ require_paths:
54
+ - lib
55
+ required_ruby_version: !ruby/object:Gem::Requirement
56
+ requirements:
57
+ - - ">="
58
+ - !ruby/object:Gem::Version
59
+ version: "0"
60
+ version:
61
+ required_rubygems_version: !ruby/object:Gem::Requirement
62
+ requirements:
63
+ - - ">="
64
+ - !ruby/object:Gem::Version
65
+ version: "0"
66
+ version:
67
+ requirements: []
68
+
69
+ rubyforge_project:
70
+ rubygems_version: 1.3.5
71
+ signing_key:
72
+ specification_version: 3
73
+ summary: Shopping Cart framework gem. Supports 'storage engines' and order total plugins
74
+ test_files:
75
+ - test/unit/order_total_collection_test.rb
76
+ - test/unit/cart_storage_test.rb
77
+ - test/unit/cart_test.rb
78
+ - test/mocks/test_cart_storage.rb
79
+ - test/mocks/test_order_total.rb
80
+ - test/mocks/test_item.rb
81
+ - test/test_helper.rb
82
+ - test/performance/browsing_test.rb