rforce 0.5.1 → 0.6

Sign up to get free protection for your applications and to get access to all the features.
data/Manifest.txt CHANGED
@@ -9,6 +9,7 @@ lib/rforce/soap_pullable.rb
9
9
  lib/rforce/soap_response.rb
10
10
  lib/rforce/soap_response_expat.rb
11
11
  lib/rforce/soap_response_hpricot.rb
12
+ lib/rforce/soap_response_nokogiri.rb
12
13
  lib/rforce/soap_response_rexml.rb
13
14
  lib/rforce/version.rb
14
15
  spec/rforce_spec.rb
data/Rakefile CHANGED
@@ -3,15 +3,23 @@
3
3
  $:.unshift './lib'
4
4
 
5
5
  require 'rubygems'
6
+ gem 'hoe', '>= 2.1.0'
6
7
  require 'hoe'
7
- require 'rforce/version'
8
-
9
- Hoe.new('rforce', RForce::VERSION) do |p|
10
- p.developer 'Ian Dees', 'undees@gmail.com'
11
- p.extra_deps = [['builder', '~> 2.0'], ['oauth', '~> 0.4']]
12
- p.extra_dev_deps = [['rspec', '~> 1.3']]
13
- p.remote_rdoc_dir = ''
14
- p.rspec_options = ['-rubygems', '--options', 'spec/spec.opts']
8
+
9
+ Hoe.plugin :gemspec
10
+
11
+ Hoe.spec 'rforce' do
12
+ developer('Ian Dees', 'undees@gmail.com')
13
+
14
+ self.extra_deps << ['builder', '~> 2.0']
15
+ self.extra_deps << ['oauth', '~> 0.4']
16
+
17
+ self.extra_dev_deps << ['rspec', '~> 1.3']
18
+
19
+ self.rdoc_locations = ['undees@rforce.rubyforge.org:/var/www/gforge-projects/rforce']
20
+ self.remote_rdoc_dir = ''
21
+
22
+ self.rspec_options = ['-rubygems', '--options', 'spec/spec.opts']
15
23
  end
16
24
 
17
25
  Dir['tasks/**/*.rake'].each { |rake| load rake }
@@ -1,3 +1,4 @@
1
+ begin; require 'rforce/soap_response_nokogiri'; rescue LoadError; end
1
2
  begin; require 'rforce/soap_response_hpricot'; rescue LoadError; end
2
3
  begin; require 'rforce/soap_response_expat'; rescue LoadError; end
3
4
  require 'rforce/soap_response_rexml'
@@ -6,7 +7,8 @@ require 'rforce/soap_response_rexml'
6
7
  module RForce
7
8
  # Use the fastest XML parser available.
8
9
  SoapResponse =
9
- (RForce::const_get(:SoapResponseExpat) rescue nil) ||
10
- (RForce::const_get(:SoapResponseHpricot) rescue nil) ||
10
+ (RForce::const_get(:SoapResponseExpat) rescue nil) ||
11
+ (RForce::const_get(:SoapResponseNokogiri) rescue nil) ||
12
+ (RForce::const_get(:SoapResponseHpricot) rescue nil) ||
11
13
  SoapResponseRexml
12
14
  end
