reckon 0.5.0 → 0.6.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.
@@ -121,8 +121,14 @@ module Reckon
121
121
  def parse(ledger)
122
122
  @entries = []
123
123
  new_entry = {}
124
+ in_comment = false
125
+ comment_chars = ';#%*|'
124
126
  ledger.strip.split("\n").each do |entry|
125
- next if entry =~ /^\s*$/ || entry =~ /^\s*;/
127
+ # strip comment lines
128
+ in_comment = true if entry == 'comment'
129
+ in_comment = false if entry == 'end comment'
130
+ next if in_comment
131
+ next if entry =~ /^\s*[#{comment_chars}]/
126
132
 
127
133
  # (date, type, code, description), type and code are optional
128
134
  if (m = entry.match(%r{^(\d+[\d/-]+)\s+([*!])?\s*(\([^)]+\))?\s*(.*)$}))
@@ -134,7 +140,11 @@ module Reckon
134
140
  desc: m[4].strip,
135
141
  accounts: []
136
142
  }
143
+ elsif entry =~ /^\s*$/ && new_entry[:date]
144
+ add_entry(new_entry)
145
+ new_entry = {}
137
146
  elsif new_entry[:date] && entry =~ /^\s+/
147
+ LOGGER.info("Adding new account #{entry}")
138
148
  new_entry[:accounts] << parse_account_line(entry)
139
149
  else
140
150
  LOGGER.info("Unknown entry type: #{entry}")
@@ -0,0 +1,4 @@
1
+ module Reckon
2
+ LOGGER = Logger.new(STDERR)
3
+ LOGGER.level = Logger::WARN
4
+ end
@@ -71,12 +71,13 @@ module Reckon
71
71
 
72
72
  def Money::likelihood( entry )
73
73
  money_score = 0
