hledger-forecast 0.4.0 → 1.1.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.
@@ -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