Permalink
Browse files

Tests! Some light refactoring to make tests possible

  • Loading branch information...
1 parent 32c4221 commit 7eefd6a683ea3c59f541b7a89a9cf2e75a048a99 @peterkeen committed Mar 18, 2012
View
@@ -9,3 +9,7 @@ end
task :release => :build do
system "gem push ledger_web-#{LedgerWeb::VERSION}.gem"
end
+
+task :test do
+ system 'rspec --color --format=documentation test'
+end
View
@@ -15,17 +15,17 @@ OptionParser.new do |opts|
opts.banner = "Usage: ledger_web [options]"
opts.on("-p", "--port PORT", Integer, "Port to expose the web interface") do |p|
- CONFIG.set :port, p.to_i
+ LedgerWeb::Config.instance.set :port, p.to_i
end
opts.on("-f", "--ledger-file FILE", String, "Ledger file to watch and load") do |f|
- CONFIG.set :ledger_file, f
+ LedgerWeb::Config.instance.set :ledger_file, f
end
opts.on("-d", "--database-url URL", String, "Database URL to load into") do |d|
- CONFIG.set :database_url, d
+ LedgerWeb::Config.instance.set :database_url, d
end
end.parse!
LedgerWeb::Watcher.run!
-LedgerWeb::Application.run!(:port => CONFIG.get(:port))
+LedgerWeb::Application.run!(:port => LedgerWeb::Config.instance.get(:port))
View
@@ -20,9 +20,12 @@ Gem::Specification.new do |s|
s.add_dependency("sinatra")
s.add_dependency("sinatra-session")
s.add_dependency("sinatra-contrib")
+ s.add_dependency("rspec")
+ s.add_dependency("database_cleaner")
s.bindir = 'bin'
s.files = `git ls-files`.split("\n")
+ s.test_files = `git ls-files -- test/*`.split("\n")
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
s.require_paths = ["lib"]
end
@@ -6,9 +6,9 @@
module LedgerWeb
class Application < Sinatra::Base
register Sinatra::Session
- set :session_secret, CONFIG.get(:session_secret)
- set :session_expire, CONFIG.get(:session_expire)
- set :views, CONFIG.get(:report_directories) + [File.join(File.dirname(__FILE__), 'views')]
+ set :session_secret, LedgerWeb::Config.instance.get(:session_secret)
+ set :session_expire, LedgerWeb::Config.instance.get(:session_expire)
+ set :views, LedgerWeb::Config.instance.get(:report_directories) + [File.join(File.dirname(__FILE__), 'views')]
set :reload_templates, true
helpers Sinatra::Capture
@@ -55,7 +55,7 @@ def find_template(views, name, engine, &block)
end
get '/' do
- index_report = CONFIG.get :index_report
+ index_report = LedgerWeb::Config.instance.get :index_report
if index_report
redirect "/reports/#{index_report.to_s}"
else
@@ -3,6 +3,17 @@ module LedgerWeb
class Config
attr_reader :vars, :hooks
+ @@should_load_user_config = true
+ @@instance = nil
+
+ def self.should_load_user_config
+ @@should_load_user_config
+ end
+
+ def self.should_load_user_config=(val)
+ @@should_load_user_config = val
+ end
+
def initialize
@vars = {}
@hooks = {}
@@ -55,40 +66,43 @@ def self.from_file(filename)
return eval(file.read, nil, filename)
end
end
- end
-end
-
-CONFIG = LedgerWeb::Config.new do |config|
- config.set :database_url, "postgres://localhost/ledger"
- config.set :port, "9090"
- config.set :ledger_file, ENV['LEDGER_FILE']
- config.set :report_directories, ["#{File.dirname(__FILE__)}/reports"]
- config.set :session_secret, 'SomethingSecretThisWayPassed'
- config.set :session_expire, 60*60
- config.set :watch_interval, 5
- config.set :watch_stable_count, 3
- config.set :ledger_bin_path, "ledger"
- config.set :ledger_format, "%(quoted(xact.beg_line)),%(quoted(date)),%(quoted(payee)),%(quoted(account)),%(quoted(commodity)),%(quoted(quantity(scrub(display_amount)))),%(quoted(cleared)),%(quoted(virtual)),%(quoted(join(note | xact.note))),%(quoted(cost))\n"
- config.set :price_lookup_skip_symbols, ['$']
-
- func = Proc.new do |symbol, min_date, max_date|
- LedgerWeb::YahooPriceLookup.new(symbol, min_date, max_date).lookup
- end
- config.set :price_function, func
-
- ledger_web_dir = "#{ENV['HOME']}/.ledger_web"
-
- if File.directory? ledger_web_dir
- if File.directory? "#{ledger_web_dir}/reports"
- dirs = config.get(:report_directories)
- dirs.unshift "#{ledger_web_dir}/reports"
- config.set :report_directories, dirs
- end
-
- if File.exists? "#{ledger_web_dir}/config.rb"
- config.override_with(LedgerWeb::Config.from_file("#{ledger_web_dir}/config.rb"))
+ def self.instance
+ @@instance ||= LedgerWeb::Config.new do |config|
+ config.set :database_url, "postgres://localhost/ledger"
+ config.set :port, "9090"
+ config.set :ledger_file, ENV['LEDGER_FILE']
+ config.set :report_directories, ["#{File.dirname(__FILE__)}/reports"]
+ config.set :session_secret, 'SomethingSecretThisWayPassed'
+ config.set :session_expire, 60*60
+ config.set :watch_interval, 5
+ config.set :watch_stable_count, 3
+ config.set :ledger_bin_path, "ledger"
+
+ config.set :ledger_format, "%(quoted(xact.beg_line)),%(quoted(date)),%(quoted(payee)),%(quoted(account)),%(quoted(commodity)),%(quoted(quantity(scrub(display_amount)))),%(quoted(cleared)),%(quoted(virtual)),%(quoted(join(note | xact.note))),%(quoted(cost))\n"
+
+ config.set :price_lookup_skip_symbols, ['$']
+
+ func = Proc.new do |symbol, min_date, max_date|
+ LedgerWeb::YahooPriceLookup.new(symbol, min_date, max_date).lookup
+ end
+ config.set :price_function, func
+
+ ledger_web_dir = "#{ENV['HOME']}/.ledger_web"
+
+ if LedgerWeb::Config.should_load_user_config && File.directory?(ledger_web_dir)
+ if File.directory? "#{ledger_web_dir}/reports"
+ dirs = config.get(:report_directories)
+ dirs.unshift "#{ledger_web_dir}/reports"
+ config.set :report_directories, dirs
+ end
+
+ if File.exists? "#{ledger_web_dir}/config.rb"
+ config.override_with(LedgerWeb::Config.from_file("#{ledger_web_dir}/config.rb"))
+ end
+ end
+ end
end
end
end
View
@@ -1,59 +1,92 @@
require 'sequel'
require 'sequel/extensions/migration'
require 'csv'
+require 'tempfile'
-DB = Sequel.connect(CONFIG.get(:database_url))
+module LedgerWeb
+ class Database
-Sequel::Migrator.apply(DB, File.join(File.dirname(__FILE__), "db/migrate"))
+ def self.connect
+ @@db = Sequel.connect(LedgerWeb::Config.instance.get(:database_url))
+ self.run_migrations()
+ end
-home_migrations = File.join(ENV['HOME'], '.ledger_web', 'migrate')
-if File.directory?(home_migrations)
- Sequel::Migrator.run(DB, home_migrations, :table => "user_schema_changes")
-end
+ def self.close
+ @@db.disconnect
+ end
-module LedgerWeb
- class Database
+ def self.handle
+ @@db
+ end
- def self.load_database
- ledger_format = CONFIG.get :ledger_format
- ledger_bin_path = CONFIG.get :ledger_bin_path
- ledger_file = CONFIG.get :ledger_file
-
- # dump ledger to tempfile
+ def self.run_migrations
+ Sequel::Migrator.apply(@@db, File.join(File.dirname(__FILE__), "db/migrate"))
+
+ home_migrations = File.join(ENV['HOME'], '.ledger_web', 'migrate')
+ if LedgerWeb::Config.should_load_user_config && File.directory?(home_migrations)
+ Sequel::Migrator.run(@@db, home_migrations, :table => "user_schema_changes")
+ end
+ end
+
+ def self.dump_ledger_to_csv
+ ledger_bin_path = LedgerWeb::Config.instance.get :ledger_bin_path
+ ledger_file = LedgerWeb::Config.instance.get :ledger_file
+ ledger_format = LedgerWeb::Config.instance.get :ledger_format
+
print " dumping ledger to file...."
file = Tempfile.new('ledger')
system "#{ledger_bin_path} -f #{ledger_file} --format='#{ledger_format}' reg > #{file.path}"
+ replaced_file = Tempfile.new('ledger')
+ replaced_file.write(file.read.gsub('\"', '""'))
+ replaced_file.flush
+
puts "done"
+ return replaced_file
+ end
+
+ def self.load_database(file)
counter = 0
- DB.transaction do
+ @@db.transaction do
- CONFIG.run_hooks(:before_load, DB)
+ LedgerWeb::Config.instance.run_hooks(:before_load, @@db)
print " clearing ledger table...."
- DB["DELETE FROM ledger"].delete
+ @@db["DELETE FROM ledger"].delete
puts "done"
print " loading into database...."
+
CSV.foreach(file.path) do |row|
counter += 1
- row = Hash[*[:xtn_id, :xtn_date, :note, :account, :commodity, :amount, :cleared, :virtual, :tags, :cost].zip(row).flatten]
-
+ row = Hash[*[
+ :xtn_id,
+ :xtn_date,
+ :note,
+ :account,
+ :commodity,
+ :amount,
+ :cleared,
+ :virtual,
+ :tags,
+ :cost
+ ].zip(row).flatten]
+
xtn_date = Date.strptime(row[:xtn_date], '%Y/%m/%d')
row[:xtn_month] = xtn_date.strftime('%Y/%m/01')
row[:xtn_year] = xtn_date.strftime('%Y/01/01')
row[:cost] = row[:cost].gsub(/[^\d\.-]/, '')
- row = CONFIG.run_hooks(:before_insert_row, row)
- DB[:ledger].insert(row)
- CONFIG.run_hooks(:after_insert_row, row)
+ row = LedgerWeb::Config.instance.run_hooks(:before_insert_row, row)
+ @@db[:ledger].insert(row)
+ LedgerWeb::Config.instance.run_hooks(:after_insert_row, row)
end
puts " Running after_load hooks"
- CONFIG.run_hooks(:after_load, DB)
+ LedgerWeb::Config.instance.run_hooks(:after_load, @@db)
end
puts " analyzing ledger table"
- DB.fetch('VACUUM ANALYZE ledger').all
+ @@db.fetch('VACUUM ANALYZE ledger').all
puts "done"
counter
end
@@ -81,11 +114,11 @@ def self.load_prices
HERE
puts "Deleting prices"
- DB["DELETE FROM prices"].delete
+ @@db["DELETE FROM prices"].delete
- rows = DB.fetch(query)
- proc = CONFIG.get :price_function
- skip = CONFIG.get :price_lookup_skip_symbols
+ rows = @@db.fetch(query)
+ proc = LedgerWeb::Config.instance.get :price_function
+ skip = LedgerWeb::Config.instance.get :price_lookup_skip_symbols
puts "Loading prices"
rows.each do |row|
@@ -95,11 +128,12 @@ def self.load_prices
prices = proc.call(row[:commodity], row[:min_date], row[:max_date])
prices.each do |price|
- DB[:prices].insert(:commodity => row[:commodity], :price_date => price[0], :price => price[1])
+ @@db[:prices].insert(:commodity => row[:commodity], :price_date => price[0], :price => price[1])
end
end
- DB.fetch("analyze prices").all
+ @@db.fetch("analyze prices").all
puts "Done loading prices"
end
end
end
+
@@ -8,6 +8,12 @@ def initialize(title, value_type, span_class)
@value_type = value_type
@span_class = span_class
end
+
+ def ==(other)
+ self.title == other.title && \
+ self.value_type == other.value_type && \
+ self.span_class == other.span_class
+ end
end
class Value
@@ -28,7 +34,10 @@ def to_s
class Report
- attr_accessor :error, :fields
+ attr_accessor :error, :fields, :rows
+
+ @@session = {}
+ @@params = {}
def self.session=(session)
@@session = session
@@ -56,7 +65,7 @@ def self.from_query(query)
params[key.to_sym] = val
end
- ds = DB.fetch(query, params)
+ ds = LedgerWeb::Database.handle.fetch(query, params)
report = self.new
begin
row = ds.first
@@ -1,3 +1,3 @@
module LedgerWeb
- VERSION = '1.4.2'
+ VERSION = '1.4.3'
end
@@ -3,23 +3,25 @@
module LedgerWeb
class Watcher
def self.run!
- directory = CONFIG.get :watch_directory
+ directory = LedgerWeb::Config.instance.get :watch_directory
glob = "*"
if directory.nil?
- directory = File.dirname(CONFIG.get :ledger_file)
- glob = File.basename(CONFIG.get :ledger_file)
+ directory = File.dirname(LedgerWeb::Config.instance.get :ledger_file)
+ glob = File.basename(LedgerWeb::Config.instance.get :ledger_file)
end
@@dw = DirectoryWatcher.new directory, :glob => glob
- @@dw.interval = CONFIG.get :watch_interval
- @@dw.stable = CONFIG.get :watch_stable_count
+ @@dw.interval = LedgerWeb::Config.instance.get :watch_interval
+ @@dw.stable = LedgerWeb::Config.instance.get :watch_stable_count
@@dw.add_observer do |*args|
args.each do |event|
if event[0] == :stable
puts "Loading database"
- count = LedgerWeb::Database.load_database
+ LedgerWeb::Database.run_migrations
+ file = LedgerWeb::Database.dump_ledger_to_csv
+ count = LedgerWeb::Database.load_database(file)
puts "Loaded #{count} records"
end
end
Oops, something went wrong.

0 comments on commit 7eefd6a

Please sign in to comment.