Skip to content

Commit 6468002

Browse files
committed
Add tests for state detection
1 parent ff5ef84 commit 6468002

File tree

2 files changed

+164
-6
lines changed

2 files changed

+164
-6
lines changed

src/test_helpers/with_todo_file.rs

Lines changed: 145 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,23 @@
11
//! Utilities for writing tests that interact with todo file
22
use std::{
33
cell::RefCell,
4+
io::Write,
45
fmt::{Debug, Formatter},
5-
path::Path,
6+
fs::File,
7+
path::{Path, PathBuf},
68
};
79

8-
use tempfile::{Builder, NamedTempFile};
10+
use tempfile::{Builder, NamedTempFile, TempDir};
911

1012
use crate::todo_file::{Line, TodoFile, TodoFileOptions};
1113

14+
fn get_repo_dir() -> PathBuf {
15+
Path::new(env!("CARGO_MANIFEST_DIR"))
16+
.join("test")
17+
.join("fixtures")
18+
.join("simple")
19+
}
20+
1221
/// Context for `with_todo_file`
1322
pub(crate) struct TodoFileTestContext {
1423
todo_file: TodoFile,
@@ -76,10 +85,7 @@ impl TodoFileTestContext {
7685
/// Will panic if a temporary file cannot be created
7786
pub(crate) fn with_todo_file<C>(lines: &[&str], callback: C)
7887
where C: FnOnce(TodoFileTestContext) {
79-
let git_repo_dir = Path::new(env!("CARGO_MANIFEST_DIR"))
80-
.join("test")
81-
.join("fixtures")
82-
.join("simple");
88+
let git_repo_dir = get_repo_dir();
8389
let git_todo_file = Builder::new()
8490
.prefix("git-rebase-todo-scratch")
8591
.suffix("")
@@ -93,3 +99,136 @@ where C: FnOnce(TodoFileTestContext) {
9399
todo_file,
94100
});
95101
}
102+
103+
104+
/// Context for `with_todo_file`
105+
pub struct TodoFileTestDirContext {
106+
todo_file: TodoFile,
107+
git_todo_dir: RefCell<TempDir>,
108+
git_todo_file: RefCell<File>,
109+
}
110+
111+
impl Debug for TodoFileTestDirContext {
112+
#[inline]
113+
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
114+
f.debug_struct("TodoFileTestDirContext")
115+
.field("todo_file", &self.todo_file)
116+
.field("filepath", &self.todo_file.filepath)
117+
.finish()
118+
}
119+
}
120+
121+
impl TodoFileTestDirContext {
122+
/// Return the path of the todo file
123+
#[inline]
124+
pub fn path(&self) -> String {
125+
String::from(self.todo_file.filepath.to_str().unwrap_or_default())
126+
}
127+
128+
/// Return the path of the todo dir
129+
#[inline]
130+
pub fn dir_path(&self) -> String {
131+
String::from(self.git_todo_dir.borrow().path().to_str().unwrap_or_default())
132+
}
133+
134+
/// Get the todo file instance
135+
#[inline]
136+
pub const fn todo_file(&self) -> &TodoFile {
137+
&self.todo_file
138+
}
139+
140+
/// Get the todo file instance as mutable
141+
#[inline]
142+
pub fn todo_file_mut(&mut self) -> &mut TodoFile {
143+
&mut self.todo_file
144+
}
145+
146+
/// Get the todo file instance
147+
#[inline]
148+
pub fn to_owned(self) -> (TempDir, TodoFile) {
149+
(self.git_todo_dir.into_inner(), self.todo_file)
150+
}
151+
152+
/// Delete the path behind the todo dir
153+
///
154+
/// # Panics
155+
/// Will panic if the dir cannot be deleted for any reason
156+
#[inline]
157+
pub fn delete_dir(&self) {
158+
self.git_todo_dir
159+
.replace(Builder::new().tempdir().unwrap())
160+
.close()
161+
.unwrap();
162+
}
163+
164+
/// Set the path behind ot todo file as readonly
165+
///
166+
/// # Panics
167+
/// Will panic if the file permissions cannot be changed for any reason
168+
#[inline]
169+
pub fn set_file_readonly(&self) {
170+
let git_todo_file = self.git_todo_file.borrow_mut();
171+
let mut permissions = git_todo_file.metadata().unwrap().permissions();
172+
permissions.set_readonly(true);
173+
git_todo_file.set_permissions(permissions).unwrap();
174+
}
175+
}
176+
177+
/// Provide a `TodoFileTestDirContext` instance containing a `Todo` for use in tests.
178+
///
179+
/// # Panics
180+
/// Will panic if a temporary file cannot be created
181+
#[inline]
182+
fn with_todo_file_dir<C>(prefix: &str, filename: &str, lines: &[&str], callback: C)
183+
where C: FnOnce(TodoFileTestDirContext) {
184+
let git_repo_dir = get_repo_dir();
185+
let git_todo_dir = Builder::new()
186+
.prefix(prefix)
187+
.suffix("")
188+
.tempdir_in(git_repo_dir.as_path())
189+
.unwrap();
190+
let git_todo_file_path = git_todo_dir.path().join(filename);
191+
let git_todo_file = File::create(git_todo_file_path.clone()).unwrap();
192+
193+
let mut todo_file = TodoFile::new(git_todo_file_path, TodoFileOptions::new(1, "#"));
194+
todo_file.set_lines(lines.iter().map(|l| Line::parse(l).unwrap()).collect());
195+
callback(TodoFileTestDirContext {
196+
git_todo_dir: RefCell::new(git_todo_dir),
197+
todo_file,
198+
git_todo_file: RefCell::new(git_todo_file),
199+
});
200+
}
201+
202+
/// Provide a `TodoFileTestDirContext` instance containing a `Todo` for use in tests.
203+
///
204+
/// # Panics
205+
/// Will panic if a temporary file cannot be created
206+
#[inline]
207+
pub fn with_todo_revise_file<C>(lines: &[&str], callback: C)
208+
where C: FnOnce(TodoFileTestDirContext) {
209+
with_todo_file_dir("revise.", "git-revise-todo", lines, callback)
210+
}
211+
212+
/// Provide a `TodoFileTestDirContext` instance containing a `Todo` for use in tests.
213+
///
214+
/// # Panics
215+
/// Will panic if a temporary file cannot be created
216+
#[inline]
217+
pub fn with_todo_rebase_edit_file<C>(lines: &[&str], callback: C)
218+
where C: FnOnce(TodoFileTestDirContext) {
219+
with_todo_file_dir("rebase-merge-scratch", "git-rebase-todo", lines, callback)
220+
}
221+
222+
/// Provide a `TodoFileTestDirContext` instance containing a `Todo`, with a stopped-sha
223+
///
224+
/// # Panics
225+
/// Will panic if a temporary file cannot be created
226+
#[inline]
227+
pub fn with_todo_rebase_edit_file_stopped<C>(lines: &[&str], callback: C)
228+
where C: FnOnce(TodoFileTestDirContext) {
229+
with_todo_rebase_edit_file(lines, |context| {
230+
let mut stopped_sha = File::create(Path::new(context.dir_path().as_str()).join("stopped-sha")).unwrap();
231+
writeln!(&mut stopped_sha, "this is a test file").unwrap();
232+
callback(context);
233+
});
234+
}

