exchange-rates-generator 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
data/History.txt ADDED
@@ -0,0 +1,3 @@
1
+ === 0.0.1 2010-03-16
2
+
3
+ * First Release
data/Manifest.txt ADDED
@@ -0,0 +1,18 @@
1
+ History.txt
2
+ Manifest.txt
3
+ README.rdoc
4
+ Rakefile
5
+ bin/generate_exchange_rates
6
+ lib/exchange-rates-generator.rb
7
+ lib/exchange-rates-generator/errors.rb
8
+ lib/exchange-rates-generator/formatters/base.rb
9
+ lib/exchange-rates-generator/formatters/ruby.rb
10
+ lib/exchange-rates-generator/formatters/javascript.rb
11
+ lib/exchange-rates-generator/sources/base.rb
12
+ lib/exchange-rates-generator/sources/ecb.rb
13
+ lib/generate_exchange_rates/cli.rb
14
+ spec/exchange-rates-generator_spec.rb
15
+ spec/generate_exchange_rates_cli_spec.rb
16
+ spec/spec.opts
17
+ spec/spec_helper.rb
18
+ tasks/rspec.rake
data/README.rdoc ADDED
@@ -0,0 +1,61 @@
1
+ = exchange-rates-generator
2
+
3
+ * http://github.com/#{github_username}/#{project_name}
4
+
5
+ == DESCRIPTION:
6
+
7
+ Generates a classes (or class like things) that can translate currency values in a specific currency to a number of other currencies.
8
+
9
+ == FEATURES/PROBLEMS:
10
+
11
+ * Generates classes (or class like things) for Ruby and Javascript
12
+ * Can support addition languages through custom formatters
13
+ * Supports a currency xml feed from ECB by default, but can support custom exchange rate sources through custom Source classes.
14
+
15
+ == SYNOPSIS:
16
+
17
+ Generate a Ruby class for convert NZD amounts to other currencies, using the default ECB source.
18
+
19
+ <tt>./generate_exchange_rates -c nzd -f ruby</tt>
20
+
21
+
22
+ Generate a Ruby library for convert NZD amounts to other currencies, using the default ECB source.
23
+
24
+ <tt>./generate_exchange_rates -c usd -f javascript</tt>
25
+
26
+ == REQUIREMENTS:
27
+
28
+ * Ruby :-)
29
+ * Extlib Gem
30
+ * Money Gem
31
+ * Patron Gem
32
+ * Nokogiri Gem
33
+
34
+ == INSTALL:
35
+
36
+ * sudo gem install exchange-rates-generator
37
+
38
+ == LICENSE:
39
+
40
+ (The MIT License)
41
+
42
+ Copyright (c) 2010 Rolly
43
+
44
+ Permission is hereby granted, free of charge, to any person obtaining
45
+ a copy of this software and associated documentation files (the
46
+ 'Software'), to deal in the Software without restriction, including
47
+ without limitation the rights to use, copy, modify, merge, publish,
48
+ distribute, sublicense, and/or sell copies of the Software, and to
49
+ permit persons to whom the Software is furnished to do so, subject to
50
+ the following conditions:
51
+
52
+ The above copyright notice and this permission notice shall be
53
+ included in all copies or substantial portions of the Software.
54
+
55
+ THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
56
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
57
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
58
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
59
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
60
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
61
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/Rakefile ADDED
@@ -0,0 +1,26 @@
1
+ require 'rubygems'
2
+ gem 'hoe', '>= 2.1.0'
3
+ require 'hoe'
4
+ require 'fileutils'
5
+ require './lib/exchange-rates-generator'
6
+
7
+ Hoe.plugin :newgem
8
+ # Hoe.plugin :website
9
+ # Hoe.plugin :cucumberfeatures
10
+
11
+ # Generate all the Rake tasks
12
+ # Run 'rake -T' to see list of generated tasks (from gem root directory)
13
+ $hoe = Hoe.spec 'exchange-rates-generator' do
14
+ self.developer 'Rolly', 'rolly@luma.co.nz'
15
+ # self.post_install_message = 'PostInstall.txt' # TODO remove if post-install message not required
16
+ self.rubyforge_name = self.name # TODO this is default value
17
+ # self.extra_deps = [['activesupport','>= 2.0.2']]
18
+
19
+ end
20
+
21
+ require 'newgem/tasks'
22
+ Dir['tasks/**/*.rake'].each { |t| load t }
23
+
24
+ # TODO - want other tests/tasks run by default? Add them to the list
25
+ # remove_task :default
26
+ # task :default => [:spec, :features]
@@ -0,0 +1,10 @@
1
+ #!/usr/bin/env ruby
2
+ #
3
+ # Created by Rolly on 2010-3-16.
4
+ # Copyright (c) 2010. All rights reserved.
5
+
6
+ require 'rubygems'
7
+ require File.expand_path(File.dirname(__FILE__) + "/../lib/exchange-rates-generator")
8
+ require "generate_exchange_rates/cli"
9
+
10
+ GenerateExchangeRates::CLI.execute(STDOUT, ARGV)
@@ -0,0 +1,38 @@
1
+ $:.unshift(File.dirname(__FILE__)) unless
2
+ $:.include?(File.dirname(__FILE__)) || $:.include?(File.expand_path(File.dirname(__FILE__)))
3
+
4
+ require 'patron'
5
+ require 'nokogiri'
6
+ require 'extlib'
7
+ require 'logger'
8
+
9
+ module ExchangeRatesGenerator
10
+ VERSION = '0.0.1'
11
+
12
+ def self.log_to=(l)
13
+ @log_to = l
14
+ end
15
+
16
+ def self.log_to
17
+ @log_to ||= STDOUT
18
+ end
19
+
20
+ def self.logger=(logger)
21
+ @logger = logger
22
+ end
23
+
24
+ def self.logger
25
+ @logger ||= begin
26
+ log = Logger.new(log_to)
27
+ log.level = Logger::INFO
28
+ log
29
+ end
30
+ end
31
+ end
32
+
33
+ require 'exchange-rates-generator/formatters/base'
34
+ require 'exchange-rates-generator/formatters/ruby'
35
+ require 'exchange-rates-generator/formatters/javascript'
36
+
37
+ require 'exchange-rates-generator/sources/base'
38
+ require 'exchange-rates-generator/sources/ecb'
@@ -0,0 +1,21 @@
1
+ module ExchangeRatesGenerator
2
+ module Errors
3
+ class ExchangeRatesError < StandardError
4
+ end
5
+
6
+ class NotFoundError < ExchangeRatesError
7
+ end
8
+
9
+ class UnknownError < ExchangeRatesError
10
+ end
11
+
12
+ class MalformedSourceClass < ExchangeRatesError
13
+ end
14
+
15
+ class CurrencyNotAvailable < ExchangeRatesError
16
+ end
17
+
18
+ class MalformedFormatterClass < ExchangeRatesError
19
+ end
20
+ end # module Errors
21
+ end # module ExchangeRatesGenerator
@@ -0,0 +1,42 @@
1
+ module ExchangeRatesGenerator
2
+ module Formatters
3
+ def self.get(formatter_name)
4
+ Object.full_const_get([self.to_s, Extlib::Inflection.classify(formatter_name.to_s)].join("::"))
5
+ end
6
+
7
+ class Base
8
+ attr_reader :currency, :rates
9
+
10
+ def initialize(currency, rates)
11
+ @currency = currency.to_s.upcase.to_sym
12
+ @rates = rates
13
+ end
14
+
15
+ def to_s
16
+ header + body + footer
17
+ end
18
+
19
+ class << self
20
+ # Returns all Formatters
21
+ #
22
+ # @return [Array]
23
+ # Array containing all Formatters
24
+ #
25
+ def formatters
26
+ @formatters ||= []
27
+ end
28
+
29
+ # Records all new Formatters
30
+ def inherited(formatter)
31
+ self.formatters << formatter
32
+ end
33
+ end
34
+
35
+ protected
36
+
37
+ def formatter_classname
38
+ @formatter_classname ||= Extlib::Inflection.classify(@currency.to_s)
39
+ end
40
+ end # class Base
41
+ end # module Formatters
42
+ end # module ExchangeRatesGenerator
@@ -0,0 +1,94 @@
1
+ module ExchangeRatesGenerator
2
+ module Formatters
3
+ class Javascript < Base
4
+ def initialize(currency, rates)
5
+ super(currency, rates)
6
+ end
7
+
8
+ def default_extension
9
+ self.class.default_extension
10
+ end
11
+
12
+ def description
13
+ self.class.description
14
+ end
15
+
16
+ class << self
17
+ def default_extension
18
+ :js
19
+ end
20
+
21
+ def description
22
+ "Javascript Formatter"
23
+ end
24
+ end
25
+
26
+ protected
27
+
28
+ def formatter_classname
29
+ @formatter_classname ||= Extlib::Inflection.underscore(@currency.to_s)
30
+ end
31
+
32
+ def header
33
+ <<-EOS
34
+ //
35
+ // THIS FILE IS AUTOMATICALLY GENERATED USING THE exchange-rates-generator RUBY GEM DO NOT EDIT IT.
36
+ //
37
+
38
+ if ( typeof(exchange_rates) === 'undefined' ) {
39
+ var exchange_rates = {};
40
+ }
41
+
42
+ // This Library provides exchange rate conversion from #{@currency.to_s} to various other currencies. The list of
43
+ // currencies that this Library can convert to can be retrieve using the supported_currencies method.
44
+ //
45
+ // Generated using the exchange-rates-generator Ruby Gem.
46
+ exchange_rates.#{formatter_classname} = function() {
47
+ EOS
48
+ end
49
+
50
+ def body
51
+ <<-EOS
52
+ return {
53
+ base_currency : function() {
54
+ return '#{@currency.to_s}';
55
+ },
56
+
57
+ supported_currencies : function() {
58
+ return [
59
+ #{rates.keys.collect {|c| " \"#{c}\"" }.join(",\n") }
60
+ ];
61
+ },
62
+
63
+ get : function(target_currency) {
64
+ return this.rates()[target_currency.toUpperCase()];
65
+ },
66
+
67
+ convert : function(amount, target_currency) {
68
+ var rate = this.get(target_currency);
69
+ if ( !rate ) {
70
+ throw "This exchange rate converter can not convert to " + target_currency;
71
+ }
72
+
73
+ return rate * parseFloat(amount, 10);
74
+ },
75
+
76
+ rates : function() {
77
+ return {
78
+ "#{@currency.to_s}" : 1.0,
79
+ #{rates.to_a.collect { |rate| " \"#{rate[0].to_s}\" : #{rate[1].to_s}" }.join(",\n")}
80
+ }
81
+ }
82
+
83
+ };
84
+ EOS
85
+ end
86
+
87
+ def footer
88
+ <<-EOS
89
+ }();
90
+ EOS
91
+ end
92
+ end
93
+ end # module Formatters
94
+ end # module ExchangeRatesGenerator
@@ -0,0 +1,136 @@
1
+ module ExchangeRatesGenerator
2
+ module Formatters
3
+ class Ruby < Base
4
+ def initialize(currency, rates)
5
+ super(currency, rates)
6
+ end
7
+
8
+ def default_extension
9
+ self.class.default_extension
10
+ end
11
+
12
+ def description
13
+ self.class.description
14
+ end
15
+
16
+ class << self
17
+ def default_extension
18
+ :rb
19
+ end
20
+
21
+ def description
22
+ "Ruby Formatter"
23
+ end
24
+ end
25
+
26
+ protected
27
+
28
+ def header
29
+ <<-EOS
30
+ #
31
+ # THIS FILE IS AUTOMATICALLY GENERATED USING THE exchange-rates-generator RUBY GEM DO NOT EDIT IT.
32
+ #
33
+ require 'money'
34
+
35
+ module ExchangeRates
36
+ class CurrencyNotAvailable < StandardError
37
+ end
38
+
39
+ # This Class provides exchange rate conversion from #{@currency.to_s} to various other currencies. The list of
40
+ # currencies that this Class can convert to can be retrieve using the supported_currencies method.
41
+ #
42
+ # This Class also supports integration with the Money Gem, for usage see the use_as_default! method.
43
+ #
44
+ # Generated using the exchange-rates-generator Ruby Gem.
45
+ class #{@currency.to_s}
46
+ class << self
47
+ def base_currency
48
+ :#{@currency.to_s}
49
+ end
50
+
51
+ def supported_currencies
52
+ rates.keys
53
+ end
54
+
55
+ # Wires this currency up to use with the Money Gem. It sets it as the default
56
+ # currency.
57
+ #
58
+ # @example
59
+ # #{@currency.to_s}.use_as_default!
60
+ # Money.us_dollar(100).exchange_to("CAD") => Money.ca_dollar(124)
61
+ #
62
+ def use_as_default!
63
+ Money.default_currency = base_currency
64
+ Money.bank = self
65
+ Money
66
+ end
67
+
68
+ EOS
69
+ end
70
+
71
+ def body
72
+ <<-EOS
73
+ # Retrieves an exchange rate.
74
+ #
75
+ # @param [String, #to_s] The target currency that we want the exchange rate for.
76
+ # @return [Float] The exchange rate
77
+ def get(target_currency)
78
+ rates[target_currency.to_s.upcase.to_sym]
79
+ end
80
+
81
+ # Convert +amount+ from base_currency to +currency+.
82
+ #
83
+ # @param [Float, #to_f] Amount to convert.
84
+ # @param [String, #to_s] The currency we want to convert to.
85
+ # @return [Float] The +amount+ converted to +currency+.
86
+ def convert(amount, currency)
87
+ rate = get(currency) or raise CurrencyNotAvailable, "Can't find required exchange rate"
88
+ rate * amount.to_f
89
+ end
90
+
91
+ # Retrieves an exchange rate, this is here to support the Money Gem.
92
+ #
93
+ # @param [String, #to_s] The source currency that we want the exchange rate for. For this class from should always match base_currency.
94
+ # @param [String, #to_s] The target currency that we want the exchange rate for.
95
+ # @return [Float] The exchange rate
96
+ def get_rate(from, to)
97
+ unless from.to_s.upcase.to_sym == :#{@currency.to_s}
98
+ raise CurrencyNotAvailable, "This exchange rate converter can only convert from #{@currency.to_s}"
99
+ end
100
+
101
+ get(to)
102
+ end
103
+
104
+ # Convert +money+ to +currency+.
105
+ #
106
+ # @param [Money] The amount to convert.
107
+ # @param [String] The currency to convert to.
108
+ # @return [Money] The +amount+ converted to +currency+.
109
+ def exchange(money, currency)
110
+ rate = get_rate(money.currency, currency.to_s) or raise CurrencyNotAvailable, "Can't find required exchange rate"
111
+
112
+ Money.new((money.cents * rate).floor, currency.to_s, money.precision)
113
+ end
114
+
115
+ # The exchange rates relative to base_currency.
116
+ #
117
+ # @return [Hash] The exchange rates relative to base_currency.
118
+ def rates
119
+ {
120
+ :#{@currency.to_s} => 1.0,
121
+ #{rates.to_a.collect { |rate| "\s\s:#{rate[0].to_s} => #{rate[1].to_s}" }.join(",\n ")}
122
+ }
123
+ end
124
+ EOS
125
+ end
126
+
127
+ def footer
128
+ <<-EOS
129
+ end
130
+ end
131
+ end # module ExchangeRates
132
+ EOS
133
+ end
134
+ end
135
+ end # module Formatters
136
+ end # module ExchangeRatesGenerator
@@ -0,0 +1,60 @@
1
+ module ExchangeRatesGenerator
2
+ module Sources
3
+ def self.get(source_name)
4
+ Object.full_const_get([self.to_s, Extlib::Inflection.classify(source_name.to_s)].join("::"))
5
+ end
6
+
7
+ class Base
8
+ class << self
9
+ # Returns all Sources
10
+ #
11
+ # @return [Array]
12
+ # Array containing all Sources
13
+ #
14
+ def sources
15
+ @sources ||= []
16
+ end
17
+
18
+ # Records all new Sources
19
+ def inherited(source)
20
+ self.sources << source
21
+ end
22
+
23
+ # Retrieve a Hash of currency codes and exchange rates, they rates will be relative to +currency_code+
24
+ #
25
+ # @param [String, #to_s] The currency code that the exchange rates will be relative to.
26
+ # @return [Hash] The exchange rates, as a Hash of currency codes and exchange rates.
27
+ def rates_for(currency_code)
28
+ # Retrieve the actual rates from the external source
29
+ rates = all_rates
30
+
31
+ adjusted_currency = currency_code.to_s.upcase.to_sym
32
+ unless rates.include?(adjusted_currency)
33
+ raise Errors::CurrencyNotAvailable, "#{adjusted_currency.to_s} was not available in this Source (#{self.to_s}), please use a different Source"
34
+ end
35
+
36
+ adjusted_rates = {}
37
+
38
+ # Add the currency we are converting to...
39
+ adjusted_rates[adjusted_currency] = 1.0
40
+
41
+ # Work out the exchange from our desired currency to our base currency. So if our base was EUR and we wanted USD this would
42
+ # be how many Euros are in one US dollar.
43
+ adjustment_factor = 1.0 / rates[adjusted_currency]
44
+ adjusted_rates[base_currency] = adjustment_factor
45
+
46
+ # Now remove it, since we've already done it.
47
+ rates.delete(base_currency)
48
+
49
+ # Now convert the rest
50
+ rates.each do |currency, rate|
51
+ adjusted_rates[currency] = rate * adjustment_factor
52
+ end
53
+
54
+ adjusted_rates
55
+ end
56
+ end
57
+
58
+ end
59
+ end # module Sources
60
+ end # module ExchangeRatesGenerator
@@ -0,0 +1,71 @@
1
+ module ExchangeRatesGenerator
2
+ module Sources
3
+ # ECB: European Central Bank home page
4
+ class Ecb < Base
5
+ class << self
6
+ # Retrieves the currency code (as an uppercase symbol) that represents this Source's Base currency.
7
+ #
8
+ # @return [Symbol] The currency code of this Source's base currency
9
+ def base_currency
10
+ :EUR
11
+ end
12
+
13
+ # Retrieves a human readable description of the Source.
14
+ #
15
+ # @return [String] The description.
16
+ def description
17
+ "European Central Bank currency feed"
18
+ end
19
+
20
+ # Retrieves all the currency rates from the external source, this is a Hash of currency codes and exchange
21
+ # rates. The currency codes will be upcased, Symbols (e.g. :USD, :NZD). The exchange rates will be with
22
+ # respect to the base_currency.
23
+ #
24
+ # @return [Hash] The rates as a Hash of currency codes => exchange rates.
25
+ def all_rates
26
+ session = Patron::Session.new
27
+ session.timeout = 30000 # 10 secs
28
+ session.connect_timeout = 2000 # 2 secs
29
+
30
+ ExchangeRatesGenerator.logger.info "Retrieving exchange rates from #{source}..."
31
+
32
+ http_response = session.get(source)
33
+
34
+ if ['404', '405', '406', '410'].include?(http_response.status)
35
+ # Not Found, auth failure, etc. Some form of it wasn't there.
36
+ raise Errors::NotFoundError, "The exchange rate source file seems to be unavailable"
37
+ elsif !['1', '2'].include?(http_response.status.to_s[0..0])
38
+ # Other non-specific failures.
39
+ raise Errors::UnexpectedError, "Error while making a request to #{source}\nResponse: #{http_response.inspect}"
40
+ end
41
+
42
+ convert_to_exchange_rate_hash(http_response.body)
43
+ end
44
+
45
+ protected
46
+
47
+ # Parse the XML response from the service
48
+ def convert_to_exchange_rate_hash(response_body)
49
+ doc = Nokogiri::HTML.parse(response_body)
50
+
51
+ hashed_rates = {}
52
+
53
+ # Normalise and Hash the result
54
+ doc.css('envelope>cube>cube>cube').each do |rate|
55
+ currency = rate[:currency].upcase.to_sym
56
+ rate = rate[:rate].to_f
57
+ hashed_rates[currency] = rate
58
+ end
59
+
60
+ hashed_rates
61
+ end
62
+
63
+ def source
64
+ 'http://www.ecb.int/stats/eurofxref/eurofxref-daily.xml'
65
+ end
66
+
67
+ end
68
+
69
+ end
70
+ end # module Sources
71
+ end # module ExchangeRatesGenerator
@@ -0,0 +1,93 @@
1
+ require 'optparse'
2
+
3
+ module GenerateExchangeRates
4
+ class CLI
5
+ def self.execute(stdout, arguments=[])
6
+
7
+ # NOTE: the option -p/--path= is given as an example, and should be replaced in your application.
8
+
9
+ options = {
10
+ :path => nil,
11
+ :source => 'ecb',
12
+ :format => 'ruby'
13
+ }
14
+ mandatory_options = %w( currency )
15
+
16
+ parser = OptionParser.new do |opts|
17
+ opts.banner = <<-BANNER.gsub(/^ /,'')
18
+ This application is wonderful because it can generate helpful classes that can do currency exchange from a single target currency to numerous others.
19
+
20
+ Usage: #{File.basename($0)} [options]
21
+
22
+ Options are:
23
+ BANNER
24
+ opts.separator ""
25
+ opts.on("-v", "--version", String,
26
+ "Displays the current version number of this Gem") { |arg| stdout.puts "#{File.basename($0)} #{ExchangeRatesGenerator::VERSION}"; exit }
27
+ opts.on("-c", "--currency CURRENCY", String,
28
+ "This is the base currency you wish to convert from.") { |arg| options[:currency] = arg }
29
+ opts.on("-p", "--path PATH", String,
30
+ "The is the default output path for the exchange rate converter.",
31
+ "Default: ~/exchange_rates.[format extension]") { |arg| options[:path] = arg }
32
+ opts.on("-s", "--source SOURCE", String,
33
+ "This is the name of the desired Source to retrieve the currency data from.",
34
+ "To get a list of all available Sources using the -l or --list flags.",
35
+ "Default: ecb") { |arg| options[:source] = arg.upcase }
36
+ opts.on("-f", "--format Format", String,
37
+ "This is the name of the desired output format of the exchange rate converter, the choice of format depends on the programming language you intend to use the converter from.",
38
+ "To get a list of all available formats using the -l or --list flags.",
39
+ "Default: ruby") { |arg| options[:format] = arg.upcase }
40
+
41
+ opts.on("-l", "--list", "List all available formats and sources") do
42
+ formatters = ExchangeRatesGenerator::Formatters::Base.formatters.collect {|f| "\s\s#{Extlib::Inflection.demodulize(f.to_s)}: #{f.description} (*.#{f.default_extension.to_s})" }.join("\n")
43
+ sources = ExchangeRatesGenerator::Sources::Base.sources.collect {|s| "\s\s#{Extlib::Inflection.demodulize(s.to_s)}: #{s.description}" }.join("\n")
44
+
45
+ stdout.puts <<-EOS
46
+ Available Formats:
47
+ #{formatters}
48
+
49
+ Available Sources:
50
+ #{sources}
51
+ EOS
52
+
53
+ exit
54
+ end
55
+ opts.on("-h", "--help",
56
+ "Show this help message.") { stdout.puts opts; exit }
57
+ opts.parse!(arguments)
58
+
59
+ if mandatory_options && mandatory_options.find { |option| options[option.to_sym].nil? }
60
+ stdout.puts opts; exit
61
+ end
62
+ end
63
+
64
+ formatter = ::ExchangeRatesGenerator::Formatters.get(options[:format].to_sym)
65
+ unless formatter
66
+ stdout.puts "Sorry, I couldn't find a formatter for the format '#{options[:format]}', use the -l or --list flag to see the complete list of available formats."
67
+ exit
68
+ end
69
+
70
+ source = ::ExchangeRatesGenerator::Sources.get(options[:source].to_sym)
71
+ unless source
72
+ stdout.puts "Sorry, I couldn't find the source '#{options[:source]}', use the -l or --list flag to see the complete list of available sources."
73
+ exit
74
+ end
75
+
76
+ path = options[:path]
77
+ path ||= "exchange_rates.#{formatter.default_extension.to_s}"
78
+
79
+ begin
80
+ File.open(path, 'w') do |file|
81
+ file.write formatter.new(options[:currency], source.rates_for(options[:currency]))
82
+ end
83
+
84
+ # TODO: Catch some exceptions?
85
+ rescue ::ExchangeRatesGenerator::Errors::ExchangeRatesError => e
86
+ stdout.puts e.message
87
+ exit
88
+ end
89
+
90
+ stdout.puts "Exchange rate converted successfully. Find it at: #{path}"
91
+ end
92
+ end
93
+ end
@@ -0,0 +1,11 @@
1
+ require File.dirname(__FILE__) + '/spec_helper.rb'
2
+
3
+ # Time to add your specs!
4
+ # http://rspec.info/
5
+ describe "Place your specs here" do
6
+
7
+ it "find this spec in spec directory" do
8
+ # violated "Be sure to write your specs"
9
+ end
10
+
11
+ end
@@ -0,0 +1,15 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
+ require 'generate_exchange_rates/cli'
3
+
4
+ describe GenerateExchangeRates::CLI, "execute" do
5
+ before(:each) do
6
+ @stdout_io = StringIO.new
7
+ GenerateExchangeRates::CLI.execute(@stdout_io, [])
8
+ @stdout_io.rewind
9
+ @stdout = @stdout_io.read
10
+ end
11
+
12
+ it "should print default output" do
13
+ @stdout.should =~ /To update this executable/
14
+ end
15
+ end
data/spec/spec.opts ADDED
@@ -0,0 +1 @@
1
+ --colour
@@ -0,0 +1,10 @@
1
+ begin
2
+ require 'spec'
3
+ rescue LoadError
4
+ require 'rubygems' unless ENV['NO_RUBYGEMS']
5
+ gem 'rspec'
6
+ require 'spec'
7
+ end
8
+
9
+ $:.unshift(File.dirname(__FILE__) + '/../lib')
10
+ require 'exchange-rates-generator'
data/tasks/rspec.rake ADDED
@@ -0,0 +1,21 @@
1
+ begin
2
+ require 'spec'
3
+ rescue LoadError
4
+ require 'rubygems' unless ENV['NO_RUBYGEMS']
5
+ require 'spec'
6
+ end
7
+ begin
8
+ require 'spec/rake/spectask'
9
+ rescue LoadError
10
+ puts <<-EOS
11
+ To use rspec for testing you must install rspec gem:
12
+ gem install rspec
13
+ EOS
14
+ exit(0)
15
+ end
16
+
17
+ desc "Run the specs under spec/models"
18
+ Spec::Rake::SpecTask.new do |t|
19
+ t.spec_opts = ['--options', "spec/spec.opts"]
20
+ t.spec_files = FileList['spec/**/*_spec.rb']
21
+ end
metadata ADDED
@@ -0,0 +1,123 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: exchange-rates-generator
3
+ version: !ruby/object:Gem::Version
4
+ prerelease: false
5
+ segments:
6
+ - 0
7
+ - 0
8
+ - 1
9
+ version: 0.0.1
10
+ platform: ruby
11
+ authors:
12
+ - Rolly
13
+ autorequire:
14
+ bindir: bin
15
+ cert_chain: []
16
+
17
+ date: 2010-03-16 00:00:00 +13:00
18
+ default_executable:
19
+ dependencies:
20
+ - !ruby/object:Gem::Dependency
21
+ name: rubyforge
22
+ prerelease: false
23
+ requirement: &id001 !ruby/object:Gem::Requirement
24
+ requirements:
25
+ - - ">="
26
+ - !ruby/object:Gem::Version
27
+ segments:
28
+ - 2
29
+ - 0
30
+ - 4
31
+ version: 2.0.4
32
+ type: :development
33
+ version_requirements: *id001
34
+ - !ruby/object:Gem::Dependency
35
+ name: gemcutter
36
+ prerelease: false
37
+ requirement: &id002 !ruby/object:Gem::Requirement
38
+ requirements:
39
+ - - ">="
40
+ - !ruby/object:Gem::Version
41
+ segments:
42
+ - 0
43
+ - 5
44
+ - 0
45
+ version: 0.5.0
46
+ type: :development
47
+ version_requirements: *id002
48
+ - !ruby/object:Gem::Dependency
49
+ name: hoe
50
+ prerelease: false
51
+ requirement: &id003 !ruby/object:Gem::Requirement
52
+ requirements:
53
+ - - ">="
54
+ - !ruby/object:Gem::Version
55
+ segments:
56
+ - 2
57
+ - 5
58
+ - 0
59
+ version: 2.5.0
60
+ type: :development
61
+ version_requirements: *id003
62
+ description: Generates a classes (or class like things) that can translate currency values in a specific currency to a number of other currencies.
63
+ email:
64
+ - rolly@luma.co.nz
65
+ executables:
66
+ - generate_exchange_rates
67
+ extensions: []
68
+
69
+ extra_rdoc_files:
70
+ - History.txt
71
+ - Manifest.txt
72
+ files:
73
+ - History.txt
74
+ - Manifest.txt
75
+ - README.rdoc
76
+ - Rakefile
77
+ - bin/generate_exchange_rates
78
+ - lib/exchange-rates-generator.rb
79
+ - lib/exchange-rates-generator/errors.rb
80
+ - lib/exchange-rates-generator/formatters/base.rb
81
+ - lib/exchange-rates-generator/formatters/ruby.rb
82
+ - lib/exchange-rates-generator/formatters/javascript.rb
83
+ - lib/exchange-rates-generator/sources/base.rb
84
+ - lib/exchange-rates-generator/sources/ecb.rb
85
+ - lib/generate_exchange_rates/cli.rb
86
+ - spec/exchange-rates-generator_spec.rb
87
+ - spec/generate_exchange_rates_cli_spec.rb
88
+ - spec/spec.opts
89
+ - spec/spec_helper.rb
90
+ - tasks/rspec.rake
91
+ has_rdoc: true
92
+ homepage: http://github.com/#{github_username}/#{project_name}
93
+ licenses: []
94
+
95
+ post_install_message:
96
+ rdoc_options:
97
+ - --main
98
+ - README.rdoc
99
+ require_paths:
100
+ - lib
101
+ required_ruby_version: !ruby/object:Gem::Requirement
102
+ requirements:
103
+ - - ">="
104
+ - !ruby/object:Gem::Version
105
+ segments:
106
+ - 0
107
+ version: "0"
108
+ required_rubygems_version: !ruby/object:Gem::Requirement
109
+ requirements:
110
+ - - ">="
111
+ - !ruby/object:Gem::Version
112
+ segments:
113
+ - 0
114
+ version: "0"
115
+ requirements: []
116
+
117
+ rubyforge_project: exchange-rates-generator
118
+ rubygems_version: 1.3.6
119
+ signing_key:
120
+ specification_version: 3
121
+ summary: Generates a classes (or class like things) that can translate currency values in a specific currency to a number of other currencies.
122
+ test_files: []
123
+