Skip to main content

rocketmq_remoting/protocol/header/
get_min_offset_response_header.rs

1// Copyright 2023 The RocketMQ Rust Authors
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//     http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15use rocketmq_macros::RequestHeaderCodecV2;
16use serde::Deserialize;
17use serde::Serialize;
18
19#[derive(Debug, Clone, Deserialize, Serialize, Default, RequestHeaderCodecV2)]
20pub struct GetMinOffsetResponseHeader {
21    pub offset: i64,
22}
23
24#[cfg(test)]
25mod tests {
26    use std::collections::HashMap;
27
28    use cheetah_string::CheetahString;
29    use serde_json;
30
31    use super::*;
32    use crate::protocol::command_custom_header::FromMap;
33
34    // Basic Structure Tests
35    #[test]
36    fn get_min_offset_response_header_new_with_value() {
37        let header = GetMinOffsetResponseHeader { offset: 100 };
38        assert_eq!(header.offset, 100);
39    }
40
41    #[test]
42    fn get_min_offset_response_header_default() {
43        let header = GetMinOffsetResponseHeader::default();
44        assert_eq!(header.offset, 0);
45    }
46
47    #[test]
48    fn get_min_offset_response_header_clone() {
49        let header1 = GetMinOffsetResponseHeader { offset: 12345 };
50        let header2 = header1.clone();
51        assert_eq!(header1.offset, header2.offset);
52        assert_eq!(header2.offset, 12345);
53    }
54
55    #[test]
56    fn get_min_offset_response_header_debug_format() {
57        let header = GetMinOffsetResponseHeader { offset: 1234567890 };
58        assert_eq!(
59            format!("{:?}", header),
60            "GetMinOffsetResponseHeader { offset: 1234567890 }"
61        );
62    }
63
64    // Serialization & Deserialization Tests
65    #[test]
66    fn get_min_offset_response_header_serialization() {
67        let header = GetMinOffsetResponseHeader { offset: 12345 };
68        let json = serde_json::to_string(&header).unwrap();
69        assert_eq!(json, r#"{"offset":12345}"#);
70    }
71
72    #[test]
73    fn get_min_offset_response_header_deserialization() {
74        let json = r#"{"offset":12345}"#;
75        let header: GetMinOffsetResponseHeader = serde_json::from_str(json).unwrap();
76        assert_eq!(header.offset, 12345);
77    }
78
79    #[test]
80    fn get_min_offset_response_header_round_trip() {
81        let original = GetMinOffsetResponseHeader { offset: 999999 };
82        let json = serde_json::to_string(&original).unwrap();
83        let deserialized: GetMinOffsetResponseHeader = serde_json::from_str(&json).unwrap();
84        assert_eq!(original.offset, deserialized.offset);
85    }
86
87    #[test]
88    fn get_min_offset_response_header_deserialization_with_missing_fields() {
89        let json = r#"{}"#;
90        let result: Result<GetMinOffsetResponseHeader, _> = serde_json::from_str(json);
91        assert!(result.is_err()); // field is required by serde
92    }
93
94    #[test]
95    fn get_min_offset_response_header_deserialization_with_extra_fields() {
96        let json = r#"{"offset":12345,"extraField":"ignored"}"#;
97        let header: GetMinOffsetResponseHeader = serde_json::from_str(json).unwrap();
98        assert_eq!(header.offset, 12345);
99    }
100
101    // Offset Value Tests
102    #[test]
103    fn get_min_offset_response_header_zero_offset() {
104        let header = GetMinOffsetResponseHeader { offset: 0 };
105        assert_eq!(header.offset, 0);
106    }
107
108    #[test]
109    fn get_min_offset_response_header_positive_offset_values() {
110        let test_values = vec![1, 100, 1000, 10000, 1000000];
111        for value in test_values {
112            let header = GetMinOffsetResponseHeader { offset: value };
113            assert_eq!(header.offset, value);
114        }
115    }
116
117    #[test]
118    fn get_min_offset_response_header_negative_offset() {
119        let header = GetMinOffsetResponseHeader { offset: -1 };
120        assert_eq!(header.offset, -1);
121    }
122
123    #[test]
124    fn get_min_offset_response_header_max_offset() {
125        let header = GetMinOffsetResponseHeader { offset: i64::MAX };
126        assert_eq!(header.offset, i64::MAX);
127    }
128
129    #[test]
130    fn get_min_offset_response_header_min_offset() {
131        let header = GetMinOffsetResponseHeader { offset: i64::MIN };
132        assert_eq!(header.offset, i64::MIN);
133    }
134
135    #[test]
136    fn get_min_offset_response_header_offset_preservation_after_serialization() {
137        let test_values = vec![0, -1, 100, i64::MAX, i64::MIN];
138        for value in test_values {
139            let header = GetMinOffsetResponseHeader { offset: value };
140            let json = serde_json::to_string(&header).unwrap();
141            let deserialized: GetMinOffsetResponseHeader = serde_json::from_str(&json).unwrap();
142            assert_eq!(header.offset, deserialized.offset);
143        }
144    }
145
146    // Integration with RequestHeaderCodecV2 Macro Tests
147    #[test]
148    fn get_min_offset_response_header_from_map() {
149        let mut map = HashMap::new();
150        map.insert(CheetahString::from("offset"), CheetahString::from("12345"));
151        let header = <GetMinOffsetResponseHeader as FromMap>::from(&map).unwrap();
152        assert_eq!(header.offset, 12345);
153    }
154
155    #[test]
156    fn get_min_offset_response_header_from_map_with_negative_offset() {
157        let mut map = HashMap::new();
158        map.insert(CheetahString::from("offset"), CheetahString::from("-1"));
159        let header = <GetMinOffsetResponseHeader as FromMap>::from(&map).unwrap();
160        assert_eq!(header.offset, -1);
161    }
162
163    #[test]
164    fn get_min_offset_response_header_from_map_with_max_offset() {
165        let mut map = HashMap::new();
166        map.insert(CheetahString::from("offset"), CheetahString::from(i64::MAX.to_string()));
167        let header = <GetMinOffsetResponseHeader as FromMap>::from(&map).unwrap();
168        assert_eq!(header.offset, i64::MAX);
169    }
170
171    #[test]
172    fn get_min_offset_response_header_from_empty_map() {
173        let map = HashMap::new();
174        let header = <GetMinOffsetResponseHeader as FromMap>::from(&map).unwrap();
175        assert_eq!(header.offset, 0); // should use default
176    }
177
178    // Edge Cases & Error Handling Tests
179    #[test]
180    fn get_min_offset_response_header_deserialization_malformed_json() {
181        let json = r#"{"offset":"not_a_number"}"#;
182        let result: Result<GetMinOffsetResponseHeader, _> = serde_json::from_str(json);
183        assert!(result.is_err());
184    }
185
186    #[test]
187    fn get_min_offset_response_header_deserialization_invalid_json() {
188        let json = r#"{"offset":}"#;
189        let result: Result<GetMinOffsetResponseHeader, _> = serde_json::from_str(json);
190        assert!(result.is_err());
191    }
192
193    #[test]
194    fn get_min_offset_response_header_from_map_invalid_offset() {
195        let mut map = HashMap::new();
196        map.insert(CheetahString::from("offset"), CheetahString::from("not_a_number"));
197        let result = <GetMinOffsetResponseHeader as FromMap>::from(&map);
198        // The macro-generated FromMap uses parse() which defaults to 0 on parse failure for non-required
199        // fields
200        assert_eq!(result.unwrap().offset, 0);
201    }
202
203    #[test]
204    fn get_min_offset_response_header_struct_size() {
205        use std::mem;
206        assert_eq!(mem::size_of::<GetMinOffsetResponseHeader>(), 8);
207    }
208}