reckon 0.9.5 → 0.9.6

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: 489081763b4a46c0bad41cb3ff3435c505a413e3e2cdf39984ff51b6488bbcc2
4
- data.tar.gz: c4f6cfc6bec319fd8366c5effabb6c23b086bd0b90a57f9f9f64742805a03fc1
3
+ metadata.gz: 2f1e02a1c5dde18325b138afa66518fc2516ea30e8c39eae5cdff2808f5f8bb4
4
+ data.tar.gz: 3d70362d3b8c8a3e6e147f4ca3466e35db7905e2bfe60571de9d219c330e23db
5
5
  SHA512:
6
- metadata.gz: b995bbf4939b6901fa769188a4f329a549d0ea20048a968c331fdce40c7e79174d65454d1805f5ba9a66717c7269afbdeef931af8e961a52e1327a7edbbc80e1
7
- data.tar.gz: e5107209cf8e6da13c6484d064ec7e6e911502128d891d03590b04354ae5fa24670044e77aab2b90733882391cadb3a8adbd1a8645916b7dcb39d8811dba5070
6
+ metadata.gz: 707f23ee5da2df3837f0ae5c520e8b62d802d812dd9ab3acef72853c5e7d27d51b7aeaa269f89c66de1b73ab0e6891fb9ced9d3f59fb11c49d7679fa84c0e4f5
7
+ data.tar.gz: 73bbdf6dec9a09c23735695d8c192fde6b94df1d4931e7e79a256bed20a736e46d1503985dc29689f7f4fbaefd5c11413f4a41eb58516691b77daef99c2c8c75
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- reckon (0.9.5)
4
+ reckon (0.9.6)
5
5
  chronic (>= 0.3.0)
6
6
  highline (~> 2.0)
7
7
  matrix (>= 0.4.2)
data/Rakefile CHANGED
@@ -8,6 +8,7 @@ RSpec::Core::RakeTask.new(:spec)
8
8
 
9
9
  task default: :spec
10
10
 
11
+ desc "Run specs and integration tests"
11
12
  task :test_all do
12
13
  puts "#{`ledger --version |head -n1`}"
13
14
  puts "Running unit tests"
@@ -16,6 +17,7 @@ task :test_all do
16
17
  Rake::Task["test_integration"].invoke
17
18
  end
18
19
 
20
+ desc "Run integration tests"
19
21
  task :test_integration do
20
22
  cmd = 'prove -v ./spec/integration/test.sh'
21
23
  raise 'Integration tests failed' unless system(cmd)
@@ -28,5 +28,6 @@ gem build reckon.gemspec
28
28
  echo "Push changes and tags"
29
29
  echo "git push && git push --tags"
30
30
  echo "Push new gem"
31
- echo "gem push reckon-$VERSION.gem"
31
+ echo "gem push reckon-$VERSION.gem --otp (ykman oath accounts code -s rubygems.org)"
32
+ echo "Publish draft github release"
32
33
  gh release create "v$VERSION" "reckon-$VERSION.gem" --draft --generate-notes
@@ -107,8 +107,8 @@
107
107
  require 'rubygems'
108
108
 
109
109
  module Reckon
110
+ # Parses ledger files
110
111
  class LedgerParser
111
-
112
112
  # ledger is an object that response to #each_line,
113
113
  # (i.e. a StringIO or an IO object)
114
114
  def initialize(options = {})
@@ -130,7 +130,7 @@ module Reckon
130
130
  next if entry =~ /^\s*[#{comment_chars}]/
131
131
 
132
132
  # (date, type, code, description), type and code are optional
133
- if (m = entry.match(%r{^(\d+[\d/-]+)\s+([*!])?\s*(\([^)]+\))?\s*(.*)$}))
133
+ if (m = entry.match(%r{^(\d+[^\s]+)\s+([*!])?\s*(\([^)]+\))?\s*(.*)$}))
134
134
  add_entry(entries, new_entry)
135
135
  new_entry = {
136
136
  date: try_parse_date(m[1]),
@@ -140,7 +140,7 @@ module Reckon
140
140
  accounts: []
141
141
  }
142
142
  elsif entry =~ /^\s*$/ && new_entry[:date]
143
- add_entry(entries,new_entry)
143
+ add_entry(entries, new_entry)
144
144
  new_entry = {}
145
145
  elsif new_entry[:date] && entry =~ /^\s+/
146
146
  LOGGER.info("Adding new account #{entry}")
@@ -175,13 +175,13 @@ module Reckon
175
175
  end
