securities 1.0.0 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
data/.DS_Store ADDED
Binary file
data/.travis.yml CHANGED
@@ -1,6 +1,4 @@
1
1
  rvm:
2
2
  - 1.9.3
3
3
  - 1.9.2
4
- - jruby
5
- - rbx
6
4
  script: "bundle exec rake"
data/Gemfile CHANGED
@@ -2,3 +2,7 @@ source 'https://rubygems.org'
2
2
 
3
3
  # Specify your gem's dependencies in securities.gemspec
4
4
  gemspec
5
+ gem 'guard'
6
+ gem 'guard-rspec'
7
+ gem 'guard-bundler'
8
+ gem 'growl'
data/Guardfile ADDED
@@ -0,0 +1,10 @@
1
+ guard 'bundler' do
2
+ watch('Gemfile')
3
+ watch(/^.+\.gemspec/)
4
+ end
5
+
6
+ guard 'rspec', :version => 2 do
7
+ watch(%r{^spec/.+_spec\.rb$})
8
+ watch(%r{^lib/(.+)\.rb$}) { |m| "spec/#{m[1]}_spec.rb" }
9
+ watch('spec/spec_helper.rb') { "spec" }
10
+ end
data/README.md CHANGED
@@ -23,83 +23,70 @@ Or install it yourself as:
23
23
 
24
24
  You can get stock information with commands:
25
25
 
26
- # Comma seperated symbols
27
- my_stocks = Securities::Stock.new('aapl', 'yhoo')
28
-
29
- or
30
-
31
- # Symbol array
32
- my_stocks = Securities::Stock.new(["aapl", "yhoo"])
33
-
34
- my_data = my_stocks.history(:start_date => '2012-01-01', :end_date => '2012-02-01', :periods => :weekly)
26
+ my_stocks = Securities::Stock.new(:symbol => 'AAPL', :start_date => '2012-01-01', :end_date => '2012-02-01', :type => :weekly)
35
27
 
36
- Optional parameter :periods accepts :daily, :weekly, :monthly, :dividend. If not specified, it defaults to :daily.
28
+ Optional parameter :type accepts :daily, :weekly, :monthly, :dividend. If not specified, it defaults to :daily.
37
29
 
38
30
  :end_date defaults to Date.today if not specified.
39
31
 
40
32
  You can access hash for a single stock with:
41
33
 
42
- my_data["yhoo"]
43
-
44
- or my_stocks.output["yhoo"]
34
+ my_stocks.output
35
+ my_stocks.symbol
36
+ my_stocks.start_date
37
+ my_stocks.end_date
38
+ my_stocks.type
45
39
 
46
40
  Output is returned in a hash:
47
41
 
