gmoney 0.4.0 → 0.4.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -9,7 +9,7 @@ A gem for interacting with the Google Finance API
9
9
  == Usage
10
10
 
11
11
  Login
12
- -----
12
+ --------
13
13
 
14
14
  GMoney::GFSession.login('google username', 'password')
15
15
 
@@ -17,7 +17,7 @@ Portfolios
17
17
  --------
18
18
 
19
19
  Reading
20
- > portfolios = GMoney::Portfolio.all #returns all of a users portfolios
20
+ > portfolios = GMoney::Portfolio.all #returns all of a user's portfolios
21
21
  > portfolio = GMoney::Portfolio.find(9) #returns a specific portfolio
22
22
 
23
23
  > positions = portfolio.positions #returns an Array of the Positions held within a given portfolio
@@ -45,7 +45,7 @@ Positions
45
45
  --------
46
46
 
47
47
  Reading
48
- > positions = GMoney::Position.find(9) #returns all of a users positions within a given portfolio, i.e. Portfolio "9"
48
+ > positions = GMoney::Position.find(9) #returns all of a user's positions within a given portfolio, i.e. Portfolio "9"
49
49
  > position = GMoney::Position.find("9/NASDAQ:GOOG") #returns a specific position within a given portfolio
50
50
 
51
51
  > transactions = position.transactions #returns an Array of the Transactions within a given position
@@ -66,14 +66,14 @@ Transactions
66
66
  --------
67
67
 
68
68
  Reading
69
- > transactions = GMoney::Transaction.find("9/NASDAQ:GOOG") #returns all of a users transactions within a given position
69
+ > transactions = GMoney::Transaction.find("9/NASDAQ:GOOG") #returns all of a user's transactions within a given position
70
70
  > transaction = GMoney::Transaction.find("9/NASDAQ:GOOG/2") #returns a specific transaction within a given position
71
71
 
72
72
  Creating
73
73
  > transaction = GMoney::Transaction.new
74
- > transaction.portfolio = 9 #Must be a valid portfolio id
75
- > transaction.ticker = 'nyse:c' #Must be a valid ticker symbol
76
- > transaction.type = 'Buy' #Must be one of the following: Buy, Sell, Sell Short, Buy to Cover
74
+ > transaction.portfolio = 9 #Must be a valid portfolio id
75
+ > transaction.ticker = 'nyse:c' #Must be a valid ticker symbol
76
+ > transaction.type = GMoney::BUY #Must be one of the following: Buy, Sell, Sell Short, Buy to Cover
77
77
  > transaction.save #returns transaction object
78
78
 
79
79
  Updating
@@ -90,7 +90,7 @@ Transactions
90
90
  > transaction = GMoney::Transaction.find '2/NASDAQ:GOOG/1'
91
91
  > transaction.delete #call delete on an instance of a transaction
92
92
 
93
- ----------
93
+ --------
94
94
 
95
95
  Options parameter
96
96
 
@@ -111,14 +111,14 @@ Options parameter
111
111
  * :refresh - GMoney caches the data returned from Google by default. Set :refresh => true if you would like to get the latest data.
112
112
  * :eager - GMoney lazily loads children data (i.e. positions for a given Portfolio). If you would like to load all of this data at once set :eager => true
113
113
 
114
- ----------
114
+ --------
115
115
  There are still some rough edges. Feedback is appreciated.
116
116
 
117
117
  == License
118
118
 
119
119
  (The MIT License)
120
120
 
121
- Copyright (c) 2009 Justin Spradlin
121
+ Copyright (c) 2010 Justin Spradlin
122
122
 
123
123
  Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the 'Software'), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
124
124
 
@@ -2,11 +2,11 @@
2
2
 
3
3
  Gem::Specification.new do |s|
4
4
  s.name = %q{gmoney}
5
- s.version = "0.4.0"
5
+ s.version = "0.4.2"
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-11-17}
9
+ s.date = %q{2010-01-30}
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/nil_class.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"]
@@ -15,7 +15,7 @@ Gem::Specification.new do |s|
15
15
  s.rdoc_options = ["--line-numbers", "--inline-source", "--title", "Gmoney", "--main", "README.rdoc"]
16
16
  s.require_paths = ["lib"]
17
17
  s.rubyforge_project = %q{gmoney}