74
- money_score += 20 if entry[/^[\-\+\(]{0,2}\$/]
74
+ # digits separated by , or . with no more than 2 trailing digits
75
+ money_score += 40 if entry.match(/\d+[,.]\d{2}[^\d]*$/)
75
76
  money_score += 10 if entry[/^\$?\-?\$?\d+[\.,\d]*?[\.,]\d\d$/]
76
77
  money_score += 10 if entry[/\d+[\.,\d]*?[\.,]\d\d$/]
77
78
  money_score += entry.gsub(/[^\d\.\-\+,\(\)]/, '').length if entry.length < 7
78
- money_score -= entry.length if entry.length > 8
79
- money_score -= 20 if entry !~ /^[\$\+\.\-,\d\(\)]+$/
79
+ money_score -= entry.length if entry.length > 12
80
+ money_score -= 20 if (entry !~ /^[\$\+\.\-,\d\(\)]+$/) && entry.length > 0
80
81
  money_score
81
82
  end
82
83
  end
@@ -112,60 +113,4 @@ module Reckon
112
113
  self
113
114
  end
114
115
  end
115
-
116
- class DateColumn < Array
117
- attr_accessor :endian_precedence
118
- def initialize( arr = [], options = {} )
119
- arr.each do |value|
120
- if options[:date_format]
121
- begin
122
- value = Date.strptime(value, options[:date_format])
123
- rescue
124
- puts "I'm having trouble parsing #{value} with the desired format: #{options[:date_format]}"
125
- exit 1
126
- end
127
- else
128
- value = [$1, $2, $3].join("/") if value =~ /^(\d{4})(\d{2})(\d{2})\d+\[\d+\:GMT\]$/ # chase format
129
- value = [$3, $2, $1].join("/") if value =~ /^(\d{2})\.(\d{2})\.(\d{4})$/ # german format
130
- value = [$3, $2, $1].join("/") if value =~ /^(\d{2})\-(\d{2})\-(\d{4})$/ # nordea format
131
- value = [$1, $2, $3].join("/") if value =~ /^(\d{4})\-(\d{2})\-(\d{2})$/ # yyyy-mm-dd format
132
- value = [$1, $2, $3].join("/") if value =~ /^(\d{4})(\d{2})(\d{2})/ # yyyymmdd format
133
-
134
-
135
- unless @endian_precedence # Try to detect endian_precedence
136
- reg_match = value.match( /^(\d\d)\/(\d\d)\/\d\d\d?\d?/ )
137
- # If first one is not \d\d/\d\d/\d\d\d?\d set it to default
138
- if !reg_match
139
- @endian_precedence = [:middle, :little]
140
- elsif reg_match[1].to_i > 12
141
- @endian_precedence = [:little]
142
- elsif reg_match[2].to_i > 12
143
- @endian_precedence = [:middle]
144
- end
145
- end
146
- end
147
- self.push( value )
148
- end
149
- # if endian_precedence still nil, raise error
150
- unless @endian_precedence || options[:date_format]
151
- raise( "Unable to determine date format. Please specify using --date-format" )
152
- end
153
- end
154
-
155
- def for( index )
156
- value = self.at( index )
157
- guess = Chronic.parse(value, :context => :past,
158
- :endian_precedence => @endian_precedence )
159
- if guess.to_i < 953236800 && value =~ /\//
160
- guess = Chronic.parse((value.split("/")[0...-1] + [(2000 + value.split("/").last.to_i).to_s]).join("/"), :context => :past,
161
- :endian_precedence => @endian_precedence)
162
- end
163
- guess
164
- end
165
-
166
- def pretty_for(index)
167
- self.for(index).to_date.iso8601
168
- end
169
-
170
- end
171
116
  end
@@ -0,0 +1,3 @@
1
+ module Reckon
2
+ VERSION="0.6.0"
3
+ end
@@ -1,5 +1,5 @@
1
1
  $:.push File.expand_path("../lib", __FILE__)
2
- require 'reckon/version'
2
+ require_relative 'lib/reckon/version'
3
3
 
4
4
  Gem::Specification.new do |s|
5
5
  s.name = %q{reckon}
@@ -9,10 +9,11 @@ Gem::Specification.new do |s|
9
9
  s.homepage = %q{https://github.com/cantino/reckon}
10
10
  s.description = %q{Reckon automagically converts CSV files for use with the command-line accounting tool Ledger. It also helps you to select the correct accounts associated with the CSV data using Bayesian machine learning.}
11
11
  s.summary = %q{Utility for interactively converting and labeling CSV files for the Ledger accounting tool.}
12
+ s.licenses = ['MIT']
12
13
 
13
14
  s.files = `git ls-files`.split("\n")
14
15
  s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
15
- s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
16
+ s.executables = `git ls-files -- bin/*`.split("\n").map { |f| File.basename(f) }
16
17
  s.require_paths = ["lib"]
17
18
 
18
19
  s.add_development_dependency "rspec", ">= 1.2.9"
@@ -20,6 +21,5 @@ Gem::Specification.new do |s|
20
21
  s.add_development_dependency "rantly", "= 1.2.0"
21
22
  s.add_runtime_dependency "chronic", ">= 0.3.0"
22
23
  s.add_runtime_dependency "highline", ">= 1.5.2"
23
- s.add_runtime_dependency "terminal-table", ">= 1.4.2"
24
24
  s.add_runtime_dependency "rchardet", ">= 1.8.0"
25
25
  end
@@ -0,0 +1,8 @@
1
+ 01/09/2015,05354 SUBWAY,8.19,,1000.00
2
+ 02/18/2015,WENDY'S #6338,8.55,,1000.00
3
+ 02/25/2015,WENDY'S #6338,8.55,,1000.00
4
+ 02/25/2015,WENDY'S #6338,9.14,,1000.00
5
+ 02/27/2015,WENDY'S #6338,5.85,,1000.00
6
+ 03/09/2015,WENDY'S #6338,17.70,,1000.00
7
+ 03/16/2015,WENDY'S #6338,11.15,,1000.00
8
+ 03/23/2015,WENDY'S,10.12,,1000.00
@@ -0,0 +1,9 @@
1
+ Expenses:
2
+ Dining:
3
+ Coffee:
4
+ - 'STARBUCKS'
5
+ - 'TIM HORTON'
6
+ Resturant:
7
+ - 'WENDY''S'
8
+ - 'SUBWAY'
9
+ - 'BARAKAT'
@@ -0,0 +1,2 @@
1
+ Visa, 4514010000000000, 2020-02-20, , GOJEK SINGAPORE, 8.10 SGD @ .976500000000, -7.91, D
2
+ Visa, 4514010000000000, 2020-02-20, , GOJEK SINGAPORE, 6.00 SGD @ .976600000000, -5.86, D
@@ -0,0 +1,3 @@
1
+ "Date","Note","Amount"
2
+ "2012/3/22","DEPOSIT","50.00"
3
+ "2012/3/23","TRANSFER TO SAVINGS","-10.00"
@@ -8,7 +8,7 @@ describe Reckon::App do
8
8
  context 'with chase csv input' do
9
9
  before do
10
10
  @chase = Reckon::App.new(string: BANK_CSV)
11
- @chase.learn_from(BANK_LEDGER)
11
+ @chase.learn_from_ledger(BANK_LEDGER)
12
12
  @rows = []
13
13
  @chase.each_row_backwards { |row| @rows.push(row) }
14
14
  end
@@ -68,7 +68,7 @@ describe Reckon::App do
68
68
  end
69
69
 
70
70
  it 'should learn from a ledger file' do
71
- chase.learn_from( BANK_LEDGER )
71
+ chase.learn_from_ledger(BANK_LEDGER)
72
72
  chase.walk_backwards
73
73
  output_file.string.scan('Expenses:Books').count.should == 1
74
74
  end
@@ -107,6 +107,36 @@ describe Reckon::App do
107
107
  end
108
108
  end
109
109
 
110
+ context "Issue #64 - regression test" do
111
+ it 'should work for simple file' do
112
+ rows = []
113
+ app = Reckon::App.new(file: fixture_path('test_money_column.csv'))
114
+ expect { app.each_row_backwards { |n| rows << n } }
115
+ .to output(/Skipping row: 'Date, Note, Amount'/).to_stderr_from_any_process
116
+ expect(rows.length).to eq(2)
117
+ expect(rows[0][:pretty_date]).to eq('2012-03-22')
118
+ expect(rows[0][:pretty_money]).to eq(' $50.00')
119
+ expect(rows[1][:pretty_date]).to eq('2012-03-23')
120
+ expect(rows[1][:pretty_money]).to eq('-$10.00')
121
+ end
122
+ end
123
+
124
+ context 'Issue #51 - regression test' do
125
+ it 'should assign correct accounts with tokens' do
126
+ output = StringIO.new
127
+ Reckon::App.new(
128
+ file: fixture_path('51-sample.csv'),
129
+ unattended: true,
130
+ account_tokens_file: fixture_path('51-tokens.yml'),
131
+ ignore_columns: [5],
132
+ bank_account: 'Assets:Chequing',
133
+ output_file: output
134
+ ).walk_backwards
135
+ expect(output.string).not_to include('Income:Unknown')
136
+ expect(output.string.scan('Expenses:Dining:Resturant').size).to eq(8)
137
+ end
138
+ end
139
+
110
140
  #DATA
111
141
  BANK_CSV = (<<-CSV).strip
112
142
  DEBIT,20091224120000[0:GMT],"HOST 037196321563 MO 12/22SLICEHOST",-85.00
@@ -5,38 +5,29 @@ require_relative "../spec_helper"
5
5
  require 'rubygems'
6
6
  require_relative '../../lib/reckon'
7
7
 
8
- Reckon::CSVParser.settings[:testing] = true
9
-
10
8
  describe Reckon::CSVParser do
11
- before do
12
- @chase = Reckon::CSVParser.new(file: fixture_path('chase.csv'))
13
- @some_other_bank = Reckon::CSVParser.new(file: fixture_path('some_other.csv'))
14
- @two_money_columns = Reckon::CSVParser.new(file: fixture_path('two_money_columns.csv'))
15
- @suntrust_csv = Reckon::CSVParser.new(file: fixture_path('suntrust.csv'))
16
- @simple_csv = Reckon::CSVParser.new(file: fixture_path('simple.csv'))
17
- @nationwide = Reckon::CSVParser.new(file: fixture_path('nationwide.csv'), csv_separator: ',', suffixed: true, currency: "POUND")
18
- @german_date = Reckon::CSVParser.new(file: fixture_path('german_date_example.csv'))
19
- @danish_kroner_nordea = Reckon::CSVParser.new(file: fixture_path('danish_kroner_nordea_example.csv'), csv_separator: ';', comma_separates_cents: true)
20
- @yyyymmdd_date = Reckon::CSVParser.new(file: fixture_path('yyyymmdd_date_example.csv'))
21
- @spanish_date = Reckon::CSVParser.new(file: fixture_path('spanish_date_example.csv'), date_format: '%d/%m/%Y')
22
- @english_date = Reckon::CSVParser.new(file: fixture_path('english_date_example.csv'))
23
- @ing_csv = Reckon::CSVParser.new(file: fixture_path('ing.csv'), comma_separates_cents: true )
24
- @austrian_csv = Reckon::CSVParser.new(file: fixture_path('austrian_example.csv'), comma_separates_cents: true, csv_separator: ';' )
25
- @french_csv = Reckon::CSVParser.new(file: fixture_path('french_example.csv'), csv_separator: ';', comma_separates_cents: true)
26
- @broker_canada = Reckon::CSVParser.new(file: fixture_path('broker_canada_example.csv'))
27
- @intuit_mint = Reckon::CSVParser.new(file: fixture_path('intuit_mint_example.csv'))
28
- end
29
-
30
- it "should be in testing mode" do
31
- @chase.settings[:testing].should be true
32
- Reckon::CSVParser.settings[:testing].should be true
33
- end
9
+ let(:chase) { Reckon::CSVParser.new(file: fixture_path('chase.csv')) }
10
+ let(:some_other_bank) { Reckon::CSVParser.new(file: fixture_path('some_other.csv')) }
11
+ let(:two_money_columns) { Reckon::CSVParser.new(file: fixture_path('two_money_columns.csv')) }
12
+ let(:suntrust_csv) { Reckon::CSVParser.new(file: fixture_path('suntrust.csv')) }
13
+ let(:simple_csv) { Reckon::CSVParser.new(file: fixture_path('simple.csv')) }
14
+ let(:nationwide) { Reckon::CSVParser.new(file: fixture_path('nationwide.csv'), csv_separator: ',', suffixed: true, currency: "POUND") }
15
+ let(:german_date) { Reckon::CSVParser.new(file: fixture_path('german_date_example.csv')) }
16
+ let(:danish_kroner_nordea) { Reckon::CSVParser.new(file: fixture_path('danish_kroner_nordea_example.csv'), csv_separator: ';', comma_separates_cents: true) }
17
+ let(:yyyymmdd_date) { Reckon::CSVParser.new(file: fixture_path('yyyymmdd_date_example.csv')) }
18
+ let(:spanish_date) { Reckon::CSVParser.new(file: fixture_path('spanish_date_example.csv'), date_format: '%d/%m/%Y') }
19
+ let(:english_date) { Reckon::CSVParser.new(file: fixture_path('english_date_example.csv')) }
20
+ let(:ing_csv) { Reckon::CSVParser.new(file: fixture_path('ing.csv'), comma_separates_cents: true ) }
21
+ let(:austrian_csv) { Reckon::CSVParser.new(file: fixture_path('austrian_example.csv'), comma_separates_cents: true, csv_separator: ';' ) }
22
+ let(:french_csv) { Reckon::CSVParser.new(file: fixture_path('french_example.csv'), csv_separator: ';', comma_separates_cents: true) }
23
+ let(:broker_canada) { Reckon::CSVParser.new(file: fixture_path('broker_canada_example.csv')) }
24
+ let(:intuit_mint) { Reckon::CSVParser.new(file: fixture_path('intuit_mint_example.csv')) }
34
25
 
35
26
  describe "parse" do
36
27
  it "should use binary encoding if none specified and chardet fails" do
37
28
  allow(CharDet).to receive(:detect).and_return({'encoding' => nil})
38
29
  app = Reckon::CSVParser.new(file: fixture_path("extratofake.csv"))
39
- expect(app.try_encoding("foobarbaz")).to eq("BINARY")
30
+ expect(app.send(:try_encoding, "foobarbaz")).to eq("BINARY")
40
31
  end
41
32
 
42
33
  it "should work with foreign character encodings" do
@@ -76,8 +67,8 @@ describe Reckon::CSVParser do
76
67
 
77
68
  describe "columns" do
78
69
  it "should return the csv transposed" do
79
- @simple_csv.columns.should == [["entry1", "entry4"], ["entry2", "entry5"], ["entry3", "entry6"]]
80
- @chase.columns.length.should == 4
70
+ simple_csv.columns.should == [["entry1", "entry4"], ["entry2", "entry5"], ["entry3", "entry6"]]
71
+ chase.columns.length.should == 4
81
72
  end
82
73
 
83
74
  it "should be ok with empty lines" do
@@ -88,46 +79,44 @@ describe Reckon::CSVParser do
88
79
  end
89
80
 
90
81
  describe "detect_columns" do
91
- before do
92
- @harder_date_example_csv = Reckon::CSVParser.new(file: fixture_path('harder_date_example.csv'))
93
- end
82
+ let(:harder_date_example_csv) { Reckon::CSVParser.new(file: fixture_path('harder_date_example.csv')) }
94
83
 
95
84
  it "should detect the money column" do
96
- @chase.money_column_indices.should == [3]
97
- @some_other_bank.money_column_indices.should == [3]
98
- @two_money_columns.money_column_indices.should == [3, 4]
99
- @suntrust_csv.money_column_indices.should == [3, 4]
100
- @nationwide.money_column_indices.should == [3, 4]
101
- @harder_date_example_csv.money_column_indices.should == [1]
102
- @danish_kroner_nordea.money_column_indices.should == [3]
103
- @yyyymmdd_date.money_column_indices.should == [3]
104
- @ing_csv.money_column_indices.should == [6]
105
- @austrian_csv.money_column_indices.should == [4]
106
- @french_csv.money_column_indices.should == [4]
107
- @broker_canada.money_column_indices.should == [8]
108
- @intuit_mint.money_column_indices.should == [3]
85
+ chase.money_column_indices.should == [3]
86
+ some_other_bank.money_column_indices.should == [3]
87
+ two_money_columns.money_column_indices.should == [3, 4]
88
+ suntrust_csv.money_column_indices.should == [3, 4]
89
+ nationwide.money_column_indices.should == [3, 4]
90
+ harder_date_example_csv.money_column_indices.should == [1]
91
+ danish_kroner_nordea.money_column_indices.should == [3]
92
+ yyyymmdd_date.money_column_indices.should == [3]
93
+ ing_csv.money_column_indices.should == [6]
94
+ austrian_csv.money_column_indices.should == [4]
95
+ french_csv.money_column_indices.should == [4]
96
+ broker_canada.money_column_indices.should == [8]
97
+ intuit_mint.money_column_indices.should == [3]
109
98
  end
110
99
 
111
100
  it "should detect the date column" do
112
- @chase.date_column_index.should == 1
113
- @some_other_bank.date_column_index.should == 1
114
- @two_money_columns.date_column_index.should == 0
115
- @harder_date_example_csv.date_column_index.should == 0
116
- @danish_kroner_nordea.date_column_index.should == 0
117
- @yyyymmdd_date.date_column_index.should == 1
118
- @french_csv.date_column_index.should == 1
119
- @broker_canada.date_column_index.should == 0
120
- @intuit_mint.date_column_index.should == 0
101
+ chase.date_column_index.should == 1
102
+ some_other_bank.date_column_index.should == 1
103
+ two_money_columns.date_column_index.should == 0
104
+ harder_date_example_csv.date_column_index.should == 0
105
+ danish_kroner_nordea.date_column_index.should == 0
106
+ yyyymmdd_date.date_column_index.should == 1
107
+ french_csv.date_column_index.should == 1
108
+ broker_canada.date_column_index.should == 0
109
+ intuit_mint.date_column_index.should == 0
121
110
  Reckon::CSVParser.new(:string => '2014-01-13,"22211100000",-10').date_column_index.should == 0
122
111
  end
123
112
 
124
113
  it "should consider all other columns to be description columns" do
125
- @chase.description_column_indices.should == [0, 2]
126
- @some_other_bank.description_column_indices.should == [0, 2]
127
- @two_money_columns.description_column_indices.should == [1, 2, 5]
128
- @harder_date_example_csv.description_column_indices.should == [2, 3, 4, 5, 6, 7]
129
- @danish_kroner_nordea.description_column_indices.should == [1, 2, 4]
130
- @yyyymmdd_date.description_column_indices.should == [0, 2]
114
+ chase.description_column_indices.should == [0, 2]
115
+ some_other_bank.description_column_indices.should == [0, 2]
116
+ two_money_columns.description_column_indices.should == [1, 2, 5]
117
+ harder_date_example_csv.description_column_indices.should == [2, 3, 4, 5, 6, 7]
118
+ danish_kroner_nordea.description_column_indices.should == [1, 2, 4]
119
+ yyyymmdd_date.description_column_indices.should == [0, 2]
131
120
  end
132
121
  end
133
122
 
@@ -143,36 +132,36 @@ describe Reckon::CSVParser do
143
132
 
144
133
  describe "money_for" do
145
134
  it "should return the appropriate fields" do
146
- @chase.money_for(1).should == -20
147
- @chase.money_for(4).should == 1558.52
148
- @chase.money_for(7).should == -116.22
149
- @some_other_bank.money_for(1).should == -20
150
- @some_other_bank.money_for(4).should == 1558.52
151
- @some_other_bank.money_for(7).should == -116.22
152
- @two_money_columns.money_for(0).should == -76
153
- @two_money_columns.money_for(1).should == 327.49
154
- @two_money_columns.money_for(2).should == -800
155
- @two_money_columns.money_for(3).should == -88.55
156
- @two_money_columns.money_for(4).should == 88.55
157
- @nationwide.money_for(0).should == 500.00
158
- @nationwide.money_for(1).should == -20.00
159
- @danish_kroner_nordea.money_for(0).should == -48.00
160
- @danish_kroner_nordea.money_for(1).should == -79.00
161
- @danish_kroner_nordea.money_for(2).should == 497.90
162
- @danish_kroner_nordea.money_for(3).should == -995.00
163
- @danish_kroner_nordea.money_for(4).should == -3452.90
164
- @danish_kroner_nordea.money_for(5).should == -655.00
165
- @yyyymmdd_date.money_for(0).should == -123.45
166
- @ing_csv.money_for(0).should == -136.13
167
- @ing_csv.money_for(1).should == 375.00
168
- @austrian_csv.money_for(0).should == -18.00
169
- @austrian_csv.money_for(2).should == 120.00
170
- @french_csv.money_for(0).should == -10.00
171
- @french_csv.money_for(1).should == -5.76
172
- @broker_canada.money_for(0).should == 12.55
173
- @broker_canada.money_for(1).should == -81.57
174
- @intuit_mint.money_for(0).should == 0.01
175
- @intuit_mint.money_for(1).should == -331.63
135
+ chase.money_for(1).should == -20
136
+ chase.money_for(4).should == 1558.52
137
+ chase.money_for(7).should == -116.22
138
+ some_other_bank.money_for(1).should == -20
139
+ some_other_bank.money_for(4).should == 1558.52
140
+ some_other_bank.money_for(7).should == -116.22
141
+ two_money_columns.money_for(0).should == -76
142
+ two_money_columns.money_for(1).should == 327.49
143
+ two_money_columns.money_for(2).should == -800
144
+ two_money_columns.money_for(3).should == -88.55
145
+ two_money_columns.money_for(4).should == 88.55
146
+ nationwide.money_for(0).should == 500.00
147
+ nationwide.money_for(1).should == -20.00
148
+ danish_kroner_nordea.money_for(0).should == -48.00
149
+ danish_kroner_nordea.money_for(1).should == -79.00
150
+ danish_kroner_nordea.money_for(2).should == 497.90
151
+ danish_kroner_nordea.money_for(3).should == -995.00
152
+ danish_kroner_nordea.money_for(4).should == -3452.90
153
+ danish_kroner_nordea.money_for(5).should == -655.00
154
+ yyyymmdd_date.money_for(0).should == -123.45
155
+ ing_csv.money_for(0).should == -136.13
156
+ ing_csv.money_for(1).should == 375.00
157
+ austrian_csv.money_for(0).should == -18.00
158
+ austrian_csv.money_for(2).should == 120.00
159
+ french_csv.money_for(0).should == -10.00
160
+ french_csv.money_for(1).should == -5.76
161
+ broker_canada.money_for(0).should == 12.55
162
+ broker_canada.money_for(1).should == -81.57
163
+ intuit_mint.money_for(0).should == 0.01
164
+ intuit_mint.money_for(1).should == -331.63
176
165
  end
177
166
 
178
167
  it "should handle the comma_separates_cents option correctly" do
@@ -200,59 +189,63 @@ describe Reckon::CSVParser do
200
189
 
201
190
  describe "date_for" do
202
191
  it "should return a parsed date object" do
203
- @chase.date_for(1).year.should == Time.parse("2009/12/24").year
204
- @chase.date_for(1).month.should == Time.parse("2009/12/24").month
205
- @chase.date_for(1).day.should == Time.parse("2009/12/24").day
206
- @some_other_bank.date_for(1).year.should == Time.parse("2010/12/24").year
207
- @some_other_bank.date_for(1).month.should == Time.parse("2010/12/24").month
208
- @some_other_bank.date_for(1).day.should == Time.parse("2010/12/24").day
209
- @german_date.date_for(1).year.should == Time.parse("2009/12/24").year
210
- @german_date.date_for(1).month.should == Time.parse("2009/12/24").month
211
- @german_date.date_for(1).day.should == Time.parse("2009/12/24").day
212
- @danish_kroner_nordea.date_for(0).year.should == Time.parse("2012/11/16").year
213
- @danish_kroner_nordea.date_for(0).month.should == Time.parse("2012/11/16").month
214
- @danish_kroner_nordea.date_for(0).day.should == Time.parse("2012/11/16").day
215
- @yyyymmdd_date.date_for(0).year.should == Time.parse("2012/12/31").year
216
- @yyyymmdd_date.date_for(0).month.should == Time.parse("2012/12/31").month
217
- @yyyymmdd_date.date_for(0).day.should == Time.parse("2012/12/31").day
218
- @spanish_date.date_for(1).year.should == Time.parse("2009/12/02").year
219
- @spanish_date.date_for(1).month.should == Time.parse("2009/12/02").month
220
- @spanish_date.date_for(1).day.should == Time.parse("2009/12/02").day
221
- @english_date.date_for(1).year.should == Time.parse("2009/12/24").year
222
- @english_date.date_for(1).month.should == Time.parse("2009/12/24").month
223
- @english_date.date_for(1).day.should == Time.parse("2009/12/24").day
224
- @nationwide.date_for(1).month.should == 10
225
- @ing_csv.date_for(1).month.should == Time.parse("2012/11/12").month
226
- @ing_csv.date_for(1).day.should == Time.parse("2012/11/12").day
227
- @broker_canada.date_for(5).year.should == 2014
228
- @broker_canada.date_for(5).month.should == 1
229
- @broker_canada.date_for(5).day.should == 7
230
- @intuit_mint.date_for(1).year.should == 2014
231
- @intuit_mint.date_for(1).month.should == 2
232
- @intuit_mint.date_for(1).day.should == 3
192
+ chase.date_for(1).year.should == Time.parse("2009/12/24").year
193
+ chase.date_for(1).month.should == Time.parse("2009/12/24").month
194
+ chase.date_for(1).day.should == Time.parse("2009/12/24").day
195
+ some_other_bank.date_for(1).year.should == Time.parse("2010/12/24").year
196
+ some_other_bank.date_for(1).month.should == Time.parse("2010/12/24").month
197
+ some_other_bank.date_for(1).day.should == Time.parse("2010/12/24").day
198
+ german_date.date_for(1).year.should == Time.parse("2009/12/24").year
199
+ german_date.date_for(1).month.should == Time.parse("2009/12/24").month
200
+ german_date.date_for(1).day.should == Time.parse("2009/12/24").day
201
+ danish_kroner_nordea.date_for(0).year.should == Time.parse("2012/11/16").year
202
+ danish_kroner_nordea.date_for(0).month.should == Time.parse("2012/11/16").month
203
+ danish_kroner_nordea.date_for(0).day.should == Time.parse("2012/11/16").day
204
+ yyyymmdd_date.date_for(0).year.should == Time.parse("2012/12/31").year
205
+ yyyymmdd_date.date_for(0).month.should == Time.parse("2012/12/31").month
206
+ yyyymmdd_date.date_for(0).day.should == Time.parse("2012/12/31").day
207
+ spanish_date.date_for(1).year.should == Time.parse("2009/12/02").year
208
+ spanish_date.date_for(1).month.should == Time.parse("2009/12/02").month
209
+ spanish_date.date_for(1).day.should == Time.parse("2009/12/02").day
210
+ english_date.date_for(1).year.should == Time.parse("2009/12/24").year
211
+ english_date.date_for(1).month.should == Time.parse("2009/12/24").month
212
+ english_date.date_for(1).day.should == Time.parse("2009/12/24").day
213
+ nationwide.date_for(1).month.should == 10
214
+ ing_csv.date_for(1).month.should == Time.parse("2012/11/12").month
215
+ ing_csv.date_for(1).day.should == Time.parse("2012/11/12").day
216
+ broker_canada.date_for(5).year.should == 2014
217
+ broker_canada.date_for(5).month.should == 1
218
+ broker_canada.date_for(5).day.should == 7
219
+ intuit_mint.date_for(1).year.should == 2014
220
+ intuit_mint.date_for(1).month.should == 2
221
+ intuit_mint.date_for(1).day.should == 3
233
222
  end
234
223
  end
235
224
 
236
225
  describe "description_for" do
237
226
  it "should return the combined fields that are not money for date fields" do
238
- @chase.description_for(1).should == "CHECK; CHECK 2656"
239
- @chase.description_for(7).should == "CREDIT; PAYPAL TRANSFER PPD ID: PAYPALSDSL"
227
+ chase.description_for(1).should == "CHECK; CHECK 2656"
228
+ chase.description_for(7).should == "CREDIT; PAYPAL TRANSFER PPD ID: PAYPALSDSL"
240
229
  end
241
230
 
242
231
  it "should not append empty description column" do
243
232
  parser = Reckon::CSVParser.new(:string => '01/09/2015,05354 SUBWAY,8.19,,',:date_format => '%d/%m/%Y')
244
- parser.description_column_indices.should == [1, 4]
245
233
  parser.description_for(0).should == '05354 SUBWAY'
246
234
  end
235
+
236
+ it "should handle nil description" do
237
+ parser = Reckon::CSVParser.new(string: '2015-09-01,test,3.99')
238
+ expect(parser.description_for(1)).to eq("")
239
+ end
247
240
  end
248
241
 
249
242
  describe "pretty_money_for" do
250
243
  it "work with negative and positive numbers" do
251
- @some_other_bank.pretty_money_for(1).should == "-$20.00"
252
- @some_other_bank.pretty_money_for(4).should == " $1558.52"
253
- @some_other_bank.pretty_money_for(7).should == "-$116.22"
254
- @some_other_bank.pretty_money_for(5).should == " $0.23"
255
- @some_other_bank.pretty_money_for(6).should == "-$0.96"
244
+ some_other_bank.pretty_money_for(1).should == "-$20.00"
245
+ some_other_bank.pretty_money_for(4).should == " $1558.52"
246
+ some_other_bank.pretty_money_for(7).should == "-$116.22"
247
+ some_other_bank.pretty_money_for(5).should == " $0.23"
248
+ some_other_bank.pretty_money_for(6).should == "-$0.96"
256
249
  end
257
250
 
258
251
  it "work with other currencies such as €" do
@@ -274,8 +267,15 @@ describe Reckon::CSVParser do
274
267
  end
275
268
 
276
269
  it "should work with merge columns" do
277
- @nationwide.pretty_money_for(0).should == " 500.00 POUND"
278
- @nationwide.pretty_money_for(1).should == "-20.00 POUND"
270
+ nationwide.pretty_money_for(0).should == " 500.00 POUND"
271
+ nationwide.pretty_money_for(1).should == "-20.00 POUND"
272
+ end
273
+ end
274
+
275
+ describe '85 regression test' do
276
+ it 'should detect correct date column' do
277
+ p = Reckon::CSVParser.new(file:fixture_path('85-date-example.csv'))
278
+ expect(p.date_column_index).to eq(2)
279
279
  end
280
280
  end
281
281
  end