48
- {"aapl"=>
49
- [{:date=>"2012-01-04",
50
- :open=>"410.00",
51
- :high=>"414.68",
52
- :low=>"409.28",
53
- :close=>"413.44",
54
- :volume=>"9286500",
55
- :adj_close=>"411.67"},
56
- {:date=>"2012-01-03",
42
+ [{:date=>"2012-01-03",
57
43
  :open=>"409.40",
58
44
  :high=>"412.50",
59
45
  :low=>"409.00",
60
46
  :close=>"411.23",
61
47
  :volume=>"10793600",
62
- :adj_close=>"409.47"}],
63
- "yhoo"=>
64
- [{:date=>"2012-01-04",
65
- :open=>"16.12",
66
- :high=>"16.16",
67
- :low=>"15.74",
68
- :close=>"15.78",
69
- :volume=>"35655300",
70
- :adj_close=>"15.78"},
71
- {:date=>"2012-01-03",
72
- :open=>"16.27",
73
- :high=>"16.39",
74
- :low=>"16.20",
75
- :close=>"16.29",
76
- :volume=>"19708600",
77
- :adj_close=>"16.29"}]}
78
-
79
- # Version 1.0.0
80
-
81
- Results are returned in a reversed manner from 0.1.2. Array begins from the oldest data points.
82
-
83
- Only Stock class initializes an object so you can do:
84
-
85
- my_stocks = Securities::Stock.new(["aapl", "yhoo"])
86
- my_stocks.history(:start_date => '2012-01-01', :end_date => '2012-02-01', :periods => :weekly)
87
- ^ adds @ouput variable to the my_stocks object. ^
88
-
89
- And get output with:
90
- my_stocks.output or my_stocks.output["aapl"]
91
-
92
- Given symbols, dates and periods with:
93
- my_stocks.symbols
94
- my_stocks.start_date
95
- my_stocks.end_date
96
- my_stocks.periods
48
+ :adj_close=>"409.47"},
49
+ {:date=>"2012-01-04",
50
+ :open=>"410.00",
51
+ :high=>"414.68",
52
+ :low=>"409.28",
53
+ :close=>"413.44",
54
+ :volume=>"9286500",
55
+ :adj_close=>"411.67"}]
56
+
57
+ Stock symbol lookup:
58
+
59
+ my_lookup = Securities::Lookup.new('Google')
60
+
61
+ Returns a hash with matched symbol, name, last trade, type, industry/category, exchange.
62
+
63
+ my_lookup.output
64
+
65
+ [{:symbol=>"GOOG",
66
+ :name=>"Google Inc.",
67
+ :last_trade=>"726.31",
68
+ :type=>"Stock",
69
+ :industry_category=>"Internet Information Providers",
70
+ :exchange=>"NMS"},
71
+ {:symbol=>"GOOG.MX",
72
+ :name=>"Google Inc.",
73
+ :last_trade=>"9,306.00",
74
+ :type=>"Stock",
75
+ :industry_category=>"Internet Information Providers",
76
+ :exchange=>"MEX"},
77
+ ...]
78
+
79
+ my_lookup.input returns 'Google'
80
+
81
+ # Version 2.0.0
82
+
83
+ * Adds support for stock symbol lookup.
84
+
85
+ * Removes support for multiple stock input cause it complects the gem code and its implementation without adding much to it.
97
86
 
98
87
  ## To do:
99
88
 
100
- * Write specs.
101
89
  * Add quote info (P/E, P/S, etc.)
102
- * Add symbol from name lookup.
103
90
  * Add options support.
104
91
 
105
92
  ## Contributing
data/lib/securities.rb CHANGED
@@ -1,5 +1,6 @@
1
1
  require "securities/version"
2
2
  require "securities/scraper"
3
+ require "securities/lookup"
3
4
  require "securities/stock"
4
5
 
5
6
  module Securities
@@ -0,0 +1,29 @@
1
+ module Securities
2
+ #
3
+ # Symbol lookup with Securities::Lookup.new('apple')
4
+ #
5
+ class Lookup
6
+
7
+ attr_accessor :input, :output
8
+ # Error handling
9
+ class LookupException < StandardError ; end
10
+
11
+ def initialize parameters
12
+ @input = parameters.delete(' ')
13
+ if @input.empty?
14
+ raise LookupException, 'The lookup input was empty.'
15
+ end
16
+ url = generate_lookup_url
17
+ request = :lookup
18
+ @output = Securities::Scraper.get(request, url)
19
+ end
20
+
21
+ private
22
+
23
+ def generate_lookup_url
24
+ url = 'http://finance.yahoo.com/lookup?s=' + @input
25
+ return url
26
+ end
27
+ end
28
+
29
+ end
@@ -2,6 +2,7 @@ require 'active_support/core_ext'
2
2
  require 'uri'
3
3
  require 'net/http'
4
4
  require 'csv'
5
+ require 'nokogiri'
5
6
 
6
7
  module Securities
7
8
  #
@@ -10,64 +11,73 @@ module Securities
10
11
  class Scraper
11
12
 
12
13
  # Error handling
13
- class ScraperException < StandardError
14
- end
14
+ class ScraperException < StandardError ; end
15
15
 
16
- def self.get type, parameters
16
+ def self.get type, url
17
+ results = Array.new
18
+
19
+ # Encoding for bad characters in index names.
20
+ clean_url = URI::encode(url)
21
+ uri = URI.parse(clean_url)
17
22
 
18
- # Manage different type requests.
19
- case type
20
- when :history then results = scrape_history(parameters)
21
- else raise ScraperException, 'Cannot determine request type.'
23
+ # Check connection.
24
+ begin
25
+ get = Net::HTTP.get(uri)
26
+ rescue => error
27
+ raise ScraperException, "Connection error: #{error.message}"
22
28
  end
23
29
 
