mirror of
https://github.com/roc-lang/roc.git
synced 2025-12-23 08:48:03 +00:00
Merge pull request #8527 from roc-lang/fix-str-split-on
Fix semantics for `Str.split_on`
This commit is contained in:
commit
b9d7371cd0
4 changed files with 79 additions and 1 deletions
|
|
@ -827,9 +827,9 @@ pub const Expr = union(enum) {
|
|||
.str_reserve => &.{ .consume, .borrow },
|
||||
.str_release_excess_capacity => &.{.consume},
|
||||
.str_join_with => &.{ .consume, .borrow }, // list consumed, separator borrowed
|
||||
.str_split_on => &.{ .consume, .borrow },
|
||||
|
||||
// String operations - borrowing with seamless slice result (incref internally)
|
||||
.str_split_on => &.{ .borrow, .borrow },
|
||||
.str_to_utf8 => &.{.borrow},
|
||||
.str_drop_prefix, .str_drop_suffix => &.{ .borrow, .borrow },
|
||||
|
||||
|
|
|
|||
|
|
@ -771,3 +771,45 @@ test "string literal pattern matching" {
|
|||
try testing.expect(has_alice);
|
||||
try testing.expect(has_bob);
|
||||
}
|
||||
|
||||
test "multiline string split_on" {
|
||||
// Tests splitting a multiline string and iterating over the lines.
|
||||
// This is a regression test to ensure split_on works correctly with
|
||||
// multiline strings and doesn't cause memory issues.
|
||||
const allocator = testing.allocator;
|
||||
|
||||
try ensureRocBinary(allocator);
|
||||
|
||||
const run_result = try std.process.Child.run(.{
|
||||
.allocator = allocator,
|
||||
.argv = &[_][]const u8{
|
||||
"./zig-out/bin/roc",
|
||||
"test/fx/multiline_split_leak.roc",
|
||||
},
|
||||
});
|
||||
defer allocator.free(run_result.stdout);
|
||||
defer allocator.free(run_result.stderr);
|
||||
|
||||
switch (run_result.term) {
|
||||
.Exited => |code| {
|
||||
if (code != 0) {
|
||||
std.debug.print("Run failed with exit code {}\n", .{code});
|
||||
std.debug.print("STDOUT: {s}\n", .{run_result.stdout});
|
||||
std.debug.print("STDERR: {s}\n", .{run_result.stderr});
|
||||
return error.RunFailed;
|
||||
}
|
||||
},
|
||||
else => {
|
||||
std.debug.print("Run terminated abnormally: {}\n", .{run_result.term});
|
||||
std.debug.print("STDOUT: {s}\n", .{run_result.stdout});
|
||||
std.debug.print("STDERR: {s}\n", .{run_result.stderr});
|
||||
return error.RunFailed;
|
||||
},
|
||||
}
|
||||
|
||||
// Verify the output contains lines from the multiline string
|
||||
try testing.expect(std.mem.indexOf(u8, run_result.stdout, "This is a longer line number one") != null);
|
||||
try testing.expect(std.mem.indexOf(u8, run_result.stdout, "This is a longer line number two") != null);
|
||||
try testing.expect(std.mem.indexOf(u8, run_result.stdout, "L68") != null);
|
||||
try testing.expect(std.mem.indexOf(u8, run_result.stdout, "The last line is here") != null);
|
||||
}
|
||||
|
|
|
|||
20
test/fx/multiline_split_leak.roc
Normal file
20
test/fx/multiline_split_leak.roc
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
app [main!] { pf: platform "./platform/main.roc" }
|
||||
|
||||
import pf.Stdout
|
||||
|
||||
input =
|
||||
\\This is a longer line number one
|
||||
\\This is a longer line number two
|
||||
\\L68
|
||||
\\L30
|
||||
\\R48
|
||||
\\L5
|
||||
\\R60
|
||||
\\L55
|
||||
\\L1
|
||||
\\The last line is here
|
||||
|
||||
main! = || {
|
||||
for line in input.split_on("\n")
|
||||
Stdout.line!(line)
|
||||
}
|
||||
16
test/snapshots/repl/multiline_string_split_7_lines.md
Normal file
16
test/snapshots/repl/multiline_string_split_7_lines.md
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
# META
|
||||
~~~ini
|
||||
description=Multiline string with 7 lines split - memory leak test
|
||||
type=repl
|
||||
~~~
|
||||
# SOURCE
|
||||
~~~roc
|
||||
» input = "L68\nL30\nR48\nL5\nR60\nL55\nL1"
|
||||
» input.split_on("\n")
|
||||
~~~
|
||||
# OUTPUT
|
||||
assigned `input`
|
||||
---
|
||||
["L68", "L30", "R48", "L5", "R60", "L55", "L1"]
|
||||
# PROBLEMS
|
||||
NIL
|
||||
Loading…
Add table
Add a link
Reference in a new issue