1pub mod currency;
2pub mod amount;
3pub mod errors;
4pub mod traits;
5pub mod ecb;
6pub mod tax;
7
8#[macro_use]
9#[cfg(test)]
10extern crate more_asserts;
11
12#[cfg(test)]
13mod tests {
14 use crate::currency::Currency;
15 use crate::amount::Amount;
16 use crate::traits::ExchangeRate;
17 use crate::errors::Error;
18 use crate::ecb::EuropeanCentralBank;
19 use crate::tax;
20
21 #[test]
22 fn test_currency_decimals() {
23 assert_eq!(0, Currency::CVE.decimals());
24 assert_eq!(2, Currency::EUR.decimals());
25 assert_eq!(3, Currency::BHD.decimals());
26 }
27
28 #[test]
29 fn test_currency_abbreviation() {
30 assert!("EUR" == Currency::EUR.abbreviation());
31 assert!("USD" == Currency::USD.abbreviation());
32 }
33
34 #[test]
35 fn test_amount_major_minor() {
36 let amount = Amount::new(525, Currency::CVE);
37 assert_eq!(525, amount.major());
38 assert!(amount.minor().is_none());
39
40 let amount = Amount::new(525, Currency::EUR);
41 assert_eq!(5, amount.major());
42 assert!(amount.minor().is_some());
43 assert_eq!(25, amount.minor().unwrap());
44
45 let amount = Amount::new(525, Currency::BHD);
46 assert_eq!(0, amount.major());
47 assert!(amount.minor().is_some());
48 assert_eq!(525, amount.minor().unwrap());
49 }
50
51 #[test]
52 fn test_amount_add_sub() {
53 let amount1 = Amount::new(100, Currency::EUR);
54 let amount2 = Amount::new(150, Currency::EUR);
55 let amount3 = Amount::new(200, Currency::USD);
56 let expect = Amount::new(250, Currency::EUR);
57
58 let res = amount1 + amount2;
59 assert!(res.is_ok());
60 let res = res.unwrap();
61 assert_eq!(expect, res);
62 let res = res - amount2;
63 assert!(res.is_ok());
64 assert_eq!(amount1, res.unwrap());
65
66 let res = amount1 + amount3;
67 assert!(res.is_err());
68 }
69
70 #[derive(Clone, Copy)]
71 struct ExchangeRateMock;
72
73 #[derive(Clone, Copy)]
74 struct ExchangeRateErrorMock;
75
76 impl ExchangeRate for ExchangeRateMock {
77 fn exchange_rate(self, _from: Currency, _to: Currency) -> Result<f64, Error>
78 {
79 Ok(2.0f64)
80 }
81 }
82
83 impl ExchangeRate for ExchangeRateErrorMock {
84 fn exchange_rate(self, _from: Currency, _to: Currency) -> Result<f64, Error>
85 {
86 Err(Error::CouldNotGetExchangeRate)
87 }
88 }
89
90 #[test]
91 fn test_amount_exchange() {
92 let exchange_mock = ExchangeRateMock;
93 let exchange_error_mock = ExchangeRateErrorMock;
94 let amount_eur = Amount::new(100, Currency::EUR);
95 let amount_usd = amount_eur.exchange(Currency::USD, &exchange_mock);
96 assert!(amount_usd.is_ok());
97 assert_eq!(amount_usd.unwrap().amount, 200);
98 let amount_usd = amount_eur.exchange(Currency::USD, &exchange_error_mock);
99 assert!(amount_usd.is_err());
100 }
101
102 #[test]
103 fn test_ecb_exchange_rate() {
104 let ecb = EuropeanCentralBank;
105 let rate = ecb.exchange_rate(Currency::EUR, Currency::JPY);
106 assert!(rate.is_ok());
107 assert_gt!(rate.unwrap(), 1.0);
108 }
109
110 #[test]
111 fn test_tax_add() {
112 let net_amount = Amount::new(500, Currency::EUR);
113 let gross_amount = tax::add_tax(net_amount, 0.16);
114 assert_eq!(580, gross_amount.amount);
115 let tax_amount = tax::get_tax(net_amount, 0.16);
116 assert_eq!(80, tax_amount.amount);
117 let net_amount = tax::remove_tax(gross_amount, 0.16);
118 assert_eq!(500, net_amount.amount);
119 }
120}