1: <?php
2: /**
3: * A test helper for generating complex test setups.
4: *
5: * PHP version 5
6: *
7: * @category Horde
8: * @package Test
9: * @author Gunnar Wrobel <wrobel@pardus.de>
10: * @license http://www.horde.org/licenses/lgpl21 LGPL
11: * @link http://www.horde.org/components/Horde_Test
12: */
13:
14: /**
15: * A test helper for generating complex test setups.
16: *
17: * Copyright 2011-2012 Horde LLC (http://www.horde.org/)
18: *
19: * See the enclosed file COPYING for license information (LGPL). If you
20: * did not receive this file, see http://www.horde.org/licenses/lgpl21.
21: *
22: * @since Horde_Test 1.2.0
23: *
24: * @category Horde
25: * @package Test
26: * @author Gunnar Wrobel <wrobel@pardus.de>
27: * @license http://www.horde.org/licenses/lgpl21 LGPL
28: * @link http://www.horde.org/components/Horde_Test
29: */
30: class Horde_Test_Setup
31: {
32: /**
33: * The Horde_Injector instance which serves as our service container.
34: *
35: * @var Horde_Injector
36: */
37: private $_injector;
38:
39: /**
40: * In case the setup turns out to be unfullfillable this should contain an
41: * appropriate message indicating the problem.
42: *
43: * @var string
44: */
45: private $_error;
46:
47: /**
48: * Global parameters that apply to several factories.
49: *
50: * @var string
51: */
52: private $_params = array();
53:
54: /**
55: * Constructor.
56: */
57: public function __construct()
58: {
59: if (class_exists('Horde_Injector')) {
60: $this->_injector = new Horde_Injector(new Horde_Injector_TopLevel());
61: $this->_injector->setInstance('Horde_Injector', $this->_injector);
62: } else {
63: $this->_error = 'The Horde_Injector class is unavailable!';
64: }
65: }
66:
67: /**
68: * Add a new set of elements to the service container.
69: *
70: * @param array $params All parameters necessary for creating the services.
71: * The keys of the array elements define the name that
72: * will be used for registering the test service with
73: * the injector. The element values are a
74: * configuration array with the following elements:
75: * <pre>
76: * 'factory' - (string) Name of the factory. Can be a full class name or an
77: * abbreviated name that will get prepended with
78: * 'Horde_Test_Factory_'
79: * 'method' - (string) Method name that will be invoked on the above factory
80: * to generate the test service.
81: * 'params' - (array) Any parameters the factory method might require for
82: * generating the test service. See the various factories/methods
83: * for details.
84: * </pre>
85: *
86: * @return NULL
87: */
88: public function setup($params)
89: {
90: if (isset($params['_PARAMS'])) {
91: $this->_params = $params['_PARAMS'];
92: unset($params['_PARAMS']);
93: }
94: foreach ($params as $interface => $setup) {
95: if (is_array($setup)) {
96: $factory = $setup['factory'];
97: $method = isset($setup['method']) ? $setup['method'] : 'create';
98: $params = isset($setup['params']) ? $setup['params'] : array();
99: } else {
100: $factory = $setup;
101: $method = 'create';
102: $params = array();
103: }
104: if (!empty($this->_error)) {
105: break;
106: }
107: $this->add($interface, $factory, $method, $params);
108: }
109: }
110:
111: /**
112: * Add a new element to the service container.
113: *
114: * @oaram string $interface The interface name to register the service with.
115: * @param string $factory The (abbreviated) name of the factory.
116: * @param string $method The factory method that will generate the
117: * service.
118: * @param array $params All parameters necessary for creating the
119: * service.
120: *
121: * @return NULL
122: */
123: public function add($interface, $factory, $method, $params)
124: {
125: if (!empty($this->_error)) {
126: return;
127: }
128: if (!class_exists('Horde_Test_Factory_' . $factory) &&
129: !class_exists($factory)) {
130: $this->_error = "Neither the class \"Horde_Test_Factory_$factory\" nor \"$factory\" exist. \"$interface\" cannot be created!";
131: return;
132: }
133: if (class_exists('Horde_Test_Factory_' . $factory)) {
134: $f = $this->_injector->getInstance('Horde_Test_Factory_' . $factory);
135: } else {
136: $f = $this->_injector->getInstance($factory);
137: }
138: if (!method_exists($f, $method) &&
139: !method_exists($f, 'create' . $method)) {
140: $this->_error = "The factory lacks the specified method \"$method\"!";
141: return;
142: }
143: if (method_exists($f, 'create' . $method)) {
144: $method = 'create' . $method;
145: }
146: $params = array_merge($this->_params, $params);
147: try {
148: $this->_injector->setInstance($interface, $f->{$method}($params));
149: } catch (Horde_Test_Exception $e) {
150: $this->_error = $e->getMessage() . "\n\n" . $e->getFile() . ':' . $e->getLine();
151: }
152: }
153:
154: /**
155: * Export elements from the injector into global scope.
156: *
157: * @param array $elements The elements to export.
158: *
159: * @return NULL
160: */
161: public function makeGlobal($elements)
162: {
163: if (!empty($this->_error)) {
164: return;
165: }
166: foreach ($elements as $key => $interface) {
167: $GLOBALS[$key] = $this->_injector->getInstance($interface);
168: }
169: }
170:
171: /**
172: * Return any potential setup error.
173: *
174: * @return string The error.
175: */
176: public function getError()
177: {
178: return $this->_error;
179: }
180:
181: /**
182: * Return the service container.
183: *
184: * @return Horde_Injector The injector.
185: */
186: public function getInjector()
187: {
188: return $this->_injector;
189: }
190: }
191: