1#![feature(inherent_associated_types)]
23#![feature(type_alias_impl_trait)]
24#![feature(unboxed_closures)]
25
26pub mod cache;
27pub mod cli;
28pub mod core;
29pub mod json;
30pub mod log;
31pub mod maths;
32pub mod net;
33pub mod queue;
34pub mod search;
35pub mod strings;
36pub mod threading;
37
38#[cfg(test)]
39mod tests {
40 use super::*;
41 use crate::cache::RUMCache;
42 use crate::search::rumtk_search::*;
43 use crate::strings::{RUMArrayConversions, RUMString, RUMStringConversions, StringUtils};
44 use compact_str::{format_compact, CompactString};
45 use serde::Deserialize;
46 use std::future::IntoFuture;
47 use std::sync::Arc;
48 use tokio::sync::RwLock;
49
50 #[test]
51 fn test_escaping_control() {
52 let input = "\r\n\'\"";
53 let expected = "\\r\\n\\'\\\"";
54 let result = strings::escape(&input);
55 println!(
56 "Input: {} Expected: {} Got: {}",
57 input,
58 expected,
59 result.as_str()
60 );
61 assert_eq!(expected, result, "Incorrect string escaping!");
62 println!("Passed!")
63 }
64
65 #[test]
66 fn test_escaping_unicode() {
67 let input = "❤";
68 let expected = "\\u2764";
69 let result = strings::escape(&input);
70 println!(
71 "Input: {} Expected: {} Got: {}",
72 input,
73 expected,
74 result.as_str()
75 );
76 assert_eq!(expected, result, "Incorrect string escaping!");
77 println!("Passed!")
78 }
79
80 #[test]
81 fn test_unescaping_unicode() {
82 let input = "❤";
83 let escaped = strings::escape(&input);
84 let expected = "❤";
85 let result = RUMString::from_utf8(strings::unescape(&escaped.as_str()).unwrap()).unwrap();
86 println!(
87 "Input: {} Expected: {} Got: {}",
88 input,
89 expected,
90 result.as_str()
91 );
92 assert_eq!(expected, result.as_str(), "Incorrect string unescaping!");
93 println!("Passed!")
94 }
95
96 #[test]
97 fn test_unescaping_string() {
98 let input = "I \\u2764 my wife!";
99 let expected = "I ❤ my wife!";
100 let result = strings::unescape_string(&input).unwrap();
101 println!(
102 "Input: {} Expected: {} Got: {}",
103 input,
104 expected,
105 result.as_str()
106 );
107 assert_eq!(expected, result.as_str(), "Incorrect string unescaping!");
108 println!("Passed!")
109 }
110
111 #[test]
112 fn test_unique_string() {
113 let input = "I❤mywife!";
114 assert!(input.is_unique(), "String was not detected as unique.");
115 }
116
117 #[test]
118 fn test_non_unique_string() {
119 let input = "I❤❤mywife!";
120 assert!(!input.is_unique(), "String was detected as unique.");
121 }
122
123 #[test]
124 fn test_escaping_string() {
125 let input = "I ❤ my wife!";
126 let expected = "I \\u2764 my wife!";
127 let result = strings::escape(&input);
128 println!(
129 "Input: {} Expected: {} Got: {}",
130 input,
131 expected,
132 result.as_str()
133 );
134 assert_eq!(expected, result.as_str(), "Incorrect string escaping!");
135 println!("Passed!")
136 }
137
138 #[test]
139 fn test_autodecode_utf8() {
140 let input = "I ❤ my wife!";
141 let result = strings::try_decode(input.as_bytes());
142 println!(
143 "Input: {} Expected: {} Got: {}",
144 input,
145 input,
146 result.as_str()
147 );
148 assert_eq!(input, result, "Incorrect string decoding!");
149 println!("Passed!")
150 }
151
152 #[test]
153 fn test_autodecode_other() {
154 let input = "I ❤ my wife!";
156 let expected = "I ❤ my wife!";
157 let result = input;
158 println!("Input: {} Expected: {} Got: {}", input, input, result);
159 assert_eq!(input, result, "Incorrect string decoding!");
160 println!("Passed!")
161 }
162
163 #[test]
164 fn test_decode() {
165 let input = "I ❤ my wife!";
166 let expected = "I ❤ my wife!";
167 let result = strings::try_decode_with(input.as_bytes(), "utf-8");
168 println!(
169 "Input: {} Expected: {} Got: {}",
170 input,
171 input,
172 result.as_str()
173 );
174 assert_eq!(input, result, "Incorrect string decoding!");
175 println!("Passed!")
176 }
177
178 #[test]
179 fn test_rumcache_insertion() {
180 let mut cache: RUMCache<&str, CompactString> = RUMCache::with_capacity(5);
181 cache.insert("❤", CompactString::from("I ❤ my wife!"));
182 println!("Contents: {:#?}", &cache);
183 assert_eq!(cache.len(), 1, "Incorrect number of items in cache!");
184 println!("Passed!")
185 }
186
187 #[test]
188 fn test_search_string_letters() {
189 let input = "Hello World!";
190 let expr = r"\w";
191 let result = string_search(input, expr, "");
192 let expected: RUMString = RUMString::from("HelloWorld");
193 println!(
194 "Input: {:?} Expected: {:?} Got: {:?}",
195 input, expected, result
196 );
197 assert_eq!(expected, result, "String search results mismatch");
198 println!("Passed!")
199 }
200
201 #[test]
202 fn test_search_string_words() {
203 let input = "Hello World!";
204 let expr = r"\w+";
205 let result = string_search(input, expr, " ");
206 let expected: RUMString = RUMString::from("Hello World");
207 println!(
208 "Input: {:?} Expected: {:?} Got: {:?}",
209 input, expected, result
210 );
211 assert_eq!(expected, result, "String search results mismatch");
212 println!("Passed!")
213 }
214
215 #[test]
216 fn test_search_string_named_groups() {
217 let input = "Hello World!";
218 let expr = r"(?<hello>\w{5}) (?<world>\w{5})";
219 let result = string_search_named_captures(input, expr, "");
220 let expected: RUMString = RUMString::from("World");
221 println!(
222 "Input: {:?} Expected: {:?} Got: {:?}",
223 input, expected, result
224 );
225 assert_eq!(expected, result["world"], "String search results mismatch");
226 println!("Passed!")
227 }
228
229 #[test]
230 fn test_search_string_all_groups() {
231 let input = "Hello World!";
232 let expr = r"(?<hello>\w{5}) (?<world>\w{5})";
233 let result = string_search_all_captures(input, expr, "");
234 let expected: Vec<&str> = vec!["Hello", "World"];
235 println!(
236 "Input: {:?} Expected: {:?} Got: {:?}",
237 input, expected, result
238 );
239 assert_eq!(expected, result, "String search results mismatch");
240 println!("Passed!")
241 }
242
243 #[test]
245 fn test_default_num_threads() {
246 use num_cpus;
247 let threads = threading::threading_functions::get_default_system_thread_count();
248 assert_eq!(
249 threads >= num_cpus::get(),
250 true,
251 "Default thread count is incorrect! We got {}, but expected {}!",
252 threads,
253 num_cpus::get()
254 );
255 }
256
257 #[test]
258 fn test_execute_job() {
259 let rt = rumtk_init_threads!();
260 let expected = vec![1, 2, 3];
261 let task_processor = async |args: &SafeTaskArgs<i32>| -> TaskResult<i32> {
262 let owned_args = Arc::clone(args);
263 let lock_future = owned_args.read();
264 let locked_args = lock_future.await;
265 let mut results = TaskItems::<i32>::with_capacity(locked_args.len());
266 print!("Contents: ");
267 for arg in locked_args.iter() {
268 results.push(arg.clone());
269 println!("{} ", &arg);
270 }
271 Ok(results)
272 };
273 let locked_args = RwLock::new(expected.clone());
274 let task_args = SafeTaskArgs::<i32>::new(locked_args);
275 let task_result = rumtk_wait_on_task!(rt, task_processor, &task_args);
276 let result = task_result.unwrap();
277 assert_eq!(&result, &expected, "{}", format_compact!("Task processing returned a different result than expected! Expected {:?} \nResults {:?}", &expected, &result));
278 }
279
280 #[test]
281 fn test_execute_job_macros() {
282 let rt = rumtk_init_threads!();
283 let expected = vec![1, 2, 3];
284 let task_processor = async |args: &SafeTaskArgs<i32>| -> TaskResult<i32> {
285 let owned_args = Arc::clone(args);
286 let lock_future = owned_args.read();
287 let locked_args = lock_future.await;
288 let mut results = TaskItems::<i32>::with_capacity(locked_args.len());
289 print!("Contents: ");
290 for arg in locked_args.iter() {
291 results.push(arg.clone());
292 println!("{} ", &arg);
293 }
294 Ok(results)
295 };
296 let task_args = rumtk_create_task_args!(1, 2, 3);
297 let task_result = rumtk_wait_on_task!(rt, task_processor, &task_args);
298 let result = task_result.unwrap();
299 assert_eq!(&result, &expected, "{}", format_compact!("Task processing returned a different result than expected! Expected {:?} \nResults {:?}", &expected, &result));
300 }
301
302 #[test]
303 fn test_execute_job_macros_one_line() {
304 let rt = rumtk_init_threads!();
305 let expected = vec![1, 2, 3];
306 let result = rumtk_exec_task!(
307 async |args: &SafeTaskArgs<i32>| -> TaskResult<i32> {
308 let owned_args = Arc::clone(args);
309 let lock_future = owned_args.read();
310 let locked_args = lock_future.await;
311 let mut results = TaskItems::<i32>::with_capacity(locked_args.len());
312 print!("Contents: ");
313 for arg in locked_args.iter() {
314 results.push(arg.clone());
315 println!("{} ", &arg);
316 }
317 Ok(results)
318 },
319 vec![1, 2, 3]
320 )
321 .unwrap();
322 assert_eq!(&result, &expected, "{}", format_compact!("Task processing returned a different result than expected! Expected {:?} \nResults {:?}", &expected, &result));
323 }
324
325 #[test]
326 fn test_clamp_index_positive_index() {
327 let values = vec![1, 2, 3, 4];
328 let given_index = 3isize;
329 let max_size = values.len() as isize;
330 let index = clamp_index(&given_index, &max_size).unwrap();
331 assert_eq!(
332 index, 3,
333 "Index mismatch! Requested index {} but got {}",
334 &given_index, &index
335 );
336 assert_eq!(
337 values[index], 4,
338 "Value mismatch! Expected {} but got {}",
339 &values[3], &values[index]
340 );
341 }
342
343 #[test]
344 fn test_clamp_index_reverse_index() {
345 let values = vec![1, 2, 3, 4];
346 let given_index = -1isize;
347 let max_size = values.len() as isize;
348 let index = clamp_index(&given_index, &max_size).unwrap();
349 assert_eq!(
350 index, 4,
351 "Index mismatch! Requested index {} but got {}",
352 &given_index, &index
353 );
354 assert_eq!(
355 values[index - 1],
356 4,
357 "Value mismatch! Expected {} but got {}",
358 &values[3],
359 &values[index]
360 );
361 }
362
363 use crate::core::clamp_index;
365 use crate::json::serialization::Serialize;
366 use crate::net::tcp::LOCALHOST;
367 use crate::threading::thread_primitives::{SafeTaskArgs, TaskItems, TaskResult};
368 use crate::threading::threading_functions::sleep;
369 use queue::queue::*;
370
371 #[test]
372 fn test_queue_data() {
373 let expected = vec![
374 RUMString::from("Hello"),
375 RUMString::from("World!"),
376 RUMString::from("Overcast"),
377 RUMString::from("and"),
378 RUMString::from("Sad"),
379 ];
380 let mut queue = TaskQueue::<RUMString>::new(&5).unwrap();
381 let locked_args = RwLock::new(expected.clone());
382 let task_args = SafeTaskArgs::<RUMString>::new(locked_args);
383 let processor = rumtk_create_task!(
384 async |args: &SafeTaskArgs<RUMString>| -> TaskResult<RUMString> {
385 let owned_args = Arc::clone(args);
386 let lock_future = owned_args.read();
387 let locked_args = lock_future.await;
388 let mut results = TaskItems::<RUMString>::with_capacity(locked_args.len());
389 print!("Contents: ");
390 for arg in locked_args.iter() {
391 print!("{} ", &arg);
392 results.push(RUMString::new(arg));
393 }
394 Ok(results)
395 },
396 task_args
397 );
398 queue.add_task::<_>(processor);
399 let results = queue.wait();
400 let mut result_data = Vec::<RUMString>::with_capacity(5);
401 for r in results {
402 for v in r.unwrap().iter() {
403 result_data.push(v.clone());
404 }
405 }
406 assert_eq!(result_data, expected, "Results do not match expected!");
407 }
408
409 #[test]
411 fn test_server_start() {
412 let mut server = match rumtk_create_server!("localhost", 0) {
413 Ok(server) => server,
414 Err(e) => panic!("Failed to create server because {}", e),
415 };
416 match server.start(false) {
417 Ok(_) => (),
418 Err(e) => panic!("Failed to start server because {}", e),
419 }
420 }
421
422 #[test]
423 fn test_server_send() {
424 let msg = RUMString::from("Hello World!");
425 let mut server = match rumtk_create_server!(LOCALHOST, 0, 1) {
426 Ok(server) => server,
427 Err(e) => panic!("Failed to create server because {}", e),
428 };
429 match server.start(false) {
430 Ok(_) => (),
431 Err(e) => panic!("Failed to start server because {}", e),
432 };
433 let address_info = server.get_address_info().unwrap();
434 let (ip, port) = rumtk_get_ip_port!(address_info);
435 println!("Sleeping");
436 rumtk_sleep!(1);
437 let mut client = match rumtk_connect!(port) {
438 Ok(client) => client,
439 Err(e) => panic!("Failed to create server because {}", e),
440 };
441 let client_id = client.get_address().unwrap();
442 rumtk_sleep!(1);
443 match server.send(&client_id, &msg.to_raw()) {
444 Ok(_) => (),
445 Err(e) => panic!("Server failed to send message because {}", e),
446 };
447 rumtk_sleep!(1);
448 let received_message = client.receive().unwrap();
449 assert_eq!(
450 &msg.to_raw(),
451 &received_message,
452 "{}",
453 format_compact!(
454 "Received message does not match sent message by server {:?}",
455 &received_message
456 )
457 );
458 }
459
460 #[test]
461 fn test_server_receive() {
462 let msg = RUMString::from("Hello World!");
463 let mut server = match rumtk_create_server!(LOCALHOST, 0) {
464 Ok(server) => server,
465 Err(e) => panic!("Failed to create server because {}", e),
466 };
467 match server.start(false) {
468 Ok(_) => (),
469 Err(e) => panic!("Failed to start server because {}", e),
470 };
471 let address_info = server.get_address_info().unwrap();
472 let (ip, port) = rumtk_get_ip_port!(address_info);
473 println!("Sleeping");
474 rumtk_sleep!(1);
475 let mut client = match rumtk_connect!(port) {
476 Ok(client) => client,
477 Err(e) => panic!("Failed to create server because {}", e),
478 };
479 match client.send(&msg.to_raw()) {
480 Ok(_) => (),
481 Err(e) => panic!("Failed to send message because {}", e),
482 };
483 rumtk_sleep!(1);
484 let client_id = client.get_address().expect("Failed to get client id");
485 let incoming_message = server.receive(&client_id).unwrap().to_rumstring();
486 println!("Received message => {:?}", &incoming_message);
487 assert_eq!(&incoming_message, msg, "Received message corruption!");
488 }
489
490 #[test]
491 fn test_server_get_clients() {
492 let mut server = match rumtk_create_server!(LOCALHOST, 0) {
493 Ok(server) => server,
494 Err(e) => panic!("Failed to create server because {}", e),
495 };
496 match server.start(false) {
497 Ok(_) => (),
498 Err(e) => panic!("Failed to start server because {}", e),
499 };
500 let address_info = server.get_address_info().unwrap();
501 let (ip, port) = rumtk_get_ip_port!(address_info);
502 println!("Sleeping");
503 rumtk_sleep!(1);
504 let mut client = match rumtk_connect!(port) {
505 Ok(client) => client,
506 Err(e) => panic!("Failed to create server because {}", e),
507 };
508 rumtk_sleep!(1);
509 let expected_client_id = client.get_address().expect("Failed to get client id");
510 let clients = server.get_client_ids();
511 let incoming_client_id = clients.get(0).expect("Expected client to have connected!");
512 println!("Connected client id => {}", &incoming_client_id);
513 assert_eq!(
514 &incoming_client_id, &expected_client_id,
515 "Connected client does not match the connecting client! Client id => {}",
516 &incoming_client_id
517 );
518 }
519
520 #[test]
521 fn test_server_stop() {
522 let msg = RUMString::from("Hello World!");
523 let mut server = match rumtk_create_server!("localhost", 0) {
524 Ok(server) => server,
525 Err(e) => panic!("Failed to create server because {}", e),
526 };
527 match server.start(false) {
528 Ok(_) => (),
529 Err(e) => panic!("Failed to start server because {}", e),
530 };
531 println!("Sleeping");
532 rumtk_sleep!(1);
533 match server.stop() {
534 Ok(_) => (),
535 Err(e) => panic!("Failed to stop server because {}", e),
536 };
537 }
538
539 #[test]
540 fn test_server_get_address_info() {
541 let msg = RUMString::from("Hello World!");
542 let mut server = match rumtk_create_server!("localhost", 0) {
543 Ok(server) => server,
544 Err(e) => panic!("Failed to create server because {}", e),
545 };
546 match server.start(false) {
547 Ok(_) => (),
548 Err(e) => panic!("Failed to start server because {}", e),
549 };
550 println!("Sleeping");
551 rumtk_sleep!(1);
552 match server.get_address_info() {
553 Some(addr) => println!("Server address info => {}", addr),
554 None => panic!("No address. Perhaps the server was never initialized?"),
555 };
556 }
557
558 #[test]
559 fn test_client_send() {
560 let msg = RUMString::from("Hello World!");
561 let mut server = match rumtk_create_server!(LOCALHOST, 0) {
562 Ok(server) => server,
563 Err(e) => panic!("Failed to create server because {}", e),
564 };
565 match server.start(false) {
566 Ok(_) => (),
567 Err(e) => panic!("Failed to start server because {}", e),
568 };
569 let address_info = server.get_address_info().unwrap();
570 let (ip, port) = rumtk_get_ip_port!(address_info);
571 println!("Sleeping");
572 rumtk_sleep!(1);
573 let mut client = match rumtk_connect!(port) {
574 Ok(client) => client,
575 Err(e) => panic!("Failed to create server because {}", e),
576 };
577 rumtk_sleep!(2);
578 match client.send(&msg.to_raw()) {
579 Ok(_) => (),
580 Err(e) => panic!("Failed to send message because {}", e),
581 };
582 rumtk_sleep!(1);
583 let clients = server.get_client_ids();
584 let incoming_client_id = clients.first().expect("Expected client to have connected!");
585 let mut received_message = server.receive(incoming_client_id).unwrap();
586 if received_message.is_empty() {
587 rumtk_sleep!(1);
588 received_message = server.receive(incoming_client_id).unwrap();
589 }
590 assert_eq!(
591 &msg.to_raw(),
592 &received_message,
593 "{}",
594 format_compact!(
595 "Received message does not match sent message by client {:?}",
596 &received_message
597 )
598 );
599 }
600
601 #[test]
604 fn test_serialize_json() {
605 #[derive(Serialize)]
606 struct MyStruct {
607 hello: RUMString,
608 }
609
610 let hw = MyStruct {
611 hello: RUMString::from("World"),
612 };
613 let hw_str = rumtk_serialize!(&hw, true).unwrap();
614
615 assert!(
616 !hw_str.is_empty(),
617 "Empty JSON string generated from the test struct!"
618 );
619 }
620
621 #[test]
622 fn test_deserialize_json() {
623 #[derive(Serialize, Deserialize, PartialEq)]
624 struct MyStruct {
625 hello: RUMString,
626 }
627
628 let hw = MyStruct {
629 hello: RUMString::from("World"),
630 };
631 let hw_str = rumtk_serialize!(&hw, true).unwrap();
632 let new_hw: MyStruct = rumtk_deserialize!(&hw_str).unwrap();
633
634 assert!(
635 new_hw == hw,
636 "Deserialized JSON does not match the expected value!"
637 );
638 }
639
640 }