18
- s.rubygems_version = %q{1.3.4}
18
+ s.rubygems_version = %q{1.3.5}
19
19
  s.summary = %q{A gem for interacting with the Google Finance API}
20
20
 
21
21
  if s.respond_to? :specification_version then
@@ -1,6 +1,6 @@
1
1
  # Justin Spradlin
2
2
  # www.fiascode.com
3
- # (C) 2009
3
+ # (C) 2010
4
4
 
5
5
 
6
6
  $:.unshift File.expand_path(File.dirname(__FILE__))
@@ -28,7 +28,7 @@ require 'gmoney/transaction'
28
28
  require 'gmoney/transaction_feed_parser'
29
29
 
30
30
  module GMoney
31
- VERSION = '0.4.0'
31
+ VERSION = '0.4.2'
32
32
  GF_URL = "https://finance.google.com/finance"
33
33
  GF_FEED_URL = "#{GF_URL}/feeds/default"
34
34
  GF_PORTFOLIO_FEED_URL = "#{GF_FEED_URL}/portfolios"
@@ -36,6 +36,12 @@ module GMoney
36
36
  HTTPOK = 200
37
37
  HTTPCreated = 201
38
38
 
39
+ BUY = 'Buy'
40
+ SELL = 'Sell'
41
+ SELL_SHORT = 'Sell Short'
42
+ BUY_TO_COVER = 'Buy to Cover'
43
+
44
+
39
45
  def self.version
40
46
  VERSION
41
47
  end
@@ -10,6 +10,10 @@ module GMoney
10
10
  :return_ytd, :return1y, :return3y, :return5y, :return_overall,
11
11
  :cost_basis, :days_gain, :gain, :market_value
12
12
 
13
+ def pid
14
+ @id.portfolio_feed_id
15
+ end
16
+
13
17
  def self.all(options = {})
14
18
  retreive_portfolios(:all, options)
15
19
  end
@@ -20,9 +24,9 @@ module GMoney
20
24
 
21
25
  def positions(options = {})
22
26
  if options[:refresh]
23
- @positions = Position.find(@id.portfolio_feed_id, options)
27
+ @positions = Position.find(pid, options)
24
28
  else
25
- @positions ||= Position.find(@id.portfolio_feed_id, options)
29
+ @positions ||= Position.find(pid, options)
26
30
  end
27
31
 
28
32
  @positions.is_a?(Array) ? @positions : [@positions]
@@ -37,7 +41,7 @@ module GMoney
37
41
  end
38
42
 
39
43
  def delete
40
- Portfolio.delete(@id.portfolio_feed_id)
44
+ Portfolio.delete(pid)
41
45
  freeze
42
46
  end
43
47
 
@@ -7,6 +7,10 @@ module GMoney
7
7
  :full_name, :gain_percentage, :return1w, :return4w, :return3m,
8
8
  :return_ytd, :return1y, :return3y, :return5y, :return_overall,
9
9
  :cost_basis, :days_gain, :gain, :market_value
10
+
11
+ def pid
12
+ @id.position_feed_id
13
+ end
10
14
 
11
15
  def self.find(id, options={})
12
16
  find_by_url("#{GF_PORTFOLIO_FEED_URL}/#{id.portfolio_id}/positions/#{id.position_id}", options)
@@ -14,9 +18,9 @@ module GMoney
14
18
 
15
19
  def transactions(options={})
16
20
  if options[:refresh]
17
- @transactions = Transaction.find(@id.position_feed_id, options)
21
+ @transactions = Transaction.find(pid, options)
18
22
  else
19
- @transactions ||= Transaction.find(@id.position_feed_id, options)
23
+ @transactions ||= Transaction.find(pid, options)
20
24
  end
21
25
 
22
26
  @transactions.is_a?(Array) ? @transactions : [@transactions]
@@ -27,7 +31,7 @@ module GMoney
27
31
  end
28
32
 
29
33
  def delete
30
- Position.delete(@id.position_feed_id)
34
+ Position.delete(pid)
31
35
  freeze
32
36
  end
33
37
 
@@ -3,10 +3,41 @@ module GMoney
3
3
  class TransactionRequestError < StandardError; end
4
4
  class TransactionDeleteError < StandardError;end
5
5
  class TransactionSaveError < StandardError;end
