rforce 0.5.1 → 0.6
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/Manifest.txt +1 -0
- data/Rakefile +16 -8
- data/lib/rforce/soap_response.rb +4 -2
- data/lib/rforce/soap_response_nokogiri.rb +45 -0
- data/lib/rforce/version.rb +1 -1
- data/spec/rforce_spec.rb +60 -1
- data/tasks/timing.rake +3 -1
- metadata +11 -4
data/Manifest.txt
CHANGED
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
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
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 }
|
data/lib/rforce/soap_response.rb
CHANGED
@@ -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(:
|
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
|
data/lib/rforce/version.rb
CHANGED
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><tag attr="Bee's knees & toes"></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
|
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
|
-
-
|
8
|
-
|
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:
|
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"
|