Website Summary Files Commits Branches @commit @diff @stats
path: root / vm / src / vmm / command.rs
diff options
context:
space:
mode:
Commita6a5cf874fc03296c01bb72abdcb564e5d65ddcd (patch)
Author
 Syndamia <kamen@syndamia.com>
2025-02-15 10:29:05 +0200
Committer
 Syndamia <kamen@syndamia.com>
2025-02-15 10:29:05 +0200
Fileseb585f078e928748dad4e2c7c3b8f2f19bbcaf82 /vm/src/vmm/command.rs
tonkobali-a6a5cf874fc03296c01bb72abdcb564e5d65ddcd.tar
tonkobali-a6a5cf874fc03296c01bb72abdcb564e5d65ddcd.tar.gz
tonkobali-a6a5cf874fc03296c01bb72abdcb564e5d65ddcd.zip
Parent448f86e335b8ecd4699c2eadc03fc97ca0bdc19f (diff)
test(vm): Add tests
1 files changed, 106 insertions, 7 deletions
-rw-r--r--vm/src/vmm/command.rs113
diff --git a/vm/src/vmm/command.rs b/vm/src/vmm/command.rs
index 188030e..22d0ff3 100644
--- a/vm/src/vmm/command.rs
+++ b/vm/src/vmm/command.rs
@@ -11,14 +11,17 @@ fn expects_n_args(args: &Vec<&str>, n: usize) -> Result<(), String> {
}
}
-fn parse_location(arg: &str, assignment: bool) -> Result<Vec<usize>, String> {
+fn parse_location(arg: &str, assignment: bool) -> Result<Vec<Word>, String> {
let nums_str = arg.to_string();
let nums = nums_str
.split(&['.', ':'])
.collect::<Vec<&str>>();
- let start = nums[0].parse::<usize>()
+ let start = nums[0].parse::<Word>()
.map_err(|_| format!("Unknown command '{}'!", nums[0]))?;
+ if start < 0 {
+ return Err(format!("Address '{}' cannot be negative!", start));
+ }
// Single location
if nums.len() == 1 {
@@ -26,22 +29,25 @@ fn parse_location(arg: &str, assignment: bool) -> Result<Vec<usize>, String> {
}
// Range location
else {
- let end = nums[1].parse::<usize>()
+ let end = nums[1].parse::<Word>()
.map_err(|_| format!("Expected location!"))?;
if assignment {
Ok(vec![start, end])
}
// Range addresses
+ else if end < 0 {
+ return Err(format!("Address '{}' cannot be negative!", end));
+ }
else {
Ok(Vec::from_iter(start..=end))
}
}
}
-fn assign_location(locs: Vec<usize>, vm: &mut VirtualMachine) {
- print_locations(vec![locs[0]], vm);
- vm.set_word(locs[0], locs[1] as Word);
+fn assign_location(locs: Vec<Word>, vm: &mut VirtualMachine) {
+ print_locations(vec![locs[0] as usize], vm);
+ vm.set_word(locs[0] as usize, locs[1] as Word);
}
fn print_locations(locs: Vec<usize>, vm: &VirtualMachine) {
@@ -148,10 +154,103 @@ Memory IO:
assign_location(locs, vm);
}
else {
- print_locations(locs, vm);
+ let mut locs_casted = Vec::new();
+ for elem in locs {
+ let elem = elem.try_into()
+ .map_err(|_| format!("Expected address, got '{}'!", elem))?;
+ locs_casted.push(elem);
+ }
+ print_locations(locs_casted, vm);
}
}
},
}
Ok(())
}
+
+#[cfg(test)]
+mod tests {
+ use super::*;
+
+ #[test]
+ fn expect_args_too_few() {
+ let res = expects_n_args(&vec!["abc", "arg1"], 2);
+ assert!(res.is_err());
+ }
+
+ #[test]
+ fn expect_args_too_many() {
+ let res = expects_n_args(&vec!["abc", "arg1", "arg2", "arg3"], 2);
+ assert!(res.is_err());
+ }
+
+ #[test]
+ fn expect_args_exact() {
+ let res = expects_n_args(&vec!["abc", "arg1", "arg2"], 2);
+ assert!(res.is_ok());
+ }
+
+ #[test]
+ fn parse_location_single_positive() {
+ let res = parse_location("1234", false);
+ assert!(res.is_ok());
+ let res = res.unwrap();
+ assert_eq!(res.len(), 1);
+ assert_eq!(res[0], 1234);
+ }
+
+ #[test]
+ fn parse_location_single_negative() {
+ let res = parse_location("-1234", false);
+ assert!(res.is_err());
+ }
+
+ #[test]
+ fn parse_location_range_positives() {
+ let res = parse_location("1002.1011", false);
+ assert!(res.is_ok());
+
+ let res = res.unwrap();
+ assert_eq!(res.len(), 10);
+ for i in 1002..=1011 {
+ assert_eq!(res[i-1002], i as Word);
+ }
+ }
+
+ #[test]
+ fn parse_location_range_negative() {
+ let res = parse_location("-1002.1011", false);
+ assert!(res.is_err());
+
+ let res = parse_location("1002.-1011", false);
+ assert!(res.is_err());
+ }
+
+ #[test]
+ fn parse_location_assignment_positive() {
+ let res = parse_location("1829:99", true);
+ assert!(res.is_ok());
+
+ let res = res.unwrap();
+ assert_eq!(res.len(), 2);
+ assert_eq!(res[0], 1829);
+ assert_eq!(res[1], 99);
+ }
+
+ #[test]
+ fn parse_location_assignment_negative_address() {
+ let res = parse_location("-1829:99", true);
+ assert!(res.is_err());
+ }
+
+ #[test]
+ fn parse_location_assignment_negative_value() {
+ let res = parse_location("1829:-99", true);
+ assert!(res.is_ok());
+
+ let res = res.unwrap();
+ assert_eq!(res.len(), 2);
+ assert_eq!(res[0], 1829);
+ assert_eq!(res[1], -99);
+ }
+}