فهرست منبع

WIP migrating to unit tests for the intcomputer module

Jake Fenton 1 سال پیش
والد
کامیت
e7709d85c5
7فایلهای تغییر یافته به همراه153 افزوده شده و 31 حذف شده
  1. 10 10
      src/bin/02.rs
  2. 30 0
      src/bin/05.rs
  3. 57 0
      src/bin/intcomputer/input_provider.rs
  4. 10 21
      src/bin/intcomputer/mod.rs
  5. 18 0
      src/bin/intcomputer/opcode.rs
  6. 28 0
      src/bin/intcomputer/test.rs
  7. 0 0
      src/examples/05.txt

+ 10 - 10
src/bin/02.rs

@@ -39,15 +39,15 @@ fn main() {
 mod tests {
     use super::*;
 
-    #[test]
-    fn test_part_one() {
-        let input = advent_of_code::read_file("examples", 2);
-        assert_eq!(part_one(&input), Some(3500));
-    }
+    // #[test]
+    // fn test_part_one() {
+    //     let input = advent_of_code::read_file("examples", 2);
+    //     assert_eq!(part_one(&input), Some(3500));
+    // }
 
-    #[test]
-    fn test_part_two() {
-        let input = advent_of_code::read_file("examples", 2);
-        assert_eq!(part_two(&input), None);
-    }
+    // #[test]
+    // fn test_part_two() {
+    //     let input = advent_of_code::read_file("examples", 2);
+    //     assert_eq!(part_two(&input), None);
+    // }
 }

+ 30 - 0
src/bin/05.rs

@@ -0,0 +1,30 @@
+pub fn part_one(input: &str) -> Option<u32> {
+    None
+}
+
+pub fn part_two(input: &str) -> Option<u32> {
+    None
+}
+
+fn main() {
+    let input = &advent_of_code::read_file("inputs", 5);
+    advent_of_code::solve!(1, part_one, input);
+    advent_of_code::solve!(2, part_two, input);
+}
+
+#[cfg(test)]
+mod tests {
+    use super::*;
+
+    #[test]
+    fn test_part_one() {
+        let input = advent_of_code::read_file("examples", 5);
+        assert_eq!(part_one(&input), None);
+    }
+
+    #[test]
+    fn test_part_two() {
+        let input = advent_of_code::read_file("examples", 5);
+        assert_eq!(part_two(&input), None);
+    }
+}

+ 57 - 0
src/bin/intcomputer/input_provider.rs

@@ -0,0 +1,57 @@
+use std::io;
+use core::fmt::Debug;
+
+#[derive(Debug)]
+pub struct InputProviderError {
+    pub msg: String
+}
+
+pub trait InputProvider {
+    fn get_input(&mut self) -> Result<i32, InputProviderError>;
+}
+
+pub struct NullProvider {
+
+}
+
+impl InputProvider for NullProvider {
+    fn get_input(&mut self) -> Result<i32, InputProviderError> {
+        panic!("This method deliberately not implemented")
+    }
+}
+
+struct ConsoleProvider {
+
+}
+
+impl Debug for dyn InputProvider {
+    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
+        write!(f, "InputProvider")
+    }
+}
+
+impl InputProvider for ConsoleProvider {
+    fn get_input(&mut self) -> Result<i32, InputProviderError> {
+        let mut user_input = String::new();
+        let stdin = io::stdin(); // We get `Stdin` here.
+        stdin.read_line(&mut user_input).unwrap();
+        Ok(user_input.parse().unwrap())
+    }
+}
+
+struct TestProvder {
+    queued: Vec<i32>,
+    idx: usize
+}
+
+impl InputProvider for TestProvder {
+    fn get_input(&mut self) -> Result<i32, InputProviderError> {
+        if self.idx >= self.queued.len() {
+            Err(InputProviderError{msg: "out of queued inputs".to_string()})
+        } else {
+            let res = self.queued[self.idx];
+            self.idx += 1;
+            return Ok(res);
+        }
+    }
+}

+ 10 - 21
src/bin/intcomputer/mod.rs

@@ -1,35 +1,23 @@
-use std::{convert::TryFrom};
+mod test;
+mod opcode;
+use opcode::Opcode;
+mod input_provider;
+use input_provider::{InputProvider, NullProvider};
 
+#[derive(Debug)]
 pub struct Computer {
     tape: Vec<i32>,
-    ptr_pos: usize
+    ptr_pos: usize,
+    input_provider: Box<dyn InputProvider>
 }
 
-enum Opcode {
-    ADD = 1,
-    MULT = 2,
-    TERMINATE = 99,
-}
-
-impl TryFrom<i32> for Opcode {
-    type Error = ();
-
-    fn try_from(v: i32) -> Result<Self, Self::Error> {
-        match v {
-            x if x == Opcode::ADD as i32 => Ok(Opcode::ADD),
-            x if x == Opcode::MULT as i32 => Ok(Opcode::MULT),
-            x if x == Opcode::TERMINATE as i32 => Ok(Opcode::TERMINATE),
-            _ => Err(()),
-        }
-    }
-}
 
+#[derive(Debug)]
 pub struct Error {
     pub msg: String
 }
 
 impl Computer {
-
     fn add(&mut self, left_addy: usize, right_addy: usize, dest_addy: usize) -> Result<(), Error>{
         let memsize = self.tape.len();
         if left_addy < memsize && right_addy < memsize && dest_addy < memsize {
@@ -65,6 +53,7 @@ impl Computer {
         return Computer { 
             tape: iter.map(|item| item.clone()).collect(),
             ptr_pos: 0,
+            input_provider: Box::new(NullProvider{})
         }
     }
 

+ 18 - 0
src/bin/intcomputer/opcode.rs

@@ -0,0 +1,18 @@
+pub enum Opcode {
+    ADD = 1,
+    MULT = 2,
+    TERMINATE = 99,
+}
+
+impl TryFrom<i32> for Opcode {
+    type Error = ();
+
+    fn try_from(v: i32) -> Result<Self, Self::Error> {
+        match v {
+            x if x == Opcode::ADD as i32 => Ok(Opcode::ADD),
+            x if x == Opcode::MULT as i32 => Ok(Opcode::MULT),
+            x if x == Opcode::TERMINATE as i32 => Ok(Opcode::TERMINATE),
+            _ => Err(()),
+        }
+    }
+}

+ 28 - 0
src/bin/intcomputer/test.rs

@@ -0,0 +1,28 @@
+#[cfg(test)]
+mod tests {
+    use crate::intcomputer;
+
+    fn parse_str_to_intcodes(input: &str) -> Vec<i32> {
+        input.split(",").map(|item| item.parse().unwrap()).collect()
+    }
+
+    #[test]
+    fn test_day02_ex01_basic_add_and_mult() {
+        let input = "1,9,10,3,2,3,11,0,99,30,40,50";
+        let mut computer = intcomputer::Computer::from_iter(
+            parse_str_to_intcodes(input).iter()
+        );
+        computer.execute().unwrap();
+        assert_eq!(*(computer.get_pos(0)), 3500);
+    }
+
+    #[test]
+    fn test_day05_take_input() {
+        let input = "3,0,99";
+        let mut computer = intcomputer::Computer::from_iter(
+            parse_str_to_intcodes(input).iter()
+        );
+        computer.execute().unwrap();
+        assert_eq!(*(computer.get_pos(0)), 3500);
+    }
+}

+ 0 - 0
src/examples/05.txt