use super::*;
use crate::ai::ai_state::lifecycle::TEST_MAX_CONTEXT_LENGTH;
use crate::ai::ai_state::{Suggestion, SuggestionType};
use insta::assert_snapshot;
use ratatui::Terminal;
use ratatui::backend::TestBackend;
use ratatui::layout::Rect;
fn create_test_terminal(width: u16, height: u16) -> Terminal<TestBackend> {
let backend = TestBackend::new(width, height);
Terminal::new(backend).unwrap()
}
fn render_ai_popup_to_string(ai_state: &mut AiState, width: u16, height: u16) -> String {
let mut terminal = create_test_terminal(width, height);
terminal
.draw(|f| {
let input_area = Rect {
x: 0,
y: height - 4,
width,
height: 3,
};
render_popup(ai_state, f, input_area);
})
.unwrap();
terminal.backend().to_string()
}
#[test]
fn snapshot_consistent_spacing_two_suggestions() {
let mut state = AiState::new_with_config(
true,
true,
"Anthropic".to_string(),
"claude-3-5-sonnet-20241022".to_string(),
TEST_MAX_CONTEXT_LENGTH,
);
state.visible = true;
state.response = "AI response".to_string();
state.suggestions = vec![
Suggestion {
query: ".first".to_string(),
description: "First suggestion".to_string(),
suggestion_type: SuggestionType::Fix,
},
Suggestion {
query: ".second".to_string(),
description: "Second suggestion".to_string(),
suggestion_type: SuggestionType::Next,
},
];
let output = render_ai_popup_to_string(&mut state, 100, 30);
assert_snapshot!(output);
}
#[test]
fn snapshot_consistent_spacing_three_suggestions() {
let mut state = AiState::new_with_config(
true,
true,
"Anthropic".to_string(),
"claude-3-5-sonnet-20241022".to_string(),
TEST_MAX_CONTEXT_LENGTH,
);
state.visible = true;
state.response = "AI response".to_string();
state.suggestions = vec![
Suggestion {
query: ".first".to_string(),
description: "First suggestion".to_string(),
suggestion_type: SuggestionType::Fix,
},
Suggestion {
query: ".second".to_string(),
description: "Second suggestion".to_string(),
suggestion_type: SuggestionType::Next,
},
Suggestion {
query: ".third".to_string(),
description: "Third suggestion".to_string(),
suggestion_type: SuggestionType::Optimize,
},
];
let output = render_ai_popup_to_string(&mut state, 100, 30);
assert_snapshot!(output);
}
#[test]
fn snapshot_consistent_spacing_five_suggestions() {
let mut state = AiState::new_with_config(
true,
true,
"Anthropic".to_string(),
"claude-3-5-sonnet-20241022".to_string(),
TEST_MAX_CONTEXT_LENGTH,
);
state.visible = true;
state.response = "AI response".to_string();
state.suggestions = vec![
Suggestion {
query: ".suggestion1".to_string(),
description: "Description 1".to_string(),
suggestion_type: SuggestionType::Fix,
},
Suggestion {
query: ".suggestion2".to_string(),
description: "Description 2".to_string(),
suggestion_type: SuggestionType::Next,
},
Suggestion {
query: ".suggestion3".to_string(),
description: "Description 3".to_string(),
suggestion_type: SuggestionType::Optimize,
},
Suggestion {
query: ".suggestion4".to_string(),
description: "Description 4".to_string(),
suggestion_type: SuggestionType::Fix,
},
Suggestion {
query: ".suggestion5".to_string(),
description: "Description 5".to_string(),
suggestion_type: SuggestionType::Next,
},
];
let output = render_ai_popup_to_string(&mut state, 100, 30);
assert_snapshot!(output);
}
#[test]
fn snapshot_spacing_with_varying_lengths() {
let mut state = AiState::new_with_config(
true,
true,
"Anthropic".to_string(),
"claude-3-5-sonnet-20241022".to_string(),
TEST_MAX_CONTEXT_LENGTH,
);
state.visible = true;
state.response = "AI response".to_string();
state.suggestions = vec![
Suggestion {
query: ".short".to_string(),
description: "Short".to_string(),
suggestion_type: SuggestionType::Fix,
},
Suggestion {
query: ".users[] | select(.active == true and .age > 18)".to_string(),
description: "This is a much longer description that wraps across multiple lines to test spacing consistency".to_string(),
suggestion_type: SuggestionType::Next,
},
Suggestion {
query: ".medium".to_string(),
description: "Medium length description here".to_string(),
suggestion_type: SuggestionType::Optimize,
},
];
let output = render_ai_popup_to_string(&mut state, 100, 30);
assert_snapshot!(output);
}
#[test]
fn snapshot_no_spacing_after_last_suggestion() {
let mut state = AiState::new_with_config(
true,
true,
"Anthropic".to_string(),
"claude-3-5-sonnet-20241022".to_string(),
TEST_MAX_CONTEXT_LENGTH,
);
state.visible = true;
state.response = "AI response".to_string();
state.suggestions = vec![
Suggestion {
query: ".first".to_string(),
description: "First".to_string(),
suggestion_type: SuggestionType::Fix,
},
Suggestion {
query: ".last".to_string(),
description: "Last suggestion should have no spacing after it".to_string(),
suggestion_type: SuggestionType::Next,
},
];
let output = render_ai_popup_to_string(&mut state, 100, 30);
assert!(output.contains("[Next] .last"));
assert_snapshot!(output);
}
#[test]
fn snapshot_spacing_maintained_with_first_option_selected() {
let mut state = AiState::new_with_config(
true,
true,
"Anthropic".to_string(),
"claude-3-5-sonnet-20241022".to_string(),
TEST_MAX_CONTEXT_LENGTH,
);
state.visible = true;
state.response = "AI response".to_string();
state.suggestions = vec![
Suggestion {
query: ".first".to_string(),
description: "First suggestion".to_string(),
suggestion_type: SuggestionType::Fix,
},
Suggestion {
query: ".second".to_string(),
description: "Second suggestion".to_string(),
suggestion_type: SuggestionType::Next,
},
Suggestion {
query: ".third".to_string(),
description: "Third suggestion".to_string(),
suggestion_type: SuggestionType::Optimize,
},
];
state.selection.select_index(0);
let output = render_ai_popup_to_string(&mut state, 100, 30);
assert_snapshot!(output);
}
#[test]
fn snapshot_spacing_maintained_with_middle_option_selected() {
let mut state = AiState::new_with_config(
true,
true,
"Anthropic".to_string(),
"claude-3-5-sonnet-20241022".to_string(),
TEST_MAX_CONTEXT_LENGTH,
);
state.visible = true;
state.response = "AI response".to_string();
state.suggestions = vec![
Suggestion {
query: ".first".to_string(),
description: "First suggestion".to_string(),
suggestion_type: SuggestionType::Fix,
},
Suggestion {
query: ".second".to_string(),
description: "Second suggestion".to_string(),
suggestion_type: SuggestionType::Next,
},
Suggestion {
query: ".third".to_string(),
description: "Third suggestion".to_string(),
suggestion_type: SuggestionType::Optimize,
},
];
state.selection.select_index(1);
let output = render_ai_popup_to_string(&mut state, 100, 30);
assert_snapshot!(output);
}
#[test]
fn snapshot_spacing_maintained_with_last_option_selected() {
let mut state = AiState::new_with_config(
true,
true,
"Anthropic".to_string(),
"claude-3-5-sonnet-20241022".to_string(),
TEST_MAX_CONTEXT_LENGTH,
);
state.visible = true;
state.response = "AI response".to_string();
state.suggestions = vec![
Suggestion {
query: ".first".to_string(),
description: "First suggestion".to_string(),
suggestion_type: SuggestionType::Fix,
},
Suggestion {
query: ".second".to_string(),
description: "Second suggestion".to_string(),
suggestion_type: SuggestionType::Next,
},
Suggestion {
query: ".third".to_string(),
description: "Third suggestion".to_string(),
suggestion_type: SuggestionType::Optimize,
},
];
state.selection.select_index(2);
let output = render_ai_popup_to_string(&mut state, 100, 30);
assert_snapshot!(output);
}