176
176
 
177
177
  def format_row(row, line1, line2)
178
- out = "#{row[:pretty_date]}\t#{row[:description]}#{row[:note] ? "\t; " + row[:note]: ""}\n"
178
+ note = row[:note] ? "\t; row[:note]" : ""
179
+ out = "#{row[:pretty_date]}\t#{row[:description]}#{note}\n"
179
180
  out += "\t#{line1.first}\t\t\t#{line1.last}\n"
180
181
  out += "\t#{line2.first}\t\t\t#{line2.last}\n\n"
181
182
  out
182
183
  end
183
184
 
184
-
185
185
  private
186
186
 
187
187
  def add_entry(entries, entry)
@@ -1,3 +1,3 @@
1
1
  module Reckon
2
- VERSION = "0.9.5"
2
+ VERSION = "0.9.6"
3
3
  end
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env ruby
2
- #encoding: utf-8
2
+ # encoding: utf-8
3
3
 
4
4
  require_relative "../spec_helper"
5
5
  require 'rubygems'
@@ -28,27 +28,31 @@ describe Reckon::LedgerParser do
28
28
  property_of do
29
29
  Rantly do
30
30
  description = Proc.new do
31
- sized(15){string}.tr(%q{'`:*\\},'').gsub(/\s+/, ' ').gsub(/^[!;<\[( #{comment_chars}]+/, '')
31
+ sized(15) {
32
+ string
33
+ }.tr(%q{'`:*\\}, '').gsub(/\s+/, ' ').gsub(/^[!;<\[( #{comment_chars}]+/, '')
32
34
  end
33
35
  currency = choose(*currencies) # to be consistent within the transaction
34
- single_line_comments = ";#|%*".split('').map { |n| "#{n} #{call(description)}" }
36
+ single_line_comments = ";#|%*".split('').map { |n|
37
+ "#{n} #{call(description)}"
38
+ }
35
39
  comments = ['', '; ', "\t;#{call(description)}", " ; #{call(description)}"]
36
40
  date = Time.at(range(0, 1_581_389_644)).strftime(choose(*formats))
37
41
  codes = [' ', " (#{string(:alnum).tr('()', '')}) "]
38
42
  account = Proc.new { choose(*delimiters) + call(description) }
39
43
  account_money = Proc.new do
40
- sprintf("%.02f", (float * range(5,10) + 1) * choose(1, -1))
44
+ sprintf("%.02f", (float * range(5, 10) + 1) * choose(1, -1))
41
45
  end
42
46
  account_line = Proc.new do
43
47
  call(account) + \
44
- choose(*delimiters) + \
45
- currency + \
46
- choose(*currency_delimiters) + \
47
- call(account_money) + \
48
- choose(*comments)
48
+ choose(*delimiters) + \
49
+ currency + \
50
+ choose(*currency_delimiters) + \
51
+ call(account_money) + \
52
+ choose(*comments)
49
53
  end
50
54
  ledger = "#{date}#{choose(*types)}#{choose(*codes)}#{call(description)}\n"
51
- range(1,5).times do
55
+ range(1, 5).times do
52
56
  ledger += "#{call(account_line)}\n"
53
57
  end
54
58
  ledger += "#{call(account)}\n"
@@ -56,7 +60,10 @@ describe Reckon::LedgerParser do
56
60
  ledger
57
61
  end
58
62
  end.check(1000) do |s|
59
- filter_format = lambda { |n| [n['date'], n['desc'], n['name'], sprintf("%.02f", n['amount'])] }
63
+ filter_format = lambda { |n|
64
+ [n['date'], n['desc'], n['name'],
65
+ sprintf("%.02f", n['amount'])]
66
+ }
60
67
  headers = %w[date code desc name currency amount type commend]
61
68
  safe_s = Shellwords.escape(s)
62
69
 
@@ -64,7 +71,8 @@ describe Reckon::LedgerParser do
64
71
  actual = CSV.parse(lp_csv, headers: headers).map(&filter_format)
65
72
 
66
73
  ledger_csv = `echo #{safe_s} | ledger csv --date-format '%Y/%m/%d' -f - `
67
- expected = CSV.parse(ledger_csv.gsub('\"', '""'), headers: headers).map(&filter_format)
74
+ expected = CSV.parse(ledger_csv.gsub('\"', '""'),
75
+ headers: headers).map(&filter_format)
68
76
  expected.length.times do |i|
69
77
  expect(actual[i]).to eq(expected[i])
70
78
  end
@@ -72,34 +80,35 @@ describe Reckon::LedgerParser do
72
80
  end
73
81
 
74
82
  it 'should filter block comments' do
75
- ledger = <<HERE
76
- 1970/11/01 Dinner should show up
77
- Assets:Checking -123.00
78
- Expenses:Restaurants
83
+ ledger = <<~HERE
84
+ 1970/11/01 Dinner should show up
85
+ Assets:Checking -123.00
86
+ Expenses:Restaurants
79
87
 
80
- comment
88
+ comment
81
89
 
82
- 1970/11/01 Lunch should NOT show up
83
- Assets:Checking -12.00
84
- Expenses:Restaurants
90
+ 1970/11/01 Lunch should NOT show up
91
+ Assets:Checking -12.00
92
+ Expenses:Restaurants
85
93
 
86
- end comment
87
- HERE
94
+ end comment
95
+ HERE
88
96
  entries = Reckon::LedgerParser.new.parse(StringIO.new(ledger))
89
97
  expect(entries.length).to eq(1)
90
98
  expect(entries.first[:desc]).to eq('Dinner should show up')
91
-
92
99
  end
93
100
 
94
101
  it 'should transaction comments' do
95
- ledger = <<HERE
96
- 2020-03-27 AMZN Mktp USX999H3203; Shopping; Sale
97
- Expenses:Household $82.77
98
- Liabilities:ChaseSapphire -$81.77
99
- # END FINANCE SCRIPT OUTPUT Thu 02 Apr 2020 12:05:54 PM EDT
100
- HERE
102
+ ledger = <<~HERE
103
+ 2020-03-27 AMZN Mktp USX999H3203; Shopping; Sale
104
+ Expenses:Household $82.77
105
+ Liabilities:ChaseSapphire -$81.77
106
+ # END FINANCE SCRIPT OUTPUT Thu 02 Apr 2020 12:05:54 PM EDT
107
+ HERE
101
108
  entries = Reckon::LedgerParser.new.parse(StringIO.new(ledger))
102
- expect(entries.first[:accounts].map { |n| n[:name] }).to eq(['Expenses:Household', 'Liabilities:ChaseSapphire'])
109
+ expect(entries.first[:accounts].map { |n|
110
+ n[:name]
111
+ }).to eq(['Expenses:Household', 'Liabilities:ChaseSapphire'])
103
112
  expect(entries.first[:accounts].size).to eq(2)
104
113
  expect(entries.length).to eq(1)
105
114
  end
@@ -123,80 +132,99 @@ HERE
123
132
  @entries.last[:accounts].last[:name].should == "Assets:Bank:Checking"
124
133
  @entries.last[:accounts].last[:amount].should == -20.24
125
134
  end
135
+
136
+ it "should parse dot-separated dates" do
137
+ ledger = <<~HERE
138
+ 2024.03.12 groceries; 11223344556; 32095205940
139
+ assets:bank:spending 530.00 NOK
140
+ assets:bank:co:groceries
141
+
142
+ 2024.03.13 autosave; 11223344555; 11223344556
143
+ assets:bank:savings
144
+ assets:bank:spending -10.00 NOK
145
+ HERE
146
+ options = { ledger_date_format: '%Y.%m.%d' }
147
+ entries = Reckon::LedgerParser.new(options).parse(StringIO.new(ledger))
148
+ expect(entries.first[:date]).to eq(Date.new(2024, 3, 12))
149
+ expect(entries.last[:date]).to eq(Date.new(2024, 3, 13))
150
+ expect(entries.length).to eq(2)
151
+ end
126
152
  end
127
153
 
128
154
  describe "balance" do
129
155
  it "it should balance out missing account values" do
130
156
  @ledger.send(:balance, [
131
- { :name => "Account1", :amount => 1000 },
132
- { :name => "Account2", :amount => nil }
133
- ]).should == [ { :name => "Account1", :amount => 1000 }, { :name => "Account2", :amount => -1000 } ]
157
+ { :name => "Account1", :amount => 1000 },
158
+ { :name => "Account2", :amount => nil }
159
+ ]).should == [{ :name => "Account1", :amount => 1000 },
160
+ { :name => "Account2", :amount => -1000 }]
134
161
  end
135
162
 
136
163
  it "it should balance out missing account values" do
137
164
  @ledger.send(:balance, [
138
- { :name => "Account1", :amount => 1000 },
139
- { :name => "Account2", :amount => 100 },
140
- { :name => "Account3", :amount => -200 },
141
- { :name => "Account4", :amount => nil }
142
- ]).should == [
143
- { :name => "Account1", :amount => 1000 },
144
- { :name => "Account2", :amount => 100 },
145
- { :name => "Account3", :amount => -200 },
146
- { :name => "Account4", :amount => -900 }
147
- ]
165
+ { :name => "Account1", :amount => 1000 },
166
+ { :name => "Account2", :amount => 100 },
167
+ { :name => "Account3", :amount => -200 },
168
+ { :name => "Account4", :amount => nil }
169
+ ]).should == [
170
+ { :name => "Account1", :amount => 1000 },
171
+ { :name => "Account2", :amount => 100 },
172
+ { :name => "Account3", :amount => -200 },
173
+ { :name => "Account4", :amount => -900 }
174
+ ]
148
175
  end