24
- return results
25
- end
26
-
27
- def self.scrape_history parameters
28
- results = Hash.new
29
- parameters.each do |symbol, url|
30
+ case type
31
+ #
32
+ # Scraping for lookup.
33
+ when :lookup
34
+ doc = Nokogiri::HTML(get)
30
35
 
31
- uri = URI.parse(url)
36
+ table = doc.at('div#yfi_sym_results tbody')
32
37
 
33
- # Check connection
34
- begin
35
- get = Net::HTTP.get(uri)
36
- rescue => error
37
- raise ScraperException, "Connection error: #{error.message}"
38
+ if table.nil?
39
+ raise ScraperException, 'There were no results for this lookup.'
38
40
  end
39
41
 
40
- # Skip first line because it contains headers with Date,Open,High,Low,Close,Volume,Adj Close
42
+ # Symbol Name Last Trade Type Industry/Category Exchange
43
+ table.xpath('tr').each do |tr|
44
+ row = tr.xpath('td')
45
+ results << {:symbol => row[0].text,
46
+ :name => row[1].text,
47
+ :last_trade => row[2].text,
48
+ :type => row[3].text,
49
+ :industry_category => row[4].text,
50
+ :exchange => row[5].text}
51
+ end
52
+ #
53
+ # Scraping for history
54
+ when :history
55
+ # Skip first line because it contains headers with Date,Open,High,Low,Close,Volume,Adj Close.
41
56
  # Check for errors during CSV parsing.
42
57
  begin
43
58
  csv = CSV.parse(get, :headers => true)
44
59
  rescue => error
45
- # PROBABLY an invalid symbol specified or there was some other way the parser couldn't read a CSV.
46
- # It will no longer raise exception because it causes a bug.
47
- # bug => if exception occurs in one symbol, it will not give any results for any other.
48
- # raise ScraperException, "Invalid symbol '#{symbol}' specified."
49
- results[symbol] = []
50
- next
60
+ # Probably an invalid symbol specified or there was some other way the parser couldn't read a CSV.
61
+ raise ScraperException, 'Stock symbol does not exist.'
51
62
  end
52
63
 
53
- data = Array.new
54
64
  csv.each_with_index do |row, index|
55
65
  line = Hash.new
56
66
  csv.headers.each_with_index do |header, i|
57
- # Set headers as keys for data hash.
67
+ # Set headers as keys for the data hash.
58
68
  line[header.parameterize.underscore.to_sym] = row[i]
59
- data[index] = line
69
+ results[index] = line
60
70
  end
61
71
  end
62
72
 
63
- # It will no longer raise exception if data is empty, because it causes a
64
- # bug => if exception occurs in one symbol, it will not give any results for any other.
65
- # if data.empty?
66
- # raise ScraperException, "There were no results for #{symbol}."
67
- # end
73
+ if results.empty?
74
+ raise ScraperException, 'There were no results for this symbol.'
75
+ end
68
76
 
69
- results[symbol] = data.reverse
77
+ # Reversing results to return from the oldest to the newest.
78
+ results = results.reverse
70
79
  end
80
+
71
81
  return results
72
82
  end
73
83
 
@@ -1,160 +1,120 @@
1
1
  module Securities
2
2
 
3
- # Usage: my_stocks = Securities::Stock.new('aapl', 'yhoo').history(:start_date => '2012-01-01', :end_date => '2012-02-01', :periods => :weekly)
4
- # :periods accepts :daily, :weekly, :monthly, :dividend. If not specified, it defaults to :daily.
5
- #
6
- # You can access hash for a single stock with:
7
- # my_stocks["yhoo"]
8
-
9
3
  class Stock
10
4
 
11
- attr_accessor :symbols, :output, :start_date, :end_date, :periods
5
+ attr_accessor :symbol, :output, :start_date, :end_date, :type
12
6
  # REGEX for YYYY-MM-DD
13
7
  DATE_REGEX = /^[0-9]{4}\-(0[1-9]|1[012])\-(0[1-9]|[12][0-9]|3[01])/
14
- PERIODS_ARRAY = [:daily, :weekly, :monthly, :dividends]
8
+ TYPE_CODES_ARRAY = {:daily => 'd', :weekly => 'w', :monthly => 'm', :dividends => 'v'}
15
9
 
16
10
  # Error handling
17
- class StockException < StandardError
18
- end
19
-
20
- def initialize *parameters
21
- validate_symbols(parameters)
22
- end
11
+ class StockException < StandardError ; end
23
12
 
24
- def history parameters
25
- type = :history
26
- parameters[:symbols] = @symbols
27
- validate_history(parameters)
28
- urls = generate_history_url(parameters)
13
+ def initialize parameters
14
+ validate_input(parameters)
15
+ @symbol = parameters[:symbol]
29
16
  @start_date = parameters[:start_date]
30
17
  @end_date = parameters[:end_date]
31
- @periods = parameters[:periods]
32
- @output = Securities::Scraper.get(type, urls)
18
+ @type = parameters[:type]
19
+ url = generate_history_url
20
+ request = :history
21
+ @output = Securities::Scraper.get(request, url)
33
22
  end
34
23
 
35
24
  private
36
25
 
37
- #
38
- # History URL generator
39
- #
40
- # Generating URL for various types of requests within stocks.
41
- #
42
- # Using Yahoo Finance
43
- # http://ichart.finance.yahoo.com/table.csv?s=%s&a=%s&b=%s&c=%s&d=%s&e=%s&f=%s&g=%s&ignore=.csv
44
- #
45
- # s = ticker symbol.
46
- #
47
- # Start date
48
- # a = start_month
49
- # b = start_day
50
- # c = start_year
51
- #
52
- # End date
53
- # d = end_month
54
- # e = end_day
55
- # f = end_year
56
- #
57
- # g = :periods
58
- # Possible values are 'd' for daily (the default), 'w' for weekly, 'm' for monthly and 'v' for dividends.
59
-
60
- def generate_history_url parameters
61
-
62
- start_date = parameters[:start_date].to_date
63
- end_date = parameters[:end_date].to_date
64
-
65
- periods = case parameters[:periods]
66
- when :daily then 'd'
67
- when :weekly then 'w'
68
- when :monthly then 'm'
69
- when :dividends then 'v'
70
- end
71
-
72
- results = Hash.new
73
- @symbols.each do |symbol|
26
+ #
27
+ # History URL generator
28
+ #
29
+ # Generating URL for various types of requests within stocks.
30
+ #
31
+ # Using Yahoo Finance
32
+ # http://ichart.finance.yahoo.com/table.csv?s=%s&a=%s&b=%s&c=%s&d=%s&e=%s&f=%s&g=%s&ignore=.csv
33
+ #
34
+ # s = stock symbol
35
+ #
36
+ # Period start date
37
+ # a = start month
38
+ # b = start day
39
+ # c = start year
40
+ #
41
+ # Period end date
42
+ # d = end month
43
+ # e = end day
44
+ # f = end year
45
+ #
46
+ # g = type
47
+ # Type values allowed: 'd' for daily (the default), 'w' for weekly, 'm' for monthly and 'v' for dividends.
48
+ def generate_history_url
49
+
74
50
  url = 'http://ichart.finance.yahoo.com/table.csv?s=%s&a=%s&b=%s&c=%s&d=%s&e=%s&f=%s&g=%s&ignore=.csv' % [
75
- symbol,
76
- start_date.month - 1,
77
- start_date.day,
78
- start_date.year,
79
- end_date.month - 1,
80
- end_date.day,
81
- end_date.year,
82
- periods
51
+ @symbol,
52
+ @start_date.to_date.month - 1,
53
+ @start_date.to_date.day,
54
+ @start_date.to_date.year,
55
+ @end_date.to_date.month - 1,
56
+ @end_date.to_date.day,
57
+ @end_date.to_date.year,
58
+ TYPE_CODES_ARRAY[@type]
83
59
  ]
84
- results[symbol] = url
85
- end
86
-
87
- # Returns a hash {'symbol' => 'url'}
88
- return results
89
- end
90
-
91
- #
92
- # Input parameters validation
93
- #
94
- def validate_symbols parameters
95
-
96
- # Reject empty symbol hashes.
97
- @symbols = parameters.reject(&:empty?)
98
-
99
- if @symbols.nil?
100
- raise StockException, 'You must specify at least one stock symbol.'
101
- end
102
-
103
- # FIXME: A kinda hacky way to check if parameters are a nested array (when accepting an array as a symbols argument).
104
- # Unnesting an array.
105
- @symbols[0].is_a?(Array) ? @symbols = @symbols[0] : nil
106
-
107
- unless @symbols.uniq.length == @symbols.length
108
- raise StockException, 'Duplicate stock symbols given.'
109
- end
110
- end
111
60
 
