11//! Utilities for writing tests that interact with todo file
22use 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
1012use 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`
1322pub ( crate ) struct TodoFileTestContext {
1423 todo_file : TodoFile ,
@@ -76,10 +85,7 @@ impl TodoFileTestContext {
7685/// Will panic if a temporary file cannot be created
7786pub ( crate ) fn with_todo_file < C > ( lines : & [ & str ] , callback : C )
7887where 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+ }
0 commit comments