jspradlin-gmoney 0.0.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.
Files changed (43) hide show
  1. data/Manifest +42 -0
  2. data/README.rdoc +29 -0
  3. data/Rakefile +25 -0
  4. data/gmoney.gemspec +30 -0
  5. data/lib/extensions/string.rb +10 -0
  6. data/lib/gmoney.rb +39 -0
  7. data/lib/gmoney/authentication_request.rb +52 -0
  8. data/lib/gmoney/feed_parser.rb +37 -0
  9. data/lib/gmoney/gf_request.rb +15 -0
  10. data/lib/gmoney/gf_response.rb +5 -0
  11. data/lib/gmoney/gf_service.rb +46 -0
  12. data/lib/gmoney/gf_session.rb +18 -0
  13. data/lib/gmoney/portfolio.rb +34 -0
  14. data/lib/gmoney/portfolio_feed_parser.rb +7 -0
  15. data/lib/gmoney/position.rb +33 -0
  16. data/lib/gmoney/position_feed_parser.rb +7 -0
  17. data/lib/gmoney/transaction.rb +21 -0
  18. data/lib/gmoney/transaction_feed_parser.rb +9 -0
  19. data/spec/authentication_request_spec.rb +101 -0
  20. data/spec/fixtures/cacert.pem +67 -0
  21. data/spec/fixtures/default_portfolios_feed.xml +45 -0
  22. data/spec/fixtures/empty_portfolio_feed.xml +24 -0
  23. data/spec/fixtures/portfolio_9_feed.xml +25 -0
  24. data/spec/fixtures/portfolio_feed_with_returns.xml +69 -0
  25. data/spec/fixtures/positions_feed_for_portfolio_14.xml +13 -0
  26. data/spec/fixtures/positions_feed_for_portfolio_9.xml +63 -0
  27. data/spec/fixtures/positions_feed_for_portfolio_9r.xml +130 -0
  28. data/spec/fixtures/transactions_feed_for_GOOG.xml +78 -0
  29. data/spec/gmoney_spec.rb +9 -0
  30. data/spec/portfolio_feed_parser_spec.rb +41 -0
  31. data/spec/portfolio_spec.rb +96 -0
  32. data/spec/position_feed_parser_spec.rb +39 -0
  33. data/spec/position_spec.rb +80 -0
  34. data/spec/request_spec.rb +29 -0
  35. data/spec/response_spec.rb +18 -0
  36. data/spec/service_spec.rb +127 -0
  37. data/spec/session_spec.rb +32 -0
  38. data/spec/spec.opts +2 -0
  39. data/spec/spec_helper.rb +1 -0
  40. data/spec/string_spec.rb +40 -0
  41. data/spec/transaction_feed_parser_spec.rb +29 -0
  42. data/spec/transaction_spec.rb +46 -0
  43. metadata +114 -0
