reactive_shipping 3.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +15 -0
- data/.travis.yml +33 -0
- data/.yardopts +13 -0
- data/CHANGELOG.md +225 -0
- data/CONTRIBUTING.md +23 -0
- data/Gemfile +3 -0
- data/MIT-LICENSE +21 -0
- data/README.md +158 -0
- data/Rakefile +35 -0
- data/dev.yml +17 -0
- data/gemfiles/activesupport42.gemfile +5 -0
- data/gemfiles/activesupport50.gemfile +6 -0
- data/gemfiles/activesupport51.gemfile +5 -0
- data/gemfiles/activesupport52.gemfile +5 -0
- data/gemfiles/activesupport_master.gemfile +5 -0
- data/lib/certs/eParcel.dtd +111 -0
- data/lib/reactive_shipping.rb +26 -0
- data/lib/reactive_shipping/address_validation_response.rb +30 -0
- data/lib/reactive_shipping/carrier.rb +184 -0
- data/lib/reactive_shipping/carriers.rb +35 -0
- data/lib/reactive_shipping/carriers/australia_post.rb +248 -0
- data/lib/reactive_shipping/carriers/benchmark_carrier.rb +31 -0
- data/lib/reactive_shipping/carriers/bogus_carrier.rb +12 -0
- data/lib/reactive_shipping/carriers/canada_post.rb +263 -0
- data/lib/reactive_shipping/carriers/canada_post_pws.rb +908 -0
- data/lib/reactive_shipping/carriers/fedex.rb +797 -0
- data/lib/reactive_shipping/carriers/kunaki.rb +155 -0
- data/lib/reactive_shipping/carriers/new_zealand_post.rb +260 -0
- data/lib/reactive_shipping/carriers/shipwire.rb +178 -0
- data/lib/reactive_shipping/carriers/stamps.rb +860 -0
- data/lib/reactive_shipping/carriers/ups.rb +1060 -0
- data/lib/reactive_shipping/carriers/usps.rb +708 -0
- data/lib/reactive_shipping/carriers/usps_returns.rb +86 -0
- data/lib/reactive_shipping/delivery_date_estimate.rb +20 -0
- data/lib/reactive_shipping/delivery_date_estimates_response.rb +11 -0
- data/lib/reactive_shipping/errors.rb +35 -0
- data/lib/reactive_shipping/external_return_label_request.rb +417 -0
- data/lib/reactive_shipping/external_return_label_response.rb +26 -0
- data/lib/reactive_shipping/label.rb +10 -0
- data/lib/reactive_shipping/label_response.rb +10 -0
- data/lib/reactive_shipping/location.rb +166 -0
- data/lib/reactive_shipping/package.rb +165 -0
- data/lib/reactive_shipping/package_item.rb +60 -0
- data/lib/reactive_shipping/rate_estimate.rb +197 -0
- data/lib/reactive_shipping/rate_response.rb +33 -0
- data/lib/reactive_shipping/response.rb +44 -0
- data/lib/reactive_shipping/shipment_event.rb +22 -0
- data/lib/reactive_shipping/shipment_packer.rb +108 -0
- data/lib/reactive_shipping/shipping_response.rb +34 -0
- data/lib/reactive_shipping/tracking_response.rb +120 -0
- data/lib/reactive_shipping/version.rb +3 -0
- data/reactive_shipping.gemspec +38 -0
- data/shipit.rubygems.yml +1 -0
- data/test/console.rb +39 -0
- data/test/credentials.yml +76 -0
- data/test/fixtures/files/label1.pdf +0 -0
- data/test/fixtures/files/ups-shipping-label.gif +0 -0
- data/test/fixtures/json/australia_post/calculate_domestic.json +13 -0
- data/test/fixtures/json/australia_post/calculate_domestic_2.json +19 -0
- data/test/fixtures/json/australia_post/calculate_international.json +12 -0
- data/test/fixtures/json/australia_post/calculate_international_2.json +15 -0
- data/test/fixtures/json/australia_post/error_message.json +5 -0
- data/test/fixtures/json/australia_post/service_domestic.json +117 -0
- data/test/fixtures/json/australia_post/service_domestic_2.json +117 -0
- data/test/fixtures/json/australia_post/service_international.json +76 -0
- data/test/fixtures/json/australia_post/service_international_2.json +59 -0
- data/test/fixtures/json/newzealandpost/domestic_book.json +1 -0
- data/test/fixtures/json/newzealandpost/domestic_default.json +1 -0
- data/test/fixtures/json/newzealandpost/domestic_error.json +1 -0
- data/test/fixtures/json/newzealandpost/domestic_poster.json +1 -0
- data/test/fixtures/json/newzealandpost/domestic_small_half_pound.json +1 -0
- data/test/fixtures/json/newzealandpost/international_book.json +1 -0
- data/test/fixtures/json/newzealandpost/international_new_zealand_wii.json +1 -0
- data/test/fixtures/json/newzealandpost/international_small_half_pound.json +1 -0
- data/test/fixtures/json/newzealandpost/international_wii.json +1 -0
- data/test/fixtures/xml/canadapost/example_request.xml +25 -0
- data/test/fixtures/xml/canadapost/example_response.xml +130 -0
- data/test/fixtures/xml/canadapost/example_response_error.xml +16 -0
- data/test/fixtures/xml/canadapost/example_response_french.xml +122 -0
- data/test/fixtures/xml/canadapost/example_response_with_nil_value.xml +164 -0
- data/test/fixtures/xml/canadapost/example_response_with_postal_outlet.xml +155 -0
- data/test/fixtures/xml/canadapost/example_response_with_postal_outlet_french.xml +274 -0
- data/test/fixtures/xml/canadapost/example_response_with_strange_delivery_date.xml +130 -0
- data/test/fixtures/xml/canadapost_pws/dnc_tracking_details_en.xml +112 -0
- data/test/fixtures/xml/canadapost_pws/merchant_details_error.xml +7 -0
- data/test/fixtures/xml/canadapost_pws/merchant_details_response.xml +7 -0
- data/test/fixtures/xml/canadapost_pws/option_response.xml +13 -0
- data/test/fixtures/xml/canadapost_pws/option_response_no_conflicts.xml +7 -0
- data/test/fixtures/xml/canadapost_pws/rates_info.xml +190 -0
- data/test/fixtures/xml/canadapost_pws/rates_info_error.xml +7 -0
- data/test/fixtures/xml/canadapost_pws/receipt_response.xml +42 -0
- data/test/fixtures/xml/canadapost_pws/receipt_response_no_priced_options.xml +36 -0
- data/test/fixtures/xml/canadapost_pws/register_token_error.xml +7 -0
- data/test/fixtures/xml/canadapost_pws/register_token_response.xml +3 -0
- data/test/fixtures/xml/canadapost_pws/service_options_response.xml +42 -0
- data/test/fixtures/xml/canadapost_pws/services_error.xml +6 -0
- data/test/fixtures/xml/canadapost_pws/services_response.xml +32 -0
- data/test/fixtures/xml/canadapost_pws/shipment_domestic.xml +69 -0
- data/test/fixtures/xml/canadapost_pws/shipment_response.xml +20 -0
- data/test/fixtures/xml/canadapost_pws/shipment_us.xml +69 -0
- data/test/fixtures/xml/canadapost_pws/tracking_details_en.xml +152 -0
- data/test/fixtures/xml/canadapost_pws/tracking_details_en_error.xml +7 -0
- data/test/fixtures/xml/canadapost_pws/tracking_details_en_undelivered.xml +116 -0
- data/test/fixtures/xml/canadapost_pws/tracking_details_fr.xml +156 -0
- data/test/fixtures/xml/canadapost_pws/tracking_details_no_expected_delivery_date.xml +40 -0
- data/test/fixtures/xml/fedex/create_shipment_response.xml +2 -0
- data/test/fixtures/xml/fedex/freight_rate_request.xml +82 -0
- data/test/fixtures/xml/fedex/freight_rate_response.xml +506 -0
- data/test/fixtures/xml/fedex/invalid_fedex_reply.xml +27 -0
- data/test/fixtures/xml/fedex/ottawa_to_beverly_hills_commercial_rate_request.xml +79 -0
- data/test/fixtures/xml/fedex/ottawa_to_beverly_hills_no_saturday_rate_request.xml +79 -0
- data/test/fixtures/xml/fedex/ottawa_to_beverly_hills_rate_request.xml +80 -0
- data/test/fixtures/xml/fedex/ottawa_to_beverly_hills_rate_response.xml +214 -0
- data/test/fixtures/xml/fedex/raterequest_reply.xml +213 -0
- data/test/fixtures/xml/fedex/raterequest_response_with_ground_home_delivery.xml +206 -0
- data/test/fixtures/xml/fedex/reply_without_notifications.xml +185 -0
- data/test/fixtures/xml/fedex/tracking_request.xml +29 -0
- data/test/fixtures/xml/fedex/tracking_response_bad_tracking_number.xml +20 -0
- data/test/fixtures/xml/fedex/tracking_response_delivered_at_door.xml +254 -0
- data/test/fixtures/xml/fedex/tracking_response_delivered_at_facility.xml +403 -0
- data/test/fixtures/xml/fedex/tracking_response_delivered_with_signature.xml +269 -0
- data/test/fixtures/xml/fedex/tracking_response_empty_status_detail.xml +84 -0
- data/test/fixtures/xml/fedex/tracking_response_failure_code_9045.xml +52 -0
- data/test/fixtures/xml/fedex/tracking_response_failure_code_9080.xml +51 -0
- data/test/fixtures/xml/fedex/tracking_response_in_transit.xml +127 -0
- data/test/fixtures/xml/fedex/tracking_response_invalid_tracking_number.xml +52 -0
- data/test/fixtures/xml/fedex/tracking_response_missing_status_code.xml +89 -0
- data/test/fixtures/xml/fedex/tracking_response_multiple_results.xml +100 -0
- data/test/fixtures/xml/fedex/tracking_response_not_found.xml +52 -0
- data/test/fixtures/xml/fedex/tracking_response_shipment_exception.xml +209 -0
- data/test/fixtures/xml/fedex/tracking_response_unable_to_process.xml +32 -0
- data/test/fixtures/xml/fedex/tracking_response_with_blank_state.xml +107 -0
- data/test/fixtures/xml/fedex/unknown_fedex_document_reply.xml +3 -0
- data/test/fixtures/xml/kunaki/invalid_state_response.xml +3 -0
- data/test/fixtures/xml/kunaki/no_valid_items_response.xml +3 -0
- data/test/fixtures/xml/kunaki/successful_rates_response.xml +3 -0
- data/test/fixtures/xml/kunaki/unsuccessful_rates_response.xml +9 -0
- data/test/fixtures/xml/shipwire/international_rates_response.xml +17 -0
- data/test/fixtures/xml/shipwire/new_carrier_rate_response.xml +18 -0
- data/test/fixtures/xml/shipwire/no_rates_response.xml +7 -0
- data/test/fixtures/xml/shipwire/rates_response.xml +36 -0
- data/test/fixtures/xml/shipwire/rates_response_no_estimate.xml +14 -0
- data/test/fixtures/xml/stamps/authenticate_user_request.xml +15 -0
- data/test/fixtures/xml/stamps/authenticate_user_response.xml +10 -0
- data/test/fixtures/xml/stamps/cleanse_address_request.xml +19 -0
- data/test/fixtures/xml/stamps/cleanse_address_response.xml +27 -0
- data/test/fixtures/xml/stamps/create_indicium_request.xml +69 -0
- data/test/fixtures/xml/stamps/create_indicium_response.xml +40 -0
- data/test/fixtures/xml/stamps/expired_authenticator_response.xml +15 -0
- data/test/fixtures/xml/stamps/get_account_info_request.xml +11 -0
- data/test/fixtures/xml/stamps/get_account_info_response.xml +36 -0
- data/test/fixtures/xml/stamps/get_purchase_status_request.xml +12 -0
- data/test/fixtures/xml/stamps/get_purchase_status_response.xml +16 -0
- data/test/fixtures/xml/stamps/get_rates_request.xml +19 -0
- data/test/fixtures/xml/stamps/get_rates_response.xml +351 -0
- data/test/fixtures/xml/stamps/purchase_postage_request.xml +13 -0
- data/test/fixtures/xml/stamps/purchase_postage_response.xml +17 -0
- data/test/fixtures/xml/stamps/track_shipment_request.xml +12 -0
- data/test/fixtures/xml/stamps/track_shipment_response.xml +45 -0
- data/test/fixtures/xml/ups/access_request.xml +6 -0
- data/test/fixtures/xml/ups/delivered_shipment_with_refund.xml +290 -0
- data/test/fixtures/xml/ups/delivered_shipment_without_events_tracking_response.xml +62 -0
- data/test/fixtures/xml/ups/delivery_dates_response.xml +140 -0
- data/test/fixtures/xml/ups/example_tracking_response.xml +53 -0
- data/test/fixtures/xml/ups/in_transit_shipment.xml +183 -0
- data/test/fixtures/xml/ups/out_for_delivery_shipment.xml +165 -0
- data/test/fixtures/xml/ups/package_exceeds_maximum_length.xml +12 -0
- data/test/fixtures/xml/ups/rate_single_service.xml +54 -0
- data/test/fixtures/xml/ups/rescheduled_shipment.xml +204 -0
- data/test/fixtures/xml/ups/shipment_accept_response.xml +42 -0
- data/test/fixtures/xml/ups/shipment_confirm_response.xml +33 -0
- data/test/fixtures/xml/ups/shipment_from_tiger_direct.xml +222 -0
- data/test/fixtures/xml/ups/test_real_home_as_residential_destination_response.xml +290 -0
- data/test/fixtures/xml/ups/test_real_home_as_residential_destination_response_with_insured.xml +289 -0
- data/test/fixtures/xml/ups/test_real_home_as_residential_destination_with_origin_account_response.xml +311 -0
- data/test/fixtures/xml/ups/tracking_request.xml +9 -0
- data/test/fixtures/xml/ups/triple_accept_response.xml +72 -0
- data/test/fixtures/xml/ups/triple_confirm_response.xml +32 -0
- data/test/fixtures/xml/ups/void_shipment_response.xml +11 -0
- data/test/fixtures/xml/usps/api_error_rate_response.xml +53 -0
- data/test/fixtures/xml/usps/beverly_hills_to_new_york_book_commercial_base_rate_response.xml +2 -0
- data/test/fixtures/xml/usps/beverly_hills_to_new_york_book_commercial_plus_rate_response.xml +258 -0
- data/test/fixtures/xml/usps/beverly_hills_to_new_york_book_rate_response.xml +108 -0
- data/test/fixtures/xml/usps/beverly_hills_to_ottawa_american_wii_commercial_base_rate_response.xml +84 -0
- data/test/fixtures/xml/usps/beverly_hills_to_ottawa_american_wii_commercial_plus_rate_response.xml +212 -0
- data/test/fixtures/xml/usps/beverly_hills_to_ottawa_american_wii_rate_response.xml +230 -0
- data/test/fixtures/xml/usps/first_class_packages_with_invalid_mail_type_response.xml +12 -0
- data/test/fixtures/xml/usps/first_class_packages_with_mail_type_response.xml +16 -0
- data/test/fixtures/xml/usps/first_class_packages_without_mail_type_response.xml +12 -0
- data/test/fixtures/xml/usps/invalid_xml_response.xml +10 -0
- data/test/fixtures/xml/usps/invalid_xml_tracking_response_error.xml +2 -0
- data/test/fixtures/xml/usps/tracking_request.xml +10 -0
- data/test/fixtures/xml/usps/tracking_request_batch.xml +12 -0
- data/test/fixtures/xml/usps/tracking_response.xml +162 -0
- data/test/fixtures/xml/usps/tracking_response_alt.xml +53 -0
- data/test/fixtures/xml/usps/tracking_response_batch.xml +231 -0
- data/test/fixtures/xml/usps/tracking_response_failure.xml +11 -0
- data/test/fixtures/xml/usps/tracking_response_not_available.xml +12 -0
- data/test/fixtures/xml/usps/tracking_response_test_error.xml +8 -0
- data/test/fixtures/xml/usps/us_rate_request.xml +18 -0
- data/test/fixtures/xml/usps/us_rate_request_large.xml +18 -0
- data/test/fixtures/xml/usps/world_rate_request_only_country.xml +22 -0
- data/test/fixtures/xml/usps/world_rate_request_with_value.xml +24 -0
- data/test/fixtures/xml/usps/world_rate_request_without_value.xml +24 -0
- data/test/fixtures/xml/usps_returns/external_return_label_response.xml +2 -0
- data/test/fixtures/xml/usps_returns/external_return_label_response_failure.xml +10 -0
- data/test/remote/australia_post_test.rb +140 -0
- data/test/remote/canada_post_pws_platform_test.rb +259 -0
- data/test/remote/canada_post_pws_test.rb +169 -0
- data/test/remote/canada_post_test.rb +55 -0
- data/test/remote/fedex_test.rb +400 -0
- data/test/remote/kunaki_test.rb +37 -0
- data/test/remote/new_zealand_post_test.rb +149 -0
- data/test/remote/shipwire_test.rb +84 -0
- data/test/remote/stamps_test.rb +396 -0
- data/test/remote/usps_returns_test.rb +72 -0
- data/test/remote/usps_test.rb +243 -0
- data/test/test_helper.rb +296 -0
- data/test/unit/carrier_test.rb +130 -0
- data/test/unit/carriers/australia_post_test.rb +181 -0
- data/test/unit/carriers/benchmark_test.rb +18 -0
- data/test/unit/carriers/canada_post_pws_rating_test.rb +379 -0
- data/test/unit/carriers/canada_post_pws_register_test.rb +76 -0
- data/test/unit/carriers/canada_post_pws_shipping_test.rb +258 -0
- data/test/unit/carriers/canada_post_pws_test.rb +59 -0
- data/test/unit/carriers/canada_post_pws_tracking_test.rb +154 -0
- data/test/unit/carriers/canada_post_test.rb +148 -0
- data/test/unit/carriers/fedex_test.rb +693 -0
- data/test/unit/carriers/kunaki_test.rb +56 -0
- data/test/unit/carriers/new_zealand_post_test.rb +177 -0
- data/test/unit/carriers/shipwire_test.rb +188 -0
- data/test/unit/carriers/stamps_test.rb +245 -0
- data/test/unit/carriers/ups_test.rb +580 -0
- data/test/unit/carriers/usps_returns_test.rb +45 -0
- data/test/unit/carriers/usps_test.rb +633 -0
- data/test/unit/carriers_test.rb +16 -0
- data/test/unit/external_return_label_request_test.rb +258 -0
- data/test/unit/location_test.rb +234 -0
- data/test/unit/package_item_test.rb +232 -0
- data/test/unit/package_test.rb +404 -0
- data/test/unit/rate_estimate_test.rb +93 -0
- data/test/unit/response_test.rb +38 -0
- data/test/unit/shipment_event_test.rb +20 -0
- data/test/unit/shipment_packer_test.rb +212 -0
- data/test/unit/tracking_response_test.rb +41 -0
- metadata +684 -0
@@ -0,0 +1,232 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
class PackageItemTest < ActiveSupport::TestCase
|
4
|
+
setup do
|
5
|
+
@name = "Fancy Pants"
|
6
|
+
@weight = 100
|
7
|
+
@value = 1299
|
8
|
+
@quantity = 3
|
9
|
+
@sku = "1234567890"
|
10
|
+
@hs_code = "1234.56.78"
|
11
|
+
@options = {
|
12
|
+
units: :metric,
|
13
|
+
sku: @sku,
|
14
|
+
hs_code: @hs_code,
|
15
|
+
type: :actual,
|
16
|
+
}
|
17
|
+
|
18
|
+
@item = PackageItem.new(@name, @weight, @value, @quantity, @options)
|
19
|
+
@mass = Measured::Weight.new(@weight, :grams)
|
20
|
+
end
|
21
|
+
|
22
|
+
test "#initialize with all attributes" do
|
23
|
+
assert_equal @name, @item.name
|
24
|
+
assert_equal @options, @item.options
|
25
|
+
assert_equal @hs_code, @item.hs_code
|
26
|
+
assert_equal @sku, @item.sku
|
27
|
+
assert_equal @value, @item.value
|
28
|
+
assert_equal @quantity, @item.quantity
|
29
|
+
end
|
30
|
+
|
31
|
+
test "#initialize assumes symbol keys" do
|
32
|
+
options = {
|
33
|
+
"units" => :imperial,
|
34
|
+
"sku" => @sku,
|
35
|
+
"hs_code" => @hs_code,
|
36
|
+
}
|
37
|
+
@item = PackageItem.new(@name, @weight, @value, @quantity, options)
|
38
|
+
|
39
|
+
assert_nil @item.hs_code
|
40
|
+
assert_nil @item.sku
|
41
|
+
refute_equal @weight, @item.ounces
|
42
|
+
assert_equal @weight, @item.grams
|
43
|
+
end
|
44
|
+
|
45
|
+
test "#initialize with a negative quantity" do
|
46
|
+
assert_equal 1, PackageItem.new(@name, @weight, @value, -1).quantity
|
47
|
+
assert_equal 1, PackageItem.new(@name, @weight, @value, 0).quantity
|
48
|
+
end
|
49
|
+
|
50
|
+
test "#initialize weight mass object" do
|
51
|
+
@item = PackageItem.new(@name, @mass, @value, @quantity, @options)
|
52
|
+
assert_equal @mass, @item.weight
|
53
|
+
end
|
54
|
+
|
55
|
+
test "#initialize weight default metric" do
|
56
|
+
assert_equal @weight, @item.grams
|
57
|
+
refute_equal @weight, @item.ounces
|
58
|
+
end
|
59
|
+
|
60
|
+
test "#initialize weight accepts imperial" do
|
61
|
+
@item = PackageItem.new(@name, @weight, @value, @quantity, @options.merge(units: :imperial))
|
62
|
+
|
63
|
+
assert_equal @weight, @item.ounces
|
64
|
+
refute_equal @weight, @item.grams
|
65
|
+
end
|
66
|
+
|
67
|
+
test "#initialize_weight accepts metric" do
|
68
|
+
@item = PackageItem.new(@name, @weight, @value, @quantity, @options.merge(units: :metric))
|
69
|
+
|
70
|
+
assert_equal @weight, @item.grams
|
71
|
+
refute_equal @weight, @item.ounces
|
72
|
+
end
|
73
|
+
|
74
|
+
test "#initialize weight does not accept strings" do
|
75
|
+
@item = PackageItem.new(@name, @weight, @value, @quantity, @options.merge(units: "imperial"))
|
76
|
+
|
77
|
+
assert_equal @weight, @item.grams
|
78
|
+
refute_equal @weight, @item.ounces
|
79
|
+
end
|
80
|
+
|
81
|
+
test "#initialize value from cents" do
|
82
|
+
@item = PackageItem.new(@name, @weight, "1.23", @quantity, @options)
|
83
|
+
|
84
|
+
assert_equal 123, @item.value
|
85
|
+
end
|
86
|
+
|
87
|
+
test "#weight default lookup" do
|
88
|
+
assert_equal @mass, @item.weight
|
89
|
+
assert_instance_of Measured::Weight, @item.weight
|
90
|
+
end
|
91
|
+
|
92
|
+
test "#weight type: actual" do
|
93
|
+
assert_equal @mass, @item.weight(type: :actual)
|
94
|
+
assert_instance_of Measured::Weight, @item.weight(type: :actual)
|
95
|
+
end
|
96
|
+
|
97
|
+
test "#weight type: volumetric" do
|
98
|
+
begin
|
99
|
+
assert_equal :todo, @item.weight(type: :volumetric)
|
100
|
+
assert_instance_of Measured::Weight, @item.weight(type: :volumetric)
|
101
|
+
flunk "This code path is broken but passed unexpectedly"
|
102
|
+
rescue NoMethodError
|
103
|
+
skip "This code path is broken"
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
test "#weight type: dimensional" do
|
108
|
+
begin
|
109
|
+
assert_equal :todo, @item.weight(type: :dimensional)
|
110
|
+
assert_instance_of Measured::Weight, @item.weight(type: :dimensional)
|
111
|
+
flunk "This code path is broken but passed unexpectedly"
|
112
|
+
rescue NoMethodError
|
113
|
+
skip "This code path is broken"
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
test "#weight type: billable is the max of weight and volumetric" do
|
118
|
+
begin
|
119
|
+
assert_equal :todo, @item.weight(type: :billable)
|
120
|
+
assert_instance_of Measured::Weight, @item.weight(type: :billable)
|
121
|
+
flunk "This code path is broken but passed unexpectedly"
|
122
|
+
rescue NoMethodError
|
123
|
+
skip "This code path is broken"
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
127
|
+
test "#grams is the value" do
|
128
|
+
assert_equal 100, @item.grams
|
129
|
+
end
|
130
|
+
|
131
|
+
test "#grams accepts options with type" do
|
132
|
+
begin
|
133
|
+
assert_equal :todo, @item.grams(type: :volumetric)
|
134
|
+
flunk "This code path is broken but passed unexpectedly"
|
135
|
+
rescue NoMethodError
|
136
|
+
skip "This code path is broken"
|
137
|
+
end
|
138
|
+
end
|
139
|
+
|
140
|
+
test "#grams converts to another unit" do
|
141
|
+
@item = PackageItem.new(@name, 100, @value, @quantity, @options.merge(units: :imperial))
|
142
|
+
|
143
|
+
assert_in_delta 2834.9, @item.grams, 0.1
|
144
|
+
end
|
145
|
+
|
146
|
+
test "#grams aliases to g" do
|
147
|
+
assert_equal @item.grams, @item.g
|
148
|
+
end
|
149
|
+
|
150
|
+
test "#ounces is the value" do
|
151
|
+
@item = PackageItem.new(@name, @weight, @value, @quantity, @options.merge(units: :imperial))
|
152
|
+
|
153
|
+
assert_equal 100, @item.ounces
|
154
|
+
end
|
155
|
+
|
156
|
+
test "#ounces accepts options with type" do
|
157
|
+
begin
|
158
|
+
assert_equal :todo, @item.ounces(type: :volumetric)
|
159
|
+
flunk "This code path is broken but passed unexpectedly"
|
160
|
+
rescue NoMethodError
|
161
|
+
skip "This code path is broken"
|
162
|
+
end
|
163
|
+
end
|
164
|
+
|
165
|
+
test "#ounces converts to another unit" do
|
166
|
+
@item = PackageItem.new(@name, @weight, @value, @quantity, @options.merge(units: :metric))
|
167
|
+
|
168
|
+
assert_in_delta 3.5, @item.ounces, 0.1
|
169
|
+
end
|
170
|
+
|
171
|
+
test "#ounces aliases to oz" do
|
172
|
+
assert_equal @item.ounces, @item.oz
|
173
|
+
end
|
174
|
+
|
175
|
+
test "#pounds is the value" do
|
176
|
+
@item = PackageItem.new(@name, 32, @value, @quantity, @options.merge(units: :imperial))
|
177
|
+
|
178
|
+
assert_equal 2, @item.pounds
|
179
|
+
end
|
180
|
+
|
181
|
+
test "#pounds accepts options with type" do
|
182
|
+
begin
|
183
|
+
assert_equal :todo, @item.pounds(type: :volumetric)
|
184
|
+
flunk "This code path is broken but passed unexpectedly"
|
185
|
+
rescue
|
186
|
+
skip "This code path is broken"
|
187
|
+
end
|
188
|
+
end
|
189
|
+
|
190
|
+
test "#pounds converts to another unit" do
|
191
|
+
@item = PackageItem.new(@name, 1000, @value, @quantity, @options.merge(units: :metric))
|
192
|
+
|
193
|
+
assert_in_delta 2.2, @item.pounds, 0.1
|
194
|
+
end
|
195
|
+
|
196
|
+
test "#pounds aliases to lb" do
|
197
|
+
assert_equal @item.pounds, @item.lb
|
198
|
+
end
|
199
|
+
|
200
|
+
test "#pounds aliases to lbs" do
|
201
|
+
assert_equal @item.pounds, @item.lbs
|
202
|
+
end
|
203
|
+
|
204
|
+
test "#kilograms is the value" do
|
205
|
+
@item = PackageItem.new(@name, 1000, @value, @quantity, @options.merge(units: :metric))
|
206
|
+
|
207
|
+
assert_equal 1, @item.kilograms
|
208
|
+
end
|
209
|
+
|
210
|
+
test "#kilograms accepts options with type" do
|
211
|
+
begin
|
212
|
+
assert_equal :todo, @item.kilograms(type: :volumetric)
|
213
|
+
flunk "This code path is broken but passed unexpectedly"
|
214
|
+
rescue
|
215
|
+
skip "This code path is broken"
|
216
|
+
end
|
217
|
+
end
|
218
|
+
|
219
|
+
test "#kilograms converts to another unit" do
|
220
|
+
@item = PackageItem.new(@name, 1000, @value, @quantity, @options.merge(units: :imperial))
|
221
|
+
|
222
|
+
assert_in_delta 28.3, @item.kilograms, 0.1
|
223
|
+
end
|
224
|
+
|
225
|
+
test "#kilograms aliases to kg" do
|
226
|
+
assert_equal @item.kilograms, @item.kg
|
227
|
+
end
|
228
|
+
|
229
|
+
test "#kilograms aliases to kgs" do
|
230
|
+
assert_equal @item.kilograms, @item.kgs
|
231
|
+
end
|
232
|
+
end
|
@@ -0,0 +1,404 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
class PackageTest < ActiveSupport::TestCase
|
4
|
+
setup do
|
5
|
+
@weight = 100
|
6
|
+
@dimensions = [5, 6, 7]
|
7
|
+
@value = 1299
|
8
|
+
@currency = "USD"
|
9
|
+
@cylinder = false
|
10
|
+
@tube = false
|
11
|
+
@gift = false
|
12
|
+
@oversized = false
|
13
|
+
@unpackaged = false
|
14
|
+
@dim_units = :metric
|
15
|
+
@units = :metric
|
16
|
+
@weight_units = :metric
|
17
|
+
@options = {
|
18
|
+
value: @value,
|
19
|
+
currency: @currency,
|
20
|
+
cylinder: @cylinder,
|
21
|
+
tube: @tube,
|
22
|
+
gift: @gift,
|
23
|
+
oversized: @oversized,
|
24
|
+
unpackaged: @unpackaged,
|
25
|
+
dim_units: @dim_units,
|
26
|
+
units: @units,
|
27
|
+
weight_units: @weight_units,
|
28
|
+
}
|
29
|
+
|
30
|
+
@package = Package.new(@weight, @dimensions, @options)
|
31
|
+
@imperial_package = Package.new(@weight, @dimensions, @options.merge(units: :imperial, dim_units: :imperial, weight_units: :imperial))
|
32
|
+
|
33
|
+
@mass = Measured::Weight.new(@weight, :grams)
|
34
|
+
end
|
35
|
+
|
36
|
+
test "#initialize package from mass" do
|
37
|
+
ten_pounds = Measured::Weight.new(10, :pounds)
|
38
|
+
package = Package.new(ten_pounds, [])
|
39
|
+
assert_equal ten_pounds, package.weight
|
40
|
+
end
|
41
|
+
|
42
|
+
test "#initialize with defaults" do
|
43
|
+
assert_equal @value, @package.value
|
44
|
+
assert_equal @currency, @package.currency
|
45
|
+
assert_equal @cylinder, @package.cylinder?
|
46
|
+
assert_equal @tube, @package.tube?
|
47
|
+
assert_equal @oversized, @package.oversized?
|
48
|
+
assert_equal @unpackaged, @package.unpackaged?
|
49
|
+
assert_equal @gift, @package.gift?
|
50
|
+
end
|
51
|
+
|
52
|
+
test "#initialize with currency cents" do
|
53
|
+
@package = Package.new(@weight, @dimensions, value: money)
|
54
|
+
assert_equal @currency, @package.currency
|
55
|
+
assert_equal @value, @package.value
|
56
|
+
end
|
57
|
+
|
58
|
+
test "#initialize sorts the passed in dimensions" do
|
59
|
+
@package = Package.new(@weight, [9, 8, 7], @options)
|
60
|
+
|
61
|
+
assert_equal [7, 8, 9], @package.centimetres
|
62
|
+
end
|
63
|
+
|
64
|
+
test "#initialize sets default dimensions if blank" do
|
65
|
+
@package = Package.new(@weight, [], @options)
|
66
|
+
|
67
|
+
assert_equal [0, 0, 0], @package.centimetres
|
68
|
+
end
|
69
|
+
|
70
|
+
test "#initialize increases dimension size to three elements in the array and pads" do
|
71
|
+
@package = Package.new(@weight, [2], @options)
|
72
|
+
|
73
|
+
assert_equal [2, 2, 2], @package.centimetres
|
74
|
+
end
|
75
|
+
|
76
|
+
test "#initialize default units" do
|
77
|
+
assert_equal @dimensions, @package.centimetres
|
78
|
+
assert_equal @weight, @package.grams
|
79
|
+
end
|
80
|
+
|
81
|
+
test "#initialize units" do
|
82
|
+
assert_equal @dimensions, @imperial_package.inches
|
83
|
+
end
|
84
|
+
|
85
|
+
test "#initialize weight_units" do
|
86
|
+
@package = Package.new(@weight, @dimensions, @options.merge(weight_units: :imperial))
|
87
|
+
|
88
|
+
assert_equal @weight, @package.ounces
|
89
|
+
end
|
90
|
+
|
91
|
+
test "#unpackaged?" do
|
92
|
+
assert_predicate Package.new(@weight, @dimensions, unpackaged: true), :unpackaged?
|
93
|
+
refute_predicate Package.new(@weight, @dimensions, unpackaged: false), :unpackaged?
|
94
|
+
end
|
95
|
+
|
96
|
+
test "#oversized?" do
|
97
|
+
assert_predicate Package.new(@weight, @dimensions, oversized: true), :oversized?
|
98
|
+
refute_predicate Package.new(@weight, @dimensions, oversized: false), :oversized?
|
99
|
+
end
|
100
|
+
|
101
|
+
test "#gift?" do
|
102
|
+
assert_predicate Package.new(@weight, @dimensions, gift: true), :gift?
|
103
|
+
refute_predicate Package.new(@weight, @dimensions, gift: false), :gift?
|
104
|
+
end
|
105
|
+
|
106
|
+
test "#cylinder? and #tube? check both values" do
|
107
|
+
@package = Package.new(@weight, @dimensions, cylinder: false, tube: false)
|
108
|
+
refute_predicate @package, :cylinder?
|
109
|
+
refute_predicate @package, :tube?
|
110
|
+
|
111
|
+
@package = Package.new(@weight, @dimensions, cylinder: true, tube: false)
|
112
|
+
assert_predicate @package, :cylinder?
|
113
|
+
assert_predicate @package, :tube?
|
114
|
+
|
115
|
+
@package = Package.new(@weight, @dimensions, cylinder: false, tube: true)
|
116
|
+
assert_predicate @package, :cylinder?
|
117
|
+
assert_predicate @package, :tube?
|
118
|
+
|
119
|
+
@package = Package.new(@weight, @dimensions, cylinder: true, tube: true)
|
120
|
+
assert_predicate @package, :cylinder?
|
121
|
+
assert_predicate @package, :tube?
|
122
|
+
end
|
123
|
+
|
124
|
+
test "#inches performs lookup with a numerical index" do
|
125
|
+
assert_equal @dimensions[0], @imperial_package.inches(0)
|
126
|
+
assert_equal @dimensions[1], @imperial_package.inches(1)
|
127
|
+
assert_equal @dimensions[2], @imperial_package.inches(2)
|
128
|
+
assert_nil @imperial_package.inches(3)
|
129
|
+
end
|
130
|
+
|
131
|
+
test "#inches for dimension x" do
|
132
|
+
assert_equal @dimensions[2], @imperial_package.inches(:x)
|
133
|
+
assert_equal @dimensions[2], @imperial_package.inches(:max)
|
134
|
+
assert_equal @dimensions[2], @imperial_package.inches(:length)
|
135
|
+
assert_equal @dimensions[2], @imperial_package.inches(:long)
|
136
|
+
end
|
137
|
+
|
138
|
+
test "#inches for dimension y" do
|
139
|
+
assert_equal @dimensions[1], @imperial_package.inches(:y)
|
140
|
+
assert_equal @dimensions[1], @imperial_package.inches(:mid)
|
141
|
+
assert_equal @dimensions[1], @imperial_package.inches(:width)
|
142
|
+
assert_equal @dimensions[1], @imperial_package.inches(:wide)
|
143
|
+
end
|
144
|
+
|
145
|
+
test "#inches for dimension z" do
|
146
|
+
assert_equal @dimensions[0], @imperial_package.inches(:z)
|
147
|
+
assert_equal @dimensions[0], @imperial_package.inches(:min)
|
148
|
+
assert_equal @dimensions[0], @imperial_package.inches(:height)
|
149
|
+
assert_equal @dimensions[0], @imperial_package.inches(:depth)
|
150
|
+
assert_equal @dimensions[0], @imperial_package.inches(:high)
|
151
|
+
assert_equal @dimensions[0], @imperial_package.inches(:deep)
|
152
|
+
end
|
153
|
+
|
154
|
+
test "#inches for girth of a cylinder" do
|
155
|
+
@imperial_package = Package.new(@weight, @dimensions, @options.merge(cylinder: true, units: :imperial, dim_units: :imperial))
|
156
|
+
|
157
|
+
assert_predicate @imperial_package, :cylinder?
|
158
|
+
assert_in_delta 17.2, @imperial_package.inches(:girth), 1
|
159
|
+
assert_in_delta 17.2, @imperial_package.inches(:around), 1
|
160
|
+
assert_in_delta 17.2, @imperial_package.inches(:circumference), 1
|
161
|
+
|
162
|
+
end
|
163
|
+
|
164
|
+
test "#inches for girth of a non cylinder" do
|
165
|
+
refute_predicate @imperial_package, :cylinder?
|
166
|
+
assert_in_delta 22, @imperial_package.inches(:girth), 1
|
167
|
+
assert_in_delta 22, @imperial_package.inches(:around), 1
|
168
|
+
assert_in_delta 22, @imperial_package.inches(:circumference), 1
|
169
|
+
end
|
170
|
+
|
171
|
+
test "#inches for the volume of a cylinder" do
|
172
|
+
@imperial_package = Package.new(@weight, @dimensions, @options.merge(cylinder: true, units: :imperial, dim_units: :imperial))
|
173
|
+
|
174
|
+
assert_predicate @imperial_package, :cylinder?
|
175
|
+
assert_in_delta 522.4, @imperial_package.inches(:volume), 1
|
176
|
+
end
|
177
|
+
|
178
|
+
test "#inches for volume" do
|
179
|
+
refute_predicate @imperial_package, :cylinder?
|
180
|
+
assert_equal 210, @imperial_package.inches(:volume)
|
181
|
+
end
|
182
|
+
|
183
|
+
test "#inches for box_volume" do
|
184
|
+
assert_equal 210, @imperial_package.inches(:box_volume)
|
185
|
+
end
|
186
|
+
|
187
|
+
test "#inches of an unknown value" do
|
188
|
+
assert_nil @imperial_package.inches(:unknown)
|
189
|
+
end
|
190
|
+
|
191
|
+
test "#inches alias to #in" do
|
192
|
+
assert_equal @dimensions, @imperial_package.inches
|
193
|
+
assert_equal @dimensions, @imperial_package.in
|
194
|
+
end
|
195
|
+
|
196
|
+
test "#centimetres performs lookup with a numerical index" do
|
197
|
+
assert_equal @dimensions[0], @package.centimetres(0)
|
198
|
+
assert_equal @dimensions[1], @package.centimetres(1)
|
199
|
+
assert_equal @dimensions[2], @package.centimetres(2)
|
200
|
+
assert_nil @package.centimetres(3)
|
201
|
+
end
|
202
|
+
|
203
|
+
test "#centimetres for dimension x" do
|
204
|
+
assert_equal @dimensions[2], @package.centimetres(:x)
|
205
|
+
assert_equal @dimensions[2], @package.centimetres(:max)
|
206
|
+
assert_equal @dimensions[2], @package.centimetres(:length)
|
207
|
+
assert_equal @dimensions[2], @package.centimetres(:long)
|
208
|
+
end
|
209
|
+
|
210
|
+
test "#centimetres for dimension y" do
|
211
|
+
assert_equal @dimensions[1], @package.centimetres(:y)
|
212
|
+
assert_equal @dimensions[1], @package.centimetres(:mid)
|
213
|
+
assert_equal @dimensions[1], @package.centimetres(:width)
|
214
|
+
assert_equal @dimensions[1], @package.centimetres(:wide)
|
215
|
+
end
|
216
|
+
|
217
|
+
test "#centimetres for dimension z" do
|
218
|
+
assert_equal @dimensions[0], @package.centimetres(:z)
|
219
|
+
assert_equal @dimensions[0], @package.centimetres(:min)
|
220
|
+
assert_equal @dimensions[0], @package.centimetres(:height)
|
221
|
+
assert_equal @dimensions[0], @package.centimetres(:depth)
|
222
|
+
assert_equal @dimensions[0], @package.centimetres(:high)
|
223
|
+
assert_equal @dimensions[0], @package.centimetres(:deep)
|
224
|
+
end
|
225
|
+
|
226
|
+
test "#centimetres for girth of a cylinder" do
|
227
|
+
@package = Package.new(@weight, @dimensions, @options.merge(cylinder: true, units: :metric, dim_units: :metric))
|
228
|
+
|
229
|
+
assert_predicate @package, :cylinder?
|
230
|
+
assert_in_delta 17.2, @package.centimetres(:girth), 1
|
231
|
+
assert_in_delta 17.2, @package.centimetres(:around), 1
|
232
|
+
assert_in_delta 17.2, @package.centimetres(:circumference), 1
|
233
|
+
|
234
|
+
end
|
235
|
+
|
236
|
+
test "#centimetres for girth of a non-cylinder" do
|
237
|
+
refute_predicate @package, :cylinder?
|
238
|
+
assert_in_delta 22, @package.centimetres(:girth), 1
|
239
|
+
assert_in_delta 22, @package.centimetres(:around), 1
|
240
|
+
assert_in_delta 22, @package.centimetres(:circumference), 1
|
241
|
+
end
|
242
|
+
|
243
|
+
test "#centimetres for the volume of a cylinder" do
|
244
|
+
@package = Package.new(@weight, @dimensions, @options.merge(cylinder: true, units: :metric, dim_units: :metric))
|
245
|
+
|
246
|
+
assert_predicate @package, :cylinder?
|
247
|
+
assert_in_delta 522.4, @package.centimetres(:volume), 1
|
248
|
+
end
|
249
|
+
|
250
|
+
test "#centimetres for volume" do
|
251
|
+
refute_predicate @package, :cylinder?
|
252
|
+
assert_equal 210, @package.centimetres(:volume)
|
253
|
+
end
|
254
|
+
|
255
|
+
test "#centimetres for box_volume" do
|
256
|
+
assert_equal 210, @package.centimetres(:box_volume)
|
257
|
+
end
|
258
|
+
|
259
|
+
test "#centimetres of an unknown value" do
|
260
|
+
assert_nil @package.centimetres(:unknown)
|
261
|
+
end
|
262
|
+
|
263
|
+
test "#centimetres alias to #cm" do
|
264
|
+
assert_equal @dimensions, @package.centimetres
|
265
|
+
assert_equal @dimensions, @package.cm
|
266
|
+
end
|
267
|
+
|
268
|
+
test "#weight" do
|
269
|
+
assert_equal @mass, @package.weight
|
270
|
+
assert_instance_of Measured::Weight, @package.weight
|
271
|
+
end
|
272
|
+
|
273
|
+
test "#weight for actual" do
|
274
|
+
assert_equal @mass, @package.weight(type: :actual)
|
275
|
+
assert_instance_of Measured::Weight, @package.weight(type: :actual)
|
276
|
+
end
|
277
|
+
|
278
|
+
test "#weight volumetric" do
|
279
|
+
assert_equal Measured::Weight.new(35, :grams), @package.weight(type: :volumetric)
|
280
|
+
end
|
281
|
+
|
282
|
+
test "#weight dimensional" do
|
283
|
+
assert_equal Measured::Weight.new(35, :grams), @package.weight(type: :dimensional)
|
284
|
+
end
|
285
|
+
|
286
|
+
test "#weight billable is the max of weight and volumetric" do
|
287
|
+
assert_equal Measured::Weight.new(100, :grams), @package.weight(type: :billable)
|
288
|
+
|
289
|
+
@package = Package.new(500, [1, 1, 1], @options)
|
290
|
+
assert_equal Measured::Weight.new(500, :grams), @package.weight(type: :billable)
|
291
|
+
end
|
292
|
+
|
293
|
+
test "#grams value" do
|
294
|
+
assert_equal 100, @package.grams
|
295
|
+
end
|
296
|
+
|
297
|
+
test "#grams accepts options with type" do
|
298
|
+
assert_in_delta 35, @package.grams(type: :volumetric), 1
|
299
|
+
end
|
300
|
+
|
301
|
+
test "#grams converts to another unit from another system" do
|
302
|
+
@package = Package.new(@weight, @dimensions, weight_units: :imperial)
|
303
|
+
|
304
|
+
assert_in_delta 2834.9, @package.grams, 1
|
305
|
+
end
|
306
|
+
|
307
|
+
test "#grams alias to #g" do
|
308
|
+
assert_equal @package.grams, @package.g
|
309
|
+
end
|
310
|
+
|
311
|
+
test "#ounces value" do
|
312
|
+
assert_equal 100, @imperial_package.ounces
|
313
|
+
end
|
314
|
+
|
315
|
+
test "#ounces accepts options with type" do
|
316
|
+
assert_in_delta 20.2, @imperial_package.ounces(type: :volumetric), 1
|
317
|
+
end
|
318
|
+
|
319
|
+
test "#ounces converts to another unit from another system" do
|
320
|
+
assert_in_delta 3.5, @package.ounces, 1
|
321
|
+
end
|
322
|
+
|
323
|
+
test "#ounces alias to #oz" do
|
324
|
+
assert_equal @imperial_package.ounces, @imperial_package.oz
|
325
|
+
end
|
326
|
+
|
327
|
+
test "#pounds value" do
|
328
|
+
assert_equal 6.25, @imperial_package.pounds
|
329
|
+
end
|
330
|
+
|
331
|
+
test "#pounds accepts options with type" do
|
332
|
+
assert_in_delta 0.07, @package.pounds(type: :volumetric), 0.01
|
333
|
+
end
|
334
|
+
|
335
|
+
test "#pounds converts to another unit from another system" do
|
336
|
+
assert_in_delta 0.22, @package.pounds, 0.01
|
337
|
+
end
|
338
|
+
|
339
|
+
test "#pounds alias to #lb" do
|
340
|
+
assert_equal @package.pounds, @package.lb
|
341
|
+
end
|
342
|
+
|
343
|
+
test "#pounds alias to #lbs" do
|
344
|
+
assert_equal @package.pounds, @package.lbs
|
345
|
+
end
|
346
|
+
|
347
|
+
test "#kilograms value" do
|
348
|
+
assert_equal 0.1, @package.kilograms
|
349
|
+
end
|
350
|
+
|
351
|
+
test "#kilograms accepts options with type" do
|
352
|
+
assert_equal 0.035, @package.kilograms(type: :volumetric)
|
353
|
+
end
|
354
|
+
|
355
|
+
test "#kilograms converts to another unit from another system" do
|
356
|
+
assert_in_delta 2.8, @imperial_package.kilograms, 1
|
357
|
+
end
|
358
|
+
|
359
|
+
test "#kilograms alias to #kg" do
|
360
|
+
assert_equal 0.1, @package.kg
|
361
|
+
end
|
362
|
+
|
363
|
+
test "#kilograms alias to #kgs" do
|
364
|
+
assert_equal @package.kilograms, @package.kgs
|
365
|
+
end
|
366
|
+
|
367
|
+
test ".cents_from nil" do
|
368
|
+
assert_nil Package.cents_from(nil)
|
369
|
+
end
|
370
|
+
|
371
|
+
test ".cents_from cents on a money object" do
|
372
|
+
assert_equal @value, Package.cents_from(money)
|
373
|
+
end
|
374
|
+
|
375
|
+
test ".cents_from float" do
|
376
|
+
assert_equal 120, Package.cents_from(1.2)
|
377
|
+
end
|
378
|
+
|
379
|
+
test ".cents_from string" do
|
380
|
+
assert_equal 120, Package.cents_from("1.20")
|
381
|
+
end
|
382
|
+
|
383
|
+
test ".cents_from integer" do
|
384
|
+
assert_equal 12, Package.cents_from(12)
|
385
|
+
end
|
386
|
+
|
387
|
+
test ".cents_from an unhandled object" do
|
388
|
+
exception = assert_raises NoMethodError do
|
389
|
+
Package.cents_from(Object.new)
|
390
|
+
end
|
391
|
+
assert_match /undefined method `to_i'/, exception.message
|
392
|
+
end
|
393
|
+
|
394
|
+
private
|
395
|
+
|
396
|
+
def money
|
397
|
+
@money ||= begin
|
398
|
+
value = Class.new { attr_accessor :currency, :cents }.new
|
399
|
+
value.currency = @currency
|
400
|
+
value.cents = @value
|
401
|
+
value
|
402
|
+
end
|
403
|
+
end
|
404
|
+
end
|