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