1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
//! `not_error` assertion rendering, split out of `r/assertions.rs` (already over the repo's
//! 1,000-line cap -- see `file-modularization` in CLAUDE.md) so this fix's regression coverage
//! has somewhere to live without growing an oversized file further. Mirrors
//! `swift/not_error_assertion.rs`'s split for the identical reason. ~keep
//!
//! ~keep The non-void arm used to emit a bare `expect_true(TRUE)` -- a testthat expectation
//! that cannot fail, i.e. no real check at all. The obvious replacement,
//! `expect_true(!is.null(result))`, is unsafe for two result shapes: a `result_is_simple`
//! extendr scalar return and a bare `result_is_option` (`Option<T>`) return can both
//! legitimately be R's "nothing here" on a *successful* call -- `Result<Option<T>, E>::Ok(None)`
//! is not an error, and asserting non-null there would fail correct binding behaviour. Swift's
//! `bare_result_is_option` (`swift/not_error_assertion.rs`) documents the identical trap for the
//! same reason.
//!
//! For those two shapes the real, failable check moves to the call site instead: `r/test_case.rs`
//! wraps the fallible call itself in testthat's `expect_no_error(...)` (verified empirically to
//! both propagate the call's return value on success, via `x <- expect_no_error(expr)`, and to
//! fail the test when `expr` raises) rather than asserting on a value whose emptiness is
//! sometimes the correct outcome. This module's `render` therefore renders nothing for either
//! shape -- not a vacuous placeholder, but a deliberate no-op because the real assertion already
//! ran one statement earlier. Every other (non-simple, non-option) shape gets the real,
//! non-vacuous `expect_true(!is.null(result))` check.
use Write as FmtWrite;
/// True when `result` may legitimately be R `NULL`/`NA` after a *successful* call under this
/// result shape, so a bare non-null check on it would reject correct behaviour.
///
/// Shared between this module's `render` (which must render nothing here rather than a false
/// check) and `r/test_case.rs` (which must wrap the call itself in `expect_no_error(...)` to
/// still leave a real check, and must not let its own vacuous-assertion fallback re-inject the
/// unsafe check this function exists to avoid). ~keep
pub
/// Render the `not_error` assertion for a non-void R call.
///
/// `returns_void` and `unsafe_for_null_check` are mutually exclusive real-check locations, not
/// two guards on the same one: a `returns_void` call binds no `result` at all (`test_case.rs`'s
/// `expect_no_error(function(...))`, no assignment), while an `unsafe_for_null_check` call still
/// binds `result` for other assertions to use but defers its `not_error` check to the same
/// `expect_no_error(...)` wrapper around the assignment's right-hand side. Both cases render
/// nothing here because the real, failable expectation already ran at the call site. ~keep
pub