reckon 0.9.6 → 0.11.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 2f1e02a1c5dde18325b138afa66518fc2516ea30e8c39eae5cdff2808f5f8bb4
4
- data.tar.gz: 3d70362d3b8c8a3e6e147f4ca3466e35db7905e2bfe60571de9d219c330e23db
3
+ metadata.gz: 58ef387a88fd33e7aeddc98842e3c5cf147e74830b659393ec5f75d0179d6bba
4
+ data.tar.gz: 3983fafdcce5b9e016dfd09cfa7a905bc0bf829d3b15f383f162b5738bbf0f49
5
5
  SHA512:
6
- metadata.gz: 707f23ee5da2df3837f0ae5c520e8b62d802d812dd9ab3acef72853c5e7d27d51b7aeaa269f89c66de1b73ab0e6891fb9ced9d3f59fb11c49d7679fa84c0e4f5
7
- data.tar.gz: 73bbdf6dec9a09c23735695d8c192fde6b94df1d4931e7e79a256bed20a736e46d1503985dc29689f7f4fbaefd5c11413f4a41eb58516691b77daef99c2c8c75
6
+ metadata.gz: 44731aea841dc2c3a4830085eda5dccc3b8958502eb21b8aee7ea4d52f2429e7dc2125de4c15084c804970ebc1199a859ef87437518f9635d0f8c33ae7c4444c
7
+ data.tar.gz: c2f4ed1e9ccf0f169a285d5337b3f97b7867d018a8541f4c009fe4dc105f0141884066071860a68b9baf688452b44ccc34b109d6ad4ff576645213c0ece3019e
data/.rubocop.yml CHANGED
@@ -18,3 +18,15 @@ Metrics/AbcSize:
18
18
 
19
19
  Style/NumericPredicate:
20
20
  Enabled: False
21
+
22
+ Metrics/PerceivedComplexity:
23
+ Enabled: False
24
+
25
+ Metrics/CyclomaticComplexity:
26
+ Enabled: False
27
+
28
+ Style/FormatString:
29
+ Enabled: False
30
+
31
+ Naming/MethodParameterName:
32
+ Enabled: False
data/CHANGELOG.md CHANGED
@@ -1,5 +1,31 @@
1
1
  # Changelog
2
2
 
