1 use std::cell::{Cell, RefCell}; 2 use std::collections::VecDeque; 3 4 use jni::sys::{jarray, jbyteArray, jint, jintArray, jshort, jshortArray, jsize}; 5 use uwb_uci_rust::error::UwbErr; 6 use uwb_uci_rust::uci::Dispatcher; 7 8 use crate::mock_dispatcher::MockDispatcher; 9 use crate::Context; 10 11 #[cfg(test)] 12 pub struct MockContext { 13 dispatcher: Cell<MockDispatcher>, 14 expected_calls: RefCell<VecDeque<ExpectedCall>>, 15 } 16 17 #[cfg(test)] 18 impl MockContext { new(dispatcher: MockDispatcher) -> Self19 pub fn new(dispatcher: MockDispatcher) -> Self { 20 Self { dispatcher: Cell::new(dispatcher), expected_calls: Default::default() } 21 } 22 get_mock_dispatcher(&mut self) -> &mut MockDispatcher23 pub fn get_mock_dispatcher(&mut self) -> &mut MockDispatcher { 24 self.dispatcher.get_mut() 25 } 26 expect_convert_byte_array( &mut self, expected_array: jbyteArray, out: Result<Vec<u8>, jni::errors::Error>, )27 pub fn expect_convert_byte_array( 28 &mut self, 29 expected_array: jbyteArray, 30 out: Result<Vec<u8>, jni::errors::Error>, 31 ) { 32 self.expected_calls 33 .borrow_mut() 34 .push_back(ExpectedCall::ConvertByteArray { expected_array, out }); 35 } 36 expect_get_array_length( &mut self, expected_array: jarray, out: Result<jsize, jni::errors::Error>, )37 pub fn expect_get_array_length( 38 &mut self, 39 expected_array: jarray, 40 out: Result<jsize, jni::errors::Error>, 41 ) { 42 self.expected_calls 43 .borrow_mut() 44 .push_back(ExpectedCall::GetArrayLength { expected_array, out }); 45 } 46 expect_get_short_array_region( &mut self, expected_array: jshortArray, expected_start: jsize, out: Result<Box<[jshort]>, jni::errors::Error>, )47 pub fn expect_get_short_array_region( 48 &mut self, 49 expected_array: jshortArray, 50 expected_start: jsize, 51 out: Result<Box<[jshort]>, jni::errors::Error>, 52 ) { 53 self.expected_calls.borrow_mut().push_back(ExpectedCall::GetShortArrayRegion { 54 expected_array, 55 expected_start, 56 out, 57 }); 58 } 59 expect_get_int_array_region( &mut self, expected_array: jintArray, expected_start: jsize, out: Result<Box<[jint]>, jni::errors::Error>, )60 pub fn expect_get_int_array_region( 61 &mut self, 62 expected_array: jintArray, 63 expected_start: jsize, 64 out: Result<Box<[jint]>, jni::errors::Error>, 65 ) { 66 self.expected_calls.borrow_mut().push_back(ExpectedCall::GetIntArrayRegion { 67 expected_array, 68 expected_start, 69 out, 70 }); 71 } 72 } 73 74 #[cfg(test)] 75 impl<'a> Context<'a> for MockContext { convert_byte_array(&self, array: jbyteArray) -> Result<Vec<u8>, jni::errors::Error>76 fn convert_byte_array(&self, array: jbyteArray) -> Result<Vec<u8>, jni::errors::Error> { 77 let mut expected_calls = self.expected_calls.borrow_mut(); 78 match expected_calls.pop_front() { 79 Some(ExpectedCall::ConvertByteArray { expected_array, out }) 80 if array == expected_array => 81 { 82 out 83 } 84 Some(call) => { 85 expected_calls.push_front(call); 86 Err(jni::errors::Error::JniCall(jni::errors::JniError::Unknown)) 87 } 88 None => Err(jni::errors::Error::JniCall(jni::errors::JniError::Unknown)), 89 } 90 } 91 get_array_length(&self, array: jarray) -> Result<jsize, jni::errors::Error>92 fn get_array_length(&self, array: jarray) -> Result<jsize, jni::errors::Error> { 93 let mut expected_calls = self.expected_calls.borrow_mut(); 94 match expected_calls.pop_front() { 95 Some(ExpectedCall::GetArrayLength { expected_array, out }) 96 if array == expected_array => 97 { 98 out 99 } 100 Some(call) => { 101 expected_calls.push_front(call); 102 Err(jni::errors::Error::JniCall(jni::errors::JniError::Unknown)) 103 } 104 None => Err(jni::errors::Error::JniCall(jni::errors::JniError::Unknown)), 105 } 106 } 107 get_short_array_region( &self, array: jshortArray, start: jsize, buf: &mut [jshort], ) -> Result<(), jni::errors::Error>108 fn get_short_array_region( 109 &self, 110 array: jshortArray, 111 start: jsize, 112 buf: &mut [jshort], 113 ) -> Result<(), jni::errors::Error> { 114 let mut expected_calls = self.expected_calls.borrow_mut(); 115 match expected_calls.pop_front() { 116 Some(ExpectedCall::GetShortArrayRegion { expected_array, expected_start, out }) 117 if array == expected_array && start == expected_start => 118 { 119 match out { 120 Ok(expected_buf) => { 121 buf.clone_from_slice(&expected_buf); 122 Ok(()) 123 } 124 Err(err) => Err(err), 125 } 126 } 127 Some(call) => { 128 expected_calls.push_front(call); 129 Err(jni::errors::Error::JniCall(jni::errors::JniError::Unknown)) 130 } 131 None => Err(jni::errors::Error::JniCall(jni::errors::JniError::Unknown)), 132 } 133 } 134 get_int_array_region( &self, array: jintArray, start: jsize, buf: &mut [jint], ) -> Result<(), jni::errors::Error>135 fn get_int_array_region( 136 &self, 137 array: jintArray, 138 start: jsize, 139 buf: &mut [jint], 140 ) -> Result<(), jni::errors::Error> { 141 let mut expected_calls = self.expected_calls.borrow_mut(); 142 match expected_calls.pop_front() { 143 Some(ExpectedCall::GetIntArrayRegion { expected_array, expected_start, out }) 144 if array == expected_array && start == expected_start => 145 { 146 match out { 147 Ok(expected_buf) => { 148 buf.clone_from_slice(&expected_buf); 149 Ok(()) 150 } 151 Err(err) => Err(err), 152 } 153 } 154 Some(call) => { 155 expected_calls.push_front(call); 156 Err(jni::errors::Error::JniCall(jni::errors::JniError::Unknown)) 157 } 158 None => Err(jni::errors::Error::JniCall(jni::errors::JniError::Unknown)), 159 } 160 } 161 get_dispatcher(&self) -> Result<&'a mut dyn Dispatcher, UwbErr>162 fn get_dispatcher(&self) -> Result<&'a mut dyn Dispatcher, UwbErr> { 163 unsafe { Ok(&mut *(self.dispatcher.as_ptr())) } 164 } 165 } 166 167 #[cfg(test)] 168 enum ExpectedCall { 169 ConvertByteArray { 170 expected_array: jbyteArray, 171 out: Result<Vec<u8>, jni::errors::Error>, 172 }, 173 GetArrayLength { 174 expected_array: jarray, 175 out: Result<jsize, jni::errors::Error>, 176 }, 177 GetShortArrayRegion { 178 expected_array: jshortArray, 179 expected_start: jsize, 180 out: Result<Box<[jshort]>, jni::errors::Error>, 181 }, 182 GetIntArrayRegion { 183 expected_array: jintArray, 184 expected_start: jsize, 185 out: Result<Box<[jint]>, jni::errors::Error>, 186 }, 187 } 188