149
176
 
150
177
  it "it should work on normal values too" do
151
178
  @ledger.send(:balance, [
152
- { :name => "Account1", :amount => 1000 },
153
- { :name => "Account2", :amount => -1000 }
154
- ]).should == [ { :name => "Account1", :amount => 1000 }, { :name => "Account2", :amount => -1000 } ]
179
+ { :name => "Account1", :amount => 1000 },
180
+ { :name => "Account2", :amount => -1000 }
181
+ ]).should == [{ :name => "Account1", :amount => 1000 },
182
+ { :name => "Account2", :amount => -1000 }]
155
183
  end
156
184
  end
157
185
 
158
186
  # Data
159
187
 
160
- EXAMPLE_LEDGER = (<<-LEDGER).strip
161
- = /^Expenses:Books/
162
- (Liabilities:Taxes) -0.10
188
+ EXAMPLE_LEDGER = (<<~LEDGER).strip
189
+ = /^Expenses:Books/
190
+ (Liabilities:Taxes) -0.10
163
191
 
164
- ~ Monthly
165
- Assets:Bank:Checking $500.00
166
- Income:Salary
192
+ ~ Monthly
193
+ Assets:Bank:Checking $500.00
194
+ Income:Salary
167
195
 
168
- 2004-05-01 * Checking balance
169
- Assets:Bank:Checking $1,000.00
170
- Equity:Opening Balances
196
+ 2004-05-01 * Checking balance
197
+ Assets:Bank:Checking $1,000.00
198
+ Equity:Opening Balances
171
199
 
