Algorithm-Classifier-IsolationForest
view release on metacpan or search on metacpan
t/90-cli-commands.t view on Meta::CPAN
#!perl
# 90-cli-commands.t
#
# Smoke-tests the iforest CLI subcommands by running bin/iforest in a
# subprocess against a temp model + CSV. We chain them through a
# realistic workflow:
#
# fit -> info
# -> bench
# -> pack -> predict (packed input)
# -> predict (raw CSV input, for regression baseline)
#
# Each subtest checks the relevant artefacts and output snippets but
# stays loose on the exact wording -- we want to catch breakage, not
# pin the formatting.
use strict;
use warnings;
use Test::More;
use File::Temp qw(tempdir);
use File::Spec;
my $bin = File::Spec->rel2abs('bin/iforest');
plan skip_all => "bin/iforest not found" unless -x $bin;
my $tmp = tempdir( CLEANUP => 1 );
# --- 1. Generate a tiny CSV training dataset ----------------------------
my $train_csv = "$tmp/train.csv";
my $query_csv = "$tmp/query.csv";
my $model = "$tmp/model.json";
my $packed = "$tmp/query.packed";
my $pred_csv = "$tmp/pred.csv";
my $pred2_csv = "$tmp/pred2.csv";
{
open my $fh, '>', $train_csv or die $!;
# 50 inliers around the origin + 3 outliers far away (3 features).
srand(1);
for ( 1 .. 50 ) {
print $fh join( ',', map { sprintf( '%.4f', rand() - 0.5 ) } 1 .. 3 ), "\n";
}
print $fh "8,8,8\n-7,-7,-7\n7,-7,7\n";
close $fh;
}
{
open my $fh, '>', $query_csv or die $!;
# 5 inliers + 2 outliers.
srand(2);
for ( 1 .. 5 ) {
print $fh join( ',', map { sprintf( '%.4f', rand() - 0.5 ) } 1 .. 3 ), "\n";
}
print $fh "9,9,9\n-8,-8,-8\n";
close $fh;
}
# --- 2. fit (a known-good command) --------------------------------------
subtest 'fit produces a model' => sub {
my $out = `$^X -Ilib $bin fit -i $train_csv -o $model -n 30 -m 16 -s 42 2>&1`;
is( $?, 0, 'fit exits 0' );
ok( -s $model, 'model.json was written' );
};
# --- 3. info ------------------------------------------------------------
subtest 'info dumps model metadata' => sub {
( run in 1.473 second using v1.01-cache-2.11-cpan-600a1bdf6e4 )