src/todo_file/state.rs

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ mod tests {
5252
use rstest::rstest;
5353

5454
use super::*;
55+
use crate::testutil::{with_todo_revise_file, TodoFileTestDirContext, with_todo_rebase_edit_file, with_todo_rebase_edit_file_stopped};
5556

5657
#[rstest]
5758
#[case::edit(State::Initial, "initial")]
@@ -60,4 +61,22 @@ mod tests {
6061
fn to_string(#[case] action: State, #[case] expected: &str) {
6162
assert_eq!(format!("{action}"), expected);
6263
}
64+
65+
#[rstest]
66+
#[case::edit(State::Initial)]
67+
#[case::edit(State::Edit)]
68+
#[case::edit(State::Revise)]
69+
fn detect(#[case] expected: State) {
70+
let check = |context: TodoFileTestDirContext| {
71+
assert_eq!(
72+
detect_state(context.todo_file().filepath.as_path()).unwrap(),
73+
expected
74+
)
75+
};
76+
match expected {
77+
State::Initial => with_todo_rebase_edit_file(&[], check),
78+
State::Edit => with_todo_rebase_edit_file_stopped(&[], check),
79+
State::Revise => with_todo_revise_file(&[], check),
80+
}
81+
}
6382
}

0 commit comments

Comments
 (0)