reckon 0.8.1 ā†’ 0.9.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (39) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/ruby.yml +1 -1
  3. data/.gitignore +5 -0
  4. data/.rubocop.yml +20 -0
  5. data/CHANGELOG.md +22 -0
  6. data/Gemfile.lock +21 -21
  7. data/README.md +2 -0
  8. data/Rakefile +2 -2
  9. data/bin/build-new-version.sh +3 -2
  10. data/bin/reckon +1 -1
  11. data/lib/reckon/app.rb +27 -24
  12. data/lib/reckon/beancount_parser.rb +150 -0
  13. data/lib/reckon/cosine_similarity.rb +0 -1
  14. data/lib/reckon/csv_parser.rb +89 -44
  15. data/lib/reckon/date_column.rb +18 -7
  16. data/lib/reckon/ledger_parser.rb +23 -15
  17. data/lib/reckon/money.rb +18 -16
  18. data/lib/reckon/options.rb +47 -18
  19. data/lib/reckon/version.rb +1 -1
  20. data/lib/reckon.rb +1 -0
  21. data/spec/cosine_training_and_test.rb +1 -1
  22. data/spec/data_fixtures/multi-line-field.csv +5 -0
  23. data/spec/integration/ask_for_account/cli_input.txt +1 -0
  24. data/spec/integration/invalid_header_example/output.ledger +6 -7
  25. data/spec/integration/invalid_header_example/test_args +1 -1
  26. data/spec/integration/tab_delimited_file/input.csv +2 -0
  27. data/spec/integration/tab_delimited_file/output.ledger +8 -0
  28. data/spec/integration/tab_delimited_file/test_args +1 -0
  29. data/spec/integration/test.sh +3 -5
  30. data/spec/integration/two_money_columns_manual/input.csv +5 -0
  31. data/spec/integration/two_money_columns_manual/output.ledger +16 -0
  32. data/spec/integration/two_money_columns_manual/test_args +1 -0
  33. data/spec/reckon/csv_parser_spec.rb +85 -26
  34. data/spec/reckon/date_column_spec.rb +6 -0
  35. data/spec/reckon/ledger_parser_spec.rb +25 -23
  36. data/spec/reckon/options_spec.rb +2 -2
  37. data/spec/spec_helper.rb +2 -0
  38. metadata +17 -141
  39. data/spec/integration/ask_for_account/cli_input.exp +0 -33
