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