Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .config/jp/tools/src/fs/grep_files_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,8 @@ async fn test_grep_files() {

let matches = fs_grep_files(root, pattern.to_owned(), Some(5), paths)
.await
.unwrap();
.unwrap()
.replace('\\', "/");

assert_eq!(matches, expected.join(""), "test case: {name}");
}
Expand Down
10 changes: 9 additions & 1 deletion .config/jp/tools/src/fs/list_files.rs
Original file line number Diff line number Diff line change
Expand Up @@ -189,7 +189,15 @@ mod tests {

let files = fs_list_files(root, prefixes, extensions).await.unwrap();

assert_eq!(files.into_files(), expected, "test case: {name}");
assert_eq!(
files
.into_files()
.into_iter()
.map(|s| s.replace('\\', "/"))
.collect::<Vec<_>>(),
expected,
"test case: {name}"
);
}
}

Expand Down
6 changes: 6 additions & 0 deletions .config/jp/tools/src/fs/modify_file_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -123,8 +123,14 @@ fn test_validate_patterns() {

#[test]
fn test_validate_path() {
#[rustfmt::skip]
let cases = [
#[cfg(unix)]
("absolute", "/absolute/path", Err("Path must be relative.")),

#[cfg(windows)]
("absolute", "c:/absolute/path", Err("Path must be relative.")),

("relative", "src/main.rs", Ok(())),
];

Expand Down
4 changes: 4 additions & 0 deletions crates/jp_cli/src/cmd/query/interrupt/signals.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ pub fn handle_streaming_signal(
info!(?signal, "Received signal during streaming.");

match signal {
#[cfg(any(unix, test))]
SignalTo::Quit => {
// Treat Quit like Stop: save partial content and exit gracefully.
// This ensures we don't lose progress on hard quit signals.
Expand Down Expand Up @@ -81,6 +82,7 @@ pub fn handle_streaming_signal(
}
}

#[cfg(any(unix, test))]
SignalTo::ReloadFromDisk => LoopAction::Continue,
}
}
Expand Down Expand Up @@ -140,6 +142,7 @@ pub fn handle_tool_signal(
backend: &dyn PromptBackend,
) -> ToolSignalResult {
match signal {
#[cfg(any(unix, test))]
SignalTo::Quit => {
// For hard quit during tool execution, we cancel and let the normal
// flow handle persistence (responses will be cancelled).
Expand Down Expand Up @@ -177,6 +180,7 @@ pub fn handle_tool_signal(
}
}

#[cfg(any(unix, test))]
SignalTo::ReloadFromDisk => ToolSignalResult::Continue,
}
}
Expand Down
13 changes: 9 additions & 4 deletions crates/jp_cli/src/cmd/query/tool/renderer_tests.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use std::{sync::Arc, time::Duration};

use camino_tempfile::Utf8TempDir;
use jp_config::{
AppConfig,
conversation::tool::{CommandConfigOrString, style::ParametersStyle},
Expand Down Expand Up @@ -228,9 +229,11 @@ async fn test_format_args_function_call() {
#[tokio::test]
async fn test_format_args_custom_with_echo() {
let mut args = Map::new();
args.insert("path".into(), Value::String("/tmp/test.txt".into()));
let root = Utf8TempDir::new().unwrap();
let path = root.path().join("test.txt");
args.insert("path".into(), Value::String(path.into()));
let style = ParametersStyle::Custom(CommandConfigOrString::String("echo custom-output".into()));
let result = format_args("my_tool", &args, &style, Utf8Path::new("/tmp"))
let result = format_args("my_tool", &args, &style, root.path())
.await
.unwrap();
assert_eq!(result, ":\n\ncustom-output");
Expand All @@ -239,9 +242,11 @@ async fn test_format_args_custom_with_echo() {
#[tokio::test]
async fn test_format_args_custom_empty_output_returns_empty() {
let mut args = Map::new();
args.insert("path".into(), Value::String("/tmp/test.txt".into()));
let root = Utf8TempDir::new().unwrap();
let path = root.path().join("test.txt");
args.insert("path".into(), Value::String(path.into()));
let style = ParametersStyle::Custom(CommandConfigOrString::String("true".into()));
let result = format_args("my_tool", &args, &style, Utf8Path::new("/tmp"))
let result = format_args("my_tool", &args, &style, root.path())
.await
.unwrap();
assert_eq!(result, "");
Expand Down
2 changes: 2 additions & 0 deletions crates/jp_cli/src/cmd/query/turn/coordinator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -283,6 +283,7 @@ impl TurnCoordinator {
///
/// Used when handling hard quit signals (SIGQUIT) where we want to save
/// progress and exit gracefully without showing an interrupt menu.
#[cfg(any(unix, test))]
pub fn force_complete(&mut self) {
self.state = TurnPhase::Complete;
}
Expand All @@ -291,6 +292,7 @@ impl TurnCoordinator {
///
/// Injects any partial content into the stream and transitions to
/// Complete so that the turn loop persists and exits.
#[cfg(any(unix, test))]
pub fn handle_quit(&mut self, stream: &mut ConversationStream) {
if let Some(content) = self.peek_partial_content() {
self.push_event(stream, ChatResponse::message(&content));
Expand Down
8 changes: 6 additions & 2 deletions crates/jp_cli/src/signals.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
use async_stream::stream;
use futures::{Stream, StreamExt as _};
use tokio::{runtime::Runtime, sync::broadcast};
use tracing::{error, info};
use tracing::error;
#[cfg(unix)]
use tracing::info;

pub type ShutdownTx = broadcast::Sender<()>;
pub type SignalTx = broadcast::Sender<SignalTo>;
Expand All @@ -11,10 +13,12 @@ pub type SignalRx = broadcast::Receiver<SignalTo>;
#[derive(Debug, Clone, Copy, PartialEq)]
pub enum SignalTo {
/// Reload config from the filesystem.
#[cfg(any(unix, test))]
ReloadFromDisk,
/// Shutdown process, with a grace period.
Shutdown,
/// Shutdown process immediately.
#[cfg(any(unix, test))]
Quit,
}

Expand Down Expand Up @@ -153,7 +157,7 @@ fn os_signals() -> impl Stream<Item = SignalTo> {

stream! {
loop {
let signal = tokio::signal::ctrl_c().map(|_| SignalTo::Shutdown(None)).await;
let signal = tokio::signal::ctrl_c().map(|_| SignalTo::Shutdown).await;

yield signal;
}
Expand Down
1 change: 1 addition & 0 deletions crates/jp_config/src/util_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -280,6 +280,7 @@ fn test_load_partial_at_path() {
}

#[test]
#[cfg_attr(windows, ignore = "overflows the stack on Windows")]
fn test_load_partial_at_path_recursive() {
struct TestCase {
files: Vec<(&'static str, &'static str)>,
Expand Down
9 changes: 9 additions & 0 deletions crates/jp_llm/src/test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -320,13 +320,22 @@ pub async fn run_chat_completion(

if !recording {
// dummy api key value when replaying a cassette
#[cfg(unix)]
match provider_id {
ProviderId::Anthropic => config.anthropic.api_key_env = "USER".to_owned(),
ProviderId::Google => config.google.api_key_env = "USER".to_owned(),
ProviderId::Openai => config.openai.api_key_env = "USER".to_owned(),
ProviderId::Openrouter => config.openrouter.api_key_env = "USER".to_owned(),
_ => {}
}
#[cfg(windows)]
match provider_id {
ProviderId::Anthropic => config.anthropic.api_key_env = "USERNAME".to_owned(),
ProviderId::Google => config.google.api_key_env = "USERNAME".to_owned(),
ProviderId::Openai => config.openai.api_key_env = "USERNAME".to_owned(),
ProviderId::Openrouter => config.openrouter.api_key_env = "USERNAME".to_owned(),
_ => {}
}
}

let provider = get_provider(provider_id, &config).unwrap();
Expand Down
2 changes: 1 addition & 1 deletion crates/jp_workspace/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -764,7 +764,7 @@ mod tests {
}
}

let result = Workspace::find_root(cwd, case.workspace_dir_name.unwrap_or("default"));
let result = Workspace::find_root(cwd, case.workspace_dir_name.unwrap_or("non-exist"));
assert_eq!(result, expected, "Failed test case: {name}");
}
}
Expand Down