33namespace Kolyunya \Codeception \Module ;
44
55use Exception ;
6+ use ReflectionClass ;
67use Codeception \Lib \ModuleContainer ;
78use Codeception \Module ;
9+ use Kolyunya \Codeception \Lib \Base \ComponentInterface ;
810use Kolyunya \Codeception \Lib \MarkupValidator \MarkupProviderInterface ;
911use Kolyunya \Codeception \Lib \MarkupValidator \MarkupReporterInterface ;
1012use Kolyunya \Codeception \Lib \MarkupValidator \MarkupValidatorInterface ;
1416 */
1517class MarkupValidator extends Module
1618{
19+
20+ const COMPONENT_CLASS_CONFIG_KEY = 'class ' ;
21+
22+ const COMPONENT_CONFIG_CONFIG_KEY = 'config ' ;
23+
24+ const PROVIDER_INTERFACE = 'Kolyunya\Codeception\Lib\MarkupValidator\MarkupProviderInterface ' ;
1725 const PROVIDER_CONFIG_KEY = 'provider ' ;
1826
27+ const VALIDATOR_INTERFACE = 'Kolyunya\Codeception\Lib\MarkupValidator\MarkupValidatorInterface ' ;
1928 const VALIDATOR_CONFIG_KEY = 'validator ' ;
2029
30+ const REPORTER_INTERFACE = 'Kolyunya\Codeception\Lib\MarkupValidator\MarkupReporterInterface ' ;
2131 const REPORTER_CONFIG_KEY = 'reporter ' ;
2232
23- const COMPONENT_CLASS_CONFIG_KEY = 'class ' ;
24-
25- const COMPONENT_CONFIG_CONFIG_KEY = 'config ' ;
33+ const PRINTER_INTERFACE = 'Kolyunya\Codeception\Lib\MarkupValidator\MessagePrinterInterface ' ;
34+ const PRINTER_CONFIG_KEY = 'printer ' ;
2635
2736 /**
2837 * {@inheritDoc}
@@ -95,38 +104,64 @@ public function validateMarkup(array $reporterConfiguration = array())
95104 */
96105 private function initializeProvider ()
97106 {
98- $ providerName = self ::PROVIDER_CONFIG_KEY ;
99- $ providerClass = $ this ->getComponentClass ($ providerName );
100- $ providerConfig = $ this ->getComponentConfig ($ providerName );
101- $ this ->provider = new $ providerClass ($ this ->moduleContainer , $ providerConfig );
102- $ providerInterface = 'Kolyunya\Codeception\Lib\MarkupValidator\MarkupProviderInterface ' ;
103- $ this ->validateComponentInstance ($ this ->provider , $ providerInterface , $ providerName );
107+ $ this ->provider = $ this ->instantiateComponent (
108+ self ::PROVIDER_CONFIG_KEY ,
109+ self ::PROVIDER_INTERFACE ,
110+ array (
111+ $ this ->moduleContainer ,
112+ )
113+ );
104114 }
105115
106116 /**
107117 * Initializes markup validator.
108118 */
109119 private function initializeValidator ()
110120 {
111- $ validatorName = self ::VALIDATOR_CONFIG_KEY ;
112- $ validatorClass = $ this ->getComponentClass ($ validatorName );
113- $ validatorConfig = $ this ->getComponentConfig ($ validatorName );
114- $ this ->validator = new $ validatorClass ($ validatorConfig );
115- $ validatorInterface = 'Kolyunya\Codeception\Lib\MarkupValidator\MarkupValidatorInterface ' ;
116- $ this ->validateComponentInstance ($ this ->validator , $ validatorInterface , $ validatorName );
121+ $ this ->validator = $ this ->instantiateComponent (
122+ self ::VALIDATOR_CONFIG_KEY ,
123+ self ::VALIDATOR_INTERFACE
124+ );
117125 }
118126
119127 /**
120- * Initializes markup validator .
128+ * Initializes markup reporter .
121129 */
122130 private function initializeReporter ()
123131 {
124- $ reporterName = self ::REPORTER_CONFIG_KEY ;
125- $ reporterClass = $ this ->getComponentClass ($ reporterName );
126- $ reporterConfig = $ this ->getComponentConfig ($ reporterName );
127- $ this ->reporter = new $ reporterClass ($ reporterConfig );
128- $ reporterInterface = 'Kolyunya\Codeception\Lib\MarkupValidator\MarkupReporterInterface ' ;
129- $ this ->validateComponentInstance ($ this ->reporter , $ reporterInterface , $ reporterName );
132+ $ this ->reporter = $ this ->instantiateComponent (
133+ self ::REPORTER_CONFIG_KEY ,
134+ self ::REPORTER_INTERFACE
135+ );
136+ }
137+
138+ /**
139+ * Instantiates and returns a module component.
140+ *
141+ * @param string $componentName Component name.
142+ * @param string $interface An interface component must implement.
143+ * @param array $arguments Component's constructor arguments.
144+ *
145+ * @throws Exception When component does not implement expected interface.
146+ *
147+ * @return object Instance of a module component.
148+ */
149+ private function instantiateComponent ($ componentName , $ interface , array $ arguments = array ())
150+ {
151+ $ componentClass = $ this ->getComponentClass ($ componentName );
152+ $ componentReflectionClass = new ReflectionClass ($ componentClass );
153+ if ($ componentReflectionClass ->implementsInterface ($ interface ) === false ) {
154+ $ errorMessageTemplate = 'Invalid class «%s» provided for component «%s». It must implement «%s». ' ;
155+ $ errorMessage = sprintf ($ errorMessageTemplate , $ componentClass , $ componentName , $ interface );
156+ throw new Exception ($ errorMessage );
157+ }
158+
159+ /* @var $component ComponentInterface */
160+ $ component = $ componentReflectionClass ->newInstanceArgs ($ arguments );
161+ $ componentConfiguration = $ this ->getComponentConfiguration ($ componentName );
162+ $ component ->setConfiguration ($ componentConfiguration );
163+
164+ return $ component ;
130165 }
131166
132167 /**
@@ -156,9 +191,9 @@ private function getComponentClass($componentName)
156191 *
157192 * @param string $componentName Component name.
158193 *
159- * @return string Component configuration parameters.
194+ * @return array Component configuration parameters.
160195 */
161- private function getComponentConfig ($ componentName )
196+ private function getComponentConfiguration ($ componentName )
162197 {
163198 $ componentConfig = array ();
164199
@@ -174,25 +209,4 @@ private function getComponentConfig($componentName)
174209
175210 return $ componentConfig ;
176211 }
177-
178- /**
179- * Ensures that a component is an instance of a specifi interface.
180- *
181- * @param object $component Component instance to validate.
182- * @param string $interface Interface to validate component instance against.
183- * @param string $componentName Component name. User for error logging.
184- *
185- * @throws Exception When `component` is not an instance of the `interface`.
186- */
187- private function validateComponentInstance ($ component , $ interface , $ componentName )
188- {
189- if (($ component instanceof $ interface ) === false ) {
190- $ componentClass = get_class ($ component );
191- $ errorMessage = vsprintf ('Invalid class «%s» provided for component «%s». ' , array (
192- $ componentClass ,
193- $ componentName ,
194- ));
195- throw new Exception ($ errorMessage );
196- }
197- }
198212}
0 commit comments