Skip to content

Commit b63b739

Browse files
tests: +30 across broadcasting / f-strings / regex
test_broadcasting_extras.omc (10): scalar broadcast lhs/rhs, elementwise sub/mul, 2D add same shape, 2D + row-vector broadcast, arr_neg with negative, arr_scale, arr_div_int with division-by-zero handling, outer-product composition. test_fstring_extras.omc (10): simple int interp, arithmetic in subst, no-subs literal, empty f-string, multiple subs, escaped braces, function call in subst, float interp, string interp. test_regex_extras.omc (10): anchored ^...$, basic substring match, find_all digits, replace basic + all-occurrences, find first, split CSV, special chars (literal dot, shorthand classes), optional ?, one-or-more +. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
1 parent 49cdf60 commit b63b739

3 files changed

Lines changed: 211 additions & 0 deletions

File tree

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
# More broadcasting + 2D array op coverage.
2+
3+
fn assert_eq(actual, expected, msg) {
4+
if actual != expected {
5+
test_record_failure(msg + ": expected " + to_string(expected) + " got " + to_string(actual));
6+
}
7+
}
8+
9+
fn assert_true(cond, msg) { if !cond { test_record_failure(msg); } }
10+
11+
# Scalar broadcast on arr_add
12+
fn test_arr_add_scalar_lhs() {
13+
h r = arr_add(10, [1, 2, 3]);
14+
assert_eq(arr_get(r, 0), 11, "10+1");
15+
assert_eq(arr_get(r, 2), 13, "10+3");
16+
}
17+
18+
fn test_arr_add_scalar_rhs() {
19+
h r = arr_add([1, 2, 3], 10);
20+
assert_eq(arr_get(r, 0), 11, "1+10");
21+
}
22+
23+
# Elementwise 1D
24+
fn test_arr_sub_elementwise() {
25+
h r = arr_sub([10, 20, 30], [1, 2, 3]);
26+
assert_eq(arr_get(r, 0), 9, "10-1");
27+
assert_eq(arr_get(r, 1), 18, "20-2");
28+
assert_eq(arr_get(r, 2), 27, "30-3");
29+
}
30+
31+
fn test_arr_mul_elementwise() {
32+
h r = arr_mul([1, 2, 3], [4, 5, 6]);
33+
assert_eq(arr_get(r, 0), 4, "1*4");
34+
assert_eq(arr_get(r, 2), 18, "3*6");
35+
}
36+
37+
# 2D add
38+
fn test_2d_add_same_shape() {
39+
h A = [[1, 2], [3, 4]];
40+
h B = [[10, 20], [30, 40]];
41+
h C = arr_add(A, B);
42+
h r0 = arr_get(C, 0);
43+
h r1 = arr_get(C, 1);
44+
assert_eq(arr_get(r0, 0), 11, "(0,0)");
45+
assert_eq(arr_get(r1, 1), 44, "(1,1)");
46+
}
47+
48+
# 2D broadcast 1D row
49+
fn test_2d_plus_row_broadcast() {
50+
h A = [[1, 2, 3], [10, 20, 30]];
51+
h bias = [100, 200, 300];
52+
h C = arr_add(A, bias);
53+
h r0 = arr_get(C, 0);
54+
assert_eq(arr_get(r0, 0), 101, "broadcast row");
55+
}
56+
57+
# arr_neg
58+
fn test_arr_neg() {
59+
h r = arr_neg([1, 0 - 2, 3]);
60+
assert_eq(arr_get(r, 0), 0 - 1, "neg 1");
61+
assert_eq(arr_get(r, 1), 2, "neg -2");
62+
}
63+
64+
# arr_scale
65+
fn test_arr_scale() {
66+
h r = arr_scale([1, 2, 3], 10);
67+
assert_eq(arr_get(r, 0), 10, "1*10");
68+
assert_eq(arr_get(r, 2), 30, "3*10");
69+
}
70+
71+
# arr_div_int with zero
72+
fn test_arr_div_int_with_zero() {
73+
h r = arr_div_int([10, 20, 30], [2, 0, 3]);
74+
assert_eq(arr_get(r, 0), 5, "10/2");
75+
assert_eq(arr_get(r, 1), 0, "div by 0 = 0");
76+
assert_eq(arr_get(r, 2), 10, "30/3");
77+
}
78+
79+
# Composition: outer-product-then-sum
80+
fn test_outer_sum_composition() {
81+
h o = arr_outer([1.0, 2.0], [3.0, 4.0]);
82+
h r0 = arr_get(o, 0); # [3, 4]
83+
h sum0 = arr_sum_int([arr_get(r0, 0), arr_get(r0, 1)]);
84+
assert_eq(sum0, 7, "row sum");
85+
}
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
# More f-string interpolation tests.
2+
3+
fn assert_eq(actual, expected, msg) {
4+
if actual != expected {
5+
test_record_failure(msg + ": expected " + to_string(expected) + " got " + to_string(actual));
6+
}
7+
}
8+
9+
fn assert_true(cond, msg) { if !cond { test_record_failure(msg); } }
10+
11+
fn test_fstring_simple_int() {
12+
h x = 42;
13+
h s = f"answer is {x}";
14+
assert_eq(s, "answer is 42", "simple int interp");
15+
}
16+
17+
fn test_fstring_arithmetic() {
18+
h x = 5;
19+
h s = f"x*2 = {x * 2}";
20+
assert_eq(s, "x*2 = 10", "arithmetic in f-string");
21+
}
22+
23+
fn test_fstring_no_subst() {
24+
h s = f"no substitutions";
25+
assert_eq(s, "no substitutions", "literal f-string");
26+
}
27+
28+
fn test_fstring_empty() {
29+
h s = f"";
30+
assert_eq(s, "", "empty f-string");
31+
}
32+
33+
fn test_fstring_multiple_subs() {
34+
h a = 1;
35+
h b = 2;
36+
h c = 3;
37+
h s = f"{a}+{b}={c}";
38+
assert_eq(s, "1+2=3", "multiple subs");
39+
}
40+
41+
fn test_fstring_with_braces_escape() {
42+
h s = f"literal {{ brace }}";
43+
assert_eq(s, "literal { brace }", "escaped braces");
44+
}
45+
46+
fn test_fstring_with_quotes() {
47+
h s = f"quoted text";
48+
assert_true(str_len(s) > 0, "quotes work");
49+
}
50+
51+
fn test_fstring_function_call() {
52+
h xs = [1, 2, 3];
53+
h s = f"len = {arr_len(xs)}";
54+
assert_eq(s, "len = 3", "function call in subst");
55+
}
56+
57+
fn test_fstring_float() {
58+
h x = 3.14;
59+
h s = f"pi = {x}";
60+
assert_true(re_match("pi = ", s) == 1, "float interpolated");
61+
}
62+
63+
fn test_fstring_with_strings() {
64+
h name = "world";
65+
h s = f"hello, {name}!";
66+
assert_eq(s, "hello, world!", "string interpolation");
67+
}
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
# More regex tests.
2+
3+
fn assert_eq(actual, expected, msg) {
4+
if actual != expected {
5+
test_record_failure(msg + ": expected " + to_string(expected) + " got " + to_string(actual));
6+
}
7+
}
8+
9+
fn assert_true(cond, msg) { if !cond { test_record_failure(msg); } }
10+
11+
fn test_re_match_anchored() {
12+
assert_eq(re_match("^[0-9]+$", "123"), 1, "all digits");
13+
assert_eq(re_match("^[0-9]+$", "12a"), 0, "with letter");
14+
}
15+
16+
fn test_re_match_basic() {
17+
assert_eq(re_match("abc", "xabcy"), 1, "substring match");
18+
assert_eq(re_match("xyz", "abc"), 0, "no match");
19+
}
20+
21+
fn test_re_find_all_digits() {
22+
h all = re_find_all("[0-9]+", "a1 b22 c333");
23+
assert_eq(arr_len(all), 3, "3 matches");
24+
assert_eq(arr_get(all, 0), "1", "first");
25+
assert_eq(arr_get(all, 2), "333", "third");
26+
}
27+
28+
fn test_re_replace_basic() {
29+
assert_eq(re_replace("[0-9]+", "abc123def", "X"), "abcXdef", "digits replaced");
30+
}
31+
32+
fn test_re_replace_all_occurrences() {
33+
assert_eq(re_replace("a", "banana", "Z"), "bZnZnZ", "all replaced");
34+
}
35+
36+
fn test_re_find_first() {
37+
h s = re_find("[a-z]+", "ABC def GHI");
38+
assert_eq(s, "def", "first lowercase run");
39+
}
40+
41+
fn test_re_split_csv() {
42+
h parts = re_split(",", "a,b,c");
43+
assert_eq(arr_len(parts), 3, "3 parts");
44+
}
45+
46+
fn test_re_match_special_chars() {
47+
assert_eq(re_match("\\.", "a.b"), 1, "literal dot");
48+
assert_eq(re_match("\\d", "x5"), 1, "shorthand class");
49+
}
50+
51+
fn test_re_match_optional() {
52+
assert_eq(re_match("colou?r", "color"), 1, "optional u");
53+
assert_eq(re_match("colou?r", "colour"), 1, "optional u present");
54+
}
55+
56+
fn test_re_match_one_or_more() {
57+
assert_eq(re_match("a+", "aaa"), 1, "1+");
58+
assert_eq(re_match("a+", "b"), 0, "no a");
59+
}

0 commit comments

Comments
 (0)