active_shipping 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (81) hide show
  1. data/.gitignore +6 -0
  2. data/CHANGELOG +23 -0
  3. data/MIT-LICENSE +20 -0
  4. data/README.markdown +173 -0
  5. data/Rakefile +55 -0
  6. data/VERSION +1 -0
  7. data/init.rb +1 -0
  8. data/lib/active_shipping.rb +50 -0
  9. data/lib/active_shipping/lib/connection.rb +170 -0
  10. data/lib/active_shipping/lib/country.rb +319 -0
  11. data/lib/active_shipping/lib/error.rb +4 -0
  12. data/lib/active_shipping/lib/post_data.rb +22 -0
  13. data/lib/active_shipping/lib/posts_data.rb +47 -0
  14. data/lib/active_shipping/lib/requires_parameters.rb +16 -0
  15. data/lib/active_shipping/lib/utils.rb +18 -0
  16. data/lib/active_shipping/lib/validateable.rb +76 -0
  17. data/lib/active_shipping/shipping/base.rb +15 -0
  18. data/lib/active_shipping/shipping/carrier.rb +75 -0
  19. data/lib/active_shipping/shipping/carriers.rb +17 -0
  20. data/lib/active_shipping/shipping/carriers/bogus_carrier.rb +16 -0
  21. data/lib/active_shipping/shipping/carriers/fedex.rb +315 -0
  22. data/lib/active_shipping/shipping/carriers/shipwire.rb +167 -0
  23. data/lib/active_shipping/shipping/carriers/ups.rb +368 -0
  24. data/lib/active_shipping/shipping/carriers/usps.rb +496 -0
  25. data/lib/active_shipping/shipping/location.rb +100 -0
  26. data/lib/active_shipping/shipping/package.rb +144 -0
  27. data/lib/active_shipping/shipping/rate_estimate.rb +54 -0
  28. data/lib/active_shipping/shipping/rate_response.rb +19 -0
  29. data/lib/active_shipping/shipping/response.rb +49 -0
  30. data/lib/active_shipping/shipping/shipment_event.rb +14 -0
  31. data/lib/active_shipping/shipping/tracking_response.rb +22 -0
  32. data/lib/certs/cacert.pem +7815 -0
  33. data/lib/vendor/quantified/MIT-LICENSE +22 -0
  34. data/lib/vendor/quantified/README.markdown +49 -0
  35. data/lib/vendor/quantified/Rakefile +21 -0
  36. data/lib/vendor/quantified/init.rb +0 -0
  37. data/lib/vendor/quantified/lib/quantified.rb +6 -0
  38. data/lib/vendor/quantified/lib/quantified/attribute.rb +208 -0
  39. data/lib/vendor/quantified/lib/quantified/length.rb +20 -0
  40. data/lib/vendor/quantified/lib/quantified/mass.rb +19 -0
  41. data/lib/vendor/quantified/test/length_test.rb +92 -0
  42. data/lib/vendor/quantified/test/mass_test.rb +88 -0
  43. data/lib/vendor/quantified/test/test_helper.rb +2 -0
  44. data/lib/vendor/test_helper.rb +13 -0
  45. data/lib/vendor/xml_node/README +36 -0
  46. data/lib/vendor/xml_node/Rakefile +21 -0
  47. data/lib/vendor/xml_node/benchmark/bench_generation.rb +32 -0
  48. data/lib/vendor/xml_node/init.rb +1 -0
  49. data/lib/vendor/xml_node/lib/xml_node.rb +222 -0
  50. data/lib/vendor/xml_node/test/test_generating.rb +94 -0
  51. data/lib/vendor/xml_node/test/test_parsing.rb +43 -0
  52. data/test/fixtures.yml +13 -0
  53. data/test/fixtures/xml/fedex/ottawa_to_beverly_hills_rate_request.xml +67 -0
  54. data/test/fixtures/xml/fedex/ottawa_to_beverly_hills_rate_response.xml +213 -0
  55. data/test/fixtures/xml/fedex/tracking_request.xml +27 -0
  56. data/test/fixtures/xml/fedex/tracking_response.xml +153 -0
  57. data/test/fixtures/xml/shipwire/international_rates_response.xml +17 -0
  58. data/test/fixtures/xml/shipwire/invalid_credentials_response.xml +4 -0
  59. data/test/fixtures/xml/shipwire/new_carrier_rate_response.xml +18 -0
  60. data/test/fixtures/xml/shipwire/no_rates_response.xml +7 -0
  61. data/test/fixtures/xml/shipwire/rates_response.xml +36 -0
  62. data/test/fixtures/xml/ups/example_tracking_response.xml +53 -0
  63. data/test/fixtures/xml/ups/shipment_from_tiger_direct.xml +222 -0
  64. data/test/fixtures/xml/ups/test_real_home_as_residential_destination_response.xml +1 -0
  65. data/test/fixtures/xml/usps/beverly_hills_to_ottawa_book_rate_response.xml +85 -0
  66. data/test/fixtures/xml/usps/beverly_hills_to_ottawa_book_wii_rate_response.xml +168 -0
  67. data/test/fixtures/xml/usps/beverly_hills_to_ottawa_wii_rate_response.xml +85 -0
  68. data/test/remote/fedex_test.rb +140 -0
  69. data/test/remote/shipwire_test.rb +88 -0
  70. data/test/remote/ups_test.rb +187 -0
  71. data/test/remote/usps_test.rb +184 -0
  72. data/test/test_helper.rb +167 -0
  73. data/test/unit/base_test.rb +18 -0
  74. data/test/unit/carriers/fedex_test.rb +78 -0
  75. data/test/unit/carriers/shipwire_test.rb +130 -0
  76. data/test/unit/carriers/ups_test.rb +81 -0
  77. data/test/unit/carriers/usps_test.rb +206 -0
  78. data/test/unit/location_test.rb +46 -0
  79. data/test/unit/package_test.rb +65 -0
  80. data/test/unit/response_test.rb +10 -0
  81. metadata +158 -0
@@ -0,0 +1,88 @@
1
+ require File.dirname(__FILE__) + '/test_helper'
2
+ require 'quantified/mass'
3
+
4
+ class MassTest < Test::Unit::TestCase
5
+ include Quantified
6
+ Mass.numeric_methods :grams, :kilograms, :ounces, :pounds
7
+
8
+ def setup
9
+ @mass = Mass.new(5, :pounds)
10
+ end
11
+
12
+ def test_inspect
13
+ assert_equal "#<Quantified::Mass: 5 pounds>", @mass.inspect
14
+ end
15
+
16
+ def test_to_s
17
+ assert_equal "5 pounds", @mass.to_s
18
+ end
19
+
20
+ def test_initialize_from_numeric
21
+ assert_equal "5 pounds", 5.pounds.to_s
22
+ end
23
+
24
+ def test_equalities
25
+ assert_equal 1.pounds, (1.0).pounds
26
+ # == based on value
27
+ assert_equal 4000.pounds, Mass.new(2, :short_tons)
28
+ # eql? based on value and unit
29
+ assert !4000.pounds.eql?(Mass.new(2, :short_tons))
30
+ # equal? based on object identity
31
+ assert !2.pounds.equal?(2.pounds)
32
+ end
33
+
34
+ def test_convert_short_tons_to_pounds
35
+ assert 4000.pounds.eql?(Mass.new(2, :short_tons).to_pounds)
36
+ end
37
+
38
+ def test_convert_pounds_to_short_tons
39
+ assert Mass.new(2, :short_tons).eql?(4000.pounds.to_short_tons)
40
+ end
41
+
42
+ def test_convert_short_tons_to_milligrams
43
+ assert Mass.new(907_184_740, :milligrams).eql?(Mass.new(1, :short_tons).to_milligrams)
44
+ end
45
+
46
+ def test_convert_milligrams_to_short_tons
47
+ assert Mass.new(1, :short_tons).eql?(Mass.new(907_184_740, :milligrams).to_short_tons)
48
+ end
49
+
50
+ def test_convert_grams_to_ounces
51
+ assert 1.ounces.eql?((28.349523125).grams.to_ounces)
52
+ assert 1.ounces.eql?((28.349523125).grams.in_ounces)
53
+ end
54
+
55
+ def test_comparison_with_numeric
56
+ assert 2.pounds > 1
57
+ assert 2.pounds == 2
58
+ assert 2.pounds <= 2
59
+ assert 2.pounds < 3
60
+ end
61
+
62
+ def test_method_missing_to_i
63
+ assert_equal 2, (2.4).pounds.to_i
64
+ end
65
+
66
+ def test_method_missing_to_f
67
+ assert_equal 2.4, (2.4).pounds.to_f
68
+ end
69
+
70
+ def test_method_missing_minus
71
+ assert_equal 2.pounds, 5.pounds - 3.pounds
72
+ end
73
+
74
+ def test_numeric_methods_not_added_for_some_units
75
+ assert_raises NoMethodError do
76
+ 2.short_tons
77
+ end
78
+ assert_raises NoMethodError do
79
+ 2.milligrams
80
+ end
81
+ end
82
+
83
+ def test_systems
84
+ assert_equal [:metric, :imperial], Mass.systems
85
+ assert_equal [:grams, :milligrams, :kilograms], Mass.units(:metric)
86
+ assert_equal [:ounces, :pounds, :stones, :short_tons], Mass.units(:imperial)
87
+ end
88
+ end
@@ -0,0 +1,2 @@
1
+ require 'test/unit'
2
+ require File.dirname(__FILE__) + '/../lib/quantified'
@@ -0,0 +1,13 @@
1
+ #!/usr/bin/env ruby
2
+ $:.unshift(File.dirname(__FILE__) + '/../lib')
3
+
4
+
5
+ require 'test/unit'
6
+ require 'active_shipping'
7
+
8
+ begin
9
+ require 'mocha'
10
+ rescue LoadError
11
+ require 'rubygems'
12
+ require 'mocha'
13
+ end
@@ -0,0 +1,36 @@
1
+ XML Node
2
+ ==========
3
+
4
+
5
+ Example for generating xml:
6
+
7
+ # Create an atom like document
8
+
9
+ root = XmlNode.new 'feed' do |feed|
10
+
11
+ feed << XmlNode.new('id', 'tag:atom.com,2007:1')
12
+ feed << XmlNode.new('title', 'Atom test feed')
13
+ feed << XmlNode.new('author') do |author|
14
+ author << XmlNode.new("name", "tobi")
15
+ author << XmlNode.new("email", "tobi@gmail.com")
16
+ end
17
+
18
+ feed << XmlNode.new('entry') do |entry|
19
+ entry << XmlNode.new('title', 'First post')
20
+ entry << XmlNode.new('summary', 'Lorem ipsum', :type => 'xhtml')
21
+ entry << XmlNode.new('created_at', Time.now)
22
+ end
23
+
24
+ feed << XmlNode.new('dc:published', Time.now)
25
+ end
26
+
27
+ root.to_xml #=> Well formatted xml
28
+
29
+
30
+ Example for parsing xml:
31
+
32
+
33
+ xml = XmlNode.parse('<feed attr="1"><element>text</element><element>text</element></feed>')
34
+ xml['attr'] #=> '1'
35
+ xml.children['element'].text #=> 'text'
36
+ xml.children.each { |e| e... }
@@ -0,0 +1,21 @@
1
+ require 'rake'
2
+ require 'rake/testtask'
3
+ require 'rake/rdoctask'
4
+
5
+ desc 'Default: run unit tests.'
6
+ task :default => :test
7
+
8
+ desc 'Test the plugin.'
9
+ Rake::TestTask.new(:test) do |t|
10
+ t.libs << 'lib'
11
+ t.pattern = 'test/**/test_*.rb'
12
+ t.verbose = true
13
+ end
14
+
15
+ desc 'Generate documentation for the calculations plugin.'
16
+ Rake::RDocTask.new(:rdoc) do |rdoc|
17
+ rdoc.rdoc_dir = 'rdoc'
18
+ rdoc.title = 'XmlNode'
19
+ rdoc.options << '--line-numbers --inline-source'
20
+ rdoc.rdoc_files.include('lib/**/*.rb')
21
+ end
@@ -0,0 +1,32 @@
1
+ require "benchmark"
2
+ require File.dirname(__FILE__) + "/../lib/xml_node"
3
+
4
+ class XmlNode
5
+
6
+ def to_xml_as_array
7
+ xml = []
8
+ document = REXML::Document.new
9
+ document << REXML::XMLDecl.new('1.0')
10
+ document << @element
11
+ document.write( xml, 0)
12
+ xml.to_s
13
+ end
14
+
15
+ def to_xml_no_format
16
+ xml = ''
17
+ document = REXML::Document.new
18
+ document << REXML::XMLDecl.new('1.0')
19
+ document << @element
20
+ document.write( xml)
21
+ xml
22
+ end
23
+
24
+ end
25
+
26
+ TESTS = 10000
27
+
28
+ Benchmark.bmbm do |results|
29
+ results.report { TESTS.times do XmlNode.new('feed') { |n| n << XmlNode.new('element', 'test'); n << XmlNode.new('element') }.to_xml end }
30
+ results.report { TESTS.times do XmlNode.new('feed') { |n| n << XmlNode.new('element', 'test'); n << XmlNode.new('element') }.to_xml_as_array end }
31
+ results.report { TESTS.times do XmlNode.new('feed') { |n| n << XmlNode.new('element', 'test'); n << XmlNode.new('element') }.to_xml_no_format end }
32
+ end
@@ -0,0 +1 @@
1
+ # Include hook code here
@@ -0,0 +1,222 @@
1
+ require 'rexml/document'
2
+
3
+ class Object
4
+ def to_xml_value
5
+ to_s
6
+ end
7
+ end
8
+
9
+ class NilClass
10
+ def to_xml_value
11
+ nil
12
+ end
13
+ end
14
+
15
+ class TrueClass
16
+ def to_xml_value
17
+ to_s
18
+ end
19
+ end
20
+
21
+ class FalseClass
22
+ def to_xml_value
23
+ to_s
24
+ end
25
+ end
26
+
27
+ class Time
28
+ def to_xml_value
29
+ self.xmlschema
30
+ end
31
+ end
32
+
33
+ class DateTime
34
+ def to_xml_value
35
+ self.xmlschema
36
+ end
37
+ end
38
+
39
+ class Date
40
+ def to_xml_value
41
+ self.to_time.xmlschema
42
+ end
43
+ end
44
+
45
+ class REXML::Element
46
+ def to_xml_element
47
+ self
48
+ end
49
+ end
50
+
51
+ class XmlNode
52
+ attr_accessor :child_nodes
53
+ attr_reader :element
54
+
55
+ class List
56
+ include Enumerable
57
+
58
+ def initialize(parent)
59
+ @parent = parent
60
+ @children = {}
61
+ end
62
+
63
+ def [](value)
64
+ node_for @parent.element.elements[value]
65
+ end
66
+
67
+ def []=(value, key)
68
+ @parent.element.elements[value.to_s] = key.to_xml_element
69
+ end
70
+
71
+ def each(&block)
72
+ @parent.element.each_element { |e| yield node_for(e) }
73
+ end
74
+
75
+ private
76
+
77
+ def node_for(element)
78
+ @parent.child_nodes[element] ||= XmlNode.new(element)
79
+ end
80
+ end
81
+
82
+ # Allows for very pretty xml generation akin to xml builder.
83
+ #
84
+ # Example:
85
+ #
86
+ # # Create an atom like document
87
+ # doc = Document.new
88
+ # doc.root = XmlNode.new 'feed' do |feed|
89
+ #
90
+ # feed << XmlNode.new('id', 'tag:atom.com,2007:1')
91
+ # feed << XmlNode.new('title', 'Atom test feed')
92
+ # feed << XmlNode.new('author') do |author|
93
+ # author << XmlNode.new("name", "tobi")
94
+ # author << XmlNode.new("email", "tobi@gmail.com")
95
+ # end
96
+ #
97
+ # feed << XmlNode.new('entry') do |entry|
98
+ # entry << XmlNode.new('title', 'First post')
99
+ # entry << XmlNode.new('summary', 'Lorem ipsum', :type => 'xhtml')
100
+ # entry << XmlNode.new('created_at', Time.now)
101
+ # end
102
+ #
103
+ # feed << XmlNode.new('dc:published', Time.now)
104
+ # end
105
+ #
106
+ def initialize(node, *args)
107
+ @element = if node.is_a?(REXML::Element)
108
+ node
109
+ else
110
+ REXML::Element.new(node)
111
+ end
112
+
113
+ @child_nodes = {}
114
+
115
+ if attributes = args.last.is_a?(Hash) ? args.pop : nil
116
+ attributes.each { |k,v| @element.add_attribute(k.to_s, v.to_xml_value) }
117
+ end
118
+
119
+ if !args[0].nil?
120
+ @element.text = args[0].to_xml_value
121
+ end
122
+
123
+ if block_given?
124
+ yield self
125
+ end
126
+ end
127
+
128
+ def self.parse(xml)
129
+ self.new(REXML::Document.new(xml).root)
130
+ end
131
+
132
+ def children
133
+ XmlNode::List.new(self)
134
+ end
135
+
136
+ def []=(key, value)
137
+ @element.attributes[key.to_s] = value.to_xml_value
138
+ end
139
+
140
+ def [](key)
141
+ @element.attributes[key]
142
+ end
143
+
144
+ # Add a namespace to the node
145
+ # Example
146
+ #
147
+ # node.namespace 'http://www.w3.org/2005/Atom'
148
+ # node.namespace :opensearch, 'http://a9.com/-/spec/opensearch/1.1/'
149
+ #
150
+ def namespace(*args)
151
+ args[0] = args[0].to_s if args[0].is_a?(Symbol)
152
+ @element.add_namespace(*args)
153
+ end
154
+
155
+ def cdata=(value)
156
+ new_cdata = REXML::CData.new( value )
157
+ @element.children.each do |c|
158
+ if c.is_a?(REXML::CData)
159
+ return @element.replace_child(c,new_cdata)
160
+ end
161
+ end
162
+ @element << new_cdata
163
+ rescue RuntimeError => e
164
+ @element << REXML::Text.new(e.message)
165
+ end
166
+
167
+ def cdata
168
+ @element.cdatas.first.to_s
169
+ end
170
+
171
+ def name
172
+ @element.name
173
+ end
174
+
175
+ def text=(value)
176
+ @element.text = REXML::Text.new( value )
177
+ end
178
+
179
+ def text
180
+ @element.text
181
+ end
182
+
183
+ def find(scope, xpath)
184
+ case scope
185
+ when :first
186
+ elem = @element.elements[xpath]
187
+ elem.nil? ? nil : child_nodes[elem] ||= XmlNode.new(elem)
188
+ when :all
189
+ @element.elements.to_a(xpath).collect { |e| child_nodes[e] ||= XmlNode.new(e) }
190
+ end
191
+ end
192
+
193
+ def <<(elem)
194
+ case elem
195
+ when nil then return
196
+ when Array
197
+ elem.each { |e| @element << e.to_xml_element }
198
+ else
199
+ @element << elem.to_xml_element
200
+ end
201
+ end
202
+
203
+ def to_xml_element
204
+ @element
205
+ end
206
+
207
+ def to_s
208
+ @element.to_s
209
+ end
210
+
211
+ # Use to get pretty formatted xml including DECL
212
+ # instructions
213
+ def to_xml
214
+ xml = []
215
+ document = REXML::Document.new
216
+ document << REXML::XMLDecl.new('1.0')
217
+ document << @element
218
+ document.write( xml, 0)
219
+ xml.join
220
+ end
221
+
222
+ end
@@ -0,0 +1,94 @@
1
+ require 'rubygems'
2
+ require 'active_support'
3
+ require "test/unit"
4
+
5
+ require File.dirname(__FILE__) + "/../lib/xml_node"
6
+
7
+ class TestXmlNode < Test::Unit::TestCase
8
+
9
+ def test_init_sanity
10
+ assert_raise(ArgumentError) { XmlNode.new }
11
+ assert_nothing_raised { XmlNode.new('feed')}
12
+ assert_nothing_raised { XmlNode.new('feed', 'content') }
13
+ assert_nothing_raised { XmlNode.new('feed', :attribute => true) }
14
+ assert_nothing_raised { XmlNode.new('feed', 'content', :attribute => true) }
15
+ end
16
+
17
+ def test_element_generation
18
+ assert_equal '<feed/>', XmlNode.new('feed').to_s
19
+ assert_equal '<feed>content</feed>', XmlNode.new('feed', 'content').to_s
20
+ assert_equal "<feed attr='true'>content</feed>", XmlNode.new('feed', 'content', :attr => true).to_s
21
+ assert_equal "<feed attr='true'/>", XmlNode.new('feed', :attr => true).to_s
22
+ end
23
+
24
+ def test_nesting
25
+ assert_equal '<feed><element/></feed>', XmlNode.new('feed') { |n| n << XmlNode.new('element') }.to_s
26
+ assert_equal '<feed><element><id>1</id></element></feed>', XmlNode.new('feed') { |n| n << XmlNode.new('element') { |n| n << XmlNode.new('id', '1')} }.to_s
27
+ end
28
+
29
+ def test_cdata
30
+ node = XmlNode.new('feed')
31
+ node.text = '...'
32
+ node.cdata = 'Goodbye world'
33
+ node.cdata = 'Hello world'
34
+
35
+ assert_equal '<feed>...<![CDATA[Hello world]]></feed>', node.to_s
36
+ assert_equal 'Hello world', node.cdata
37
+ assert_equal '...', node.text
38
+ end
39
+
40
+ def test_text
41
+ node = XmlNode.new('feed')
42
+ node.text = 'Hello world'
43
+
44
+ assert_equal '<feed>Hello world</feed>', node.to_s
45
+ assert_equal 'Hello world', node.text
46
+ end
47
+
48
+ def test_attributes
49
+ node = XmlNode.new('feed')
50
+ node['attr'] = 1
51
+ assert_equal '1', node['attr']
52
+ end
53
+
54
+ def test_namespace
55
+ node = XmlNode.new('feed')
56
+ node.namespace 'http://www.w3.org/2005/Atom'
57
+ assert_equal "<feed xmlns='http://www.w3.org/2005/Atom'/>", node.to_s
58
+ end
59
+
60
+ def test_named_namespace
61
+ node = XmlNode.new('feed')
62
+ node.namespace :opensearch, 'http://a9.com/-/spec/opensearch/1.1/'
63
+ assert_equal "<feed xmlns:opensearch='http://a9.com/-/spec/opensearch/1.1/'/>", node.to_s
64
+ end
65
+
66
+ def test_generate_nice_xml
67
+ assert_equal "<?xml version='1.0'?>\n<feed>\n <element>test</element>\n <element/>\n</feed>", XmlNode.new('feed') { |n| n << XmlNode.new('element', 'test'); n << XmlNode.new('element') }.to_xml
68
+ end
69
+
70
+ def test_add_array_of_nodes
71
+ assert_equal '<feed><e>1</e><e>2</e><e>3</e></feed>', XmlNode.new('feed') { |n| n << [1,2,3].collect{ |i| XmlNode.new('e', i) }}.to_s
72
+ end
73
+
74
+ def test_boolean
75
+ assert_equal '<boolean>true</boolean>', XmlNode.new('boolean', true).to_s
76
+ assert_equal '<boolean>false</boolean>', XmlNode.new('boolean', false).to_s
77
+ end
78
+
79
+ def test_nil
80
+ assert_equal '<nil/>', XmlNode.new('nil', nil).to_s
81
+ end
82
+
83
+
84
+ def test_dont_choke_on_nil_pushing
85
+ feed = XmlNode.new 'feed'
86
+ assert_nothing_raised do
87
+ feed << nil
88
+ end
89
+ assert_equal '<feed/>', feed.to_s
90
+ end
91
+
92
+
93
+
94
+ end