hledger-forecast 0.4.0 → 1.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,90 @@
1
+ module HledgerForecast
2
+ module Transactions
3
+ # Generate auto-posting hledger transactions
4
+ # Example output:
5
+ # = Expenses:Groceries date:2024-01-01..2025-12-31
6
+ # Expenses:Groceries *0.1 ; Groceries
7
+ # Assets:Checking *-0.1
8
+ class Modifiers
9
+ def self.generate(data, options)
10
+ new(data, options).generate
11
+ end
12
+
13
+ def generate
14
+ return nil unless modifiers?
15
+
16
+ process_modifier
17
+
18
+ output
19
+ end
20
+
21
+ def self.get_modifiers(transaction, block)
22
+ modifiers = []
23
+
24
+ transaction['modifiers'].each do |modifier|
25
+ description = transaction['description']
26
+ description += " - #{modifier['description']}" unless modifier['description'].empty?
27
+
28
+ modifiers << {
29
+ account: block['account'],
30
+ amount: modifier['amount'],
31
+ category: transaction['category'],
32
+ description: description,
33
+ from: Date.parse(modifier['from'] || block['from']),
34
+ to: modifier['to'] ? Date.parse(modifier['to']) : nil
35
+ }
36
+ end
37
+
38
+ modifiers
39
+ end
40
+
41
+ private
42
+
43
+ attr_reader :data, :options, :output
44
+
45
+ def initialize(data, options)
46
+ @data = data
47
+ @options = options
48
+ @output = []
49
+ end
50
+
51
+ def modifiers?
52
+ @data.any? do |_, blocks|
53
+ blocks.any? do |block|
54
+ block[:transactions].any? do |_, transactions|
55
+ transactions.any? { |t| !t[:modifiers].empty? }
56
+ end
57
+ end
58
+ end
59
+ end
60
+
61
+ def process_modifier
62
+ get_transactions.each do |modifier|
63
+ account = modifier[:account].ljust(@options[:max_category])
64
+ category = modifier[:category].ljust(@options[:max_category])
65
+ # Fix the ljust by counting strings in amount
66
+ amount = modifier[:amount].to_s.ljust(@options[:max_amount] - 1)
67
+ to = modifier[:to] ? "..#{modifier[:to]}" : nil
68
+
69
+ header = "= #{modifier[:category]} date:#{modifier[:from]}#{to}\n"
70
+ transactions = " #{category} *#{amount}; #{modifier[:description]}\n"
71
+ footer = " #{account} *#{modifier[:amount] * -1}\n\n"
72
+
73
+ output << { header: header, transactions: [transactions], footer: footer }
74
+ end
75
+ end
76
+
77
+ def get_transactions
78
+ @data.each_with_object([]) do |(_key, blocks), result|
79
+ blocks.each do |block|
80
+ block[:transactions].each_value do |transactions|
81
+ transactions.each do |t|
82
+ result.concat(t[:modifiers]) if t[:modifiers]
83
+ end
84
+ end
85
+ end
86
+ end
87
+ end
88
+ end
89
+ end
90
+ end
@@ -0,0 +1,87 @@
1
+ module HledgerForecast
2
+ module Transactions
3
+ # Generate hledger transactions based on the non-existance of a transaction
4
+ # in your ledger. This is useful for ensuring that certain expenses are
5
+ # accounted for, even if you forget to enter them.
6
+ #
7
+ # Example output:
8
+ # ~ 2023-05-1 * [TRACKED] Food expenses
9
+ # Expenses:Groceries $250.00 ; Food expenses
10
+ # Assets:Checking
11
+ class Trackers
12
+ def self.generate(data, options)
13
+ new(data, options).generate
14
+ end
15
+
16
+ def generate
17
+ return nil unless tracked?(data)
18
+
19
+ data.each_value do |blocks|
20
+ blocks.each do |block|
21
+ process_tracked(block)
22
+ end
23
+ end
24
+
25
+ output
26
+ end
27
+
28
+ def self.track?(transaction, data, options)
29
+ now = Date.today
30
+ transaction['track'] && Date.parse(data['from']) <= now && !exists?(transaction, data['account'],
31
+ data['from'], now, options)
32
+ end
33
+
34
+ def self.exists?(transaction, account, from, to, options)
35
+ # Format the money
36
+ amount = Formatter.format_money(transaction['amount'], options)
37
+ inverse_amount = Formatter.format_money(transaction['amount'] * -1, options)
38
+
39
+ category = transaction['category'].gsub('[', '\\[').gsub(']', '\\]').gsub('(', '\\(').gsub(')', '\\)')
40
+
41
+ # We run two commands and check to see if category +/- amount or account +/- amount exists
42
+ command1 = %(hledger print -f #{options[:transaction_file]} "date:#{from}..#{to}" | tr -s '[:space:]' ' ' | grep -q -Eo "#{category} (#{amount}|#{inverse_amount})")
43
+ command2 = %(hledger print -f #{options[:transaction_file]} "date:#{from}..#{to}" | tr -s '[:space:]' ' ' | grep -q -Eo "#{account} (#{amount}|#{inverse_amount})")
44
+
45
+ system(command1) || system(command2)
46
+ end
47
+
48
+ private
49
+
50
+ attr_reader :data, :options, :output
51
+
52
+ def initialize(data, options)
53
+ @data = data
54
+ @options = options
55
+ @output = []
56
+ end
57
+
58
+ def tracked?(data)
59
+ data.any? do |_, blocks|
60
+ blocks.any? do |block|
61
+ block[:transactions].any? do |_, transactions|
62
+ transactions.any? { |t| t[:track] }
63
+ end
64
+ end
65
+ end
66
+ end
67
+
68
+ def process_tracked(block)
69
+ block[:transactions].each do |_to, transactions|
70
+ transactions.each do |t|
71
+ next unless t[:track]
72
+
73
+ category = t[:category].ljust(options[:max_category])
74
+ amount = t[:amount].to_s.ljust(options[:max_amount])
75
+
76
+ header = "~ #{Date.new(Date.today.year, Date.today.month,
77
+ 1).next_month} * [TRACKED] #{t[:description]}\n"
78
+ transactions = " #{category} #{amount}; #{t[:description]}\n"
79
+ footer = " #{block[:account]}\n\n"
80
+
81
+ output << { header: header, transactions: [transactions], footer: footer }
82
+ end
83
+ end
84
+ end
85
+ end
86
+ end
87
+ end
@@ -1,3 +1,3 @@
1
1
  module HledgerForecast
