1
1
use environment:: Environment ;
2
2
use error_chain:: ChainedError ;
3
3
use errors:: * ;
4
- use output:: { OutputAssertion , OutputKind } ;
4
+ use output:: { Content , Output , OutputKind , OutputPredicate } ;
5
5
use std:: default;
6
6
use std:: ffi:: { OsStr , OsString } ;
7
7
use std:: io:: Write ;
@@ -18,8 +18,8 @@ pub struct Assert {
18
18
current_dir : Option < PathBuf > ,
19
19
expect_success : Option < bool > ,
20
20
expect_exit_code : Option < i32 > ,
21
- expect_output : Vec < OutputAssertion > ,
22
- stdin_contents : Option < String > ,
21
+ expect_output : Vec < OutputPredicate > ,
22
+ stdin_contents : Option < Vec < u8 > > ,
23
23
}
24
24
25
25
impl default:: Default for Assert {
@@ -118,8 +118,8 @@ impl Assert {
118
118
/// .stdout().contains("42")
119
119
/// .unwrap();
120
120
/// ```
121
- pub fn stdin ( mut self , contents : & str ) -> Self {
122
- self . stdin_contents = Some ( String :: from ( contents) ) ;
121
+ pub fn stdin < S : Into < Vec < u8 > > > ( mut self , contents : S ) -> Self {
122
+ self . stdin_contents = Some ( contents. into ( ) ) ;
123
123
self
124
124
}
125
125
@@ -289,7 +289,6 @@ impl Assert {
289
289
OutputAssertionBuilder {
290
290
assertion : self ,
291
291
kind : OutputKind :: StdOut ,
292
- expected_result : true ,
293
292
}
294
293
}
295
294
@@ -310,7 +309,6 @@ impl Assert {
310
309
OutputAssertionBuilder {
311
310
assertion : self ,
312
311
kind : OutputKind :: StdErr ,
313
- expected_result : true ,
314
312
}
315
313
}
316
314
@@ -327,10 +325,10 @@ impl Assert {
327
325
/// assert!(test.is_ok());
328
326
/// ```
329
327
pub fn execute ( self ) -> Result < ( ) > {
330
- let cmd = & self . cmd [ 0 ] ;
328
+ let bin = & self . cmd [ 0 ] ;
331
329
332
330
let args: Vec < _ > = self . cmd . iter ( ) . skip ( 1 ) . collect ( ) ;
333
- let mut command = Command :: new ( cmd ) ;
331
+ let mut command = Command :: new ( bin ) ;
334
332
let command = command
335
333
. stdin ( Stdio :: piped ( ) )
336
334
. stdout ( Stdio :: piped ( ) )
@@ -353,38 +351,34 @@ impl Assert {
353
351
. stdin
354
352
. as_mut ( )
355
353
. expect ( "Couldn't get mut ref to command stdin" )
356
- . write_all ( contents. as_bytes ( ) ) ?;
354
+ . write_all ( contents) ?;
357
355
}
358
356
let output = spawned. wait_with_output ( ) ?;
359
357
360
358
if let Some ( expect_success) = self . expect_success {
361
359
if expect_success != output. status . success ( ) {
362
360
let out = String :: from_utf8_lossy ( & output. stdout ) . to_string ( ) ;
363
361
let err = String :: from_utf8_lossy ( & output. stderr ) . to_string ( ) ;
364
- bail ! ( ErrorKind :: StatusMismatch (
365
- self . cmd. clone( ) ,
366
- expect_success,
367
- out,
368
- err,
369
- ) ) ;
362
+ let err: Error = ErrorKind :: StatusMismatch ( expect_success, out, err) . into ( ) ;
363
+ bail ! ( err. chain_err( || ErrorKind :: AssertionFailed ( self . cmd. clone( ) ) ) ) ;
370
364
}
371
365
}
372
366
373
367
if self . expect_exit_code . is_some ( ) && self . expect_exit_code != output. status . code ( ) {
374
368
let out = String :: from_utf8_lossy ( & output. stdout ) . to_string ( ) ;
375
369
let err = String :: from_utf8_lossy ( & output. stderr ) . to_string ( ) ;
376
- bail ! ( ErrorKind :: ExitCodeMismatch (
377
- self . cmd. clone( ) ,
378
- self . expect_exit_code,
379
- output. status. code( ) ,
380
- out,
381
- err,
382
- ) ) ;
370
+ let err: Error =
371
+ ErrorKind :: ExitCodeMismatch ( self . expect_exit_code , output. status . code ( ) , out, err)
372
+ . into ( ) ;
373
+ bail ! ( err. chain_err( || ErrorKind :: AssertionFailed ( self . cmd. clone( ) ) ) ) ;
383
374
}
384
375
385
376
self . expect_output
386
377
. iter ( )
387
- . map ( |a| a. execute ( & output, & self . cmd ) )
378
+ . map ( |a| {
379
+ a. verify ( & output)
380
+ . chain_err ( || ErrorKind :: AssertionFailed ( self . cmd . clone ( ) ) )
381
+ } )
388
382
. collect :: < Result < Vec < ( ) > > > ( ) ?;
389
383
390
384
Ok ( ( ) )
@@ -414,98 +408,96 @@ impl Assert {
414
408
pub struct OutputAssertionBuilder {
415
409
assertion : Assert ,
416
410
kind : OutputKind ,
417
- expected_result : bool ,
418
411
}
419
412
420
413
impl OutputAssertionBuilder {
421
- /// Negate the assertion predicate
414
+ /// Expect the command's output to **contain** `output`.
422
415
///
423
416
/// # Examples
424
417
///
425
418
/// ```rust
426
419
/// extern crate assert_cli;
427
420
///
428
421
/// assert_cli::Assert::command(&["echo", "42"])
429
- /// .stdout().not(). contains("73 ")
422
+ /// .stdout().contains("42 ")
430
423
/// .unwrap();
431
424
/// ```
432
- // No clippy, we don't want to implement std::ops::Not :)
433
- #[ cfg_attr( feature = "cargo-clippy" , allow( should_implement_trait) ) ]
434
- pub fn not ( mut self ) -> Self {
435
- self . expected_result = !self . expected_result ;
436
- self
425
+ pub fn contains < O : Into < Content > > ( mut self , output : O ) -> Assert {
426
+ let pred = OutputPredicate :: new ( self . kind , Output :: contains ( output) ) ;
427
+ self . assertion . expect_output . push ( pred) ;
428
+ self . assertion
437
429
}
438
430
439
- /// Expect the command's output to **contain** `output`.
431
+ /// Expect the command to output **exactly** this `output`.
440
432
///
441
433
/// # Examples
442
434
///
443
435
/// ```rust
444
436
/// extern crate assert_cli;
445
437
///
446
438
/// assert_cli::Assert::command(&["echo", "42"])
447
- /// .stdout().contains ("42")
439
+ /// .stdout().is ("42")
448
440
/// .unwrap();
449
441
/// ```
450
- pub fn contains < O : Into < String > > ( mut self , output : O ) -> Assert {
451
- self . assertion . expect_output . push ( OutputAssertion {
452
- expect : output. into ( ) ,
453
- fuzzy : true ,
454
- expected_result : self . expected_result ,
455
- kind : self . kind ,
456
- } ) ;
442
+ pub fn is < O : Into < Content > > ( mut self , output : O ) -> Assert {
443
+ let pred = OutputPredicate :: new ( self . kind , Output :: is ( output) ) ;
444
+ self . assertion . expect_output . push ( pred) ;
457
445
self . assertion
458
446
}
459
447
460
- /// Expect the command to output **exactly** this `output`.
448
+ /// Expect the command's output to not **contain** `output`.
461
449
///
462
450
/// # Examples
463
451
///
464
452
/// ```rust
465
453
/// extern crate assert_cli;
466
454
///
467
455
/// assert_cli::Assert::command(&["echo", "42"])
468
- /// .stdout().is("42 ")
456
+ /// .stdout().doesnt_contain("73 ")
469
457
/// .unwrap();
470
458
/// ```
471
- pub fn is < O : Into < String > > ( mut self , output : O ) -> Assert {
472
- self . assertion . expect_output . push ( OutputAssertion {
473
- expect : output. into ( ) ,
474
- fuzzy : false ,
475
- expected_result : self . expected_result ,
476
- kind : self . kind ,
477
- } ) ;
459
+ pub fn doesnt_contain < O : Into < Content > > ( mut self , output : O ) -> Assert {
460
+ let pred = OutputPredicate :: new ( self . kind , Output :: doesnt_contain ( output) ) ;
461
+ self . assertion . expect_output . push ( pred) ;
478
462
self . assertion
479
463
}
480
464
481
- /// Expect the command's output to not **contain** `output`.
465
+ /// Expect the command to output to not be **exactly** this `output`.
482
466
///
483
467
/// # Examples
484
468
///
485
469
/// ```rust
486
470
/// extern crate assert_cli;
487
471
///
488
472
/// assert_cli::Assert::command(&["echo", "42"])
489
- /// .stdout().doesnt_contain ("73")
473
+ /// .stdout().isnt ("73")
490
474
/// .unwrap();
491
475
/// ```
492
- pub fn doesnt_contain < O : Into < String > > ( self , output : O ) -> Assert {
493
- self . not ( ) . contains ( output)
476
+ pub fn isnt < O : Into < Content > > ( mut self , output : O ) -> Assert {
477
+ let pred = OutputPredicate :: new ( self . kind , Output :: isnt ( output) ) ;
478
+ self . assertion . expect_output . push ( pred) ;
479
+ self . assertion
494
480
}
495
481
496
- /// Expect the command to output to not be **exactly** this `output` .
482
+ /// Expect the command output to satisfy the given predicate .
497
483
///
498
484
/// # Examples
499
485
///
500
486
/// ```rust
501
487
/// extern crate assert_cli;
502
488
///
503
- /// assert_cli::Assert::command(&["echo", "42"])
504
- /// .stdout().isnt("73 ")
489
+ /// assert_cli::Assert::command(&["echo", "-n", " 42"])
490
+ /// .stdout().satisfies(|x| x.len() == 2, "bad length ")
505
491
/// .unwrap();
506
492
/// ```
507
- pub fn isnt < O : Into < String > > ( self , output : O ) -> Assert {
508
- self . not ( ) . is ( output)
493
+ pub fn satisfies < F , M > ( mut self , pred : F , msg : M ) -> Assert
494
+ where
495
+ F : ' static + Fn ( & str ) -> bool ,
496
+ M : Into < String > ,
497
+ {
498
+ let pred = OutputPredicate :: new ( self . kind , Output :: satisfies ( pred, msg) ) ;
499
+ self . assertion . expect_output . push ( pred) ;
500
+ self . assertion
509
501
}
510
502
}
511
503
@@ -522,7 +514,11 @@ mod test {
522
514
fn take_ownership ( ) {
523
515
let x = Environment :: inherit ( ) ;
524
516
525
- command ( ) . with_env ( x. clone ( ) ) . with_env ( & x) . with_env ( x) ;
517
+ command ( )
518
+ . with_env ( x. clone ( ) )
519
+ . with_env ( & x)
520
+ . with_env ( x)
521
+ . unwrap ( ) ;
526
522
}
527
523
528
524
#[ test]
@@ -564,8 +560,7 @@ mod test {
564
560
command ( )
565
561
. with_env ( y)
566
562
. stdout ( )
567
- . not ( )
568
- . contains ( "key=value" )
563
+ . doesnt_contain ( "key=value" )
569
564
. execute ( )
570
565
. unwrap ( ) ;
571
566
}
0 commit comments