doors.rs
35.1 kB · rust · 1052 lines
1use mrlyrs::core::cell::{magic, merge, mosaic, remap, rot90_map, tile_map, Cell};2use mrlyrs::core::colors::Color;3use mrlyrs::core::ramp::Colorizer;4use mrlyrs::core::resample::{block, resample, Filter};5use mrlyrs::core::rng::Rng;6use mrlyrs::core::tensor::{Dtype, Tensor};7use mrlyrs::core::{gif, png, unpng};8use mrlyrs::gen::draw::ConfigNd;9use mrlyrs::gen::name::Tile as Name;10use mrlyrs::gen::recipe::{Catalog, Design, Group, Source, Tile as Recipe};11use mrlyrs::life::models::Config;12use mrlyrs::life::source::{Counts, Source as Seq};13use mrlyrs::math::bang::factory::MagicLayer;14use mrlyrs::math::bang::Code;15use mrlyrs::math::cell::models::{Cell2d, Cell3d, CellNd};16use mrlyrs::math::graph::models::{Branch, Network};17use mrlyrs::math::name::Bang;18use mrlyrs::math::name::{Named, Word};19use mrlyrs::math::shape::{Frac, Shape};20use mrlyrs::math::six::{Orientation, Projection};21use mrlyrs::{core, font, gen, life, math, num};22use std::panic::{catch_unwind, AssertUnwindSafe};23use std::str::FromStr;2425fn turn(rng: &mut Rng) -> usize {26 rng.below(4)27}2829fn square() -> Tensor {30 Tensor::of(vec![1, 2, 3, 4], vec![2, 2]).unwrap()31}3233fn unit_cell() -> Cell {34 Cell::new(math::atoms::ones_2d(2))35}3637fn empty_2d() -> Cell2d {38 Cell2d::new(Tensor::new(vec![0, 0])).unwrap()39}4041fn empty_3d() -> Cell3d {42 Cell3d::new(Tensor::new(vec![0, 0, 0])).unwrap()43}4445fn stray_network() -> Network {46 let mut net = Network::new(1);47 net.add_node(vec![0.0]).unwrap();48 net.branches.push(Branch {49 parent: 0,50 child: 9,51 radius: 1.0,52 });53 net54}5556fn lonely_network() -> Network {57 let mut net = Network::new(1);58 net.add_node(vec![0.0]).unwrap();59 net60}6162fn wild_shape() -> Shape {63 Shape::Ball {64 center: vec![Frac {65 num: 1,66 den: i64::MAX,67 }],68 radius: Frac::new(1, 2).unwrap(),69 }70}7172const BAD: &[(&str, fn())] = &[73 // CORE74 ("core::tensor::of, a short buffer", || {75 let _ = Tensor::of(vec![1, 2, 3], vec![2, 2]);76 }),77 ("core::tensor::of, a long buffer", || {78 let _ = Tensor::of(vec![1, 2, 3, 4, 5], vec![2, 2]);79 }),80 ("core::tensor::rot90, an axis past the rank", || {81 let _ = square().rot90(1, (0, 2));82 }),83 ("core::tensor::rot90, one axis twice", || {84 let _ = square().rot90(1, (1, 1));85 }),86 ("core::tensor::tile, too few reps", || {87 let _ = square().tile(&[2]);88 }),89 ("core::tensor::tile, no reps", || {90 let _ = square().tile(&[]);91 }),92 ("core::tensor::get, an index of the wrong rank", || {93 let _ = square().get(&[0]);94 }),95 ("core::tensor::get, an index past the extent", || {96 let _ = square().get(&[2, 0]);97 }),98 ("core::tensor::set, an index past the extent", || {99 let _ = square().set(&[0, 2], 9);100 }),101 ("core::tensor::bytes, a wide tensor", || {102 let _ = Tensor::typed(vec![2, 2], Dtype::U16).bytes();103 }),104 ("core::tensor::bytes_mut, a wide tensor", || {105 let _ = Tensor::typed(vec![2, 2], Dtype::I32).bytes_mut();106 }),107 ("core::tensor::flip, an axis past the rank", || {108 let _ = square().flip(2);109 }),110 ("core::tensor::transpose, an axis past the rank", || {111 let _ = square().transpose(0, 2);112 }),113 ("core::cell::rot90_map, one axis twice", || {114 let _ = rot90_map(&[3, 3], 1, (0, 0));115 }),116 ("core::cell::tile_map, too many reps", || {117 let _ = tile_map(&[3, 3], &[2, 2, 2]);118 }),119 ("core::cell::remap, a map shorter than the cell", || {120 let _ = remap(&unit_cell(), &[0, 1, 2], &[2, 2]);121 }),122 ("core::cell::merge, no cells", || {123 let _ = merge(&[], &[1]);124 }),125 ("core::cell::merge, reps that do not hold the cells", || {126 let _ = merge(&[unit_cell(), unit_cell()], &[2]);127 }),128 ("core::cell::mosaic, a mask past the cell list", || {129 let mask = Tensor::of(vec![0, 2, 0, 0], vec![2, 2]).unwrap();130 let _ = mosaic(&mask, std::slice::from_ref(&unit_cell()));131 }),132 ("core::cell::magic, one layer", || {133 let _ = magic(&[unit_cell()]);134 }),135 ("core::colors::from_hex, a non-ascii hex", || {136 let _ = Color::from_hex("a\u{e9}bcd");137 }),138 ("core::colors::from_hex, an emoji", || {139 let _ = Color::from_hex("\u{1f600}\u{1f600}");140 }),141 ("core::colors::from_hex, an empty text", || {142 let _ = Color::from_hex("");143 }),144 ("core::colors::to_hex, a transparent color", || {145 let _ = Color::rgba(0, 0, 0, 0).to_hex();146 }),147 ("core::codec::png, a zero scale", || {148 let _ = png(&[[0, 0, 0, 255]], 1, 1, 0);149 }),150 (151 "core::codec::png, a size that is not the pixel count",152 || {153 let _ = png(&[[0, 0, 0, 255]], 2, 2, 1);154 },155 ),156 ("core::codec::png, no pixels", || {157 let _ = png(&[], 0, 0, 1);158 }),159 ("core::codec::png, a scale past the width", || {160 let _ = png(&[[0, 0, 0, 255]], 1, 1, 1 << 40);161 }),162 ("core::codec::unpng, no bytes", || {163 let _ = unpng(&[]);164 }),165 ("core::codec::unpng, bytes that are not a png", || {166 let _ = unpng(b"not a png at all");167 }),168 ("core::codec::gif, a zero delay", || {169 let _ = gif(&[&[0u8, 1, 1, 0][..]], &[[0, 0, 0, 255]], 2, 2, 0, 5);170 }),171 ("core::codec::gif, no frames", || {172 let _ = gif(&[], &[[0, 0, 0, 255]], 2, 2, 1, 5);173 }),174 ("core::codec::gif, an empty palette", || {175 let _ = gif(&[&[0u8, 1, 1, 0][..]], &[], 2, 2, 1, 5);176 }),177 ("core::codec::gif, an index past the palette", || {178 let _ = gif(&[&[0u8, 1, 2, 0][..]], &[[0, 0, 0, 255]], 2, 2, 1, 5);179 }),180 ("core::ramp::color, a zero maximum", || {181 let _ = Colorizer::heat().color(usize::MAX, 0);182 }),183 ("core::resample::resample, a zero target", || {184 let _ = resample(&[[0u8, 0, 0, 255]; 4], 2, 2, 0, 4, Filter::Nearest);185 }),186 (187 "core::resample::resample, a size that is not the pixels",188 || {189 let _ = resample(&[[0u8, 0, 0, 255]; 4], 3, 2, 4, 4, Filter::Nearest);190 },191 ),192 ("core::resample::resample, a target past the width", || {193 let _ = resample(&[[0u8, 0, 0, 255]; 4], 2, 2, usize::MAX, 2, Filter::Nearest);194 }),195 (196 "core::resample::block, a size that is not the buffer",197 || {198 let _ = block(&[1u8, 2, 3], 2, 2, 1);199 },200 ),201 ("core::resample::block, a factor past the width", || {202 let _ = block(&[1u8, 2, 3, 4], 2, 2, usize::MAX);203 }),204 ("core::rng::choice, an empty slice", || {205 let empty: [usize; 0] = [];206 let _ = Rng::new(2).choice(&empty);207 }),208 ("core::rng::below, a zero bound", || {209 let _ = Rng::new(2).below(0);210 }),211 ("core::rng::range, a high below the low", || {212 let _ = Rng::new(2).range(9, 1);213 }),214 ("core::rng::sample_indices, more than there are", || {215 let _ = Rng::new(2).sample_indices(2, 9);216 }),217 // NUM218 ("num::factor::factorial, one past the ceiling", || {219 let _ = num::factor::factorial(35);220 }),221 ("num::factor::factorial, a four byte maximum", || {222 let _ = num::factor::factorial(u32::MAX as usize);223 }),224 ("num::factor::gcd, two zeroes", || {225 let _ = num::factor::gcd(0, 0);226 }),227 ("num::factor::gcd, the widest pair", || {228 let _ = num::factor::gcd(u128::MAX, u128::MAX);229 }),230 ("num::factor::divisors, a zero", || {231 let _ = num::factor::divisors(0);232 }),233 ("num::factor::mobius, a zero", || {234 let _ = num::factor::mobius(0);235 }),236 ("num::prime::is_prime, the widest number", || {237 let _ = num::prime::is_prime(usize::MAX);238 }),239 ("num::series::zeta, an s of one", || {240 let _ = num::series::zeta(1.0, 10);241 }),242 ("num::series::zeta, an s that is not a number", || {243 let _ = num::series::zeta(f64::NAN, 10);244 }),245 ("num::series::visible, a zero dimension", || {246 let _ = num::series::visible(10, 0);247 }),248 ("num::series::bernoulli, a count past thirty two", || {249 let _ = num::series::bernoulli(33);250 }),251 ("num::lattice::zeta_whole, an s of one", || {252 let _ = num::lattice::zeta_whole(1);253 }),254 ("num::lattice::visible_density, a dimension of one", || {255 let _ = num::lattice::visible_density(1);256 }),257 ("num::blend::decimate, a zero step", || {258 let _ = num::blend::decimate(&[1, 2, 3], 0, 0);259 }),260 ("num::blend::sigma, a sum past the width", || {261 let _ = num::blend::sigma(&[i128::MAX, 1]);262 }),263 (264 "num::design::peaks, an axis shorter than the scores",265 || {266 let _ = num::design::peaks(&[1.0, 2.0], &[1.0, 2.0, 3.0], (0.0, 1.0), 0.5);267 },268 ),269 (270 "num::design::spectrum, a pole list under the samples",271 || {272 let _ = num::design::spectrum(&[0.0, 1.0], &[1.0, 2.0, 3.0, 4.0]);273 },274 ),275 ("num::fft::fft, two buffers of unequal length", || {276 let mut re = vec![0.0; 8];277 let mut im = vec![0.0; 4];278 let _ = num::fft::fft(&mut re, &mut im, false);279 }),280 ("num::fft::fft, a length that is not a power of two", || {281 let mut re = vec![0.0; 6];282 let mut im = vec![0.0; 6];283 let _ = num::fft::fft(&mut re, &mut im, false);284 }),285 (286 "num::fft::fft2, a buffer that is not the side squared",287 || {288 let mut re = vec![0.0; 9];289 let mut im = vec![0.0; 9];290 let _ = num::fft::fft2(&mut re, &mut im, 4, false);291 },292 ),293 (294 "num::fft::transform, a buffer that is not the side squared",295 || {296 let _ = num::fft::transform(&[1.0; 9], 4);297 },298 ),299 ("num::fft::embed_kernel, an even mask side", || {300 let _ = num::fft::embed_kernel(&[1; 4], 2, 8);301 }),302 ("num::fft::embed_kernel, a mask past the field", || {303 let _ = num::fft::embed_kernel(&[1; 81], 9, 8);304 }),305 (306 "num::fft::convolve, a kernel that is not the side squared",307 || {308 let _ = num::fft::convolve(&[1.0; 16], &[1.0; 9], 4);309 },310 ),311 ("num::ladder::Design::new, a digit past the base", || {312 let _ = num::ladder::Design::new(5, &[3]);313 }),314 (315 "num::ladder::Design::with_peel, a digit past the base",316 || {317 let _ = num::ladder::Design::with_peel(5, &[0, 7], 3);318 },319 ),320 ("num::memory::Rule::new, a zero dimension", || {321 let _ = num::memory::Rule::new(0, 1, 0);322 }),323 ("num::memory::Rule::new, a code past its width", || {324 let _ = num::memory::Rule::new(1, 2, 16);325 }),326 (327 "num::memory::Rule::full, a width past the dimension",328 || {329 let _ = num::memory::Rule::full(3, 3);330 },331 ),332 ("num::radix::Base::new, a unit base", || {333 let _ = num::radix::Base::new(num::gauss::Ring::Gaussian, (1, 0));334 }),335 ("num::radix::tile, an m of twelve", || {336 let _ = num::radix::tile(12, 1);337 }),338 ("num::radix::tile, a code past its range", || {339 let _ = num::radix::tile(3, 1 << 9);340 }),341 ("num::sieve::side, a letter that is not odd", || {342 let _ = num::sieve::side(&[4]);343 }),344 ("num::sieve::raster, a letter that is not odd", || {345 let _ = num::sieve::raster(&[0]);346 }),347 ("num::sieve::punctures, a letter that is not odd", || {348 let _ = num::sieve::punctures(&[2], 2);349 }),350 ("num::blend::cauchy, a sum past the width", || {351 let _ = num::blend::cauchy(&[i128::MAX, 1], &[2, 1]);352 }),353 ("num::lattice::recovered, a zero dimension", || {354 let _ = num::lattice::recovered(10, 0);355 }),356 (357 "num::fft::magnitude_spectrum, a buffer that is not the side squared",358 || {359 let _ = num::fft::magnitude_spectrum(&[1.0; 9], 4);360 },361 ),362 (363 "num::fft::radial_profile, a buffer that is not the side squared",364 || {365 let _ = num::fft::radial_profile(&[1.0; 9], 4);366 },367 ),368 (369 "num::fft::convolve_with, a field that is not the side squared",370 || {371 let _ = num::fft::convolve_with(&[1.0; 9], &[1.0; 16], &[1.0; 16], 4);372 },373 ),374 ("num::sieve::cells, a letter that is not odd", || {375 let _ = num::sieve::cells(&[4], 2);376 }),377 ("num::sieve::holes, a letter that is not odd", || {378 let _ = num::sieve::holes(&[4, 3], 2);379 }),380 ("num::sieve::limit, a letter that is not odd", || {381 let _ = num::sieve::limit(&[4, 6], 2);382 }),383 (384 "num::radix::Radix::from_code, a code past its range",385 || {386 let base = num::radix::Base::new(num::gauss::Ring::Eisenstein, (3, 0)).unwrap();387 let _ = num::radix::Radix::from_code(base, 1 << 9);388 },389 ),390 (391 "num::radix::Radix::new, digits that do not cover the residues",392 || {393 let base = num::radix::Base::new(num::gauss::Ring::Eisenstein, (3, 0)).unwrap();394 let _ = num::radix::Radix::new(base, vec![(0, 0), (1, 0)], vec![(1, 0); 3]);395 },396 ),397 ("num::radix::with_twists, a twist past the digits", || {398 let _ = num::radix::twindragon().unwrap().with_twists(&[0, 9]);399 }),400 ("num::memory::Rule::full, a zero dimension", || {401 let _ = num::memory::Rule::full(0, 1);402 }),403 ("num::ladder::Design::new, a base of one", || {404 let _ = num::ladder::Design::new(1, &[0, 1]);405 }),406 // MATH407 ("math::atoms::carpet_2d, a zero side", || {408 let _ = math::atoms::carpet_2d(0);409 }),410 (411 "math::spectrum::symmetric_eigenvalues, a crooked matrix",412 || {413 let _ = math::spectrum::symmetric_eigenvalues(&[vec![1.0, 2.0]]);414 },415 ),416 ("math::spectrum::symmetric_eigenvalues, a nan", || {417 let _ = math::spectrum::symmetric_eigenvalues(&[vec![f64::NAN]]);418 }),419 (420 "math::spectrum::clusters, a nan in the sorted slice",421 || {422 let _ = math::spectrum::clusters(&[0.0, f64::NAN], 1e-9);423 },424 ),425 (426 "math::spectrum::laplacian_spectrum, a lone node normalised",427 || {428 let _ = math::spectrum::laplacian_spectrum(&lonely_network(), true);429 },430 ),431 (432 "math::spin::arcs, a raster that is not the side squared",433 || {434 let _ = math::spin::arcs(&[1.0f32; 15], 4, 1.0);435 },436 ),437 (438 "math::spin::profile, a raster that is not the side squared",439 || {440 let _ = math::spin::profile(&[1.0f32; 15], 4, 8);441 },442 ),443 (444 "math::moire::field::from_data, a count that is not the side squared",445 || {446 let _ = math::moire::field::Field::from_data(vec![0.0; 3], 2);447 },448 ),449 ("math::moire::pairs::sampled, a zero scale", || {450 let _ = math::moire::pairs::sampled(0, 3);451 }),452 ("math::graph::models::add_node, a stray dimension", || {453 let _ = Network::new(2).add_node(vec![0.0]);454 }),455 (456 "math::graph::models::add_branch, a node past the list",457 || {458 let _ = Network::new(2).add_branch(0, 5, 1.0);459 },460 ),461 (462 "math::graph::models::degree, a branch past the nodes",463 || {464 let _ = stray_network().degree();465 },466 ),467 (468 "math::graph::census::census, a branch past the nodes",469 || {470 let _ = math::graph::census::census(&stray_network());471 },472 ),473 (474 "math::cell::models::Cell2d::new, a tensor of rank three",475 || {476 let _ = Cell2d::new(Tensor::new(vec![2, 2, 2]));477 },478 ),479 (480 "math::cell::models::Cell3d::new, a tensor of rank two",481 || {482 let _ = Cell3d::new(Tensor::new(vec![2, 2]));483 },484 ),485 (486 "math::cell::models::CellNd::new, a tensor of the wrong rank",487 || {488 let _ = CellNd::<1>::new(Tensor::new(vec![2, 2]));489 },490 ),491 ("math::two::carpet, a zero side", || {492 let _ = math::two::carpet(0, 1);493 }),494 ("math::two::carpet, a zero level", || {495 let _ = math::two::carpet(3, 0);496 }),497 ("math::two::to_json, an empty cell", || {498 let _ = math::two::to_json(&empty_2d());499 }),500 ("math::two::census, an empty cell", || {501 let _ = math::two::census::census(&empty_2d());502 }),503 ("math::three::census::surface, an empty cell", || {504 let _ = math::three::census::surface(&empty_3d());505 }),506 (507 "math::counts::counting::fill, a code past its range",508 || {509 let _ = math::counts::counting::fill(Code::from(16u64), 3, 2, 1, 2);510 },511 ),512 ("math::counts::counting::fill, a dimension of seven", || {513 let _ = math::counts::counting::fill(Code::from(1u64), 3, 7, 1, 2);514 }),515 ("math::counts::counting::limit, a level past a u128", || {516 let _ = math::counts::counting::limit(Code::from(7u64), 2, 1000, 2);517 }),518 ("math::bang::bang, a zero dimension", || {519 let _ = math::bang::universe::bang(0);520 }),521 ("math::bang::bang, a dimension of five", || {522 let _ = math::bang::universe::bang(5);523 }),524 ("math::bang::Universe::distinct, the plane", || {525 let _ = math::bang::universe::bang(2).unwrap().distinct();526 }),527 ("math::bang::baseq::canonical, an empty group", || {528 let _ = math::bang::baseq::canonical(&[], Code::from(1u64));529 }),530 (531 "math::bang::baseq::group_order, a dimension past the factorial",532 || {533 let _ = math::bang::baseq::group_order(2, 35);534 },535 ),536 (537 "math::bang::baseq::predicted_group_order, a dimension past the factorial",538 || {539 let _ = math::bang::baseq::predicted_group_order(2, 35);540 },541 ),542 (543 "math::bang::baseq::group_order, a dimension past a u128",544 || {545 let _ = math::bang::baseq::group_order(2, 200);546 },547 ),548 (549 "math::bang::baseq::predicted_group_order, a dimension past a u128",550 || {551 let _ = math::bang::baseq::predicted_group_order(3, 200);552 },553 ),554 (555 "math::bang::baseq::total_designs, a dimension of seven",556 || {557 let _ = math::bang::baseq::total_designs(2, 7);558 },559 ),560 (561 "math::bang::catalog::universe_codes, a dimension of five",562 || {563 let _ = math::bang::catalog::universe_codes(5);564 },565 ),566 (567 "math::bang::factory::code_to_corners, a code one past the corners",568 || {569 let _ = math::bang::factory::code_to_corners(Code::from(16u64), 2, 2);570 },571 ),572 (573 "math::bang::factory::code_to_corners, a dimension of seven",574 || {575 let _ = math::bang::factory::code_to_corners(Code::from(1u64), 7, 2);576 },577 ),578 (579 "math::bang::factory::total_codes, a dimension of seven",580 || {581 let _ = math::bang::factory::total_codes(7, 2);582 },583 ),584 ("math::bang::factory::magic, no layers", || {585 let _ = math::bang::factory::magic(&[]);586 }),587 ("math::six::geometry::blank, a zero radius", || {588 let _ = math::six::geometry::blank(0, Orientation::Horizontal, 1, 0);589 }),590 ("math::six::star::Star::new, a code past its range", || {591 let _ = math::six::star::Star::new(1 << 9);592 }),593 (594 "math::press::Press::new, a universe past its corners",595 || {596 let _ = math::press::Press::new(7, 2);597 },598 ),599 ("math::press::interleave, an empty weave", || {600 let _ = math::press::interleave(&[], 2);601 }),602 ("math::rules::render, a zero number", || {603 let _ = math::rules::render(|_| true, 0, 2, 2);604 }),605 ("math::shape::Frac::new, a zero denominator", || {606 let _ = Frac::new(1, 0);607 }),608 ("math::shape::Frac::plus, a sum past an i64", || {609 let _ = Frac::whole(i64::MAX).plus(Frac::whole(i64::MAX));610 }),611 ("math::shape::classify, a center past an i64", || {612 let _ = math::shape::classify(&wild_shape(), 1, &[0]);613 }),614 ("math::shape::census, a center past an i64", || {615 let _ = math::shape::census(&wild_shape(), &math::atoms::ones_2d(1));616 }),617 ("math::name::Bang::from_json, an empty text", || {618 let _ = math::name::Bang::from_json("");619 }),620 ("math::name::Bang::from_json, a code past its range", || {621 let _ = math::name::Bang::from_json(r#"{"kind":"bang","dim":2,"code":16}"#);622 }),623 ("math::name::Sequence::from_json, an empty text", || {624 let _ = math::name::Sequence::from_json("");625 }),626 ("math::name::Word::from_json, an empty text", || {627 let _ = Word::from_json("");628 }),629 (630 "math::name::Word::new, a letter the grammar cannot draw",631 || {632 let _ = Word::new(2, &[(7, 3)]);633 },634 ),635 ("math::name::Bang::from_json, a text without a kind", || {636 let _ = math::name::Bang::from_json("{}");637 }),638 ("math::name::Bang::from_json, a broken json", || {639 let _ = math::name::Bang::from_json(r#"{"kind":"bang""#);640 }),641 (642 "math::spin::ring, a raster that is not the side squared",643 || {644 let _ = math::spin::ring(&[1.0f32; 15], 4, 1.0);645 },646 ),647 (648 "math::spin::harmonics, a raster that is not the side squared",649 || {650 let _ = math::spin::harmonics(&[1.0f32; 15], 4, 8, 4);651 },652 ),653 ("math::spectrum::laplacian, a lone node normalised", || {654 let _ = math::spectrum::laplacian(&lonely_network(), true);655 }),656 ("math::graph::census::tips, a branch past the nodes", || {657 let _ = math::graph::census::tips(&stray_network());658 }),659 (660 "math::graph::census::components, a branch past the nodes",661 || {662 let _ = math::graph::census::components(&stray_network());663 },664 ),665 (666 "math::graph::models::adjacency, a branch past the nodes",667 || {668 let _ = stray_network().adjacency();669 },670 ),671 ("math::moire::pairs::sampled, a zero second scale", || {672 let _ = math::moire::pairs::sampled(3, 0);673 }),674 (675 "math::counts::counting::void, a code past its range",676 || {677 let _ = math::counts::counting::void(Code::from(16u64), 3, 2, 1, 2);678 },679 ),680 (681 "math::counts::counting::ratio, a code past its range",682 || {683 let _ = math::counts::counting::ratio(Code::from(16u64), 3, 2, 1, 2);684 },685 ),686 (687 "math::counts::counting::rational, a code past its range",688 || {689 let _ = math::counts::counting::rational(Code::from(16u64), 3, 2, 1, 2);690 },691 ),692 (693 "math::counts::counting::dimension, a code past its range",694 || {695 let _ = math::counts::counting::dimension(Code::from(16u64), 3, 2, 2);696 },697 ),698 (699 "math::bang::baseq::representatives, a walk past the limit",700 || {701 let _ = math::bang::baseq::representatives(3, 4);702 },703 ),704 ("math::bang::catalog::sources, a dimension of five", || {705 let _ = math::bang::catalog::sources(&Catalog::Universe, 5);706 }),707 (708 "math::bang::word::components, layers of two dimensions",709 || {710 let plane = MagicLayer::new(Bang::new(7, 2, 2), 3);711 let cube = MagicLayer::new(Bang::new(23, 3, 2), 3);712 let _ = math::bang::word::components(&[plane, cube]);713 },714 ),715 ("math::bang::word::fill, no layers", || {716 let _ = math::bang::word::fill(&[]);717 }),718 ("math::press::usage, a dimension of seven", || {719 let _ = math::press::usage(1, 7, 2);720 }),721 ("math::press::word_member, no layers", || {722 let _ = math::press::word_member(&[], 0);723 }),724 ("math::six::raster::raster, a zero size", || {725 let cell = math::six::cut_design(Code::from(23u64), 3, 1, 2).unwrap();726 let _ = math::six::raster::raster(&cell, 0);727 }),728 ("math::six::star::hexagon, an even layer", || {729 let _ = math::six::star::Star::new(23).unwrap().hexagon(4);730 }),731 ("math::six::star::arm, a zero layer", || {732 let _ = math::six::star::Star::new(23).unwrap().arm(0, 0);733 }),734 ("math::shape::named, a box past an i64", || {735 let _ = math::shape::named("box", 2, Frac::whole(i64::MAX));736 }),737 ("math::shape::refine, a zero base", || {738 let ball = math::shape::named("ball", 2, Frac::new(1, 2).unwrap()).unwrap();739 let _ = math::shape::refine(&math::atoms::ones_2d(3), &ball, 0, 1, false);740 }),741 ("math::shape::regions, a center past an i64", || {742 let _ = math::shape::regions(&wild_shape(), &[1]);743 }),744 ("math::shape::crop, a center past an i64", || {745 let _ = math::shape::crop(&math::atoms::ones_2d(1), &wild_shape(), true);746 }),747 ("math::rules::render, a zero dimension", || {748 let _ = math::rules::render(|_| true, 3, 0, 2);749 }),750 ("math::rules::render, a zero base", || {751 let _ = math::rules::render(|_| true, 3, 2, 0);752 }),753 (754 "math::name::Sequence::from_json, a measure the axis has not",755 || {756 let _ = math::name::Sequence::from_json(757 r#"{"kind":"sequence","dim":2,"code":7,"measure":"area","axis":"side"}"#,758 );759 },760 ),761 (762 "math::name::Word::new, a letter past the code range",763 || {764 let _ = Word::new(2, &[(273, 3), (9, 2)]);765 },766 ),767 // LIFE768 ("life::animate, an even mask", || {769 let even = Cell2d::new(Tensor::full(vec![2, 2], 1)).unwrap();770 let config = Config::new(even, vec![3], vec![2, 3]);771 let seed = Cell2d::new(Tensor::full(vec![3, 3], 1)).unwrap();772 let _ = life::animate(&seed, &config);773 }),774 (775 "life::elementary::history, a row that is not binary",776 || {777 let _ = life::elementary::history(&[0, 2, 0], 90, 1, false);778 },779 ),780 ("life::elementary::step, a row that is not binary", || {781 let _ = life::elementary::step(&[1, 0, 9], 90, true);782 }),783 ("life::mask::design_mask, a code past its range", || {784 let _ = life::mask::design_mask(2, Code::from(7u64), 4, 1);785 }),786 ("life::mask::design_mask, a zero level", || {787 let _ = life::mask::design_mask(1, Code::from(1u64), 3, 0);788 }),789 ("life::render::heatmap, a zero scale", || {790 let _ = life::render::heatmap(&[empty_2d()], 0);791 }),792 ("life::render::heatmap, grids of two sizes", || {793 let odd = Cell2d::new(Tensor::new(vec![3, 3])).unwrap();794 let _ = life::render::heatmap(&[empty_2d(), odd], 4);795 }),796 ("life::source::counts, a code past the universe", || {797 let _ = life::source::counts(Seq::CodeFills(1 << 20), 8, true, true);798 }),799 (800 "life::source::Counts::values, a code past the universe",801 || {802 let _ = Counts::drawn(Seq::CodeFills(1 << 20), false, false).values(8);803 },804 ),805 ("life::metrics::entropy, an empty grid", || {806 let _ = life::metrics::entropy(&empty_2d());807 }),808 ("life::metrics::churn, no grids", || {809 let _ = life::metrics::churn(&[]);810 }),811 (812 "life::mask::design_mask, a dimension the lattice has not",813 || {814 let _ = life::mask::design_mask(3, Code::from(7u64), 3, 1);815 },816 ),817 ("life::mask::design_mask, a level past the grid", || {818 let _ = life::mask::design_mask(2, Code::from(7u64), 3, 1000);819 }),820 (821 "life::source::counts, a void code past the universe",822 || {823 let _ = life::source::counts(Seq::CodeVoids(1 << 20), 8, true, true);824 },825 ),826 (827 "life::models::Config::counts, a drawn source past the universe",828 || {829 let mask = Cell2d::new(Tensor::full(vec![3, 3], 1)).unwrap();830 let drawn = Counts::drawn(Seq::CodeFills(1 << 20), false, false);831 let _ = Config::new(mask, drawn, vec![2, 3]).counts();832 },833 ),834 // FONT835 ("font::glyph, a char the alphabet has not", || {836 let _ = font::glyph('\u{1f600}');837 }),838 ("font::supported, the whole alphabet", || {839 let _ = font::supported();840 }),841 ("font::raster::raster, an empty text", || {842 let _ = font::raster::raster("");843 }),844 ("font::raster::raster, a char the alphabet has not", || {845 let _ = font::raster::raster("\u{1f600}");846 }),847 ("font::paths::path, a char the alphabet has not", || {848 let _ = font::paths::path('\u{1f600}');849 }),850 ("font::paths::floor, no rows", || {851 let _ = font::paths::floor(&[]);852 }),853 ("font::paths::draft, no rows", || {854 let _ = font::paths::draft(&[]);855 }),856 ("font::animate::animate, an empty text", || {857 let _ = font::animate::animate("", 0);858 }),859 ("font::animate::merge, an empty text", || {860 let _ = font::animate::merge("", 0);861 }),862 ("font::animate::cycle, an empty merge", || {863 let _ = font::animate::cycle(&font::animate::animate("a", 1), &[], 1);864 }),865 ("font::animate::cycle, an empty write", || {866 let _ = font::animate::cycle(&font::animate::animate("", 0), &[vec![0]], 1);867 }),868 // GEN869 ("gen::background, a zero width", || {870 let _ = gen::background(7, 0, 3);871 }),872 ("gen::background, a zero height", || {873 let _ = gen::background(7, 2, 0);874 }),875 ("gen::recipe::Tile::new, a recipe with no slots", || {876 let _ = Recipe::new(Group::General).check();877 }),878 ("gen::recipe::Tile::size, sizes that disagree", || {879 let _ = Recipe::new(Group::General).size(5, 5).check();880 }),881 ("gen::draw::create, a config that draws no tile", || {882 let narrow: ConfigNd<2> = ConfigNd {883 min_size: 9,884 max_size: 3,885 ..Default::default()886 };887 let _ = gen::draw::create(&narrow, turn, &mut Rng::new(1));888 }),889 ("gen::draw::create, a config with no catalog", || {890 let sourceless: ConfigNd<2> = ConfigNd {891 catalog: Catalog::Codes(Vec::new()),892 ..Default::default()893 };894 let _ = gen::draw::create(&sourceless, turn, &mut Rng::new(1));895 }),896 ("gen::draw::random_tile, a size below the floor", || {897 let _ = gen::draw::random_tile::<2>(1, turn, &mut Rng::new(1));898 }),899 ("gen::build::build_2d, a recipe with no slots", || {900 let _ = gen::build::build_2d(&Recipe::new(Group::General));901 }),902 ("gen::build::build_2d, a cubic design in the plane", || {903 let mut cubic = Recipe::new(Group::General);904 cubic.sources = vec![Source::Classic(Design::Xtree)];905 cubic.numbers = vec![3];906 cubic.levels = vec![1];907 cubic.rotations = vec![0];908 cubic.anti = vec![false];909 cubic.resize();910 let _ = gen::build::build_2d(&cubic);911 }),912 ("gen::build::build_3d, a recipe with no slots", || {913 let _ = gen::build::build_3d(&Recipe::new(Group::General));914 }),915 ("gen::build::build_6d, a recipe with no slots", || {916 let bare = gen::build::HexTile {917 projection: Projection::Iso,918 tile: Recipe::new(Group::General),919 };920 let _ = gen::build::build_6d(&bare);921 }),922 ("gen::name::Tile::of, a recipe with no slots", || {923 let _ = Name::of(&Recipe::new(Group::General));924 }),925 ("gen::name::Tile::from_json, an empty text", || {926 let _ = Name::from_json("");927 }),928 ("gen::name::Tile::from_json, a code past its range", || {929 let _ = Name::from_json(r#"{"kind":"tile","code":16,"side":3}"#);930 }),931 (932 "gen::variation::create, a config that draws no tile",933 || {934 let _ = gen::variation::create(&gen::variation::Config::default(), &mut Rng::new(5));935 },936 ),937 ("gen::draw::create, a config with no groups", || {938 let groupless: ConfigNd<2> = ConfigNd {939 groups: Vec::new(),940 ..Default::default()941 };942 let _ = gen::draw::create(&groupless, turn, &mut Rng::new(1));943 }),944 ("gen::build::build_3d, a flat design in the cube", || {945 let mut flat = Recipe::new(Group::General);946 flat.sources = vec![Source::Classic(Design::Htree)];947 flat.numbers = vec![3];948 flat.levels = vec![1];949 flat.rotations = vec![0];950 flat.anti = vec![false];951 flat.resize();952 let _ = gen::build::build_3d(&flat);953 }),954 (955 "gen::variation::create, a config that draws no tile",956 || {957 let narrow = gen::variation::Config {958 tile: ConfigNd {959 min_size: 9,960 max_size: 3,961 ..Default::default()962 },963 ..Default::default()964 };965 let _ = gen::variation::create(&narrow, &mut Rng::new(5));966 },967 ),968 ("gen::variation::create, a config with no catalog", || {969 let sourceless = gen::variation::Config {970 tile: ConfigNd {971 catalog: Catalog::Codes(Vec::new()),972 ..Default::default()973 },974 ..Default::default()975 };976 let _ = gen::variation::create(&sourceless, &mut Rng::new(5));977 }),978 (979 "gen::name::Tile::from_json, a side the design has not",980 || {981 let _ = Name::from_json(r#"{"kind":"tile","code":7,"side":99}"#);982 },983 ),984 (985 "gen::name::Tile::from_json, a text that is not json",986 || {987 let _ = Name::from_json("tile code 7, side 3, level 2");988 },989 ),990 // FROM STR991 ("math::bang::Code::from_str, an empty text", || {992 let _ = Code::from_str("");993 }),994 ("gen::recipe::Group::from_str, an empty text", || {995 let _ = Group::from_str("");996 }),997 ("gen::recipe::Parity::from_str, an empty text", || {998 let _ = mrlyrs::gen::recipe::Parity::from_str("");999 }),1000 (1001 "math::bang::catalog::Design::from_str, an empty text",1002 || {1003 let _ = Design::from_str("");1004 },1005 ),1006 (1007 "math::bang::word::Schedule::from_str, an empty text",1008 || {1009 let _ = math::bang::word::Schedule::from_str("");1010 },1011 ),1012 ("core::paint::Edition::from_str, an empty text", || {1013 let _ = core::paint::Edition::from_str("");1014 }),1015 ("core::paint::Ink::from_str, an empty text", || {1016 let _ = core::paint::Ink::from_str("");1017 }),1018 ("core::paint::Scheme::from_str, an empty text", || {1019 let _ = core::paint::Scheme::from_str("");1020 }),1021 ("core::paint::Target::from_str, an empty text", || {1022 let _ = core::paint::Target::from_str("");1023 }),1024 ("num::spiral::Lattice::from_str, an empty text", || {1025 let _ = num::spiral::Lattice::from_str("");1026 }),1027 ("num::spiral::Mark::from_str, an empty text", || {1028 let _ = num::spiral::Mark::from_str("");1029 }),1030 ("num::spiral::Growth::from_str, an empty text", || {1031 let _ = num::spiral::Growth::from_str("");1032 }),1033 ("num::morse::Lift::from_str, an empty text", || {1034 let _ = num::morse::Lift::from_str("");1035 }),1036 ("life::Fate::from_str, an empty text", || {1037 let _ = life::Fate::from_str("");1038 }),1039];10401041#[test]1042fn no_door_panics_on_a_bad_input() {1043 let hook = std::panic::take_hook();1044 std::panic::set_hook(Box::new(|_| {}));1045 let panicked: Vec<&str> = BAD1046 .iter()1047 .filter(|(_, call)| catch_unwind(AssertUnwindSafe(call)).is_err())1048 .map(|(name, _)| *name)1049 .collect();1050 std::panic::set_hook(hook);1051 assert!(panicked.is_empty(), "{panicked:?}");1052}