securities 1.0.0 → 2.0.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/.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