6
+ class TransactionIdError < StandardError;end
6
7
 
7
8
  attr_reader :id, :updated, :title
8
9
  attr_accessor :type, :date, :shares, :notes, :commission, :price, :portfolio, :ticker, :currency_code
9
10
 
11
+ def tid
12
+ @id.transaction_feed_id
13
+ end
14
+
15
+ def portfolio
16
+ if @id
17
+ @portfolio = tid.portfolio_id
18
+ else
19
+ @portfolio
20
+ end
21
+ end
22
+
23
+ def ticker
24
+ if @id
25
+ @ticker = tid.position_id
26
+ else
27
+ @ticker
28
+ end
29
+ end
30
+
31
+ def portfolio=(p)
32
+ raise TransactionIdError, "You can't modify the portfolio for a Transaction that already has an id" if @id
33
+ @portfolio = p
34
+ end
35
+
36
+ def ticker=(t)
37
+ raise TransactionIdError, "You can't modify the ticker for a Transaction that already has an id" if @id
38
+ @ticker = t
39
+ end
40
+
10
41
  def self.find(id, options={})
11
42
  find_by_url("#{GF_PORTFOLIO_FEED_URL}/#{id.portfolio_id}/positions/#{id.position_id}/transactions/#{id.transaction_id}", options)
12
43
  end
@@ -20,7 +51,7 @@ module GMoney
20
51
  end
21
52
 
22
53
  def delete
23
- Transaction.delete(@id.transaction_feed_id)
54
+ Transaction.delete(tid)
24
55
  freeze
25
56
  end
26
57
 
@@ -80,7 +111,6 @@ module GMoney
80
111
  if response.status_code == HTTPCreated || response.status_code == HTTPOK
81
112
  transaction = TransactionFeedParser.parse_transaction_feed(response.body)[0]
82
113
  self.instance_variable_set("@id", transaction.id) if response.status_code == HTTPCreated
83
- transaction.portfolio = @portfolio if response.status_code == HTTPCreated
84
114
  else
85
115
  raise TransactionSaveError, response.body
86
116
  end
@@ -88,11 +118,11 @@ module GMoney
88
118
  end
89
119
 
90
120
  def is_valid_transaction?
91
- !(@portfolio.to_s.blank? || @ticker.blank? || !is_valid_transaction_type?)
121
+ !(portfolio.to_s.blank? || ticker.blank? || !is_valid_transaction_type?)
92
122
  end
93
123
 
94
124
  def is_valid_transaction_type?
95
- ['Buy', 'Sell', 'Buy to Cover', 'Sell Short'].include?(@type)
125
+ [BUY, SELL, SELL_SHORT, BUY_TO_COVER].include?(@type)
96
126
  end
97
127
 
98
128
  private :save_transaction, :is_valid_transaction?, :is_valid_transaction_type?
@@ -20,7 +20,17 @@ describe GMoney::Portfolio do
20
20
  @gf_response.status_code = 200
21
21
  @gf_response.body = @default_feed
22
22
  @positions = nil
23
- end
23
+ end
24
+
25
+ it "should have return a human readable (i.e. non-url) portfolio id" do
26
+ @gf_response.body = @default_feed
27
+
28
+ portfolios = portfolio_helper(@url)
29
+
30
+ portfolios[0].pid.should be_eql("8")
31
+ portfolios[1].pid.should be_eql("9")
32
+ portfolios[2].pid.should be_eql("3")
33
+ end
24
34
 
25
35
  it "should return all Portfolios when status_code is 200" do
26
36
  @gf_response.body = @default_feed
@@ -20,6 +20,16 @@ describe GMoney::Position do
20
20
  @gf_response.body = @defaul_feed
21
21
  @transactions = []
22
22
  end
23
+
24
+ it "should have return a human readable (i.e. non-url) position id" do
25
+ @gf_response.body = @feed_with_returns
26
+
27
+ positions = position_helper(@portfolio_id, {:returns => true})
28
+
29
+ positions[0].pid.should be_eql("9/NASDAQ:JAVA")
30
+ positions[1].pid.should be_eql("9/NASDAQ:GOOG")
31
+ positions[2].pid.should be_eql("9/NASDAQ:AAPL")
32
+ end
23
33
 
24
34
  it "should return all Positions when status_code is 200" do
