@@ -9,11 +9,12 @@ use std::fs;
99use std:: io:: Write ;
1010use std:: os:: unix:: ffi:: OsStrExt ;
1111use std:: path:: { Path , PathBuf } ;
12+ use std:: process:: Command ;
1213
1314#[ derive( Debug , Serialize , Deserialize ) ]
14- pub struct Config {
15- pub stdout : Vec < u8 > ,
16- pub exitcode : i32 ,
15+ pub enum Config {
16+ Config { stdout : Vec < u8 > , exitcode : i32 } ,
17+ Wrapper { executable : PathBuf } ,
1718}
1819
1920#[ derive( Debug ) ]
@@ -37,6 +38,15 @@ impl ExecutableMock {
3738 Ok ( ExecutableMock { temp_file } )
3839 }
3940
41+ fn wrapper ( context : & Context , executable : & Path ) -> R < ExecutableMock > {
42+ ExecutableMock :: new (
43+ context,
44+ Config :: Wrapper {
45+ executable : executable. to_owned ( ) ,
46+ } ,
47+ )
48+ }
49+
4050 pub fn path ( & self ) -> PathBuf {
4151 self . temp_file . path ( )
4252 }
@@ -57,8 +67,16 @@ impl ExecutableMock {
5767 let config: Config = deserialize ( & ExecutableMock :: skip_hashbang_line ( fs:: read (
5868 executable_mock_path,
5969 ) ?) ) ?;
60- context. stdout ( ) . write_all ( & config. stdout ) ?;
61- Ok ( ExitCode ( config. exitcode ) )
70+ match config {
71+ Config :: Config { stdout, exitcode } => {
72+ context. stdout ( ) . write_all ( & stdout) ?;
73+ Ok ( ExitCode ( exitcode) )
74+ }
75+ Config :: Wrapper { executable } => {
76+ Command :: new ( & executable) . output ( ) ?;
77+ Ok ( ExitCode ( 0 ) )
78+ }
79+ }
6280 }
6381
6482 fn skip_hashbang_line ( input : Vec < u8 > ) -> Vec < u8 > {
@@ -75,33 +93,63 @@ impl ExecutableMock {
7593mod test {
7694 use super :: * ;
7795 use std:: process:: Command ;
78- use test_utils:: TempFile ;
96+ use test_utils:: { trim_margin , TempFile } ;
7997
80- #[ test]
81- fn creates_an_executable_that_outputs_the_given_stdout ( ) -> R < ( ) > {
82- let mock_executable = ExecutableMock :: new (
83- & Context :: new_mock ( ) ,
84- Config {
85- stdout : b"foo" . to_vec ( ) ,
86- exitcode : 0 ,
87- } ,
88- ) ?;
89- let output = Command :: new ( mock_executable. path ( ) ) . output ( ) ?;
90- assert_eq ! ( output. stdout, b"foo" ) ;
91- Ok ( ( ) )
98+ mod new {
99+ use super :: * ;
100+
101+ #[ test]
102+ fn creates_an_executable_that_outputs_the_given_stdout ( ) -> R < ( ) > {
103+ let executable_mock = ExecutableMock :: new (
104+ & Context :: new_mock ( ) ,
105+ Config :: Config {
106+ stdout : b"foo" . to_vec ( ) ,
107+ exitcode : 0 ,
108+ } ,
109+ ) ?;
110+ let output = Command :: new ( & executable_mock. path ( ) ) . output ( ) ;
111+ assert_eq ! ( output?. stdout, b"foo" ) ;
112+ Ok ( ( ) )
113+ }
114+
115+ #[ test]
116+ fn creates_an_executable_that_exits_with_the_given_exitcode ( ) -> R < ( ) > {
117+ let executable_mock = ExecutableMock :: new (
118+ & Context :: new_mock ( ) ,
119+ Config :: Config {
120+ stdout : b"foo" . to_vec ( ) ,
121+ exitcode : 42 ,
122+ } ,
123+ ) ?;
124+ let output = Command :: new ( executable_mock. path ( ) ) . output ( ) ?;
125+ assert_eq ! ( output. status. code( ) , Some ( 42 ) ) ;
126+ Ok ( ( ) )
127+ }
92128 }
93129
94- #[ test]
95- fn creates_an_executable_that_exits_with_the_given_exitcode ( ) -> R < ( ) > {
96- let mock_executable = ExecutableMock :: new (
97- & Context :: new_mock ( ) ,
98- Config {
99- stdout : b"foo" . to_vec ( ) ,
100- exitcode : 42 ,
101- } ,
102- ) ?;
103- let output = Command :: new ( mock_executable. path ( ) ) . output ( ) ?;
104- assert_eq ! ( output. status. code( ) , Some ( 42 ) ) ;
105- Ok ( ( ) )
130+ mod wrapper {
131+ use super :: * ;
132+ use crate :: utils:: path_to_string;
133+ use tempdir:: TempDir ;
134+
135+ #[ test]
136+ fn executes_the_given_command ( ) -> R < ( ) > {
137+ let temp_dir = TempDir :: new ( "test" ) ?;
138+ let path = temp_dir. path ( ) . join ( "foo.txt" ) ;
139+ let script = TempFile :: write_temp_script (
140+ trim_margin ( & format ! (
141+ "
142+ |#!/usr/bin/env bash
143+ |echo foo > {}
144+ " ,
145+ path_to_string( & path) ?
146+ ) ) ?
147+ . as_bytes ( ) ,
148+ ) ?;
149+ let executable_mock = ExecutableMock :: wrapper ( & Context :: new_mock ( ) , & script. path ( ) ) ?;
150+ Command :: new ( executable_mock. path ( ) ) . status ( ) ?;
151+ assert_eq ! ( String :: from_utf8( fs:: read( & path) ?) ?, "foo\n " ) ;
152+ Ok ( ( ) )
153+ }
106154 }
107155}
0 commit comments