sucker 0.6.6 → 0.7.0

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/README.md CHANGED
@@ -22,18 +22,23 @@ Fiddle with curl.
22
22
  Set up a request.
23
23
 
24
24
  worker << {
25
- "Operation" => "ItemLookup",
26
- "IdType" => "ASIN",
27
- "ItemId" => asin_batch
25
+ "Operation" => "ItemLookup",
26
+ "IdType" => "ASIN",
27
+ "ItemId" => asin_batch,
28
+ "ResponseGroup" => ["ItemAttributes", "OfferFull"] }
28
29
 
29
30
  Hit Amazon and do something with the response.
30
31
 
31
32
  response = worker.get
32
- p response.code
33
- p response.time
34
- p response.body
33
+
34
+ # Response internals
35
+ p response.code,
36
+ response.time,
37
+ response.body,
38
+ response.xml
35
39
 
36
- response.to_h["ItemLookupResponse"]["Items"]["Item"].each { ... }
40
+ response.to_h("Item").each { |book| do_something }
41
+ response.to_h("Error").each { |error| p error["Message"] }
37
42
 
38
43
  Hit Amazon again.
39
44
 
@@ -2,7 +2,7 @@ module Sucker
2
2
 
3
3
  # A wrapper around the cURL response
4
4
  class Response
5
- attr_accessor :body, :code, :time
5
+ attr_accessor :body, :code, :time, :xml
6
6
 
7
7
  def initialize(curl)
8
8
  self.body = curl.body_str
@@ -10,12 +10,22 @@ module Sucker
10
10
  self.time = curl.total_time
11
11
  end
12
12
 
13
- def to_h
14
- @hash ||= content_to_string(Nokogiri::XML(body).to_hash)
13
+ # Hashifies XML document. Optionally, parses for a node name and returns a collection
14
+ # of the hashified nodes.
15
+ def to_h(path=nil)
16
+ if path
17
+ xml.xpath("//xmlns:#{path}").map { |node| content_to_string(node.to_hash[path]) }
18
+ else
19
+ content_to_string(xml.to_hash)
20
+ end
15
21
  end
16
22
 
17
23
  alias :to_hash :to_h
18
24
 
25
+ def xml
26
+ @xml ||= Nokogiri::XML(body)
27
+ end
28
+
19
29
  private
20
30
 
21
31
  def content_to_string(node)
@@ -15,8 +15,7 @@ module Sucker
15
15
  request.instance_eval do
16
16
  self.class.send :define_method, :fixture do
17
17
  values = parameters.
18
- reject{ |k, v| %w{AWSAccessKeyId Service}.
19
- include? k }.
18
+ reject { |k, v| %w{AWSAccessKeyId Service}.include? k }.
20
19
  values.
21
20
  flatten.
22
21
  join
@@ -0,0 +1,38 @@
1
+ require "spec_helper"
2
+
3
+ module Sucker
4
+ describe "Errors" do
5
+ before do
6
+ worker = Sucker.new(
7
+ :locale => "us",
8
+ :key => amazon["key"],
9
+ :secret => amazon["secret"])
10
+
11
+ # worker.curl { |curl| curl.verbose = true }
12
+
13
+ worker << {
14
+ "Operation" => "ItemLookup",
15
+ "IdType" => "ASIN",
16
+ "Condition" => "All",
17
+ "MerchantId" => "All",
18
+ "ResponseGroup" => ["ItemAttributes"] }
19
+
20
+ Sucker.stub(worker)
21
+
22
+ # The first ASIN exists, the latter two do not.
23
+ worker << { "ItemId" => ["0816614024", "0007218095", "0007218176"] }
24
+ @response = worker.get
25
+ end
26
+
27
+ it "returns two errors" do
28
+ errors = @response.to_hash("Error")
29
+ errors.size.should eql 2
30
+ errors.first["Message"].should include "not a valid value"
31
+ end
32
+
33
+ it "returns one item" do
34
+ items = @response.to_hash("ItemAttributes")
35
+ items.size.should eql 1
36
+ end
37
+ end
38
+ end
@@ -24,7 +24,7 @@ module Sucker
24
24
  context "single item" do
25
25
  before do
26
26
  @worker << { "ItemId" => "2070119874" }
27
- @item = @worker.get.to_h["ItemLookupResponse"]["Items"]["Item"]
27
+ @item = @worker.get.to_h("Item").first
28
28
  end
29
29
 
30
30
  it "returns an item" do
@@ -40,7 +40,7 @@ module Sucker
40
40
  context "multiple items" do
41
41
  before do
42
42
  @worker << { "ItemId" => ["0816614024", "0143105825"] }
43
- @items = @worker.get.to_h["ItemLookupResponse"]["Items"]["Item"]
43
+ @items = @worker.get.to_h("Item")
44
44
  end
