add more proptests for output

This commit is contained in:
🪞👃🪞 2025-01-27 18:41:27 +01:00
parent c78dd2453a
commit 2e18ca96fd
9 changed files with 154 additions and 78 deletions

View file

@ -1,42 +1,4 @@
default:
bacon -sj test
tui:
cargo run --example tui
cloc:
for src in {cli,edn/src,input/src,jack/src,midi/src,output/src,plugin/src,sampler/src,tek/src,time/src,tui/src}; do echo; echo $src; cloc --quiet $src; done
test:
cargo test --workspace --exclude jack
covfig := "CARGO_INCREMENTAL=0 RUSTFLAGS='-Cinstrument-coverage' RUSTDOCFLAGS='-Cinstrument-coverage' LLVM_PROFILE_FILE='cov/cargo-test-%p-%m.profraw'"
cov:
rm -rf target/coverage/html || true
{{covfig}} time cargo test --workspace --exclude jack --profile coverage
{{covfig}} time grcov . --binary-path ./target/coverage/deps/ -s . -t html --ignore-not-existing --ignore '../*' --ignore "/*" --ignore 'target/*' -o target/coverage/html
llcov:
time cargo llvm-cov --workspace --exclude jack --profile coverage --no-report
time cargo llvm-cov --workspace --exclude jack --profile coverage --no-report --doc
time cargo llvm-cov report --doctests --html #--output-path target/coverage/html
prof:
CARGO_PROFILE_RELEASE_DEBUG=true cargo flamegraph -- arranger
status:
cargo c
cloc --by-file src/
git status
doc:
cargo doc --document-private-items
upstreams := "codeberg origin" # TODO!
amend:
git commit --amend
push:
git push -u codeberg main && git push -u origin main
tpush:
git push --tags -u codeberg && git push --tags -u origin
fpush:
git push -fu codeberg main && git push -fu origin main
ftpush:
git push --tags -fu codeberg && git push --tags -fu origin
upstreams := "codeberg origin" # TODO!
debug := "reset && cargo run --"
release := "reset && cargo run --release --"
name := "-n tek"
@ -47,15 +9,37 @@ audio-in := "-l 'Komplete Audio 6 Pro:capture_AUX1' -r 'Komplete Audio 6 Pro:c
audio-out := "-L 'Komplete Audio 6 Pro:playback_AUX1' -R 'Komplete Audio 6 Pro:playback_AUX1'"
firefox-in := "-l 'Firefox:output_FL' -r 'Firefox:output_FR'"
# TODO: arranger track mappings
#-i "1=Midi-Bridge:nanoKEY Studio 2:(capture_0) nanoKEY Studio nanoKEY Studio _"
#-o "1=Midi-Bridge:Komplete Audio 6 1:(playback_0) Komplete Audio 6 MIDI 1"
#-i "2=Midi-Bridge:nanoKEY Studio 2:(capture_0) nanoKEY Studio nanoKEY Studio _"
#-o "2=Midi-Bridge:Komplete Audio 6 1:(playback_0) Komplete Audio 6 MIDI 1"
#-i "3=Midi-Bridge:nanoKEY Studio 2:(capture_0) nanoKEY Studio nanoKEY Studio _"
#-o "3=Midi-Bridge:Komplete Audio 6 1:(playback_0) Komplete Audio 6 MIDI 1"
#-i "4=Midi-Bridge:nanoKEY Studio 2:(capture_0) nanoKEY Studio nanoKEY Studio _"
#-o "4=Midi-Bridge:Komplete Audio 6 1:(playback_0) Komplete Audio 6 MIDI 1"
default:
bacon -s
tui:
cargo run --example tui
cloc:
for src in {cli,edn/src,input/src,jack/src,midi/src,output/src,plugin/src,sampler/src,tek/src,time/src,tui/src}; do echo; echo $src; cloc --quiet $src; done
test:
cargo test --workspace --exclude jack
prof:
CARGO_PROFILE_RELEASE_DEBUG=true cargo flamegraph -- arranger
doc:
cargo doc --workspace --document-private-items
covfig := "CARGO_INCREMENTAL=0 RUSTFLAGS='-Cinstrument-coverage' RUSTDOCFLAGS='-Cinstrument-coverage' LLVM_PROFILE_FILE='cov/cargo-test-%p-%m.profraw'"
cov:
rm -rf target/coverage/html || true
{{covfig}} time cargo test --workspace --exclude jack --profile coverage
{{covfig}} time grcov . --binary-path ./target/coverage/deps/ -s . -t html --ignore-not-existing --ignore '../*' --ignore "/*" --ignore 'target/*' -o target/coverage/html
llcov:
time cargo llvm-cov --workspace --exclude jack --profile coverage --no-report
time cargo llvm-cov --workspace --exclude jack --profile coverage --no-report --doc
time cargo llvm-cov report --doctests --html #--output-path target/coverage/html
amend:
git commit --amend
push:
git push -u codeberg main && git push -u origin main
tpush:
git push --tags -u codeberg && git push --tags -u origin
fpush:
git push -fu codeberg main && git push -fu origin main
ftpush:
git push --tags -fu codeberg && git push --tags -fu origin
run:
{{debug}}