@@ -31,7 +31,7 @@ main () {
31
31
  TEST_DIR=$(dirname "$t")
32
32
  TEST_LOG=$(mktemp)
33
33
  pushd "$TEST_DIR" >/dev/null || exit 1
34
- if [[ -e "cli_input.exp" ]]; then
34
+ if [[ -e "cli_input.txt" ]]; then
35
35
  cli_test >$TEST_LOG 2>&1
36
36
  else
37
37
  unattended_test >$TEST_LOG 2>&1
@@ -56,10 +56,8 @@ main () {
56
56
 
57
57
  cli_test () {
58
58
  OUTPUT_FILE=$(mktemp)
59
- CLI_CMD="$RECKON_CMD --table-output-file $OUTPUT_FILE $(cat test_args)"
60
- TEST_CMD="expect -d -c 'spawn $CLI_CMD' cli_input.exp"
61
- eval "$TEST_CMD" 2>&1
62
- ERROR=0
59
+ TEST_CMD="$RECKON_CMD --table-output-file $OUTPUT_FILE $(cat test_args)"
60
+ cat cli_input.txt | $TEST_CMD
63
61
  TEST_DIFF=$(diff -u "$OUTPUT_FILE" expected_output)
64
62
 
65
63
  # ${#} is character length, test that there was no output from diff
@@ -0,0 +1,5 @@
1
+ Date,Summary,Withdrawal,Deposit,Ending balance,Remarks,In/outward transfer account,Notes
2
+ 2021/07/02,Expense,200,,999,,,
3
+ 2021/07/02,Expense,100,,999,,,
4
+ 2021/07/08,Transfer,,200,999,,,In1
5
+ 2021/07/08,Transfer,500,,999,,,Out1
@@ -0,0 +1,16 @@
1
+ 2021-07-02 Expense; 999
2
+ Expenses:Unknown
3
+ Assets:Bank:Checking -$100.00
4
+
5
+ 2021-07-02 Expense; 999
6
+ Expenses:Unknown
7
+ Assets:Bank:Checking -$200.00
8
+
9
+ 2021-07-08 Transfer; 999; In1
10
+ Assets:Bank:Checking $200.00
11
+ Expenses:Unknown
12
+
13
+ 2021-07-08 Transfer; 999; Out1
14
+ Expenses:Unknown
15
+ Assets:Bank:Checking -$500.00
16
+
@@ -0,0 +1 @@
1
+ -f input.csv --unattended --account Assets:Bank:Checking --money-columns 3,4
@@ -1,5 +1,4 @@
1
1
  #!/usr/bin/env ruby
2
- # coding: utf-8
3
2
 
4
3
  require_relative "../spec_helper"
5
4
  require 'rubygems'
@@ -8,24 +7,53 @@ require_relative '../../lib/reckon'
8
7
  describe Reckon::CSVParser do
9
8
  let(:chase) { Reckon::CSVParser.new(file: fixture_path('chase.csv')) }
10
9
  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')) }
10
+ let(:two_money_columns) {
11
+ Reckon::CSVParser.new(file: fixture_path('two_money_columns.csv'))
12
+ }
12
13
  let(:suntrust_csv) { Reckon::CSVParser.new(file: fixture_path('suntrust.csv')) }
13
14
  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')) }
15
+ let(:nationwide) {
16
+ Reckon::CSVParser.new(file: fixture_path('nationwide.csv'), csv_separator: ',',
17
+ suffixed: true, currency: "POUND")
18
+ }
19
+ let(:german_date) {
20
+ Reckon::CSVParser.new(file: fixture_path('german_date_example.csv'))
21
+ }
22
+ let(:danish_kroner_nordea) {
23
+ Reckon::CSVParser.new(file: fixture_path('danish_kroner_nordea_example.csv'),
24
+ csv_separator: ';', comma_separates_cents: true)
25
+ }
26
+ let(:yyyymmdd_date) {
27
+ Reckon::CSVParser.new(file: fixture_path('yyyymmdd_date_example.csv'))
28
+ }
29
+ let(:spanish_date) {
30
+ Reckon::CSVParser.new(file: fixture_path('spanish_date_example.csv'),
31
+ date_format: '%d/%m/%Y')
32
+ }
33
+ let(:english_date) {
34
+ Reckon::CSVParser.new(file: fixture_path('english_date_example.csv'))
35
+ }
36
+ let(:ing_csv) {
37
+ Reckon::CSVParser.new(file: fixture_path('ing.csv'), comma_separates_cents: true)
38
+ }
39
+ let(:austrian_csv) {
40
+ Reckon::CSVParser.new(file: fixture_path('austrian_example.csv'),
41
+ comma_separates_cents: true, csv_separator: ';')
42
+ }
43
+ let(:french_csv) {
44
+ Reckon::CSVParser.new(file: fixture_path('french_example.csv'), csv_separator: ';',
45
+ comma_separates_cents: true)
46
+ }
47
+ let(:broker_canada) {
48
+ Reckon::CSVParser.new(file: fixture_path('broker_canada_example.csv'))
49
+ }
50
+ let(:intuit_mint) {
51
+ Reckon::CSVParser.new(file: fixture_path('intuit_mint_example.csv'))
52
+ }
25
53
 
26
54
  describe "parse" do
27
55
  it "should use binary encoding if none specified and chardet fails" do
28
- allow(CharDet).to receive(:detect).and_return({'encoding' => nil})
56
+ allow(CharDet).to receive(:detect).and_return({ 'encoding' => nil })
29
57
  app = Reckon::CSVParser.new(file: fixture_path("extratofake.csv"))
30
58
  expect(app.send(:try_encoding, "foobarbaz")).to eq("BINARY")
31
59
  end
@@ -37,12 +65,16 @@ describe Reckon::CSVParser do
37
65
  end
38
66
 
39
67
  it "should work with other separators" do
40
- Reckon::CSVParser.new(:string => "one;two\nthree;four", :csv_separator => ';').columns.should == [['one', 'three'], ['two', 'four']]
68
+ Reckon::CSVParser.new(:string => "one;two\nthree;four",
69
+ :csv_separator => ';').columns.should == [
70
+ ['one', 'three'], ['two', 'four']
71
+ ]
41
72
  end
42
73
 
43
74
  it 'should parse quoted lines' do
44
75
  file = %q("30.03.2015";"29.03.2015";"09.04.2015";"BARAUSZAHLUNGSENTGELT";"5266 xxxx xxxx 9454";"";"0";"EUR";"0,00";"EUR";"-3,50";"0")
45
- Reckon::CSVParser.new(string: file, csv_separator: ';', comma_separates_cents: true).columns.length.should == 12
76
+ Reckon::CSVParser.new(string: file, csv_separator: ';',
77
+ comma_separates_cents: true).columns.length.should == 12
46
78
  end
47
79
 
48
80
  it 'should parse csv with BOM' do
@@ -50,11 +82,26 @@ describe Reckon::CSVParser do
50
82
  Reckon::CSVParser.new(file: file).columns.length.should == 41
51
83
  end
52
84
 
85
+ it 'should parse multi-line csv fields' do
86
+ file = File.expand_path(fixture_path("multi-line-field.csv"))
87
+ p = Reckon::CSVParser.new(file: file)
88
+ expect(p.columns[0].length).to eq 2
89
+ expected_field = "In case of errors or questions about your\n" +
90
+ " electronic transfers:\n" +
91
+ " This is a multi-line string\n" +
92
+ " "
93
+ expect(p.columns[-1][-1]).to eq expected_field
94
+ end
95
+
53
96
  describe 'file with invalid csv in header' do
54
97
  let(:invalid_file) { fixture_path('invalid_header_example.csv') }
55
98
 
56
99
  it 'should ignore invalid header lines' do
57
- Reckon::CSVParser.new(file: invalid_file, contains_header: 4)
100
+ parser = Reckon::CSVParser.new(file: invalid_file, contains_header: 4)
101
+ expect(parser.csv_data).to eq([
102
+ ["19/02/2016", "VIR RECU 508160",
103
+ "VIR RECU 1234567834S DE: Francois REF: 123457891234567894561231 PROVENANCE: DE Allemagne ", "50,00", "EUR"], ["18/02/2016", "COTISATION JAZZ", "COTISATION JAZZ ", "-8,10", "EUR"]
104
+ ])
58
105
  end
59
106
 
60
107
  it 'should fail' do
@@ -67,19 +114,24 @@ describe Reckon::CSVParser do
67
114
 
68
115
  describe "columns" do
69
116
  it "should return the csv transposed" do
70
- simple_csv.columns.should == [["entry1", "entry4"], ["entry2", "entry5"], ["entry3", "entry6"]]
117
+ simple_csv.columns.should == [["entry1", "entry4"], ["entry2", "entry5"],
118
+ ["entry3", "entry6"]]
71
119
  chase.columns.length.should == 4
72
120
  end
73
121
 
74
122
  it "should be ok with empty lines" do
75
123
  lambda {
76
- Reckon::CSVParser.new(:string => "one,two\nthree,four\n\n\n\n\n").columns.should == [['one', 'three'], ['two', 'four']]
124
+ Reckon::CSVParser.new(:string => "one,two\nthree,four\n\n\n\n\n").columns.should == [
125
+ ['one', 'three'], ['two', 'four']
126
+ ]
77
127
  }.should_not raise_error
78
128
  end
79
129
  end
80
130
 
81
131
  describe "detect_columns" do
82
- let(:harder_date_example_csv) { Reckon::CSVParser.new(file: fixture_path('harder_date_example.csv')) }
132
+ let(:harder_date_example_csv) {
133
+ Reckon::CSVParser.new(file: fixture_path('harder_date_example.csv'))
134
+ }
83
135
 
84
136
  it "should detect the money column" do
85
137
  chase.money_column_indices.should == [3]
@@ -165,13 +217,17 @@ describe Reckon::CSVParser do
165
217
  end
166
218
 
167
219
  it "should handle the comma_separates_cents option correctly" do
168
- european_csv = Reckon::CSVParser.new(:string => "$2,00;something\n1.025,67;something else", :csv_separator => ';', :comma_separates_cents => true)
220
+ european_csv = Reckon::CSVParser.new(
221
+ :string => "$2,00;something\n1.025,67;something else", :csv_separator => ';', :comma_separates_cents => true
222
+ )
169
223
  european_csv.money_for(0).should == 2.00
170
224
  european_csv.money_for(1).should == 1025.67
171
225
  end
172
226
 
173
227
  it "should return negated values if the inverse option is passed" do
174
- inversed_csv = Reckon::CSVParser.new(file: fixture_path('inversed_credit_card.csv'), inverse: true)
228
+ inversed_csv = Reckon::CSVParser.new(
229
+ file: fixture_path('inversed_credit_card.csv'), inverse: true
230
+ )
175
231
  inversed_csv.money_for(0).should == -30.00
176
232
  inversed_csv.money_for(3).should == 500.00
177
233
  end
@@ -229,7 +285,8 @@ describe Reckon::CSVParser do
229
285
  end
230
286
 
231
287
  it "should not append empty description column" do
232
- parser = Reckon::CSVParser.new(:string => '01/09/2015,05354 SUBWAY,8.19,,',:date_format => '%d/%m/%Y')
288
+ parser = Reckon::CSVParser.new(:string => '01/09/2015,05354 SUBWAY,8.19,,',
289
+ :date_format => '%d/%m/%Y')
233
290
  parser.description_for(0).should == '05354 SUBWAY'
234
291
  end
235
292
 
@@ -249,7 +306,8 @@ describe Reckon::CSVParser do
249
306
  end
250
307
 
251
308
  it "work with other currencies such as ā‚¬" do
252
- euro_bank = Reckon::CSVParser.new(file: fixture_path('some_other.csv'), currency: "ā‚¬", suffixed: false )
309
+ euro_bank = Reckon::CSVParser.new(file: fixture_path('some_other.csv'),
310
+ currency: "ā‚¬", suffixed: false)
253
311
  euro_bank.pretty_money_for(1).should == "-ā‚¬20.00"
254
312
  euro_bank.pretty_money_for(4).should == " ā‚¬1,558.52"
255
313
  euro_bank.pretty_money_for(7).should == "-ā‚¬116.22"
@@ -258,7 +316,8 @@ describe Reckon::CSVParser do
258
316
  end
259
317
 
260
318
  it "work with suffixed currencies such as SEK" do
261
- swedish_bank = Reckon::CSVParser.new(file: fixture_path('some_other.csv'), currency: 'SEK', suffixed: true )
319
+ swedish_bank = Reckon::CSVParser.new(file: fixture_path('some_other.csv'),
320
+ currency: 'SEK', suffixed: true)
262
321
  swedish_bank.pretty_money_for(1).should == "-20.00 SEK"
263
322
  swedish_bank.pretty_money_for(4).should == " 1,558.52 SEK"
264
323
  swedish_bank.pretty_money_for(7).should == "-116.22 SEK"
@@ -274,7 +333,7 @@ describe Reckon::CSVParser do
274
333
 
275
334
  describe '85 regression test' do
276
335
  it 'should detect correct date column' do
277
- p = Reckon::CSVParser.new(file:fixture_path('85-date-example.csv'))
336
+ p = Reckon::CSVParser.new(file: fixture_path('85-date-example.csv'))
278
337
  expect(p.date_column_index).to eq(2)
279
338
  end
280
339
  end
@@ -50,4 +50,10 @@ describe Reckon::DateColumn do
50
50
  .to eq('2013-12-13')
51
51
  end
52
52
  end
53
+
54
+ describe "#likelihood" do
55
+ it "should prefer numbers that looks like dates" do
56
+ expect(Reckon::DateColumn.likelihood("123456789")).to be < Reckon::DateColumn.likelihood("20160102")
57
+ end
58
+ end
53
59
  end
@@ -8,10 +8,12 @@ require 'pp'
8
8
  require 'rantly'
9
9
  require 'rantly/rspec_extensions'
10
10
  require 'shellwords'
11
+ require 'stringio'
11
12
 
12
13
  describe Reckon::LedgerParser do
13
14
  before do
14
- @ledger = Reckon::LedgerParser.new(EXAMPLE_LEDGER, date_format: '%Y/%m/%d')
15
+ @ledger = Reckon::LedgerParser.new(date_format: '%Y/%m/%d')
16
+ @entries = @ledger.parse(StringIO.new(EXAMPLE_LEDGER))
15
17
  end
16
18
 
17
19
  describe "parse" do
@@ -58,7 +60,7 @@ describe Reckon::LedgerParser do
58
60
  headers = %w[date code desc name currency amount type commend]
59
61
  safe_s = Shellwords.escape(s)
60
62
 
61
- lp_csv = Reckon::LedgerParser.new(s, date_format: '%Y/%m/%d').to_csv.join("\n")
63
+ lp_csv = Reckon::LedgerParser.new(date_format: '%Y/%m/%d').to_csv(StringIO.new(s)).join("\n")
62
64
  actual = CSV.parse(lp_csv, headers: headers).map(&filter_format)
63
65
 
64
66
  ledger_csv = `echo #{safe_s} | ledger csv --date-format '%Y/%m/%d' -f - `
@@ -83,9 +85,9 @@ comment
83
85
 
84
86
  end comment
85
87
  HERE
86
- l = Reckon::LedgerParser.new(ledger)
87
- expect(l.entries.length).to eq(1)
88
- expect(l.entries.first[:desc]).to eq('Dinner should show up')
88
+ entries = Reckon::LedgerParser.new.parse(StringIO.new(ledger))
89
+ expect(entries.length).to eq(1)
90
+ expect(entries.first[:desc]).to eq('Dinner should show up')
89
91
 
90
92
  end
91
93
 
@@ -96,30 +98,30 @@ HERE
96
98
  Liabilities:ChaseSapphire -$81.77
97
99
  # END FINANCE SCRIPT OUTPUT Thu 02 Apr 2020 12:05:54 PM EDT
98
100
  HERE
99
- l = Reckon::LedgerParser.new(ledger)
100
- expect(l.entries.first[:accounts].map { |n| n[:name] }).to eq(['Expenses:Household', 'Liabilities:ChaseSapphire'])
101
- expect(l.entries.first[:accounts].size).to eq(2)
102
- expect(l.entries.length).to eq(1)
101
+ entries = Reckon::LedgerParser.new.parse(StringIO.new(ledger))
102
+ expect(entries.first[:accounts].map { |n| n[:name] }).to eq(['Expenses:Household', 'Liabilities:ChaseSapphire'])
103
+ expect(entries.first[:accounts].size).to eq(2)
104
+ expect(entries.length).to eq(1)
103
105
  end
104
106
 
105
107
  it "should ignore non-standard entries" do
106
- @ledger.entries.length.should == 7
108
+ @entries.length.should == 7
107
109
  end
108
110
 
109
111
  it "should parse entries correctly" do
110
- @ledger.entries.first[:desc].should == "Checking balance"
111
- @ledger.entries.first[:date].should == Date.parse("2004-05-01")
112
- @ledger.entries.first[:accounts].first[:name].should == "Assets:Bank:Checking"
113
- @ledger.entries.first[:accounts].first[:amount].should == 1000
114
- @ledger.entries.first[:accounts].last[:name].should == "Equity:Opening Balances"
115
- @ledger.entries.first[:accounts].last[:amount].should == -1000
116
-
117
- @ledger.entries.last[:desc].should == "Credit card company"
118
- @ledger.entries.last[:date].should == Date.parse("2004/05/27")
119
- @ledger.entries.last[:accounts].first[:name].should == "Liabilities:MasterCard"
120
- @ledger.entries.last[:accounts].first[:amount].should == 20.24
121
- @ledger.entries.last[:accounts].last[:name].should == "Assets:Bank:Checking"
122
- @ledger.entries.last[:accounts].last[:amount].should == -20.24
112
+ @entries.first[:desc].should == "Checking balance"
113
+ @entries.first[:date].should == Date.parse("2004-05-01")
114
+ @entries.first[:accounts].first[:name].should == "Assets:Bank:Checking"
115
+ @entries.first[:accounts].first[:amount].should == 1000
116
+ @entries.first[:accounts].last[:name].should == "Equity:Opening Balances"
117
+ @entries.first[:accounts].last[:amount].should == -1000
118
+
119
+ @entries.last[:desc].should == "Credit card company"
120
+ @entries.last[:date].should == Date.parse("2004/05/27")
121
+ @entries.last[:accounts].first[:name].should == "Liabilities:MasterCard"
122
+ @entries.last[:accounts].first[:amount].should == 20.24
123
+ @entries.last[:accounts].last[:name].should == "Assets:Bank:Checking"
124
+ @entries.last[:accounts].last[:amount].should == -20.24
123
125
  end
124
126
  end
125
127
 
@@ -2,7 +2,7 @@ require "spec_helper"
2
2
 
3
3
  describe '#parse_opts' do
4
4
  it 'should assign to :string option' do
5
- options = Reckon::Options.parse(
5
+ options = Reckon::Options.parse_command_line_options(
6
6
  %w[-f - --unattended --account bank],
7
7
  StringIO.new('foo,bar,baz')
8
8
  )
@@ -10,7 +10,7 @@ describe '#parse_opts' do
10
10
  end
11
11
 
12
12
  it 'should require --unattended flag' do
13
- expect { Reckon::Options.parse(%w[-f - --account bank]) }.to(
13
+ expect { Reckon::Options.parse_command_line_options(%w[-f - --account bank]) }.to(
14
14
  raise_error(RuntimeError, "--unattended is required to use STDIN as CSV source.")
15
15
  )
16
16
  end
data/spec/spec_helper.rb CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'rubygems'
2
4
  require 'rspec'
3
5
  require 'reckon'
metadata CHANGED
@@ -1,16 +1,16 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: reckon
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.8.1
4
+ version: 0.9.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Andrew Cantino
8
8
  - BlackEdder
9
9
  - Ben Prew
10
- autorequire:
10
+ autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2022-07-02 00:00:00.000000000 Z
13
+ date: 2023-03-19 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: rspec
@@ -123,6 +123,7 @@ files:
123
123
  - ".document"
124
124
  - ".github/workflows/ruby.yml"
125
125
  - ".gitignore"
126
+ - ".rubocop.yml"
126
127
  - ".ruby-gemset"
127
128
  - ".ruby-version"
128
129
  - CHANGELOG.md
@@ -135,6 +136,7 @@ files:
135
136
  - bin/reckon
136
137
  - lib/reckon.rb
137
138
  - lib/reckon/app.rb
139
+ - lib/reckon/beancount_parser.rb
138
140
  - lib/reckon/cosine_similarity.rb
139
141
  - lib/reckon/csv_parser.rb
140
142
  - lib/reckon/date_column.rb
@@ -165,6 +167,7 @@ files:
165
167
  - spec/data_fixtures/intuit_mint_example.csv
166
168
  - spec/data_fixtures/invalid_header_example.csv
167
169
  - spec/data_fixtures/inversed_credit_card.csv
170
+ - spec/data_fixtures/multi-line-field.csv
168
171
  - spec/data_fixtures/nationwide.csv
169
172
  - spec/data_fixtures/simple.csv
170
173
  - spec/data_fixtures/some_other.csv
@@ -177,7 +180,7 @@ files:
177
180
  - spec/integration/another_bank_example/input.csv
178
181
  - spec/integration/another_bank_example/output.ledger
179
182
  - spec/integration/another_bank_example/test_args
180
- - spec/integration/ask_for_account/cli_input.exp
183
+ - spec/integration/ask_for_account/cli_input.txt
181
184
  - spec/integration/ask_for_account/expected_output
182
185
  - spec/integration/ask_for_account/input.csv
183
186
  - spec/integration/ask_for_account/test_args
@@ -258,6 +261,9 @@ files:
258
261
  - spec/integration/suntrust/input.csv
259
262
  - spec/integration/suntrust/output.ledger
260
263
  - spec/integration/suntrust/test_args
264
+ - spec/integration/tab_delimited_file/input.csv
265
+ - spec/integration/tab_delimited_file/output.ledger
266
+ - spec/integration/tab_delimited_file/test_args
261
267
  - spec/integration/test.sh
262
268
  - spec/integration/test_money_column/input.csv
263
269
  - spec/integration/test_money_column/output.ledger
@@ -265,6 +271,9 @@ files:
265
271
  - spec/integration/two_money_columns/input.csv
266
272
  - spec/integration/two_money_columns/output.ledger
267
273
  - spec/integration/two_money_columns/test_args
274
+ - spec/integration/two_money_columns_manual/input.csv
275
+ - spec/integration/two_money_columns_manual/output.ledger
276
+ - spec/integration/two_money_columns_manual/test_args
268
277
  - spec/integration/yyyymmdd_date_example/input.csv
269
278
  - spec/integration/yyyymmdd_date_example/output.ledger
270
279
  - spec/integration/yyyymmdd_date_example/test_args
@@ -281,7 +290,7 @@ homepage: https://github.com/cantino/reckon
281
290
  licenses:
282
291
  - MIT
283
292
  metadata: {}
284
- post_install_message:
293
+ post_install_message:
285
294
  rdoc_options: []
286
295
  require_paths:
287
296
  - lib
@@ -296,142 +305,9 @@ required_rubygems_version: !ruby/object:Gem::Requirement
296
305
  - !ruby/object:Gem::Version
297
306
  version: '0'
298
307
  requirements: []
299
- rubygems_version: 3.3.7
300
- signing_key:
308
+ rubygems_version: 3.3.5
309
+ signing_key:
301
310
  specification_version: 4
302
311
  summary: Utility for interactively converting and labeling CSV files for the Ledger
303
312
  accounting tool.
304
- test_files:
305
- - spec/cosine_training_and_test.rb
306
- - spec/data_fixtures/51-sample.csv
307
- - spec/data_fixtures/51-tokens.yml
308
- - spec/data_fixtures/73-sample.csv
309
- - spec/data_fixtures/73-tokens.yml
310
- - spec/data_fixtures/73-transactions.ledger
311
- - spec/data_fixtures/85-date-example.csv
312
- - spec/data_fixtures/austrian_example.csv
313
- - spec/data_fixtures/bom_utf8_file.csv
314
- - spec/data_fixtures/broker_canada_example.csv
315
- - spec/data_fixtures/chase.csv
316
- - spec/data_fixtures/danish_kroner_nordea_example.csv
317
- - spec/data_fixtures/english_date_example.csv
318
- - spec/data_fixtures/extratofake.csv
319
- - spec/data_fixtures/french_example.csv
320
- - spec/data_fixtures/german_date_example.csv
321
- - spec/data_fixtures/harder_date_example.csv
322
- - spec/data_fixtures/ing.csv
323
- - spec/data_fixtures/intuit_mint_example.csv
324
- - spec/data_fixtures/invalid_header_example.csv
325
- - spec/data_fixtures/inversed_credit_card.csv
326
- - spec/data_fixtures/nationwide.csv
327
- - spec/data_fixtures/simple.csv
328
- - spec/data_fixtures/some_other.csv
329
- - spec/data_fixtures/spanish_date_example.csv
330
- - spec/data_fixtures/suntrust.csv
331
- - spec/data_fixtures/test_money_column.csv
332
- - spec/data_fixtures/tokens.yaml
333
- - spec/data_fixtures/two_money_columns.csv
334
- - spec/data_fixtures/yyyymmdd_date_example.csv
335
- - spec/integration/another_bank_example/input.csv
336
- - spec/integration/another_bank_example/output.ledger
337
- - spec/integration/another_bank_example/test_args
338
- - spec/integration/ask_for_account/cli_input.exp
339
- - spec/integration/ask_for_account/expected_output
340
- - spec/integration/ask_for_account/input.csv
341
- - spec/integration/ask_for_account/test_args
342
- - spec/integration/austrian_example/input.csv
343
- - spec/integration/austrian_example/output.ledger
344
- - spec/integration/austrian_example/test_args
345
- - spec/integration/bom_utf8_file/input.csv
346
- - spec/integration/bom_utf8_file/output.ledger
347
- - spec/integration/bom_utf8_file/test_args
348
- - spec/integration/broker_canada_example/input.csv
349
- - spec/integration/broker_canada_example/output.ledger
350
- - spec/integration/broker_canada_example/test_args
351
- - spec/integration/chase/account_tokens_and_regex/output.ledger
352
- - spec/integration/chase/account_tokens_and_regex/test_args
353
- - spec/integration/chase/account_tokens_and_regex/tokens.yml
354
- - spec/integration/chase/default_account_names/output.ledger
355
- - spec/integration/chase/default_account_names/test_args
356
- - spec/integration/chase/input.csv
357
- - spec/integration/chase/learn_from_existing/learn.ledger
358
- - spec/integration/chase/learn_from_existing/output.ledger
359
- - spec/integration/chase/learn_from_existing/test_args
360
- - spec/integration/chase/simple/output.ledger
361
- - spec/integration/chase/simple/test_args
362
- - spec/integration/danish_kroner_nordea_example/input.csv
363
- - spec/integration/danish_kroner_nordea_example/output.ledger
364
- - spec/integration/danish_kroner_nordea_example/test_args
365
- - spec/integration/english_date_example/input.csv
366
- - spec/integration/english_date_example/output.ledger
367
- - spec/integration/english_date_example/test_args
368
- - spec/integration/extratofake/input.csv
369
- - spec/integration/extratofake/output.ledger
370
- - spec/integration/extratofake/test_args
371
- - spec/integration/french_example/input.csv
372
- - spec/integration/french_example/output.ledger
373
- - spec/integration/french_example/test_args
374
- - spec/integration/german_date_example/input.csv
375
- - spec/integration/german_date_example/output.ledger
376
- - spec/integration/german_date_example/test_args
377
- - spec/integration/harder_date_example/input.csv
378
- - spec/integration/harder_date_example/output.ledger
379
- - spec/integration/harder_date_example/test_args
380
- - spec/integration/ing/input.csv
381
- - spec/integration/ing/output.ledger
382
- - spec/integration/ing/test_args
383
- - spec/integration/intuit_mint_example/input.csv
384
- - spec/integration/intuit_mint_example/output.ledger
385
- - spec/integration/intuit_mint_example/test_args
386
- - spec/integration/invalid_header_example/input.csv
387
- - spec/integration/invalid_header_example/output.ledger
388
- - spec/integration/invalid_header_example/test_args
389
- - spec/integration/inversed_credit_card/input.csv
390
- - spec/integration/inversed_credit_card/output.ledger
391
- - spec/integration/inversed_credit_card/test_args
392
- - spec/integration/ledger_date_format/compare_cmds
393
- - spec/integration/ledger_date_format/input.csv
394
- - spec/integration/ledger_date_format/output.ledger
395
- - spec/integration/ledger_date_format/test_args
396
- - spec/integration/nationwide/input.csv
397
- - spec/integration/nationwide/output.ledger
398
- - spec/integration/nationwide/test_args
399
- - spec/integration/regression/issue_51_account_tokens/input.csv
400
- - spec/integration/regression/issue_51_account_tokens/output.ledger
401
- - spec/integration/regression/issue_51_account_tokens/test_args
402
- - spec/integration/regression/issue_51_account_tokens/tokens.yml
403
- - spec/integration/regression/issue_64_date_column/input.csv
404
- - spec/integration/regression/issue_64_date_column/output.ledger
405
- - spec/integration/regression/issue_64_date_column/test_args
406
- - spec/integration/regression/issue_73_account_token_matching/input.csv
407
- - spec/integration/regression/issue_73_account_token_matching/output.ledger
408
- - spec/integration/regression/issue_73_account_token_matching/test_args
409
- - spec/integration/regression/issue_73_account_token_matching/tokens.yml
410
- - spec/integration/regression/issue_85_date_example/input.csv
411
- - spec/integration/regression/issue_85_date_example/output.ledger
412
- - spec/integration/regression/issue_85_date_example/test_args
413
- - spec/integration/spanish_date_example/input.csv
414
- - spec/integration/spanish_date_example/output.ledger
415
- - spec/integration/spanish_date_example/test_args
416
- - spec/integration/suntrust/input.csv
417
- - spec/integration/suntrust/output.ledger
418
- - spec/integration/suntrust/test_args
419
- - spec/integration/test.sh
420
- - spec/integration/test_money_column/input.csv
421
- - spec/integration/test_money_column/output.ledger
422
- - spec/integration/test_money_column/test_args
423
- - spec/integration/two_money_columns/input.csv
424
- - spec/integration/two_money_columns/output.ledger
425
- - spec/integration/two_money_columns/test_args
426
- - spec/integration/yyyymmdd_date_example/input.csv
427
- - spec/integration/yyyymmdd_date_example/output.ledger
428
- - spec/integration/yyyymmdd_date_example/test_args
429
- - spec/reckon/app_spec.rb
430
- - spec/reckon/csv_parser_spec.rb
431
- - spec/reckon/date_column_spec.rb
432
- - spec/reckon/ledger_parser_spec.rb
433
- - spec/reckon/money_column_spec.rb
434
- - spec/reckon/money_spec.rb
435
- - spec/reckon/options_spec.rb
436
- - spec/spec.opts
437
- - spec/spec_helper.rb
313
+ test_files: []
@@ -1,33 +0,0 @@
1
- #!/usr/bin/expect -f
2
-
3
-
4
- set timeout 7
5
- match_max 100000
6
- expect "What is this account named in Ledger |Assets:Bank:Checking|?\r
7
- \[1Gā–½\[6n"
8
- send -- "\[45;2R"
9
- expect -exact "\[1G\[K\[6n"
10
- send -- "\[45;1R"
11
- expect "\[1G\[K\[1G\[1G"
12
- send -- "T"
13
- expect "\[1GT\[K\[1G\[2G"
14
- send -- "e"
15
- expect "\[1GTe\[K\[1G\[3G"
16
- send -- "s"
17
- expect "\[1GTes\[K\[1G\[4G"
18
- send -- "t"
19
- expect "\[1GTest\[K\[1G\[5G"
20
- send -- ":"
21
- expect "\[1GTest:\[K\[1G\[6G"
22
- send -- ":"
23
- expect "\[1GTest::\[K\[1G\[7G"
24
- send -- "B"
25
- expect "\[1GTest::B\[K\[1G\[8G"
26
- send -- "a"
27
- expect "\[1GTest::Ba\[K\[1G\[9G"
28
- send -- "n"
29
- expect "\[1GTest::Ban\[K\[1G\[10G"
30
- send -- "k"
31
- expect "\[1GTest::Bank\[K\[1G\[11G"
32
- send -- "\r"
33
- expect eof