whisky_common/tx_tester/
outputs.rs

1use crate::{Datum, Value};
2
3use super::TxTester;
4
5impl TxTester {
6    /// ## Filtering methods for testing outputs
7    ///
8    /// Not apply filter to outputs
9    pub fn all_outputs(&mut self) -> &mut Self {
10        self.outputs_evaluating = self.tx_body.outputs.clone();
11        self
12    }
13
14    /// ## Filtering methods for testing outputs
15    ///
16    /// Filter outputs by address
17    pub fn outputs_at(&mut self, address: &str) -> &mut Self {
18        self.outputs_evaluating = self
19            .tx_body
20            .outputs
21            .iter()
22            .filter(|output| output.address == address)
23            .cloned()
24            .collect();
25        self
26    }
27
28    /// ## Filtering methods for testing outputs
29    ///
30    /// Filter outputs by unit
31    pub fn outputs_with(&mut self, unit: &str) -> &mut Self {
32        self.outputs_evaluating = self
33            .tx_body
34            .outputs
35            .iter()
36            .filter(|output| {
37                let output_value = Value::from_asset_vec(&output.amount);
38                let quantity = output_value.get(unit);
39                quantity > 0
40            })
41            .cloned()
42            .collect();
43        self
44    }
45
46    /// ## Filtering methods for testing outputs
47    ///
48    /// Filter outputs by policy ID
49    pub fn outputs_with_policy(&mut self, policy_id: &str) -> &mut Self {
50        self.outputs_evaluating = self
51            .tx_body
52            .outputs
53            .iter()
54            .filter(|output| {
55                let output_value = Value::from_asset_vec(&output.amount);
56                let assets = output_value.get_policy_assets(policy_id);
57                assets.len() > 0
58            })
59            .cloned()
60            .collect();
61        self
62    }
63
64    /// ## Filtering methods for testing outputs
65    ///
66    /// Filter outputs by address and policy ID
67    pub fn outputs_at_with_policy(&mut self, address: &str, policy_id: &str) -> &mut Self {
68        self.outputs_evaluating = self
69            .tx_body
70            .outputs
71            .iter()
72            .filter(|output| {
73                let output_value = Value::from_asset_vec(&output.amount);
74                let assets = output_value.get_policy_assets(policy_id);
75                output.address == address && assets.len() > 0
76            })
77            .cloned()
78            .collect();
79        self
80    }
81
82    /// ## Filtering methods for testing outputs
83    ///
84    /// Filter outputs by address and unit
85    pub fn outputs_at_with(&mut self, address: &str, unit: &str) -> &mut Self {
86        self.outputs_evaluating = self
87            .tx_body
88            .outputs
89            .iter()
90            .filter(|output| {
91                let output_value = Value::from_asset_vec(&output.amount);
92                let quantity = output_value.get(unit);
93                output.address == address && quantity > 0
94            })
95            .cloned()
96            .collect();
97        self
98    }
99
100    /// ## Testing methods for outputs
101    ///
102    /// *Reminder - It must be called after filtering methods for outputs*
103    ///
104    /// Check if outputs contain the expected value.
105    pub fn outputs_value(&mut self, expected_value: Value) -> &mut Self {
106        let mut value = Value::new();
107        self.outputs_evaluating.iter().for_each(|output| {
108            value.add_assets(&output.amount);
109        });
110        let is_value_correct = value.eq(&expected_value);
111        if !is_value_correct {
112            self.add_trace(
113                "outputs_value",
114                &format!(
115                    "tx outputs {:?} have value {:?}, expected {:?}",
116                    self.outputs_evaluating, value, expected_value
117                ),
118            );
119        }
120        self
121    }
122
123    /// ## Testing methods for outputs
124    ///
125    /// *Reminder - It must be called after filtering methods for outputs*
126    ///
127    /// Check if outputs contain a specific inline datum.
128    pub fn outputs_inline_datum_exist(&mut self, datum_cbor: &str) -> &mut Self {
129        let outputs_with_inline_datum: Vec<_> = self
130            .outputs_evaluating
131            .iter()
132            .filter(|output| {
133                if let Some(Datum::Inline(datum)) = &output.datum {
134                    *datum == *datum_cbor
135                } else {
136                    false
137                }
138            })
139            .cloned()
140            .collect();
141
142        if outputs_with_inline_datum.is_empty() {
143            self.add_trace(
144                "outputs_inline_datum_exist",
145                &format!("No outputs with inline datum matching: {}", datum_cbor),
146            );
147        }
148        self
149    }
150}