2
- VERSION = "0.4.0"
2
+ VERSION = "1.1.0"
3
3
  end
@@ -12,8 +12,16 @@ require 'yaml'
12
12
  Money.locale_backend = nil
13
13
  Money.rounding_mode = BigDecimal::ROUND_HALF_UP
14
14
 
15
- require_relative 'hledger_forecast/version'
16
- require_relative 'hledger_forecast/generator'
17
- require_relative 'hledger_forecast/summarize'
18
- require_relative 'hledger_forecast/tracker'
15
+ require_relative 'hledger_forecast/calculator'
19
16
  require_relative 'hledger_forecast/cli'
17
+ require_relative 'hledger_forecast/formatter'
18
+ require_relative 'hledger_forecast/generator'
19
+ require_relative 'hledger_forecast/settings'
20
+ require_relative 'hledger_forecast/summarizer'
21
+ require_relative 'hledger_forecast/summarizer_formatter'
22
+ require_relative 'hledger_forecast/version'
23
+
24
+ require_relative 'hledger_forecast/transactions/default'
25
+ require_relative 'hledger_forecast/transactions/modifiers'
26
+ require_relative 'hledger_forecast/transactions/trackers'
27
+
data/spec/custom_spec.rb CHANGED
@@ -1,6 +1,6 @@
1
1
  require_relative '../lib/hledger_forecast'