View file

@ -8,4 +8,4 @@ tek_edn = { path = "../edn" }
[dev-dependencies]
tek_tui = { path = "../tui" }
proptest = "^1"
proptest = "^1.6.0"

View file

@ -0,0 +1,7 @@
# Seeds for failure cases proptest has generated in the past. It is
# automatically read and these particular cases re-run before any
# novel cases are generated.
#
# It is recommended to check this file in to source control so that
# everyone who runs the test benefits from these saved cases.
cc d2cd65ec39a1bf43c14bb2d3196c7e84ba854411360e570f06dd7ede62b0fd61 # shrinks to x = 0, y = 43998, w = 0, h = 43076, a = 0, b = 0

View file

@ -0,0 +1,7 @@
# Seeds for failure cases proptest has generated in the past. It is
# automatically read and these particular cases re-run before any
# novel cases are generated.
#
# It is recommended to check this file in to source control so that
# everyone who runs the test benefits from these saved cases.
cc 5b236150b286e479089d5bf6accc8ffbc3c0b0a1f955682af1987f342930d31e # shrinks to x = 0, y = 0, w = 0, h = 0, a = 1

View file

@ -6,6 +6,17 @@ pub trait Area<N: Coordinate>: From<[N;4]> + Debug + Copy {
fn y (&self) -> N;
fn w (&self) -> N;
fn h (&self) -> N;
#[inline] fn zero () -> [N;4] {
[N::zero(), N::zero(), N::zero(), N::zero()]
}
#[inline] fn from_position (pos: impl Size<N>) -> [N;4] {
let [x, y] = pos.wh();
[x, y, 0.into(), 0.into()]
}
#[inline] fn from_size (size: impl Size<N>) -> [N;4] {
let [w, h] = size.wh();
[0.into(), 0.into(), w, h]
}
#[inline] fn expect_min (&self, w: N, h: N) -> Usually<&Self> {
if self.w() < w || self.h() < h {
Err(format!("min {w}x{h}").into())
@ -49,14 +60,13 @@ pub trait Area<N: Coordinate>: From<[N;4]> + Debug + Copy {
#[inline] fn center (&self) -> [N;2] {
[self.x().plus(self.w()/2.into()), self.y().plus(self.h()/2.into())]
}
#[inline] fn center_x (&self, n: N) -> [N;4] {
let [x, y, w, h] = self.xywh();
[(x.plus(w / 2.into())).minus(n / 2.into()), y.plus(h / 2.into()), n, 1.into()]
}
#[inline] fn center_y (&self, n: N) -> [N;4] {
let [x, y, w, h] = self.xywh();
[x.plus(w / 2.into()), (y + h / 2.into()).minus(n / 2.into()), 1.into(), n]
[x.plus(w / 2.into()), (y.plus(h / 2.into())).minus(n / 2.into()), 1.into(), n]
}
#[inline] fn center_xy (&self, [n, m]: [N;2]) -> [N;4] {
let [x, y, w, h] = self.xywh();
@ -66,17 +76,6 @@ pub trait Area<N: Coordinate>: From<[N;4]> + Debug + Copy {
#[inline] fn centered (&self) -> [N;2] {
[self.x().minus(self.w()/2.into()), self.y().minus(self.h()/2.into())]
}
#[inline] fn zero () -> [N;4] {
[N::zero(), N::zero(), N::zero(), N::zero()]
}
#[inline] fn from_position (pos: impl Size<N>) -> [N;4] {
let [x, y] = pos.wh();
[x, y, 0.into(), 0.into()]
}
#[inline] fn from_size (size: impl Size<N>) -> [N;4] {
let [w, h] = size.wh();
[0.into(), 0.into(), w, h]
}
}
impl<N: Coordinate> Area<N> for (N, N, N, N) {
@ -92,3 +91,40 @@ impl<N: Coordinate> Area<N> for [N;4] {
#[inline] fn w (&self) -> N { self[2] }
#[inline] fn h (&self) -> N { self[3] }
}
#[cfg(test)] mod test_area {
use super::*;
use proptest::prelude::*;
proptest! {
#[test] fn test_area (
x in u16::MIN..u16::MAX,
y in u16::MIN..u16::MAX,
w in u16::MIN..u16::MAX,
h in u16::MIN..u16::MAX,
a in u16::MIN..u16::MAX,
b in u16::MIN..u16::MAX,
) {
let _: [u16;4] = <[u16;4] as Area<u16>>::zero();
let _: [u16;4] = <[u16;4] as Area<u16>>::from_position([a, b]);
let _: [u16;4] = <[u16;4] as Area<u16>>::from_size([a, b]);
let area: [u16;4] = [x, y, w, h];
let _ = area.expect_min(a, b);
let _ = area.xy();
let _ = area.wh();
let _ = area.xywh();
let _ = area.clip_h(a);
let _ = area.clip_w(b);
let _ = area.clip([a, b]);
let _ = area.set_w(a);
let _ = area.set_h(b);
let _ = area.x2();
let _ = area.y2();
let _ = area.lrtb();
let _ = area.center();
let _ = area.center_x(a);
let _ = area.center_y(b);
let _ = area.center_xy([a, b]);
let _ = area.centered();
}
}
}