@@ -0,0 +1,45 @@
1
+ require 'nokogiri'
2
+
3
+ module RForce
4
+ class SoapResponseNokogiri
5
+ def initialize(content)
6
+ @content = content
7
+ end
8
+
9
+ def parse
10
+ doc = Nokogiri::XML(@content)
11
+ body = doc.at_xpath("//soapenv:Body")
12
+ to_hash(body)
13
+ end
14
+
15
+ private
16
+ def to_hash(node)
17
+ if node.text?
18
+ stripped = node.text.strip
19
+ return stripped.empty? ? nil : stripped
20
+ end
21
+
22
+ children = node.children.reject {|c| c.text? && c.text.strip.empty? }
23
+
24
+ return nil if children.empty?
25
+
26
+ return children.first.text.strip if children.first.text?
27
+
28
+ elements = MethodHash.new
29
+
30
+ children.each do |elem|
31
+ name = elem.name.split(":").last.to_sym
32
+
33
+ if !elements[name]
34
+ elements[name] = to_hash(elem)
35
+ elsif Array === elements[name]
36
+ elements[name] << to_hash(elem)
37
+ else
38
+ elements[name] = [elements[name]] << to_hash(elem)
39
+ end
40
+ end
41
+
42
+ return elements.empty? ? nil : elements
43
+ end
44
+ end
45
+ end
@@ -1,3 +1,3 @@
1
1
  module RForce
2
- VERSION = '0.5.1'
2
+ VERSION = '0.6'
3
3
  end
data/spec/rforce_spec.rb CHANGED
@@ -49,7 +49,7 @@ describe 'a SoapResponse implementation' do
49
49
  fname = File.join(File.dirname(__FILE__), 'soap-response.xml')
50
50
  @contents = File.open(fname) {|f| f.read}
51
51
 
52
- [:rexml, :expat, :hpricot].each do |processor|
52
+ [:rexml, :expat, :hpricot, :nokogiri].each do |processor|
53
53
  name = "SoapResponse#{processor.to_s.capitalize}"
54
54
  variable = "@#{processor}_recs"
55
55
 
@@ -109,6 +109,65 @@ describe 'SoapResponseHpricot' do
109
109
  end
110
110
  end
111
111
 
112
+ describe 'SoapResponseNokogiri' do
113
+ SOAP_WRAPPER = <<-XML
114
+ <?xml version="1.0" encoding="UTF-8"?>
115
+ <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns="urn:partner.soap.sforce.com" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:sf="urn:sobject.partner.soap.sforce.com">
116
+ <soapenv:Body>
117
+ %s
118
+ </soapnenv:Body>
119
+ </soapenv:Envelope>
120
+ XML
121
+ def wrap_in_salesforce_envelope(xml)
122
+ SOAP_WRAPPER % xml
123
+ end
124
+
125
+ it 'parses nested elements into nested hashes' do
126
+ xml = wrap_in_salesforce_envelope("""
127
+ <foo>
128
+ <bar>Bin</bar>
129
+ </foo>""")
130
+
131
+ SoapResponseNokogiri.new(xml).parse.should == {:foo => {:bar => "Bin"}}
132
+ end
133
+
134
+ it 'parses repeated elements into arrays' do
135
+ xml = wrap_in_salesforce_envelope("""
136
+ <foo>
137
+ <bar>Bin</bar>
138
+ <bar>Bash</bar>
139
+ </foo>""")
140
+
141
+ SoapResponseNokogiri.new(xml).parse.should == {:foo => {:bar => ["Bin", "Bash"]}}
142
+ end
143
+
144
+ it 'disregards namespacing when determining hash keys' do
145
+ xml = wrap_in_salesforce_envelope("""
146
+ <soapenv:foo>
147
+ <bar>Bin</bar>
148
+ <soapenv:bar>Bash</bar>
149
+ </foo>""")
150
+
151
+ SoapResponseNokogiri.new(xml).parse.should == {:foo => {:bar => ["Bin", "Bash"]}}
152
+ end
153
+
154
+ it 'unescapes any HTML contained in text nodes' do
155
+ xml = wrap_in_salesforce_envelope("""
156
+ <soapenv:foo>
157
+ <bar>Bin</bar>
158
+ <bar>&lt;tag attr=&quot;Bee&apos;s knees &amp; toes&quot;&gt;</bar>
159
+ </foo>""")
160
+
161
+ SoapResponseNokogiri.new(xml).parse()[:foo][:bar].last.should == %q(<tag attr="Bee's knees & toes">)
162
+ end
163
+
164
+ it 'returns an object that can be navigated via methods in addition to keys' do
165
+ xml = wrap_in_salesforce_envelope("<foo><bar><bin>bash</bin></bar></foo>")
166
+ SoapResponseNokogiri.new(xml).parse().foo.bar.bin.should == "bash"
167
+ end
168
+
169
+ end
170
+
112
171
  CreateXml = <<HERE.gsub(/\n\s*/, '')
