1<?php defined('SYSPATH') OR die('Kohana bootstrap needs to be included before tests run');
2
3/**
4 * Tests Kohana Form helper
5 *
6 * @group kohana
7 * @group kohana.core
8 * @group kohana.core.form
9 *
10 * @package    Kohana
11 * @category   Tests
12 * @author     Kohana Team
13 * @author     Jeremy Bush <contractfrombelow@gmail.com>
14 * @copyright  (c) 2008-2012 Kohana Team
15 * @license    http://kohanaframework.org/license
16 */
17class Kohana_FormTest extends Unittest_TestCase
18{
19	/**
20	 * Defaults for this test
21	 * @var array
22	 */
23	// @codingStandardsIgnoreStart
24	protected $environmentDefault = array(
25		'Kohana::$base_url' => '/',
26		'HTTP_HOST' => 'kohanaframework.org',
27		'Kohana::$index_file' => '',
28	);
29	// @codingStandardsIgnoreEnd
30
31	/**
32	 * Provides test data for test_open()
33	 *
34	 * @return array
35	 */
36	public function provider_open()
37	{
38		return array(
39			array(
40				  array('', NULL),
41				  array('action' => '')
42			),
43			array(
44				  array(NULL, NULL),
45				  array('action' => '')
46			),
47			array(
48				  array('foo', NULL),
49				  array('action' => '/foo')
50			),
51			array(
52				  array('foo', array('method' => 'get')),
53				  array('action' => '/foo', 'method' => 'get')
54			),
55		);
56	}
57
58	/**
59	 * Tests Form::open()
60	 *
61	 * @test
62	 * @dataProvider provider_open
63	 * @param boolean $input  Input for Form::open
64	 * @param boolean $expected Output for Form::open
65	 */
66	public function test_open($input, $expected)
67	{
68		list($action, $attributes) = $input;
69
70		$tag = Form::open($action, $attributes);
71
72		$matcher = array(
73			'tag' => 'form',
74			// Default attributes
75			'attributes' => array(
76				'method'         => 'post',
77				'accept-charset' => 'utf-8',
78			),
79		);
80
81		$matcher['attributes'] = $expected + $matcher['attributes'];
82
83		$this->assertTag($matcher, $tag);
84	}
85
86	/**
87	 * Tests Form::close()
88	 *
89	 * @test
90	 */
91	public function test_close()
92	{
93		$this->assertSame('</form>', Form::close());
94	}
95
96	/**
97	 * Provides test data for test_input()
98	 *
99	 * @return array
100	 */
101	public function provider_input()
102	{
103		return array(
104			// $value, $result
105			array('input',    'foo', 'bar', NULL, 'input'),
106			array('input',    'foo',  NULL, NULL, 'input'),
107			array('hidden',   'foo', 'bar', NULL, 'hidden'),
108			array('password', 'foo', 'bar', NULL, 'password'),
109		);
110	}
111
112	/**
113	 * Tests Form::input()
114	 *
115	 * @test
116	 * @dataProvider provider_input
117	 * @param boolean $input  Input for Form::input
118	 * @param boolean $expected Output for Form::input
119	 */
120	public function test_input($type, $name, $value, $attributes)
121	{
122		$matcher = array(
123			'tag' => 'input',
124			'attributes' => array('name' => $name, 'type' => $type)
125		);
126
127		// Form::input creates a text input
128		if ($type === 'input')
129		{
130			$matcher['attributes']['type'] = 'text';
131		}
132
133		// NULL just means no value
134		if ($value !== NULL)
135		{
136			$matcher['attributes']['value'] = $value;
137		}
138
139		// Add on any attributes
140		if (is_array($attributes))
141		{
142			$matcher['attributes'] = $attributes + $matcher['attributes'];
143		}
144
145		$tag = Form::$type($name, $value, $attributes);
146
147		$this->assertTag($matcher, $tag, $tag);
148	}
149
150	/**
151	 * Provides test data for test_file()
152	 *
153	 * @return array
154	 */
155	public function provider_file()
156	{
157		return array(
158			// $value, $result
159			array('foo', NULL, '<input type="file" name="foo" />'),
160		);
161	}
162
163	/**
164	 * Tests Form::file()
165	 *
166	 * @test
167	 * @dataProvider provider_file
168	 * @param boolean $input  Input for Form::file
169	 * @param boolean $expected Output for Form::file
170	 */
171	public function test_file($name, $attributes, $expected)
172	{
173		$this->assertSame($expected, Form::file($name, $attributes));
174	}
175
176	/**
177	 * Provides test data for test_check()
178	 *
179	 * @return array
180	 */
181	public function provider_check()
182	{
183		return array(
184			// $value, $result
185			array('checkbox', 'foo', NULL, FALSE, NULL),
186			array('checkbox', 'foo', NULL, TRUE, NULL),
187			array('checkbox', 'foo', 'bar', TRUE, NULL),
188
189			array('radio', 'foo', NULL, FALSE, NULL),
190			array('radio', 'foo', NULL, TRUE, NULL),
191			array('radio', 'foo', 'bar', TRUE, NULL),
192		);
193	}
194
195	/**
196	 * Tests Form::check()
197	 *
198	 * @test
199	 * @dataProvider provider_check
200	 * @param boolean $input  Input for Form::check
201	 * @param boolean $expected Output for Form::check
202	 */
203	public function test_check($type, $name, $value, $checked, $attributes)
204	{
205		$matcher = array('tag' => 'input', 'attributes' => array('name' => $name, 'type' => $type));
206
207		if ($value !== NULL)
208		{
209			$matcher['attributes']['value'] = $value;
210		}
211
212		if (is_array($attributes))
213		{
214			$matcher['attributes'] = $attributes + $matcher['attributes'];
215		}
216
217		if ($checked === TRUE)
218		{
219			$matcher['attributes']['checked'] = 'checked';
220		}
221
222		$tag = Form::$type($name, $value, $checked, $attributes);
223		$this->assertTag($matcher, $tag, $tag);
224	}
225
226	/**
227	 * Provides test data for test_text()
228	 *
229	 * @return array
230	 */
231	public function provider_text()
232	{
233		return array(
234			// $value, $result
235			array('textarea', 'foo', 'bar', NULL),
236			array('textarea', 'foo', 'bar', array('rows' => 20, 'cols' => 20)),
237			array('button', 'foo', 'bar', NULL),
238			array('label', 'foo', 'bar', NULL),
239			array('label', 'foo', NULL, NULL),
240		);
241	}
242
243	/**
244	 * Tests Form::textarea()
245	 *
246	 * @test
247	 * @dataProvider provider_text
248	 * @param boolean $input  Input for Form::textarea
249	 * @param boolean $expected Output for Form::textarea
250	 */
251	public function test_text($type, $name, $body, $attributes)
252	{
253		$matcher = array(
254			'tag' => $type,
255			'attributes' => array(),
256			'content' => $body,
257		);
258
259		if ($type !== 'label')
260		{
261			$matcher['attributes'] = array('name' => $name);
262		}
263		else
264		{
265			$matcher['attributes'] = array('for' => $name);
266		}
267
268
269		if (is_array($attributes))
270		{
271			$matcher['attributes'] = $attributes + $matcher['attributes'];
272		}
273
274		$tag = Form::$type($name, $body, $attributes);
275
276		$this->assertTag($matcher, $tag, $tag);
277	}
278
279
280	/**
281	 * Provides test data for test_select()
282	 *
283	 * @return array
284	 */
285	public function provider_select()
286	{
287		return array(
288			// $value, $result
289			array('foo', NULL, NULL, "<select name=\"foo\"></select>"),
290			array('foo', array('bar' => 'bar'), NULL, "<select name=\"foo\">\n<option value=\"bar\">bar</option>\n</select>"),
291			array('foo', array('bar' => 'bar'), 'bar', "<select name=\"foo\">\n<option value=\"bar\" selected=\"selected\">bar</option>\n</select>"),
292			array('foo', array('bar' => array('foo' => 'bar')), NULL, "<select name=\"foo\">\n<optgroup label=\"bar\">\n<option value=\"foo\">bar</option>\n</optgroup>\n</select>"),
293			array('foo', array('bar' => array('foo' => 'bar')), 'foo', "<select name=\"foo\">\n<optgroup label=\"bar\">\n<option value=\"foo\" selected=\"selected\">bar</option>\n</optgroup>\n</select>"),
294			// #2286
295			array('foo', array('bar' => 'bar', 'unit' => 'test', 'foo' => 'foo'), array('bar', 'foo'), "<select name=\"foo\" multiple=\"multiple\">\n<option value=\"bar\" selected=\"selected\">bar</option>\n<option value=\"unit\">test</option>\n<option value=\"foo\" selected=\"selected\">foo</option>\n</select>"),
296		);
297	}
298
299	/**
300	 * Tests Form::select()
301	 *
302	 * @test
303	 * @dataProvider provider_select
304	 * @param boolean $input  Input for Form::select
305	 * @param boolean $expected Output for Form::select
306	 */
307	public function test_select($name, $options, $selected, $expected)
308	{
309		// Much more efficient just to assertSame() rather than assertTag() on each element
310		$this->assertSame($expected, Form::select($name, $options, $selected));
311	}
312
313	/**
314	 * Provides test data for test_submit()
315	 *
316	 * @return array
317	 */
318	public function provider_submit()
319	{
320		return array(
321			// $value, $result
322			array('foo', 'Foobar!', '<input type="submit" name="foo" value="Foobar!" />'),
323		);
324	}
325
326	/**
327	 * Tests Form::submit()
328	 *
329	 * @test
330	 * @dataProvider provider_submit
331	 * @param boolean $input  Input for Form::submit
332	 * @param boolean $expected Output for Form::submit
333	 */
334	public function test_submit($name, $value, $expected)
335	{
336		$matcher = array(
337			'tag' => 'input',
338			'attributes' => array('name' => $name, 'type' => 'submit', 'value' => $value)
339		);
340
341		$this->assertTag($matcher, Form::submit($name, $value));
342	}
343
344
345	/**
346	 * Provides test data for test_image()
347	 *
348	 * @return array
349	 */
350	public function provider_image()
351	{
352		return array(
353			// $value, $result
354			array('foo', 'bar', array('src' => 'media/img/login.png'), '<input type="image" name="foo" value="bar" src="/media/img/login.png" />'),
355		);
356	}
357
358	/**
359	 * Tests Form::image()
360	 *
361	 * @test
362	 * @dataProvider provider_image
363	 * @param boolean $name         Input for Form::image
364	 * @param boolean $value        Input for Form::image
365	 * @param boolean $attributes  Input for Form::image
366	 * @param boolean $expected    Output for Form::image
367	 */
368	public function test_image($name, $value, $attributes, $expected)
369	{
370		$this->assertSame($expected, Form::image($name, $value, $attributes));
371	}
372
373	/**
374	 * Provides test data for test_label()
375	 *
376	 * @return array
377	 */
378	function provider_label()
379	{
380		return array(
381			// $value, $result
382			// Single for provided
383			array('email', NULL, NULL, '<label for="email">Email</label>'),
384			array('email_address', NULL, NULL, '<label for="email_address">Email Address</label>'),
385			array('email-address', NULL, NULL, '<label for="email-address">Email Address</label>'),
386			// For and text values provided
387			array('name', 'First name', NULL, '<label for="name">First name</label>'),
388			// with attributes
389			array('lastname', 'Last name', array('class' => 'text'), '<label class="text" for="lastname">Last name</label>'),
390			array('lastname', 'Last name', array('class' => 'text', 'id'=>'txt_lastname'), '<label id="txt_lastname" class="text" for="lastname">Last name</label>'),
391		);
392	}
393
394	/**
395	 * Tests Form::label()
396	 *
397	 * @test
398	 * @dataProvider provider_label
399	 * @param boolean $for         Input for Form::label
400	 * @param boolean $text        Input for Form::label
401	 * @param boolean $attributes  Input for Form::label
402	 * @param boolean $expected    Output for Form::label
403	 */
404	function test_label($for, $text, $attributes, $expected)
405	{
406		$this->assertSame($expected, Form::label($for, $text, $attributes));
407	}
408}
409