@@ -0,0 +1,29 @@
1
+ require File.join(File.dirname(__FILE__), '/spec_helper')
2
+
3
+ describe GMoney::GFRequest do
4
+
5
+ before(:each) do
6
+ @gfrequest = GMoney::GFRequest.new('http://someurl.com')
7
+ end
8
+
9
+ it "should accept body and method arguments" do
10
+ gfrequest_with_body_and_method = GMoney::GFRequest.new('http://someurl.com', {:body => 'body text', :method => :post})
11
+ gfrequest_with_body_and_method.body.should be_eql('body text')
12
+ gfrequest_with_body_and_method.method.should be_eql(:post)
13
+ end
14
+
15
+ it "should use :get as the default method" do
16
+ @gfrequest.method.should be_eql(:get)
17
+ end
18
+
19
+ it "should be able to take header parameters as a Hash" do
20
+ gfrequest_with_header_hash = GMoney::GFRequest.new('http://someurl.com', {:headers => {:header1 => 'some header'}})
21
+ gfrequest_with_header_hash.headers.should == {:header1 => 'some header'}
22
+ end
23
+
24
+ it "should not accept random options" do
25
+ lambda {
26
+ GMoney::GFRequest.new('http://someurl.com', {:random_opt => 'randomness'})
27
+ }.should raise_error(NoMethodError)
28
+ end
29
+ end
@@ -0,0 +1,18 @@
1
+ require File.join(File.dirname(__FILE__), '/spec_helper')
2
+
3
+ describe GMoney::GFResponse do
4
+
5
+ before(:each) do
6
+ @gfresponse = GMoney::GFResponse.new
7
+ end
8
+
9
+ it "should accept body, status code, and header parameters" do
10
+ @gfresponse.body = 'body'
11
+ @gfresponse.status_code = 200
12
+ @gfresponse.headers = {:header1 => 'header1', :header2 => 'header2'}
13
+
14
+ @gfresponse.body.should be_eql('body')
15
+ @gfresponse.status_code.should be_eql(200)
16
+ @gfresponse.headers.should == {:header1 => 'header1', :header2 => 'header2'}
17
+ end
18
+ end
@@ -0,0 +1,127 @@
1
+ require File.join(File.dirname(__FILE__), '/spec_helper')
2
+
3
+ describe GMoney::GFService do
4
+ before(:all) do
5
+ @feed = File.read('spec/fixtures/default_portfolios_feed.xml')
6
+ end
7
+
8
+ before(:each) do
9
+ @gfrequest = GMoney::GFRequest.new('https://someurl.com')
10
+ @gfresponse = GMoney::GFResponse.new
11
+ @gfresponse.status_code = 200
12
+ @gfresponse.body = @feed
13
+ end
14
+
15
+ it "should be able to make a get request" do
16
+ @gfrequest.body = ''
17
+ response = request_helper(Net::HTTP::Get)
18
+
19
+ response.status_code.should be_eql(@gfresponse.status_code)
20
+ response.body.should be_eql(@feed)
21
+ end
22
+
23
+ it "should be able to make a post request" do
24
+ @gfrequest.body = 'body'
25
+ @gfrequest.method = :post
26
+ @gfresponse.status_code = 201
27
+
28
+ response = request_helper(Net::HTTP::Post)
29
+
30
+ response.status_code.should be_eql(@gfresponse.status_code)
31
+ response.body.should be_eql(@feed)
32
+ end
33
+
34
+ it "should be able to make a put request" do
35
+ @gfrequest.body = 'body'
36
+ @gfrequest.method = :put
37
+
38
+ response = request_helper(Net::HTTP::Put)
39
+
40
+ response.status_code.should be_eql(@gfresponse.status_code)
41
+ response.body.should be_eql(@feed)
42
+ end
43
+
44
+ it "should be able to make a delete request" do
45
+ @gfrequest.body = 'body'
46
+ @gfrequest.method = :delete
47
+
48
+ response = request_helper(Net::HTTP::Delete)
49
+
50
+ response.status_code.should be_eql(@gfresponse.status_code)
51
+ end
52
+
53
+ it "should raise an argument error when an invalid method type is used" do
54
+ @gfrequest.body = 'body'
55
+ @gfrequest.method = :invalid
56
+
57
+ lambda {
58
+ response = error_request_helper(Net::HTTP::Get)
59
+ }.should raise_error(ArgumentError)
60
+ end
61
+
62
+ it "should allow for request headers" do
63
+ @gfrequest.body = ''
64
+ @gfrequest.method = :get
65
+ @gfrequest.headers = {:h1 => 'header 1', :h2 => 'header 2'}
66
+
67
+ response = request_helper(Net::HTTP::Get, true)
68
+
69
+ response.status_code.should be_eql(@gfresponse.status_code)
70
+ response.body.should be_eql(@feed)
71
+ end
72
+
73
+ def request_helper(class_type, with_headers = false)
74
+ set_url_expectations
75
+ http = set_http_expectations
76
+ request = set_request_expecations(class_type)
77
+ set_header_expectations(request) if with_headers
78
+ res = set_response_expecations
79
+
80
+ http.should_receive(:request).with(request).and_return(res)
81
+ GMoney::GFService.send_request(@gfrequest)
82
+ end
83
+
84
+ def error_request_helper(class_type)
85
+ set_url_expectations
86
+ set_http_expectations
87
+ GMoney::GFService.send_request(@gfrequest)
88
+ end
89
+
90
+ def set_url_expectations
91
+ url = mock
92
+ url.should_receive(:host).and_return(@gfrequest.url)
93
+ url.should_receive(:port).and_return(443)
94
+ url.should_receive(:request_uri).any_number_of_times.and_return(@gfrequest.url)
95
+ url.should_receive(:scheme).and_return('https')
96
+ URI.should_receive(:parse).with(@gfrequest.url).and_return(url)
97
+ url
98
+ end
99
+
100
+ def set_http_expectations
101
+ http = mock
102
+ http.should_receive(:use_ssl=).with(true)
103
+ http.should_receive(:verify_mode=).with(OpenSSL::SSL::VERIFY_NONE)
104
+ Net::HTTP.should_receive(:new).with(@gfrequest.url, 443).and_return(http)
105
+ http
106
+ end
107
+
108
+ def set_request_expecations(class_type)
109
+ method_type = mock
110
+ method_type.should_receive(:body=).with(@gfrequest.body)
111
+ class_type.should_receive(:new).with(@gfrequest.url).and_return(method_type)
112
+ method_type
113
+ end
114
+
115
+ def set_response_expecations
116
+ res = mock
117
+ res.should_receive(:body).and_return(@feed)
118
+ res.should_receive(:each).and_yield(:rh1,'rheader1').and_yield(:rh2,'rheader2')
119
+ res.should_receive(:code).and_return(@gfresponse.status_code)
120
+ res
121
+ end
122
+
123
+ def set_header_expectations(req)
124
+ req.should_receive(:[]=).with(:h1, "header 1").any_number_of_times
125
+ req.should_receive(:[]=).with(:h2, "header 2").any_number_of_times
126
+ end
127
+ end
@@ -0,0 +1,32 @@
1
+ require File.join(File.dirname(__FILE__), '/spec_helper')
2
+
3
+ describe GMoney::GFSession do
4
+
5
+ before(:each) do
6
+ @auth_request = mock('GMoney::AuthenticationRequest')
7
+ end
8
+
9
+ it "should be able to retrieve an auth_token for a user" do
10
+ @auth_request.should_receive(:auth_token).with({}).and_return('toke')
11
+
12
+ GMoney::AuthenticationRequest.should_receive(:new).with('email', 'password').once.and_return(@auth_request)
13
+ GMoney::GFSession.login('email', 'password')
14
+ GMoney::GFSession.auth_token.should be_eql('toke')
15
+ end
16
+
17
+ it "should be able to retrieve an auth_token for a user with secure ssl" do
18
+ @auth_request.should_receive(:auth_token).with({:secure => true}).and_return('secure toke')
19
+
20
+ GMoney::AuthenticationRequest.should_receive(:new).with('email', 'password').once.and_return(@auth_request)
21
+ GMoney::GFSession.login('email', 'password', :secure => true)
22
+ GMoney::GFSession.auth_token.should be_eql('secure toke')
23
+ end
24
+
25
+ it "should retain the email address for this session" do
26
+ @auth_request.should_receive(:auth_token).with({}).and_return('toke')
27
+
28
+ GMoney::AuthenticationRequest.should_receive(:new).with('email@example.com', 'password').once.and_return(@auth_request)
29
+ GMoney::GFSession.login('email@example.com', 'password')
30
+ GMoney::GFSession.email.should be_eql('email@example.com')
31
+ end
32
+ end
@@ -0,0 +1,2 @@
1
+ --colour
2
+ --format specdoc
@@ -0,0 +1 @@
1
+ require File.dirname(__FILE__) + '/../lib/gmoney'
@@ -0,0 +1,40 @@
1
+ require File.join(File.dirname(__FILE__), '/spec_helper')
2
+
3
+ describe String do
4
+ it "should convert camel cased strings to strings with underscores" do
5
+ 'CamelCase'.camel_to_us.should be_eql('camel_case')
6
+ 'CamelCamelCase'.camel_to_us.should be_eql('camel_camel_case')
7
+ 'Camel2Camel2Case'.camel_to_us.should be_eql('camel2_camel2_case')
8
+ 'getHTTPResponseCode'.camel_to_us.should be_eql('get_http_response_code')
9
+ 'get2HTTPResponseCode'.camel_to_us.should be_eql('get2_http_response_code')
10
+ 'HTTPResponseCode'.camel_to_us.should be_eql('http_response_code')
11
+ 'HTTPResponseCodeXYZ'.camel_to_us.should be_eql('http_response_code_xyz')
12
+ 'returnYTD='.camel_to_us.should be_eql('return_ytd=')
13
+ 'return_ytd='.camel_to_us.should be_eql('return_ytd=')
14
+ end
15
+
16
+ it "should be able to detect if its contents are numeric" do
17
+ '0'.is_numeric?.should be_true
18
+ '0.0'.is_numeric?.should be_true
19
+ '1'.is_numeric?.should be_true
20
+ '-1'.is_numeric?.should be_true
21
+ '-0.3423'.is_numeric?.should be_true
22
+ '234.2352'.is_numeric?.should be_true
23
+ '-234.2352'.is_numeric?.should be_true
24
+ '-0.2352'.is_numeric?.should be_true
25
+ '-0.2352'.is_numeric?.should be_true
26
+ '-.2352'.is_numeric?.should be_true
27
+
28
+ 'a'.is_numeric?.should be_false
29
+ 'cat'.is_numeric?.should be_false
30
+ '-.23s52'.is_numeric?.should be_false
31
+ '0.0s'.is_numeric?.should be_false
32
+ 's0.0'.is_numeric?.should be_false
33
+ 's1'.is_numeric?.should be_false
34
+ '1s1'.is_numeric?.should be_false
35
+ '1s'.is_numeric?.should be_false
36
+ '@'.is_numeric?.should be_false
37
+ '$123.23'.is_numeric?.should be_false
38
+ '.'.is_numeric?.should be_false
39
+ end
40
+ end
@@ -0,0 +1,29 @@
1
+ require File.join(File.dirname(__FILE__), '/spec_helper')
2
+
3
+ describe GMoney::TransactionFeedParser do
4
+ before(:all) do
5
+ feed = File.read('spec/fixtures/transactions_feed_for_GOOG.xml')
6
+ @transactions = GMoney::TransactionFeedParser.parse_transaction_feed(feed)
7
+ end
8
+
9
+ it "should create Transaction objects out of transaction feeds" do
10
+ @transactions.each do |transaction|
11
+ transaction.should be_instance_of(GMoney::Transaction)
12
+ end
13
+ end
14
+
15
+ it "should return an Array of Transaction objects equal to the size of Transaction entries" do
16
+ @transactions.size.should be_eql(4)
17
+ end
18
+
19
+ it "should create Transaction objects with valid numeric data types" do
20
+ @transactions.each do |transaction|
21
+ transaction.public_methods(false).each do |pm|
22
+ if !(['id', 'updated', 'title', 'date', 'type', 'notes'].include? pm) && !(pm.include?('='))
23
+ return_val = transaction.send(pm)
24
+ return_val.should be_instance_of(Float) if return_val
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,46 @@
1
+ require File.join(File.dirname(__FILE__), '/spec_helper')
2
+
3
+ describe GMoney::Transaction do
4
+ before(:all) do
5
+ @goog_feed = File.read('spec/fixtures/transactions_feed_for_GOOG.xml')
6
+ end
7
+
8
+ before(:each) do
9
+ @url = 'https://finance.google.com/finance/feeds/default/portfolios/9/positions/NASDAQ:GOOG/transactions'
10
+
11
+ @gf_request = GMoney::GFRequest.new(@url)
12
+ @gf_request.method = :get
13
+
14
+ @gf_response = GMoney::GFResponse.new
15
+ @gf_response.status_code = 200
16
+ @gf_response.body = @goog_feed
17
+ end
18
+
19
+ it "should return all Tranasactions when the status code is 200" do
20
+ transactions = transaction_helper(@url)
21
+
22
+ transactions.size.should be_eql(4)
23
+ transactions[1].commission.should be_eql(12.75)
24
+ transactions[1].notes.should be_eql('Buy some more Google.')
25
+ end
26
+
27
+ it "should raise an error when the status code is not 200" do
28
+ @gf_response.status_code = 404
29
+
30
+ lambda { transaction_helper(@url) }.should raise_error(GMoney::Transaction::TransactionRequestError)
31
+ end
32
+
33
+ =begin TODO - create a method that retreives individual transactions
34
+ it "should return a specific transactions is the request a specific transactions" do
35
+ =end
36
+
37
+ def transaction_helper(url)
38
+ GMoney::GFSession.should_receive(:auth_token).and_return('toke')
39
+
40
+ GMoney::GFRequest.should_receive(:new).with(url, :headers => {"Authorization" => "GoogleLogin auth=toke"}).and_return(@gf_request)
41
+
42
+ GMoney::GFService.should_receive(:send_request).with(@gf_request).and_return(@gf_response)
43
+
44
+ GMoney::Transaction.find_by_url(url)
45
+ end
46
+ end
metadata ADDED
@@ -0,0 +1,114 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: jspradlin-gmoney
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.2
5
+ platform: ruby
6
+ authors:
7
+ - Justin Spradlin
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2009-09-15 00:00:00 -07:00
13
+ default_executable:
14
+ dependencies: []
15
+
16
+ description: A gem for interacting with the Google Finance API
17
+ email: jspradlin@gmail.com
18
+ executables: []
19
+
20
+ extensions: []
21
+
22
+ extra_rdoc_files:
23
+ - README.rdoc
24
+ - lib/extensions/string.rb
25
+ - lib/gmoney.rb
26
+ - lib/gmoney/authentication_request.rb
27
+ - lib/gmoney/feed_parser.rb
28
+ - lib/gmoney/gf_request.rb
29
+ - lib/gmoney/gf_response.rb
30
+ - lib/gmoney/gf_service.rb
31
+ - lib/gmoney/gf_session.rb
32
+ - lib/gmoney/portfolio.rb
33
+ - lib/gmoney/portfolio_feed_parser.rb
34
+ - lib/gmoney/position.rb
35
+ - lib/gmoney/position_feed_parser.rb
36
+ - lib/gmoney/transaction.rb
37
+ - lib/gmoney/transaction_feed_parser.rb
38
+ files:
39
+ - Manifest
40
+ - README.rdoc
41
+ - Rakefile
42
+ - gmoney.gemspec
43
+ - lib/extensions/string.rb
44
+ - lib/gmoney.rb
45
+ - lib/gmoney/authentication_request.rb
46
+ - lib/gmoney/feed_parser.rb
47
+ - lib/gmoney/gf_request.rb
48
+ - lib/gmoney/gf_response.rb
49
+ - lib/gmoney/gf_service.rb
50
+ - lib/gmoney/gf_session.rb
51
+ - lib/gmoney/portfolio.rb
52
+ - lib/gmoney/portfolio_feed_parser.rb
53
+ - lib/gmoney/position.rb
54
+ - lib/gmoney/position_feed_parser.rb
55
+ - lib/gmoney/transaction.rb
56
+ - lib/gmoney/transaction_feed_parser.rb
57
+ - spec/authentication_request_spec.rb
58
+ - spec/fixtures/cacert.pem
59
+ - spec/fixtures/default_portfolios_feed.xml
60
+ - spec/fixtures/empty_portfolio_feed.xml
61
+ - spec/fixtures/portfolio_9_feed.xml
62
+ - spec/fixtures/portfolio_feed_with_returns.xml
63
+ - spec/fixtures/positions_feed_for_portfolio_14.xml
64
+ - spec/fixtures/positions_feed_for_portfolio_9.xml
65
+ - spec/fixtures/positions_feed_for_portfolio_9r.xml
66
+ - spec/fixtures/transactions_feed_for_GOOG.xml
67
+ - spec/gmoney_spec.rb
68
+ - spec/portfolio_feed_parser_spec.rb
69
+ - spec/portfolio_spec.rb
70
+ - spec/position_feed_parser_spec.rb
71
+ - spec/position_spec.rb
72
+ - spec/request_spec.rb
73
+ - spec/response_spec.rb
74
+ - spec/service_spec.rb
75
+ - spec/session_spec.rb
76
+ - spec/spec.opts
77
+ - spec/spec_helper.rb
78
+ - spec/string_spec.rb
79
+ - spec/transaction_feed_parser_spec.rb
80
+ - spec/transaction_spec.rb
81
+ has_rdoc: false
82
+ homepage: http://github.com/jspradlin/gmoney
83
+ licenses:
84
+ post_install_message:
85
+ rdoc_options:
86
+ - --line-numbers
87
+ - --inline-source
88
+ - --title
89
+ - Gmoney
90
+ - --main
91
+ - README.rdoc
92
+ require_paths:
93
+ - lib
94
+ required_ruby_version: !ruby/object:Gem::Requirement
95
+ requirements:
96
+ - - ">="
97
+ - !ruby/object:Gem::Version
98
+ version: "0"
99
+ version:
100
+ required_rubygems_version: !ruby/object:Gem::Requirement
101
+ requirements:
102
+ - - ">="
103
+ - !ruby/object:Gem::Version
104
+ version: "1.2"
105
+ version:
106
+ requirements: []
107
+
108
+ rubyforge_project: gmoney
109
+ rubygems_version: 1.3.5
110
+ signing_key:
111
+ specification_version: 3
112
+ summary: A gem for interacting with the Google Finance API
113
+ test_files: []
114
+