113
172
  <partner:create>
114
173
  <partner:sObjects>
data/tasks/timing.rake CHANGED
@@ -7,7 +7,8 @@ task :timing do
7
7
 
8
8
  [:SoapResponseRexml,
9
9
  :SoapResponseExpat,
10
- :SoapResponseHpricot].each do |name|
10
+ :SoapResponseHpricot,
11
+ :SoapResponseNokogiri].each do |name|
11
12
  begin
12
13
  klass = RForce.const_get name
13
14
  started_at = Time.now
@@ -15,6 +16,7 @@ task :timing do
15
16
  elapsed = Time.now - started_at
16
17
  puts "#{klass}: #{elapsed}"
17
18
  rescue NameError
19
+ puts $!
18
20
  # no-op
19
21
  end
20
22
  end
metadata CHANGED
@@ -1,12 +1,12 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rforce
3
3
  version: !ruby/object:Gem::Version
4
+ hash: 7
4
5
  prerelease: false
5
6
  segments:
6
7
  - 0
7
- - 5
8
- - 1
9
- version: 0.5.1
8
+ - 6
9
+ version: "0.6"
10
10
  platform: ruby
11
11
  authors:
12
12
  - Ian Dees
@@ -14,7 +14,7 @@ autorequire:
14
14
  bindir: bin
15
15
  cert_chain: []
16
16
 
17
- date: 2010-12-21 00:00:00 -08:00
17
+ date: 2011-01-18 00:00:00 -08:00
18
18
  default_executable:
19
19
  dependencies:
20
20
  - !ruby/object:Gem::Dependency
@@ -25,6 +25,7 @@ dependencies:
25
25
  requirements:
26
26
  - - ~>
27
27
  - !ruby/object:Gem::Version
28
+ hash: 3
28
29
  segments:
29
30
  - 2
30
31
  - 0
@@ -39,6 +40,7 @@ dependencies:
39
40
  requirements:
40
41
  - - ~>
41
42
  - !ruby/object:Gem::Version
43
+ hash: 3
42
44
  segments:
43
45
  - 0
44
46
  - 4
@@ -53,6 +55,7 @@ dependencies:
53
55
  requirements:
54
56
  - - ~>
55
57
  - !ruby/object:Gem::Version
58
+ hash: 9
56
59
  segments:
57
60
  - 1
58
61
  - 3
@@ -67,6 +70,7 @@ dependencies:
67
70
  requirements:
68
71
  - - ">="
69
72
  - !ruby/object:Gem::Version
73
+ hash: 47
70
74
  segments:
71
75
  - 2
72
76
  - 8
@@ -97,6 +101,7 @@ files:
97
101
  - lib/rforce/soap_response.rb
98
102
  - lib/rforce/soap_response_expat.rb
99
103
  - lib/rforce/soap_response_hpricot.rb
104
+ - lib/rforce/soap_response_nokogiri.rb
100
105
  - lib/rforce/soap_response_rexml.rb
101
106
  - lib/rforce/version.rb
102
107
  - spec/rforce_spec.rb
@@ -119,6 +124,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
119
124
  requirements:
120
125
  - - ">="
121
126
  - !ruby/object:Gem::Version
127
+ hash: 3
122
128
  segments:
123
129
  - 0
124
130
  version: "0"
@@ -127,6 +133,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
127
133
  requirements:
128
134
  - - ">="
129
135
  - !ruby/object:Gem::Version
136
+ hash: 3
130
137
  segments:
131
138
  - 0
132
139
  version: "0"