2
2
 
3
- config = <<~YAML
3
+ base_config = <<~YAML
4
4
  custom:
5
5
  - frequency: "every 2 weeks"
6
6
  from: "2023-05-01"
@@ -21,7 +21,7 @@ config = <<~YAML
21
21
  currency: GBP
22
22
  YAML
23
23
 
24
- output = <<~JOURNAL
24
+ base_output = <<~JOURNAL
25
25
  ~ every 2 weeks from 2023-05-01 * Hair and beauty
26
26
  [Expenses:Personal Care] £80.00; Hair and beauty
27
27
  [Assets:Bank]
@@ -32,9 +32,36 @@ output = <<~JOURNAL
32
32
 
33
33
  JOURNAL
34
34
 
35
+ calculated_config = <<~YAML
36
+ custom:
37
+ - frequency: "every 2 weeks"
38
+ from: "2023-05-01"
39
+ account: "[Assets:Bank]"
40
+ transactions:
41
+ - amount: 80
42
+ category: "[Expenses:Personal Care]"
43
+ description: Hair and beauty
44
+ to: "=6"
45
+
46
+ settings:
47
+ currency: GBP
48
+ YAML
49
+
50
+ calculated_output = <<~JOURNAL
51
+ ~ every 2 weeks from 2023-05-01 to 2023-10-31 * Hair and beauty
52
+ [Expenses:Personal Care] £80.00; Hair and beauty
53
+ [Assets:Bank]
54
+
55
+ JOURNAL
56
+
35
57
  RSpec.describe 'generate' do
36
58
  it 'generates a forecast with correct CUSTOM transactions' do
37
- generated_journal = HledgerForecast::Generator.generate(config)
38
- expect(generated_journal).to eq(output)
59
+ generated_journal = HledgerForecast::Generator.generate(base_config)
60
+ expect(generated_journal).to eq(base_output)
61
+ end
62
+
63
+ it 'generates a forecast with correct CUSTOM transactions and CALCULATED to dates' do
64
+ generated_journal = HledgerForecast::Generator.generate(calculated_config)
65
+ expect(generated_journal).to eq(calculated_output)
39
66
  end
40
67
  end
@@ -5,7 +5,7 @@ base_config = <<~YAML
5
5
  - account: "Assets:Bank"
6
6
  from: "2023-01-01"
7
7
  transactions:
8
- - amount: 500
8
+ - amount: 300
9
9
  category: "Expenses:Groceries"
10
10
  description: Food shopping
11
11
  modifiers:
@@ -17,6 +17,17 @@ base_config = <<~YAML
17
17
  description: "Y2 inflation"
18
18
  from: "2025-01-01"
19
19
  to: "2025-12-31"
20
+ - account: "Assets:Savings"
21
+ from: "2023-05-01"
22
+ transactions:
23
+ - amount: 500
24
+ category: "Assets:Bank"
25
+ description: Savings
26
+ modifiers:
27
+ - amount: 0.1
28
+ description: "Savings uplift"
29
+ from: "2024-05-01"
30
+ to: "2025-04-30"
20
31
 
21
32
  settings:
22
33
  currency: USD
@@ -24,9 +35,13 @@ YAML
24
35
 
25
36
  base_journal = <<~JOURNAL
26
37
  ~ monthly from 2023-01-01 * Food shopping
27
- Expenses:Groceries $500.00; Food shopping
38
+ Expenses:Groceries $300.00; Food shopping
28
39
  Assets:Bank
29
40
 
41
+ ~ monthly from 2023-05-01 * Savings
42
+ Assets:Bank $500.00; Savings
43
+ Assets:Savings
44
+
30
45
  = Expenses:Groceries date:2024-01-01..2024-12-31
31
46
  Expenses:Groceries *0.02 ; Food shopping - Y1 inflation
32
47
  Assets:Bank *-0.02
