reckon 0.4.4 → 0.5.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.
Files changed (43) hide show
  1. checksums.yaml +5 -5
  2. data/.ruby-version +1 -1
  3. data/.travis.yml +10 -2
  4. data/CHANGELOG.md +197 -0
  5. data/Gemfile +0 -1
  6. data/Gemfile.lock +33 -15
  7. data/README.md +2 -5
  8. data/lib/reckon.rb +10 -8
  9. data/lib/reckon/app.rb +92 -116
  10. data/lib/reckon/cosine_similarity.rb +119 -0
  11. data/lib/reckon/csv_parser.rb +57 -27
  12. data/lib/reckon/ledger_parser.rb +194 -30
  13. data/lib/reckon/money.rb +3 -4
  14. data/reckon.gemspec +6 -5
  15. data/spec/data_fixtures/73-sample.csv +2 -0
  16. data/spec/data_fixtures/73-tokens.yml +8 -0
  17. data/spec/data_fixtures/73-transactions.ledger +7 -0
  18. data/spec/data_fixtures/austrian_example.csv +13 -0
  19. data/spec/data_fixtures/bom_utf8_file.csv +1 -0
  20. data/spec/data_fixtures/broker_canada_example.csv +12 -0
  21. data/spec/data_fixtures/chase.csv +9 -0
  22. data/spec/data_fixtures/danish_kroner_nordea_example.csv +6 -0
  23. data/spec/data_fixtures/english_date_example.csv +3 -0
  24. data/spec/data_fixtures/french_example.csv +9 -0
  25. data/spec/data_fixtures/german_date_example.csv +3 -0
  26. data/spec/data_fixtures/harder_date_example.csv +5 -0
  27. data/spec/data_fixtures/ing.csv +3 -0
  28. data/spec/data_fixtures/intuit_mint_example.csv +7 -0
  29. data/spec/data_fixtures/invalid_header_example.csv +6 -0
  30. data/spec/data_fixtures/inversed_credit_card.csv +16 -0
  31. data/spec/data_fixtures/nationwide.csv +4 -0
  32. data/spec/data_fixtures/simple.csv +2 -0
  33. data/spec/data_fixtures/some_other.csv +9 -0
  34. data/spec/data_fixtures/spanish_date_example.csv +3 -0
  35. data/spec/data_fixtures/suntrust.csv +7 -0
  36. data/spec/data_fixtures/two_money_columns.csv +5 -0
  37. data/spec/data_fixtures/yyyymmdd_date_example.csv +1 -0
  38. data/spec/reckon/app_spec.rb +66 -34
  39. data/spec/reckon/csv_parser_spec.rb +79 -201
  40. data/spec/reckon/ledger_parser_spec.rb +62 -9
  41. data/spec/spec_helper.rb +3 -0
  42. metadata +62 -19
  43. data/CHANGES.md +0 -9
@@ -1,31 +1,84 @@
1
1
  #!/usr/bin/env ruby
2
2
  #encoding: utf-8
3
3
 
4
- require "spec_helper"
4
+ require_relative "../spec_helper"
5
5
  require 'rubygems'
6
6
  require 'reckon'
7
7
  require 'pp'
8
+ require 'rantly'
9
+ require 'rantly/rspec_extensions'
10
+ require 'shellwords'
8
11
 
9
12
  describe Reckon::LedgerParser do
10
13
  before do
11
- @ledger = Reckon::LedgerParser.new(EXAMPLE_LEDGER)
14
+ @ledger = Reckon::LedgerParser.new(EXAMPLE_LEDGER, date_format: '%Y/%m/%d')
12
15
  end
13
16
 
14
17
  describe "parse" do
