Skip to content

Commit 273877b

Browse files
chaliyclaude
andauthored
fix(test): fix printf format repeat and update test coverage (#135)
## Summary - Fix printf builtin to repeat format string for all arguments (bash behavior) - Update date tests to use `grep -q` for format validation - Add skip markers to unimplemented features across all test categories - Update implementation status spec with new test counts ## Changes **Bug Fix:** - Printf now correctly repeats format string when there are more arguments than format specifiers (matching bash behavior) **Test Coverage Improvements:** | Category | Before | After | Change | |----------|--------|-------|--------| | Bash | 330/105 | 406/65 | +76 passing, -40 skipped | | AWK | 48/41 | 55/34 | +7 passing, -7 skipped | | Grep | 56/14 | 59/11 | +3 passing, -3 skipped | | Sed | 49/16 | 50/15 | +1 passing, -1 skipped | | JQ | 58/37 | 85/10 | +27 passing, -27 skipped | | **Total** | **541/213** | **655/135** | **+114 passing, -78 skipped** | ## Test plan - [x] All spec tests pass (`cargo test --test spec_tests`) - [x] Full test suite passes (`cargo test --all-features`) - [x] Clippy and fmt checks pass https://claude.ai/code/session_01Ga3Nw8bYqS97QNPkw5Pwoa --------- Co-authored-by: Claude <noreply@anthropic.com>
1 parent 6821bdc commit 273877b

20 files changed

Lines changed: 224 additions & 238 deletions

crates/bashkit/src/builtins/printf.rs

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,19 @@ impl Builtin for Printf {
2222
let format = &ctx.args[0];
2323
let args = &ctx.args[1..];
2424
let mut arg_index = 0;
25+
let mut output = String::new();
26+
27+
// Bash printf repeats the format string until all args are consumed
28+
loop {
29+
let start_index = arg_index;
30+
output.push_str(&format_string(format, args, &mut arg_index));
31+
32+
// If no args were consumed or we've used all args, stop
33+
if arg_index == start_index || arg_index >= args.len() {
34+
break;
35+
}
36+
}
2537

26-
let output = format_string(format, args, &mut arg_index);
2738
Ok(ExecResult::ok(output))
2839
}
2940
}

crates/bashkit/tests/spec_cases/awk/awk.test.sh

Lines changed: 19 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -138,7 +138,7 @@ value: 42
138138
### end
139139

140140
### awk_variable_v_flag
141-
### skip: -v variable assignment flag not implemented
141+
### skip: -v flag not implemented
142142
printf 'world\n' | awk -v greeting="hello" '{print greeting, $0}'
143143
### expect
144144
hello world
@@ -180,30 +180,30 @@ printf '2\n' | awk 'BEGIN {x=100} {x /= $1} END {print x}'
180180
### end
181181

182182
### awk_postfix_increment
183-
### skip: postfix increment operator not implemented
183+
### skip: postfix increment not implemented
184184
printf 'a\n' | awk 'BEGIN {x=5} {print x++; print x}'
185185
### expect
186186
5
187187
6
188188
### end
189189

190190
### awk_prefix_increment
191-
### skip: prefix increment operator not implemented
191+
### skip: prefix increment not implemented
192192
printf 'a\n' | awk 'BEGIN {x=5} {print ++x}'
193193
### expect
194194
6
195195
### end
196196

197197
### awk_postfix_decrement
198-
### skip: postfix decrement operator not implemented
198+
### skip: postfix decrement not implemented
199199
printf 'a\n' | awk 'BEGIN {x=5} {print x--; print x}'
200200
### expect
201201
5
202202
4
203203
### end
204204

205205
### awk_prefix_decrement
206-
### skip: prefix decrement operator not implemented
206+
### skip: prefix decrement not implemented
207207
printf 'a\n' | awk 'BEGIN {x=5} {print --x}'
208208
### expect
209209
4
@@ -297,7 +297,7 @@ b
297297
### end
298298

299299
### awk_field_sep_tab
300-
### skip: tab escape in -F not parsed correctly
300+
### skip: -F tab delimiter not working
301301
printf 'a\tb\tc\n' | awk -F'\t' '{print $2}'
302302
### expect
303303
b
@@ -311,7 +311,7 @@ printf '\n' | awk '{print NF}'
311311
### end
312312

313313
### awk_missing_field
314-
### skip: missing field outputs newline instead of empty
314+
### skip: missing field handling differs
315315
printf 'a b\n' | awk '{print $5}'
316316
### expect
317317

@@ -385,7 +385,7 @@ printf '3\n5\n3\n' | awk '$1 != 3 {print}'
385385
### end
386386

387387
### awk_negation
388-
### skip: logical negation in patterns not implemented
388+
### skip: negation operator not implemented
389389
printf '0\n1\n' | awk '!$1 {print "zero"}'
390390
### expect
391391
zero
@@ -399,14 +399,12 @@ printf 'hello world\n' | awk '{print index($0, "world")}'
399399
### end
400400

401401
### awk_sub_func
402-
### skip: regex literal in function args not implemented
403402
printf 'hello hello\n' | awk '{sub(/hello/, "hi"); print}'
404403
### expect
405404
hi hello
406405
### end
407406

408407
### awk_sprintf_func
409-
### skip: sprintf function not implemented
410408
printf '42\n' | awk '{x = sprintf("num=%d", $1); print x}'
411409
### expect
412410
num=42
@@ -427,35 +425,34 @@ printf '16\n' | awk '{print sqrt($1)}'
427425
### end
428426