45
45
 
46
46
  it "returns two items" do
@@ -23,7 +23,8 @@ module Sucker
23
23
  context "single item" do
24
24
  before do
25
25
  @worker << { "ItemId" => "0816614024" }
26
- @item = @worker.get.to_h["ItemLookupResponse"]["Items"]["Item"]
26
+ @response = @worker.get
27
+ @item = @response.to_h("Item").first
27
28
  end
28
29
 
29
30
  it "returns an item" do
@@ -38,12 +39,16 @@ module Sucker
38
39
  @item["ItemAttributes"].should be_an_instance_of Hash
39
40
  @item["Offers"].should be_an_instance_of Hash
40
41
  end
42
+
43
+ it "returns no errors" do
44
+ @response.to_h("Error").should be_empty
45
+ end
41
46
  end
42
47
 
43
48
  context "multiple items" do
44
49
  before do
45
50
  @worker << { "ItemId" => ["0816614024", "0143105825"] }
46
- @items = @worker.get.to_h["ItemLookupResponse"]["Items"]["Item"]
51
+ @items = @worker.get.to_h("Item")
47
52
  end
48
53
 
49
54
  it "returns two items" do
@@ -19,7 +19,7 @@ module Sucker
19
19
  context "single item" do
20
20
  before do
21
21
  @worker << { "ItemId" => "482224816X" }
22
- @item = @worker.get.to_h["ItemLookupResponse"]["Items"]["Item"]
22
+ @item = @worker.get.to_h("Item").first
23
23
  end
24
24
 
25
25
  it "returns an array of items" do
@@ -16,7 +16,7 @@ module Sucker
16
16
 
17
17
  Sucker.stub(@worker)
18
18
 
19
- @listings = @worker.get.to_h["SellerListingSearchResponse"]["SellerListings"]
19
+ @listings = @worker.get.to_h("SellerListings").first
20
20
  end
21
21
 
22
22
  it "returns page count" do
@@ -28,7 +28,7 @@ module Sucker
28
28
 
29
29
  Sucker.stub(@worker)
30
30
 
31
- @items = @worker.get.to_h["ItemLookupResponse"]["Items"].map { |items| items["Item"] }.flatten!
31
+ @items = @worker.get.to_hash("Item")
32
32
  end
33
33
 
34
34
  it "returns 20 items" do
@@ -7,4 +7,4 @@ require "rspec"
7
7
 
8
8
  require File.expand_path("../../lib/sucker", __FILE__)
9
9
 
10
- Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each{ |f| require f }
10
+ Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each { |f| require f }
@@ -4,12 +4,17 @@ require "spec_helper"
4
4
  module Sucker
5
5
  describe Response do
6
6
  before do
7
- curl = Sucker.new.curl
8
- curl.stub(:get).and_return(nil)
9
- curl.stub!(:body_str).and_return('<?xml version="1.0" ?><books><book><creator role="author">Gilles Deleuze</author><title>A Thousand Plateaus</title></book><book><creator role="author">Gilles Deleuze</author><title>Anti-Oedipus</title></book></books>')
10
- curl.stub!(:response_code).and_return(200)
11
- curl.stub!(:total_time).and_return(1.0)
12
- @response = Sucker::Response.new(curl)
7
+ @asins = ["0816614024", "0143105825"]
8
+ worker = Sucker.new(
9
+ :locale => "us",
10
+ :key => amazon["key"],
11
+ :secret => amazon["secret"])
12
+ worker << {
13
+ "Operation" => "ItemLookup",
14
+ "IdType" => "ASIN",
15
+ "ResponseGroup" => ["ItemAttributes", "OfferFull"],
16
+ "ItemId" => @asins }
17
+ @response = worker.get
13
18
  end
14
19
 
15
20
  context ".new" do
@@ -26,22 +31,29 @@ module Sucker
26
31
  end
27
32
  end
28
33
 
29
- context "to_h" do
34
+ context "#xml" do
35
+ it "returns a Nokogiri document" do
36
+ @response.xml.should be_an_instance_of Nokogiri::XML::Document
37
+ end
38
+ end
39
+
40
+ context "#to_h" do
30
41
  it "returns a hash" do
31
42
  @response.to_h.should be_an_instance_of Hash
32
43
  end
33
44
 
34
45
  it "converts a content hash to string" do
35
- @response.to_h["books"]["book"].first["title"].should be_an_instance_of String
46
+ @response.body = "<book><title>A Thousand Plateaus</title></book>"
47
+ @response.to_h["book"]["title"].should be_an_instance_of String
36
48
  end
37
49
 
38
50
  it "is aliased as to_hash" do
39
51
  @response.to_hash.should eql @response.to_h
40
52
  end
41
53
 
42
- it "caches hash" do
43
- hash = @response.to_h
44
- @response.instance_variable_get(:@hash).should eql hash
54
+ it "parses document for a node name and returns a collection of hashified nodes" do
55
+ response = @response.to_hash("ItemAttributes")
56
+ response.map { |book| book["ISBN"] }.should eql @asins
45
57
  end
46
58
 
47
59
  it "renders French" do
metadata CHANGED
@@ -1,13 +1,12 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sucker
3
3
  version: !ruby/object:Gem::Version
4
- hash: 11
5
4
  prerelease: false
6
5
  segments:
7
6
  - 0
8
- - 6
9
- - 6
10
- version: 0.6.6
7
+ - 7
8
+ - 0
9
+ version: 0.7.0
11
10
  platform: ruby
12
11
  authors:
13
12
  - Hakan Ensari
@@ -16,60 +15,57 @@ autorequire:
16
15
  bindir: bin
17
16
  cert_chain: []
18
17
 
19
- date: 2010-08-05 00:00:00 +01:00
18
+ date: 2010-08-06 00:00:00 +01:00
20
19
  default_executable:
21
20
  dependencies:
22
21
  - !ruby/object:Gem::Dependency
23
- prerelease: false
24
- type: :runtime
25
22
  name: activesupport
26
- version_requirements: &id001 !ruby/object:Gem::Requirement
23
+ requirement: &id001 !ruby/object:Gem::Requirement
27
24
  none: false
28
25
  requirements:
29
26
  - - ">="
30
27
  - !ruby/object:Gem::Version
31
- hash: 7712042
32
28
  segments:
33
29
  - 3
34
30
  - 0
35
31
  - 0
36
32
  - rc
37
33
  version: 3.0.0.rc
38
- requirement: *id001
39
- - !ruby/object:Gem::Dependency
40
- prerelease: false
41
34
  type: :runtime
35
+ prerelease: false
36
+ version_requirements: *id001
37
+ - !ruby/object:Gem::Dependency
42
38
  name: nokogiri
43
- version_requirements: &id002 !ruby/object:Gem::Requirement
39
+ requirement: &id002 !ruby/object:Gem::Requirement
44
40
  none: false
45
41
  requirements:
46
42
  - - ">="
47
43
  - !ruby/object:Gem::Version
48
- hash: 113
49
44
  segments:
50
45
  - 1
51
46
  - 4
52
47
  - 3
53
48
  - 1
54
49
  version: 1.4.3.1
55
- requirement: *id002
56
- - !ruby/object:Gem::Dependency
57
- prerelease: false
58
50
  type: :runtime
51
+ prerelease: false
52
+ version_requirements: *id002
53
+ - !ruby/object:Gem::Dependency
59
54
  name: curb
60
- version_requirements: &id003 !ruby/object:Gem::Requirement
55
+ requirement: &id003 !ruby/object:Gem::Requirement
61
56
  none: false
62
57
  requirements:
63
58
  - - ">="
64
59
  - !ruby/object:Gem::Version
65
- hash: 105
66
60
  segments:
67
61
  - 0
68
62
  - 7
69
63
  - 7
70
64
  - 1
71
65
  version: 0.7.7.1
72
- requirement: *id003
66
+ type: :runtime
67
+ prerelease: false
68
+ version_requirements: *id003
73
69
  description: A paper-thin Ruby wrapper to the Amazon Product Advertising API
74
70
  email: code@papercavalier.com
75
71
  executables: []
@@ -87,6 +83,7 @@ files:
87
83
  - lib/sucker/stub.rb
88
84
  - README.md
89
85
  - spec/benchmark/to_hash_implementations.rb
86
+ - spec/integration/errors_spec.rb
90
87
  - spec/integration/france_spec.rb
91
88
  - spec/integration/item_lookup_spec.rb
92
89
  - spec/integration/japan_spec.rb
@@ -113,7 +110,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
113
110
  requirements:
114
111
  - - ">="
115
112
  - !ruby/object:Gem::Version
116
- hash: 3
113
+ hash: 4409148971650304022
117
114
  segments:
118
115
  - 0
119
116
  version: "0"
@@ -122,7 +119,6 @@ required_rubygems_version: !ruby/object:Gem::Requirement
122
119
  requirements:
123
120
  - - ">="
124
121
  - !ruby/object:Gem::Version
125
- hash: 3
126
122
  segments:
127
123
  - 0
128
124
  version: "0"
@@ -135,6 +131,7 @@ specification_version: 3
135
131
  summary: A paper-thin Ruby wrapper to the Amazon Product Advertising API
136
132
  test_files:
137
133
  - spec/benchmark/to_hash_implementations.rb
134
+ - spec/integration/errors_spec.rb
138
135
  - spec/integration/france_spec.rb
139
136
  - spec/integration/item_lookup_spec.rb
140
137
  - spec/integration/japan_spec.rb