debug
This commit is contained in:
334
include/condorcet/Tests/src/ResultTest.php
Normal file
334
include/condorcet/Tests/src/ResultTest.php
Normal file
@@ -0,0 +1,334 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace CondorcetPHP\Condorcet\Tests;
|
||||
|
||||
use CondorcetPHP\Condorcet\Algo\Methods\KemenyYoung\KemenyYoung;
|
||||
use CondorcetPHP\Condorcet\Algo\StatsVerbosity;
|
||||
use CondorcetPHP\Condorcet\{Condorcet, Election};
|
||||
use CondorcetPHP\Condorcet\Throwable\{AlgorithmException, ResultException};
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
class ResultTest extends TestCase
|
||||
{
|
||||
private readonly Election $election1;
|
||||
|
||||
protected function setUp(): void
|
||||
{
|
||||
$this->election1 = new Election;
|
||||
}
|
||||
|
||||
public function testGetResultAsString(): void
|
||||
{
|
||||
$this->election1->addCandidate('B');
|
||||
$this->election1->addCandidate('A');
|
||||
$this->election1->addCandidate('C');
|
||||
|
||||
$this->election1->parseVotes('
|
||||
B > A > C * 7
|
||||
A > B > C * 7
|
||||
C > A > B * 2
|
||||
C > B > A * 2
|
||||
');
|
||||
|
||||
|
||||
self::assertSame(
|
||||
'A = B > C',
|
||||
$this->election1->getResult('Ranked Pairs')->getResultAsString()
|
||||
);
|
||||
}
|
||||
|
||||
public function testGetResultAsInternalKey(): void
|
||||
{
|
||||
$this->election1->addCandidate('B');
|
||||
$this->election1->addCandidate('A');
|
||||
$this->election1->addCandidate('C');
|
||||
|
||||
$this->election1->parseVotes('
|
||||
B > A > C * 7
|
||||
A > B > C * 7
|
||||
C > A > B * 2
|
||||
C > B > A * 2
|
||||
');
|
||||
|
||||
|
||||
self::assertSame(
|
||||
[1 => [0, 1], 2 => [2]],
|
||||
$this->election1->getResult('Ranked Pairs')->getResultAsInternalKey()
|
||||
);
|
||||
}
|
||||
|
||||
public function testgetCondorcetElectionGeneratorVersion(): void
|
||||
{
|
||||
$this->election1->addCandidate('B');
|
||||
$this->election1->addCandidate('A');
|
||||
$this->election1->addCandidate('C');
|
||||
|
||||
$this->election1->addVote('C > B > A');
|
||||
|
||||
self::assertSame(Condorcet::getVersion(), $this->election1->getResult('Ranked Pairs')->getCondorcetElectionGeneratorVersion());
|
||||
}
|
||||
|
||||
public function testResultClassgenerator(): void
|
||||
{
|
||||
$this->election1->addCandidate('B');
|
||||
$this->election1->addCandidate('A');
|
||||
$this->election1->addCandidate('C');
|
||||
|
||||
$this->election1->addVote('C > B > A');
|
||||
|
||||
self::assertSame(\CondorcetPHP\Condorcet\Algo\Methods\RankedPairs\RankedPairsMargin::class, $this->election1->getResult('Ranked Pairs')->getClassGenerator());
|
||||
}
|
||||
|
||||
public function testMethod(): void
|
||||
{
|
||||
$this->election1->addCandidate('B');
|
||||
$this->election1->addCandidate('A');
|
||||
$this->election1->addCandidate('C');
|
||||
|
||||
$this->election1->addVote('C > B > A');
|
||||
|
||||
self::assertSame('Ranked Pairs Margin', $this->election1->getResult('Ranked Pairs')->getMethod());
|
||||
}
|
||||
|
||||
public function testGetBuildTimeStamp(): void
|
||||
{
|
||||
$this->election1->addCandidate('B');
|
||||
$this->election1->addCandidate('A');
|
||||
$this->election1->addCandidate('C');
|
||||
|
||||
$this->election1->addVote('C > B > A');
|
||||
|
||||
self::assertIsFloat($this->election1->getResult('Ranked Pairs')->getBuildTimeStamp());
|
||||
}
|
||||
|
||||
public function testGetWinner(): void
|
||||
{
|
||||
$this->election1->addCandidate('a');
|
||||
$this->election1->addCandidate('b');
|
||||
$this->election1->addCandidate('c');
|
||||
|
||||
$this->election1->parseVotes('
|
||||
a > c > b * 23
|
||||
b > c > a * 19
|
||||
c > b > a * 16
|
||||
c > a > b * 2
|
||||
');
|
||||
|
||||
self::assertEquals('c', $this->election1->getResult()->getWinner());
|
||||
self::assertEquals('c', $this->election1->getResult()->getCondorcetWinner());
|
||||
}
|
||||
|
||||
public function testGetLoser(): void
|
||||
{
|
||||
$this->election1->addCandidate('Memphis');
|
||||
$this->election1->addCandidate('Nashville');
|
||||
$this->election1->addCandidate('Knoxville');
|
||||
$this->election1->addCandidate('Chattanooga');
|
||||
|
||||
$this->election1->parseVotes('
|
||||
Memphis > Nashville > Chattanooga * 42
|
||||
Nashville > Chattanooga > Knoxville * 26
|
||||
Chattanooga > Knoxville > Nashville * 15
|
||||
Knoxville > Chattanooga > Nashville * 17
|
||||
');
|
||||
|
||||
self::assertEquals('Memphis', $this->election1->getResult()->getLoser());
|
||||
self::assertEquals('Memphis', $this->election1->getResult()->getCondorcetLoser());
|
||||
}
|
||||
|
||||
public function testgetOriginalResultArrayWithString(): void
|
||||
{
|
||||
$this->election1->addCandidate('a');
|
||||
$this->election1->addCandidate('b');
|
||||
$this->election1->addCandidate('c');
|
||||
|
||||
$this->election1->addVote('a > b > c');
|
||||
|
||||
self::assertEquals(
|
||||
[1 => 'a',
|
||||
2 => 'b',
|
||||
3 => 'c',
|
||||
],
|
||||
$this->election1->getResult()->getOriginalResultArrayWithString()
|
||||
);
|
||||
}
|
||||
|
||||
public function testOffsetSet(): never
|
||||
{
|
||||
$this->expectException(ResultException::class);
|
||||
$this->expectExceptionMessage('Result cannot be changed');
|
||||
|
||||
$this->election1->addCandidate('B');
|
||||
$this->election1->addCandidate('A');
|
||||
$this->election1->addCandidate('C');
|
||||
|
||||
$this->election1->addVote('C > B > A');
|
||||
|
||||
$result = $this->election1->getResult('Schulze');
|
||||
|
||||
$result[] = 42;
|
||||
}
|
||||
|
||||
public function testOffUnset(): never
|
||||
{
|
||||
$this->expectException(ResultException::class);
|
||||
$this->expectExceptionMessage('Result cannot be changed');
|
||||
|
||||
$this->election1->addCandidate('B');
|
||||
$this->election1->addCandidate('A');
|
||||
$this->election1->addCandidate('C');
|
||||
|
||||
$this->election1->addVote('C > B > A');
|
||||
|
||||
$result = $this->election1->getResult('Schulze');
|
||||
|
||||
self::assertTrue(isset($result[1]));
|
||||
|
||||
unset($result[1]);
|
||||
}
|
||||
|
||||
public function testIterator(): void
|
||||
{
|
||||
$this->election1->addCandidate('B');
|
||||
$this->election1->addCandidate('A');
|
||||
$this->election1->addCandidate('C');
|
||||
|
||||
$vote = $this->election1->addVote('C > B > A');
|
||||
|
||||
$result = $this->election1->getResult('Schulze');
|
||||
|
||||
foreach ($result as $key => $value) {
|
||||
self::assertSame($vote->getRanking()[$key], $value);
|
||||
}
|
||||
}
|
||||
|
||||
public function testBadMethodName(): never
|
||||
{
|
||||
$this->expectException(AlgorithmException::class);
|
||||
$this->expectExceptionMessage('The voting algorithm is not available: bad method');
|
||||
|
||||
$this->election1->addCandidate('B');
|
||||
$this->election1->addCandidate('A');
|
||||
$this->election1->addCandidate('C');
|
||||
|
||||
$this->election1->parseVotes('A>B>C');
|
||||
|
||||
$this->election1->getResult('bad method');
|
||||
}
|
||||
|
||||
public function testResultRankOrdering(): void
|
||||
{
|
||||
$this->election1->addCandidate('B');
|
||||
$this->election1->addCandidate('C');
|
||||
$this->election1->addCandidate('A');
|
||||
|
||||
$this->election1->addVote('C = A = B');
|
||||
|
||||
self::assertSame(
|
||||
[1 => ['A', 'B', 'C'],
|
||||
],
|
||||
$this->election1->getResult()->getOriginalResultArrayWithString()
|
||||
);
|
||||
}
|
||||
|
||||
public function testProportional(): void
|
||||
{
|
||||
$this->election1->addCandidate('A');
|
||||
$this->election1->addCandidate('B');
|
||||
$this->election1->addCandidate('C');
|
||||
|
||||
$this->election1->addVote('A');
|
||||
|
||||
$this->election1->setNumberOfSeats(2);
|
||||
|
||||
$result = $this->election1->getResult('STV');
|
||||
|
||||
self::assertSame(
|
||||
2,
|
||||
$result->getNumberOfSeats()
|
||||
);
|
||||
|
||||
self::assertTrue(
|
||||
$result->getClassGenerator()::IS_PROPORTIONAL
|
||||
);
|
||||
|
||||
self::assertTrue(
|
||||
$result->isProportional()
|
||||
);
|
||||
|
||||
$result = $this->election1->getResult('Schulze');
|
||||
|
||||
self::assertNull(
|
||||
$result->getNumberOfSeats()
|
||||
);
|
||||
|
||||
self::assertFalse(
|
||||
$result->getClassGenerator()::IS_PROPORTIONAL
|
||||
);
|
||||
|
||||
self::assertFalse(
|
||||
$result->isProportional()
|
||||
);
|
||||
}
|
||||
|
||||
public function testMethodOption(): void
|
||||
{
|
||||
$this->election1->addCandidate('A');
|
||||
$this->election1->addCandidate('B');
|
||||
$this->election1->addCandidate('C');
|
||||
|
||||
$this->election1->addVote('A>B>C');
|
||||
|
||||
$class = Condorcet::getMethodClass('Borda');
|
||||
|
||||
self::assertSame(1, $class::$optionStarting);
|
||||
|
||||
$b1 = $this->election1->getResult('Borda');
|
||||
$c1 = $this->election1->getResult('Copeland');
|
||||
|
||||
self::assertSame(1, $b1->getMethodOptions()['Starting']);
|
||||
|
||||
self::assertTrue($this->election1->setMethodOption('Borda Count', 'Starting', 0));
|
||||
self::assertSame(0, $class::$optionStarting);
|
||||
|
||||
self::assertSame(1, $b1->getMethodOptions()['Starting']);
|
||||
|
||||
$b2 = $this->election1->getResult('Borda');
|
||||
$c2 = $this->election1->getResult('Copeland');
|
||||
|
||||
self::assertNotSame($b1, $b2);
|
||||
self::assertSame($c1, $c2);
|
||||
|
||||
self::assertSame(0, $b2->getMethodOptions()['Starting']);
|
||||
|
||||
self::assertFalse($this->election1->setMethodOption('Unregistered method', 'Starting', 0));
|
||||
}
|
||||
|
||||
public function testVerbosityLevel(): void
|
||||
{
|
||||
$this->election1->addCandidate('A');
|
||||
$this->election1->addCandidate('B');
|
||||
$this->election1->addCandidate('C');
|
||||
|
||||
$this->election1->addVote('A>B>C');
|
||||
|
||||
$r1 = $this->election1->getResult(KemenyYoung::class);
|
||||
self::assertSame(StatsVerbosity::STD, $r1->statsVerbosity);
|
||||
|
||||
$this->election1->setStatsVerbosity(StatsVerbosity::STD);
|
||||
$r2 = $this->election1->getResult(KemenyYoung::class);
|
||||
self::assertSame($r1, $r2);
|
||||
|
||||
$this->election1->setStatsVerbosity(StatsVerbosity::FULL);
|
||||
$r3 = $this->election1->getResult(KemenyYoung::class);
|
||||
|
||||
self::assertSame(StatsVerbosity::STD, $r1->statsVerbosity);
|
||||
self::assertSame(StatsVerbosity::FULL, $r3->statsVerbosity);
|
||||
|
||||
self::assertNotSame($r1, $r3);
|
||||
self::assertArrayNotHasKey('Ranking Scores', $r1->getStats());
|
||||
self::assertArrayHasKey('Ranking Scores', $r3->getStats());
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user