reckon 0.9.5 → 0.9.6

Sign up to get free protection for your applications and to get access to all the features.
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