gmoney 0.1.0 → 0.2.0
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/README.rdoc +27 -5
- data/gmoney.gemspec +2 -2
- data/lib/extensions/string.rb +11 -3
- data/lib/gmoney.rb +1 -1
- data/lib/gmoney/portfolio.rb +22 -3
- data/lib/gmoney/position.rb +30 -1
- data/lib/gmoney/transaction.rb +20 -1
- data/spec/portfolio_feed_parser_spec.rb +2 -1
- data/spec/portfolio_spec.rb +49 -0
- data/spec/position_feed_parser_spec.rb +2 -2
- data/spec/position_spec.rb +56 -0
- data/spec/string_spec.rb +6 -1
- data/spec/transaction_feed_parser_spec.rb +1 -2
- data/spec/transaction_spec.rb +51 -1
- metadata +2 -2
data/README.rdoc
CHANGED
@@ -6,24 +6,30 @@ A gem for interacting with the Google Finance API
|
|
6
6
|
|
7
7
|
gem install gmoney
|
8
8
|
|
9
|
-
or
|
10
|
-
|
11
|
-
gem install jspradlin-gmoney --source http://gems.github.com
|
12
|
-
|
13
9
|
== Usage
|
14
10
|
|
15
11
|
Login
|
16
12
|
-----
|
17
13
|
|
18
|
-
|
14
|
+
GMoney::GFSession.login('google username', 'password')
|
19
15
|
|
20
16
|
Portfolios
|
21
17
|
--------
|
22
18
|
|
19
|
+
Reading
|
23
20
|
> portfolios = GMoney::Portfolio.all #returns all of a users portfolios
|
24
21
|
> portfolio = GMoney::Portfolio.find(9) #returns a specific portfolio
|
25
22
|
|
26
23
|
> positions = portfolio.positions #returns an Array of the Positions held within a given portfolio
|
24
|
+
|
25
|
+
Deleting
|
26
|
+
> GMoney::Portfolio.delete 2
|
27
|
+
|
28
|
+
or
|
29
|
+
|
30
|
+
> portfolio = GMoney::Portfolio.find 2
|
31
|
+
> portfolio.destroy #call destroy on an instance of a portfolio
|
32
|
+
|
27
33
|
|
28
34
|
Positions
|
29
35
|
--------
|
@@ -32,6 +38,14 @@ Positions
|
|
32
38
|
> position = GMoney::Position.find("9/NASDAQ:GOOG") #returns a specific position within a given portfolio
|
33
39
|
|
34
40
|
> transactions = position.transactions #returns an Array of the Transactions within a given position
|
41
|
+
|
42
|
+
Deleting
|
43
|
+
> GMoney::Position.delete '2/NASDAQ:GOOG'
|
44
|
+
|
45
|
+
or
|
46
|
+
|
47
|
+
> position = GMoney::Position.find '2/NASDAQ:GOOG'
|
48
|
+
> position.destroy #call destroy on an instance of a position
|
35
49
|
|
36
50
|
Transactions
|
37
51
|
--------
|
@@ -39,6 +53,14 @@ Transactions
|
|
39
53
|
> transactions = GMoney::Transaction.find("9/NASDAQ:GOOG") #returns all of a users transactions within a given position
|
40
54
|
> transaction = GMoney::Transaction.find("9/NASDAQ:GOOG/2") #returns a specific transaction within a given position
|
41
55
|
|
56
|
+
Deleting
|
57
|
+
> GMoney::Transaction.delete '2/NASDAQ:GOOG/1'
|
58
|
+
|
59
|
+
or
|
60
|
+
|
61
|
+
> transaction = GMoney::Transaction.find '2/NASDAQ:GOOG/1'
|
62
|
+
> transaction.destroy #call destroy on an instance of a transaction
|
63
|
+
|
42
64
|
----------
|
43
65
|
|
44
66
|
Options parameter
|
data/gmoney.gemspec
CHANGED
@@ -2,11 +2,11 @@
|
|
2
2
|
|
3
3
|
Gem::Specification.new do |s|
|
4
4
|
s.name = %q{gmoney}
|
5
|
-
s.version = "0.
|
5
|
+
s.version = "0.2.0"
|
6
6
|
|
7
7
|
s.required_rubygems_version = Gem::Requirement.new(">= 1.2") if s.respond_to? :required_rubygems_version=
|
8
8
|
s.authors = ["Justin Spradlin"]
|
9
|
-
s.date = %q{2009-
|
9
|
+
s.date = %q{2009-11-13}
|
10
10
|
s.description = %q{A gem for interacting with the Google Finance API}
|
11
11
|
s.email = %q{jspradlin@gmail.com}
|
12
12
|
s.extra_rdoc_files = ["README.rdoc", "lib/extensions/fixnum.rb", "lib/extensions/string.rb", "lib/gmoney.rb", "lib/gmoney/authentication_request.rb", "lib/gmoney/feed_parser.rb", "lib/gmoney/gf_request.rb", "lib/gmoney/gf_response.rb", "lib/gmoney/gf_service.rb", "lib/gmoney/gf_session.rb", "lib/gmoney/portfolio.rb", "lib/gmoney/portfolio_feed_parser.rb", "lib/gmoney/position.rb", "lib/gmoney/position_feed_parser.rb", "lib/gmoney/transaction.rb", "lib/gmoney/transaction_feed_parser.rb"]
|
data/lib/extensions/string.rb
CHANGED
@@ -1,7 +1,8 @@
|
|
1
1
|
class String
|
2
|
-
class
|
3
|
-
class
|
4
|
-
class
|
2
|
+
class ParseError < StandardError; end
|
3
|
+
class PortfolioParseError < ParseError; end
|
4
|
+
class PositionParseError < ParseError; end
|
5
|
+
class TransactionParseError < ParseError; end
|
5
6
|
|
6
7
|
@@portfolio_re = /\d+/
|
7
8
|
@@portfolio_re_in = /^\d+$/
|
@@ -30,6 +31,13 @@ class String
|
|
30
31
|
"#{portfolio}/#{position}"
|
31
32
|
end
|
32
33
|
|
34
|
+
def transaction_feed_id
|
35
|
+
portfolio = self[self.rindex('portfolios/')+11..index('/positions')-1]
|
36
|
+
position = self[self.rindex('positions/')+10..index('/transactions')-1]
|
37
|
+
transaction = self[rindex('/')+1..-1]
|
38
|
+
"#{portfolio}/#{position}/#{transaction}"
|
39
|
+
end
|
40
|
+
|
33
41
|
def portfolio_id
|
34
42
|
if self[@@transaction_re_in] || self[@@position_re_in] || self[@@portfolio_re_in]
|
35
43
|
self[@@portfolio_re]
|
data/lib/gmoney.rb
CHANGED
@@ -27,7 +27,7 @@ require 'gmoney/transaction'
|
|
27
27
|
require 'gmoney/transaction_feed_parser'
|
28
28
|
|
29
29
|
module GMoney
|
30
|
-
VERSION = '0.
|
30
|
+
VERSION = '0.2.0'
|
31
31
|
GF_URL = "https://finance.google.com/finance"
|
32
32
|
GF_FEED_URL = "#{GF_URL}/feeds/default"
|
33
33
|
GF_PORTFOLIO_FEED_URL = "#{GF_FEED_URL}/portfolios"
|
data/lib/gmoney/portfolio.rb
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
module GMoney
|
2
2
|
class Portfolio
|
3
3
|
class PortfolioRequestError < StandardError;end
|
4
|
+
class PortfolioDeleteError < StandardError;end
|
4
5
|
|
5
6
|
attr_accessor :title, :currency_code
|
6
7
|
|
@@ -25,7 +26,16 @@ module GMoney
|
|
25
26
|
|
26
27
|
@positions.is_a?(Array) ? @positions : [@positions]
|
27
28
|
end
|
28
|
-
|
29
|
+
|
30
|
+
def self.delete(id)
|
31
|
+
delete_portfolio(id)
|
32
|
+
end
|
33
|
+
|
34
|
+
def destroy
|
35
|
+
Portfolio.delete(@id.portfolio_feed_id)
|
36
|
+
freeze
|
37
|
+
end
|
38
|
+
|
29
39
|
def self.retreive_portfolios(id, options = {})
|
30
40
|
url = GF_PORTFOLIO_FEED_URL
|
31
41
|
url += "/#{id}" if id != :all
|
@@ -45,8 +55,17 @@ module GMoney
|
|
45
55
|
return portfolios[0] if portfolios.size == 1
|
46
56
|
|
47
57
|
portfolios
|
48
|
-
end
|
58
|
+
end
|
59
|
+
|
60
|
+
#If you are working behind some firewalls HTTP DELETE request won't work.
|
61
|
+
#To overcome this problem the google doc say to use a post request with
|
62
|
+
#the X-HTTP-Method-Override set to "DELETE"
|
63
|
+
def self.delete_portfolio(id)
|
64
|
+
url = "#{GF_PORTFOLIO_FEED_URL}/#{id}"
|
65
|
+
response = GFService.send_request(GFRequest.new(url, :method => :post, :headers => {"Authorization" => "GoogleLogin auth=#{GFSession.auth_token}", "X-HTTP-Method-Override" => "DELETE"}))
|
66
|
+
raise PortfolioDeleteError, response.body if response.status_code != HTTPOK
|
67
|
+
end
|
49
68
|
|
50
|
-
private_class_method :retreive_portfolios
|
69
|
+
private_class_method :retreive_portfolios, :delete_portfolio
|
51
70
|
end
|
52
71
|
end
|
data/lib/gmoney/position.rb
CHANGED
@@ -1,6 +1,8 @@
|
|
1
1
|
module GMoney
|
2
2
|
class Position
|
3
3
|
class PositionRequestError < StandardError; end
|
4
|
+
class PositionDeleteError < StandardError; end
|
5
|
+
|
4
6
|
attr_reader :id, :updated, :title, :feed_link, :exchange, :symbol, :shares,
|
5
7
|
:full_name, :gain_percentage, :return1w, :return4w, :return3m,
|
6
8
|
:return_ytd, :return1y, :return3y, :return5y, :return_overall,
|
@@ -19,6 +21,15 @@ module GMoney
|
|
19
21
|
|
20
22
|
@transactions.is_a?(Array) ? @transactions : [@transactions]
|
21
23
|
end
|
24
|
+
|
25
|
+
def self.delete(id)
|
26
|
+
delete_position(id)
|
27
|
+
end
|
28
|
+
|
29
|
+
def destroy
|
30
|
+
Position.delete(@id.position_feed_id)
|
31
|
+
freeze
|
32
|
+
end
|
22
33
|
|
23
34
|
def self.find_by_url(url, options = {})
|
24
35
|
positions = []
|
@@ -39,6 +50,24 @@ module GMoney
|
|
39
50
|
positions
|
40
51
|
end
|
41
52
|
|
42
|
-
|
53
|
+
#In order to delete a position you must delete all the transactions that fall under
|
54
|
+
#that position.
|
55
|
+
def self.delete_position(id)
|
56
|
+
begin
|
57
|
+
trans = Transaction.find("#{id.portfolio_id}/#{id.position_id}")
|
58
|
+
if trans.class == Transaction
|
59
|
+
trans.destroy
|
60
|
+
else
|
61
|
+
trans.each {|t| t.destroy }
|
62
|
+
end
|
63
|
+
rescue Transaction::TransactionRequestError => e
|
64
|
+
raise PositionDeleteError, e.message
|
65
|
+
rescue String::ParseError
|
66
|
+
raise PositionDeleteError, 'Invalid Position ID'
|
67
|
+
end
|
68
|
+
nil
|
69
|
+
end
|
70
|
+
|
71
|
+
private_class_method :find_by_url, :delete_position
|
43
72
|
end
|
44
73
|
end
|
data/lib/gmoney/transaction.rb
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
module GMoney
|
2
2
|
class Transaction
|
3
3
|
class TransactionRequestError < StandardError; end
|
4
|
+
class TransactionDeleteError < StandardError;end
|
4
5
|
|
5
6
|
attr_reader :id, :updated, :title
|
6
7
|
|
@@ -10,6 +11,15 @@ module GMoney
|
|
10
11
|
find_by_url("#{GF_PORTFOLIO_FEED_URL}/#{id.portfolio_id}/positions/#{id.position_id}/transactions/#{id.transaction_id}", options)
|
11
12
|
end
|
12
13
|
|
14
|
+
def self.delete(id)
|
15
|
+
delete_transaction(id)
|
16
|
+
end
|
17
|
+
|
18
|
+
def destroy
|
19
|
+
Transaction.delete(@id.transaction_feed_id)
|
20
|
+
freeze
|
21
|
+
end
|
22
|
+
|
13
23
|
def self.find_by_url(url, options={})
|
14
24
|
transactions = []
|
15
25
|
|
@@ -26,6 +36,15 @@ module GMoney
|
|
26
36
|
transactions
|
27
37
|
end
|
28
38
|
|
29
|
-
|
39
|
+
#If you are working behind some firewalls DELETE HTTP request won't work.
|
40
|
+
#To overcome this problem the google doc say to use a post request with
|
41
|
+
#the X-HTTP-Method-Override set to "DELETE"
|
42
|
+
def self.delete_transaction(id)
|
43
|
+
url = "#{GF_PORTFOLIO_FEED_URL}/#{id.portfolio_id}/positions/#{id.position_id}/transactions/#{id.transaction_id}"
|
44
|
+
response = GFService.send_request(GFRequest.new(url, :method => :post, :headers => {"Authorization" => "GoogleLogin auth=#{GFSession.auth_token}", "X-HTTP-Method-Override" => "DELETE"}))
|
45
|
+
raise TransactionDeleteError, response.body if response.status_code != HTTPOK
|
46
|
+
end
|
47
|
+
|
48
|
+
private_class_method :find_by_url, :delete_transaction
|
30
49
|
end
|
31
50
|
end
|
@@ -31,7 +31,8 @@ describe GMoney::PortfolioFeedParser do
|
|
31
31
|
it "should create Portfolio objects with valid numeric data types for the returns" do
|
32
32
|
@portfolios_with_returns.each do |portfolio|
|
33
33
|
portfolio.public_methods(false).each do |pm|
|
34
|
-
if
|
34
|
+
if (['gain_percentage', 'return1w', 'return4w', 'return3m', 'return_ytd', 'return1y', 'return3y', 'return5y',
|
35
|
+
'return_overall', 'cost_basis', 'days_gain', 'gain', 'market_value'].include? pm) && !(pm.include?('='))
|
35
36
|
return_val = portfolio.send(pm)
|
36
37
|
return_val.should be_instance_of(Float) if return_val
|
37
38
|
end
|
data/spec/portfolio_spec.rb
CHANGED
@@ -93,6 +93,47 @@ describe GMoney::Portfolio do
|
|
93
93
|
portfolio.positions.size.should be_eql(2)
|
94
94
|
end
|
95
95
|
|
96
|
+
it "should delete portfolios using a class method and id" do
|
97
|
+
@gf_request = GMoney::GFRequest.new(@url)
|
98
|
+
@gf_request.method = :delete
|
99
|
+
|
100
|
+
@gf_response = GMoney::GFResponse.new
|
101
|
+
@gf_response.status_code = 200
|
102
|
+
|
103
|
+
portfolio_delete_helper("#{@url}/19")
|
104
|
+
|
105
|
+
GMoney::Portfolio.delete(19).should be_nil
|
106
|
+
end
|
107
|
+
|
108
|
+
it "should delete portfolios by calling destroy on an instance of a portfolio" do
|
109
|
+
@gf_request = GMoney::GFRequest.new(@url)
|
110
|
+
@gf_request.method = :delete
|
111
|
+
|
112
|
+
@gf_response = GMoney::GFResponse.new
|
113
|
+
@gf_response.status_code = 200
|
114
|
+
|
115
|
+
portfolio = GMoney::Portfolio.new
|
116
|
+
portfolio.instance_variable_set("@id", "#{@url}/24")
|
117
|
+
|
118
|
+
portfolio_delete_helper("#{@url}/24")
|
119
|
+
|
120
|
+
portfolio_return = portfolio.destroy
|
121
|
+
portfolio_return.should be_eql(portfolio)
|
122
|
+
portfolio_return.frozen?.should be_true
|
123
|
+
end
|
124
|
+
|
125
|
+
it "should raise a PortfolioDeleteError when there is an attempt to delete an portfolio that doesn't exist')" do
|
126
|
+
@gf_request = GMoney::GFRequest.new(@url)
|
127
|
+
@gf_request.method = :delete
|
128
|
+
|
129
|
+
@gf_response = GMoney::GFResponse.new
|
130
|
+
@gf_response.status_code = 400
|
131
|
+
@gf_request.body = "Invalid portfolio ID."
|
132
|
+
|
133
|
+
portfolio_delete_helper("#{@url}/asdf")
|
134
|
+
|
135
|
+
lambda { GMoney::Portfolio.delete("asdf") }.should raise_error(GMoney::Portfolio::PortfolioDeleteError, @gf_response.body)
|
136
|
+
end
|
96
137
|
|
97
138
|
def portfolio_helper(url, id = nil, options = {})
|
98
139
|
GMoney::GFSession.should_receive(:auth_token).and_return('toke')
|
@@ -110,4 +151,12 @@ describe GMoney::Portfolio do
|
|
110
151
|
|
111
152
|
portfolios = id ? GMoney::Portfolio.find(id, options) : GMoney::Portfolio.all(options)
|
112
153
|
end
|
154
|
+
|
155
|
+
def portfolio_delete_helper(url)
|
156
|
+
GMoney::GFSession.should_receive(:auth_token).and_return('toke')
|
157
|
+
|
158
|
+
GMoney::GFRequest.should_receive(:new).with(url, :method => :post, :headers => {"Authorization" => "GoogleLogin auth=toke", "X-HTTP-Method-Override" => "DELETE"}).and_return(@gf_request)
|
159
|
+
|
160
|
+
GMoney::GFService.should_receive(:send_request).with(@gf_request).and_return(@gf_response)
|
161
|
+
end
|
113
162
|
end
|
@@ -28,8 +28,8 @@ describe GMoney::PositionFeedParser do
|
|
28
28
|
|
29
29
|
it "should create Position objects with valid numeric data types for the returns" do
|
30
30
|
@positions_with_returns.each do |position|
|
31
|
-
position.public_methods(false).each do |pm|
|
32
|
-
if
|
31
|
+
position.public_methods(false).each do |pm|
|
32
|
+
if (['shares', 'gain_percentage', 'return1w', 'return4w', 'return3m', 'return_ytd', 'return1y', 'return3y', 'return5y', 'return_overall', 'cost_basis', 'days_gain', 'gain', 'market_value'].include? pm) && !(pm.include?('='))
|
33
33
|
return_val = position.send(pm)
|
34
34
|
return_val.should be_instance_of(Float) if return_val
|
35
35
|
end
|
data/spec/position_spec.rb
CHANGED
@@ -10,6 +10,7 @@ describe GMoney::Position do
|
|
10
10
|
|
11
11
|
before(:each) do
|
12
12
|
@portfolio_id = '9'
|
13
|
+
@url = 'https://finance.google.com/finance/feeds/default/portfolios/9/positions'
|
13
14
|
|
14
15
|
@gf_request = GMoney::GFRequest.new(@portfolio_id)
|
15
16
|
@gf_request.method = :get
|
@@ -87,6 +88,51 @@ describe GMoney::Position do
|
|
87
88
|
position.transactions(:eager => true).size.should be_eql(3)
|
88
89
|
end
|
89
90
|
|
91
|
+
|
92
|
+
it "should delete positions (with a single transaction) using a class method and id" do
|
93
|
+
@trans = GMoney::Transaction.new
|
94
|
+
@trans.instance_variable_set("@id", "#{@url}/NASDAQ:GOOG/transactions/21")
|
95
|
+
|
96
|
+
position_delete_helper('9/NASDAQ:GOOG')
|
97
|
+
|
98
|
+
GMoney::Position.delete('9/NASDAQ:GOOG').should be_nil
|
99
|
+
end
|
100
|
+
|
101
|
+
it "should delete positions (with multiple transactions) using a class method and id" do
|
102
|
+
tran1 = GMoney::Transaction.new
|
103
|
+
tran1.instance_variable_set("@id", "#{@url}/NASDAQ:GOOG/transactions/21")
|
104
|
+
tran2 = GMoney::Transaction.new
|
105
|
+
tran2.instance_variable_set("@id", "#{@url}/NASDAQ:GOOG/transactions/22")
|
106
|
+
@trans = [tran1, tran2]
|
107
|
+
|
108
|
+
position_delete_helper('9/NASDAQ:GOOG')
|
109
|
+
|
110
|
+
GMoney::Position.delete('9/NASDAQ:GOOG').should be_nil
|
111
|
+
end
|
112
|
+
|
113
|
+
it "should delete positions when calling destroy on an instance of a position" do
|
114
|
+
position = GMoney::Position.new
|
115
|
+
position.instance_variable_set("@id", "#{@url}/NASDAQ:GOOG")
|
116
|
+
|
117
|
+
@trans = GMoney::Transaction.new
|
118
|
+
@trans.instance_variable_set("@id", "#{@url}/NASDAQ:GOOG/transactions/21")
|
119
|
+
|
120
|
+
position_delete_helper('9/NASDAQ:GOOG')
|
121
|
+
|
122
|
+
position_return = position.destroy
|
123
|
+
position_return.should be_eql(position)
|
124
|
+
position_return.frozen?.should be_true
|
125
|
+
end
|
126
|
+
|
127
|
+
it "should raise a PositionDeleteError when there is an attempt to delete a position with a bad position id')" do
|
128
|
+
lambda { GMoney::Position.delete("9/NASDAQ:GOOG/asdf") }.should raise_error(GMoney::Position::PositionDeleteError, 'Invalid Position ID')
|
129
|
+
end
|
130
|
+
|
131
|
+
it "should raise a PositionDeleteError when there is an attempt to delete a position with a bad position id')" do
|
132
|
+
GMoney::Transaction.should_receive(:find).with('9/NYSE:C').and_raise(GMoney::Transaction::TransactionRequestError.new('No position exists with ticker NYSE:C'))
|
133
|
+
lambda { GMoney::Position.delete("9/NYSE:C") }.should raise_error(GMoney::Position::PositionDeleteError, 'No position exists with ticker NYSE:C')
|
134
|
+
end
|
135
|
+
|
90
136
|
def position_helper(id, options = {})
|
91
137
|
GMoney::GFSession.should_receive(:auth_token).and_return('toke')
|
92
138
|
|
@@ -106,4 +152,14 @@ describe GMoney::Position do
|
|
106
152
|
|
107
153
|
GMoney::Position.find(id, options)
|
108
154
|
end
|
155
|
+
|
156
|
+
def position_delete_helper(id)
|
157
|
+
GMoney::Transaction.should_receive(:find).with(id).and_return(@trans)
|
158
|
+
|
159
|
+
if @trans.class == GMoney::Transaction
|
160
|
+
@trans.should_receive(:destroy)
|
161
|
+
else
|
162
|
+
@trans.each {|t| t.should_receive(:destroy)}
|
163
|
+
end
|
164
|
+
end
|
109
165
|
end
|
data/spec/string_spec.rb
CHANGED
@@ -42,10 +42,15 @@ describe String do
|
|
42
42
|
"http://finance.google.com/finance/feeds/user@example.com/portfolios/9".portfolio_feed_id.should be_eql("9")
|
43
43
|
end
|
44
44
|
|
45
|
-
it "should be able to parse a position id from an position feed
|
45
|
+
it "should be able to parse a position id from an position feed url" do
|
46
46
|
"http://finance.google.com/finance/feeds/user@example.com/portfolios/9/positions/NASDAG:GOOG".position_feed_id.should be_eql("9/NASDAG:GOOG")
|
47
47
|
end
|
48
48
|
|
49
|
+
it "should be able to parse a transaction id from an transaction feed url" do
|
50
|
+
"http://finance.google.com/finance/feeds/user@example.com/portfolios/9/positions/NASDAG:GOOG/transactions/12".transaction_feed_id.should be_eql("9/NASDAG:GOOG/12")
|
51
|
+
"http://finance.google.com/finance/feeds/user@example.com/portfolios/12/positions/NYSE:GLD/transactions/3".transaction_feed_id.should be_eql("12/NYSE:GLD/3")
|
52
|
+
end
|
53
|
+
|
49
54
|
it "should be able to parse a portfolio id out of a string" do
|
50
55
|
1.portfolio_id.should be_eql("1")
|
51
56
|
"1".portfolio_id.should be_eql("1")
|
@@ -5,7 +5,6 @@ describe GMoney::TransactionFeedParser do
|
|
5
5
|
feed = File.read('spec/fixtures/transactions_feed_for_GOOG.xml')
|
6
6
|
@transactions = GMoney::TransactionFeedParser.parse_transaction_feed(feed)
|
7
7
|
end
|
8
|
-
|
9
8
|
it "should create Transaction objects out of transaction feeds" do
|
10
9
|
@transactions.each do |transaction|
|
11
10
|
transaction.should be_instance_of(GMoney::Transaction)
|
@@ -19,7 +18,7 @@ describe GMoney::TransactionFeedParser do
|
|
19
18
|
it "should create Transaction objects with valid numeric data types" do
|
20
19
|
@transactions.each do |transaction|
|
21
20
|
transaction.public_methods(false).each do |pm|
|
22
|
-
if
|
21
|
+
if (['shares', 'commission', 'price'].include? pm) && !(pm.include?('='))
|
23
22
|
return_val = transaction.send(pm)
|
24
23
|
return_val.should be_instance_of(Float) if return_val
|
25
24
|
end
|
data/spec/transaction_spec.rb
CHANGED
@@ -41,7 +41,49 @@ describe GMoney::Transaction do
|
|
41
41
|
|
42
42
|
transaction.commission.should be_eql(50.0)
|
43
43
|
transaction.price.should be_eql(400.0)
|
44
|
-
end
|
44
|
+
end
|
45
|
+
|
46
|
+
it "should delete transactions using a class method and id" do
|
47
|
+
@gf_request = GMoney::GFRequest.new("#{@url}/24")
|
48
|
+
@gf_request.method = :post
|
49
|
+
|
50
|
+
@gf_response = GMoney::GFResponse.new
|
51
|
+
@gf_response.status_code = 200
|
52
|
+
|
53
|
+
transaction_delete_helper("#{@url}/24")
|
54
|
+
|
55
|
+
GMoney::Transaction.delete('9/NASDAQ:GOOG/24').should be_nil
|
56
|
+
end
|
57
|
+
|
58
|
+
it "should delete transactions when calling destroy on an instance of a transaction" do
|
59
|
+
@gf_request = GMoney::GFRequest.new("#{@url}/21")
|
60
|
+
@gf_request.method = :post
|
61
|
+
|
62
|
+
@gf_response = GMoney::GFResponse.new
|
63
|
+
@gf_response.status_code = 200
|
64
|
+
|
65
|
+
transaction = GMoney::Transaction.new
|
66
|
+
transaction.instance_variable_set("@id", "#{@url}/21")
|
67
|
+
|
68
|
+
transaction_delete_helper("#{@url}/21")
|
69
|
+
|
70
|
+
transaction_return = transaction.destroy
|
71
|
+
transaction_return.should be_eql(transaction)
|
72
|
+
transaction_return.frozen?.should be_true
|
73
|
+
end
|
74
|
+
|
75
|
+
it "should raise a TransactionDeleteError when there is an attempt to delete a transaction from a portfolio that doesn't exist')" do
|
76
|
+
@gf_request = GMoney::GFRequest.new("#{@url}/24")
|
77
|
+
@gf_request.method = :post
|
78
|
+
|
79
|
+
@gf_response = GMoney::GFResponse.new
|
80
|
+
@gf_response.status_code = 400
|
81
|
+
@gf_request.body = "Invalid Portfolio"
|
82
|
+
|
83
|
+
transaction_delete_helper("#{@url}/24")
|
84
|
+
|
85
|
+
lambda { GMoney::Transaction.delete("9/NASDAQ:GOOG/24") }.should raise_error(GMoney::Transaction::TransactionDeleteError, @gf_response.body)
|
86
|
+
end
|
45
87
|
|
46
88
|
def transaction_helper(id, options={})
|
47
89
|
GMoney::GFSession.should_receive(:auth_token).and_return('toke')
|
@@ -54,4 +96,12 @@ describe GMoney::Transaction do
|
|
54
96
|
|
55
97
|
GMoney::Transaction.find(id, options)
|
56
98
|
end
|
99
|
+
|
100
|
+
def transaction_delete_helper(url)
|
101
|
+
GMoney::GFSession.should_receive(:auth_token).and_return('toke')
|
102
|
+
|
103
|
+
GMoney::GFRequest.should_receive(:new).with(url, :method => :post, :headers => {"Authorization" => "GoogleLogin auth=toke", "X-HTTP-Method-Override" => "DELETE"}).and_return(@gf_request)
|
104
|
+
|
105
|
+
GMoney::GFService.should_receive(:send_request).with(@gf_request).and_return(@gf_response)
|
106
|
+
end
|
57
107
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: gmoney
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Justin Spradlin
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2009-
|
12
|
+
date: 2009-11-13 00:00:00 -05:00
|
13
13
|
default_executable:
|
14
14
|
dependencies: []
|
15
15
|
|