@@ -35,6 +50,10 @@ base_journal = <<~JOURNAL
35
50
  Expenses:Groceries *0.05 ; Food shopping - Y2 inflation
36
51
  Assets:Bank *-0.05
37
52
 
53
+ = Assets:Bank date:2024-05-01..2025-04-30
54
+ Assets:Bank *0.1 ; Savings - Savings uplift
55
+ Assets:Savings *-0.1
56
+
38
57
  JOURNAL
39
58
 
40
59
  no_date_config = <<~YAML
@@ -67,20 +86,16 @@ JOURNAL
67
86
  RSpec.describe 'Applying modifiers to transactions -' do
68
87
  it 'Auto-postings should be created correctly' do
69
88
  generated = HledgerForecast::Generator
70
- generated.modified = {} # Clear modified transactions
71
89
 
72
90
  generated_journal = generated.generate(base_config)
73
- generated.modified = {} # Clear modified transactions
74
91
 
75
92
  expect(generated_journal).to eq(base_journal)
76
93
  end
77
94
 
78
95
  it 'Auto-postings should be created correctly if no dates are set' do
79
96
  generated = HledgerForecast::Generator
80
- generated.modified = {} # Clear modified transactions
81
97
 
82
98
  generated_journal = generated.generate(no_date_config)
83
- generated.modified = {} # Clear modified transactions
84
99
 
85
100
  expect(generated_journal).to eq(no_date_journal)
86
101
  end
@@ -1,47 +1,32 @@
1
1
  require_relative '../lib/hledger_forecast'
2
2
 
3
3
  config = <<~YAML
4
- settings:
5
- currency: GBP
4
+ settings:
5
+ currency: GBP
6
6
 
7
- monthly:
8
- - from: "2023-03-01"
9
- account: "Assets:Bank"
10
- transactions:
11
- - description: Mortgage
12
- to: "2023-06-01"
13
- category: "Expenses:Mortgage"
14
- amount: 2000.00
15
- - description: Mortgage top up
16
- to: "2023-06-01"
17
- category: "Expenses:Mortgage Top Up"
18
- amount: 200.00
19
- - description: Food
20
- category: "Expenses:Food"
21
- amount: 100.00
22
- - description: Party time
23
- category: "Expenses:Going Out"
24
- amount: 50.00
7
+ monthly:
8
+ - from: "2023-03-01"
9
+ to: "2023-06-01"
10
+ account: "Assets:Bank"
11
+ transactions:
12
+ - description: Mortgage
13
+ category: "Expenses:Mortgage"
14
+ amount: 2000.00
15
+ - description: Food
16
+ category: "Expenses:Food"
17
+ amount: 100.00
25
18
  YAML
26
19
 
27
20
  output = <<~JOURNAL
28
- ~ monthly from 2023-03-01 * Food, Party time
29
- Expenses:Food £100.00 ; Food
30
- Expenses:Going Out £50.00 ; Party time
31
- Assets:Bank
32
-
33
- ~ monthly from 2023-03-01 to 2023-06-01 * Mortgage
34
- Expenses:Mortgage £2,000.00; Mortgage
35
- Assets:Bank
36
-
37
- ~ monthly from 2023-03-01 to 2023-06-01 * Mortgage top up
38
- Expenses:Mortgage Top Up £200.00 ; Mortgage top up
39
- Assets:Bank
21
+ ~ monthly from 2023-03-01 to 2023-06-01 * Mortgage, Food
22
+ Expenses:Mortgage £2,000.00; Mortgage
23
+ Expenses:Food £100.00 ; Food
24
+ Assets:Bank
40
25
 
41
26
  JOURNAL
42
27
 
43
28
  RSpec.describe 'generate' do
44
- it 'generates a forecast with correct MONTHLY transactions that have an end date' do
29
+ it 'generates a forecast with correct MONTHLY transactions that have an end date, at the top level' do
45
30
  expect(HledgerForecast::Generator.generate(config)).to eq(output)
46
31
  end
47
32
  end