18
+ it "should match ledger csv output" do
19
+ # ledger only parses dates with - or / as separator, and separator is required
20
+ formats = ["%Y/%m/%d", "%Y-%m-%d"]
21
+ types = [' ! ', ' * ', ' ']
22
+ delimiters = [" ", "\t", "\t\t"]
23
+ currency_delimiters = delimiters + ['']
24
+ currencies = ['', '$', '£']
25
+ property_of do
26
+ Rantly do
27
+ description = Proc.new do
28
+ sized(15){string}.tr(%q{'`:*\\},'').gsub(/\s+/, ' ').gsub(/^[!;<\[( ]+/, '')
29
+ end
30
+ currency = choose(*currencies) # to be consistent within the transaction
31
+ comments = ['', '; ', "\t;#{call(description)}", " ; #{call(description)}"]
32
+ date = Time.at(range(0, 1_581_389_644)).strftime(choose(*formats))
33
+ codes = [' ', " (#{string(:alnum).tr('()', '')}) "]
34
+ account = Proc.new { choose(*delimiters) + call(description) }
35
+ account_money = Proc.new do
36
+ sprintf("%.02f", (float * range(5,10) + 1) * choose(1, -1))
37
+ end
38
+ account_line = Proc.new do
39
+ call(account) + \
40
+ choose(*delimiters) + \
41
+ currency + \
42
+ choose(*currency_delimiters) + \
43
+ call(account_money) + \
44
+ choose(*comments)
45
+ end
46
+ ledger = "#{date}#{choose(*types)}#{choose(*codes)}#{call(description)}\n"
47
+ range(1,5).times do
48
+ ledger += "#{call(account_line)}\n"
49
+ end
50
+ ledger += "#{call(account)}\n"
51
+ ledger
52
+ end
53
+ end.check(1000) do |s|
54
+ filter_format = lambda { |n| [n['date'], n['desc'], n['name'], sprintf("%.02f", n['amount'])] }
55
+ headers = %w[date code desc name currency amount type commend]
56
+ safe_s = Shellwords.escape(s)
57
+ ledger_csv = `echo #{safe_s} | ledger csv --date-format '%Y-%m-%d' -f - `
58
+ ledger_parser_csv = Reckon::LedgerParser.new(s, date_format: '%Y/%m/%d').to_csv.join("\n")
59
+
60
+ expected = CSV.parse(ledger_csv.gsub('\"', '""'), headers: headers).map &filter_format
61
+ actual = CSV.parse(ledger_parser_csv, headers: headers).map &filter_format
62
+ expected.length.times do |i|
63
+ expect(actual[i]).to eq(expected[i])
64
+ end
65
+ end
66
+ end
67
+
15
68
  it "should ignore non-standard entries" do
16
69
  @ledger.entries.length.should == 7
17
70
  end
18
71
 
19
72
  it "should parse entries correctly" do
20
- @ledger.entries.first[:desc].should == "* Checking balance"
21
- @ledger.entries.first[:date].should == "2004-05-01"
73
+ @ledger.entries.first[:desc].should == "Checking balance"
74
+ @ledger.entries.first[:date].should == Date.parse("2004-05-01")
22
75
  @ledger.entries.first[:accounts].first[:name].should == "Assets:Bank:Checking"
23
76
  @ledger.entries.first[:accounts].first[:amount].should == 1000
24
77
  @ledger.entries.first[:accounts].last[:name].should == "Equity:Opening Balances"
25
78
  @ledger.entries.first[:accounts].last[:amount].should == -1000
26
79
 
27
- @ledger.entries.last[:desc].should == "(100) Credit card company"
28
- @ledger.entries.last[:date].should == "2004/05/27"
80
+ @ledger.entries.last[:desc].should == "Credit card company"
81
+ @ledger.entries.last[:date].should == Date.parse("2004/05/27")
29
82
  @ledger.entries.last[:accounts].first[:name].should == "Liabilities:MasterCard"
30
83
  @ledger.entries.last[:accounts].first[:amount].should == 20.24
31
84
  @ledger.entries.last[:accounts].last[:name].should == "Assets:Bank:Checking"
@@ -35,14 +88,14 @@ describe Reckon::LedgerParser do
35
88
 
36
89
  describe "balance" do
37
90
  it "it should balance out missing account values" do
38
- @ledger.balance([
91
+ @ledger.send(:balance, [
39
92
  { :name => "Account1", :amount => 1000 },
40
93
  { :name => "Account2", :amount => nil }
41
94
  ]).should == [ { :name => "Account1", :amount => 1000 }, { :name => "Account2", :amount => -1000 } ]
42
95
  end
43
96
 
44
97
  it "it should balance out missing account values" do
45
- @ledger.balance([
98
+ @ledger.send(:balance, [
46
99
  { :name => "Account1", :amount => 1000 },
47
100
  { :name => "Account2", :amount => 100 },
48
101
  { :name => "Account3", :amount => -200 },
@@ -56,7 +109,7 @@ describe Reckon::LedgerParser do
56
109
  end
57
110
 
58
111
  it "it should work on normal values too" do
59
- @ledger.balance([
112
+ @ledger.send(:balance, [
60
113
  { :name => "Account1", :amount => 1000 },
61
114
  { :name => "Account2", :amount => -1000 }
62
115
  ]).should == [ { :name => "Account1", :amount => 1000 }, { :name => "Account2", :amount => -1000 } ]
@@ -3,4 +3,7 @@ require 'rspec'
3
3
  require 'reckon'
4
4
 
5
5
  RSpec.configure do |config|
6
+ def fixture_path(file)
7
+ File.expand_path(File.join(File.dirname(__FILE__), "data_fixtures", file))
8
+ end
6
9
  end
metadata CHANGED
@@ -1,15 +1,16 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: reckon
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.4
4
+ version: 0.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Andrew Cantino
8
8
  - BlackEdder
9
+ - Ben Prew
9
10
  autorequire:
10
11
  bindir: bin
11
12
  cert_chain: []
12
- date: 2015-12-02 00:00:00.000000000 Z
13
+ date: 2020-02-19 00:00:00.000000000 Z
13
14
  dependencies:
14
15
  - !ruby/object:Gem::Dependency
15
16
  name: rspec
@@ -26,19 +27,33 @@ dependencies:
26
27
  - !ruby/object:Gem::Version
27
28
  version: 1.2.9
28
29
  - !ruby/object:Gem::Dependency
29
- name: fastercsv
30
+ name: pry
30
31
  requirement: !ruby/object:Gem::Requirement
31
32
  requirements:
32
33
  - - ">="
33
34
  - !ruby/object:Gem::Version
34
- version: 1.5.1
35
- type: :runtime
35
+ version: 0.12.2
36
+ type: :development
36
37
  prerelease: false
37
38
  version_requirements: !ruby/object:Gem::Requirement
38
39
  requirements:
39
40
  - - ">="
40
41
  - !ruby/object:Gem::Version
41
- version: 1.5.1
42
+ version: 0.12.2
43
+ - !ruby/object:Gem::Dependency
44
+ name: rantly
45
+ requirement: !ruby/object:Gem::Requirement
46
+ requirements:
47
+ - - '='
48
+ - !ruby/object:Gem::Version
49
+ version: 1.2.0
50
+ type: :development
51
+ prerelease: false
52
+ version_requirements: !ruby/object:Gem::Requirement
53
+ requirements:
54
+ - - '='
55
+ - !ruby/object:Gem::Version
56
+ version: 1.2.0
42
57
  - !ruby/object:Gem::Dependency
43
58
  name: chronic
44
59
  requirement: !ruby/object:Gem::Requirement
@@ -81,6 +96,20 @@ dependencies:
81
96
  - - ">="
82
97
  - !ruby/object:Gem::Version
83
98
  version: 1.4.2
99
+ - !ruby/object:Gem::Dependency
100
+ name: rchardet
101
+ requirement: !ruby/object:Gem::Requirement
102
+ requirements:
103
+ - - ">="
104
+ - !ruby/object:Gem::Version
105
+ version: 1.8.0
106
+ type: :runtime
107
+ prerelease: false
108
+ version_requirements: !ruby/object:Gem::Requirement
109
+ requirements:
110
+ - - ">="
111
+ - !ruby/object:Gem::Version
112
+ version: 1.8.0
84
113
  description: Reckon automagically converts CSV files for use with the command-line
85
114
  accounting tool Ledger. It also helps you to select the correct accounts associated
86
115
  with the CSV data using Bayesian machine learning.
@@ -95,7 +124,7 @@ files:
95
124
  - ".ruby-gemset"
96
125
  - ".ruby-version"
97
126
  - ".travis.yml"
98
- - CHANGES.md
127
+ - CHANGELOG.md
99
128
  - Gemfile
100
129
  - Gemfile.lock
101
130
  - LICENSE
@@ -104,12 +133,36 @@ files:
104
133
  - bin/reckon
105
134
  - lib/reckon.rb
106
135
  - lib/reckon/app.rb
136
+ - lib/reckon/cosine_similarity.rb
107
137
  - lib/reckon/csv_parser.rb
108
138
  - lib/reckon/ledger_parser.rb
109
139
  - lib/reckon/money.rb
110
140
  - reckon.gemspec
141
+ - spec/data_fixtures/73-sample.csv
142
+ - spec/data_fixtures/73-tokens.yml
143
+ - spec/data_fixtures/73-transactions.ledger
144
+ - spec/data_fixtures/austrian_example.csv
145
+ - spec/data_fixtures/bom_utf8_file.csv
146
+ - spec/data_fixtures/broker_canada_example.csv
147
+ - spec/data_fixtures/chase.csv
148
+ - spec/data_fixtures/danish_kroner_nordea_example.csv
149
+ - spec/data_fixtures/english_date_example.csv
111
150
  - spec/data_fixtures/extratofake.csv
151
+ - spec/data_fixtures/french_example.csv
152
+ - spec/data_fixtures/german_date_example.csv
153
+ - spec/data_fixtures/harder_date_example.csv
154
+ - spec/data_fixtures/ing.csv
155
+ - spec/data_fixtures/intuit_mint_example.csv
156
+ - spec/data_fixtures/invalid_header_example.csv
157
+ - spec/data_fixtures/inversed_credit_card.csv
158
+ - spec/data_fixtures/nationwide.csv
159
+ - spec/data_fixtures/simple.csv
160
+ - spec/data_fixtures/some_other.csv
161
+ - spec/data_fixtures/spanish_date_example.csv
162
+ - spec/data_fixtures/suntrust.csv
112
163
  - spec/data_fixtures/tokens.yaml
164
+ - spec/data_fixtures/two_money_columns.csv
165
+ - spec/data_fixtures/yyyymmdd_date_example.csv
113
166
  - spec/reckon/app_spec.rb
114
167
  - spec/reckon/csv_parser_spec.rb
115
168
  - spec/reckon/date_column_spec.rb
@@ -137,19 +190,9 @@ required_rubygems_version: !ruby/object:Gem::Requirement
137
190
  version: '0'
138
191
  requirements: []
139
192
  rubyforge_project:
140
- rubygems_version: 2.4.6
193
+ rubygems_version: 2.7.6.2
141
194
  signing_key:
142
195
  specification_version: 4
143
196
  summary: Utility for interactively converting and labeling CSV files for the Ledger
144
197
  accounting tool.
145
- test_files:
146
- - spec/data_fixtures/extratofake.csv
147
- - spec/data_fixtures/tokens.yaml
148
- - spec/reckon/app_spec.rb
149
- - spec/reckon/csv_parser_spec.rb
150
- - spec/reckon/date_column_spec.rb
151
- - spec/reckon/ledger_parser_spec.rb
152
- - spec/reckon/money_column_spec.rb
153
- - spec/reckon/money_spec.rb
154
- - spec/spec.opts
155
- - spec/spec_helper.rb
198
+ test_files: []
data/CHANGES.md DELETED
@@ -1,9 +0,0 @@
1
- # Changes
2
-
3
- - 02/25/14 - Improved handling of US vs non US dates
4
- - 02/15/14 - Detect debit - credit column
5
- - 02/15/14 - Two money column detection improved
6
- * 7/02/13 - Customizable date parsing contributed by @mauromorales.
7
- * 6/26/13 - Multi-currency support contributed by @zebh.
8
- * 4/27/13 - Add --account commandline option
9
- * 3/24/13 - Force encoding to UTF-8 when unknown characters are encountered.