Completed
Push — master ( 25ec1c...ee1026 )
by Erin
01:51
created

ReporterFactory::createComposite()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 18
Code Lines 12

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 12
nc 2
nop 1
dl 0
loc 18
rs 9.4285
c 0
b 0
f 0
1
<?php
2
namespace Peridot\Reporter;
3
4
use Evenement\EventEmitterInterface;
5
use Peridot\Configuration;
6
use Peridot\Core\HasEventEmitterTrait;
7
use Symfony\Component\Console\Output\BufferedOutput;
8
use Symfony\Component\Console\Output\OutputInterface;
9
10
/**
11
 * The ReporterFactory is used to list and register Peridot reporters.
12
 *
13
 * @package Peridot\Reporter
14
 */
15
class ReporterFactory
16
{
17
    use HasEventEmitterTrait;
18
19
    /**
20
     * @var \Peridot\Configuration
21
     */
22
    protected $configuration;
23
24
    /**
25
     * @var \Peridot\Runner\Runner
26
     */
27
    protected $runner;
28
29
    /**
30
     * @var \Symfony\Component\Console\Output\OutputInterface
31
     */
32
    protected $output;
33
34
    /**
35
     * Registered reporters
36
     *
37
     * @var array
38
     */
39
    protected $reporters = array(
40
        'spec' => ['description' => 'hierarchical spec list', 'factory' => 'Peridot\Reporter\SpecReporter']
41
    );
42
43
    /**
44
     * @param Configuration $configuration
45
     * @param OutputInterface $output
46
     * @param EventEmitterInterface $eventEmitter
47
     */
48
    public function __construct(
49
        Configuration $configuration,
50
        OutputInterface $output,
51
        EventEmitterInterface $eventEmitter
52
    ) {
53
        $this->configuration = $configuration;
54
        $this->output = $output;
55
        $this->eventEmitter = $eventEmitter;
56
    }
57
58
    /**
59
     * Return an instance of the named reporter
60
     *
61
     * @param $name
62
     * @return \Peridot\Reporter\AbstractBaseReporter
63
     */
64
    public function create($name)
65
    {
66
        return $this->createWithOutput($this->output, $name);
67
    }
68
69
    /**
70
     * Return an instance of the named reporter
71
     *
72
     * @param $name
73
     * @return \Peridot\Reporter\AbstractBaseReporter
74
     */
75
    public function createComposite(array $names)
76
    {
77
        if (empty($names)) {
78
            throw new \InvalidArgumentException('Reporter names cannot be empty.');
79
        }
80
81
        return new CompositeReporter(
82
            array_merge(
83
                [$this->createWithOutput($this->output, array_shift($names))],
84
                array_map(function ($name) {
85
                    return $this->createWithOutput(new BufferedOutput(), $name);
86
                }, $names)
87
            ),
88
            $this->configuration,
89
            $this->output,
90
            $this->eventEmitter
91
        );
92
    }
93
94
    /**
95
     * Return the factory defined for the named reporter
96
     *
97
     * @param string $name
98
     * @return null|string|callable
99
     */
100
    public function getReporterFactory($name)
101
    {
102
        $definition = $this->getReporterDefinition($name);
103
        if (! isset($definition['factory'])) {
104
            $definition['factory'] = null;
105
        }
106
        return $definition['factory'];
107
    }
108
109
    /**
110
     * Return the definition of the named reporter
111
     *
112
     * @param string $name
113
     * @return array
114
     */
115
    public function getReporterDefinition($name)
116
    {
117
        $definition = [];
118
        if (isset($this->reporters[$name])) {
119
            $definition = $this->reporters[$name];
120
        }
121
        return $definition;
122
    }
123
124
    /**
125
     * Register a named reporter with the factory.
126
     *
127
     * @param string $name
128
     * @param string $description
129
     * @param string $factory Either a callable or a fully qualified class name
130
     */
131
    public function register($name, $description, $factory)
132
    {
133
        $this->reporters[$name] = ['description' => $description, 'factory' => $factory];
134
    }
135
136
    /**
137
     * @return array
138
     */
139
    public function getReporters()
140
    {
141
        return $this->reporters;
142
    }
143
144
    private function createWithOutput(OutputInterface $output, $name)
145
    {
146
        $factory = $this->getReporterFactory($name);
147
        $isClass = is_string($factory) && class_exists($factory);
148
149
        if ($isClass) {
150
            return new $factory($this->configuration, $output, $this->eventEmitter);
151
        }
152
153
        if (is_callable($factory)) {
154
            return new AnonymousReporter($factory, $this->configuration, $output, $this->eventEmitter);
155
        }
156
157
        throw new \RuntimeException("Reporter class could not be created");
158
    }
159
}
160