@@ -1,32 +1,69 @@
1
1
  require_relative '../lib/hledger_forecast'
2
2
 
3
- config = <<~YAML
3
+ base_config = <<~YAML
4
4
  settings:
5
5
  currency: GBP
6
6
 
7
7
  monthly:
8
8
  - from: "2023-03-01"
9
- to: "2023-06-01"
10
9
  account: "Assets:Bank"
11
10
  transactions:
12
11
  - description: Mortgage
12
+ to: "2023-06-01"
13
13
  category: "Expenses:Mortgage"
14
14
  amount: 2000.00
15
+ - description: Mortgage top up
16
+ to: "2023-06-01"
17
+ category: "Expenses:Mortgage Top Up"
18
+ amount: 200.00
15
19
  - description: Food
16
20
  category: "Expenses:Food"
17
21
  amount: 100.00
22
+ - description: Party time
23
+ category: "Expenses:Going Out"
24
+ amount: 50.00
18
25
  YAML
19
26
 
20
- output = <<~JOURNAL
21
- ~ monthly from 2023-03-01 to 2023-06-01 * Mortgage, Food
27
+ base_output = <<~JOURNAL
28
+ ~ monthly from 2023-03-01 to 2023-06-01 * Mortgage, Mortgage top up
29
+ Expenses:Mortgage £2,000.00; Mortgage
30
+ Expenses:Mortgage Top Up £200.00 ; Mortgage top up
31
+ Assets:Bank
32
+
33
+ ~ monthly from 2023-03-01 * Food, Party time
34
+ Expenses:Food £100.00 ; Food
35
+ Expenses:Going Out £50.00 ; Party time
36
+ Assets:Bank
37
+
38
+ JOURNAL
39
+
40
+ computed_config = <<~YAML
41
+ settings:
42
+ currency: GBP
43
+
44
+ monthly:
45
+ - from: "2023-03-01"
46
+ account: "Assets:Bank"
47
+ transactions:
48
+ - description: Mortgage
49
+ category: "Expenses:Mortgage"
50
+ to: "=12"
51
+ amount: 2000.00
52
+ YAML
53
+
54
+ computed_output = <<~JOURNAL
55
+ ~ monthly from 2023-03-01 to 2024-02-29 * Mortgage
22
56
  Expenses:Mortgage £2,000.00; Mortgage
23
- Expenses:Food £100.00 ; Food
24
57
  Assets:Bank
25
58
 
26
59
  JOURNAL
27
60
 
28
61
  RSpec.describe 'generate' do
29
- it 'generates a forecast with correct MONTHLY transactions that have an end date, at the top level' do
30
- expect(HledgerForecast::Generator.generate(config)).to eq(output)
62
+ it 'generates a forecast with correct MONTHLY transactions that have an end date' do
63
+ expect(HledgerForecast::Generator.generate(base_config)).to eq(base_output)
64
+ end
65
+
66
+ it 'generates a forecast with correct MONTHLY transactions that have a COMPUTED end date' do
67
+ expect(HledgerForecast::Generator.generate(computed_config)).to eq(computed_output)
31
68
  end
32
69
  end
data/spec/monthly_spec.rb CHANGED
@@ -23,14 +23,14 @@ config = <<~YAML
23
23
  YAML
24
24
 
25
25
  output = <<~JOURNAL
26
- ~ monthly from 2023-03-01 * Mortgage, Food
27
- Expenses:Mortgage £2,000.55; Mortgage
28
- Expenses:Food £100.00 ; Food
29
- Assets:Bank
26
+ ~ monthly from 2023-03-01 * Mortgage, Food
27
+ Expenses:Mortgage £2,000.55; Mortgage
28
+ Expenses:Food £100.00 ; Food
29
+ Assets:Bank
30
30
 
31
- ~ monthly from 2023-03-01 * Savings
32
- Assets:Bank £-1,000.00; Savings
33
- Assets:Savings
31
+ ~ monthly from 2023-03-01 * Savings
32
+ Assets:Bank £-1,000.00; Savings
33
+ Assets:Savings
34
34
 
