relax 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/LICENSE +20 -0
- data/README +4 -0
- data/lib/relax/api.rb +49 -0
- data/lib/relax/query.rb +39 -0
- data/lib/relax/request.rb +49 -0
- data/lib/relax/response.rb +110 -0
- data/lib/relax/symbolic_hash.rb +65 -0
- data/lib/relax.rb +7 -0
- data/spec/query_spec.rb +45 -0
- data/spec/request_spec.rb +86 -0
- data/spec/response_spec.rb +82 -0
- data/spec/symbolic_hash_spec.rb +67 -0
- metadata +66 -0
data/LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2007 Tyler Hunt
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README
ADDED
data/lib/relax/api.rb
ADDED
@@ -0,0 +1,49 @@
|
|
1
|
+
require 'openssl'
|
2
|
+
require 'net/https'
|
3
|
+
require 'uri'
|
4
|
+
require 'date'
|
5
|
+
require 'base64'
|
6
|
+
require 'erb'
|
7
|
+
|
8
|
+
module Relax
|
9
|
+
class API
|
10
|
+
attr_reader :endpoint
|
11
|
+
|
12
|
+
def initialize(endpoint)
|
13
|
+
@endpoint = URI::parse(endpoint)
|
14
|
+
end
|
15
|
+
|
16
|
+
private
|
17
|
+
|
18
|
+
def default_query
|
19
|
+
Query.new
|
20
|
+
end
|
21
|
+
|
22
|
+
def query(request)
|
23
|
+
Query.new(default_query.merge(request.to_query))
|
24
|
+
end
|
25
|
+
|
26
|
+
def call(request, response_class)
|
27
|
+
uri = @endpoint.clone
|
28
|
+
uri.query = query(request).to_s
|
29
|
+
response = request(uri)
|
30
|
+
puts "Response:\n#{response.body}\n\n" if $DEBUG
|
31
|
+
response_class.new(response.body)
|
32
|
+
end
|
33
|
+
|
34
|
+
def request(uri)
|
35
|
+
puts "Request:\n#{uri.to_s}\n\n" if $DEBUG
|
36
|
+
http = Net::HTTP.new(uri.host, uri.port)
|
37
|
+
|
38
|
+
if uri.scheme == 'https'
|
39
|
+
http.use_ssl = true
|
40
|
+
http.verify_mode = OpenSSL::SSL::VERIFY_NONE
|
41
|
+
end
|
42
|
+
|
43
|
+
http.start do |http|
|
44
|
+
request = Net::HTTP::Get.new("#{uri.path}?#{uri.query}")
|
45
|
+
http.request(request)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
data/lib/relax/query.rb
ADDED
@@ -0,0 +1,39 @@
|
|
1
|
+
require 'erb'
|
2
|
+
require 'uri'
|
3
|
+
|
4
|
+
require 'relax/symbolic_hash'
|
5
|
+
|
6
|
+
module Relax
|
7
|
+
class Query < SymbolicHash
|
8
|
+
def to_s
|
9
|
+
keys.sort { |a, b| a.to_s <=> b.to_s }.collect do |key|
|
10
|
+
"#{key.to_s}=#{self.class.escape_value(fetch(key))}"
|
11
|
+
end.join('&')
|
12
|
+
end
|
13
|
+
|
14
|
+
class << self
|
15
|
+
def parse(uri)
|
16
|
+
query = uri.query.split('&').inject({}) do |query, parameter|
|
17
|
+
key, value = parameter.split('=')
|
18
|
+
query[key] = unescape_value(value)
|
19
|
+
query
|
20
|
+
end
|
21
|
+
self.new(query)
|
22
|
+
end
|
23
|
+
|
24
|
+
def escape_value(value)
|
25
|
+
ERB::Util.url_encode(value.to_s).gsub('%20', '+')
|
26
|
+
end
|
27
|
+
|
28
|
+
def unescape_value(value)
|
29
|
+
URI.unescape(value)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
protected
|
34
|
+
|
35
|
+
def convert_value(value)
|
36
|
+
value.to_s
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
require 'relax/query'
|
2
|
+
|
3
|
+
module Relax
|
4
|
+
class Request
|
5
|
+
def initialize(options = {})
|
6
|
+
self.class.class_variables.each do |variable|
|
7
|
+
instance_variable_set(variable.slice(1..-1), self.class.send(:class_variable_get, variable))
|
8
|
+
end
|
9
|
+
|
10
|
+
options.each do |key, value|
|
11
|
+
instance_variable_set "@#{key}", value
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
def to_query
|
16
|
+
keys.inject(Query.new) do |parameters, key|
|
17
|
+
parameters[convert_key(key)] = send(key)
|
18
|
+
parameters
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
def to_s
|
23
|
+
keys.sort { |a, b| a.to_s <=> b.to_s }.collect do |key|
|
24
|
+
"#{key.to_s}=#{ERB::Util.url_encode(send('[]', key).to_s)}"
|
25
|
+
end.join('&')
|
26
|
+
end
|
27
|
+
|
28
|
+
class << self
|
29
|
+
def parameter(name, options = {})
|
30
|
+
attr_accessor name
|
31
|
+
class_variable_set("@@#{name}", options.delete(:value)) if options[:value]
|
32
|
+
end
|
33
|
+
|
34
|
+
def []=(key, value)
|
35
|
+
parameter(key, {:value => value})
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
protected
|
40
|
+
|
41
|
+
def keys
|
42
|
+
instance_variables.collect { |v| v.sub('@', '') }
|
43
|
+
end
|
44
|
+
|
45
|
+
def convert_key(key)
|
46
|
+
key
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
@@ -0,0 +1,110 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'hpricot'
|
3
|
+
|
4
|
+
require 'date'
|
5
|
+
|
6
|
+
module Relax
|
7
|
+
class Response
|
8
|
+
attr_accessor :xml
|
9
|
+
|
10
|
+
def initialize(xml)
|
11
|
+
@xml = Hpricot.XML(xml.to_s)
|
12
|
+
|
13
|
+
if parameter = self.class.instance_variable_get('@parameters')
|
14
|
+
parameter.each do |parameter, options|
|
15
|
+
element = options[:element] ? options[:element] : parameter
|
16
|
+
|
17
|
+
if attribute = options[:attribute] and attribute == true
|
18
|
+
node = attribute(root, element)
|
19
|
+
elsif attribute
|
20
|
+
node = attribute(element(element), attribute)
|
21
|
+
elsif options[:collection]
|
22
|
+
node = elements(element)
|
23
|
+
else
|
24
|
+
node = element(element)
|
25
|
+
end
|
26
|
+
|
27
|
+
if options[:collection]
|
28
|
+
value = node.collect do |element|
|
29
|
+
options[:collection].new(element)
|
30
|
+
end
|
31
|
+
else
|
32
|
+
case options[:type]
|
33
|
+
when :float
|
34
|
+
value = float_value(node)
|
35
|
+
|
36
|
+
when :integer
|
37
|
+
value = integer_value(node)
|
38
|
+
|
39
|
+
when :text
|
40
|
+
else
|
41
|
+
value = text_value(node)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
instance_variable_set("@#{parameter}", value)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
def root
|
51
|
+
@xml.root
|
52
|
+
end
|
53
|
+
|
54
|
+
def is?(name)
|
55
|
+
root.name.gsub(/.*:(.*)/, '\1') == node_name(name)
|
56
|
+
end
|
57
|
+
|
58
|
+
def element(name)
|
59
|
+
root.at(root_path(name))
|
60
|
+
end
|
61
|
+
|
62
|
+
def attribute(element, name)
|
63
|
+
element[name]
|
64
|
+
end
|
65
|
+
|
66
|
+
def elements(name)
|
67
|
+
root.search(root_path(name))
|
68
|
+
end
|
69
|
+
|
70
|
+
def value(value)
|
71
|
+
value.is_a?(Hpricot::Elem) ? value.inner_text : value.to_s
|
72
|
+
end
|
73
|
+
|
74
|
+
def text_value(value)
|
75
|
+
value(value)
|
76
|
+
end
|
77
|
+
|
78
|
+
def integer_value(value)
|
79
|
+
value(value).to_i
|
80
|
+
end
|
81
|
+
|
82
|
+
def float_value(value)
|
83
|
+
value(value).to_f
|
84
|
+
end
|
85
|
+
|
86
|
+
def date_value(value)
|
87
|
+
Date.parse(value(value))
|
88
|
+
end
|
89
|
+
|
90
|
+
alias :has? :element
|
91
|
+
|
92
|
+
class << self
|
93
|
+
def parameter(name, options = {})
|
94
|
+
attr_accessor name
|
95
|
+
@parameters ||= {}
|
96
|
+
@parameters[name] = options
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
private
|
101
|
+
|
102
|
+
def node_name(name)
|
103
|
+
name.to_s.downcase
|
104
|
+
end
|
105
|
+
|
106
|
+
def root_path(name)
|
107
|
+
"/#{node_name(name)}"
|
108
|
+
end
|
109
|
+
end
|
110
|
+
end
|
@@ -0,0 +1,65 @@
|
|
1
|
+
module Relax
|
2
|
+
class SymbolicHash < Hash
|
3
|
+
def initialize(constructor = {})
|
4
|
+
if constructor.is_a?(Hash)
|
5
|
+
super()
|
6
|
+
update(constructor)
|
7
|
+
else
|
8
|
+
super(constructor)
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
def [](key)
|
13
|
+
super(convert_key(key))
|
14
|
+
end
|
15
|
+
|
16
|
+
def []=(key, value)
|
17
|
+
super(convert_key(key), convert_value(value))
|
18
|
+
end
|
19
|
+
|
20
|
+
def update(other_hash)
|
21
|
+
other_hash.each_pair { |key, value| store(convert_key(key), convert_value(value)) }
|
22
|
+
self
|
23
|
+
end
|
24
|
+
|
25
|
+
alias_method :merge!, :update
|
26
|
+
|
27
|
+
def fetch(key, *extras)
|
28
|
+
super(convert_key(key), *extras)
|
29
|
+
end
|
30
|
+
|
31
|
+
def values_at(*indices)
|
32
|
+
indices.collect { |key| self[convert_key(key)] }
|
33
|
+
end
|
34
|
+
|
35
|
+
def dup
|
36
|
+
SymbolicHash.new(self)
|
37
|
+
end
|
38
|
+
|
39
|
+
def merge(hash)
|
40
|
+
self.dup.update(hash)
|
41
|
+
end
|
42
|
+
|
43
|
+
def delete(key)
|
44
|
+
super(convert_key(key))
|
45
|
+
end
|
46
|
+
|
47
|
+
def key?(key)
|
48
|
+
super(convert_key(key))
|
49
|
+
end
|
50
|
+
|
51
|
+
alias_method :include?, :key?
|
52
|
+
alias_method :has_key?, :key?
|
53
|
+
alias_method :member?, :key?
|
54
|
+
|
55
|
+
protected
|
56
|
+
|
57
|
+
def convert_key(key)
|
58
|
+
!key.kind_of?(Symbol) ? key.to_sym : key
|
59
|
+
end
|
60
|
+
|
61
|
+
def convert_value(value)
|
62
|
+
value
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
data/lib/relax.rb
ADDED
data/spec/query_spec.rb
ADDED
@@ -0,0 +1,45 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/spec_helper'
|
2
|
+
|
3
|
+
require 'relax/query'
|
4
|
+
|
5
|
+
describe 'a query' do
|
6
|
+
before(:each) do
|
7
|
+
@uri = URI::parse('http://example.com/?action=search&query=keyword')
|
8
|
+
@query = Relax::Query.new
|
9
|
+
end
|
10
|
+
|
11
|
+
it 'should convert to a query string' do
|
12
|
+
@query[:action] = 'Search'
|
13
|
+
@query[:query] = 'strings'
|
14
|
+
@query.to_s.should == 'action=Search&query=strings'
|
15
|
+
end
|
16
|
+
|
17
|
+
it 'should convert its values to strings' do
|
18
|
+
date = Date.today
|
19
|
+
@query[:date] = date
|
20
|
+
@query.to_s.should == "date=#{date.to_s}"
|
21
|
+
end
|
22
|
+
|
23
|
+
it 'should escape its values using "+" instead of "%20"' do
|
24
|
+
Relax::Query.send(:escape_value, 'two words').should == 'two+words'
|
25
|
+
end
|
26
|
+
|
27
|
+
it 'should sort its parameters' do
|
28
|
+
@query[:charlie] = 3
|
29
|
+
@query[:alpha] = 1
|
30
|
+
@query[:bravo] = 2
|
31
|
+
@query.to_s.should == 'alpha=1&bravo=2&charlie=3'
|
32
|
+
end
|
33
|
+
|
34
|
+
it 'should encode its parameter values' do
|
35
|
+
@query[:spaces] = 'two words'
|
36
|
+
@query[:url] = 'http://example.com/'
|
37
|
+
@query.to_s.should == 'spaces=two+words&url=http%3A%2F%2Fexample.com%2F'
|
38
|
+
end
|
39
|
+
|
40
|
+
it 'should be able to parse query strings' do
|
41
|
+
parsed_query = Relax::Query.parse(@uri)
|
42
|
+
parsed_query[:action].should == 'search'
|
43
|
+
parsed_query[:query].should == 'keyword'
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,86 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/spec_helper'
|
2
|
+
|
3
|
+
require 'relax/request'
|
4
|
+
|
5
|
+
class TestRequest < Relax::Request
|
6
|
+
parameter :action
|
7
|
+
parameter :token_id
|
8
|
+
parameter :user_id
|
9
|
+
end
|
10
|
+
|
11
|
+
class ChildRequest < TestRequest
|
12
|
+
parameter :child_id
|
13
|
+
end
|
14
|
+
|
15
|
+
describe 'an option initialized request', :shared => true do
|
16
|
+
it 'should have its values set by the options hash' do
|
17
|
+
request = TestRequest.new(:action => 'FetchAll', :token_id => 123)
|
18
|
+
request.action.should eql('FetchAll')
|
19
|
+
request.token_id.should eql(123)
|
20
|
+
request.user_id.should be_nil
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
describe 'a request that converts to a query', :shared => true do
|
25
|
+
before(:each) do
|
26
|
+
@query = TestRequest.new(:action => 'Search', :token_id => 123).to_query
|
27
|
+
end
|
28
|
+
|
29
|
+
it 'should include its parameters in the query' do
|
30
|
+
@query[:action].should eql('Search')
|
31
|
+
@query[:token_id].should eql('123')
|
32
|
+
@query[:user_id].should be_nil
|
33
|
+
end
|
34
|
+
|
35
|
+
it 'should only include parameters in the query if they are set' do
|
36
|
+
@query.key?(:action).should be_true
|
37
|
+
@query.key?(:token_id).should be_true
|
38
|
+
@query.key?(:user_id).should be_false
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
describe 'a normal request' do
|
43
|
+
it_should_behave_like 'a request that converts to a query'
|
44
|
+
it_should_behave_like 'an option initialized request'
|
45
|
+
end
|
46
|
+
|
47
|
+
describe 'a template request' do
|
48
|
+
it_should_behave_like 'a request that converts to a query'
|
49
|
+
it_should_behave_like 'an option initialized request'
|
50
|
+
|
51
|
+
before(:each) do
|
52
|
+
TestRequest[:api_key] = '123456'
|
53
|
+
TestRequest[:secret] = 'shhh!'
|
54
|
+
end
|
55
|
+
|
56
|
+
it 'should always have the template values in its query' do
|
57
|
+
request = TestRequest.new
|
58
|
+
request.api_key.should eql('123456')
|
59
|
+
request.secret.should eql('shhh!')
|
60
|
+
end
|
61
|
+
|
62
|
+
it 'should allow its template variables to be overridden' do
|
63
|
+
request = TestRequest.new(:secret => 'abracadabra')
|
64
|
+
request.api_key.should eql('123456')
|
65
|
+
request.secret.should eql('abracadabra')
|
66
|
+
end
|
67
|
+
|
68
|
+
it 'should pass its template on to its children' do
|
69
|
+
request = ChildRequest.new
|
70
|
+
request.api_key.should eql('123456')
|
71
|
+
request.secret.should eql('shhh!')
|
72
|
+
end
|
73
|
+
|
74
|
+
it 'should allow template parameters on its children that are additive' do
|
75
|
+
ChildRequest[:query] = '1a2b3c'
|
76
|
+
child = ChildRequest.new
|
77
|
+
child.api_key.should eql('123456')
|
78
|
+
child.secret.should eql('shhh!')
|
79
|
+
child.query.should eql('1a2b3c')
|
80
|
+
|
81
|
+
parent = TestRequest.new
|
82
|
+
parent.api_key.should eql('123456')
|
83
|
+
parent.secret.should eql('shhh!')
|
84
|
+
parent.respond_to?(:query).should be_false
|
85
|
+
end
|
86
|
+
end
|
@@ -0,0 +1,82 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/spec_helper'
|
2
|
+
|
3
|
+
require 'relax/response'
|
4
|
+
|
5
|
+
XML = <<EOF
|
6
|
+
<?xml version="1.0"?>
|
7
|
+
<RESTResponse>
|
8
|
+
<Tokens>
|
9
|
+
<TokenId>JPMQARDVJK</TokenId>
|
10
|
+
<Status>Active</Status>
|
11
|
+
</Tokens>
|
12
|
+
<Tokens>
|
13
|
+
<TokenId>RDVJKJPMQA</TokenId>
|
14
|
+
<Status>Inactive</Status>
|
15
|
+
</Tokens>
|
16
|
+
<Status>Success</Status>
|
17
|
+
<RequestId valid="true">44287</RequestId>
|
18
|
+
</RESTResponse>
|
19
|
+
EOF
|
20
|
+
|
21
|
+
class TestResponse < Relax::Response
|
22
|
+
class Token < Relax::Response
|
23
|
+
parameter :token_id, :element => :tokenid
|
24
|
+
parameter :status
|
25
|
+
end
|
26
|
+
|
27
|
+
parameter :status
|
28
|
+
parameter :request_id, :element => :requestid, :type => :integer
|
29
|
+
parameter :valid_request, :element => :requestid, :attribute => :valid
|
30
|
+
parameter :tokens, :collection => Token
|
31
|
+
end
|
32
|
+
|
33
|
+
describe 'a response' do
|
34
|
+
before(:each) do
|
35
|
+
@response = Relax::Response.new(XML)
|
36
|
+
end
|
37
|
+
|
38
|
+
it 'should allow access to the root' do
|
39
|
+
root = @response.root
|
40
|
+
root.should be_an_instance_of(Hpricot::Elem)
|
41
|
+
root.name.should eql('restresponse')
|
42
|
+
end
|
43
|
+
|
44
|
+
it 'should be checkable by the name of its root' do
|
45
|
+
@response.is?(:RESTResponse).should be_true
|
46
|
+
end
|
47
|
+
|
48
|
+
it 'should allow access to an element by its name' do
|
49
|
+
@response.element(:RequestId).should be_an_instance_of(Hpricot::Elem)
|
50
|
+
end
|
51
|
+
|
52
|
+
it 'should allow access to an element\'s elements by its name' do
|
53
|
+
tokens = @response.elements(:Tokens)
|
54
|
+
tokens.should be_an_instance_of(Hpricot::Elements)
|
55
|
+
tokens.should_not be_empty
|
56
|
+
end
|
57
|
+
|
58
|
+
it 'should allow access to an element\'s value by its name' do
|
59
|
+
token = Relax::Response.new(@response.elements(:Tokens).first)
|
60
|
+
token.element(:TokenId).inner_text.should eql('JPMQARDVJK')
|
61
|
+
token.element(:Status).inner_text.should eql('Active')
|
62
|
+
end
|
63
|
+
|
64
|
+
it 'should have a means of checking for the existence of a node' do
|
65
|
+
@response.has?(:Status).should_not be_nil
|
66
|
+
@response.has?(:Errors).should be_nil
|
67
|
+
end
|
68
|
+
|
69
|
+
it 'should be able to define children of Request without modifying parent' do
|
70
|
+
Relax::Response.new(XML).respond_to?(:status).should be_false
|
71
|
+
TestResponse.new(XML).respond_to?(:status).should be_true
|
72
|
+
end
|
73
|
+
|
74
|
+
it 'should automatically pull parameters from the XML' do
|
75
|
+
response = TestResponse.new(XML)
|
76
|
+
response.status.should eql('Success')
|
77
|
+
response.request_id.should eql(44287)
|
78
|
+
response.valid_request.should eql('true')
|
79
|
+
response.tokens.length.should eql(2)
|
80
|
+
response.tokens.first.status.should eql('Active')
|
81
|
+
end
|
82
|
+
end
|
@@ -0,0 +1,67 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/spec_helper'
|
2
|
+
|
3
|
+
require 'relax/symbolic_hash'
|
4
|
+
|
5
|
+
describe 'a symbolic hash' do
|
6
|
+
before(:each) do
|
7
|
+
@url = 'http://example.com/'
|
8
|
+
@query = Relax::SymbolicHash.new
|
9
|
+
end
|
10
|
+
|
11
|
+
it 'should be accessible via string or symbol keys' do
|
12
|
+
@query[:amount] = 10
|
13
|
+
@query[:amount].should == 10
|
14
|
+
@query['amount'].should == 10
|
15
|
+
end
|
16
|
+
|
17
|
+
it 'should convert keys to symbols' do
|
18
|
+
@query['symbol'] = 'aleph'
|
19
|
+
@query[:symbol].should == 'aleph'
|
20
|
+
end
|
21
|
+
|
22
|
+
it 'should convert keys to symbols' do
|
23
|
+
@query['symbol'] = 'aleph'
|
24
|
+
@query[:symbol].should == 'aleph'
|
25
|
+
end
|
26
|
+
|
27
|
+
it 'should test for keys by symbol' do
|
28
|
+
@query[:symbol] = 'aleph'
|
29
|
+
@query.key?('symbol').should be_true
|
30
|
+
end
|
31
|
+
|
32
|
+
it 'should delete values with a symbolic key' do
|
33
|
+
@query[:symbol] = 'aleph'
|
34
|
+
@query.delete('symbol')
|
35
|
+
@query.key?(:symbol).should be_false
|
36
|
+
end
|
37
|
+
|
38
|
+
it 'should be mergeable' do
|
39
|
+
@query[:one] = 2
|
40
|
+
merged_query = @query.merge({ :one => 1, :two => 2 })
|
41
|
+
merged_query[:one].should == 1
|
42
|
+
merged_query[:two].should == 2
|
43
|
+
end
|
44
|
+
|
45
|
+
it 'should be able to duplicate itself' do
|
46
|
+
@query[:one] = 'uno'
|
47
|
+
@query[:two] = 'dos'
|
48
|
+
new_query = @query.dup
|
49
|
+
new_query[:one].should == 'uno'
|
50
|
+
new_query[:two].should == 'dos'
|
51
|
+
|
52
|
+
@query[:three] == 'tres'
|
53
|
+
new_query.key?(:three).should be_false
|
54
|
+
end
|
55
|
+
|
56
|
+
it 'should be able to get multiple values by symbol' do
|
57
|
+
@query[:one] = 1
|
58
|
+
@query[:two] = 2
|
59
|
+
@query.values_at(:one, :two).should == [1, 2]
|
60
|
+
end
|
61
|
+
|
62
|
+
it 'should be instantiable with a hash' do
|
63
|
+
query = Relax::SymbolicHash.new({ :one => 1, :two => 2 })
|
64
|
+
query[:one].should == 1
|
65
|
+
query[:two].should == 2
|
66
|
+
end
|
67
|
+
end
|
metadata
ADDED
@@ -0,0 +1,66 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
rubygems_version: 0.9.2
|
3
|
+
specification_version: 1
|
4
|
+
name: relax
|
5
|
+
version: !ruby/object:Gem::Version
|
6
|
+
version: 0.0.1
|
7
|
+
date: 2007-09-24 00:00:00 -04:00
|
8
|
+
summary: A simple library for creating REST consumers.
|
9
|
+
require_paths:
|
10
|
+
- lib
|
11
|
+
email: tyler@protoh.com
|
12
|
+
homepage: http://protoh.com/
|
13
|
+
rubyforge_project:
|
14
|
+
description:
|
15
|
+
autorequire: relax
|
16
|
+
default_executable:
|
17
|
+
bindir: bin
|
18
|
+
has_rdoc: true
|
19
|
+
required_ruby_version: !ruby/object:Gem::Version::Requirement
|
20
|
+
requirements:
|
21
|
+
- - ">"
|
22
|
+
- !ruby/object:Gem::Version
|
23
|
+
version: 0.0.0
|
24
|
+
version:
|
25
|
+
platform: ruby
|
26
|
+
signing_key:
|
27
|
+
cert_chain:
|
28
|
+
post_install_message:
|
29
|
+
authors:
|
30
|
+
- Tyler Hunt
|
31
|
+
files:
|
32
|
+
- lib/relax.rb
|
33
|
+
- lib/relax
|
34
|
+
- lib/relax/response.rb
|
35
|
+
- lib/relax/api.rb
|
36
|
+
- lib/relax/request.rb
|
37
|
+
- lib/relax/query.rb
|
38
|
+
- lib/relax/symbolic_hash.rb
|
39
|
+
- README
|
40
|
+
- LICENSE
|
41
|
+
test_files:
|
42
|
+
- spec/request_spec.rb
|
43
|
+
- spec/symbolic_hash_spec.rb
|
44
|
+
- spec/query_spec.rb
|
45
|
+
- spec/response_spec.rb
|
46
|
+
rdoc_options: []
|
47
|
+
|
48
|
+
extra_rdoc_files:
|
49
|
+
- README
|
50
|
+
- LICENSE
|
51
|
+
executables: []
|
52
|
+
|
53
|
+
extensions: []
|
54
|
+
|
55
|
+
requirements: []
|
56
|
+
|
57
|
+
dependencies:
|
58
|
+
- !ruby/object:Gem::Dependency
|
59
|
+
name: hpricot
|
60
|
+
version_requirement:
|
61
|
+
version_requirements: !ruby/object:Gem::Version::Requirement
|
62
|
+
requirements:
|
63
|
+
- - ">="
|
64
|
+
- !ruby/object:Gem::Version
|
65
|
+
version: "0.5"
|
66
|
+
version:
|