tylerhunt-relax 0.0.5 → 0.1.1

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.
@@ -1,79 +0,0 @@
1
- module Relax
2
- # SymbolicHash provides an extension of Hash, but one that only supports keys
3
- # that are symbols. This has been done in an effort to prevent the case where
4
- # both a string key and a symbol key are set on the same hash, and espcially
5
- # for dealing with this particular case when convert the hash to a string.
6
- #
7
- # === Example
8
- #
9
- # hash = Relax::SymbolicHash.new
10
- # hash[:one] = 1
11
- # hash['one'] = 2
12
- # puts hash[:one] # => 2
13
- #
14
- # === Credits
15
- #
16
- # Some of the inspiration (and code) for this class comes from the
17
- # HashWithIndifferentAccess that ships with Rails.
18
- class SymbolicHash < Hash
19
- def initialize(constructor = {})
20
- if constructor.is_a?(Hash)
21
- super()
22
- update(constructor)
23
- else
24
- super(constructor)
25
- end
26
- end
27
-
28
- def [](key)
29
- super(convert_key(key))
30
- end
31
-
32
- def []=(key, value)
33
- super(convert_key(key), convert_value(value))
34
- end
35
-
36
- def update(other_hash)
37
- other_hash.each_pair { |key, value| store(convert_key(key), convert_value(value)) }
38
- self
39
- end
40
- alias :merge! :update
41
-
42
- def fetch(key, *extras)
43
- super(convert_key(key), *extras)
44
- end
45
-
46
- def values_at(*indices)
47
- indices.collect { |key| self[convert_key(key)] }
48
- end
49
-
50
- def dup
51
- SymbolicHash.new(self)
52
- end
53
-
54
- def merge(hash)
55
- self.dup.update(hash)
56
- end
57
-
58
- def delete(key)
59
- super(convert_key(key))
60
- end
61
-
62
- def key?(key)
63
- super(convert_key(key))
64
- end
65
- alias :include? :key?
66
- alias :has_key? :key?
67
- alias :member? :key?
68
-
69
- protected
70
-
71
- def convert_key(key)
72
- !key.kind_of?(Symbol) ? key.to_sym : key
73
- end
74
-
75
- def convert_value(value)
76
- value
77
- end
78
- end
79
- end
@@ -1,29 +0,0 @@
1
- require File.dirname(__FILE__) + '/../spec_helper'
2
-
3
- require 'relax'
4
- require 'relax/parsers/factory'
5
-
6
- class TestParser ; end
7
-
8
- describe 'a parser factory' do
9
-
10
- before(:each) do
11
- @factory = Relax::Parsers::Factory
12
- Relax::Parsers::Factory.register(:test, TestParser)
13
- end
14
-
15
- it 'should raise UnrecognizedParser for un-registered names' do
16
- lambda {
17
- @factory.get(:bad_name)
18
- }.should raise_error(Relax::UnrecognizedParser)
19
- end
20
-
21
- it 'should return a registered parser class' do
22
- @factory.get(:test).should ==TestParser
23
- end
24
-
25
- it 'should register the first registered parser as the default' do
26
- @factory.get(:default).should ==Relax::Parsers::Hpricot
27
- end
28
-
29
- end
@@ -1,35 +0,0 @@
1
- require File.dirname(__FILE__) + '/../spec_helper'
2
- require File.dirname(__FILE__) + '/../parser_helper'
3
-
4
-
5
- class HpricotTestResponse < Relax::Response
6
- class Token < Relax::Response
7
- parser :hpricot
8
- parameter :token_id, :element => :tokenid
9
- parameter :status
10
- end
11
-
12
- class Error < Relax::Response
13
- parser :hpricot
14
- parameter :code, :type => :integer
15
- parameter :message
16
- end
17
-
18
- parser :hpricot
19
- parameter :status, :required => true
20
- parameter :request_id, :element => :requestid, :type => :integer
21
- parameter :valid_request, :element => :requestid, :attribute => :valid
22
- parameter :tokens, :collection => Token
23
- parameter :error, :type => Error
24
- end
25
-
26
-
27
- describe 'an Hpricot parser' do
28
-
29
- before(:each) do
30
- @response = HpricotTestResponse.new(XML)
31
- end
32
-
33
- it_should_behave_like 'a successfully parsed response'
34
-
35
- end
@@ -1,40 +0,0 @@
1
- require File.dirname(__FILE__) + '/../spec_helper'
2
- require File.dirname(__FILE__) + '/../parser_helper'
3
-
4
-
5
- class RexmlTestResponse < Relax::Response
6
- class Token < Relax::Response
7
- parser :rexml
8
- parameter :token_id, :element => 'TokenId'
9
- parameter :status, :element => 'Status'
10
- end
11
-
12
- class Error < Relax::Response
13
- parser :rexml
14
- parameter :code, :element => 'Code', :type => :integer
15
- parameter :message, :element => 'Message'
16
- end
17
-
18
- parser :rexml
19
- parameter :status, :element => 'Status', :required => true
20
- parameter :request_id, :element => 'RequestId', :type => :integer
21
- parameter :valid_request, :element => 'RequestId', :attribute => :valid
22
- parameter :namespace, :element => 'Namespace', :namespace => 'ns1'
23
- parameter :tokens, :element => 'Tokens', :collection => Token
24
- parameter :error, :element => 'Error', :type => Error
25
- end
26
-
27
-
28
- describe 'a REXML parser' do
29
-
30
- before(:each) do
31
- @response = RexmlTestResponse.new(XML)
32
- end
33
-
34
- it_should_behave_like 'a successfully parsed response'
35
-
36
- it 'should parse namespaced parameters' do
37
- @response.namespace.should eql('Passed')
38
- end
39
-
40
- end
data/spec/query_spec.rb DELETED
@@ -1,60 +0,0 @@
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 eql('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 eql("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 eql('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 eql('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 eql('search')
43
- parsed_query[:query].should eql('keyword')
44
- end
45
-
46
- it 'should parse key value pairs into only two parts' do
47
- parsed_query = Relax::Query.parse(URI.parse("http://example.com/?action=test=&foo=bar"))
48
- parsed_query[:action].should eql('test=')
49
- end
50
-
51
- it 'should unescape query string key-value pair keys' do
52
- parsed_query = Relax::Query.parse(URI.parse("http://example.com/?action%20helper=test"))
53
- parsed_query[:"action helper"].should eql('test')
54
- end
55
-
56
- it 'should unescape query string key-value pair values' do
57
- parsed_query = Relax::Query.parse(URI.parse("http://example.com/?action=test%20action"))
58
- parsed_query[:action].should eql('test action')
59
- end
60
- end
data/spec/request_spec.rb DELETED
@@ -1,108 +0,0 @@
1
- require File.dirname(__FILE__) + '/spec_helper'
2
-
3
- require 'relax/request'
4
-
5
- class Amount < Relax::Request
6
- parameter :amount
7
- parameter :currency
8
- end
9
-
10
- class TestRequest < Relax::Request
11
- parameter :action
12
- parameter :token_id
13
- parameter :user_id
14
- parameter :amount, :type => Amount
15
- end
16
-
17
- class ChildRequest < TestRequest
18
- parameter :child_id
19
- end
20
-
21
- describe 'an option initialized request', :shared => true do
22
- it 'should have its values set by the options hash' do
23
- request = TestRequest.new(:action => 'FetchAll', :token_id => 123)
24
- request.action.should eql('FetchAll')
25
- request.token_id.should eql(123)
26
- request.user_id.should be_nil
27
- end
28
- end
29
-
30
- describe 'a request that converts to a query', :shared => true do
31
- before(:each) do
32
- @query = TestRequest.new(:action => 'Search', :token_id => 123).to_query
33
- end
34
-
35
- it 'should include its parameters in the query' do
36
- @query[:action].should eql('Search')
37
- @query[:token_id].should eql('123')
38
- @query[:user_id].should be_nil
39
- @query[:amount].should be_nil
40
- end
41
-
42
- it 'should only include parameters in the query if they are set' do
43
- @query.key?(:action).should be_true
44
- @query.key?(:token_id).should be_true
45
- @query.key?(:user_id).should be_false
46
- @query.key?(:amount).should be_false
47
- end
48
- end
49
-
50
- describe 'a normal request' do
51
- it_should_behave_like 'a request that converts to a query'
52
- it_should_behave_like 'an option initialized request'
53
- end
54
-
55
- describe 'a template request' do
56
- it_should_behave_like 'a request that converts to a query'
57
- it_should_behave_like 'an option initialized request'
58
-
59
- before(:each) do
60
- # this syntax may need to go away unless we can find a way to make it work
61
- TestRequest[:api_key] = '123456'
62
- TestRequest[:secret] = 'shhh!'
63
- end
64
-
65
- it 'should always have the template values in its query' do
66
- request = TestRequest.new
67
- request.api_key.should eql('123456')
68
- request.secret.should eql('shhh!')
69
- end
70
-
71
- it 'should allow its template variables to be overridden' do
72
- request = TestRequest.new(:secret => 'abracadabra')
73
- request.api_key.should eql('123456')
74
- request.secret.should eql('abracadabra')
75
- end
76
-
77
- it 'should pass its template on to its children' do
78
- request = ChildRequest.new
79
- request.api_key.should eql('123456')
80
- request.secret.should eql('shhh!')
81
- end
82
-
83
- it 'should allow template parameters on its children that are additive' do
84
- ChildRequest[:query] = '1a2b3c'
85
- child = ChildRequest.new
86
- child.api_key.should eql('123456')
87
- child.secret.should eql('shhh!')
88
- child.query.should eql('1a2b3c')
89
-
90
- parent = TestRequest.new
91
- parent.api_key.should eql('123456')
92
- parent.secret.should eql('shhh!')
93
- parent.respond_to?(:query).should be_false
94
- end
95
- end
96
-
97
- describe 'a request with a custom type' do
98
- before(:each) do
99
- request = TestRequest.new(:action => 'Pay', :token_id => 123)
100
- request.amount = Amount.new(:amount => 3.50, :currency => 'USD')
101
- @query = request.to_query
102
- end
103
-
104
- it 'should add the type parameters to the query' do
105
- @query.key?(:"amount.amount").should be_true
106
- @query.key?(:"amount.currency").should be_true
107
- end
108
- end
@@ -1,98 +0,0 @@
1
- require File.dirname(__FILE__) + '/spec_helper'
2
-
3
-
4
- class BaseResponse < Relax::Response
5
- parameter :status, :required => true
6
- parameter :request_id, :element => :requestid, :type => :integer
7
- end
8
-
9
- class TestResponse < BaseResponse
10
- class Token < Relax::Response
11
- parameter :token_id, :element => :tokenid
12
- parameter :status
13
- end
14
-
15
- class Error < Relax::Response
16
- parser :hpricot
17
- parameter :code, :type => :integer
18
- parameter :message
19
- end
20
-
21
- parameter :valid_request, :element => :requestid, :attribute => :valid
22
- parameter :tokens, :collection => Token
23
- parameter :error, :type => Error
24
- end
25
-
26
-
27
- describe 'a response' do
28
- before(:each) do
29
- @response = Relax::Response.new(XML)
30
- end
31
-
32
- it 'should allow access to the root' do
33
- root = @response.root
34
- root.should be_an_instance_of(Hpricot::Elem)
35
- root.name.should eql('RESTResponse')
36
- end
37
-
38
- it 'should be checkable by the name of its root' do
39
- @response.is?(:RESTResponse).should be_true
40
- end
41
-
42
- it 'should allow access to an element by its name' do
43
- @response.element(:RequestId).should be_an_instance_of(Hpricot::Elem)
44
- end
45
-
46
- it 'should allow access to an element\'s elements by its name' do
47
- tokens = @response.elements(:Tokens)
48
- tokens.should be_an_instance_of(Hpricot::Elements)
49
- tokens.should_not be_empty
50
- end
51
-
52
- it 'should allow access to an element\'s value by its name' do
53
- token = Relax::Response.new(@response.elements(:Tokens).first)
54
- token.element(:TokenId).inner_text.should eql('JPMQARDVJK')
55
- token.element(:Status).inner_text.should eql('Active')
56
- end
57
-
58
- it 'should have a means of checking for the existence of a node' do
59
- @response.has?(:Status).should_not be_nil
60
- @response.has?(:Errors).should be_nil
61
- end
62
-
63
- it 'should be able to define children of Response without modifying parent' do
64
- Relax::Response.new(XML).respond_to?(:status).should be_false
65
- TestResponse.new(XML).respond_to?(:status).should be_true
66
- end
67
-
68
- it 'should automatically pull parameters from the XML' do
69
- response = TestResponse.new(XML)
70
- response.valid_request.should eql('true')
71
- response.tokens.length.should eql(2)
72
- response.tokens.first.status.should eql('Active')
73
- response.error.code.should eql(1)
74
- response.error.message.should eql('Failed')
75
- end
76
-
77
- it "should automatically pull its parent's parameters from the XML" do
78
- response = TestResponse.new(XML)
79
- response.status.should eql('Success')
80
- response.request_id.should eql(44287)
81
- end
82
-
83
- it 'should be relationally equivalent to its children' do
84
- (Relax::Response === TestResponse).should be_true
85
- end
86
-
87
- it 'should raise MissingParameter if required parameters are missing' do
88
- proc { TestResponse.new('') }.should raise_error(Relax::MissingParameter)
89
- end
90
-
91
- it 'should use the default parser when undefined' do
92
- TestResponse::Token.new('').parser_name.should ==:default
93
- end
94
-
95
- it 'should use the defined parser when given' do
96
- TestResponse::Error.new('').parser_name.should ==:hpricot
97
- end
98
- end