use super::super::*;
use super::create_test_targets;
#[test]
fn test_import_skips_duplicates_with_timestamp() {
use reedline::History;
use tempfile::TempDir;
let temp_dir = TempDir::new().unwrap();
let mut targets = create_test_targets(&temp_dir);
let ts = DateTime::parse_from_rfc3339("2024-06-15T14:30:45Z")
.unwrap()
.with_timezone(&Utc);
let entries = vec![ImportEntry {
command: "library(dplyr)".to_string(),
timestamp: Some(ts),
mode: Some("r".to_string()),
}];
let result = import_entries(&mut targets, entries, None, true).unwrap();
assert_eq!(result.r_imported, 1);
assert_eq!(result.duplicates_skipped, 0);
let entries = vec![ImportEntry {
command: "library(dplyr)".to_string(),
timestamp: Some(ts),
mode: Some("r".to_string()),
}];
let result = import_entries(&mut targets, entries, None, true).unwrap();
assert_eq!(result.r_imported, 0);
assert_eq!(result.duplicates_skipped, 1);
let query = reedline::SearchQuery::everything(reedline::SearchDirection::Backward, None);
let items = targets.r_history.search(query).unwrap();
assert_eq!(items.len(), 1);
}
#[test]
fn test_import_skips_duplicates_without_timestamp() {
use reedline::History;
use tempfile::TempDir;
let temp_dir = TempDir::new().unwrap();
let mut targets = create_test_targets(&temp_dir);
let entries = vec![ImportEntry {
command: "summary(iris)".to_string(),
timestamp: None,
mode: Some("r".to_string()),
}];
let result = import_entries(&mut targets, entries, None, true).unwrap();
assert_eq!(result.r_imported, 1);
assert_eq!(result.duplicates_skipped, 0);
let entries = vec![ImportEntry {
command: "summary(iris)".to_string(),
timestamp: None,
mode: Some("r".to_string()),
}];
let result = import_entries(&mut targets, entries, None, true).unwrap();
assert_eq!(result.r_imported, 0);
assert_eq!(result.duplicates_skipped, 1);
let query = reedline::SearchQuery::everything(reedline::SearchDirection::Backward, None);
let items = targets.r_history.search(query).unwrap();
assert_eq!(items.len(), 1);
}
#[test]
fn test_import_allows_same_command_different_timestamp() {
use reedline::History;
use tempfile::TempDir;
let temp_dir = TempDir::new().unwrap();
let mut targets = create_test_targets(&temp_dir);
let ts1 = DateTime::parse_from_rfc3339("2024-06-15T14:30:45Z")
.unwrap()
.with_timezone(&Utc);
let ts2 = DateTime::parse_from_rfc3339("2024-06-15T15:00:00Z")
.unwrap()
.with_timezone(&Utc);
let entries = vec![ImportEntry {
command: "library(dplyr)".to_string(),
timestamp: Some(ts1),
mode: Some("r".to_string()),
}];
let result = import_entries(&mut targets, entries, None, true).unwrap();
assert_eq!(result.r_imported, 1);
let entries = vec![ImportEntry {
command: "library(dplyr)".to_string(),
timestamp: Some(ts2),
mode: Some("r".to_string()),
}];
let result = import_entries(&mut targets, entries, None, true).unwrap();
assert_eq!(result.r_imported, 1);
assert_eq!(result.duplicates_skipped, 0);
let query = reedline::SearchQuery::everything(reedline::SearchDirection::Backward, None);
let items = targets.r_history.search(query).unwrap();
assert_eq!(items.len(), 2);
}
#[test]
fn test_import_duplicates_flag_disables_dedup() {
use reedline::History;
use tempfile::TempDir;
let temp_dir = TempDir::new().unwrap();
let mut targets = create_test_targets(&temp_dir);
let ts = DateTime::parse_from_rfc3339("2024-06-15T14:30:45Z")
.unwrap()
.with_timezone(&Utc);
let entries = vec![ImportEntry {
command: "library(dplyr)".to_string(),
timestamp: Some(ts),
mode: Some("r".to_string()),
}];
let result = import_entries(&mut targets, entries, None, false).unwrap();
assert_eq!(result.r_imported, 1);
let entries = vec![ImportEntry {
command: "library(dplyr)".to_string(),
timestamp: Some(ts),
mode: Some("r".to_string()),
}];
let result = import_entries(&mut targets, entries, None, false).unwrap();
assert_eq!(result.r_imported, 1);
assert_eq!(result.duplicates_skipped, 0);
let query = reedline::SearchQuery::everything(reedline::SearchDirection::Backward, None);
let items = targets.r_history.search(query).unwrap();
assert_eq!(items.len(), 2);
}
#[test]
fn test_import_dedup_works_per_database() {
use reedline::History;
use tempfile::TempDir;
let temp_dir = TempDir::new().unwrap();
let mut targets = create_test_targets(&temp_dir);
let entries = vec![ImportEntry {
command: "ls -la".to_string(),
timestamp: None,
mode: Some("r".to_string()),
}];
let result = import_entries(&mut targets, entries, None, true).unwrap();
assert_eq!(result.r_imported, 1);
let entries = vec![ImportEntry {
command: "ls -la".to_string(),
timestamp: None,
mode: Some("shell".to_string()),
}];
let result = import_entries(&mut targets, entries, None, true).unwrap();
assert_eq!(result.shell_imported, 1);
assert_eq!(result.duplicates_skipped, 0);
let r_query = reedline::SearchQuery::everything(reedline::SearchDirection::Backward, None);
let r_items = targets.r_history.search(r_query).unwrap();
assert_eq!(r_items.len(), 1);
let shell_query = reedline::SearchQuery::everything(reedline::SearchDirection::Backward, None);
let shell_items = targets.shell_history.search(shell_query).unwrap();
assert_eq!(shell_items.len(), 1);
}
#[test]
fn test_import_dry_run_with_dedup() {
use tempfile::TempDir;
let temp_dir = TempDir::new().unwrap();
let mut targets = create_test_targets(&temp_dir);
let ts = DateTime::parse_from_rfc3339("2024-06-15T14:30:45Z")
.unwrap()
.with_timezone(&Utc);
let entries = vec![ImportEntry {
command: "library(dplyr)".to_string(),
timestamp: Some(ts),
mode: Some("r".to_string()),
}];
import_entries(&mut targets, entries, None, false).unwrap();
let r_dedup = DedupSet::from_history(&targets.r_history).unwrap();
let shell_dedup = DedupSet::from_history(&targets.shell_history).unwrap();
let entries = vec![
ImportEntry {
command: "library(dplyr)".to_string(), timestamp: Some(ts),
mode: Some("r".to_string()),
},
ImportEntry {
command: "print(1)".to_string(), timestamp: None,
mode: Some("r".to_string()),
},
];
let result = import_entries_dry_run(&entries, Some(&r_dedup), Some(&shell_dedup));
assert_eq!(result.r_imported, 1);
assert_eq!(result.duplicates_skipped, 1);
}
#[test]
fn test_import_mixed_dedup_new_and_existing() {
use reedline::History;
use tempfile::TempDir;
let temp_dir = TempDir::new().unwrap();
let mut targets = create_test_targets(&temp_dir);
let ts = DateTime::parse_from_rfc3339("2024-06-15T14:30:45Z")
.unwrap()
.with_timezone(&Utc);
let entries = vec![ImportEntry {
command: "library(dplyr)".to_string(),
timestamp: Some(ts),
mode: Some("r".to_string()),
}];
import_entries(&mut targets, entries, None, false).unwrap();
let entries = vec![
ImportEntry {
command: "library(dplyr)".to_string(), timestamp: Some(ts),
mode: Some("r".to_string()),
},
ImportEntry {
command: "print(1)".to_string(), timestamp: None,
mode: Some("r".to_string()),
},
ImportEntry {
command: "git status".to_string(), timestamp: None,
mode: Some("shell".to_string()),
},
];
let result = import_entries(&mut targets, entries, None, true).unwrap();
assert_eq!(result.r_imported, 1);
assert_eq!(result.shell_imported, 1);
assert_eq!(result.duplicates_skipped, 1);
let r_query = reedline::SearchQuery::everything(reedline::SearchDirection::Backward, None);
let r_items = targets.r_history.search(r_query).unwrap();
assert_eq!(r_items.len(), 2);
let shell_query = reedline::SearchQuery::everything(reedline::SearchDirection::Backward, None);
let shell_items = targets.shell_history.search(shell_query).unwrap();
assert_eq!(shell_items.len(), 1);
}
#[test]
fn test_import_dry_run_with_partial_dedup() {
use tempfile::TempDir;
let temp_dir = TempDir::new().unwrap();
let mut targets = create_test_targets(&temp_dir);
let entries = vec![ImportEntry {
command: "library(dplyr)".to_string(),
timestamp: None,
mode: Some("r".to_string()),
}];
import_entries(&mut targets, entries, None, false).unwrap();
let r_dedup = DedupSet::from_history(&targets.r_history).unwrap();
let entries = vec![
ImportEntry {
command: "library(dplyr)".to_string(), timestamp: None,
mode: Some("r".to_string()),
},
ImportEntry {
command: "print(1)".to_string(), timestamp: None,
mode: Some("r".to_string()),
},
ImportEntry {
command: "ls -la".to_string(), timestamp: None,
mode: Some("shell".to_string()),
},
];
let result = import_entries_dry_run(&entries, Some(&r_dedup), None);
assert_eq!(result.r_imported, 1); assert_eq!(result.shell_imported, 1); assert_eq!(result.duplicates_skipped, 1); }
#[test]
fn test_import_skips_notimestamp_when_timestamped_exists() {
use reedline::History;
use tempfile::TempDir;
let temp_dir = TempDir::new().unwrap();
let mut targets = create_test_targets(&temp_dir);
let ts = DateTime::parse_from_rfc3339("2024-06-15T14:30:45Z")
.unwrap()
.with_timezone(&Utc);
let entries = vec![ImportEntry {
command: "library(dplyr)".to_string(),
timestamp: Some(ts),
mode: Some("r".to_string()),
}];
let result = import_entries(&mut targets, entries, None, true).unwrap();
assert_eq!(result.r_imported, 1);
let entries = vec![ImportEntry {
command: "library(dplyr)".to_string(),
timestamp: None,
mode: Some("r".to_string()),
}];
let result = import_entries(&mut targets, entries, None, true).unwrap();
assert_eq!(result.r_imported, 0);
assert_eq!(result.duplicates_skipped, 1);
let query = reedline::SearchQuery::everything(reedline::SearchDirection::Backward, None);
let items = targets.r_history.search(query).unwrap();
assert_eq!(items.len(), 1);
assert!(items[0].start_timestamp.is_some());
}
#[test]
fn test_from_db_matches_from_history() {
use tempfile::TempDir;
let temp_dir = TempDir::new().unwrap();
let mut targets = create_test_targets(&temp_dir);
let ts1 = Utc::now();
let ts2 = ts1 + chrono::Duration::seconds(60);
let entries = vec![
ImportEntry {
command: "library(dplyr)".to_string(),
timestamp: Some(ts1),
mode: Some("r".to_string()),
},
ImportEntry {
command: "print(1)".to_string(),
timestamp: Some(ts2),
mode: Some("r".to_string()),
},
ImportEntry {
command: "summary(iris)".to_string(),
timestamp: None, mode: Some("r".to_string()),
},
];
import_entries(&mut targets, entries, None, false).unwrap();
let r_path = temp_dir.path().join("r.db");
let from_history = DedupSet::from_history(&targets.r_history).unwrap();
let from_db = DedupSet::from_db(&r_path).unwrap();
assert_eq!(from_history.commands, from_db.commands);
assert_eq!(from_history.command_timestamps, from_db.command_timestamps);
assert!(from_history.is_duplicate("library(dplyr)", Some(&ts1)));
assert!(from_db.is_duplicate("library(dplyr)", Some(&ts1)));
assert!(!from_history.is_duplicate("new_cmd", None));
assert!(!from_db.is_duplicate("new_cmd", None));
assert!(from_history.is_duplicate("summary(iris)", None));
assert!(from_db.is_duplicate("summary(iris)", None));
}