35
35
  JOURNAL
36
36
 
@@ -0,0 +1,86 @@
1
+ require_relative '../lib/hledger_forecast'
2
+
3
+ config = <<~YAML
4
+ monthly:
5
+ - account: "Assets:Bank"
6
+ from: "2023-03-01"
7
+ transactions:
8
+ - amount: 2000.55
9
+ category: "Expenses:Mortgage"
10
+ description: Mortgage
11
+ to: "=24"
12
+ - amount: 100
13
+ category: "Expenses:Food"
14
+ description: Food
15
+ - account: "Assets:Savings"
16
+ from: "2023-03-01"
17
+ transactions:
18
+ - amount: -1000
19
+ category: "Assets:Bank"
20
+ description: Savings
21
+
22
+ custom:
23
+ - frequency: "every 2 weeks"
24
+ from: "2023-05-01"
25
+ account: "[Assets:Bank]"
26
+ roll-up: 26
27
+ transactions:
28
+ - amount: 80
29
+ category: "[Expenses:Personal Care]"
30
+ description: Hair and beauty
31
+ - frequency: "every 5 days"
32
+ from: "2023-05-01"
33
+ account: "[Assets:Checking]"
34
+ roll-up: 73
35
+ transactions:
36
+ - amount: 50
37
+ category: "[Expenses:Groceries]"
38
+ description: Gotta feed that stomach
39
+
40
+ settings:
41
+ currency: GBP
42
+ YAML
43
+
44
+ RSpec.describe HledgerForecast::Summarizer do
45
+ let(:summarizer) { described_class.new }
46
+
47
+ describe '#generate with roll_up' do
48
+ let(:forecast) { YAML.safe_load(config) }
49
+ let(:cli_options) { { roll_up: 'monthly' } }
50
+
51
+ before do
52
+ summarizer.summarize(config, cli_options)
53
+ end
54
+
55
+ it 'generates the correct output' do
56
+ output = summarizer.send(:generate, forecast)
57
+
58
+ expect(output.first).to include(:account, :from, :to, :type, :frequency)
59
+ expect(output.first[:amount]).to eq(2000.55)
60
+ expect(output.last[:rolled_up_amount]).to eq(304) # ((50 * 73) / 12)
61
+ expect(output.length).to eq(5)
62
+ end
63
+
64
+ it 'transaction TO date take precedence over block TO date' do
65
+ output = summarizer.send(:generate, forecast)
66
+
67
+ expect(output.first[:to]).to eq(Date.parse("2025-02-28"))
68
+ end
69
+ end
70
+
71
+ describe '#generate' do
72
+ let(:forecast) { YAML.safe_load(config) }
73
+ let(:cli_options) { nil }
74
+
75
+ before do
76
+ summarizer.summarize(config, cli_options)
77
+ end
78
+
79
+ it 'generates the correct output' do
80
+ output = summarizer.send(:generate, forecast)
81
+
82
+ # expect(output.first).to include(:account, :from, :to, :type, :frequency)
83
+ expect(output.length).to eq(5)
84
+ end
85
+ end
86
+ end
data/spec/track_spec.rb CHANGED
@@ -42,70 +42,13 @@ base_output = <<~JOURNAL
42
42
  JOURNAL
43
43
 
44
44
  RSpec.describe 'Tracking transactions -' do
