1- capture_failure <- new_capture(" expectation_failure" )
2- capture_success <- function (expr ) {
1+ capture_success_failure <- function (expr ) {
32 cnd <- NULL
43
5- withCallingHandlers(
6- expr ,
7- expectation_failure = function (cnd ) {
8- invokeRestart(" continue_test" )
9- },
10- expectation_success = function (cnd ) {
11- cnd <<- cnd
12- }
4+ n_success <- 0
5+ n_failure <- 0
6+
7+ last_failure <- NULL
8+
9+ withRestarts(
10+ withCallingHandlers(
11+ expr ,
12+ expectation_failure = function (cnd ) {
13+ last_failure <<- cnd
14+ n_failure <<- n_failure + 1
15+ # Finish the test without bubbling up
16+ invokeRestart(" failed" )
17+ },
18+ expectation_success = function (cnd ) {
19+ n_success <<- n_success + 1
20+ # Don't bubble up to any other handlers
21+ invokeRestart(" continue_test" )
22+ }
23+ ),
24+ failed = function () {}
1325 )
14- cnd
15- }
1626
17- new_capture(" expectation_success" )
27+ list (n_success = n_success , n_failure = n_failure , last_failure = last_failure )
28+ }
1829
1930# ' Tools for testing expectations
2031# '
2132# ' @description
22- # ' * `expect_success()` and `expect_failure()` check that there's at least
23- # ' one success or failure respectively.
24- # ' * `expect_snapshot_failure()` records the failure message so that you can
25- # ' manually check that it is informative.
26- # ' * `expect_no_success()` and `expect_no_failure()` check that are no
27- # ' successes or failures.
33+ # ' `expect_success()` checks that there's exactly one success and no failures;
34+ # ' `expect_failure()` checks that there's exactly one failure and no successes.
35+ # ' `expect_snapshot_failure()` records the failure message so that you can
36+ # ' manually check that it is informative.
2837# '
2938# ' Use `show_failure()` in examples to print the failure message without
3039# ' throwing an error.
@@ -34,41 +43,40 @@ new_capture("expectation_success")
3443# ' @param ... Other arguments passed on to [expect_match()].
3544# ' @export
3645expect_success <- function (expr ) {
37- exp <- capture_success (expr )
46+ status <- capture_success_failure (expr )
3847
39- if (is.null(exp )) {
40- fail(" Expectation did not succeed" )
41- } else {
48+ if (status $ n_success == 1 && status $ n_failure == 0 ) {
4249 succeed()
50+ } else if (status $ n_success == 0 ) {
51+ fail(" Expectation did not succeed" )
52+ } else if (status $ n_success > 1 ) {
53+ fail(sprintf(" Expectation succeeded %i times, instead of once" , status $ n_success ))
54+ } else if (status $ n_failure > 0 ) {
55+ fail(sprintf(" Expectation failed %i times, instead of zero" , status $ n_failure ))
4356 }
44- invisible (NULL )
45- }
4657
47- # ' @export
48- # ' @rdname expect_success
49- expect_no_success <- function (expr ) {
50- exp <- capture_success(expr )
51-
52- if (! is.null(exp )) {
53- fail(" Expectation succeeded" )
54- } else {
55- succeed()
56- }
5758 invisible (NULL )
5859}
5960
6061# ' @export
6162# ' @rdname expect_success
6263expect_failure <- function (expr , message = NULL , ... ) {
63- exp <- capture_failure (expr )
64+ status <- capture_success_failure (expr )
6465
65- if (is.null(exp )) {
66+ if (status $ n_failure == 1 && status $ n_success == 0 ) {
67+ if (! is.null(message )) {
68+ return (expect_match(status $ last_failure $ message , message , ... ))
69+ }
70+ } else if (status $ n_failure == 0 ) {
6671 fail(" Expectation did not fail" )
67- } else if (! is.null(message )) {
68- expect_match(exp $ message , message , ... )
69- } else {
70- succeed()
72+ } else if (status $ n_failure > 1 ) {
73+ # This should be impossible, but including for completeness
74+ fail(" Expectation failed more than once" )
75+ } else if (status $ n_success != 0 ) {
76+ fail(sprintf(" Expectation succeeded %i times, instead of never" , status $ n_success ))
7177 }
78+
79+ succeed()
7280 invisible (NULL )
7381}
7482
@@ -78,12 +86,36 @@ expect_snapshot_failure <- function(expr) {
7886 expect_snapshot_error(expr , " expectation_failure" )
7987}
8088
89+ # ' Test for absence of success or failure
90+ # '
91+ # ' @description
92+ # ' `r lifecycle::badge("deprecated")`
93+ # '
94+ # ' These functions are deprecated because [expect_success()] and
95+ # ' [expect_failure()] now test for exactly one success or no failures, and
96+ # ' exactly one failure and no successes.
97+ # '
98+ # ' @keywords internal
8199# ' @export
82- # ' @rdname expect_success
100+ expect_no_success <- function (expr ) {
101+ lifecycle :: deprecate_warn(" 3.3.0" , " expect_no_success()" , " expect_failure()" )
102+ status <- capture_success_failure(expr )
103+
104+ if (status $ n_success > 0 ) {
105+ fail(" Expectation succeeded" )
106+ } else {
107+ succeed()
108+ }
109+ invisible (NULL )
110+ }
111+
112+ # ' @export
113+ # ' @rdname expect_no_success
83114expect_no_failure <- function (expr ) {
84- exp <- capture_failure(expr )
115+ lifecycle :: deprecate_warn(" 3.3.0" , " expect_no_failure()" , " expect_success()" )
116+ status <- capture_success_failure(expr )
85117
86- if (! is.null( exp ) ) {
118+ if (status $ n_failure > 0 ) {
87119 fail(" Expectation failed" )
88120 } else {
89121 succeed()
0 commit comments