Skip to content

Commit

Permalink
feat(cli): ✨ Add operations for read lines and write file
Browse files Browse the repository at this point in the history
  • Loading branch information
SpiralOutDotEu committed Nov 1, 2023
1 parent d15bddb commit 6b068a7
Showing 1 changed file with 105 additions and 1 deletion.
106 changes: 105 additions & 1 deletion src/utils/filesystem_operations.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
use std::{
fs, io,
collections::HashMap,
fs::{self, File, OpenOptions},
io::{self, BufRead, BufReader, Write},
path::Path,
sync::{Arc, Mutex},
};
Expand All @@ -18,6 +20,8 @@ pub trait FileSystemOps {
/// # Returns
/// A `Result` indicating the success or failure of the operation.
fn move_item(&self, src: &str, dst: &str) -> Result<(), String>;
fn read_lines(&self, path: &str) -> Result<Vec<String>, String>;
fn write_to_file(&self, path: &str, content: &str) -> Result<(), String>;
}

/// A real implementation of the `FileSystemOps` trait that performs file system operations.
Expand Down Expand Up @@ -48,6 +52,27 @@ impl FileSystemOps for RealFileSystemOps {

Ok(())
}

fn read_lines(&self, path: &str) -> Result<Vec<String>, String> {
let file = File::open(path).map_err(|e| e.to_string())?;
let reader = BufReader::new(file);
let lines = reader
.lines()
.collect::<Result<Vec<String>, io::Error>>()
.map_err(|e| e.to_string())?;
Ok(lines)
}

fn write_to_file(&self, path: &str, content: &str) -> Result<(), String> {
let mut file = OpenOptions::new()
.write(true)
.create(true)
.open(path)
.map_err(|e| e.to_string())?;
file.write_all(content.as_bytes())
.map_err(|e| e.to_string())?;
Ok(())
}
}

/// A mock implementation of the `FileSystemOps` trait for testing purposes.
Expand All @@ -56,20 +81,57 @@ impl FileSystemOps for RealFileSystemOps {
/// allowing tests to verify correct behavior without performing real file system operations.
pub struct MockFileSystemOps {
operations: Arc<Mutex<Vec<(String, String)>>>,
written_content: Arc<Mutex<HashMap<String, String>>>,
stubbed_file_content: Arc<Mutex<HashMap<String, Vec<String>>>>,
}

impl MockFileSystemOps {
/// Creates a new `MockFileSystemOps` instance.
pub fn new() -> Self {
MockFileSystemOps {
operations: Arc::new(Mutex::new(Vec::new())),
written_content: Arc::new(Mutex::new(HashMap::new())),
stubbed_file_content: Arc::new(Mutex::new(HashMap::new())),
}
}

pub fn stub_file_content(&self, path: &str, content: Vec<String>) {
self.stubbed_file_content
.lock()
.unwrap()
.insert(path.to_string(), content);
}
/// Returns a list of operations that this runner was called with.
pub fn operations(&self) -> Vec<(String, String)> {
self.operations.lock().unwrap().clone()
}

pub fn set_readable_content(&self, path: &str, content: Vec<String>) {
self.stubbed_file_content
.lock()
.unwrap()
.insert(path.to_string(), content);
}

pub fn get_written_content(&self, path: &str) -> Option<String> {
self.written_content.lock().unwrap().get(path).cloned()
}

pub fn create_file(&self, path: &str) -> Result<(), String> {
self.operations
.lock()
.unwrap()
.push(("create_file".to_string(), path.to_string()));
Ok(())
}

pub fn delete_file(&self, path: &str) -> Result<(), String> {
self.operations
.lock()
.unwrap()
.push(("delete_file".to_string(), path.to_string()));
Ok(())
}
}

impl FileSystemOps for MockFileSystemOps {
Expand All @@ -80,6 +142,21 @@ impl FileSystemOps for MockFileSystemOps {
.push((src.to_string(), dst.to_string()));
Ok(())
}

fn read_lines(&self, path: &str) -> Result<Vec<String>, String> {
match self.stubbed_file_content.lock().unwrap().get(path) {
Some(content) => Ok(content.clone()),
None => Err("File not found".to_string()),
}
}

fn write_to_file(&self, path: &str, content: &str) -> Result<(), String> {
self.written_content
.lock()
.unwrap()
.insert(path.to_string(), content.to_string());
Ok(())
}
}

#[cfg(test)]
Expand All @@ -101,4 +178,31 @@ mod tests {
vec![(src.to_string(), dst.to_string())]
);
}

#[test]
fn test_read_lines() {
let mock_ops = MockFileSystemOps::new();
let path = "test.txt";
let content = vec!["line 1".to_string(), "line 2".to_string()];
mock_ops.set_readable_content(path, content.clone());

let result = mock_ops.read_lines(path);

assert_eq!(result, Ok(content));
}

#[test]
fn test_write_to_file() {
let mock_ops = MockFileSystemOps::new();
let path = "test.txt";
let content = "some content";

let result = mock_ops.write_to_file(path, content);

assert!(result.is_ok());
assert_eq!(
mock_ops.get_written_content(path),
Some(content.to_string())
);
}
}

0 comments on commit 6b068a7

Please sign in to comment.