1
+ use environment:: Environment ;
1
2
use errors:: * ;
2
3
use output:: { OutputAssertion , OutputKind } ;
3
4
use std:: default;
@@ -10,6 +11,7 @@ use std::vec::Vec;
10
11
#[ derive( Debug ) ]
11
12
pub struct Assert {
12
13
cmd : Vec < String > ,
14
+ env : Environment ,
13
15
current_dir : Option < PathBuf > ,
14
16
expect_success : Option < bool > ,
15
17
expect_exit_code : Option < i32 > ,
@@ -27,6 +29,7 @@ impl default::Default for Assert {
27
29
. into_iter ( )
28
30
. map ( String :: from)
29
31
. collect ( ) ,
32
+ env : Environment :: inherit ( ) ,
30
33
current_dir : None ,
31
34
expect_success : Some ( true ) ,
32
35
expect_exit_code : None ,
@@ -87,6 +90,7 @@ impl Assert {
87
90
/// .with_args(&["42"])
88
91
/// .stdout().contains("42")
89
92
/// .unwrap();
93
+ ///
90
94
/// ```
91
95
pub fn with_args ( mut self , args : & [ & str ] ) -> Self {
92
96
self . cmd . extend ( args. into_iter ( ) . cloned ( ) . map ( String :: from) ) ;
@@ -128,6 +132,41 @@ impl Assert {
128
132
self
129
133
}
130
134
135
+ /// Sets environments variables for the command.
136
+ ///
137
+ /// # Examples
138
+ ///
139
+ /// ```rust
140
+ /// extern crate assert_cli;
141
+ ///
142
+ /// assert_cli::Assert::command(&["printenv"])
143
+ /// .with_env(&[("TEST_ENV", "OK")])
144
+ /// .stdout().contains("TEST_ENV=OK")
145
+ /// .execute()
146
+ /// .unwrap();
147
+ ///
148
+ /// let env = assert_cli::Environment::empty()
149
+ /// .insert("FOO", "BAR");
150
+ ///
151
+ /// assert_cli::Assert::command(&["printenv"])
152
+ /// .with_env(&env)
153
+ /// .stdout().is("FOO=BAR")
154
+ /// .execute()
155
+ /// .unwrap();
156
+ ///
157
+ /// ::std::env::set_var("BAZ", "BAR");
158
+ ///
159
+ /// assert_cli::Assert::command(&["printenv"])
160
+ /// .stdout().contains("BAZ=BAR")
161
+ /// .execute()
162
+ /// .unwrap();
163
+ /// ```
164
+ pub fn with_env < E : Into < Environment > > ( mut self , env : E ) -> Self {
165
+ self . env = env. into ( ) ;
166
+
167
+ self
168
+ }
169
+
131
170
/// Small helper to make chains more readable.
132
171
///
133
172
/// # Examples
@@ -253,13 +292,17 @@ impl Assert {
253
292
/// ```
254
293
pub fn execute ( self ) -> Result < ( ) > {
255
294
let cmd = & self . cmd [ 0 ] ;
295
+
256
296
let args: Vec < _ > = self . cmd . iter ( ) . skip ( 1 ) . collect ( ) ;
257
297
let mut command = Command :: new ( cmd) ;
258
298
let command = command
259
299
. stdin ( Stdio :: piped ( ) )
260
300
. stdout ( Stdio :: piped ( ) )
261
- . stderr ( Stdio :: piped ( ) ) ;
262
- let command = command. args ( & args) ;
301
+ . stderr ( Stdio :: piped ( ) )
302
+ . env_clear ( )
303
+ . envs ( self . env . clone ( ) . compile ( ) )
304
+ . args ( & args) ;
305
+
263
306
let command = match self . current_dir {
264
307
Some ( ref dir) => command. current_dir ( dir) ,
265
308
None => command,
@@ -426,3 +469,168 @@ impl OutputAssertionBuilder {
426
469
self . not ( ) . is ( output)
427
470
}
428
471
}
472
+
473
+ #[ cfg( test) ]
474
+ mod test {
475
+ use super :: * ;
476
+ use std:: ffi:: OsString ;
477
+
478
+ fn command ( ) -> Assert {
479
+ Assert :: command ( & [ "printenv" ] )
480
+ }
481
+
482
+ #[ test]
483
+ fn take_ownership ( ) {
484
+ let x = Environment :: inherit ( ) ;
485
+
486
+ command ( ) . with_env ( x. clone ( ) ) . with_env ( & x) . with_env ( x) ;
487
+ }
488
+
489
+ #[ test]
490
+ fn in_place_mod ( ) {
491
+ let y = Environment :: empty ( ) ;
492
+
493
+ let y = y. insert ( "key" , "value" ) ;
494
+
495
+ assert_eq ! (
496
+ y. compile( ) ,
497
+ vec![ ( OsString :: from( "key" ) , OsString :: from( "value" ) ) ]
498
+ ) ;
499
+ }
500
+
501
+ #[ test]
502
+ fn in_place_mod2 ( ) {
503
+ let x = Environment :: inherit ( ) ;
504
+
505
+ command ( )
506
+ . with_env ( & x. insert ( "key" , "value" ) . insert ( "key" , "vv" ) )
507
+ . stdout ( )
508
+ . contains ( "key=vv" )
509
+ . execute ( )
510
+ . unwrap ( ) ;
511
+ // Granted, `insert` moved `x`, so we can no longer reference it, even
512
+ // though only a reference was passed to `with_env`
513
+ }
514
+
515
+ #[ test]
516
+ fn in_place_mod3 ( ) {
517
+ // In-place modification while allowing later accesses to the `Environment`
518
+ let y = Environment :: empty ( ) ;
519
+
520
+ assert_eq ! (
521
+ y. clone( ) . insert( "key" , "value" ) . compile( ) ,
522
+ vec![ ( OsString :: from( "key" ) , OsString :: from( "value" ) ) ]
523
+ ) ;
524
+
525
+ command ( )
526
+ . with_env ( y)
527
+ . stdout ( )
528
+ . not ( )
529
+ . contains ( "key=value" )
530
+ . execute ( )
531
+ . unwrap ( ) ;
532
+ }
533
+
534
+ #[ test]
535
+ fn empty_env ( ) {
536
+ // In-place modification while allowing later accesses to the `Environment`
537
+ let y = Environment :: empty ( ) ;
538
+
539
+ assert ! ( command( ) . with_env( y) . stdout( ) . is( "" ) . execute( ) . is_ok( ) ) ;
540
+ }
541
+ #[ test]
542
+ fn take_vec ( ) {
543
+ let v = vec ! [ ( "bar" . to_string( ) , "baz" . to_string( ) ) ] ;
544
+
545
+ command ( )
546
+ . with_env ( & vec ! [ ( "bar" , "baz" ) ] )
547
+ . stdout ( )
548
+ . contains ( "bar=baz" )
549
+ . execute ( )
550
+ . unwrap ( ) ;
551
+
552
+ command ( )
553
+ . with_env ( & v)
554
+ . stdout ( )
555
+ . contains ( "bar=baz" )
556
+ . execute ( )
557
+ . unwrap ( ) ;
558
+
559
+ command ( )
560
+ . with_env ( & vec ! [ ( "bar" , "baz" ) ] )
561
+ . stdout ( )
562
+ . isnt ( "" )
563
+ . execute ( )
564
+ . unwrap ( ) ;
565
+ }
566
+
567
+ #[ test]
568
+ fn take_slice_of_strs ( ) {
569
+ command ( )
570
+ . with_env ( & [ ( "bar" , "BAZ" ) ] )
571
+ . stdout ( )
572
+ . contains ( "bar=BAZ" )
573
+ . execute ( )
574
+ . unwrap ( ) ;
575
+
576
+ command ( )
577
+ . with_env ( & [ ( "bar" , "BAZ" ) ] [ ..] )
578
+ . stdout ( )
579
+ . contains ( "bar=BAZ" )
580
+ . execute ( )
581
+ . unwrap ( ) ;
582
+
583
+ command ( )
584
+ . with_env ( [ ( "bar" , "BAZ" ) ] . as_ref ( ) )
585
+ . stdout ( )
586
+ . contains ( "bar=BAZ" )
587
+ . execute ( )
588
+ . unwrap ( ) ;
589
+ }
590
+
591
+ #[ test]
592
+ fn take_slice_of_strings ( ) {
593
+ // same deal as above
594
+
595
+ command ( )
596
+ . with_env ( & [ ( "bar" . to_string ( ) , "BAZ" . to_string ( ) ) ] )
597
+ . stdout ( )
598
+ . contains ( "bar=BAZ" )
599
+ . execute ( )
600
+ . unwrap ( ) ;
601
+
602
+ command ( )
603
+ . with_env ( & [ ( "bar" . to_string ( ) , "BAZ" . to_string ( ) ) ] [ ..] )
604
+ . stdout ( )
605
+ . contains ( "bar=BAZ" )
606
+ . execute ( )
607
+ . unwrap ( ) ;
608
+ }
609
+
610
+ #[ test]
611
+ fn take_slice ( ) {
612
+ command ( )
613
+ . with_env ( & [ ( "hey" , "ho" ) ] )
614
+ . stdout ( )
615
+ . contains ( "hey=ho" )
616
+ . execute ( )
617
+ . unwrap ( ) ;
618
+
619
+ command ( )
620
+ . with_env ( & [ ( "hey" , "ho" . to_string ( ) ) ] )
621
+ . stdout ( )
622
+ . contains ( "hey=ho" )
623
+ . execute ( )
624
+ . unwrap ( ) ;
625
+ }
626
+
627
+ #[ test]
628
+ fn take_string_i32 ( ) {
629
+ command ( )
630
+ . with_env ( & [ ( "bar" , 3 as i32 ) ] )
631
+ . stdout ( )
632
+ . contains ( "bar=3" )
633
+ . execute ( )
634
+ . unwrap ( ) ;
635
+ }
636
+ }
0 commit comments