use super::*;
#[test]
fn open_validates_exclusion_pids_for_system_capture() {
for kind in [SourceKind::SystemLoopback, SourceKind::Mix] {
let config = StreamConfig {
kind,
exclude_pids: vec![0],
..Default::default()
};
let backend = Box::new(MockBackend::new(48_000, 2, 440.0));
assert!(matches!(
Stream::open(config, backend),
Err(Error::InvalidArg(message))
if message == "exclude_pids: pid 0 is not a valid process id"
));
for exclude_pids in [vec![], vec![42]] {
let config = StreamConfig {
kind,
exclude_pids,
..Default::default()
};
let backend = Box::new(MockBackend::new(48_000, 2, 440.0));
assert!(Stream::open(config, backend).is_ok());
}
}
for kind in [SourceKind::Mic, SourceKind::ProcessLoopback] {
let config = StreamConfig {
kind,
exclude_pids: vec![0],
..Default::default()
};
let backend = Box::new(MockBackend::new(48_000, 2, 440.0));
assert!(Stream::open(config, backend).is_ok());
}
}
#[test]
fn switch_source_rejects_zero_exclusion_pid_before_replacing_backend() {
let backend = Box::new(MockBackend::new(48_000, 2, 440.0));
let mut stream = Stream::open(StreamConfig::default(), backend).expect("open");
stream.start().expect("start mock capture");
for kind in [SourceKind::SystemLoopback, SourceKind::Mix] {
let new_config = StreamConfig {
kind,
exclude_pids: vec![42, 0],
..Default::default()
};
assert!(matches!(
stream.switch_source(new_config),
Err(Error::InvalidArg(message))
if message == "exclude_pids: pid 0 is not a valid process id"
));
assert_eq!(stream.config.kind, SourceKind::Mic);
assert!(stream.config.exclude_pids.is_empty());
}
stream.stop();
}
#[test]
fn open_rejects_zero_ring_capacity() {
let backend = Box::new(MockBackend::new(48_000, 2, 440.0));
let config = StreamConfig {
ring_capacity_chunks: 0,
..Default::default()
};
let err = open_err(Stream::open(config, backend), "capacity 0");
assert!(
matches!(err, Error::InvalidArg(_)),
"expected InvalidArg: {err:?}"
);
}
#[test]
fn open_rejects_invalid_output_channels() {
let backend = Box::new(MockBackend::new(48_000, 2, 440.0));
let config = StreamConfig {
output: OutputFormat {
sample_rate: 48_000,
channels: 3,
},
..Default::default()
};
let err = open_err(Stream::open(config, backend), "ch=3");
assert!(
matches!(err, Error::UnsupportedFormat(_)),
"expected UnsupportedFormat: {err:?}"
);
}
#[test]
fn open_rejects_out_of_range_output_rate() {
let backend = Box::new(MockBackend::new(48_000, 2, 440.0));
let config = StreamConfig {
output: OutputFormat {
sample_rate: 1_000_000,
channels: 2,
},
..Default::default()
};
let err = open_err(Stream::open(config, backend), "extreme rate");
assert!(
matches!(err, Error::UnsupportedFormat(_)),
"expected UnsupportedFormat: {err:?}"
);
}
#[test]
fn open_rejects_zero_native_format() {
struct ZeroFormatBackend;
impl CaptureBackend for ZeroFormatBackend {
fn native_format(&self) -> (u32, u16) {
(0, 0)
}
fn start(&mut self, _sink: RawSink) -> Result<()> {
Ok(())
}
fn stop(&mut self) {}
}
let backend = Box::new(ZeroFormatBackend);
let err = open_err(
Stream::open(StreamConfig::default(), backend),
"native_format 0",
);
assert!(
matches!(err, Error::InvalidArg(_)),
"expected InvalidArg: {err:?}"
);
}
#[test]
fn invalid_gain_rejected() {
let backend = Box::new(MockBackend::new(48_000, 2, 440.0));
let config = StreamConfig {
gain: -1.0,
..Default::default()
};
let err = open_err(Stream::open(config, backend), "gain=-1.0");
assert!(
matches!(err, Error::InvalidArg(_)),
"expected InvalidArg: {err:?}"
);
let backend = Box::new(MockBackend::new(48_000, 2, 440.0));
let config = StreamConfig {
gain: f32::NAN,
..Default::default()
};
let err = open_err(Stream::open(config, backend), "gain=NaN");
assert!(
matches!(err, Error::InvalidArg(_)),
"expected InvalidArg: {err:?}"
);
let backend = Box::new(MockBackend::new(48_000, 2, 440.0));
let stream = Stream::open(StreamConfig::default(), backend).expect("open");
assert!(matches!(stream.set_gain(-1.0), Err(Error::InvalidArg(_))));
assert!(matches!(
stream.set_gain(f32::NAN),
Err(Error::InvalidArg(_))
));
assert_eq!(
stream.gain(),
1.0,
"failed set_gain should not change the current value"
);
}
#[test]
fn secondary_output_cannot_change_on_switch() {
let config = StreamConfig {
secondary_output: Some(OutputFormat {
sample_rate: 16_000,
channels: 1,
}),
..Default::default()
};
let backend = Box::new(MockBackend::new(48_000, 2, 440.0));
let mut stream = Stream::open(config, backend).expect("open");
stream.start().expect("start");
let new_config = StreamConfig {
secondary_output: Some(OutputFormat {
sample_rate: 8_000,
channels: 1,
}),
..Default::default()
};
let err = stream.switch_source(new_config);
stream.stop();
assert!(
matches!(err, Err(Error::InvalidArg(_))),
"expected InvalidArg when changing the secondary format: {err:?}"
);
}