1- use std:: {
2- path:: { Path , PathBuf } ,
3- sync:: Arc ,
4- time:: Duration ,
5- } ;
1+ use std:: { sync:: Arc , time:: Duration } ;
62
7- use derive_more:: From ;
83use leucite:: { MemorySize , Rules } ;
94
105mod builder;
116pub use builder:: TestContextBuilder ;
127
13- use crate :: { cases:: TestCase , runner:: TestRunner } ;
14-
15- /// Configuration for how a file should be setup for test cases to be run
16- #[ derive( Clone , Debug , PartialEq , Eq ) ]
17- pub struct FileConfig {
18- /// This path is relative to the temporary directory created while running tests
19- src : FileContent ,
20- dest : PathBuf ,
21- }
22-
23- impl FileConfig {
24- pub fn new ( src : impl Into < FileContent > , dest : impl AsRef < Path > ) -> Self {
25- let dest = dest. as_ref ( ) ;
26- let dest = if dest. is_absolute ( ) {
27- dest. strip_prefix ( "/" ) . unwrap ( ) . to_path_buf ( )
28- } else {
29- dest. to_path_buf ( )
30- } ;
31-
32- Self {
33- src : src. into ( ) ,
34- dest,
35- }
36- }
37-
38- pub ( crate ) async fn write_file ( & self , base : impl AsRef < Path > ) -> std:: io:: Result < u64 > {
39- let target = base. as_ref ( ) . join ( & self . dest ) ;
40- match self . src {
41- FileContent :: Path ( ref path) => tokio:: fs:: copy ( path, target) . await ,
42- FileContent :: Bytes ( ref contents) => tokio:: fs:: write ( target, contents)
43- . await
44- . map ( |_| contents. len ( ) as _ ) ,
45- }
46- }
47-
48- pub fn dest ( & self ) -> & Path {
49- & self . dest
50- }
51- }
52-
53- impl < S , D > From < ( S , D ) > for FileConfig
54- where
55- S : Into < FileContent > ,
56- D : AsRef < Path > ,
57- {
58- fn from ( ( source, destination) : ( S , D ) ) -> Self {
59- Self :: new ( source, destination)
60- }
61- }
62-
63- /// Representation of the content of a file to be added into a test environment
64- ///
65- /// [`FileContent::Path`] represents a path on the host system. The test runner will copy from
66- /// this path into the test environment _at compile time_. If the data should be loaded now,
67- /// consider using [`FileContent::Bytes`].
68- ///
69- /// [`FileContent::Bytes`] contains a vec of bytes that will be written to the file when the tests
70- /// are compiled.
71- #[ derive( Clone , Debug , From , PartialEq , Eq ) ]
72- pub enum FileContent {
73- /// Copies a file directly from this path
74- ///
75- /// NOTE: This happens when the tests are compiled/run. If you want to load the file into
76- /// memory first, use [`FileContent::Bytes`].
77- Path ( PathBuf ) ,
78- /// Creates a new file with this content
79- Bytes ( Vec < u8 > ) ,
80- }
81-
82- impl From < & Path > for FileContent {
83- fn from ( value : & Path ) -> Self {
84- Self :: path ( value)
85- }
86- }
87-
88- impl From < & [ u8 ] > for FileContent {
89- fn from ( value : & [ u8 ] ) -> Self {
90- Self :: bytes ( value)
91- }
92- }
93-
94- impl < const N : usize > From < & [ u8 ; N ] > for FileContent {
95- fn from ( value : & [ u8 ; N ] ) -> Self {
96- Self :: bytes ( value)
97- }
98- }
99-
100- impl FileContent {
101- /// Construct a `FileContent::Path` from something that's like a path
102- ///
103- /// ```
104- /// # use erudite::context::FileContent;
105- /// let content = FileContent::path("/foo/bar");
106- /// ```
107- pub fn path ( path : impl Into < PathBuf > ) -> Self {
108- Self :: Path ( path. into ( ) )
109- }
110-
111- /// Construct a `FileContent::Bytes` from something that's like a string.
112- ///
113- /// ```
114- /// # use erudite::context::FileContent;
115- /// let content = FileContent::string("// some rust code");
116- /// ```
117- pub fn string ( string : impl Into < String > ) -> Self {
118- Self :: bytes ( string. into ( ) )
119- }
120-
121- /// Construct a `FileContent::Bytes` from raw bytes
122- ///
123- /// ```
124- /// # use erudite::context::FileContent;
125- /// let content = FileContent::bytes([0xfa, 0xca, 0xde]);
126- /// ```
127- pub fn bytes ( bytes : impl Into < Vec < u8 > > ) -> Self {
128- Self :: Bytes ( bytes. into ( ) )
129- }
130- }
8+ use crate :: { cases:: TestCase , runner:: TestRunner , FileConfig } ;
1319
13210// TODO: rename (and update test names)
13311#[ derive( Copy , Clone , Debug , Eq , PartialEq ) ]
@@ -247,7 +125,10 @@ mod test {
247125
248126 use tmpdir:: TmpDir ;
249127
250- use crate :: context:: { CommandConfig , FileConfig , FileContent } ;
128+ use crate :: {
129+ context:: { CommandConfig , FileConfig } ,
130+ FileContent ,
131+ } ;
251132
252133 #[ tokio:: test]
253134 async fn file_config_path ( ) {
@@ -270,6 +151,32 @@ mod test {
270151 assert_eq ! ( read, "some content" ) ;
271152 }
272153
154+ #[ tokio:: test]
155+ async fn file_config_path_dir ( ) {
156+ let tmpdir = TmpDir :: new ( "erudite-test" ) . await . unwrap ( ) ;
157+ let source = tmpdir. as_ref ( ) . join ( "foo" ) ;
158+ tokio:: fs:: create_dir_all ( & source) . await . unwrap ( ) ;
159+ tokio:: fs:: write ( source. join ( "bar.txt" ) , "Some content in /foo/bar.txt" )
160+ . await
161+ . unwrap ( ) ;
162+
163+ let config = FileConfig :: new ( source, "out" ) ;
164+ assert_eq ! ( config. dest( ) , Path :: new( "out" ) ) ;
165+ config
166+ . write_file ( & tmpdir)
167+ . await
168+ . expect ( "failed while copying file" ) ;
169+
170+ let dir = tokio:: fs:: metadata ( tmpdir. as_ref ( ) . join ( "foo" ) )
171+ . await
172+ . expect ( "failed while reading file" ) ;
173+ assert ! ( dir. is_dir( ) ) ;
174+ let read = tokio:: fs:: read_to_string ( tmpdir. as_ref ( ) . join ( "foo/bar.txt" ) )
175+ . await
176+ . expect ( "failed while reading file" ) ;
177+ assert_eq ! ( read, "Some content in /foo/bar.txt" ) ;
178+ }
179+
273180 #[ tokio:: test]
274181 async fn file_config_bytes ( ) {
275182 let tmpdir = TmpDir :: new ( "erudite-test" ) . await . unwrap ( ) ;
0 commit comments