#![cfg(feature = "logging")]
use genetic_algorithms::chromosomes::Binary as BinaryChromosome;
use genetic_algorithms::configuration::ProblemSolving;
use genetic_algorithms::ga::Ga;
use genetic_algorithms::initializers::binary_random_initialization;
use genetic_algorithms::operations::{Crossover, Mutation, Selection, Survivor};
use genetic_algorithms::traits::{
ConfigurationT, CrossoverConfig, MutationConfig, SelectionConfig, StoppingConfig,
};
use genetic_algorithms::ChromosomeLength;
struct PanicLogger;
impl log::Log for PanicLogger {
fn enabled(&self, _metadata: &log::Metadata<'_>) -> bool {
true
}
fn log(&self, record: &log::Record<'_>) {
panic!(
"genetic_algorithms must not install or invoke a logger on the caller's behalf, \
but got a log record: [{level}] {message}",
level = record.level(),
message = record.args()
);
}
fn flush(&self) {}
}
static PANIC_LOGGER: PanicLogger = PanicLogger;
fn count_ones(genes: &[genetic_algorithms::genotypes::Binary]) -> f64 {
genes.iter().filter(|g| g.value).count() as f64
}
#[test]
fn ga_does_not_install_logger() {
let mut ga: Ga<BinaryChromosome> = Ga::new()
.with_population_size(4)
.with_chromosome_length(ChromosomeLength::Fixed(4))
.with_initialization_fn(binary_random_initialization)
.with_fitness_fn(count_ones)
.with_selection_method(Selection::Random)
.with_crossover_method(Crossover::Uniform)
.with_mutation_method(Mutation::BitFlip)
.with_survivor_method(Survivor::Fitness)
.with_problem_solving(ProblemSolving::Maximization)
.with_max_generations(1)
.build()
.expect("valid configuration");
let result = ga.run();
assert!(result.is_ok(), "GA run should complete without error");
log::set_logger(&PANIC_LOGGER).expect(
"global logger slot should still be free after Ga::run() — \
the library must not install env_logger or any other logger",
);
log::set_max_level(log::LevelFilter::Trace);
log::set_max_level(log::LevelFilter::Off);
}