25
35
  @gf_response.body = @default_feed
@@ -19,6 +19,55 @@ describe GMoney::Transaction do
19
19
  @gf_response.body = @goog_feed
20
20
  end
21
21
 
22
+ it "should have return a human readable (i.e. non-url) transaction id" do
23
+ transactions = transaction_helper(@transaction_id)
24
+ transactions[0].tid.should be_eql("9/NASDAQ:GOOG/2")
25
+ transactions[1].tid.should be_eql("9/NASDAQ:GOOG/10")
26
+ end
27
+
28
+ it "should return the portfolio id when it is set or infer the portfolio id from the transaction id when the portfolio id is not set" do
29
+ transaction = GMoney::Transaction.new
30
+ transaction.portfolio.should be_nil
31
+
32
+ transaction.portfolio = '18'
33
+ transaction.portfolio.should be_eql('18')
34
+
35
+ transaction.instance_variable_set("@id", "http://finance.google.com/finance/feeds/user@example.com/portfolios/9/positions/NASDAQ:GOOG/transactions/12")
36
+ transaction.portfolio.should be_eql('9')
37
+
38
+ transaction = GMoney::Transaction.new
39
+ transaction.instance_variable_set("@id", "http://finance.google.com/finance/feeds/user@example.com/portfolios/9/positions/NASDAQ:GOOG/transactions/12")
40
+ transaction.portfolio.should be_eql('9')
41
+ end
42
+
43
+ it "should return the ticker id when it is set or infer the ticker id from the transaction id when the ticker id is not set" do
44
+ transaction = GMoney::Transaction.new
45
+ transaction.ticker.should be_nil
46
+
47
+ transaction.ticker = 'NASDAQ:AAPL'
48
+ transaction.ticker.should be_eql('NASDAQ:AAPL')
49
+
50
+ transaction.instance_variable_set("@id", "http://finance.google.com/finance/feeds/user@example.com/portfolios/9/positions/NASDAQ:GOOG/transactions/12")
51
+ transaction.ticker.should be_eql('NASDAQ:GOOG')
52
+
53
+ transaction = GMoney::Transaction.new
54
+ transaction.instance_variable_set("@id", "http://finance.google.com/finance/feeds/user@example.com/portfolios/9/positions/NASDAQ:GOOG/transactions/12")
55
+ transaction.ticker.should be_eql('NASDAQ:GOOG')
56
+ end
57
+
58
+ it "should not allow users to set a portfolio on a transaction for transactions that have already been saved" do
59
+ transaction = GMoney::Transaction.new
60
+ transaction.instance_variable_set("@id", "http://finance.google.com/finance/feeds/user@example.com/portfolios/9/positions/NASDAQ:GOOG/transactions/12")
61
+
62
+ lambda { transaction.portfolio = 10 }.should raise_error(GMoney::Transaction::TransactionIdError, "You can't modify the portfolio for a Transaction that already has an id")
63
+ end
64
+
65
+ it "should not allow users to set a portfolio on a transaction for transactions that have already been saved" do
66
+ transaction = GMoney::Transaction.new
67
+ transaction.instance_variable_set("@id", "http://finance.google.com/finance/feeds/user@example.com/portfolios/9/positions/NASDAQ:GOOG/transactions/12")
68
+ lambda { transaction.ticker = "NASDAQ::AAPL" }.should raise_error(GMoney::Transaction::TransactionIdError, "You can't modify the ticker for a Transaction that already has an id")
69
+ end
70
+
22
71
  it "should return all Tranasactions when the status code is 200" do
23
72
  transactions = transaction_helper(@transaction_id)
24
73
 
@@ -96,10 +145,10 @@ describe GMoney::Transaction do
96
145
 
97
146
  trans.portfolio = 1
98
147
  trans.ticker = "NYSE:GLD"
99
- trans.type = 'Buy'
148
+ trans.type = GMoney::BUY
100
149
  trans.public_is_valid_transaction?.should be_true
101
150
 
102
- trans.type = 'Sell'
151
+ trans.type = GMoney::SELL
103
152
  trans.public_is_valid_transaction?.should be_true
104
153
 
105
154
  trans.type = 'Buy to Cover'
@@ -120,12 +169,12 @@ describe GMoney::Transaction do
120
169
 
121
170
  trans.portfolio = 1
