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}