116 lines
3.2 KiB
Plaintext
116 lines
3.2 KiB
Plaintext
// Vectors mirror ref/hare/strings/replace.ha where ww can express them.
|
|
// External strings_test package per the Go foo_test idiom (rule-5/9
|
|
// carve-out, task #16); the shared streq helper lives in
|
|
// helpers_test.ww — same-package test files compose in dir-mode
|
|
// (the package, not the file, is the unit of testing).
|
|
package strings_test;
|
|
|
|
import strings;
|
|
import os;
|
|
import test;
|
|
|
|
// ref/hare/strings/replace.ha:46 (#4). Hare rows 1-5 (target found
|
|
// once / multiple times / shorter / longer / multibyte) plus ww rows
|
|
// (no-match returns fresh copy, empty-replacement, result-shrinks-to-
|
|
// empty).
|
|
|
|
@test fn replace_cases() void = {
|
|
// Hare row 1: target found once.
|
|
match (strings.replace("Hello world!", "world", "there")) {
|
|
case let s: str => {
|
|
assert(!(!streq(s, "Hello there!")));
|
|
os.free(s.ptr: *void, s.len: u64);
|
|
};
|
|
case nomem => { abort(); };
|
|
};
|
|
|
|
// Hare row 2: needle found four times (replacement same length).
|
|
match (strings.replace("I like dogs, dogs, birds, dogs", "dogs", "cats")) {
|
|
case let s: str => {
|
|
assert(!(!streq(s, "I like cats, cats, birds, cats")));
|
|
os.free(s.ptr: *void, s.len: u64);
|
|
};
|
|
case nomem => { abort(); };
|
|
};
|
|
|
|
// Hare row 3: replacement shorter than needle, non-overlapping
|
|
// matches (Hare advances by needle.len, not 1).
|
|
match (strings.replace("aaaaaa", "aa", "a")) {
|
|
case let s: str => {
|
|
assert(!(!streq(s, "aaa")));
|
|
os.free(s.ptr: *void, s.len: u64);
|
|
};
|
|
case nomem => { abort(); };
|
|
};
|
|
|
|
// Hare row 4: replacement longer than needle.
|
|
match (strings.replace("aaa", "a", "aa")) {
|
|
case let s: str => {
|
|
assert(!(!streq(s, "aaaaaa")));
|
|
os.free(s.ptr: *void, s.len: u64);
|
|
};
|
|
case nomem => { abort(); };
|
|
};
|
|
|
|
// Hare row 5: multibyte UTF-8 (3-byte runes).
|
|
match (strings.replace("こんにちは", "にち", "ばん")) {
|
|
case let s: str => {
|
|
assert(!(!streq(s, "こんばんは")));
|
|
os.free(s.ptr: *void, s.len: u64);
|
|
};
|
|
case nomem => { abort(); };
|
|
};
|
|
|
|
// ww row 1: needle not found — fresh copy (distinct from
|
|
// borrowed input ptr).
|
|
let src: str = "hello world";
|
|
match (strings.replace(src, "xyz", "abc")) {
|
|
case let s: str => {
|
|
assert(!(!streq(s, "hello world")));
|
|
assert(!(s.ptr == src.ptr));
|
|
os.free(s.ptr: *void, s.len: u64);
|
|
};
|
|
case nomem => { abort(); };
|
|
};
|
|
|
|
// ww row 2: empty replacement — needle is removed.
|
|
match (strings.replace("foo-bar-baz", "-", "")) {
|
|
case let s: str => {
|
|
assert(!(!streq(s, "foobarbaz")));
|
|
os.free(s.ptr: *void, s.len: u64);
|
|
};
|
|
case nomem => { abort(); };
|
|
};
|
|
|
|
// ww row 3: result shrinks to empty — total==0 nil-alloc path.
|
|
match (strings.replace("aaaa", "aa", "")) {
|
|
case let s: str => {
|
|
assert(!(!streq(s, "")));
|
|
assert(!(s.len != 0));
|
|
};
|
|
case nomem => { abort(); };
|
|
};
|
|
|
|
// ww row 4: multibyte single-rune replace — every "に" → "X".
|
|
match (strings.replace("こんにちは", "に", "X")) {
|
|
case let s: str => {
|
|
assert(!(!streq(s, "こんXちは")));
|
|
os.free(s.ptr: *void, s.len: u64);
|
|
};
|
|
case nomem => { abort(); };
|
|
};
|
|
|
|
// ww row 5: empty input — returns empty.
|
|
match (strings.replace("", "x", "y")) {
|
|
case let s: str => {
|
|
assert(!(s.len != 0));
|
|
};
|
|
case nomem => { abort(); };
|
|
};
|
|
};
|
|
|
|
@test fn replace_empty_needle_aborts() void = {
|
|
test.expectabort();
|
|
strings.replace("abc", "", "x");
|
|
};
|