122
171
  trans.ticker = " "
123
- trans.type = 'Buy'
172
+ trans.type = GMoney::BUY
124
173
  trans.public_is_valid_transaction?.should be_false
125
174
 
126
175
  trans.portfolio = " "
127
176
  trans.ticker = "NYSE:GLD"
128
- trans.type = 'Buy'
177
+ trans.type = GMoney::BUY
129
178
  trans.public_is_valid_transaction?.should be_false
130
179
 
131
180
  trans.portfolio = nil
@@ -135,12 +184,12 @@ describe GMoney::Transaction do
135
184
 
136
185
  trans.portfolio = nil
137
186
  trans.ticker = "NYSE:GLD"
138
- trans.type = 'Buy'
187
+ trans.type = GMoney::BUY
139
188
  trans.public_is_valid_transaction?.should be_false
140
189
 
141
190
  trans.portfolio = "1"
142
191
  trans.ticker = nil
143
- trans.type = 'Buy'
192
+ trans.type = GMoney::BUY
144
193
  trans.public_is_valid_transaction?.should be_false
145
194
  end
146
195
 
@@ -148,7 +197,7 @@ describe GMoney::Transaction do
148
197
  transaction = GMoney::Transaction.new
149
198
  transaction.portfolio = 9
150
199
  transaction.ticker = 'NASDAQ:GOOG'
151
- transaction.type = 'Buy'
200
+ transaction.type = GMoney::BUY
152
201
  transaction.shares = 50
153
202
  transaction.price = 450.0
154
203
  transaction.commission = 20.0
@@ -171,7 +220,7 @@ describe GMoney::Transaction do
171
220
  transaction = GMoney::Transaction.new
172
221
  transaction.portfolio = 9
173
222
  transaction.ticker = 'NASDAQ:GOOG'
174
- transaction.type = 'Buy'
223
+ transaction.type = GMoney::BUY
175
224
  transaction.shares = 50
176
225
  transaction.price = 450.0
177
226
  transaction.commission = 20.0
@@ -192,12 +241,12 @@ describe GMoney::Transaction do
192
241
  lambda { transaction.save }.should raise_error(GMoney::Transaction::TransactionSaveError, "You must include a portfolio id, ticker symbol, and transaction type ['Buy', 'Sell', 'Buy to Cover', 'Sell Short'] in order to create a transaction.")
193
242
 
194
243
  transaction.portfolio = 9
195
- transaction.type = 'Buy'
244
+ transaction.type = GMoney::BUY
196
245
  lambda { transaction.save }.should raise_error(GMoney::Transaction::TransactionSaveError, "You must include a portfolio id, ticker symbol, and transaction type ['Buy', 'Sell', 'Buy to Cover', 'Sell Short'] in order to create a transaction.")
197
246
 
198
247
  transaction.portfolio = nil
199
248
  transaction.ticker = 'NASDAQ:GOOG'
200
- transaction.type = 'Buy'
249
+ transaction.type = GMoney::BUY
201
250
  lambda { transaction.save }.should raise_error(GMoney::Transaction::TransactionSaveError, "You must include a portfolio id, ticker symbol, and transaction type ['Buy', 'Sell', 'Buy to Cover', 'Sell Short'] in order to create a transaction.")
202
251
  end
203
252
 
@@ -205,7 +254,7 @@ describe GMoney::Transaction do
205
254
  transaction = GMoney::Transaction.new
206
255
  transaction.portfolio = 9
207
256
  transaction.ticker = 'asdfasd:asdfs' #invalid ticker
208
- transaction.type = 'Buy'
257
+ transaction.type = GMoney::BUY
209
258
  transaction.shares = 50
210
259
  transaction.price = 450.0
211
260
  transaction.commission = 20.0
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.0
4
+ version: 0.4.2
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-11-17 00:00:00 -05:00
12
+ date: 2010-01-30 00:00:00 -05:00
13
13
  default_executable:
14
14
  dependencies: []
15
15
 
@@ -117,7 +117,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
117
117
  requirements: []
118
118
 
119
119
  rubyforge_project: gmoney
120
- rubygems_version: 1.3.4
120
+ rubygems_version: 1.3.5
121
121
  signing_key:
122
122
  specification_version: 3
123
123
  summary: A gem for interacting with the Google Finance API