3
+ ## [v0.11.0](https://github.com/cantino/reckon/tree/v0.11.0) (2025-03-04)
4
+
5
+ [Full Changelog](https://github.com/cantino/reckon/compare/v0.10.0...v0.11.0)
6
+
7
+ **Closed issues:**
8
+
9
+ - Feature request: confidence score [\#134](https://github.com/cantino/reckon/issues/134)
10
+ - feature request [\#133](https://github.com/cantino/reckon/issues/133)
11
+
12
+ ## [v0.10.0](https://github.com/cantino/reckon/tree/v0.10.0) (2024-11-27)
13
+
14
+ [Full Changelog](https://github.com/cantino/reckon/compare/v0.9.6...v0.10.0)
15
+
16
+ **Closed issues:**
17
+
18
+ - Is it possible to use reckon with only no info about incoming or going out? [\#131](https://github.com/cantino/reckon/issues/131)
19
+ - Reckon fails immediately with error about uninitialized constant `Readline` [\#129](https://github.com/cantino/reckon/issues/129)
20
+
21
+ ## [v0.9.6](https://github.com/cantino/reckon/tree/v0.9.6) (2024-03-27)
22
+
23
+ [Full Changelog](https://github.com/cantino/reckon/compare/v0.9.5...v0.9.6)
24
+
25
+ **Closed issues:**
26
+
27
+ - reckon can't learn from a file with the "wrong" date format [\#130](https://github.com/cantino/reckon/issues/130)
28
+
3
29
  ## [v0.9.5](https://github.com/cantino/reckon/tree/v0.9.5) (2024-01-08)
4
30
 
5
31
  [Full Changelog](https://github.com/cantino/reckon/compare/v0.9.4...v0.9.5)
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- reckon (0.9.6)
4
+ reckon (0.11.0)
5
5
  chronic (>= 0.3.0)
6
6
  highline (~> 2.0)
7
7
  matrix (>= 0.4.2)
@@ -21,7 +21,7 @@ GEM
21
21
  method_source (~> 1.0)
22
22
  rake (13.0.6)
23
23
  rantly (1.2.0)
24
- rchardet (1.8.0)
24
+ rchardet (1.9.0)
25
25
  rspec (3.12.0)
26
26
  rspec-core (~> 3.12.0)
27
27
  rspec-expectations (~> 3.12.0)
data/README.md CHANGED
@@ -49,6 +49,8 @@ Learn more:
49
49
  Column number of the money columns, starts from 1 (1 or 2 columns)
50
50
  --raw-money
51
51
  Don't format money column (for stocks)
52
+ --sort DATE|DESC|AMT
53
+ Sort file by date, description, or amount
52
54
  --date-column 3
53
55
  Column number of the date column, starts from 1
54
56
  --contains-header [N]
@@ -106,6 +108,9 @@ Would tokenize to 'ING', 'Direct' and 'Deposit'. The matcher would then suggest
106
108
  Here's an example of `tokens.yaml`:
107
109
 
108
110
  ```
111
+ config:
112
+ similarity_threshold: 2 # range 0-10
113
+
109
114
  Income:
110
115
  Salary:
111
116
  - 'LÖN'
@@ -124,6 +129,8 @@ Expenses:
124
129
 
125
130
  Reckon will use `Income:Unknown` or `Expenses:Unknown` if it can't match a transaction to an account.
126
131
 
132
+ The config key is a special key used to set configuration when running in unattended mode. The only config variable is similarity_threshold (currently).
133
+
127
134
  You can override these names with the `--default_outof_account` and `--default_into_account` options.
128
135
 
129
136
  ### Substring Match
data/lib/reckon/app.rb CHANGED
@@ -3,6 +3,8 @@
3
3
  require 'yaml'
4
4
  require 'stringio'
5
5
 
6
+ UnattendedConfig = Struct.new(:similarity_threshold)
7
+
6
8
  module Reckon
7
9
  # The main app
8
10
  class App
@@ -10,10 +12,11 @@ module Reckon
10
12
 
11
13
  def initialize(opts = {})
12
14
  self.options = opts
13
- LOGGER.level = Logger::INFO if options[:verbose]
15
+ LOGGER.level = options[:verbose] || Logger::WARN
14
16
 
15
17
  self.regexps = {}
16
18
  self.seen = Set.new
19
+ options[:sort] ||= :date
17
20
  @cli = HighLine.new
18
21
  @csv_parser = CSVParser.new(options)
19
22
  @matcher = CosineSimilarity.new(options)
@@ -41,7 +44,11 @@ module Reckon
41
44
 
42
45
  raise "#{filename} doesn't exist!" unless File.exist?(filename)
43
46
 
44
- extract_account_tokens(YAML.load_file(filename)).each do |account, tokens|
47
+ tokens = YAML.load_file(filename)
48
+ cfg = build_unattended_config(tokens.delete('config'))
49
+ @options[:similarity_threshold] = cfg.similarity_threshold if cfg
50
+
51
+ extract_account_tokens(tokens).each do |account, tokens|
45
52
  tokens.each do |t|
46
53
  if t.start_with?('/')
47
54
  add_regexp(account, t)
@@ -52,6 +59,13 @@ module Reckon
52
59
  end
53
60
  end
54
61
 
62
+ def build_unattended_config(cfg)
63
+ return unless cfg
64
+ invalid = cfg.keys - UnattendedConfig.members.map(&:to_s)
65
+ raise "Invalid keys in config: #{invalid}" if invalid.any?
66
+ return UnattendedConfig.new(*cfg.values_at(*UnattendedConfig.members.map(&:to_s)))
67
+ end
68
+
55
69
  def learn_from_ledger_file(ledger_file)
56
70
  return unless ledger_file
57
71
 
@@ -80,7 +94,7 @@ module Reckon
80
94
 
81
95
  # Add tokens from account_tokens_file to accounts
82
96
  def extract_account_tokens(subtree, account = nil)
83
- if subtree.nil?
97
+ if subtree.nil? || !subtree
84
98
  puts "Warning: empty #{account} tree"
85
99
  {}
86
100
  elsif subtree.is_a?(Array)
@@ -141,6 +155,11 @@ module Reckon
141
155
  line2 = [options[:bank_account], row[:pretty_money]]
142
156
  end
143
157
 
158
+ if answer == '~~SKIP~~'
159
+ LOGGER.info "skipping transaction: #{row}"
160
+ next
161
+ end
162
+
144
163
  finish if %w[quit q].include?(answer)
145
164
  if %w[skip s].include?(answer)
146
165
  interactive_output "Skipping"
@@ -168,18 +187,29 @@ module Reckon
168
187
  :money => @csv_parser.money_for(index),
169
188
  :description => @csv_parser.description_for(index) }
170
189
  end
171
- rows.sort_by { |n| [n[:date], -n[:money], n[:description]] }.each { |row| yield row }
190
+ rows.sort_by do |n|
191
+ [n[options[:sort]], -n[:money], n[:description]]
192
+ end.each do |row|
193
+ yield row
194
+ end
172
195
  end
173
196
 
174
197
  def print_transaction(rows, fh = $stdout)
175
198
  str = "\n"
176
- header = %w[Date Amount Description Note]
199
+ header = %w[Date Amount Description]
200
+ header += ["Note"] if rows.map { |r| r[:note] }.any?
177
201
  maxes = header.map(&:length)
178
-
179
- rows = rows.map { |r| [r[:pretty_date], r[:pretty_money], r[:description], r[:note]] }
202
+ rows = rows.map do |r|
203
+ [r[:pretty_date], r[:pretty_money], r[:description], r[:note]].compact
204
+ end
180
205
 
181
206
  rows.each do |r|
182
- r.length.times { |i| l = r[i] ? r[i].length : 0; maxes[i] = l if maxes[i] < l }
207
+ r.length.times do |i|
208
+ l = 0
209
+ l = r[i].length if r[i]
210
+ maxes[i] ||= 0
211
+ maxes[i] = l if maxes[i] < l
212
+ end
183
213
  end
184
214
 
185
215
  header.each_with_index do |n, i|
@@ -199,6 +229,15 @@ module Reckon
199
229
  end
200
230
 
201
231
  def ask_account_question(msg, row)
232
+ # return account token if it matches
233
+ token_answer = most_specific_regexp_match(row)
234
+ if token_answer.any?
235
+ row[:note] = "Matched account token"
236
+ puts "NOTE: Matched account token"
237
+ puts token_answer[0]
238
+ return token_answer[0]
239
+ end
240
+
202
241
  possible_answers = suggest(row)
203
242
  LOGGER.info "possible_answers===> #{possible_answers.inspect}"
204
243
 
@@ -261,7 +300,10 @@ module Reckon
261
300
 
262
301
  def suggest(row)
263
302
  most_specific_regexp_match(row) +
264
- @matcher.find_similar(row[:description]).map { |n| n[:account] }
303
+ @matcher.find_similar(row[:description]).filter do |n|
304
+ !@options[:similarity_threshold] ||
305
+ n.fetch(:simliarity, 0) * 10 >= @options[:similarity_threshold]
306
+ end.map { |n| n[:account] }
265
307
  end
266
308
 
267
309
  def output(ledger_line)
@@ -12,6 +12,7 @@ require 'set'
12
12
  # These weights and measures are used to suggest which account a transaction should be
13
13
  # assigned to.
14
14
  module Reckon
15
+ # Calculates cosine similarity for tf/idf
15
16
  class CosineSimilarity
16
17
  DocumentInfo = Struct.new(:tokens, :accounts)
17
18
 
@@ -64,13 +64,13 @@ module Reckon
64
64
  private
65
65
 
66
66
  def filter_csv
67
- if options[:ignore_columns]
68
- new_columns = []
69
- columns.each_with_index do |column, index|
70
- new_columns << column unless options[:ignore_columns].include?(index + 1)
71
- end
72
- @columns = new_columns
67
+ return unless options[:ignore_columns]
68
+
69
+ new_columns = []
70
+ columns.each_with_index do |column, index|
71
+ new_columns << (options[:ignore_columns].include?(index + 1) ? [''] * column.length : column)
73
72
  end
73
+ @columns = new_columns
74
74
  end
75
75
 
76
76
  def evaluate_columns(cols)
@@ -222,7 +222,8 @@ module Reckon
222
222
  # convert to a stringio object to handle multi-line fields
223
223
  parser_opts = {
224
224
  col_sep: separator,
225
- skip_blanks: true
225
+ skip_blanks: true,
226
+ row_sep: :auto
226
227
  }
227
228
  begin
228
229
  rows = CSV.parse(StringIO.new(data), **parser_opts)
@@ -235,7 +236,7 @@ module Reckon
235
236
  index = data.index("\n", index) + 1 # skip over newline character
236
237
  count += 1
237
238
  end
238
- rows = CSV.parse(StringIO.new(data[index..-1]), **parser_opts)
239
+ rows = CSV.parse(StringIO.new(data[index..]), **parser_opts)
239
240
  rows[0..-footer_lines_to_skip]
240
241
  end
241
242
  end
@@ -175,7 +175,7 @@ module Reckon
175
175
  end
176
176
 
177
177
  def format_row(row, line1, line2)
178
- note = row[:note] ? "\t; row[:note]" : ""
178
+ note = row[:note] ? "\t; #{row[:note]}" : ""
179
179
  out = "#{row[:pretty_date]}\t#{row[:description]}#{note}\n"
180
180
  out += "\t#{line1.first}\t\t\t#{line1.last}\n"
181
181
  out += "\t#{line2.first}\t\t\t#{line2.last}\n\n"
data/lib/reckon/logger.rb CHANGED
@@ -1,4 +1,8 @@
1
1
  module Reckon
2
2
  LOGGER = Logger.new(STDERR)
3
3
  LOGGER.level = Logger::WARN
4
+
5
+ def log(tag, msg)
6
+ LOGGER.add(Logger::WARN, msg, tag)
7
+ end
4
8
  end
@@ -4,7 +4,6 @@ module Reckon
4
4
  # Singleton class for parsing command line flags
5
5
  class Options
6
6
  def self.parse_command_line_options(args = ARGV, stdin = $stdin)
7
- cli = HighLine.new
8
7
  options = { output_file: $stdout }
9
8
  OptionParser.new do |opts|
10
9
  opts.banner = "Usage: Reckon.rb [options]"
@@ -18,8 +17,17 @@ module Reckon
18
17
  options[:bank_account] = a
19
18
  end
20
19
 
21
- opts.on("-v", "--[no-]verbose", "Run verbosely") do |v|
22
- options[:verbose] = v
20
+ options[:verbose] = Logger::WARN
21
+ opts.on("-v", "--v", "Run verbosely (show info log messages)") do
22
+ options[:verbose] = Logger::INFO
23
+ end
24
+
25
+ opts.on("", "--verbose", "Run verbosely (show info log messages)") do
26
+ options[:verbose] = Logger::INFO
27
+ end
28
+
29
+ opts.on("", "--vv", "Run very verbosely (show debug log messages)") do
30
+ options[:verbose] = Logger::DEBUG
23
31
  end
24
32
 
25
33
  opts.on("-i", "--inverse", "Use the negative of each amount") do |v|
@@ -58,6 +66,19 @@ module Reckon
58
66
  options[:raw] = n
59
67
  end
60
68
 
69
+ options[:sort] = :date
70
+ opts.on("", "--sort DATE|DESC|AMT", "Sort file by date, description, or amount") do |s|
71
+ if s == 'DESC'
72
+ options[:sort] = :description
73
+ elsif s == 'AMT'
74
+ options[:sort] = :money
75
+ elsif s == 'DATE'
76
+ options[:sort] = :date
77
+ else
78
+ raise "'#{s}' is not valid. valid sort options are DATE, DESC, AMT"
79
+ end
80
+ end
81
+
61
82
  opts.on("", "--date-column 3", Integer,
62
83
  "Column number of the date column, starts from 1") do |col|
63
84
  options[:date_column] = col
@@ -161,26 +182,35 @@ module Reckon
161
182
  options[:string] = stdin.read
162
183
  end
163
184
 
185
+ validate_options(options)
186
+
187
+ return options
188
+ end
189
+
190
+ def self.validate_options(options)
191
+ cli = HighLine.new
164
192
  unless options[:file]
165
193
  options[:file] = cli.ask("What CSV file should I parse? ")
166
- unless options[:file].empty?
167
- puts "\nYou must provide a CSV file to parse.\n"
168
- puts parser
194
+ if options[:file].empty?
195
+ puts "\nERROR: You must provide a CSV file to parse.\n"
169
196
  exit
170
197
  end
171
198
  end
172
199
 
173
200
  unless options[:bank_account]
174
- raise "Must specify --account in unattended mode" if options[:unattended]
201
+ if options[:unattended]
202
+ puts "ERROR: Must specify --account in unattended mode"
203
+ exit
204
+ end
175
205
 
176
- options[:bank_account] = cli.ask("What is this account named in Ledger?\n") do |q|
206
+ options[:bank_account] = cli.ask("What is the Ledger account name?\n") do |q|
177
207
  q.readline = true
178
208
  q.validate = /^.{2,}$/
179
209
  q.default = "Assets:Bank:Checking"
180
210
  end
181
211
  end
182
212
 
183
- return options
213
+ return true
184
214
  end
185
215
  end
186
216
  end
@@ -1,3 +1,3 @@
1
1
  module Reckon
2
- VERSION = "0.9.6"
2
+ VERSION = "0.11.0"
3
3
  end
@@ -8,7 +8,7 @@ ledger_file = ARGV[0]
8
8
  account = ARGV[1]
9
9
  seed = ARGV[2] ? ARGV[2].to_i : Random.new_seed
10
10
 
11
- ledger = Reckon::LedgerParser.new(File.new(ledger_file))
11
+ ledger = Reckon::LedgerParser.new.parse(File.new(ledger_file))
12
12
  matcher = Reckon::CosineSimilarity.new({})
13
13
 
14
14
  train = []
@@ -50,3 +50,4 @@ end
50
50
  # pp result.compact
51
51
  puts "using #{seed} as random seed"
52
52
  puts "true: #{result.count(nil)} false: #{result.count { |v| !v.nil? }}"
53
+ puts(result.filter { |v| !v.nil? })
@@ -1,11 +1,11 @@
1
1
 
2
- Date | Amount | Description | Note |
3
- 2003-12-24 | $2,105.00 | CREDIT; Some Company vendorpymt PPD ID: 5KL3832735 | |
4
- 2004-12-24 | -$116.22 | CREDIT; PAYPAL TRANSFER PPD ID: PAYPALSDSL | |
5
- 2005-12-24 | -$0.96 | DEBIT; WEBSITE-BALANCE-10DEC09 12 12/10WEBSITE-BAL | |
6
- 2006-12-24 | $0.23 | DEBIT; WEBSITE-BALANCE-17DEC09 12 12/17WEBSITE-BAL | |
7
- 2007-12-24 | $1,558.52 | CREDIT; Blarg BLARG REVENUE PPD ID: 00jah78563 | |
8
- 2008-12-24 | $3,520.00 | CREDIT; Some Company vendorpymt PPD ID: 59728JSL20 | |
9
- 2009-12-24 | -$7.00 | DEBIT; GITHUB 041287430274 CA 12/22GITHUB 04 | |
10
- 2010-12-24 | -$20.00 | CHECK; CHECK 2656 | |
11
- 2011-12-24 | -$85.00 | DEBIT; HOST 037196321563 MO 12/22SLICEHOST | |
2
+ Date | Amount | Description |
3
+ 2003-12-24 | $2,105.00 | CREDIT; Some Company vendorpymt PPD ID: 5KL3832735 |
4
+ 2004-12-24 | -$116.22 | CREDIT; PAYPAL TRANSFER PPD ID: PAYPALSDSL |
5
+ 2005-12-24 | -$0.96 | DEBIT; WEBSITE-BALANCE-10DEC09 12 12/10WEBSITE-BAL |
6
+ 2006-12-24 | $0.23 | DEBIT; WEBSITE-BALANCE-17DEC09 12 12/17WEBSITE-BAL |
7
+ 2007-12-24 | $1,558.52 | CREDIT; Blarg BLARG REVENUE PPD ID: 00jah78563 |
8
+ 2008-12-24 | $3,520.00 | CREDIT; Some Company vendorpymt PPD ID: 59728JSL20 |
9
+ 2009-12-24 | -$7.00 | DEBIT; GITHUB 041287430274 CA 12/22GITHUB 04 |
10
+ 2010-12-24 | -$20.00 | CHECK; CHECK 2656 |
11
+ 2011-12-24 | -$85.00 | DEBIT; HOST 037196321563 MO 12/22SLICEHOST |
@@ -0,0 +1,9 @@
1
+ DEBIT,20091224120000[0:GMT],"HOST 037196321563 MO 12/22SLICEHOST",-85.00
2
+ CHECK,20091224120000[0:GMT],"Book Store",-20.00
3
+ DEBIT,20091224120000[0:GMT],"GITHUB 041287430274 CA 12/22GITHUB 04",-7.00
4
+ CREDIT,20091223120000[0:GMT],"Some Company vendorpymt PPD ID: 59728JSL20",3520.00
5
+ CREDIT,20091223120000[0:GMT],"Blarg BLARG REVENUE PPD ID: 00jah78563",1558.52
6
+ DEBIT,20091221120000[0:GMT],"WEBSITE-BALANCE-17DEC09 12 12/17WEBSITE-BAL",-12.23
7
+ DEBIT,20091214120000[0:GMT],"WEBSITE-BALANCE-10DEC09 12 12/10WEBSITE-BAL",-20.96
8
+ CREDIT,20091211120000[0:GMT],"PAYPAL TRANSFER PPD ID: PAYPALSDSL",-116.22
9
+ CREDIT,20091210120000[0:GMT],"Some Company vendorpymt PPD ID: 5KL3832735",2105.00
@@ -0,0 +1,36 @@
1
+ 2009-12-10 CREDIT; Some Company vendorpymt PPD ID: 5KL3832735
2
+ Assets:Bank:Checking $2,105.00
3
+ Income:Unknown
4
+
5
+ 2009-12-11 CREDIT; PAYPAL TRANSFER PPD ID: PAYPALSDSL
6
+ Expenses:Unknown
7
+ Assets:Bank:Checking -$116.22
8
+
9
+ 2009-12-14 DEBIT; WEBSITE-BALANCE-10DEC09 12 12/10WEBSITE-BAL
10
+ Expenses:Websites
11
+ Assets:Bank:Checking -$20.96
12
+
13
+ 2009-12-21 DEBIT; WEBSITE-BALANCE-17DEC09 12 12/17WEBSITE-BAL
14
+ Expenses:Websites
15
+ Assets:Bank:Checking -$12.23
16
+
17
+ 2009-12-23 CREDIT; Some Company vendorpymt PPD ID: 59728JSL20
18
+ Assets:Bank:Checking $3,520.00
19
+ Income:Unknown
20
+
21
+ 2009-12-23 CREDIT; Blarg BLARG REVENUE PPD ID: 00jah78563
22
+ Assets:Bank:Checking $1,558.52
23
+ Income:Unknown
24
+
25
+ 2009-12-24 DEBIT; GITHUB 041287430274 CA 12/22GITHUB 04
26
+ Expenses:Unknown
27
+ Assets:Bank:Checking -$7.00
28
+
29
+ 2009-12-24 CHECK; Book Store
30
+ Expenses:Unknown
31
+ Assets:Bank:Checking -$20.00
32
+
33
+ 2009-12-24 DEBIT; HOST 037196321563 MO 12/22SLICEHOST
34
+ Expenses:Unknown
35
+ Assets:Bank:Checking -$85.00
36
+
@@ -0,0 +1,2 @@
1
+ -f input.csv --unattended --account 'Assets:Bank:Checking' \
2
+ --account-tokens tokens.yml
@@ -0,0 +1,19 @@
1
+ config:
2
+ similarity_threshold: 6
3
+
4
+ Income:
5
+ Salary:
6
+ - 'LÖN'
7
+ - 'Salary'
8
+ Expenses:
9
+ Bank:
10
+ - 'Comission'
11
+ - /mastercard/i
12
+ Rent:
13
+ - '0011223344' # Landlord bank number
14
+ Websites:
15
+ - /web/i
16
+ Books:
17
+ - 'Book'
18
+ '[Internal:Transfer]': # Virtual account
19
+ - '4433221100' # Your own account number
@@ -59,7 +59,7 @@ describe Reckon::LedgerParser do
59
59
  ledger += choose(*single_line_comments) + "\n"
60
60
  ledger
61
61
  end
62
- end.check(1000) do |s|
62
+ end.check(100) do |s|
63
63
  filter_format = lambda { |n|
64
64
  [n['date'], n['desc'], n['name'],
65
65
  sprintf("%.02f", n['amount'])]
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: reckon
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.9.6
4
+ version: 0.11.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Andrew Cantino
@@ -10,7 +10,7 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2024-03-27 00:00:00.000000000 Z
13
+ date: 2025-03-04 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: rspec
@@ -274,6 +274,10 @@ files:
274
274
  - spec/integration/two_money_columns_manual/input.csv
275
275
  - spec/integration/two_money_columns_manual/output.ledger
276
276
  - spec/integration/two_money_columns_manual/test_args
277
+ - spec/integration/unattended_config/input.csv
278
+ - spec/integration/unattended_config/output.ledger
279
+ - spec/integration/unattended_config/test_args
280
+ - spec/integration/unattended_config/tokens.yml
277
281
  - spec/integration/yyyymmdd_date_example/input.csv
278
282
  - spec/integration/yyyymmdd_date_example/output.ledger
279
283
  - spec/integration/yyyymmdd_date_example/test_args