Skip to content

Commit 58e0c35

Browse files
committed
handled more edge cases and more tests
1 parent df29716 commit 58e0c35

File tree

1 file changed

+99
-7
lines changed

1 file changed

+99
-7
lines changed

src/main.rs

Lines changed: 99 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -282,8 +282,12 @@ fn apply_range<T: Clone>(items: &[T], range: &RangeSpec) -> Vec<T> {
282282
let len = items.len();
283283
match range {
284284
RangeSpec::Index(idx) => {
285+
// Handle empty collections
286+
if len == 0 {
287+
return vec![];
288+
}
285289
let mut i = resolve_index(*idx, len);
286-
if i >= len && len > 0 {
290+
if i >= len {
287291
i = len - 1;
288292
}
289293
items.get(i).cloned().map_or(vec![], |v| vec![v])
@@ -429,6 +433,9 @@ fn apply_ops(input: &str, ops: &[StringOp]) -> Result<String, String> {
429433
},
430434
}
431435
}
436+
437+
// Note: If the final value is a List, we join using the last split separator
438+
// or a space if no split operation was performed
432439
Ok(match val {
433440
Value::Str(s) => s,
434441
Value::List(list) => list.join(last_split_sep.as_deref().unwrap_or(" ")),
@@ -769,18 +776,21 @@ mod tests {
769776
);
770777
}
771778

779+
// New edge case tests
772780
#[test]
773781
fn test_empty_operations() {
774-
// Empty template should be handled
775-
assert!(process("test", "{}").is_ok());
782+
// Empty template should return the input as-is
783+
assert_eq!(process("test", "{}").unwrap(), "test");
776784
}
777785

778786
#[test]
779787
fn test_invalid_range_edge_cases() {
780788
// Test what happens with very large indices
781789
assert_eq!(process("a,b,c", "{split:,:100}").unwrap(), "c");
782-
// Test empty range
790+
// Test empty range (start > end)
783791
assert_eq!(process("a,b,c", "{split:,:3..1}").unwrap(), "");
792+
// Test range that starts beyond bounds
793+
assert_eq!(process("a,b,c", "{split:,:10..20}").unwrap(), "");
784794
}
785795

786796
#[test]
@@ -795,16 +805,98 @@ mod tests {
795805
assert_eq!(process("hello", "{strip:}").unwrap(), "hello");
796806
}
797807

808+
#[test]
809+
fn test_slice_empty_string() {
810+
assert_eq!(process("", "{slice:0}").unwrap(), "");
811+
assert_eq!(process("", "{slice:-1}").unwrap(), "");
812+
assert_eq!(process("", "{slice:1..3}").unwrap(), "");
813+
assert_eq!(process("", "{slice:..}").unwrap(), "");
814+
}
815+
816+
#[test]
817+
fn test_slice_empty_list() {
818+
// Split an empty string creates empty list
819+
assert_eq!(process("", "{split:,:..:slice:0}").unwrap(), "");
820+
assert_eq!(process("", "{split:,:..:slice:1..3}").unwrap(), "");
821+
}
822+
798823
#[test]
799824
fn test_invalid_regex() {
800825
// Should handle invalid regex gracefully
801826
assert!(process("test", "{replace:s/[/replacement/}").is_err());
827+
assert!(process("test", "{replace:s/*/replacement/}").is_err());
802828
}
803829

804830
#[test]
805-
fn test_slice_empty_string() {
806-
assert_eq!(process("", "{slice:0}").unwrap(), "");
807-
assert_eq!(process("", "{slice:-1}").unwrap(), "");
831+
fn test_malformed_sed_strings() {
832+
// Missing closing slash
833+
assert!(process("test", "{replace:s/pattern/replacement}").is_err());
834+
// No pattern
835+
assert!(process("test", "{replace:s//replacement/}").is_err());
836+
// Wrong format entirely
837+
assert!(process("test", "{replace:pattern/replacement}").is_err());
838+
}
839+
840+
#[test]
841+
fn test_invalid_template_format() {
842+
// Missing braces
843+
assert!(process("test", "split:,:0").is_err());
844+
// Missing opening brace
845+
assert!(process("test", "split:,:0}").is_err());
846+
// Missing closing brace
847+
assert!(process("test", "{split:,:0").is_err());
848+
}
849+
850+
#[test]
851+
fn test_unknown_operation() {
852+
assert!(process("test", "{unknown}").is_err());
853+
assert!(process("test", "{badop:arg}").is_err());
854+
}
855+
856+
#[test]
857+
fn test_invalid_range_strings() {
858+
// Invalid range formats
859+
assert!(process("a,b,c", "{split:,:abc}").is_err());
860+
assert!(process("a,b,c", "{split:,:1..abc}").is_err());
861+
assert!(process("hello", "{slice:xyz}").is_err());
862+
}
863+
864+
#[test]
865+
fn test_large_indices_handling() {
866+
let input = "a,b,c";
867+
// Very large positive index should clamp to last element
868+
assert_eq!(process(input, "{split:,:999999}").unwrap(), "c");
869+
// Very large negative index should clamp to first element
870+
assert_eq!(process(input, "{split:,:-999999}").unwrap(), "a");
871+
}
872+
873+
#[test]
874+
fn test_operations_on_empty_list() {
875+
// Create empty list and apply operations
876+
let input = "";
877+
assert_eq!(process(input, "{split:,:..:upper}").unwrap(), "");
878+
assert_eq!(process(input, "{split:,:..:lower}").unwrap(), "");
879+
assert_eq!(process(input, "{split:,:..:trim}").unwrap(), "");
880+
assert_eq!(process(input, "{split:,:..:append:!}").unwrap(), "!");
881+
assert_eq!(process(input, "{split:,:..:prepend:_}").unwrap(), "_");
882+
}
883+
884+
#[test]
885+
fn test_final_output_behavior() {
886+
// Test documented behavior: List joins with last split separator or space
887+
let input = "a,b,c";
888+
889+
// With split operation - should use comma
890+
assert_eq!(process(input, "{split:,:..:upper}").unwrap(), "A,B,C");
891+
892+
// Without split operation - should use space (no split occurred)
893+
assert_eq!(process("hello world", "{upper}").unwrap(), "HELLO WORLD");
894+
895+
// Multiple splits - should use last split separator
896+
assert_eq!(
897+
process(input, "{split:,:..:join:-:split:-:..:upper}").unwrap(),
898+
"A-B-C"
899+
);
808900
}
809901
}
810902

0 commit comments

Comments
 (0)