172
- 2004-05-01 * Checking balance
173
- Assets:Bank:Checking €1,000.00
174
- Equity:Opening Balances
200
+ 2004-05-01 * Checking balance
201
+ Assets:Bank:Checking €1,000.00
202
+ Equity:Opening Balances
175
203
 
176
- 2004-05-01 * Checking balance
177
- Assets:Bank:Checking 1,000.00 SEK
178
- Equity:Opening Balances
204
+ 2004-05-01 * Checking balance
205
+ Assets:Bank:Checking 1,000.00 SEK
206
+ Equity:Opening Balances
179
207
 
180
- 2004/05/01 * Investment balance
181
- Assets:Brokerage 50 AAPL @ $30.00
182
- Equity:Opening Balances
208
+ 2004/05/01 * Investment balance
209
+ Assets:Brokerage 50 AAPL @ $30.00
210
+ Equity:Opening Balances
183
211
 
184
- ; blah
185
- !account blah
212
+ ; blah
213
+ !account blah
186
214
 
187
- !end
215
+ !end
188
216
 
189
- D $1,000
217
+ D $1,000
190
218
 
191
- 2004/05/14 * Pay day
192
- Assets:Bank:Checking $500.00
193
- Income:Salary
219
+ 2004/05/14 * Pay day
220
+ Assets:Bank:Checking $500.00
221
+ Income:Salary
194
222
 
195
- 2004/05/27 Book Store
196
- Expenses:Books $20.00
197
- Liabilities:MasterCard
198
- 2004/05/27 (100) Credit card company
199
- Liabilities:MasterCard $20.24
200
- Assets:Bank:Checking
223
+ 2004/05/27 Book Store
224
+ Expenses:Books $20.00
225
+ Liabilities:MasterCard
226
+ 2004/05/27 (100) Credit card company
227
+ Liabilities:MasterCard $20.24
228
+ Assets:Bank:Checking
201
229
  LEDGER
202
230
  end
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.5
4
+ version: 0.9.6
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-01-08 00:00:00.000000000 Z
13
+ date: 2024-03-27 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: rspec