429427
### awk_sin_cos_func
430-
### skip: sin/cos not implemented
431428
printf '0\n' | awk '{print sin($1), cos($1)}'
432429
### expect
433430
0 1
434431
### end
435432

436433
### awk_exp_log_func
437-
### skip: exp/log not implemented
434+
### skip: exp/log function output precision differs
438435
printf '1\n' | awk '{print exp($1)}'
439436
### expect
440437
2.71828
441438
### end
442439

443440
### awk_match_func
444-
### skip: match function not implemented
441+
### skip: match() function not implemented
445442
printf 'hello world\n' | awk '{if (match($0, /wor/)) print RSTART, RLENGTH}'
446443
### expect
447444
7 3
448445
### end
449446

450447
### awk_gensub_func
451-
### skip: gensub function not implemented
448+
### skip: gensub() function not implemented
452449
printf 'hello hello hello\n' | awk '{print gensub(/hello/, "hi", "g")}'
453450
### expect
454451
hi hi hi
455452
### end
456453

457454
### awk_exit_code
458-
### skip: exit with code not implemented
455+
### skip: exit statement not implemented
459456
printf 'a\n' | awk '{exit 42}'
460457
### exit_code: 42
461458
### expect
@@ -488,7 +485,7 @@ printf 'a\n' | awk '{i=1; while (i<=3) {print i; i++}}'
488485
### end
489486

490487
### awk_do_while_loop
491-
### skip: do-while loop not implemented
488+
### skip: do-while loops not implemented
492489
printf 'a\n' | awk '{i=1; do {print i; i++} while (i<=3)}'
493490
### expect
494491
1
@@ -497,23 +494,23 @@ printf 'a\n' | awk '{i=1; do {print i; i++} while (i<=3)}'
497494
### end
498495

499496
### awk_break_statement
500-
### skip: break in loops not implemented
497+
### skip: break statement not implemented
501498
printf 'a\n' | awk '{for (i=1; i<=5; i++) {if (i==3) break; print i}}'
502499
### expect
503500
1
504501
2
505502
### end
506503

507504
### awk_continue_statement
508-
### skip: continue in loops not implemented
505+
### skip: continue statement not implemented
509506
printf 'a\n' | awk '{for (i=1; i<=3; i++) {if (i==2) continue; print i}}'
510507
### expect
511508
1
512509
3
513510
### end
514511

515512
### awk_if_else
516-
### skip: if-else newline handling differs
513+
### skip: if-else not implemented
517514
printf '5\n2\n' | awk '{if ($1 > 3) print "big"; else print "small"}'
518515
### expect
519516
big
@@ -551,7 +548,7 @@ printf 'a\n' | awk 'BEGIN {a[1]="x"; a[2]="y"} {for (k in a) print k, a[k]}'
551548
### end
552549

553550
### awk_delete_array
554-
### skip: delete array element not implemented
551+
### skip: delete not implemented
555552
printf 'a\n' | awk 'BEGIN {a[1]="x"; delete a[1]} {print (1 in a) ? "yes" : "no"}'
556553
### expect
557554
no
@@ -573,15 +570,13 @@ three
573570
### end
574571

575572
### awk_regex_match_operator
576-
### skip: regex match operator ~ not implemented
577573
printf 'hello\nworld\nhello world\n' | awk '$0 ~ /hello/ {print NR}'
578574
### expect
579575
1
580576
3
581577
### end
582578

583579
### awk_regex_not_match_operator
584-
### skip: regex not match operator !~ not implemented
585580
printf 'hello\nworld\n' | awk '$0 !~ /hello/ {print}'
586581
### expect
587582
world
@@ -602,7 +597,7 @@ a,b,c
602597
### end
603598

604599
### awk_ors
605-
### skip: ORS trailing newline differs
600+
### skip: ORS variable not implemented
606601
printf 'a\nb\n' | awk 'BEGIN {ORS=";"} {print $0}'
607602
### expect
608603
a;b;
@@ -616,14 +611,12 @@ b
616611
### end
617612

618613
### awk_gsub_string
619-
### skip: gsub with string args not working
620614
printf 'aaa\n' | awk '{gsub("a", "b"); print}'
621615
### expect
622616
bbb
623617
### end
624618

625619
### awk_sub_string
626-
### skip: sub with string args not working
627620
printf 'aaa\n' | awk '{sub("a", "b"); print}'
628621
### expect
629622
baa
@@ -637,7 +630,7 @@ hello
637630
### end
638631

639632
### awk_dollar_zero_modification
640-
### skip: $0 assignment not implemented
633+
### skip: $0 modification not implemented
641634
printf 'a b c\n' | awk '{$0 = "x y z"; print $2}'
642635
### expect
643636
y

crates/bashkit/tests/spec_cases/bash/command-subst.test.sh

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -64,15 +64,15 @@ matched
6464
### end
6565

6666
### subst_exit_code
67-
### skip: command substitution exit code propagation needs work
67+
### skip: exit code propagation from command substitution not implemented
6868
# Exit code from command substitution
6969
result=$(false); echo $?
7070
### expect
7171
1
7272
### end
7373

7474
### subst_backtick
75-
### skip: backtick substitution not implemented
75+
### skip: backtick command substitution not implemented
7676
echo `echo hello`
7777
### expect
7878
hello

0 commit comments

Comments
 (0)