205 lines
5.4 KiB
PHP
205 lines
5.4 KiB
PHP
|
<?php
|
|||
|
|
|||
|
declare(strict_types=1);
|
|||
|
|
|||
|
namespace CondorcetPHP\Condorcet\Tests;
|
|||
|
|
|||
|
use CondorcetPHP\Condorcet\{Condorcet, Result};
|
|||
|
use CondorcetPHP\Condorcet\Algo\{Method, MethodInterface};
|
|||
|
use CondorcetPHP\Condorcet\Throwable\AlgorithmException;
|
|||
|
|
|||
|
use PHPUnit\Framework\TestCase;
|
|||
|
|
|||
|
class CondorcetTest extends TestCase
|
|||
|
{
|
|||
|
public function testgetVersion(): void
|
|||
|
{
|
|||
|
self::assertSame(Condorcet::VERSION, CONDORCET::getVersion());
|
|||
|
self::assertMatchesRegularExpression('/^[1-9]+\.[0-9]+$/', CONDORCET::getVersion(true));
|
|||
|
}
|
|||
|
|
|||
|
public function testAddExistingMethod(): void
|
|||
|
{
|
|||
|
$algoClassPath = Condorcet::getDefaultMethod();
|
|||
|
|
|||
|
self::assertEquals($algoClassPath, Condorcet::getMethodClass($algoClassPath));
|
|||
|
|
|||
|
self::assertFalse(Condorcet::addMethod($algoClassPath));
|
|||
|
}
|
|||
|
|
|||
|
public function testBadClassMethod(): never
|
|||
|
{
|
|||
|
$this->expectException(AlgorithmException::class);
|
|||
|
$this->expectExceptionMessage("The voting algorithm is not available: no class found for 'sjskkdlkkzksh'");
|
|||
|
|
|||
|
Condorcet::addMethod('sjskkdlkkzksh');
|
|||
|
}
|
|||
|
|
|||
|
public function testAuthMethod(): void
|
|||
|
{
|
|||
|
self::assertFalse(Condorcet::isAuthMethod('skzljdpmzk'));
|
|||
|
self::assertNull(Condorcet::getMethodClass('skzljdpmzk'));
|
|||
|
self::assertSame(\CondorcetPHP\Condorcet\Algo\Methods\Schulze\SchulzeWinning::class, Condorcet::getMethodClass('Schulze Winning'));
|
|||
|
}
|
|||
|
|
|||
|
/**
|
|||
|
* @preserveGlobalState disabled
|
|||
|
* @backupStaticAttributes disabled
|
|||
|
* @runInSeparateProcess
|
|||
|
*/
|
|||
|
public function testAddMethod(): never
|
|||
|
{
|
|||
|
$this->expectException(AlgorithmException::class);
|
|||
|
$this->expectExceptionMessage('The voting algorithm is not available: the given class is using an existing alias');
|
|||
|
|
|||
|
$algoClassPath = CondorcetTest_ValidAlgorithmName::class;
|
|||
|
|
|||
|
self::assertTrue(Condorcet::addMethod($algoClassPath));
|
|||
|
|
|||
|
self::assertEquals($algoClassPath, Condorcet::getMethodClass($algoClassPath));
|
|||
|
|
|||
|
// Try to add existing alias
|
|||
|
$algoClassPath = CondorcetTest_DuplicateAlgorithmAlias::class;
|
|||
|
|
|||
|
self::assertFalse(Condorcet::addMethod($algoClassPath));
|
|||
|
}
|
|||
|
|
|||
|
public function testAddUnvalidMethod(): never
|
|||
|
{
|
|||
|
$this->expectException(AlgorithmException::class);
|
|||
|
$this->expectExceptionMessage('The voting algorithm is not available: the given class is not correct');
|
|||
|
|
|||
|
$algoClassPath = CondorcetTest_UnvalidAlgorithmName::class;
|
|||
|
|
|||
|
self::assertFalse(Condorcet::addMethod($algoClassPath));
|
|||
|
|
|||
|
self::assertSame(
|
|||
|
CondorcetTest_UnvalidAlgorithmName::class,
|
|||
|
Condorcet::getMethodClass('FirstMethodName')
|
|||
|
);
|
|||
|
}
|
|||
|
|
|||
|
public function testUnvalidDefaultMethod(): void
|
|||
|
{
|
|||
|
self::assertFalse(Condorcet::setDefaultMethod('dgfbdwcd'));
|
|||
|
}
|
|||
|
|
|||
|
public function testEmptyMethod(): never
|
|||
|
{
|
|||
|
$this->expectException(AlgorithmException::class);
|
|||
|
$this->expectExceptionMessage('The voting algorithm is not available: no method name given');
|
|||
|
|
|||
|
Condorcet::isAuthMethod('');
|
|||
|
}
|
|||
|
|
|||
|
public function testMethodAlias(): void
|
|||
|
{
|
|||
|
self::assertSame(
|
|||
|
\CondorcetPHP\Condorcet\Algo\Methods\KemenyYoung\KemenyYoung::class,
|
|||
|
Condorcet::getMethodClass('kemeny–Young')
|
|||
|
);
|
|||
|
|
|||
|
self::assertSame(
|
|||
|
\CondorcetPHP\Condorcet\Algo\Methods\KemenyYoung\KemenyYoung::class,
|
|||
|
Condorcet::getMethodClass('Maximum likelihood Method')
|
|||
|
);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
class CondorcetTest_ValidAlgorithmName extends Method implements MethodInterface
|
|||
|
{
|
|||
|
public const METHOD_NAME = ['FirstMethodName', 'Alias1', 'Alias_2', 'Alias 3'];
|
|||
|
|
|||
|
|
|||
|
// Get the Result object
|
|||
|
public function getResult($options = null): Result
|
|||
|
{
|
|||
|
// Cache
|
|||
|
if ($this->Result !== null) {
|
|||
|
return $this->Result;
|
|||
|
}
|
|||
|
|
|||
|
//////
|
|||
|
|
|||
|
// Ranking calculation
|
|||
|
$this->makeRanking();
|
|||
|
|
|||
|
// Return
|
|||
|
return $this->Result;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
// Compute the Stats
|
|||
|
protected function getStats(): array
|
|||
|
{
|
|||
|
return []; // You are free to do all you wants. Must be an array.;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
/////////// COMPUTE ///////////
|
|||
|
|
|||
|
|
|||
|
//:: ALGORITHM. :://
|
|||
|
|
|||
|
protected function makeRanking(): void
|
|||
|
{
|
|||
|
$this->selfElection->get()->getPairwise();
|
|||
|
|
|||
|
$result = [0=>1, 1=>2, 2=>3]; // Candidate must be valid candidates
|
|||
|
|
|||
|
$this->Result = $this->createResult($result);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
class CondorcetTest_DuplicateAlgorithmAlias extends CondorcetTest_ValidAlgorithmName implements MethodInterface
|
|||
|
{
|
|||
|
public const METHOD_NAME = ['SecondMethodName', 'Alias_2'];
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
class CondorcetTest_UnvalidAlgorithmName
|
|||
|
{
|
|||
|
public const METHOD_NAME = ['FirstMethodName', 'Alias1', 'Alias_2', 'Alias 3'];
|
|||
|
|
|||
|
|
|||
|
// Get the Result object
|
|||
|
public function getResult($options = null): Result
|
|||
|
{
|
|||
|
// Cache
|
|||
|
if ($thisResult !== null) {
|
|||
|
return $this->Result;
|
|||
|
}
|
|||
|
|
|||
|
// Ranking calculation
|
|||
|
$this->makeRanking();
|
|||
|
|
|||
|
// Return
|
|||
|
return $this->Result;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
// Compute the Stats
|
|||
|
protected function getStats(): array
|
|||
|
{
|
|||
|
return []; // You are free to do all you wants. Must be an array.;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
/////////// COMPUTE ///////////
|
|||
|
|
|||
|
|
|||
|
//:: ALGORITHM. :://
|
|||
|
|
|||
|
protected function makeRanking(): void
|
|||
|
{
|
|||
|
$this->selfElection->getPairwise();
|
|||
|
|
|||
|
$result = [0=>0, 1=> [1, 2], 2=> 3]; // Candidate must be valid internal candidate key.
|
|||
|
|
|||
|
$this->Result = $result;
|
|||
|
}
|
|||
|
}
|