Passed
Push — master ( 66c616...00643e )
by Eugene
03:07
created

ExamplesTest::parseFile()   A

Complexity

Conditions 4
Paths 4

Size

Total Lines 15
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 4
eloc 8
nc 4
nop 1
dl 0
loc 15
rs 10
c 0
b 0
f 0
1
<?php
2
3
/**
4
 * This file is part of the Tarantool Client package.
5
 *
6
 * (c) Eugene Leonovich <[email protected]>
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 */
11
12
declare(strict_types=1);
13
14
namespace Tarantool\Client\Tests\Integration;
15
16
final class ExamplesTest extends TestCase
17
{
18
    /**
19
     * @dataProvider provideExampleData
20
     */
21
    public function testExample(string $filename) : void
22
    {
23
        $info = self::parseFile($filename);
24
        self::checkExampleRequirements($info['requirements']);
25
26
        $uri = ClientBuilder::createFromEnv()->getUri();
27
28
        exec("php $filename $uri", $output, $exitCode);
29
30
        self::assertSame(0, $exitCode, implode("\n", $output));
31
32
        if (isset($info['output'])) {
33
            self::assertSame($info['output'], implode("\n", $output));
34
        }
35
    }
36
37
    public function provideExampleData() : iterable
38
    {
39
        $dir = dirname(__DIR__, 2).'/examples';
40
        foreach (glob("$dir/{**/*,*}.php", GLOB_BRACE) as $filename) {
41
            $basename = basename($filename, '.php');
42
            if ('bootstrap' === $basename) {
43
                continue;
44
            }
45
            // ignore classes
46
            if (strtolower($basename[0]) !== $basename[0]) {
47
                continue;
48
            }
49
50
            yield [$filename];
51
        }
52
    }
53
54
    private static function parseFile(string $filename) : array
55
    {
56
        $content = file_get_contents($filename);
57
58
        $result = ['requirements' => []];
59
        if (preg_match_all('~@requires\s+?(\w+?)\s+?(.+?)\s*?$~mi', $content, $matches, PREG_SET_ORDER)) {
60
            foreach ($matches as $match) {
61
                $result['requirements'][strtolower($match[1])] = $match[2];
62
            }
63
        }
64
        if (preg_match('~\/\*\s*?OUTPUT\b(.+?)\*\/~s', $content, $matches)) {
65
            $result['output'] = trim($matches[1]);
66
        }
67
68
        return $result;
69
    }
70
71
    private static function checkExampleRequirements(array $requirements) : void
72
    {
73
        if (isset($requirements['tarantool'])) {
74
            [$major, $minor, $patch] = \sscanf($requirements['tarantool'], '%d.%d.%d');
75
            $requiredVersionId = $major * 10000 + $minor * 100 + $patch;
76
            if (self::getTarantoolVersionId() < $requiredVersionId) {
77
                self::markTestSkipped(sprintf('Tarantool >= %s is required.', $requirements['tarantool']));
78
            }
79
        }
80
81
        if (isset($requirements['extension']) && !extension_loaded($requirements['extension'])) {
82
            self::markTestSkipped(sprintf('Extension %s is required.', $requirements['extension']));
83
        }
84
85
        if (isset($requirements['function']) && !\function_exists($requirements['function'])) {
86
            $pieces = \explode('::', $requirements['function']);
87
            if ((2 !== \count($pieces)) || !\class_exists($pieces[0]) || !\method_exists($pieces[0], $pieces[1])) {
88
                self::markTestSkipped(sprintf('Function %s is required.', $requirements['function']));
89
            }
90
        }
91
    }
92
}
93