Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Tests! Some light refactoring to make tests possible

  • Loading branch information...
commit 7eefd6a683ea3c59f541b7a89a9cf2e75a048a99 1 parent 32c4221
Pete Keen authored
4 Rakefile
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
8 bin/ledger_web
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))
3  ledger_web.gemspec
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
8 lib/ledger_web/app.rb
View
@@ -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
78 lib/ledger_web/config.rb
View
@@ -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
94 lib/ledger_web/db.rb
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
+
13 lib/ledger_web/report.rb
View
@@ -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
2  lib/ledger_web/version.rb
View
@@ -1,3 +1,3 @@
module LedgerWeb
- VERSION = '1.4.2'
+ VERSION = '1.4.3'
end
14 lib/ledger_web/watcher.rb
View
@@ -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
65 test/config_spec.rb
View
@@ -0,0 +1,65 @@
+require File.expand_path(File.dirname(__FILE__) + "/spec_helper")
+require 'ledger_web/config'
+
+describe LedgerWeb::Config do
+ describe "#initialize" do
+
+ it "should get and set simple values" do
+ conf = LedgerWeb::Config.new do |config|
+ config.set :key_one, "value one"
+ config.set :key_two, "value two"
+ end
+
+ conf.get(:key_one).should eq("value one")
+ conf.get(:key_two).should eq("value two")
+ end
+
+ it "should get and run simple hooks" do
+ conf = LedgerWeb::Config.new do |config|
+ config.add_hook :sample do |val|
+ val[:foo] = val[:foo] * 2
+ end
+ end
+
+ test_val = { :foo => 2 }
+ conf.run_hooks(:sample, test_val)
+ test_val[:foo].should eq(4)
+ end
+ end
+
+ describe "#override_with" do
+ it "should override keys" do
+ conf_one = LedgerWeb::Config.new do |config|
+ config.set :key_one, "value one"
+ end
+
+ conf_two = LedgerWeb::Config.new do |config|
+ config.set :key_one, "value two"
+ end
+
+ conf_one.override_with(conf_two)
+
+ conf_one.get(:key_one).should eq("value two")
+ end
+
+ it "should append hooks" do
+ conf_one = LedgerWeb::Config.new do |config|
+ config.add_hook(:sample) do |val|
+ val[:list] << 'one'
+ end
+ end
+
+ conf_two = LedgerWeb::Config.new do |config|
+ config.add_hook(:sample) do |val|
+ val[:list] << 'two'
+ end
+ end
+
+ conf_one.override_with(conf_two)
+
+ test_val = {:list => []}
+ conf_one.run_hooks(:sample, test_val)
+ test_val[:list].should eq(['one', 'two'])
+ end
+ end
+end
222 test/database_load_spec.rb
View
@@ -0,0 +1,222 @@
+require File.expand_path(File.dirname(__FILE__) + "/spec_helper")
+require 'ledger_web/db'
+require 'ledger_web/config'
+require 'csv'
+
+describe LedgerWeb::Database do
+ describe "#dump_ledger_to_csv" do
+ it "should not die" do
+ set_config :ledger_file, fixture('small')
+ file = LedgerWeb::Database.dump_ledger_to_csv
+ end
+
+ it "should dump valid csv" do
+ set_config :ledger_file, fixture('small')
+ file = LedgerWeb::Database.dump_ledger_to_csv
+
+ rows = CSV.read(file.path)
+
+ rows.should eq([
+ ["1", "2012/01/01", "Transaction One", "Assets:Savings", "$", "100", "true", "false", "", "$100.00"],
+ ["1", "2012/01/01", "Transaction One", "Assets:Checking", "$", "200", "true", "false", "", "$200.00"],
+ ["1", "2012/01/01", "Transaction One", "Equity:Opening Balances", "$", "-300", "true", "false", "", "$-300.00"],
+ ["6", "2012/01/02", "Lunch", "Expenses:Lunch", "$", "10", "true", "false", "", "$10.00"],
+ ["6", "2012/01/02", "Lunch", "Assets:Checking", "$", "-10", "true", "false", "", "$-10.00"]
+ ])
+ end
+
+ it "should dump valid csv even with quoted commodities" do
+ set_config :ledger_file, fixture('quoted')
+ file = LedgerWeb::Database.dump_ledger_to_csv
+
+ rows = CSV.read(file.path)
+
+ rows.should eq([
+ ["1", "2012/01/01", "Transaction One", "Assets:Savings", "\"Foo 123\"", "100", "true", "false", "", "100.00 \"Foo 123\""],
+ ["1", "2012/01/01", "Transaction One", "Assets:Checking", "\"Foo 123\"", "200", "true", "false", "", "200.00 \"Foo 123\""],
+ ["1", "2012/01/01", "Transaction One", "Equity:Opening Balances", "\"Foo 123\"", "-300", "true", "false", "", "-300.00 \"Foo 123\""],
+ ["6", "2012/01/02", "Lunch", "Expenses:Lunch", "\"Foo 123\"", "10", "true", "false", "", "10.00 \"Foo 123\""],
+ ["6", "2012/01/02", "Lunch", "Assets:Checking", "\"Foo 123\"", "-10", "true", "false", "", "-10.00 \"Foo 123\""]
+ ])
+ end
+
+ end
+
+ describe "#load_database" do
+ it "should load the database from a csv file" do
+ set_config :ledger_file, fixture('small')
+ file = LedgerWeb::Database.dump_ledger_to_csv
+ count = LedgerWeb::Database.load_database(file)
+ count.should eq(5)
+
+ LedgerWeb::Database.handle[:ledger].count().should eq(5)
+
+ convert_bd_to_string(LedgerWeb::Database.handle[:ledger].all()).should eq([
+ {
+ :xtn_date => Date.new(2012,1,1),
+ :checknum => nil,
+ :note => 'Transaction One',
+ :account => 'Assets:Savings',
+ :commodity => '$',
+ :amount => "100.0",
+ :tags => '',
+ :xtn_month => Date.new(2012,1,1),
+ :xtn_year => Date.new(2012,1,1),
+ :virtual => false,
+ :xtn_id => 1,
+ :cleared => true,
+ :cost => "100.0"
+ },
+ {
+ :xtn_date => Date.new(2012,1,1),
+ :checknum => nil,
+ :note => 'Transaction One',
+ :account => 'Assets:Checking',
+ :commodity => '$',
+ :amount => "200.0",
+ :tags => '',
+ :xtn_month => Date.new(2012,1,1),
+ :xtn_year => Date.new(2012,1,1),
+ :virtual => false,
+ :xtn_id => 1,
+ :cleared => true,
+ :cost => "200.0"
+ },
+ {
+ :xtn_date => Date.new(2012,1,1),
+ :checknum => nil,
+ :note => 'Transaction One',
+ :account => 'Equity:Opening Balances',
+ :commodity => '$',
+ :amount => "-300.0",
+ :tags => '',
+ :xtn_month => Date.new(2012,1,1),
+ :xtn_year => Date.new(2012,1,1),
+ :virtual => false,
+ :xtn_id => 1,
+ :cleared => true,
+ :cost => "-300.0"
+ },
+ {
+ :xtn_date => Date.new(2012,1,2),
+ :checknum => nil,
+ :note => 'Lunch',
+ :account => 'Expenses:Lunch',
+ :commodity => '$',
+ :amount => "10.0",
+ :tags => '',
+ :xtn_month => Date.new(2012,1,1),
+ :xtn_year => Date.new(2012,1,1),
+ :virtual => false,
+ :xtn_id => 6,
+ :cleared => true,
+ :cost => "10.0"
+ },
+ {
+ :xtn_date => Date.new(2012,1,2),
+ :checknum => nil,
+ :note => 'Lunch',
+ :account => 'Assets:Checking',
+ :commodity => '$',
+ :amount => "-10.0",
+ :tags => '',
+ :xtn_month => Date.new(2012,1,1),
+ :xtn_year => Date.new(2012,1,1),
+ :virtual => false,
+ :xtn_id => 6,
+ :cleared => true,
+ :cost => "-10.0"
+ },
+ ])
+
+ end
+
+ it "should load the database from a csv file containing quoted things" do
+ set_config :ledger_file, fixture('quoted')
+ file = LedgerWeb::Database.dump_ledger_to_csv
+ count = LedgerWeb::Database.load_database(file)
+ count.should eq(5)
+
+ LedgerWeb::Database.handle[:ledger].count().should eq(5)
+
+ convert_bd_to_string(LedgerWeb::Database.handle[:ledger].all()).should eq([
+ {
+ :xtn_date => Date.new(2012,1,1),
+ :checknum => nil,
+ :note => 'Transaction One',
+ :account => 'Assets:Savings',
+ :commodity => '"Foo 123"',
+ :amount => "100.0",
+ :tags => '',
+ :xtn_month => Date.new(2012,1,1),
+ :xtn_year => Date.new(2012,1,1),
+ :virtual => false,
+ :xtn_id => 1,
+ :cleared => true,
+ :cost => "100.0"
+ },
+ {
+ :xtn_date => Date.new(2012,1,1),
+ :checknum => nil,
+ :note => 'Transaction One',
+ :account => 'Assets:Checking',
+ :commodity => '"Foo 123"',
+ :amount => "200.0",
+ :tags => '',
+ :xtn_month => Date.new(2012,1,1),
+ :xtn_year => Date.new(2012,1,1),
+ :virtual => false,
+ :xtn_id => 1,
+ :cleared => true,
+ :cost => "200.0"
+ },
+ {
+ :xtn_date => Date.new(2012,1,1),
+ :checknum => nil,
+ :note => 'Transaction One',
+ :account => 'Equity:Opening Balances',
+ :commodity => '"Foo 123"',
+ :amount => "-300.0",
+ :tags => '',
+ :xtn_month => Date.new(2012,1,1),
+ :xtn_year => Date.new(2012,1,1),
+ :virtual => false,
+ :xtn_id => 1,
+ :cleared => true,
+ :cost => "-300.0"
+ },
+ {
+ :xtn_date => Date.new(2012,1,2),
+ :checknum => nil,
+ :note => 'Lunch',
+ :account => 'Expenses:Lunch',
+ :commodity => '"Foo 123"',
+ :amount => "10.0",
+ :tags => '',
+ :xtn_month => Date.new(2012,1,1),
+ :xtn_year => Date.new(2012,1,1),
+ :virtual => false,
+ :xtn_id => 6,
+ :cleared => true,
+ :cost => "10.0"
+ },
+ {
+ :xtn_date => Date.new(2012,1,2),
+ :checknum => nil,
+ :note => 'Lunch',
+ :account => 'Assets:Checking',
+ :commodity => '"Foo 123"',
+ :amount => "-10.0",
+ :tags => '',
+ :xtn_month => Date.new(2012,1,1),
+ :xtn_year => Date.new(2012,1,1),
+ :virtual => false,
+ :xtn_id => 6,
+ :cleared => true,
+ :cost => "-10.0"
+ },
+ ])
+
+ end
+ end
+end
8 test/fixtures/quoted.dat
View
@@ -0,0 +1,8 @@
+2012/01/01 * Transaction One
+ Assets:Savings 100.00 "Foo 123"
+ Assets:Checking 200.00 "Foo 123"
+ Equity:Opening Balances
+
+2012/01/02 * Lunch
+ Expenses:Lunch 10.00 "Foo 123"
+ Assets:Checking
8 test/fixtures/small.dat
View
@@ -0,0 +1,8 @@
+2012/01/01 * Transaction One
+ Assets:Savings $100.00
+ Assets:Checking $200.00
+ Equity:Opening Balances
+
+2012/01/02 * Lunch
+ Expenses:Lunch $10.00
+ Assets:Checking
53 test/report_spec.rb
View
@@ -0,0 +1,53 @@
+require File.expand_path(File.dirname(__FILE__) + "/spec_helper")
+require 'ledger_web/report'
+
+describe LedgerWeb::Report do
+ describe "#from_query" do
+ it "should run the query" do
+
+ LedgerWeb::Report.session = {:from => '2012/01/01', :to => '2012/01/01'}
+
+ load_fixture('small')
+
+ report = LedgerWeb::Report.from_query("select count(1) as foo from ledger")
+ rows = []
+ report.each_row do |row|
+ rows << row
+ end
+
+ rows[0][0][0].should eq(5)
+ rows[0][0][1].should eq(LedgerWeb::Field.new('foo', 'number', 'pull-right'))
+ end
+ end
+
+ describe "#pivot" do
+ it "should create the correct fields" do
+ LedgerWeb::Report.session = {:from => '2012/01/01', :to => '2012/01/01'}
+ load_fixture('small')
+
+ report = LedgerWeb::Report.from_query("select xtn_month, account, sum(amount) from ledger group by xtn_month, account")
+ report = report.pivot("account", "asc")
+
+ report.fields.should eq([
+ string_field('xtn_month'),
+ number_field('Assets:Checking'),
+ number_field('Assets:Savings'),
+ number_field('Equity:Opening Balances'),
+ number_field('Expenses:Lunch')
+ ])
+
+ end
+
+ it "should put the values in the right place" do
+ LedgerWeb::Report.session = {:from => '2012/01/01', :to => '2012/01/01'}
+ load_fixture('small')
+
+ report = LedgerWeb::Report.from_query("select xtn_month, account, sum(amount)::integer from ledger group by xtn_month, account")
+ report = report.pivot("account", "asc")
+
+ report.rows.should eq([
+ [Date.new(2012,1,1), 190, 100, -300, 10]
+ ])
+ end
+ end
+end
73 test/spec_helper.rb
View
@@ -0,0 +1,73 @@
+$:.unshift(File.join(File.dirname(__FILE__), "..", "lib"))
+
+require 'rspec'
+require 'ledger_web/config'
+require 'ledger_web/db'
+require 'ledger_web/report'
+require 'database_cleaner'
+
+RSpec.configure do |config|
+
+ config.before(:suite) do
+
+ system 'createdb ledger-test'
+ LedgerWeb::Config.should_load_user_config = false
+ LedgerWeb::Config.instance.set :database_url, 'postgres://localhost/ledger-test'
+ LedgerWeb::Database.connect
+ LedgerWeb::Database.run_migrations
+
+ DatabaseCleaner.strategy = :truncation
+ DatabaseCleaner.clean_with(:truncation)
+ end
+
+ config.before(:each) do
+ DatabaseCleaner.start
+ end
+
+ config.after(:each) do
+ DatabaseCleaner.clean
+ end
+
+ config.after(:suite) do
+ LedgerWeb::Database.close
+ system 'dropdb ledger-test'
+ end
+
+end
+
+def set_config(key, val)
+ LedgerWeb::Config.instance.set key, val
+end
+
+def fixture(name)
+ File.join(File.dirname(__FILE__), "fixtures", name + ".dat")
+end
+
+def convert_bd_to_string(objs)
+ objs.map do |obj|
+ obj.each do |k,v|
+ if v.is_a? BigDecimal
+ obj[k] = v.truncate(2).to_s('F')
+ end
+ end
+ obj
+ end
+end
+
+def load_fixture(name)
+ set_config :ledger_file, fixture(name)
+ file = LedgerWeb::Database.dump_ledger_to_csv
+ LedgerWeb::Database.load_database(file)
+end
+
+def field(name, type, css_class)
+ LedgerWeb::Field.new(name, type, css_class)
+end
+
+def string_field(name)
+ field(name, 'string', 'pull-left')
+end
+
+def number_field(name)
+ field(name, 'number', 'pull-right')
+end
Please sign in to comment.
Something went wrong with that request. Please try again.