### ----------------------------------------------------
### -- Math::Nearest
### -- Licenses: Artistic-2.0
### -- Authors: Anton Antonov
### -- File: t/01-Scan-method.rakutest
### ----------------------------------------------------
use v6.d;
use Test;

use lib <. lib>;

use Math::Nearest;
use Math::Nearest::Scan;
use Math::DistanceFunctions;

plan *;

my @points = ([(^100).rand, (^100).rand] xx 100).unique;

## 1
my $finder1;
$finder1 = Math::Nearest::Scan.new(@points);
isa-ok $finder1, Math::Nearest::Scan:D;

## 2
my @searchPoint1 = |@points.head;
is-deeply $finder1.k-nearest(@searchPoint1).Array, [@searchPoint1,];

## 3
my $radius3 = 12;
my @inBall3 = @points.grep({ euclidean-distance($_, @searchPoint1) ≤ $radius3 }).sort.Array;
is-deeply $finder1.nearest-within-ball(@searchPoint1, $radius3, :values).sort.Array, @inBall3;

## 4
# Make verification test with direct scanning of @points.
my @nns6 = |@points.sort({ sqrt [+] ($_.Array Z- @searchPoint1).map(* ** 2) });
is-deeply $finder1.k-nearest(@searchPoint1, 12, :!values).map({ $_<point>.value }), @nns6[^12];

## 5
my $finder5 = Math::Nearest::Scan.new(points => (3.rand xx 30), distance-function => 'euclidean-distance');
isa-ok $finder5.k-nearest(2, 2), Iterable;

## 6
isa-ok $finder5.nearest-within-ball(2, 1), Iterable;

## 7
# The method "Scan" is used for lists of strings it method => Whatever.
my @words7 = (('a'..'m').pick(4).join xx 20);
my &finder7 = nearest(@words7, method => Whatever);
isa-ok &finder7.finder, Math::Nearest::Scan;

done-testing;