112
- def validate_history parameters
113
- unless parameters.is_a?(Hash)
114
- raise StockException, 'Given parameters have to be a hash.'
61
+ return url
115
62
  end
116
63
 
117
- unless parameters.has_key?(:end_date)
118
- parameters[:end_date] = Date.today.strftime("%Y-%m-%d")
64
+ #
65
+ # Input parameters validation
66
+ #
67
+
68
+ def validate_input parameters
69
+ unless parameters.is_a?(Hash)
70
+ raise StockException, 'Given parameters have to be a hash.'
71
+ end
72
+
73
+ # Check if stock symbol is specified.
74
+ unless parameters.has_key?(:symbol)
75
+ raise StockException, 'No stock symbol specified.'
76
+ end
77
+ # Check if stock symbol is a string.
78
+ unless parameters[:symbol].is_a?(String)
79
+ raise StockException, 'Stock symbol must be a string.'
80
+ end
81
+ # Check if stock symbol is valid.
82
+ unless parameters[:symbol].match('^[a-zA-Z0-9]+$')
83
+ raise StockException, 'Invalid stock symbol specified.'
84
+ end
85
+
86
+ # Use today date if :end_date is not specified.
87
+ unless parameters.has_key?(:end_date)
88
+ parameters[:end_date] = Date.today.strftime("%Y-%m-%d")
89
+ end
90
+
91
+ unless parameters.has_key?(:start_date)
92
+ raise StockException, 'Start date must be specified.'
93
+ end
94
+
95
+ unless DATE_REGEX.match(parameters[:start_date])
96
+ raise StockException, 'Invalid start date specified. Format YYYY-MM-DD.'
97
+ end
98
+
99
+ unless DATE_REGEX.match(parameters[:end_date])
100
+ raise StockException, 'Invalid end date specified. Format YYYY-MM-DD.'
101
+ end
102
+
103
+ unless parameters[:start_date].to_date < parameters[:end_date].to_date
104
+ raise StockException, 'End date must be greater than the start date.'
105
+ end
106
+
107
+ unless parameters[:start_date].to_date < Date.today
108
+ raise StockException, 'Start date must not be in the future.'
109
+ end
110
+
111
+ # Set to default :type if key isn't specified.
112
+ parameters[:type] = :daily if !parameters.has_key?(:type)
113
+
114
+ unless TYPE_CODES_ARRAY.has_key?(parameters[:type])
115
+ raise StockException, 'Invalid type specified.'
116
+ end
119
117
  end
120
118
 
121
- unless parameters.has_key?(:start_date)
122
- raise StockException, 'Start date must be specified.'
123
- end
124
-
125
- unless DATE_REGEX.match(parameters[:start_date])
126
- raise StockException, 'Invalid start date specified. Format YYYY-MM-DD.'
127
- end
128
-
129
- unless DATE_REGEX.match(parameters[:end_date])
130
- raise StockException, 'Invalid end date specified. Format YYYY-MM-DD.'
131
- end
132
-
133
- unless parameters[:start_date].to_date < parameters[:end_date].to_date
134
- raise StockException, 'End date must be greater than the start date.'
135
- end
136
-
137
- unless parameters[:start_date].to_date < Date.today
138
- raise StockException, 'Start date must not be in the future.'
139
- end
140
-
141
- # Set to default :periods if key isn't specified.
142
- parameters[:periods] = :daily if !parameters.has_key?(:periods)
143
-
144
- unless PERIODS_ARRAY.include?(parameters[:periods])
145
- raise StockException, 'Invalid periods value specified.'
146
- end
147
- end
148
-
149
- end
150
- end
151
-
152
- #
153
- # The missing hash function
154
- # Returns true if all keys are present in hash.
155
- #
156
- class Hash
157
- def has_keys?(*_keys)
158
- (_keys - self.keys).empty?
159
119
  end
160
120
  end
@@ -1,3 +1,3 @@
1
1
  module Securities
2
- VERSION = "1.0.0"
2
+ VERSION = "2.0.0"
3
3
  end
data/securities.gemspec CHANGED
@@ -16,5 +16,6 @@ Gem::Specification.new do |gem|
16
16
  gem.version = Securities::VERSION
17
17
 
18
18
  gem.add_dependency 'rails'
19
+ gem.add_dependency 'nokogiri'
19
20
  gem.add_development_dependency 'rspec'
20
21
  end
data/spec/.DS_Store ADDED
Binary file
@@ -0,0 +1,22 @@
1
+ require 'spec_helper'
2
+
3
+ describe Securities::Lookup do
4
+ describe "Lookup" do
5
+
6
+ context "should raise an exception if parameter" do
7
+ it "is empty" do
8
+ expect { Securities::Lookup.new(' ') }.to raise_error('The lookup input was empty.')
9
+ end
10
+ it "got no results" do
11
+ expect { Securities::Lookup.new('some invalid lookup string') }.to raise_error('There were no results for this lookup.')
12
+ end
13
+ end
14
+
15
+ context "should not raise an exception if parameter" do
16
+ it "is not empty" do
17
+ expect { Securities::Lookup.new('Apple') }.not_to raise_error
18
+ end
19
+ end
20
+
21
+ end
22
+ end
data/spec/stock_spec.rb CHANGED
@@ -1,11 +1,74 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe Securities::Stock do
4
- describe ".new" do
5
-
6
- it "should raise error when no parameter is passed" do
7
- expect { Securities::Stock.new }.should raise_error
8
- end
9
-
4
+ describe "Stock" do
5
+ context "should raise an exception if parameter" do
6
+
7
+ it "is a not a hash" do
8
+ expect { Securities::Stock.new('some values') }.to raise_error('Given parameters have to be a hash.')
9
+ end
10
+
11
+ context "Symbol" do
12
+ it "is not passed" do
13
+ expect { Securities::Stock.new(:start_date => '2012-01-01', :end_date => '2012-01-04') }.to raise_error('No stock symbol specified.')
14
+ end
15
+ it "is not a string" do
16
+ expect { Securities::Stock.new(:symbol => ["AAPL", "GOOG"], :start_date => '2012-01-01', :end_date => '2012-01-04') }.to raise_error('Stock symbol must be a string.')
17
+ end
18
+ it "is an invalid string" do
19
+ expect { Securities::Stock.new(:symbol => 'AAPL company', :start_date => '2012-01-01', :end_date => '2012-01-04') }.to raise_error('Invalid stock symbol specified.')
20
+ end
21
+ end
22
+
23
+ context "History" do
24
+
25
+ it ":start_date not specified" do
26
+ expect { Securities::Stock.new(:symbol => 'AAPL', :end_date => '2012-01-01', :type => :weekly) }.to raise_error('Start date must be specified.')
27
+ end
28
+ it ":start_date or :end_date is invalid" do
29
+ expect { Securities::Stock.new(:symbol => 'AAPL', :start_date => '2012-01-50', :end_date => '2012-02-10', :type => :weekly) }.to raise_error('Invalid start date specified. Format YYYY-MM-DD.')
30
+ expect { Securities::Stock.new(:symbol => 'AAPL', :start_date => '2012-01-10', :end_date => '2012-02-50', :type => :weekly) }.to raise_error('Invalid end date specified. Format YYYY-MM-DD.')
31
+ end
32
+ it ":start_date greater than :end_date" do
33
+ expect { Securities::Stock.new(:symbol => 'AAPL', :start_date => '2012-01-10', :end_date => '2012-01-01', :type => :weekly) }.to raise_error('End date must be greater than the start date.')
34
+ end
35
+ it ":start_date is in the future" do
36
+ expect { Securities::Stock.new(:symbol => 'AAPL', :start_date => (Date.today+1).strftime("%Y-%m-%d"), :type => :weekly) }.to raise_error('End date must be greater than the start date.')
37
+ end
38
+ it ":type value is invalid" do
39
+ expect { Securities::Stock.new(:symbol => 'AAPL', :start_date => '2012-01-01', :type => :some_invalid_value) }.to raise_error('Invalid type specified.')
40
+ end
41
+ end
42
+
43
+ end
44
+
45
+ context "should not raise an exception if parameter" do
46
+
47
+ it "is a string" do
48
+ expect { Securities::Stock.new(:symbol => 'AAPL', :start_date => '2012-01-01', :end_date => '2012-01-04') }.not_to raise_error
49
+ end
50
+ it ":end_date is not specified (should default to today)" do
51
+ expect { @my_stocks = Securities::Stock.new(:symbol => 'AAPL', :start_date => (Date.today-8).strftime("%Y-%m-%d"), :type => :weekly) }.not_to raise_error
52
+ @my_stocks.end_date.to_date.should eq(Date.today)
53
+ end
54
+ it ":type is not specified (defaults to :daily)" do
55
+ expect { @my_stocks = Securities::Stock.new(:symbol => 'AAPL', :start_date => (Date.today-8).strftime("%Y-%m-%d")) }.not_to raise_error
56
+ @my_stocks.type.should eq(:daily)
57
+ end
58
+
59
+ end
60
+ end
61
+
62
+ describe "Scraper" do
63
+ context "should raise an exception if" do
64
+
65
+ it "symbol is invalid" do
66
+ expect { Securities::Stock.new(:symbol => 'invalidsymbol', :start_date => (Date.today-8).strftime("%Y-%m-%d")) }.to raise_error('Stock symbol does not exist.')
67
+ end
68
+ it "there are no results" do
69
+ expect { Securities::Stock.new(:symbol => 'AAPL', :start_date => '2012-08-01', :end_date => '2012-08-05', :type => :dividends) }.to raise_error('There were no results for this symbol.')
70
+ end
71
+
72
+ end
10
73
  end
