TimeServerTest   A
last analyzed

Complexity

Total Complexity 7

Size/Duplication

Total Lines 111
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 12

Importance

Changes 0
Metric Value
wmc 7
lcom 1
cbo 12
dl 0
loc 111
rs 10
c 0
b 0
f 0

6 Methods

Rating   Name   Duplication   Size   Complexity  
A setUp() 0 20 1
A testGetters() 0 10 1
A testFailureIsReturnedIfCannotConnect() 0 21 2
A testFailureIsReturnedIfOutputWasNotCorrect() 0 12 1
A testSuccessIsReturnedIfOutputIsCorrect() 0 9 1
A testRun() 0 20 1
1
<?php
2
3
4
namespace PhpSchool\LearnYouPhpTest\Exercise;
5
6
use Colors\Color;
7
use PhpSchool\CliMenu\Terminal\TerminalInterface;
8
use PhpSchool\LearnYouPhp\Exercise\TimeServer;
9
use PhpSchool\LearnYouPhp\TcpSocketFactory;
10
use PhpSchool\PhpWorkshop\Check\CheckRepository;
11
use PhpSchool\PhpWorkshop\Event\EventDispatcher;
12
use PhpSchool\PhpWorkshop\Exercise\ExerciseType;
13
use PhpSchool\PhpWorkshop\ExerciseDispatcher;
14
use PhpSchool\PhpWorkshop\ExerciseRunner\CliRunner;
15
use PhpSchool\PhpWorkshop\ExerciseRunner\Factory\CliRunnerFactory;
16
use PhpSchool\PhpWorkshop\ExerciseRunner\RunnerManager;
17
use PhpSchool\PhpWorkshop\Factory\RunnerFactory;
18
use PhpSchool\PhpWorkshop\Input\Input;
19
use PhpSchool\PhpWorkshop\Output\StdOutput;
20
use PhpSchool\PhpWorkshop\Result\ComparisonFailure;
21
use PhpSchool\PhpWorkshop\Result\Failure;
22
use PhpSchool\PhpWorkshop\Result\StdOutFailure;
23
use PhpSchool\PhpWorkshop\Result\Success;
24
use PhpSchool\PhpWorkshop\ResultAggregator;
25
use PhpSchool\PhpWorkshop\Solution\SolutionInterface;
26
use PHPUnit\Framework\TestCase;
27
28
/**
29
 * @author Michael Woodward <[email protected]>
30
 */
31
class TimeServerTest extends TestCase
32
{
33
34
    /**
35
     * @var TimeServer
36
     */
37
    private $exercise;
38
39
    /**
40
     * @var ExerciseDispatcher
41
     */
42
    private $exerciseDispatcher;
43
44
    public function setUp()
45
    {
46
        $results = new ResultAggregator;
47
        $eventDispatcher = new EventDispatcher($results);
48
49
        $r = new \ReflectionClass(CliRunner::class);
50
        $rp = $r->getProperty('requiredChecks');
51
        $rp->setAccessible(true);
52
        $rp->setValue([]);
53
54
        $runnerManager = new RunnerManager;
55
        $runnerManager->addFactory(new CliRunnerFactory($eventDispatcher));
56
        $this->exerciseDispatcher = new ExerciseDispatcher(
57
            $runnerManager,
58
            $results,
59
            $eventDispatcher,
60
            new CheckRepository()
61
        );
62
        $this->exercise = new TimeServer(new TcpSocketFactory);
63
    }
64
65
    public function testGetters()
66
    {
67
        $this->assertEquals('Time Server', $this->exercise->getName());
68
        $this->assertEquals('Build a Time Server!', $this->exercise->getDescription());
69
        $this->assertEquals(ExerciseType::CLI, $this->exercise->getType());
70
71
        $this->assertInstanceOf(SolutionInterface::class, $this->exercise->getSolution());
72
        $this->assertFileExists(realpath($this->exercise->getProblem()));
73
        $this->assertNull($this->exercise->tearDown());
74
    }
75
76
    public function testFailureIsReturnedIfCannotConnect()
77
    {
78
        $input = new Input('learnyouphp', ['program' => __DIR__ . '/../res/time-server/no-server.php']);
79
        $results = $this->exerciseDispatcher->verify($this->exercise, $input);
80
        $this->assertCount(2, $results);
81
82
        $failure = iterator_to_array($results)[0];
83
        $this->assertInstanceOf(Failure::class, $failure);
84
85
        if (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') {
86
            $reason  = '/^Client returns an error \(number \d+\): No connection could be made because';
87
            $reason .= ' the target machine actively refused it\.\r\n';
88
            $reason .= ' while trying to join tcp:\/\/127\.0\.0\.1:\d+\.$/';
89
        } else {
90
            $reason  = '/^Client returns an error \(number \d+\): Connection refused';
91
            $reason .= ' while trying to join tcp:\/\/127\.0\.0\.1:\d+\.$/';
92
        }
93
94
        $this->assertRegExp($reason, $failure->getReason());
95
        $this->assertEquals('Time Server', $failure->getCheckName());
96
    }
97
98
    public function testFailureIsReturnedIfOutputWasNotCorrect()
99
    {
100
        $input = new Input('learnyouphp', ['program' => __DIR__ . '/../res/time-server/solution-wrong.php']);
101
        $results = $this->exerciseDispatcher->verify($this->exercise, $input);
102
103
        $this->assertCount(2, $results);
104
        $failure = iterator_to_array($results)[0];
105
106
        $this->assertInstanceOf(ComparisonFailure::class, $failure);
107
        $this->assertNotEquals($failure->getExpectedValue(), $failure->getActualValue());
108
        $this->assertEquals('Time Server', $failure->getCheckName());
109
    }
110
111
    public function testSuccessIsReturnedIfOutputIsCorrect()
112
    {
113
        $input = new Input('learnyouphp', ['program' => __DIR__ . '/../res/time-server/solution.php']);
114
        $results = $this->exerciseDispatcher->verify($this->exercise, $input);
115
116
        $this->assertCount(2, $results);
117
        $success = iterator_to_array($results)[0];
118
        $this->assertInstanceOf(Success::class, $success);
119
    }
120
121
    public function testRun()
122
    {
123
        $color = new Color;
124
        $color->setForceStyle(true);
125
        $output = new StdOutput($color, $terminal = $this->createMock(TerminalInterface::class));
126
        
127
        $outputRegEx  = "/\n";
128
        $outputRegEx .= '\[1m\[4mArguments\[0m\[0m';
129
        $outputRegEx .= "\n";
130
        $outputRegEx .= '127.0.0.1, \d+';
131
        $outputRegEx .= "\n\n";
132
        $outputRegEx .= '\[1m\[4mOutput\[0m\[0m';
133
        $outputRegEx .= "\n";
134
        $outputRegEx .= '\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}';
135
        $outputRegEx .= "\n/";
136
        $this->expectOutputRegex($outputRegEx);
137
138
        $input = new Input('learnyouphp', ['program' => __DIR__ . '/../res/time-server/solution.php']);
139
        $this->exerciseDispatcher->run($this->exercise, $input, $output);
140
    }
141
}
142