active_cart 0.0.4 → 0.0.5

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.
data/.gitignore CHANGED
@@ -1,3 +1,4 @@
1
1
  *.gemspec
2
2
  pkg
3
3
  rdoc
4
+ test/log/*.log
data/README.rdoc CHANGED
@@ -2,11 +2,14 @@
2
2
 
3
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
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
5
+ The cart system has a storage engine, which means you aren't bound to a particular database. So far, there is a an ActiveModel storage engine, called acts_as_cart, but the
6
+ gem isn't just for Rails, by writing other engines, you could target any datastore.
6
7
 
7
8
  == Installation
8
9
  gem install active_cart
9
10
 
11
+ == Usage
12
+
10
13
  require 'rubygems'
11
14
  require 'active_cart'
12
15
 
@@ -38,8 +41,4 @@ For information about the API and interfase, checkout the documentation: http://
38
41
  >> c.total
39
42
  => 20
40
43
 
41
- == TODO
42
-
43
- Write an ActiveMerchant acts_as_ plugin. Write an interface to MondoDB or CouchDB (or both). Write a reference rails engine that implements a working shopping cart site
44
-
45
- Copyright (c) 2010 Myles Eftos (myles@madpilot.com.au), released under the MIT license
44
+ Copyright (c) 2010 Myles Eftos http://www.madpilot.com.au/contact, released under the MIT license
data/Rakefile CHANGED
@@ -20,6 +20,8 @@ begin
20
20
  gem.add_development_dependency 'redgreen'
21
21
  gem.add_development_dependency 'shoulda'
22
22
  gem.add_development_dependency 'mocha'
23
+ gem.add_development_dependency 'machinist'
24
+ gem.add_development_dependency 'faker'
23
25
  end
24
26
  Jeweler::GemcutterTasks.new
25
27
  rescue LoadError
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.0.4
1
+ 0.0.5
@@ -0,0 +1,206 @@
1
+ require 'active_record'
2
+ require 'aasm'
3
+ #require 'aasm/persistence/active_record_persistence'
4
+
5
+ module ActiveCart
6
+ module Acts
7
+ module Cart
8
+ #:nodoc
9
+ def self.included(mod)
10
+ mod.extend(ClassMethods)
11
+ end
12
+
13
+ module ClassMethods
14
+ # acts_as_cart - Turns an ActiveRecord model in to a cart. It can take a hash of options
15
+ #
16
+ # state_column: The database column that stores the persistent state machine state. Default: state
17
+ # invoice_id_column: The column that stores the invoice id. Default: invoice_id
18
+ # cart_items: The model that represents the items for this cart. Is associated as a has_many. Default: cart_items
19
+ # order_totals: The model that represents order totals for this cart. It is associated as a has_many. Default: order_totals
20
+ #
21
+ # class Cart < ActiveModel::Base
22
+ # acts_as_cart
23
+ # end
24
+ #
25
+ # The only two columns that are required for a cart model are the state_column and invoice_id_column
26
+ #
27
+ # You can create custom acts_as_state_machine (aasm) states and events after declaring acts_as_cart
28
+ #
29
+ def acts_as_cart(options = {})
30
+ cattr_accessor :aac_config
31
+
32
+ self.aac_config = {
33
+ :state_column => :state,
34
+ :invoice_id_column => :invoice_id,
35
+ :cart_items => :cart_items,
36
+ :order_totals => :order_totals
37
+ }
38
+
39
+ self.aac_config.merge!(options)
40
+
41
+ class_eval do
42
+ #include AASM::Persistence::ActiveRecordPersistence
43
+ include ActiveCart::CartStorage
44
+
45
+ def invoice_id
46
+ read_attribute(self.aac_config[:invoice_id_column])
47
+ end
48
+
49
+ def state
50
+ read_attribute(self.aac_config[:state_column])
51
+ end
52
+ end
53
+
54
+ aasm_column self.aac_config[:state_column]
55
+
56
+ has_many self.aac_config[:cart_items]
57
+ has_many self.aac_config[:order_totals]
58
+
59
+ extend Forwardable
60
+ def_delegators self.aac_config[:cart_items], :[], :<<, :[]=, :at, :clear, :collect, :map, :delete, :delete_at, :each, :each_index, :empty?, :eql?, :first, :include?, :index, :inject, :last, :length, :pop, :push, :shift, :size, :unshift
61
+ end
62
+ end
63
+ end
64
+
65
+ module Item
66
+ #:nodoc
67
+ def self.included(mod)
68
+ mod.extend(ClassMethods)
69
+ end
70
+
71
+ module ClassMethods
72
+ # acts_as_cart_item - Sets up an ActiveModel as an cart item.
73
+ #
74
+ # Cart Items are slightly different to regular items (that may be created in a backend somewhere). When building shopping carts, one of the problems when building
75
+ # shopping carts is how to store the items associated with a particular invoice. One method is to serialize Items and storing them as a blob. This causes problem if
76
+ # the object signature changes, as you won't be able to deserialize an object at a later date. The other option is to duplicate the item into another model
77
+ # which is the option acts_as_cart takes (ActiveCart itself can do either, by using a storage engine that supports the serialization option). As such, carts based
78
+ # on act_as_cart will need two tables, most likely named items and cart_items. In theory, cart_items only needs the fields required to fulfill the requirements of
79
+ # rendering an invoice (or general display), but it's probably easier to just duplicate the fields. The cart_items will also require a cart_id and a quantity field
80
+ # acts_as_cart uses the 'original' polymorphic attribute to store a reference to the original Item object. The compound attribute gets nullified if the original Item gets
81
+ # deleted.
82
+ #
83
+ # For complex carts with multiple item types, you will probably need to use STI, as it's basically impossible to use a polymorphic relationship (If someone can
84
+ # suggest a better way, I'm all ears). That said, there is no easy way to model complex carts, so I'll leave this as an exercise for the reader.
85
+ #
86
+ # Options:
87
+ #
88
+ # cart: The cart model. Association as a belongs_to. Default: cart
89
+ # quantity_column: The column that stores the quantity of this item stored in the cart. Default: quantity
90
+ # name_column: The column that stores the name of the item. Default: name
91
+ # price_column: The column that stores the price of the item. Default: price
92
+ # foreign_key: The column that stores the reference to the cart. Default: [cart]_id (Where cart is the value of the cart option)
93
+ #
94
+ # Example
95
+ #
96
+ # class Item < ActiveModel::Base
97
+ # acts_as_item
98
+ # end
99
+ #
100
+ def acts_as_cart_item(options = {})
101
+ cattr_accessor :aaci_config
102
+
103
+ self.aaci_config = {
104
+ :cart => :cart,
105
+ :quantity_column => :quantity,
106
+ :name_column => :name,
107
+ :price_column => :price
108
+ }
109
+ self.aaci_config.merge!(options)
110
+ self.aaci_config[:foreign_key] = (self.aaci_config[:cart].to_s + "_id").to_sym unless options[:foreign_key]
111
+
112
+ class_eval do
113
+ include ActiveCart::Item
114
+
115
+ def id
116
+ read_attribute(:id)
117
+ end
118
+
119
+ def name
120
+ read_attribute(self.aaci_config[:name_column])
121
+ end
122
+
123
+ def quantity
124
+ read_attribute(self.aaci_config[:quantity_column])
125
+ end
126
+
127
+ def quantity=(quantity)
128
+ write_attribute(self.aaci_config[:quantity_column], quantity)
129
+ end
130
+
131
+ def price
132
+ read_attribute(self.aaci_config[:price_column])
133
+ end
134
+ end
135
+
136
+ belongs_to self.aaci_config[:cart], :foreign_key => self.aaci_config[:foreign_key]
137
+ belongs_to :original, :polymorphic => true
138
+ end
139
+ end
140
+ end
141
+
142
+ module OrderTotal
143
+ #:nodoc
144
+ def self.included(mod)
145
+ mod.extend(ClassMethods)
146
+ end
147
+
148
+ module ClassMethods
149
+ # acts_as_order_total - Turns an ActiveModel into an order_total store.
150
+ #
151
+ # In the same way there is a seperation between items and cart_items, there is a difference between concrete order_total objects and this order_total store.
152
+ # This model acts as a way of archiving the order total results for a given cart, so an invoice can be retrieved later. It doesn't matter if the concrete order_total
153
+ # object is an ActiveModel class or not, as long as it matches the api
154
+ #
155
+ # Options:
156
+ #
157
+ # cart: The cart model. Association as a belongs_to. Default: cart
158
+ # name_column: The column that stores the name of the item. Default: name
159
+ # price_column: The column that stores the price of the item. Default: price
160
+ # foreign_key: The column that stores the reference to the cart. Default: [cart]_id (Where cart is the value of the cart option)
161
+ #
162
+ # Example
163
+ #
164
+ # class OrderTotal < ActiveModel::Base
165
+ # acts_as_order_total
166
+ # end
167
+ #
168
+ def acts_as_order_total(options = {})
169
+ cattr_accessor :aaot_config
170
+
171
+ self.aaot_config = {
172
+ :cart => :cart,
173
+ :name_column => :name,
174
+ :price_column => :price
175
+ }
176
+ self.aaot_config.merge!(options)
177
+ self.aaot_config[:foreign_key] = (self.aaot_config[:cart].to_s + "_id").to_sym unless options[:foreign_key]
178
+
179
+ class_eval do
180
+ include ActiveCart::Item
181
+
182
+ def id
183
+ read_attribute(:id)
184
+ end
185
+
186
+ def name
187
+ read_attribute(self.aaot_config[:name_column])
188
+ end
189
+
190
+ def price
191
+ read_attribute(self.aaot_config[:price_column])
192
+ end
193
+ end
194
+
195
+ belongs_to self.aaot_config[:cart], :foreign_key => self.aaot_config[:foreign_key]
196
+ end
197
+ end
198
+ end
199
+ end
200
+ end
201
+
202
+ ActiveRecord::Base.class_eval do
203
+ include ActiveCart::Acts::Cart
204
+ include ActiveCart::Acts::Item
205
+ include ActiveCart::Acts::OrderTotal
206
+ end
@@ -44,15 +44,5 @@ module ActiveCart
44
44
  def name
45
45
  raise NotImplementedError
46
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
47
  end
58
48
  end
data/lib/active_cart.rb CHANGED
@@ -9,6 +9,7 @@ require 'cart_storage'
9
9
  require 'order_total'
10
10
  require 'order_total_collection'
11
11
  require 'cart'
12
+ require 'acts_as_cart' if (Kernel.const_defined?('RAILS_ENV') || Kernel.const_defined?('Rails'))
12
13
 
13
14
  require 'storage_engines/memory'
14
15
  require 'items/memory_item'
@@ -0,0 +1,20 @@
1
+ require 'machinist/active_record'
2
+ require 'sham'
3
+ require 'faker'
4
+
5
+ Cart.blueprint do
6
+ state { 'shopping' }
7
+ end
8
+
9
+ CartItem.blueprint do
10
+ cart { Cart.make }
11
+ name { Faker::Lorem.words(2).join(' ') }
12
+ quantity { rand(10).to_i }
13
+ price { (rand(9999) + 1).to_i / 100 }
14
+ end
15
+
16
+ OrderTotal.blueprint do
17
+ cart { Cart.make }
18
+ name { Faker::Lorem.words(2).join(' ') }
19
+ total { (rand(9999) + 1).to_i / 100 }
20
+ end
@@ -0,0 +1,3 @@
1
+ class Cart < ActiveRecord::Base
2
+ acts_as_cart
3
+ end
@@ -0,0 +1,3 @@
1
+ class CartItem < ActiveRecord::Base
2
+ acts_as_cart_item
3
+ end
@@ -0,0 +1,3 @@
1
+ class OrderTotal < ActiveRecord::Base
2
+ acts_as_order_total
3
+ end
@@ -1,6 +1,7 @@
1
1
  class TestOrderTotal
2
- attr_accessor :price, :active
3
- def initialize(price, active = true)
2
+ attr_accessor :price, :active, :name
3
+ def initialize(name, price, active = true)
4
+ @name = name
4
5
  @price = price
5
6
  @active = active
6
7
  end
data/test/schema.rb ADDED
@@ -0,0 +1,24 @@
1
+ ActiveRecord::Schema.define :version => 0 do
2
+ create_table :carts, :force => true do |t|
3
+ t.string :invoice_id
4
+ t.string :state
5
+ t.string :dummy # Not needed in real carts - used sa a dummy field for testing
6
+ end
7
+
8
+ create_table :cart_items, :force => true do |t|
9
+ t.integer :cart_id
10
+ t.string :name
11
+ t.integer :quantity
12
+ t.float :price
13
+ t.integer :original_id
14
+ t.string :original_type
15
+ t.string :dummy # Not needed in real carts - used sa a dummy field for testing
16
+ end
17
+
18
+ create_table :order_totals, :force => true do |t|
19
+ t.integer :cart_id
20
+ t.string :name
21
+ t.float :total
22
+ t.string :dummy # Not needed in real carts - used sa a dummy field for testing
23
+ end
24
+ end
data/test/test_helper.rb CHANGED
@@ -1,5 +1,6 @@
1
- $:.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
2
1
  $:.unshift(File.join(File.dirname(__FILE__)))
2
+ $:.unshift(File.join(File.dirname(__FILE__), 'fixtures'))
3
+ $:.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
3
4
 
4
5
  require 'rubygems'
5
6
  require 'redgreen'
@@ -12,5 +13,34 @@ require 'mocks/test_cart_storage'
12
13
  require 'mocks/test_item'
13
14
  require 'mocks/test_order_total'
14
15
 
15
- class Test::Unit::TestCase
16
+ require 'active_record'
17
+ require 'active_record/fixtures'
18
+
19
+ # Mock out the required environment variables.
20
+ RAILS_ENV = 'test'
21
+ RAILS_ROOT = Dir.pwd
22
+
23
+ ActiveRecord::Base.logger = Logger.new(File.dirname(__FILE__) + '/log/test.log')
24
+ ActiveRecord::Base.configurations = YAML::load <<-YAML
25
+ sqlite3:
26
+ :adapter: sqlite3
27
+ :database: ':memory:'
28
+ YAML
29
+ ActiveRecord::Base.establish_connection('sqlite3')
30
+
31
+ require 'active_cart/acts_as_cart'
32
+
33
+ # Load Schema
34
+ load(File.dirname(__FILE__) + '/schema.rb')
35
+
36
+ require 'fixtures/cart'
37
+ require 'fixtures/cart_item'
38
+ require 'fixtures/order_total'
39
+ require 'blueprints'
40
+
41
+ class ActiveSupport::TestCase
42
+ include ActiveRecord::TestFixtures
43
+ self.fixture_path = File.dirname(__FILE__) + '/fixtures/'
44
+ self.use_transactional_fixtures = true
45
+ self.use_instantiated_fixtures = false
16
46
  end
@@ -0,0 +1,354 @@
1
+ require 'test_helper'
2
+
3
+ class ActsAsCartTest < ActiveSupport::TestCase
4
+ context '' do
5
+ setup do
6
+ Cart.acts_as_cart
7
+ @cart = Cart.make
8
+ end
9
+
10
+ context 'acts_as_cart' do
11
+ context 'configuration' do
12
+ should 'set defaults' do
13
+ Cart.expects(:aasm_column).with(:state)
14
+ Cart.expects(:has_many).with(:cart_items)
15
+ Cart.expects(:has_many).with(:order_totals)
16
+
17
+ Cart.acts_as_cart
18
+
19
+ assert_equal :state, Cart.aac_config[:state_column]
20
+ assert_equal :invoice_id , Cart.aac_config[:invoice_id_column]
21
+ assert_equal :cart_items , Cart.aac_config[:cart_items]
22
+ assert_equal :order_totals , Cart.aac_config[:order_totals]
23
+
24
+ end
25
+
26
+ context 'override' do
27
+ should 'change state' do
28
+ Cart.expects(:aasm_column).with(:dummy)
29
+ Cart.expects(:has_many).with(:cart_items)
30
+ Cart.expects(:has_many).with(:order_totals)
31
+
32
+ Cart.acts_as_cart :state_column => :dummy
33
+
34
+ assert_equal :dummy, Cart.aac_config[:state_column]
35
+ assert_equal :invoice_id , Cart.aac_config[:invoice_id_column]
36
+ assert_equal :cart_items , Cart.aac_config[:cart_items]
37
+ assert_equal :order_totals , Cart.aac_config[:order_totals]
38
+ end
39
+
40
+ should 'change state getter' do
41
+ Cart.acts_as_cart :state_column => :dummy
42
+ @cart = Cart.make
43
+ @cart.expects(:read_attribute).with(:dummy).returns(:shopping)
44
+ assert :shopping, @cart.state
45
+ end
46
+
47
+ should 'change invoice_id getter' do
48
+ Cart.acts_as_cart :invoice_id_column => :dummy
49
+ @cart = Cart.make
50
+ @cart.expects(:read_attribute).with(:dummy)
51
+ assert :shopping, @cart.invoice_id
52
+ end
53
+
54
+ should 'change cart_items' do
55
+ Cart.expects(:aasm_column).with(:state)
56
+ Cart.expects(:has_many).with(:test)
57
+ Cart.expects(:has_many).with(:order_totals)
58
+
59
+ Cart.acts_as_cart :cart_items => :test
60
+
61
+ assert_equal :state, Cart.aac_config[:state_column]
62
+ assert_equal :invoice_id , Cart.aac_config[:invoice_id_column]
63
+ assert_equal :test , Cart.aac_config[:cart_items]
64
+ assert_equal :order_totals , Cart.aac_config[:order_totals]
65
+ end
66
+
67
+ should 'change order_totals' do
68
+ Cart.expects(:aasm_column).with(:state)
69
+ Cart.expects(:has_many).with(:cart_items)
70
+ Cart.expects(:has_many).with(:test)
71
+
72
+ Cart.acts_as_cart :order_totals => :test
73
+
74
+ assert_equal :state, Cart.aac_config[:state_column]
75
+ assert_equal :invoice_id , Cart.aac_config[:invoice_id_column]
76
+ assert_equal :cart_items , Cart.aac_config[:cart_items]
77
+ assert_equal :test , Cart.aac_config[:order_totals]
78
+ end
79
+ end
80
+ end
81
+
82
+ context 'state' do
83
+ should 'be persistent' do
84
+ @cart.checkout!
85
+ @cart.save!
86
+ @cart = Cart.find(@cart.id)
87
+ assert_equal 'checkout', @cart.state
88
+ assert_nothing_raised do
89
+ @cart.check_payment!
90
+ end
91
+ end
92
+ end
93
+
94
+ context 'cart storage' do
95
+ should 'acts as a array' do
96
+ item = CartItem.make_unsaved(:cart => nil, :quantity => 1)
97
+ assert_nothing_raised do
98
+ @cart << item
99
+ end
100
+
101
+ @cart.save!
102
+ assert_equal 1, @cart.size
103
+ assert_equal 1, @cart.quantity
104
+ assert_equal item, @cart[0]
105
+ end
106
+
107
+ context 'delegate to item' do
108
+ setup do
109
+ @cart << CartItem.make
110
+ @cart.save!
111
+ end
112
+
113
+ should 'delegate []' do
114
+ @cart.cart_items.expects(:[]).with(0)
115
+ @cart[0]
116
+ end
117
+
118
+ should 'delegate <<' do
119
+ test = CartItem.make
120
+ @cart.cart_items.expects(:<<).with(test)
121
+ @cart << test
122
+ end
123
+
124
+ should 'delegate []=' do
125
+ test = CartItem.make
126
+ @cart.cart_items.expects(:[]=).with(0, test)
127
+ @cart[0] = test
128
+ end
129
+
130
+ should 'delegate :at' do
131
+ @cart.cart_items.expects(:at).with(1)
132
+ @cart.at(1)
133
+ end
134
+
135
+ should 'delegate :clear' do
136
+ @cart.cart_items.expects(:clear)
137
+ @cart.clear
138
+ end
139
+
140
+ should 'delegate :collect' do
141
+ @cart.cart_items.expects(:collect)
142
+ @cart.collect
143
+ end
144
+
145
+ should 'delegate :map' do
146
+ @cart.cart_items.expects(:map)
147
+ @cart.map
148
+ end
149
+
150
+ should 'delegate :delete' do
151
+ test = CartItem.make
152
+ @cart.cart_items.expects(:delete).with(test)
153
+ @cart.delete(test)
154
+ end
155
+
156
+ should 'delegate :delete_at' do
157
+ @cart.cart_items.expects(:delete_at).with(3)
158
+ @cart.delete_at(3)
159
+ end
160
+
161
+ should 'delegate :each' do
162
+ @cart.cart_items.expects(:each)
163
+ @cart.each
164
+ end
165
+
166
+ should 'delegate :each_index' do
167
+ @cart.cart_items.expects(:each_index)
168
+ @cart.each_index
169
+ end
170
+
171
+ should 'delegate :empty' do
172
+ @cart.cart_items.expects(:empty?)
173
+ @cart.empty?
174
+ end
175
+
176
+ should 'delegate :eql?' do
177
+ @cart.cart_items.expects(:eql?)
178
+ @cart.eql?
179
+ end
180
+
181
+ should 'delegate :first' do
182
+ @cart.cart_items.expects(:first)
183
+ @cart.first
184
+ end
185
+
186
+ should 'delegate :include?' do
187
+ item = CartItem.make
188
+ @cart.cart_items.expects(:include?).with(CartItem.make)
189
+ @cart.include?(item)
190
+ end
191
+
192
+ should 'delegate :index' do
193
+ @cart.cart_items.expects(:index)
194
+ @cart.index
195
+ end
196
+
197
+ should 'delegate :inject' do
198
+ @cart.cart_items.expects(:inject)
199
+ @cart.inject
200
+ end
201
+
202
+ should 'delegate :last' do
203
+ @cart.cart_items.expects(:last)
204
+ @cart.last
205
+ end
206
+
207
+ should 'delegate :length' do
208
+ @cart.cart_items.expects(:length)
209
+ @cart.length
210
+ end
211
+
212
+ should 'delegate :pop' do
213
+ @cart.cart_items.expects(:pop)
214
+ @cart.pop
215
+ end
216
+
217
+ should 'delegate :push' do
218
+ item = CartItem.make
219
+ @cart.cart_items.expects(:push).with(item)
220
+ @cart.push(item)
221
+ end
222
+
223
+ should 'delegate :shift' do
224
+ @cart.cart_items.expects(:shift)
225
+ @cart.shift
226
+ end
227
+
228
+ should 'delegate :size' do
229
+ @cart.cart_items.expects(:size)
230
+ @cart.size
231
+ end
232
+
233
+ should 'delegate :unshift' do
234
+ @cart.cart_items.expects(:unshift)
235
+ @cart.unshift
236
+ end
237
+ end
238
+ end
239
+ end
240
+
241
+ context 'acts_as_cart_item' do
242
+ context 'configuration' do
243
+ should 'set defaults' do
244
+ CartItem.acts_as_cart_item
245
+
246
+ assert_equal :cart, CartItem.aaci_config[:cart]
247
+ assert_equal :quantity , CartItem.aaci_config[:quantity_column]
248
+ assert_equal :name , CartItem.aaci_config[:name_column]
249
+ assert_equal :price , CartItem.aaci_config[:price_column]
250
+ end
251
+
252
+ context 'override' do
253
+ should 'change quantity column' do
254
+ CartItem.acts_as_cart_item :quantity_column => :dummy
255
+ @cart = CartItem.make
256
+ @cart.expects(:read_attribute).with(:dummy)
257
+ @cart.quantity
258
+ end
259
+
260
+ should 'change name column' do
261
+ CartItem.acts_as_cart_item :name_column => :dummy
262
+ @cart = CartItem.make
263
+ @cart.expects(:read_attribute).with(:dummy)
264
+ @cart.name
265
+ end
266
+
267
+ should 'change price column' do
268
+ CartItem.acts_as_cart_item :price_column => :dummy
269
+ @cart = CartItem.make
270
+ @cart.expects(:read_attribute).with(:dummy)
271
+ @cart.price
272
+ end
273
+
274
+ should 'change cart_items' do
275
+ CartItem.acts_as_cart_item :cart => :test
276
+
277
+ assert_equal :test, CartItem.aaci_config[:cart]
278
+ assert_equal :quantity , CartItem.aaci_config[:quantity_column]
279
+ assert_equal :name , CartItem.aaci_config[:name_column]
280
+ assert_equal :price , CartItem.aaci_config[:price_column]
281
+ end
282
+
283
+ should 'change the foreign_key' do
284
+ CartItem.acts_as_cart_item :foreign_key => :test_id
285
+
286
+ assert_equal :cart, CartItem.aaci_config[:cart]
287
+ assert_equal :name , CartItem.aaci_config[:name_column]
288
+ assert_equal :price , CartItem.aaci_config[:price_column]
289
+ assert_equal :test_id, CartItem.aaci_config[:foreign_key]
290
+ end
291
+ end
292
+ end
293
+ end
294
+
295
+ context 'acts_as_order_total' do
296
+ context 'configuration' do
297
+ should 'set defaults' do
298
+ OrderTotal.acts_as_order_total
299
+
300
+ assert_equal :cart, OrderTotal.aaot_config[:cart]
301
+ assert_equal :name , OrderTotal.aaot_config[:name_column]
302
+ assert_equal :price , OrderTotal.aaot_config[:price_column]
303
+ assert_equal :cart_id, OrderTotal.aaot_config[:foreign_key]
304
+ end
305
+
306
+ context 'override' do
307
+ should 'change name column' do
308
+ OrderTotal.acts_as_order_total :name_column => :dummy
309
+ @order_total = OrderTotal.make
310
+ @order_total.expects(:read_attribute).with(:dummy)
311
+ @order_total.name
312
+ end
313
+
314
+ should 'change price column' do
315
+ OrderTotal.acts_as_order_total :price_column => :dummy
316
+ @order_total = OrderTotal.make
317
+ @order_total.expects(:read_attribute).with(:dummy)
318
+ @order_total.price
319
+ end
320
+
321
+ should 'change the foreign_key' do
322
+ OrderTotal.acts_as_order_total :foreign_key => :test_id
323
+
324
+ assert_equal :cart, OrderTotal.aaot_config[:cart]
325
+ assert_equal :name , OrderTotal.aaot_config[:name_column]
326
+ assert_equal :price , OrderTotal.aaot_config[:price_column]
327
+ assert_equal :test_id, OrderTotal.aaot_config[:foreign_key]
328
+ end
329
+
330
+ should 'change cart_items' do
331
+ OrderTotal.acts_as_order_total :cart => :test
332
+
333
+ assert_equal :test, OrderTotal.aaot_config[:cart]
334
+ assert_equal :name , OrderTotal.aaot_config[:name_column]
335
+ assert_equal :price , OrderTotal.aaot_config[:price_column]
336
+ assert_equal :test_id, OrderTotal.aaot_config[:foreign_key]
337
+ end
338
+ end
339
+ end
340
+
341
+ context 'state' do
342
+ should 'be persistent' do
343
+ @cart.checkout!
344
+ @cart.save!
345
+ @cart = Cart.find(@cart.id)
346
+ assert_equal 'checkout', @cart.state
347
+ assert_nothing_raised do
348
+ @cart.check_payment!
349
+ end
350
+ end
351
+ end
352
+ end
353
+ end
354
+ end
@@ -1,6 +1,6 @@
1
1
  require 'test_helper'
2
2
 
3
- class CartStorageTest < Test::Unit::TestCase
3
+ class CartStorageTest < ActiveSupport::TestCase
4
4
  context '' do
5
5
  setup do
6
6
  @cart_storage_engine = TestCartStorage.new
@@ -1,6 +1,6 @@
1
1
  require 'test_helper'
2
2
 
3
- class CartTest < Test::Unit::TestCase
3
+ class CartTest < ActiveSupport::TestCase
4
4
  context '' do
5
5
  context 'after setup' do
6
6
  setup do
@@ -219,8 +219,8 @@ class CartTest < Test::Unit::TestCase
219
219
 
220
220
  context 'setup' do
221
221
  should 'take a block to add order_totals' do
222
- @total_1 = TestOrderTotal.new(10, true)
223
- @total_2 = TestOrderTotal.new(20, true)
222
+ @total_1 = TestOrderTotal.new('Total 1', 10, true)
223
+ @total_2 = TestOrderTotal.new('Total 2', 20, true)
224
224
 
225
225
  @cart_storage_engine = TestCartStorage.new
226
226
  @cart = ActiveCart::Cart.new(@cart_storage_engine) do |o|
@@ -239,8 +239,8 @@ class CartTest < Test::Unit::TestCase
239
239
  @item_2.price = 20
240
240
  @item_3 = TestItem.new(3)
241
241
  @item_3.price = 30
242
- @total_1 = TestOrderTotal.new(10, true)
243
- @total_2 = TestOrderTotal.new(20, true)
242
+ @total_1 = TestOrderTotal.new('Total 1', 10, true)
243
+ @total_2 = TestOrderTotal.new('Total 2', 20, true)
244
244
 
245
245
  @cart.order_total_calculators += [ @total_1, @total_2 ]
246
246
  @cart.add_to_cart(@item_1)
@@ -1,6 +1,6 @@
1
1
  require 'test_helper'
2
2
 
3
- class ItemTest < Test::Unit::TestCase
3
+ class ItemTest < ActiveSupport::TestCase
4
4
  context '' do
5
5
  should '' do
6
6
  assert true
@@ -1,6 +1,6 @@
1
1
  require 'test_helper'
2
2
 
3
- class OrderTotalCollectionTest < Test::Unit::TestCase
3
+ class OrderTotalCollectionTest < ActiveSupport::TestCase
4
4
  context '' do
5
5
  setup do
6
6
  @cart_storage_engine = TestCartStorage.new
@@ -72,10 +72,10 @@ class OrderTotalCollectionTest < Test::Unit::TestCase
72
72
 
73
73
  context 'total' do
74
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)
75
+ @total_1 = TestOrderTotal.new('Total 1', 10, true)
76
+ @total_2 = TestOrderTotal.new('Total 2', 5, false)
77
+ @total_3 = TestOrderTotal.new('Total 3', 2, true)
78
+ @total_4 = TestOrderTotal.new('Total 4', 14, true)
79
79
  end
80
80
 
81
81
  should 'call price on each order_total item that are active' do
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: active_cart
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.4
4
+ version: 0.0.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Myles Eftos
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2010-02-27 00:00:00 +08:00
12
+ date: 2010-02-28 00:00:00 +08:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
@@ -52,6 +52,26 @@ dependencies:
52
52
  - !ruby/object:Gem::Version
53
53
  version: "0"
54
54
  version:
55
+ - !ruby/object:Gem::Dependency
56
+ name: machinist
57
+ type: :development
58
+ version_requirement:
59
+ version_requirements: !ruby/object:Gem::Requirement
60
+ requirements:
61
+ - - ">="
62
+ - !ruby/object:Gem::Version
63
+ version: "0"
64
+ version:
65
+ - !ruby/object:Gem::Dependency
66
+ name: faker
67
+ type: :development
68
+ version_requirement:
69
+ version_requirements: !ruby/object:Gem::Requirement
70
+ requirements:
71
+ - - ">="
72
+ - !ruby/object:Gem::Version
73
+ version: "0"
74
+ version:
55
75
  description: You can use active_cart as the basis of a shopping cart system. It's not a shopping cart application - it's a shopping cart framework.
56
76
  email: myles@madpilot.com.au
57
77
  executables: []
@@ -67,6 +87,7 @@ files:
67
87
  - VERSION
68
88
  - install.rb
69
89
  - lib/active_cart.rb
90
+ - lib/active_cart/acts_as_cart.rb
70
91
  - lib/active_cart/cart.rb
71
92
  - lib/active_cart/cart_storage.rb
72
93
  - lib/active_cart/item.rb
@@ -74,11 +95,17 @@ files:
74
95
  - lib/active_cart/order_total.rb
75
96
  - lib/active_cart/order_total_collection.rb
76
97
  - lib/active_cart/storage_engines/memory.rb
98
+ - test/blueprints.rb
99
+ - test/fixtures/cart.rb
100
+ - test/fixtures/cart_item.rb
101
+ - test/fixtures/order_total.rb
77
102
  - test/mocks/test_cart_storage.rb
78
103
  - test/mocks/test_item.rb
79
104
  - test/mocks/test_order_total.rb
80
105
  - test/performance/browsing_test.rb
106
+ - test/schema.rb
81
107
  - test/test_helper.rb
108
+ - test/unit/acts_as_cart_test.rb
82
109
  - test/unit/cart_storage_test.rb
83
110
  - test/unit/cart_test.rb
84
111
  - test/unit/item_test.rb
@@ -116,9 +143,15 @@ test_files:
116
143
  - test/unit/order_total_collection_test.rb
117
144
  - test/unit/cart_storage_test.rb
118
145
  - test/unit/cart_test.rb
146
+ - test/unit/acts_as_cart_test.rb
119
147
  - test/unit/item_test.rb
120
148
  - test/mocks/test_cart_storage.rb
121
149
  - test/mocks/test_order_total.rb
122
150
  - test/mocks/test_item.rb
151
+ - test/schema.rb
152
+ - test/fixtures/cart_item.rb
153
+ - test/fixtures/order_total.rb
154
+ - test/fixtures/cart.rb
155
+ - test/blueprints.rb
123
156
  - test/test_helper.rb
124
157
  - test/performance/browsing_test.rb