11
74
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: securities
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
4
+ version: 2.0.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-09-04 00:00:00.000000000 Z
12
+ date: 2012-09-19 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rails
@@ -27,6 +27,22 @@ dependencies:
27
27
  - - ! '>='
28
28
  - !ruby/object:Gem::Version
29
29
  version: '0'
30
+ - !ruby/object:Gem::Dependency
31
+ name: nokogiri
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ! '>='
36
+ - !ruby/object:Gem::Version
37
+ version: '0'
38
+ type: :runtime
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ! '>='
44
+ - !ruby/object:Gem::Version
45
+ version: '0'
30
46
  - !ruby/object:Gem::Dependency
31
47
  name: rspec
32
48
  requirement: !ruby/object:Gem::Requirement
@@ -50,18 +66,23 @@ executables: []
50
66
  extensions: []
51
67
  extra_rdoc_files: []
52
68
  files:
69
+ - .DS_Store
53
70
  - .gitignore
54
71
  - .rspec
55
72
  - .travis.yml
56
73
  - Gemfile
74
+ - Guardfile
57
75
  - LICENSE
58
76
  - README.md
59
77
  - Rakefile
60
78
  - lib/securities.rb
79
+ - lib/securities/lookup.rb
61
80
  - lib/securities/scraper.rb
62
81
  - lib/securities/stock.rb
63
82
  - lib/securities/version.rb
64
83
  - securities.gemspec
84
+ - spec/.DS_Store
85
+ - spec/lookup_spec.rb
65
86
  - spec/spec_helper.rb
66
87
  - spec/stock_spec.rb
67
88
  homepage: https://github.com/Nedomas/securities
@@ -78,7 +99,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
78
99
  version: '0'
79
100
  segments:
80
101
  - 0
81
- hash: -3860670281301913454
102
+ hash: -994639684959431574
82
103
  required_rubygems_version: !ruby/object:Gem::Requirement
83
104
  none: false
84
105
  requirements:
@@ -87,7 +108,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
87
108
  version: '0'
88
109
  segments:
89
110
  - 0
90
- hash: -3860670281301913454
111
+ hash: -994639684959431574
91
112
  requirements: []
92
113
  rubyforge_project:
93
114
  rubygems_version: 1.8.24
@@ -95,5 +116,7 @@ signing_key:
95
116
  specification_version: 3
96
117
  summary: Financial information scraper gem. Uses Yahoo Finance API.
97
118
  test_files:
119
+ - spec/.DS_Store
120
+ - spec/lookup_spec.rb
98
121
  - spec/spec_helper.rb
99
122
  - spec/stock_spec.rb