45
- it 'Determines which transactions should be tracked' do
46
- generated = HledgerForecast::Generator
47
- generated.generate(base_config)
48
- tracked = generated.tracked
49
-
50
- expect(tracked[0]['transaction']).to eq(
51
- { "amount" => "£3,000.00", "category" => "Expenses:Tax", "description" => "Tax owed",
52
- "inverse_amount" => "£-3,000.00", "track" => true }
53
- )
54
- expect(tracked[0]['account']).to eq("Assets:Bank")
55
-
56
- expect(tracked[1]['transaction']).to eq(
57
- { "amount" => "£-1,500.00", "category" => "Income:Salary", "description" => "Salary", "to" => "2023-08-01",
58
- "inverse_amount" => "£1,500.00", "track" => true }
59
- )
60
- expect(tracked[1]['account']).to eq("Assets:Bank")
61
- end
62
-
63
- it 'marks a transaction as NOT FOUND if it doesnt exist' do
64
- generated = HledgerForecast::Generator
65
- generated.tracked = {} # Clear tracked transactions
66
- generated.generate(base_config)
67
- transactions_to_track = generated.tracked
68
-
69
- track = HledgerForecast::Tracker.track(transactions_to_track, 'spec/stubs/transactions_not_found.journal')
70
-
71
- expect(track[0]['found']).to eq(false)
72
- expect(track[1]['found']).to eq(false)
73
- end
74
-
75
- it 'marks a transaction as FOUND if it exists' do
76
- generated = HledgerForecast::Generator
77
- generated.tracked = {} # Clear tracked transactions
78
- generated.generate(base_config)
79
- transactions_to_track = generated.tracked
80
-
81
- track = HledgerForecast::Tracker.track(transactions_to_track, 'spec/stubs/transactions_found.journal')
82
-
83
- expect(track[0]['found']).to eq(true)
84
- expect(track[1]['found']).to eq(true)
85
- end
86
-
87
- it 'marks a transaction as FOUND if it exists, even if the category/amount are inversed' do
88
- generated = HledgerForecast::Generator
89
- generated.tracked = {} # Clear tracked transactions
90
- generated.generate(base_config)
91
- transactions_to_track = generated.tracked
92
-
93
- track = HledgerForecast::Tracker.track(transactions_to_track, 'spec/stubs/transactions_found_inverse.journal')
94
-
95
- expect(track[0]['found']).to eq(true)
96
- end
97
-
98
45
  it 'writes a NON-FOUND entry into a journal' do
99
46
  options = {}
100
47
  options[:transaction_file] = 'spec/stubs/transactions_not_found.journal'
101
48
 
102
- generated = HledgerForecast::Generator
103
- generated.tracked = {} # Clear tracked transactions
104
-
105
- generated_journal = generated.generate(base_config, options)
49
+ generated_journal = HledgerForecast::Generator.generate(base_config, options)
106
50
 
107
- expected_output = base_output
108
- expect(generated_journal).to eq(expected_output)
51
+ expect(generated_journal).to eq(base_output)
109
52
  end
110
53
 
111
54
  it 'writes a NON-FOUND entry for dates that are close to the current period' do
@@ -147,12 +90,10 @@ RSpec.describe 'Tracking transactions -' do
147
90
  options = {}
148
91
  options[:transaction_file] = temp_file.path
149
92
 
150
- generated = HledgerForecast::Generator
151
- generated.tracked = {} # Clear tracked transactions
152
-
153
- generated_journal = generated.generate(forecast_config, options)
93
+ generated_journal = HledgerForecast::Generator.generate(forecast_config, options)
154
94
 
155
95
  expected_output = <<~JOURNAL
96
+
156
97
  ~ #{next_month} * [TRACKED] New kitchen
157
98
  Expenses:House £5,000.00; New kitchen
158
99
  Assets:Bank
@@ -180,10 +121,7 @@ RSpec.describe 'Tracking transactions -' do
180
121
  options = {}
181
122
  options[:transaction_file] = 'spec/stubs/transactions_not_found.journal'
182
123
 
183
- generated = HledgerForecast::Generator
184
- generated.tracked = {} # Clear tracked transactions
185
-
186
- generated_journal = generated.generate(forecast_config, options)
124
+ generated_journal = HledgerForecast::Generator.generate(forecast_config, options)
187
125
 
188
126
  output = <<~JOURNAL
189
127
  ~ monthly from #{next_month} * Food expenses