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