33
output/src/direction.rs Normal file
View file

@ -0,0 +1,33 @@
use crate::*;
/// A cardinal direction.
#[derive(Copy, Clone, PartialEq)]
pub enum Direction { North, South, East, West, Above, Below }
impl Direction {
pub fn split_fixed <N: Coordinate> (self, area: impl Area<N>, a: N) -> ([N;4],[N;4]) {
let [x, y, w, h] = area.xywh();
match self {
North => ([x, y.plus(h).minus(a), w, a], [x, y, w, h.minus(a)]),
South => ([x, y, w, a], [x, y.plus(a), w, h.minus(a)]),
East => ([x, y, a, h], [x.plus(a), y, w.minus(a), h]),
West => ([x.plus(w).minus(a), y, a, h], [x, y, w.minus(a), h]),
Above | Below => (area.xywh(), area.xywh())
}
}
}
#[cfg(test)] mod test_op_transform {
use super::*;
use proptest::prelude::*;
proptest! {
#[test] fn test_direction (
x in u16::MIN..u16::MAX,
y in u16::MIN..u16::MAX,
w in u16::MIN..u16::MAX,
h in u16::MIN..u16::MAX,
a in u16::MIN..u16::MAX,
) {
for d in [North, South, East, West, Above, Below].iter() {
let _ = d.split_fixed([x, y, w, h], a);
}
}
}
}

View file

@ -1,6 +1,7 @@
//#![feature(lazy_type_alias)]
#![feature(type_alias_impl_trait)]
#![feature(impl_trait_in_assoc_type)]
mod direction; pub use self::direction::*;
mod coordinate; pub use self::coordinate::*;
mod size; pub use self::size::*;
mod area; pub use self::area::*;

View file

@ -1,20 +1,5 @@
use crate::*;
pub use self::Direction::*;
/// A cardinal direction.
#[derive(Copy, Clone, PartialEq)]
pub enum Direction { North, South, East, West, Above, Below }
impl Direction {
pub fn split_fixed <N: Coordinate> (self, area: impl Area<N>, a: N) -> ([N;4],[N;4]) {
let [x, y, w, h] = area.xywh();
match self {
North => ([x, (y+h).minus(a), w, a], [x, y, w, h.minus(a)]),
South => ([x, y, w, a], [x, y + a, w, h.minus(a)]),
East => ([x, y, a, h], [x + a, y, w.minus(a), h]),
West => ([(x+w).minus(a), y, a, h], [x, y, w - a, h]),
Above | Below => (area.xywh(), area.xywh())
}
}
}
pub use Direction::*;
/// A split or layer.
pub struct Bsp<X, Y>(Direction, X, Y);
impl<E: Output, A: Content<E>, B: Content<E>> Content<E> for Bsp<A, B> {

View file

@ -38,3 +38,26 @@ impl<N: Coordinate> Size<N> for [N;2] {
#[inline] fn x (&self) -> N { self[0] }
#[inline] fn y (&self) -> N { self[1] }
}
#[cfg(test)] mod test_size {
use super::*;
use proptest::prelude::*;
proptest! {
#[test] fn test_size (
x in u16::MIN..u16::MAX,
y in u16::MIN..u16::MAX,
a in u16::MIN..u16::MAX,
b in u16::MIN..u16::MAX,
) {
let size = [x, y];
let _ = size.w();
let _ = size.h();
let _ = size.wh();
let _ = size.clip_w(a);
let _ = size.clip_h(b);
let _ = size.expect_min(a, b);
let _ = size.to_area_pos();
let _ = size.to_area_size();
}
}
}