177 lines
5.5 KiB
PHP
177 lines
5.5 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace CondorcetPHP\Condorcet\Tests;
|
|
|
|
use CondorcetPHP\Condorcet\{Candidate, Election};
|
|
use CondorcetPHP\Condorcet\Throwable\{CandidateExistsException, CandidateInvalidNameException};
|
|
use PHPUnit\Framework\TestCase;
|
|
|
|
class CandidateTest extends TestCase
|
|
{
|
|
private readonly Candidate $candidate1;
|
|
|
|
protected function setUp(): void
|
|
{
|
|
$this->candidate1 = new Candidate('candidate1.n1');
|
|
}
|
|
|
|
public function testCreateTimestamp(): void
|
|
{
|
|
self::assertEquals($this->candidate1->getCreateTimestamp(), $this->candidate1->getTimestamp());
|
|
}
|
|
|
|
public function testChangeName(): void
|
|
{
|
|
self::assertTrue($this->candidate1->setName('candidate1.n2'));
|
|
|
|
self::assertEquals('candidate1.n2', $this->candidate1->getName());
|
|
|
|
self::assertLessThan($this->candidate1->getTimestamp(), $this->candidate1->getCreateTimestamp());
|
|
self::assertCount(2, $this->candidate1->getHistory());
|
|
}
|
|
|
|
public function testTrimName(): void
|
|
{
|
|
$candidate = new Candidate(' candidateName ');
|
|
self::assertSame('candidateName', (string) $candidate);
|
|
}
|
|
|
|
public function testMatchingAndTooLongName(): never
|
|
{
|
|
$name = '';
|
|
while (mb_strlen($name) < Election::MAX_CANDIDATE_NAME_LENGTH) {
|
|
$name .= uniqid();
|
|
}
|
|
$name = mb_substr($name, 0, Election::MAX_CANDIDATE_NAME_LENGTH);
|
|
|
|
// The name is exactly as long as allowed.
|
|
$candidate = new Candidate($name);
|
|
$this->assertEquals($name, (string) $candidate);
|
|
|
|
// Now the name is one character too long.
|
|
$name .= 'A';
|
|
|
|
$this->expectException(CandidateInvalidNameException::class);
|
|
$this->expectExceptionMessage("This name is not valid: {$name}");
|
|
|
|
new Candidate($name);
|
|
}
|
|
|
|
public function testBadName(): never
|
|
{
|
|
$this->expectException(CandidateInvalidNameException::class);
|
|
$this->expectExceptionMessage('This name is not valid');
|
|
|
|
new Candidate('<$"');
|
|
}
|
|
|
|
public function testBadNameWithNewline(): never
|
|
{
|
|
$this->expectException(CandidateInvalidNameException::class);
|
|
$this->expectExceptionMessage('This name is not valid');
|
|
|
|
new Candidate("A name with\n a newline");
|
|
}
|
|
|
|
public function testCandidateBadClass(): never
|
|
{
|
|
$this->expectException(\TypeError::class);
|
|
|
|
(new Election)->addCandidate(new \stdClass);
|
|
}
|
|
|
|
public function testAddSameCandidate1(): never
|
|
{
|
|
$this->expectException(CandidateExistsException::class);
|
|
$this->expectExceptionMessage('This candidate already exists: Schizophrenic');
|
|
|
|
$election1 = new Election;
|
|
|
|
$candidate = new Candidate('Schizophrenic');
|
|
|
|
$election1->addCandidate($candidate);
|
|
$election1->addCandidate($candidate);
|
|
}
|
|
|
|
public function testAddSameCandidate2(): never
|
|
{
|
|
$this->expectException(CandidateExistsException::class);
|
|
$this->expectExceptionMessage('This candidate already exists: candidate1');
|
|
|
|
$election1 = new Election;
|
|
|
|
$election1->parseCandidates('candidate1;candidate2;candidate1');
|
|
}
|
|
|
|
public function testAddSameCandidate3(): never
|
|
{
|
|
$this->expectException(CandidateExistsException::class);
|
|
$this->expectExceptionMessage('This candidate already exists: candidate1');
|
|
|
|
$election1 = new Election;
|
|
|
|
$election1->addCandidate('candidate1');
|
|
$election1->parseCandidates('candidate2;candidate1');
|
|
}
|
|
|
|
public function testAddSameCandidate4(): void
|
|
{
|
|
$election1 = new Election;
|
|
|
|
$candidate1= $election1->addCandidate('candidate1');
|
|
|
|
try {
|
|
$election1->parseCandidates('candidate2;candidate1');
|
|
} catch (\Exception) {
|
|
}
|
|
|
|
self::assertsame([$candidate1], $election1->getCandidatesList());
|
|
}
|
|
|
|
public function testSameCandidateToMultipleElection(): void
|
|
{
|
|
$this->expectException(CandidateExistsException::class);
|
|
$this->expectExceptionMessage("This candidate already exists: the name 'Debussy' is taken by another candidate");
|
|
|
|
$election1 = new Election;
|
|
$election2 = new Election;
|
|
$election3 = new Election;
|
|
|
|
// Add candidate to election
|
|
self::assertSame($this->candidate1, $election1->addCandidate($this->candidate1));
|
|
self::assertSame($this->candidate1, $election2->addCandidate($this->candidate1));
|
|
self::assertSame($this->candidate1, $election3->addCandidate($this->candidate1));
|
|
|
|
// Check Candidate Link
|
|
self::assertTrue($this->candidate1->haveLink($election1));
|
|
self::assertTrue($this->candidate1->haveLink($election2));
|
|
self::assertTrue($this->candidate1->haveLink($election3));
|
|
self::assertCount(3, $this->candidate1->getLinks());
|
|
|
|
$election3->removeCandidates('candidate1.n1');
|
|
|
|
self::assertCount(2, $this->candidate1->getLinks());
|
|
|
|
// Add some conflicts
|
|
self::assertTrue($this->candidate1->setName('candidate1.n2'));
|
|
self::assertSame('candidate1.n2', $this->candidate1->getName());
|
|
self::assertNotSame($this->candidate1, $election1->addCandidate('candidate1.n1'));
|
|
|
|
$election2->addCandidate('Debussy');
|
|
$this->candidate1->setName('Debussy');
|
|
}
|
|
|
|
public function testCloneCandidate(): void
|
|
{
|
|
($election = new Election)->addCandidate($this->candidate1);
|
|
|
|
self::assertsame(1, $this->candidate1->countLinks());
|
|
|
|
$cloneCandidate = clone $this->candidate1;
|
|
|
|
self::assertsame(0, $cloneCandidate->countLinks());
|
|
}
|
|
}
|