1#[macro_use] mod imports; use imports::*;
3
4x!{budget_comparison}
10x!{budgeting}
11x!{budget}
12x!{errors}
13x!{time_period}
14
15#[cfg(test)]
16mod budgeting_tests {
17 use super::*;
18
19 fn mock_amount(val: i64) -> MonetaryAmount {
20 MonetaryAmount::from(val)
22 }
23
24 #[test]
25 fn test_budget_builder_defaults() {
26 let budget = BudgetBuilder::<MockTransactionCategory>::default()
27 .build() .expect("Should build with all default fields");
29
30 assert_eq!(*budget.default_monthly_budget(), mock_amount(0));
32 assert_eq!(*budget.time_period(), BudgetTimePeriod::Monthly);
33 assert!(budget.monthly_category_budgets().is_empty());
34 }
35
36 #[test]
37 fn test_budget_builder_with_fields() {
38 let category_food = MockTransactionCategory::FoodServices;
39 let category_rent = MockTransactionCategory::Housing;
40
41 let budget = BudgetBuilder::default()
42 .monthly_category_budgets({
43 let mut map = HashMap::new();
44 map.insert(category_food.clone(), mock_amount(300));
45 map.insert(category_rent.clone(), mock_amount(800));
46 map
47 })
48 .default_monthly_budget(mock_amount(50))
49 .time_period(BudgetTimePeriod::Quarterly)
50 .build()
51 .unwrap();
52
53 assert_eq!(budget.monthly_amount_for_category(&category_food), mock_amount(300));
54 assert_eq!(budget.monthly_amount_for_category(&category_rent), mock_amount(800));
55 assert_eq!(*budget.default_monthly_budget(), mock_amount(50));
56 assert_eq!(*budget.time_period(), BudgetTimePeriod::Quarterly);
57 }
58
59 #[test]
60 fn test_set_and_remove_category_budget() {
61 let cat_util = MockTransactionCategory::UtilitiesAndServices;
62
63 let mut budget = BudgetBuilder::<MockTransactionCategory>::default()
65 .default_monthly_budget(mock_amount(100))
66 .build()
67 .unwrap();
68
69 assert_eq!(budget.monthly_amount_for_category(&cat_util), mock_amount(100));
71
72 budget.set_category_budget(cat_util.clone(), mock_amount(500));
74 assert_eq!(budget.monthly_amount_for_category(&cat_util), mock_amount(500));
75
76 budget.remove_category_budget(&cat_util).unwrap();
78 assert_eq!(budget.monthly_amount_for_category(&cat_util), mock_amount(100));
79 }
80
81 #[test]
82 fn test_compare_actual_to_budget_empty_account() {
83
84 let account = Account::empty();
86
87 let category_map: CategoryMap<MockTransactionCategory> = CategoryMap::new();
88
89 let budget = BudgetBuilder::default()
90 .default_monthly_budget(MonetaryAmount::from(100.0))
91 .build()
92 .unwrap();
93
94 let comps = account.compare_actual_to_budget_monthly(&budget, &category_map);
96
97 assert_eq!(comps.len(), 0);
98 }
99
100 #[traced_test]
101 fn test_compare_actual_to_budget_mock_account() {
102
103 let category_food = MockTransactionCategory::FoodServices;
104 let category_rent = MockTransactionCategory::Housing;
105
106 let root = std::env::var("CARGO_MANIFEST_DIR").unwrap();
109 let config_path = PathBuf::from(&root).join("..").join("config.toml");
110
111 let program_config = load_program_config_from_path(&config_path)
112 .expect("Could not load config in test");
113
114 let account = Account::new(TrackedYear::Twenty23, AccountKind::Credit, &program_config)
116 .expect("expected to create our account");
117
118 let category_map: CategoryMap<MockTransactionCategory> = CategoryMap::new();
119
120 let budget = BudgetBuilder::default()
121 .monthly_category_budgets({
122 let mut map = HashMap::new();
123 map.insert(category_food.clone(), mock_amount(300));
124 map.insert(category_rent.clone(), mock_amount(800));
125 map
126 })
127 .default_monthly_budget(mock_amount(50))
128 .time_period(BudgetTimePeriod::Quarterly)
129 .build()
130 .unwrap();
131
132 let comps = account.compare_actual_to_budget_monthly(&budget, &category_map);
134
135 assert!(comps.len() > 0);
136 }
137}