benschwarz-smoke 0.5.1 → 0.5.2
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/VERSION.yml +2 -2
- data/dependencies +6 -6
- data/lib/smoke.rb +1 -5
- data/vendor/crack-0.1.1/README.rdoc +22 -0
- data/vendor/{crack → crack-0.1.1}/VERSION.yml +2 -2
- data/vendor/{crack → crack-0.1.1}/lib/crack/core_extensions.rb +0 -2
- data/vendor/{crack → crack-0.1.1}/lib/crack/json.rb +1 -3
- data/vendor/{crack → crack-0.1.1}/lib/crack/xml.rb +15 -18
- data/vendor/{crack → crack-0.1.1}/test/json_test.rb +1 -25
- data/vendor/{crack → crack-0.1.1}/test/xml_test.rb +9 -47
- data/vendor/{fakeweb → fakeweb-1.2.5}/test/test_fake_web.rb +0 -17
- data/vendor/{fakeweb → fakeweb-1.2.5}/test/test_response_headers.rb +1 -7
- data/vendor/{rest-client → rest-client-1.0.1}/README.rdoc +1 -1
- data/vendor/{rest-client → rest-client-1.0.1}/Rakefile +48 -21
- data/vendor/{rest-client → rest-client-1.0.1}/lib/restclient/exceptions.rb +0 -4
- data/vendor/{rest-client → rest-client-1.0.1}/lib/restclient/request.rb +3 -5
- data/vendor/{rest-client → rest-client-1.0.1}/lib/restclient.rb +1 -7
- data/vendor/{rest-client → rest-client-1.0.1}/spec/exceptions_spec.rb +2 -13
- data/vendor/{rest-client → rest-client-1.0.1}/spec/request_spec.rb +6 -20
- data/vendor/{simple-rss → simple-rss-1.2}/lib/simple-rss.rb +7 -8
- data/vendor/{simple-rss → simple-rss-1.2}/test/base/base_test.rb +2 -2
- metadata +95 -108
- data/vendor/crack/History +0 -15
- data/vendor/crack/README.rdoc +0 -42
- data/vendor/crack/Rakefile +0 -49
- data/vendor/crack/crack.gemspec +0 -61
- data/vendor/crack/test/data/twittersearch-firefox.json +0 -1
- data/vendor/crack/test/data/twittersearch-ie.json +0 -1
- data/vendor/crack/test/hash_test.rb +0 -56
- data/vendor/crack/test/string_test.rb +0 -31
- data/vendor/fakeweb/fakeweb.gemspec +0 -21
- data/vendor/rest-client/VERSION +0 -1
- data/vendor/rest-client/rest-client.gemspec +0 -66
- data/vendor/simple-rss/install.rb +0 -40
- data/vendor/simple-rss/simple-rss.gemspec +0 -12
- /data/vendor/{crack → crack-0.1.1}/LICENSE +0 -0
- /data/vendor/{crack → crack-0.1.1}/lib/crack.rb +0 -0
- /data/vendor/{crack → crack-0.1.1}/test/crack_test.rb +0 -0
- /data/vendor/{crack → crack-0.1.1}/test/test_helper.rb +0 -0
- /data/vendor/{fakeweb → fakeweb-1.2.5}/CHANGELOG +0 -0
- /data/vendor/{fakeweb → fakeweb-1.2.5}/LICENSE.txt +0 -0
- /data/vendor/{fakeweb → fakeweb-1.2.5}/README.rdoc +0 -0
- /data/vendor/{fakeweb → fakeweb-1.2.5}/Rakefile +0 -0
- /data/vendor/{fakeweb → fakeweb-1.2.5}/lib/fake_web/ext/net_http.rb +0 -0
- /data/vendor/{fakeweb → fakeweb-1.2.5}/lib/fake_web/registry.rb +0 -0
- /data/vendor/{fakeweb → fakeweb-1.2.5}/lib/fake_web/responder.rb +0 -0
- /data/vendor/{fakeweb → fakeweb-1.2.5}/lib/fake_web/response.rb +0 -0
- /data/vendor/{fakeweb → fakeweb-1.2.5}/lib/fake_web/stub_socket.rb +0 -0
- /data/vendor/{fakeweb → fakeweb-1.2.5}/lib/fake_web/utility.rb +0 -0
- /data/vendor/{fakeweb → fakeweb-1.2.5}/lib/fake_web.rb +0 -0
- /data/vendor/{fakeweb → fakeweb-1.2.5}/lib/fakeweb.rb +0 -0
- /data/vendor/{fakeweb → fakeweb-1.2.5}/test/fixtures/google_response_from_curl +0 -0
- /data/vendor/{fakeweb → fakeweb-1.2.5}/test/fixtures/google_response_with_transfer_encoding +0 -0
- /data/vendor/{fakeweb → fakeweb-1.2.5}/test/fixtures/google_response_without_transfer_encoding +0 -0
- /data/vendor/{fakeweb → fakeweb-1.2.5}/test/fixtures/test_example.txt +0 -0
- /data/vendor/{fakeweb → fakeweb-1.2.5}/test/fixtures/test_txt_file +0 -0
- /data/vendor/{fakeweb → fakeweb-1.2.5}/test/test_allow_net_connect.rb +0 -0
- /data/vendor/{fakeweb → fakeweb-1.2.5}/test/test_deprecations.rb +0 -0
- /data/vendor/{fakeweb → fakeweb-1.2.5}/test/test_fake_authentication.rb +0 -0
- /data/vendor/{fakeweb → fakeweb-1.2.5}/test/test_fake_web_open_uri.rb +0 -0
- /data/vendor/{fakeweb → fakeweb-1.2.5}/test/test_helper.rb +0 -0
- /data/vendor/{fakeweb → fakeweb-1.2.5}/test/test_missing_open_uri.rb +0 -0
- /data/vendor/{fakeweb → fakeweb-1.2.5}/test/test_precedence.rb +0 -0
- /data/vendor/{fakeweb → fakeweb-1.2.5}/test/test_query_string.rb +0 -0
- /data/vendor/{fakeweb → fakeweb-1.2.5}/test/test_regexes.rb +0 -0
- /data/vendor/{fakeweb → fakeweb-1.2.5}/test/test_trailing_slashes.rb +0 -0
- /data/vendor/{fakeweb → fakeweb-1.2.5}/test/test_utility.rb +0 -0
- /data/vendor/{rest-client → rest-client-1.0.1}/bin/restclient +0 -0
- /data/vendor/{rest-client → rest-client-1.0.1}/lib/rest_client.rb +0 -0
- /data/vendor/{rest-client → rest-client-1.0.1}/lib/restclient/mixin/response.rb +0 -0
- /data/vendor/{rest-client → rest-client-1.0.1}/lib/restclient/raw_response.rb +0 -0
- /data/vendor/{rest-client → rest-client-1.0.1}/lib/restclient/resource.rb +0 -0
- /data/vendor/{rest-client → rest-client-1.0.1}/lib/restclient/response.rb +0 -0
- /data/vendor/{rest-client → rest-client-1.0.1}/spec/base.rb +0 -0
- /data/vendor/{rest-client → rest-client-1.0.1}/spec/mixin/response_spec.rb +0 -0
- /data/vendor/{rest-client → rest-client-1.0.1}/spec/raw_response_spec.rb +0 -0
- /data/vendor/{rest-client → rest-client-1.0.1}/spec/resource_spec.rb +0 -0
- /data/vendor/{rest-client → rest-client-1.0.1}/spec/response_spec.rb +0 -0
- /data/vendor/{rest-client → rest-client-1.0.1}/spec/restclient_spec.rb +0 -0
- /data/vendor/{simple-rss → simple-rss-1.2}/LICENSE +0 -0
- /data/vendor/{simple-rss → simple-rss-1.2}/README +0 -0
- /data/vendor/{simple-rss → simple-rss-1.2}/Rakefile +0 -0
- /data/vendor/{simple-rss → simple-rss-1.2}/test/data/atom.xml +0 -0
- /data/vendor/{simple-rss → simple-rss-1.2}/test/data/not-rss.xml +0 -0
- /data/vendor/{simple-rss → simple-rss-1.2}/test/data/rss09.rdf +0 -0
- /data/vendor/{simple-rss → simple-rss-1.2}/test/data/rss20.xml +0 -0
- /data/vendor/{simple-rss → simple-rss-1.2}/test/test_helper.rb +0 -0
data/VERSION.yml
CHANGED
data/dependencies
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
fakeweb
|
|
5
|
-
|
|
1
|
+
simple-rss 1.2
|
|
2
|
+
rest-client 1.0.1
|
|
3
|
+
json 1.1.3
|
|
4
|
+
fakeweb 1.2.5
|
|
5
|
+
crack 0.1.1
|
|
6
6
|
moneta git://github.com/benschwarz/moneta.git
|
|
7
|
-
|
|
7
|
+
dependencies git://github.com/djanowski/dependencies.git
|
data/lib/smoke.rb
CHANGED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
= crack
|
|
2
|
+
|
|
3
|
+
Really simple JSON and XML parsing, ripped from Merb and Rails. The XML parser is ripped from Merb and the JSON parser is ripped from Rails. I take no credit, just packaged them for all to enjoy and easily use.
|
|
4
|
+
|
|
5
|
+
= usage
|
|
6
|
+
|
|
7
|
+
gem 'crack'
|
|
8
|
+
require 'crack' # for xml and json
|
|
9
|
+
require 'crack/json' # for just json
|
|
10
|
+
require 'crack/xml' # for just xml
|
|
11
|
+
|
|
12
|
+
= examples
|
|
13
|
+
|
|
14
|
+
Crack::XML.parse("<tag>This is the contents</tag>")
|
|
15
|
+
# => {'tag' => 'This is the contents'}
|
|
16
|
+
|
|
17
|
+
Crack::JSON.parse('{"tag":"This is the contents"}')
|
|
18
|
+
# => {'tag' => 'This is the contents'}
|
|
19
|
+
|
|
20
|
+
== Copyright
|
|
21
|
+
|
|
22
|
+
Copyright (c) 2009 John Nunemaker. See LICENSE for details.
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
require 'rexml/parsers/streamparser'
|
|
2
2
|
require 'rexml/parsers/baseparser'
|
|
3
3
|
require 'rexml/light/node'
|
|
4
|
-
require 'rexml/text'
|
|
5
4
|
require 'date'
|
|
6
5
|
require 'time'
|
|
7
6
|
require 'yaml'
|
|
@@ -47,13 +46,7 @@ class REXMLUtilityNode #:nodoc:
|
|
|
47
46
|
|
|
48
47
|
self.available_typecasts = self.typecasts.keys
|
|
49
48
|
|
|
50
|
-
def initialize(name,
|
|
51
|
-
|
|
52
|
-
# unnormalize attribute values
|
|
53
|
-
attributes = Hash[* normalized_attributes.map { |key, value|
|
|
54
|
-
[ key, unnormalize_xml_entities(value) ]
|
|
55
|
-
}.flatten]
|
|
56
|
-
|
|
49
|
+
def initialize(name, attributes = {})
|
|
57
50
|
@name = name.tr("-", "_")
|
|
58
51
|
# leave the type alone if we don't know what it is
|
|
59
52
|
@type = self.class.available_typecasts.include?(attributes["type"]) ? attributes.delete("type") : attributes["type"]
|
|
@@ -81,10 +74,7 @@ class REXMLUtilityNode #:nodoc:
|
|
|
81
74
|
end
|
|
82
75
|
|
|
83
76
|
if @text
|
|
84
|
-
|
|
85
|
-
t.class.send(:attr_accessor, :attributes)
|
|
86
|
-
t.attributes = attributes
|
|
87
|
-
return { name => t }
|
|
77
|
+
return { name => typecast_value( translate_xml_entities( inner_html ) ) }
|
|
88
78
|
else
|
|
89
79
|
#change repeating groups into an array
|
|
90
80
|
groups = @children.inject({}) { |s,e| (s[e.name] ||= []) << e; s }
|
|
@@ -151,6 +141,19 @@ class REXMLUtilityNode #:nodoc:
|
|
|
151
141
|
proc.nil? ? value : proc.call(value)
|
|
152
142
|
end
|
|
153
143
|
|
|
144
|
+
# Convert basic XML entities into their literal values.
|
|
145
|
+
#
|
|
146
|
+
# @param value<#gsub> An XML fragment.
|
|
147
|
+
#
|
|
148
|
+
# @return <#gsub> The XML fragment after converting entities.
|
|
149
|
+
def translate_xml_entities(value)
|
|
150
|
+
value.gsub(/</, "<").
|
|
151
|
+
gsub(/>/, ">").
|
|
152
|
+
gsub(/"/, '"').
|
|
153
|
+
gsub(/'/, "'").
|
|
154
|
+
gsub(/&/, "&")
|
|
155
|
+
end
|
|
156
|
+
|
|
154
157
|
# Take keys of the form foo-bar and convert them to foo_bar
|
|
155
158
|
def undasherize_keys(params)
|
|
156
159
|
params.keys.each do |key, value|
|
|
@@ -176,12 +179,6 @@ class REXMLUtilityNode #:nodoc:
|
|
|
176
179
|
def to_s
|
|
177
180
|
to_html
|
|
178
181
|
end
|
|
179
|
-
|
|
180
|
-
private
|
|
181
|
-
|
|
182
|
-
def unnormalize_xml_entities value
|
|
183
|
-
REXML::Text.unnormalize(value)
|
|
184
|
-
end
|
|
185
182
|
end
|
|
186
183
|
|
|
187
184
|
module Crack
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
# coding: utf-8
|
|
2
1
|
require 'test_helper'
|
|
3
2
|
|
|
4
3
|
class JsonTest < Test::Unit::TestCase
|
|
@@ -40,27 +39,4 @@ class JsonTest < Test::Unit::TestCase
|
|
|
40
39
|
Crack::JSON.parse(%({: 1}))
|
|
41
40
|
}.should raise_error(Crack::ParseError)
|
|
42
41
|
end
|
|
43
|
-
|
|
44
|
-
should "should be able to parse a JSON response from a Twitter search about 'firefox'" do
|
|
45
|
-
data = ''
|
|
46
|
-
File.open(File.dirname(__FILE__) + "/data/twittersearch-firefox.json", "r") { |f|
|
|
47
|
-
data = f.read
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
lambda {
|
|
51
|
-
Crack::JSON.parse(data)
|
|
52
|
-
}.should_not raise_error(Crack::ParseError)
|
|
53
|
-
end
|
|
54
|
-
|
|
55
|
-
should "should be able to parse a JSON response from a Twitter search about 'internet explorer'" do
|
|
56
|
-
data = ''
|
|
57
|
-
File.open(File.dirname(__FILE__) + "/data/twittersearch-ie.json", "r") { |f|
|
|
58
|
-
data = f.read
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
lambda {
|
|
62
|
-
Crack::JSON.parse(data)
|
|
63
|
-
}.should_not raise_error(Crack::ParseError)
|
|
64
|
-
end
|
|
65
|
-
|
|
66
|
-
end
|
|
42
|
+
end
|
|
@@ -65,39 +65,8 @@ class XmlTest < Test::Unit::TestCase
|
|
|
65
65
|
}
|
|
66
66
|
}
|
|
67
67
|
}
|
|
68
|
-
|
|
69
|
-
Crack::XML.parse(xml).should == hash
|
|
70
|
-
end
|
|
71
|
-
|
|
72
|
-
context "Parsing xml with text and attributes" do
|
|
73
|
-
setup do
|
|
74
|
-
xml =<<-XML
|
|
75
|
-
<opt>
|
|
76
|
-
<user login="grep">Gary R Epstein</user>
|
|
77
|
-
<user>Simon T Tyson</user>
|
|
78
|
-
</opt>
|
|
79
|
-
XML
|
|
80
|
-
@data = Crack::XML.parse(xml)
|
|
81
|
-
end
|
|
82
68
|
|
|
83
|
-
should
|
|
84
|
-
@data.should == {
|
|
85
|
-
'opt' => {
|
|
86
|
-
'user' => [
|
|
87
|
-
'Gary R Epstein',
|
|
88
|
-
'Simon T Tyson'
|
|
89
|
-
]
|
|
90
|
-
}
|
|
91
|
-
}
|
|
92
|
-
end
|
|
93
|
-
|
|
94
|
-
should "be parse attributes for text node if present" do
|
|
95
|
-
@data['opt']['user'][0].attributes.should == {'login' => 'grep'}
|
|
96
|
-
end
|
|
97
|
-
|
|
98
|
-
should "default attributes to empty hash if not present" do
|
|
99
|
-
@data['opt']['user'][1].attributes.should == {}
|
|
100
|
-
end
|
|
69
|
+
Crack::XML.parse(xml).should == hash
|
|
101
70
|
end
|
|
102
71
|
|
|
103
72
|
should "should typecast an integer" do
|
|
@@ -126,26 +95,19 @@ class XmlTest < Test::Unit::TestCase
|
|
|
126
95
|
Crack::XML.parse(xml)['tag'].should == Date.parse('2007-12-31')
|
|
127
96
|
end
|
|
128
97
|
|
|
129
|
-
xml_entities = {
|
|
130
|
-
"<" => "<",
|
|
131
|
-
">" => ">",
|
|
132
|
-
'"' => """,
|
|
133
|
-
"'" => "'",
|
|
134
|
-
"&" => "&"
|
|
135
|
-
}
|
|
136
98
|
should "should unescape html entities" do
|
|
137
|
-
|
|
99
|
+
values = {
|
|
100
|
+
"<" => "<",
|
|
101
|
+
">" => ">",
|
|
102
|
+
'"' => """,
|
|
103
|
+
"'" => "'",
|
|
104
|
+
"&" => "&"
|
|
105
|
+
}
|
|
106
|
+
values.each do |k,v|
|
|
138
107
|
xml = "<tag>Some content #{v}</tag>"
|
|
139
108
|
Crack::XML.parse(xml)['tag'].should =~ Regexp.new(k)
|
|
140
109
|
end
|
|
141
110
|
end
|
|
142
|
-
|
|
143
|
-
should "should unescape XML entities in attributes" do
|
|
144
|
-
xml_entities.each do |k,v|
|
|
145
|
-
xml = "<tag attr='Some content #{v}'></tag>"
|
|
146
|
-
Crack::XML.parse(xml)['tag']['attr'].should =~ Regexp.new(k)
|
|
147
|
-
end
|
|
148
|
-
end
|
|
149
111
|
|
|
150
112
|
should "should undasherize keys as tags" do
|
|
151
113
|
xml = "<tag-1>Stuff</tag-1>"
|
|
@@ -104,23 +104,6 @@ class TestFakeWeb < Test::Unit::TestCase
|
|
|
104
104
|
end
|
|
105
105
|
end
|
|
106
106
|
|
|
107
|
-
def test_clean_registry_affects_registered_uri
|
|
108
|
-
FakeWeb.register_uri(:get, "http://example.com", :body => "registered")
|
|
109
|
-
assert FakeWeb.registered_uri?(:get, "http://example.com")
|
|
110
|
-
FakeWeb.clean_registry
|
|
111
|
-
assert !FakeWeb.registered_uri?(:get, "http://example.com")
|
|
112
|
-
end
|
|
113
|
-
|
|
114
|
-
def test_clean_registry_affects_net_http_requests
|
|
115
|
-
FakeWeb.register_uri(:get, "http://example.com", :body => "registered")
|
|
116
|
-
response = Net::HTTP.start("example.com") { |query| query.get("/") }
|
|
117
|
-
assert_equal "registered", response.body
|
|
118
|
-
FakeWeb.clean_registry
|
|
119
|
-
assert_raise FakeWeb::NetConnectNotAllowedError do
|
|
120
|
-
Net::HTTP.start("example.com") { |query| query.get("/") }
|
|
121
|
-
end
|
|
122
|
-
end
|
|
123
|
-
|
|
124
107
|
def test_response_for_with_registered_uri
|
|
125
108
|
FakeWeb.register_uri(:get, 'http://mock/test_example.txt', :body => File.dirname(__FILE__) + '/fixtures/test_example.txt')
|
|
126
109
|
assert_equal 'test example content', FakeWeb.response_for(:get, 'http://mock/test_example.txt').body
|
|
@@ -2,19 +2,13 @@ require File.join(File.dirname(__FILE__), "test_helper")
|
|
|
2
2
|
|
|
3
3
|
class TestResponseHeaders < Test::Unit::TestCase
|
|
4
4
|
|
|
5
|
-
def
|
|
5
|
+
def test_content_type_when_registering_with_string_and_content_type_header
|
|
6
6
|
FakeWeb.register_uri(:get, "http://example.com/users.json", :body => '[{"username": "chrisk"}]', :content_type => "application/json")
|
|
7
7
|
response = Net::HTTP.start("example.com") { |query| query.get("/users.json") }
|
|
8
8
|
assert_equal '[{"username": "chrisk"}]', response.body
|
|
9
9
|
assert_equal "application/json", response['Content-Type']
|
|
10
10
|
end
|
|
11
11
|
|
|
12
|
-
def test_content_type_when_registering_with_string_and_content_type_header_as_string_option
|
|
13
|
-
FakeWeb.register_uri(:get, "http://example.com/users.json", :body => '[{"username": "chrisk"}]', 'Content-Type' => "application/json")
|
|
14
|
-
response = Net::HTTP.start("example.com") { |query| query.get("/users.json") }
|
|
15
|
-
assert_equal "application/json", response['Content-Type']
|
|
16
|
-
end
|
|
17
|
-
|
|
18
12
|
def test_content_type_when_registering_with_string_only
|
|
19
13
|
FakeWeb.register_uri(:get, "http://example.com/users.json", :body => '[{"username": "chrisk"}]')
|
|
20
14
|
response = Net::HTTP.start("example.com") { |query| query.get("/users.json") }
|
|
@@ -141,7 +141,7 @@ Patches contributed by: Chris Anderson, Greg Borenstein, Ardekantur, Pedro
|
|
|
141
141
|
Belo, Rafael Souza, Rick Olson, Aman Gupta, Blake Mizerany, Brian Donovan, Ivan
|
|
142
142
|
Makfinsky, Marc-André Cournoyer, Coda Hale, Tetsuo Watanabe, Dusty Doris,
|
|
143
143
|
Lennon Day-Reynolds, James Edward Gray II, Cyril Rohr, Juan Alvarez, and Adam
|
|
144
|
-
Jacob, Paul Dlug
|
|
144
|
+
Jacob, and Paul Dlug
|
|
145
145
|
|
|
146
146
|
Released under the MIT License: http://www.opensource.org/licenses/mit-license.php
|
|
147
147
|
|
|
@@ -1,24 +1,4 @@
|
|
|
1
1
|
require 'rake'
|
|
2
|
-
|
|
3
|
-
require 'jeweler'
|
|
4
|
-
|
|
5
|
-
Jeweler::Tasks.new do |s|
|
|
6
|
-
s.name = "rest-client"
|
|
7
|
-
s.description = "A simple REST client for Ruby, inspired by the Sinatra microframework style of specifying actions: get, put, post, delete."
|
|
8
|
-
s.summary = "Simple REST client for Ruby, inspired by microframework syntax for specifying actions."
|
|
9
|
-
s.author = "Adam Wiggins"
|
|
10
|
-
s.email = "adam@heroku.com"
|
|
11
|
-
s.homepage = "http://rest-client.heroku.com/"
|
|
12
|
-
s.rubyforge_project = "rest-client"
|
|
13
|
-
s.has_rdoc = true
|
|
14
|
-
s.files = FileList["[A-Z]*", "{bin,lib,spec}/**/*"]
|
|
15
|
-
s.executables = %w(restclient)
|
|
16
|
-
end
|
|
17
|
-
|
|
18
|
-
Jeweler::RubyforgeTasks.new
|
|
19
|
-
|
|
20
|
-
############################
|
|
21
|
-
|
|
22
2
|
require 'spec/rake/spectask'
|
|
23
3
|
|
|
24
4
|
desc "Run all specs"
|
|
@@ -42,9 +22,54 @@ end
|
|
|
42
22
|
|
|
43
23
|
task :default => :spec
|
|
44
24
|
|
|
45
|
-
|
|
25
|
+
######################################################
|
|
46
26
|
|
|
27
|
+
require 'rake'
|
|
28
|
+
require 'rake/testtask'
|
|
29
|
+
require 'rake/clean'
|
|
30
|
+
require 'rake/gempackagetask'
|
|
47
31
|
require 'rake/rdoctask'
|
|
32
|
+
require 'fileutils'
|
|
33
|
+
|
|
34
|
+
version = "1.0.1"
|
|
35
|
+
name = "rest-client"
|
|
36
|
+
|
|
37
|
+
spec = Gem::Specification.new do |s|
|
|
38
|
+
s.name = name
|
|
39
|
+
s.version = version
|
|
40
|
+
s.summary = "Simple REST client for Ruby, inspired by microframework syntax for specifying actions."
|
|
41
|
+
s.description = "A simple REST client for Ruby, inspired by the Sinatra microframework style of specifying actions: get, put, post, delete."
|
|
42
|
+
s.author = "Adam Wiggins"
|
|
43
|
+
s.email = "adam@heroku.com"
|
|
44
|
+
s.homepage = "http://rest-client.heroku.com/"
|
|
45
|
+
s.rubyforge_project = "rest-client"
|
|
46
|
+
|
|
47
|
+
s.platform = Gem::Platform::RUBY
|
|
48
|
+
s.has_rdoc = true
|
|
49
|
+
|
|
50
|
+
s.files = %w(Rakefile README.rdoc) + Dir.glob("{lib,spec}/**/*")
|
|
51
|
+
s.executables = ['restclient']
|
|
52
|
+
|
|
53
|
+
s.require_path = "lib"
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
Rake::GemPackageTask.new(spec) do |p|
|
|
57
|
+
p.need_tar = true if RUBY_PLATFORM !~ /mswin/
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
task :install => [ :package ] do
|
|
61
|
+
sh %{sudo gem install pkg/#{name}-#{version}.gem}
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
task :uninstall => [ :clean ] do
|
|
65
|
+
sh %{sudo gem uninstall #{name}}
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
Rake::TestTask.new do |t|
|
|
69
|
+
t.libs << "spec"
|
|
70
|
+
t.test_files = FileList['spec/*_spec.rb']
|
|
71
|
+
t.verbose = true
|
|
72
|
+
end
|
|
48
73
|
|
|
49
74
|
Rake::RDocTask.new do |t|
|
|
50
75
|
t.rdoc_dir = 'rdoc'
|
|
@@ -56,3 +81,5 @@ Rake::RDocTask.new do |t|
|
|
|
56
81
|
t.rdoc_files.include('lib/restclient/*.rb')
|
|
57
82
|
end
|
|
58
83
|
|
|
84
|
+
CLEAN.include [ 'pkg', '*.gem', '.config' ]
|
|
85
|
+
|
|
@@ -18,10 +18,6 @@ module RestClient
|
|
|
18
18
|
def http_code
|
|
19
19
|
@response.code.to_i if @response
|
|
20
20
|
end
|
|
21
|
-
|
|
22
|
-
def http_body
|
|
23
|
-
RestClient::Request.decode(@response['content-encoding'], @response.body) if @response
|
|
24
|
-
end
|
|
25
21
|
end
|
|
26
22
|
|
|
27
23
|
# A redirect was encountered; caught by execute to retry with the new url.
|
|
@@ -39,8 +39,6 @@ module RestClient
|
|
|
39
39
|
execute_inner
|
|
40
40
|
rescue Redirect => e
|
|
41
41
|
@url = e.url
|
|
42
|
-
@method = :get
|
|
43
|
-
@payload = nil
|
|
44
42
|
execute
|
|
45
43
|
end
|
|
46
44
|
|
|
@@ -173,7 +171,7 @@ module RestClient
|
|
|
173
171
|
if res.code =~ /\A2\d{2}\z/
|
|
174
172
|
# We don't decode raw requests
|
|
175
173
|
unless @raw_response
|
|
176
|
-
|
|
174
|
+
decode res['content-encoding'], res.body if res.body
|
|
177
175
|
end
|
|
178
176
|
elsif %w(301 302 303).include? res.code
|
|
179
177
|
url = res.header['Location']
|
|
@@ -196,7 +194,7 @@ module RestClient
|
|
|
196
194
|
end
|
|
197
195
|
end
|
|
198
196
|
|
|
199
|
-
def
|
|
197
|
+
def decode(content_encoding, body)
|
|
200
198
|
if content_encoding == 'gzip' and not body.empty?
|
|
201
199
|
Zlib::GzipReader.new(StringIO.new(body)).read
|
|
202
200
|
elsif content_encoding == 'deflate'
|
|
@@ -232,7 +230,7 @@ module RestClient
|
|
|
232
230
|
end
|
|
233
231
|
|
|
234
232
|
def default_headers
|
|
235
|
-
{ :accept => '
|
|
233
|
+
{ :accept => 'application/xml', :accept_encoding => 'gzip, deflate' }
|
|
236
234
|
end
|
|
237
235
|
end
|
|
238
236
|
end
|
|
@@ -1,14 +1,8 @@
|
|
|
1
1
|
require 'uri'
|
|
2
|
+
require 'net/https'
|
|
2
3
|
require 'zlib'
|
|
3
4
|
require 'stringio'
|
|
4
5
|
|
|
5
|
-
begin
|
|
6
|
-
require 'net/https'
|
|
7
|
-
rescue LoadError => e
|
|
8
|
-
raise e unless RUBY_PLATFORM =~ /linux/
|
|
9
|
-
raise LoadError, "no such file to load -- net/https. Try running apt-get install libopenssl-ruby"
|
|
10
|
-
end
|
|
11
|
-
|
|
12
6
|
require File.dirname(__FILE__) + '/restclient/request'
|
|
13
7
|
require File.dirname(__FILE__) + '/restclient/mixin/response'
|
|
14
8
|
require File.dirname(__FILE__) + '/restclient/response'
|
|
@@ -12,10 +12,6 @@ describe RestClient::Exception do
|
|
|
12
12
|
end
|
|
13
13
|
|
|
14
14
|
describe RestClient::RequestFailed do
|
|
15
|
-
before do
|
|
16
|
-
@response = mock('HTTP Response', :code => '502')
|
|
17
|
-
end
|
|
18
|
-
|
|
19
15
|
it "stores the http response on the exception" do
|
|
20
16
|
begin
|
|
21
17
|
raise RestClient::RequestFailed, :response
|
|
@@ -25,18 +21,11 @@ describe RestClient::RequestFailed do
|
|
|
25
21
|
end
|
|
26
22
|
|
|
27
23
|
it "http_code convenience method for fetching the code as an integer" do
|
|
28
|
-
RestClient::RequestFailed.new(
|
|
29
|
-
end
|
|
30
|
-
|
|
31
|
-
it "http_body convenience method for fetching the body (decoding when necessary)" do
|
|
32
|
-
@response.stub!(:[]).with('content-encoding').and_return('gzip')
|
|
33
|
-
@response.stub!(:body).and_return('compressed body')
|
|
34
|
-
RestClient::Request.should_receive(:decode).with('gzip', 'compressed body').and_return('plain body')
|
|
35
|
-
RestClient::RequestFailed.new(@response).http_body.should == 'plain body'
|
|
24
|
+
RestClient::RequestFailed.new(mock('res', :code => '502')).http_code.should == 502
|
|
36
25
|
end
|
|
37
26
|
|
|
38
27
|
it "shows the status code in the message" do
|
|
39
|
-
RestClient::RequestFailed.new(
|
|
28
|
+
RestClient::RequestFailed.new(mock('res', :code => '502')).to_s.should match(/502/)
|
|
40
29
|
end
|
|
41
30
|
end
|
|
42
31
|
|
|
@@ -17,24 +17,24 @@ describe RestClient::Request do
|
|
|
17
17
|
@net.stub!(:verify_mode=)
|
|
18
18
|
end
|
|
19
19
|
|
|
20
|
-
it "
|
|
21
|
-
@request.default_headers[:accept].should == '
|
|
20
|
+
it "requests xml mimetype" do
|
|
21
|
+
@request.default_headers[:accept].should == 'application/xml'
|
|
22
22
|
end
|
|
23
23
|
|
|
24
24
|
it "decodes an uncompressed result body by passing it straight through" do
|
|
25
|
-
|
|
25
|
+
@request.decode(nil, 'xyz').should == 'xyz'
|
|
26
26
|
end
|
|
27
27
|
|
|
28
28
|
it "decodes a gzip body" do
|
|
29
|
-
|
|
29
|
+
@request.decode('gzip', "\037\213\b\b\006'\252H\000\003t\000\313T\317UH\257\312,HM\341\002\000G\242(\r\v\000\000\000").should == "i'm gziped\n"
|
|
30
30
|
end
|
|
31
31
|
|
|
32
32
|
it "ingores gzip for empty bodies" do
|
|
33
|
-
|
|
33
|
+
@request.decode('gzip', '').should be_empty
|
|
34
34
|
end
|
|
35
35
|
|
|
36
36
|
it "decodes a deflated body" do
|
|
37
|
-
|
|
37
|
+
@request.decode('deflate', "x\234+\316\317MUHIM\313I,IMQ(I\255(\001\000A\223\006\363").should == "some deflated text"
|
|
38
38
|
end
|
|
39
39
|
|
|
40
40
|
it "processes a successful result" do
|
|
@@ -222,20 +222,6 @@ describe RestClient::Request do
|
|
|
222
222
|
lambda { @request.process_result(res) }.should raise_error(RestClient::Redirect) { |e| e.url.should == 'http://some/index' }
|
|
223
223
|
end
|
|
224
224
|
|
|
225
|
-
it "uses GET and clears payload when following 30x redirects" do
|
|
226
|
-
url = "http://example.com/redirected"
|
|
227
|
-
|
|
228
|
-
@request.should_receive(:execute_inner).once.ordered.and_raise(RestClient::Redirect.new(url))
|
|
229
|
-
|
|
230
|
-
@request.should_receive(:execute_inner).once.ordered do
|
|
231
|
-
@request.url.should == url
|
|
232
|
-
@request.method.should == :get
|
|
233
|
-
@request.payload.should be_nil
|
|
234
|
-
end
|
|
235
|
-
|
|
236
|
-
@request.execute
|
|
237
|
-
end
|
|
238
|
-
|
|
239
225
|
it "raises Unauthorized when the response is 401" do
|
|
240
226
|
res = mock('response', :code => '401')
|
|
241
227
|
lambda { @request.process_result(res) }.should raise_error(RestClient::Unauthorized)
|
|
@@ -2,7 +2,7 @@ require 'cgi'
|
|
|
2
2
|
require 'time'
|
|
3
3
|
|
|
4
4
|
class SimpleRSS
|
|
5
|
-
VERSION = "1.2
|
|
5
|
+
VERSION = "1.2"
|
|
6
6
|
|
|
7
7
|
attr_reader :items, :source
|
|
8
8
|
alias :entries :items
|
|
@@ -33,11 +33,10 @@ class SimpleRSS
|
|
|
33
33
|
:'feedburner:origLink'
|
|
34
34
|
]
|
|
35
35
|
|
|
36
|
-
def initialize(source
|
|
36
|
+
def initialize(source)
|
|
37
37
|
@source = source.respond_to?(:read) ? source.read : source.to_s
|
|
38
38
|
@items = Array.new
|
|
39
|
-
|
|
40
|
-
|
|
39
|
+
|
|
41
40
|
parse
|
|
42
41
|
end
|
|
43
42
|
|
|
@@ -60,8 +59,8 @@ class SimpleRSS
|
|
|
60
59
|
end
|
|
61
60
|
|
|
62
61
|
# The strict attribute is for compatibility with Ruby's standard RSS parser
|
|
63
|
-
def parse(source,
|
|
64
|
-
new source
|
|
62
|
+
def parse(source, do_validate=true, ignore_unknown_element=true, parser_class=false)
|
|
63
|
+
new source
|
|
65
64
|
end
|
|
66
65
|
end
|
|
67
66
|
|
|
@@ -86,8 +85,8 @@ class SimpleRSS
|
|
|
86
85
|
|
|
87
86
|
if $2 || $3
|
|
88
87
|
tag_cleaned = clean_tag(tag)
|
|
89
|
-
|
|
90
|
-
self.class.
|
|
88
|
+
eval %{ @#{ tag_cleaned } = clean_content(tag, $2, $3) }
|
|
89
|
+
self.class.class_eval %{ attr_reader :#{ tag_cleaned } }
|
|
91
90
|
end
|
|
92
91
|
end
|
|
93
92
|
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
require File.dirname(__FILE__) + '/../test_helper'
|
|
2
2
|
class BaseTest < Test::Unit::TestCase
|
|
3
3
|
def setup
|
|
4
|
-
@rss09 = SimpleRSS.parse open(File.dirname(__FILE__) + '/../data/rss09.rdf')
|
|
5
|
-
@rss20 = SimpleRSS.parse open(File.dirname(__FILE__) + '/../data/rss20.xml')
|
|
4
|
+
@rss09 = SimpleRSS.parse open(File.dirname(__FILE__) + '/../data/rss09.rdf'), true
|
|
5
|
+
@rss20 = SimpleRSS.parse open(File.dirname(__FILE__) + '/../data/rss20.xml'), false
|
|
6
6
|
@atom = SimpleRSS.parse open(File.dirname(__FILE__) + '/../data/atom.xml')
|
|
7
7
|
end
|
|
8
8
|
|