Skip to content

Commit 3d2942b

Browse files
committed
Add test_utils module and improve thread-safety documentation
- Enhanced crate-level documentation with prominent thread-safety section - Added Thread Safety section to init() documentation - Created test_utils module with setup() function for test convenience - Added examples showing how to configure single-threaded test execution The test_utils::setup() function provides a well-documented entry point for tests, making the single-threaded requirement more discoverable.
1 parent 4b5419a commit 3d2942b

1 file changed

Lines changed: 64 additions & 5 deletions

File tree

src/lib.rs

Lines changed: 64 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -20,11 +20,17 @@
2020
//! println!("{}", json);
2121
//! ```
2222
//!
23-
//! # Safety
23+
//! # Thread Safety
2424
//!
25-
//! This crate uses FFI to call into GNU Bash's C code. The parser
26-
//! uses global state, so parsing is not thread-safe. All parsing
27-
//! should be done from a single thread.
25+
//! **Important:** This crate is NOT thread-safe. The underlying bash parser
26+
//! uses global state that cannot be safely accessed from multiple threads.
27+
//!
28+
//! - Call [`init()`] once from your main thread before parsing
29+
//! - Perform all parsing operations from a single thread
30+
//! - For tests, set `RUST_TEST_THREADS=1` or use `cargo test -- --test-threads=1`
31+
//!
32+
//! The [`init()`] function uses `std::sync::Once` internally, making it safe
33+
//! to call multiple times (subsequent calls are no-ops).
2834
//!
2935
//! # License
3036
//!
@@ -75,18 +81,71 @@ pub enum ParseError {
7581
/// This must be called once before any parsing operations.
7682
/// It is safe to call multiple times - subsequent calls are no-ops.
7783
///
84+
/// # Thread Safety
85+
///
86+
/// While this function is safe to call from multiple threads (it uses
87+
/// `std::sync::Once` internally), the actual parsing operations are
88+
/// NOT thread-safe. Call this from your main thread, then ensure all
89+
/// parsing happens on a single thread.
90+
///
7891
/// # Example
7992
///
8093
/// ```no_run
8194
/// use bash_ast::init;
8295
///
8396
/// init();
84-
/// // Now you can parse scripts
97+
/// // Now you can parse scripts (from a single thread)
8598
/// ```
8699
pub fn init() {
87100
bash_init::init();
88101
}
89102

103+
/// Test utilities for bash-ast
104+
///
105+
/// This module provides helper functions for writing tests that use bash-ast.
106+
/// These utilities handle initialization and provide better error messages.
107+
///
108+
/// # Example
109+
///
110+
/// ```no_run
111+
/// use bash_ast::test_utils;
112+
///
113+
/// #[test]
114+
/// fn my_test() {
115+
/// test_utils::setup();
116+
/// // Your test code here
117+
/// }
118+
/// ```
119+
pub mod test_utils {
120+
use super::init;
121+
122+
/// Initialize bash for testing
123+
///
124+
/// This is a convenience function for tests that calls [`init()`].
125+
/// It's safe to call multiple times.
126+
///
127+
/// **Important:** Tests using bash-ast must run single-threaded.
128+
/// Configure this via:
129+
/// - `.cargo/config.toml`: `RUST_TEST_THREADS = "1"`
130+
/// - Command line: `cargo test -- --test-threads=1`
131+
///
132+
/// # Example
133+
///
134+
/// ```no_run
135+
/// use bash_ast::test_utils;
136+
///
137+
/// #[test]
138+
/// fn test_parsing() {
139+
/// test_utils::setup();
140+
/// let result = bash_ast::parse("echo hello");
141+
/// assert!(result.is_ok());
142+
/// }
143+
/// ```
144+
pub fn setup() {
145+
init();
146+
}
147+
}
148+
90149
/// Parse a bash script and return the AST
91150
///
92151
/// # Arguments

0 commit comments

Comments
 (0)