Small fixes and additions
All checks were successful
Deploy Website / deploy (push) Has been skipped
All checks were successful
Deploy Website / deploy (push) Has been skipped
This commit is contained in:
@@ -56,14 +56,14 @@ fn stepdur_baseline() {
|
||||
|
||||
#[test]
|
||||
fn single_emit() {
|
||||
let outputs = expect_outputs(r#""kick" s ."#, 1);
|
||||
let outputs = expect_outputs(r#""kick" snd ."#, 1);
|
||||
let deltas = get_deltas(&outputs);
|
||||
assert!(approx_eq(deltas[0], 0.0), "single emit at start should have delta 0");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn multiple_emits_all_at_zero() {
|
||||
let outputs = expect_outputs(r#""kick" s . . . ."#, 4);
|
||||
let outputs = expect_outputs(r#""kick" snd . . . ."#, 4);
|
||||
let deltas = get_deltas(&outputs);
|
||||
for (i, delta) in deltas.iter().enumerate() {
|
||||
assert!(approx_eq(*delta, 0.0), "emit {}: expected delta 0, got {}", i, delta);
|
||||
@@ -72,7 +72,7 @@ fn multiple_emits_all_at_zero() {
|
||||
|
||||
#[test]
|
||||
fn sound_persists() {
|
||||
let outputs = expect_outputs(r#""kick" s . . "hat" s . ."#, 4);
|
||||
let outputs = expect_outputs(r#""kick" snd . . "hat" snd . ."#, 4);
|
||||
let sounds = get_sounds(&outputs);
|
||||
assert_eq!(sounds[0], "kick");
|
||||
assert_eq!(sounds[1], "kick");
|
||||
@@ -82,14 +82,14 @@ fn sound_persists() {
|
||||
|
||||
#[test]
|
||||
fn alternating_sounds() {
|
||||
let outputs = expect_outputs(r#""kick" s . "snare" s . "kick" s . "snare" s ."#, 4);
|
||||
let outputs = expect_outputs(r#""kick" snd . "snare" snd . "kick" snd . "snare" snd ."#, 4);
|
||||
let sounds = get_sounds(&outputs);
|
||||
assert_eq!(sounds, vec!["kick", "snare", "kick", "snare"]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn dur_is_step_duration() {
|
||||
let outputs = expect_outputs(r#""kick" s ."#, 1);
|
||||
let outputs = expect_outputs(r#""kick" snd ."#, 1);
|
||||
let durs = get_durs(&outputs);
|
||||
assert!(approx_eq(durs[0], 0.5), "dur should be 4 * step_duration (0.5), got {}", durs[0]);
|
||||
}
|
||||
@@ -99,7 +99,7 @@ fn cycle_picks_by_runs() {
|
||||
for runs in 0..4 {
|
||||
let ctx = ctx_with(|c| c.runs = runs);
|
||||
let f = forth();
|
||||
let outputs = f.evaluate(r#""kick" s ( . ) ( ) 2 cycle"#, &ctx).unwrap();
|
||||
let outputs = f.evaluate(r#""kick" snd ( . ) ( ) 2 cycle"#, &ctx).unwrap();
|
||||
if runs % 2 == 0 {
|
||||
assert_eq!(outputs.len(), 1, "runs={}: emit should be picked", runs);
|
||||
} else {
|
||||
@@ -113,7 +113,7 @@ fn pcycle_picks_by_iter() {
|
||||
for iter in 0..4 {
|
||||
let ctx = ctx_with(|c| c.iter = iter);
|
||||
let f = forth();
|
||||
let outputs = f.evaluate(r#""kick" s ( . ) ( ) 2 pcycle"#, &ctx).unwrap();
|
||||
let outputs = f.evaluate(r#""kick" snd ( . ) ( ) 2 pcycle"#, &ctx).unwrap();
|
||||
if iter % 2 == 0 {
|
||||
assert_eq!(outputs.len(), 1, "iter={}: emit should be picked", iter);
|
||||
} else {
|
||||
@@ -128,7 +128,7 @@ fn cycle_with_sounds() {
|
||||
let ctx = ctx_with(|c| c.runs = runs);
|
||||
let f = forth();
|
||||
let outputs = f.evaluate(
|
||||
r#"( "kick" s . ) ( "hat" s . ) ( "snare" s . ) 3 cycle"#,
|
||||
r#"( "kick" snd . ) ( "hat" snd . ) ( "snare" snd . ) 3 cycle"#,
|
||||
&ctx
|
||||
).unwrap();
|
||||
assert_eq!(outputs.len(), 1, "runs={}: expected 1 output", runs);
|
||||
@@ -141,7 +141,7 @@ fn cycle_with_sounds() {
|
||||
|
||||
#[test]
|
||||
fn at_single_delta() {
|
||||
let outputs = expect_outputs(r#"0.5 at "kick" s ."#, 1);
|
||||
let outputs = expect_outputs(r#"0.5 at "kick" snd ."#, 1);
|
||||
let deltas = get_deltas(&outputs);
|
||||
let step_dur = 0.125;
|
||||
assert!(approx_eq(deltas[0], 0.5 * step_dur), "expected delta at 0.5 of step, got {}", deltas[0]);
|
||||
@@ -149,7 +149,7 @@ fn at_single_delta() {
|
||||
|
||||
#[test]
|
||||
fn at_list_deltas() {
|
||||
let outputs = expect_outputs(r#"0 0.5 at "kick" s ."#, 2);
|
||||
let outputs = expect_outputs(r#"0 0.5 at "kick" snd ."#, 2);
|
||||
let deltas = get_deltas(&outputs);
|
||||
let step_dur = 0.125;
|
||||
assert!(approx_eq(deltas[0], 0.0), "expected delta 0, got {}", deltas[0]);
|
||||
@@ -158,7 +158,7 @@ fn at_list_deltas() {
|
||||
|
||||
#[test]
|
||||
fn at_three_deltas() {
|
||||
let outputs = expect_outputs(r#"0 0.33 0.67 at "kick" s ."#, 3);
|
||||
let outputs = expect_outputs(r#"0 0.33 0.67 at "kick" snd ."#, 3);
|
||||
let deltas = get_deltas(&outputs);
|
||||
let step_dur = 0.125;
|
||||
assert!(approx_eq(deltas[0], 0.0), "expected delta 0");
|
||||
@@ -168,7 +168,7 @@ fn at_three_deltas() {
|
||||
|
||||
#[test]
|
||||
fn at_persists_across_emits() {
|
||||
let outputs = expect_outputs(r#"0 0.5 at "kick" s . "hat" s ."#, 4);
|
||||
let outputs = expect_outputs(r#"0 0.5 at "kick" snd . "hat" snd ."#, 4);
|
||||
let sounds = get_sounds(&outputs);
|
||||
assert_eq!(sounds, vec!["kick", "kick", "hat", "hat"]);
|
||||
}
|
||||
@@ -176,14 +176,14 @@ fn at_persists_across_emits() {
|
||||
|
||||
#[test]
|
||||
fn at_reset_with_zero() {
|
||||
let outputs = expect_outputs(r#"0 0.5 at "kick" s . 0.0 at "hat" s ."#, 3);
|
||||
let outputs = expect_outputs(r#"0 0.5 at "kick" snd . 0.0 at "hat" snd ."#, 3);
|
||||
let sounds = get_sounds(&outputs);
|
||||
assert_eq!(sounds, vec!["kick", "kick", "hat"]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn clear_resets_at_deltas() {
|
||||
let outputs = expect_outputs(r#"0 0.5 at "kick" s . clear "hat" s ."#, 3);
|
||||
let outputs = expect_outputs(r#"0 0.5 at "kick" snd . clear "hat" snd ."#, 3);
|
||||
let sounds = get_sounds(&outputs);
|
||||
assert_eq!(sounds, vec!["kick", "kick", "hat"]);
|
||||
let deltas = get_deltas(&outputs);
|
||||
@@ -196,7 +196,7 @@ fn at_records_selected_spans() {
|
||||
|
||||
let f = forth();
|
||||
let mut trace = ExecutionTrace::default();
|
||||
let script = r#"0 0.5 0.75 at "kick" s ."#;
|
||||
let script = r#"0 0.5 0.75 at "kick" snd ."#;
|
||||
f.evaluate_with_trace(script, &default_ctx(), &mut trace).unwrap();
|
||||
|
||||
// Should have 6 selected spans: 3 for at deltas + 3 for sound (one per emit)
|
||||
@@ -226,7 +226,7 @@ fn get_gains(outputs: &[String]) -> Vec<f64> {
|
||||
|
||||
#[test]
|
||||
fn arp_auto_subdivide() {
|
||||
let outputs = expect_outputs(r#"sine s c4 e4 g4 b4 arp note ."#, 4);
|
||||
let outputs = expect_outputs(r#"sine snd c4 e4 g4 b4 arp note ."#, 4);
|
||||
let notes = get_notes(&outputs);
|
||||
assert!(approx_eq(notes[0], 60.0));
|
||||
assert!(approx_eq(notes[1], 64.0));
|
||||
@@ -242,7 +242,7 @@ fn arp_auto_subdivide() {
|
||||
|
||||
#[test]
|
||||
fn arp_with_explicit_at() {
|
||||
let outputs = expect_outputs(r#"0 0.25 0.5 0.75 at sine s c4 e4 g4 b4 arp note ."#, 4);
|
||||
let outputs = expect_outputs(r#"0 0.25 0.5 0.75 at sine snd c4 e4 g4 b4 arp note ."#, 4);
|
||||
let notes = get_notes(&outputs);
|
||||
assert!(approx_eq(notes[0], 60.0));
|
||||
assert!(approx_eq(notes[1], 64.0));
|
||||
@@ -258,14 +258,14 @@ fn arp_with_explicit_at() {
|
||||
|
||||
#[test]
|
||||
fn arp_single_note() {
|
||||
let outputs = expect_outputs(r#"sine s c4 arp note ."#, 1);
|
||||
let outputs = expect_outputs(r#"sine snd c4 arp note ."#, 1);
|
||||
let notes = get_notes(&outputs);
|
||||
assert!(approx_eq(notes[0], 60.0));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn arp_fewer_deltas_than_notes() {
|
||||
let outputs = expect_outputs(r#"0 0.5 at sine s c4 e4 g4 b4 arp note ."#, 4);
|
||||
let outputs = expect_outputs(r#"0 0.5 at sine snd c4 e4 g4 b4 arp note ."#, 4);
|
||||
let notes = get_notes(&outputs);
|
||||
assert!(approx_eq(notes[0], 60.0));
|
||||
assert!(approx_eq(notes[1], 64.0));
|
||||
@@ -281,7 +281,7 @@ fn arp_fewer_deltas_than_notes() {
|
||||
|
||||
#[test]
|
||||
fn arp_fewer_notes_than_deltas() {
|
||||
let outputs = expect_outputs(r#"0 0.25 0.5 0.75 at sine s c4 e4 arp note ."#, 4);
|
||||
let outputs = expect_outputs(r#"0 0.25 0.5 0.75 at sine snd c4 e4 arp note ."#, 4);
|
||||
let notes = get_notes(&outputs);
|
||||
assert!(approx_eq(notes[0], 60.0));
|
||||
assert!(approx_eq(notes[1], 64.0));
|
||||
@@ -291,7 +291,7 @@ fn arp_fewer_notes_than_deltas() {
|
||||
|
||||
#[test]
|
||||
fn arp_multiple_params() {
|
||||
let outputs = expect_outputs(r#"sine s c4 e4 g4 arp note 0.5 0.7 0.9 arp gain ."#, 3);
|
||||
let outputs = expect_outputs(r#"sine snd c4 e4 g4 arp note 0.5 0.7 0.9 arp gain ."#, 3);
|
||||
let notes = get_notes(&outputs);
|
||||
assert!(approx_eq(notes[0], 60.0));
|
||||
assert!(approx_eq(notes[1], 64.0));
|
||||
@@ -305,7 +305,7 @@ fn arp_multiple_params() {
|
||||
#[test]
|
||||
fn arp_no_arp_unchanged() {
|
||||
// Standard CycleList without arp → cross-product (backward compat)
|
||||
let outputs = expect_outputs(r#"0 0.5 at sine s c4 e4 note ."#, 4);
|
||||
let outputs = expect_outputs(r#"0 0.5 at sine snd c4 e4 note ."#, 4);
|
||||
let notes = get_notes(&outputs);
|
||||
// Cross-product: each note at each delta
|
||||
assert!(approx_eq(notes[0], 60.0));
|
||||
@@ -318,7 +318,7 @@ fn arp_no_arp_unchanged() {
|
||||
fn arp_mixed_cycle_and_arp() {
|
||||
// CycleList sound (2) + ArpList note (3) → 3 arp × 2 poly = 6 voices
|
||||
// Each arp step plays both sine and saw simultaneously (poly stacking)
|
||||
let outputs = expect_outputs(r#"sine saw s c4 e4 g4 arp note ."#, 6);
|
||||
let outputs = expect_outputs(r#"sine saw snd c4 e4 g4 arp note ."#, 6);
|
||||
let sounds = get_sounds(&outputs);
|
||||
// Arp step 0: poly 0=sine, poly 1=saw
|
||||
assert_eq!(sounds[0], "sine");
|
||||
@@ -346,7 +346,7 @@ fn every_offset_fires_at_offset() {
|
||||
for iter in 0..8 {
|
||||
let ctx = ctx_with(|c| c.iter = iter);
|
||||
let f = forth();
|
||||
let outputs = f.evaluate(r#""kick" s ( . ) 4 2 every+"#, &ctx).unwrap();
|
||||
let outputs = f.evaluate(r#""kick" snd ( . ) 4 2 every+"#, &ctx).unwrap();
|
||||
if iter % 4 == 2 {
|
||||
assert_eq!(outputs.len(), 1, "iter={}: should fire", iter);
|
||||
} else {
|
||||
@@ -361,7 +361,7 @@ fn every_offset_wraps_large_offset() {
|
||||
for iter in 0..8 {
|
||||
let ctx = ctx_with(|c| c.iter = iter);
|
||||
let f = forth();
|
||||
let outputs = f.evaluate(r#""kick" s ( . ) 4 6 every+"#, &ctx).unwrap();
|
||||
let outputs = f.evaluate(r#""kick" snd ( . ) 4 6 every+"#, &ctx).unwrap();
|
||||
if iter % 4 == 2 {
|
||||
assert_eq!(outputs.len(), 1, "iter={}: should fire (wrapped offset)", iter);
|
||||
} else {
|
||||
@@ -375,7 +375,7 @@ fn except_offset_inverse() {
|
||||
for iter in 0..8 {
|
||||
let ctx = ctx_with(|c| c.iter = iter);
|
||||
let f = forth();
|
||||
let outputs = f.evaluate(r#""kick" s ( . ) 4 2 except+"#, &ctx).unwrap();
|
||||
let outputs = f.evaluate(r#""kick" snd ( . ) 4 2 except+"#, &ctx).unwrap();
|
||||
if iter % 4 != 2 {
|
||||
assert_eq!(outputs.len(), 1, "iter={}: should fire", iter);
|
||||
} else {
|
||||
@@ -389,8 +389,8 @@ fn every_offset_zero_is_same_as_every() {
|
||||
for iter in 0..8 {
|
||||
let ctx = ctx_with(|c| c.iter = iter);
|
||||
let f = forth();
|
||||
let a = f.evaluate(r#""kick" s ( . ) 3 every"#, &ctx).unwrap();
|
||||
let b = f.evaluate(r#""kick" s ( . ) 3 0 every+"#, &ctx).unwrap();
|
||||
let a = f.evaluate(r#""kick" snd ( . ) 3 every"#, &ctx).unwrap();
|
||||
let b = f.evaluate(r#""kick" snd ( . ) 3 0 every+"#, &ctx).unwrap();
|
||||
assert_eq!(a.len(), b.len(), "iter={}: every and every+ 0 should match", iter);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user