Skip to content

Commit

Permalink
Extend test suite
Browse files Browse the repository at this point in the history
  • Loading branch information
viluon committed Dec 19, 2022
1 parent f1c6df6 commit 8d0e7b3
Show file tree
Hide file tree
Showing 3 changed files with 123 additions and 9 deletions.
11 changes: 11 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,3 +53,14 @@ works out of the box on Linux, which is a pretty niche subset.
- a broken user interface, overlapping icons, poor contrast in dark mode
- playback errors are silent

### Licensing

The source code of afx is free software under the terms of Affero GPL v3.
However, this repository also contains audio samples not typically distributed
with the binary builds of afx. These include:
- [`Bird Whistling, Single, Robin,
A.wav`](samples/416529__inspectorj__bird-whistling-single-robin-a.wav) by
InspectorJ, obtained from
[Freesound](https://freesound.org/people/InspectorJ/sounds/416529/), licensed
under [CC BY 4.0](https://creativecommons.org/licenses/by/4.0/). No changes
were made to this sample.
Binary file not shown.
121 changes: 112 additions & 9 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,10 @@ fn process_message(
ControlMessage::Pause(id) => {
if let Some(handle) = handles.get_mut(&id) {
handle.pause(Tween::default())?;
edit_item(id, &mut |item| {
item.status = ItemStatus::Paused;
String::new()
});
}
Ok(())
}
Expand Down Expand Up @@ -323,6 +327,36 @@ mod test {
use super::*;
use eframe::epaint::Color32;

fn build_test_model() -> Model {
let path = "samples/416529__inspectorj__bird-whistling-single-robin-a.wav".to_string();
Model {
items: vec![
Item::with_default_stem(
0,
"test 0".to_string(),
path.clone(),
Color32::BLACK,
1.0,
),
Item::with_default_stem(
1,
"test 1".to_string(),
path.clone(),
Color32::BLACK,
1.0,
),
Item::with_default_stem(
2,
"test 2".to_string(),
path,
Color32::BLACK,
1.0,
),
],
..Model::default()
}
}

#[test]
fn file_not_found() -> Result<()> {
// create a temporary directory and try to play a nonexistent file from it
Expand All @@ -337,15 +371,10 @@ mod test {
tempdir.close()?;
path
};
let model = Model {
items: vec![Item::with_default_stem(
0,
"test".to_string(),
path,
Color32::BLACK,
1.0,
)],
..Model::default()
let model = {
let mut m = build_test_model();
m.items[0].stems[0].path = path;
m
};
let mut manager = AudioManager::<CpalBackend>::new(AudioManagerSettings::default())?;
let mut handles = HashMap::new();
Expand All @@ -366,4 +395,78 @@ mod test {
assert_eq!(model.items[0].issues[0].0, IssueType::MissingFile);
Ok(())
}

#[test]
fn play_and_pause() -> Result<()> {
let model = build_test_model();
let mut manager = AudioManager::<CpalBackend>::new(AudioManagerSettings::default())?;
let mut handles = HashMap::new();

let model = Arc::new(RwLock::new(model));
let (rx, _tx) = channel();

process_message(ControlMessage::Play(0), &rx, &mut manager, &mut handles, &model)?;
std::thread::sleep(std::time::Duration::from_millis(100));
assert_eq!(model.read().items[0].status, ItemStatus::Playing);

process_message(ControlMessage::Pause(0), &rx, &mut manager, &mut handles, &model)?;
std::thread::sleep(std::time::Duration::from_millis(100));
assert_eq!(model.read().items[0].status, ItemStatus::Paused);

Ok(())
}

#[test]
fn play_many() -> Result<()> {
let model = build_test_model();
let mut manager = AudioManager::<CpalBackend>::new(AudioManagerSettings::default())?;
let mut handles = HashMap::new();

let model = Arc::new(RwLock::new(model));
let (rx, _tx) = channel();

process_message(ControlMessage::Play(0), &rx, &mut manager, &mut handles, &model)?;
process_message(ControlMessage::Play(1), &rx, &mut manager, &mut handles, &model)?;
process_message(ControlMessage::Play(2), &rx, &mut manager, &mut handles, &model)?;
std::thread::sleep(std::time::Duration::from_millis(100));
assert_eq!(model.read().items[0].status, ItemStatus::Playing);
assert_eq!(model.read().items[1].status, ItemStatus::Playing);
assert_eq!(model.read().items[2].status, ItemStatus::Playing);

process_message(ControlMessage::GlobalPause, &rx, &mut manager, &mut handles, &model)?;
std::thread::sleep(std::time::Duration::from_millis(100));
assert_eq!(model.read().items[0].status, ItemStatus::Paused);
assert_eq!(model.read().items[1].status, ItemStatus::Paused);
assert_eq!(model.read().items[2].status, ItemStatus::Paused);

process_message(ControlMessage::GlobalStop, &rx, &mut manager, &mut handles, &model)?;
std::thread::sleep(std::time::Duration::from_millis(100));
assert_eq!(model.read().items[0].status, ItemStatus::Stopped);
assert_eq!(model.read().items[1].status, ItemStatus::Stopped);
assert_eq!(model.read().items[2].status, ItemStatus::Stopped);

Ok(())
}

#[test]
fn seek() -> Result<()> {
let model = build_test_model();
let mut manager = AudioManager::<CpalBackend>::new(AudioManagerSettings::default())?;
let mut handles = HashMap::new();

let model = Arc::new(RwLock::new(model));
let (rx, _tx) = channel();

process_message(ControlMessage::Play(0), &rx, &mut manager, &mut handles, &model)?;
std::thread::sleep(std::time::Duration::from_millis(100));
assert_eq!(model.read().items[0].status, ItemStatus::Playing);

process_message(ControlMessage::Seek(0, 0.5), &rx, &mut manager, &mut handles, &model)?;
std::thread::sleep(std::time::Duration::from_millis(100));
assert_eq!(model.read().items[0].status, ItemStatus::Playing);
assert_eq!(model.read().items[0].target_position, 0.5);
// TODO requires syncs

Ok(())
}
}

0 comments on commit 8d0e7b3

Please sign in to comment.