'',
'nestingLabel' => '',
'radioWrapper' => '{{label}}',
'selectedClass' => 'selected',
];
$this->templates = new StringTemplate($templates);
$this->context = $this->getMockBuilder('Cake\View\Form\ContextInterface')->getMock();
}
/**
* Test rendering basic radio buttons without nested inputs
*
* @return void
*/
public function testRenderSimpleNotNested()
{
$this->templates->add([
'nestingLabel' => '',
'radioWrapper' => '{{input}}{{label}}',
]);
$label = new NestingLabelWidget($this->templates);
$radio = new RadioWidget($this->templates, $label);
$data = [
'name' => 'Crayons[color]',
'label' => null,
'options' => ['r' => 'Red', 'b' => 'Black'],
];
$result = $radio->render($data, $this->context);
$expected = [
['input' => [
'type' => 'radio',
'name' => 'Crayons[color]',
'value' => 'r',
'id' => 'crayons-color-r',
]],
['label' => ['for' => 'crayons-color-r']],
'Red',
'/label',
['input' => [
'type' => 'radio',
'name' => 'Crayons[color]',
'value' => 'b',
'id' => 'crayons-color-b',
]],
['label' => ['for' => 'crayons-color-b']],
'Black',
'/label',
];
$this->assertHtml($expected, $result);
$data = [
'name' => 'Crayons[color]',
'label' => false,
'options' => ['r' => 'Red', 'b' => 'Black'],
];
$result = $radio->render($data, $this->context);
$expected = [
['input' => [
'type' => 'radio',
'name' => 'Crayons[color]',
'value' => 'r',
'id' => 'crayons-color-r',
]],
['input' => [
'type' => 'radio',
'name' => 'Crayons[color]',
'value' => 'b',
'id' => 'crayons-color-b',
]],
];
$this->assertHtml($expected, $result);
}
/**
* Test rendering basic radio buttons.
*
* @return void
*/
public function testRenderSimple()
{
$label = new NestingLabelWidget($this->templates);
$radio = new RadioWidget($this->templates, $label);
$data = [
'name' => 'Crayons[color]',
'label' => null,
'options' => ['r' => 'Red', 'b' => 'Black'],
];
$result = $radio->render($data, $this->context);
$expected = [
['label' => ['for' => 'crayons-color-r']],
['input' => [
'type' => 'radio',
'name' => 'Crayons[color]',
'value' => 'r',
'id' => 'crayons-color-r',
]],
'Red',
'/label',
['label' => ['for' => 'crayons-color-b']],
['input' => [
'type' => 'radio',
'name' => 'Crayons[color]',
'value' => 'b',
'id' => 'crayons-color-b',
]],
'Black',
'/label',
];
$this->assertHtml($expected, $result);
$data = [
'name' => 'Crayons[color]',
'options' => new Collection(['r' => 'Red', 'b' => 'Black']),
];
$result = $radio->render($data, $this->context);
$this->assertHtml($expected, $result);
}
/**
* Test rendering the activeClass template var
*
* @return void
*/
public function testRenderSimpleActiveTemplateVar()
{
$this->templates->add([
'nestingLabel' => '',
'radioWrapper' => '{{input}}{{label}}',
]);
$label = new NestingLabelWidget($this->templates);
$radio = new RadioWidget($this->templates, $label);
$data = [
'name' => 'Crayons[color]',
'val' => 'r',
'options' => ['r' => 'Red', 'b' => 'Black'],
];
$result = $radio->render($data, $this->context);
$expected = [
['input' => [
'type' => 'radio',
'name' => 'Crayons[color]',
'value' => 'r',
'id' => 'crayons-color-r',
'checked' => 'checked',
]],
['label' => ['class' => 'active', 'for' => 'crayons-color-r']],
'Red',
'/label',
['input' => [
'type' => 'radio',
'name' => 'Crayons[color]',
'value' => 'b',
'id' => 'crayons-color-b',
]],
['label' => ['class' => '', 'for' => 'crayons-color-b']],
'Black',
'/label',
];
$this->assertHtml($expected, $result);
}
/**
* Test rendering inputs with the complex option form.
*
* @return void
*/
public function testRenderComplex()
{
$label = new NestingLabelWidget($this->templates);
$radio = new RadioWidget($this->templates, $label);
$data = [
'name' => 'Crayons[color]',
'options' => [
['value' => 'r', 'text' => 'Red', 'id' => 'my_id'],
['value' => 'b', 'text' => 'Black', 'id' => 'my_id_2', 'data-test' => 'test'],
],
];
$result = $radio->render($data, $this->context);
$expected = [
['label' => ['for' => 'my_id']],
['input' => [
'type' => 'radio',
'name' => 'Crayons[color]',
'value' => 'r',
'id' => 'my_id',
]],
'Red',
'/label',
['label' => ['for' => 'my_id_2']],
['input' => [
'type' => 'radio',
'name' => 'Crayons[color]',
'value' => 'b',
'id' => 'my_id_2',
'data-test' => 'test',
]],
'Black',
'/label',
];
$this->assertHtml($expected, $result);
}
/**
* Test rendering inputs with label options
*
* @return void
*/
public function testRenderComplexLabelAttributes()
{
$label = new NestingLabelWidget($this->templates);
$radio = new RadioWidget($this->templates, $label);
$data = [
'name' => 'Crayons[color]',
'options' => [
['value' => 'r', 'text' => 'Red', 'label' => ['style' => 'color:red']],
['value' => 'b', 'text' => 'Black', 'label' => ['data-test' => 'yes']],
],
];
$result = $radio->render($data, $this->context);
$expected = [
['label' => ['for' => 'crayons-color-r', 'style' => 'color:red']],
['input' => [
'type' => 'radio',
'name' => 'Crayons[color]',
'value' => 'r',
'id' => 'crayons-color-r',
]],
'Red',
'/label',
['label' => ['for' => 'crayons-color-b', 'data-test' => 'yes']],
['input' => [
'type' => 'radio',
'name' => 'Crayons[color]',
'value' => 'b',
'id' => 'crayons-color-b',
]],
'Black',
'/label',
];
$this->assertHtml($expected, $result);
}
/**
* Test that id suffixes are generated to not collide
*
* @return void
*/
public function testRenderIdSuffixGeneration()
{
$label = new NestingLabelWidget($this->templates);
$radio = new RadioWidget($this->templates, $label);
$data = [
'name' => 'Thing[value]',
'options' => ['a>b' => 'First', 'a 'Second'],
];
$result = $radio->render($data, $this->context);
$expected = [
['label' => ['for' => 'thing-value-a-b']],
['input' => [
'type' => 'radio',
'name' => 'Thing[value]',
'value' => 'a>b',
'id' => 'thing-value-a-b',
]],
'First',
'/label',
['label' => ['for' => 'thing-value-a-b1']],
['input' => [
'type' => 'radio',
'name' => 'Thing[value]',
'value' => 'a<b',
'id' => 'thing-value-a-b1',
]],
'Second',
'/label',
];
$this->assertHtml($expected, $result);
}
/**
* Test rendering checks the right option with booleanish values.
*
* @return void
*/
public function testRenderBooleanishValues()
{
$label = new NestingLabelWidget($this->templates);
$radio = new RadioWidget($this->templates, $label);
$data = [
'name' => 'Model[field]',
'options' => ['1' => 'Yes', '0' => 'No'],
'val' => '0',
];
$result = $radio->render($data, $this->context);
$expected = [
['label' => ['for' => 'model-field-1']],
['input' => ['type' => 'radio', 'name' => 'Model[field]', 'value' => '1', 'id' => 'model-field-1']],
'Yes',
'/label',
['label' => ['for' => 'model-field-0']],
['input' => ['type' => 'radio', 'name' => 'Model[field]', 'value' => '0', 'id' => 'model-field-0', 'checked' => 'checked']],
'No',
'/label',
];
$this->assertHtml($expected, $result);
$data['val'] = 0;
$result = $radio->render($data, $this->context);
$this->assertHtml($expected, $result);
$data['val'] = false;
$result = $radio->render($data, $this->context);
$this->assertHtml($expected, $result);
$expected = [
['label' => ['for' => 'model-field-1']],
['input' => ['type' => 'radio', 'name' => 'Model[field]', 'value' => '1', 'id' => 'model-field-1']],
'Yes',
'/label',
['label' => ['for' => 'model-field-0']],
['input' => ['type' => 'radio', 'name' => 'Model[field]', 'value' => '0', 'id' => 'model-field-0']],
'No',
'/label',
];
$data['val'] = null;
$result = $radio->render($data, $this->context);
$this->assertHtml($expected, $result);
$data['val'] = '';
$result = $radio->render($data, $this->context);
$this->assertHtml($expected, $result);
$expected = [
['label' => ['for' => 'model-field-1']],
['input' => ['type' => 'radio', 'name' => 'Model[field]', 'value' => '1', 'id' => 'model-field-1', 'checked' => 'checked']],
'Yes',
'/label',
['label' => ['for' => 'model-field-0']],
['input' => ['type' => 'radio', 'name' => 'Model[field]', 'value' => '0', 'id' => 'model-field-0']],
'No',
'/label',
];
$data['val'] = '1';
$result = $radio->render($data, $this->context);
$this->assertHtml($expected, $result);
$data['val'] = 1;
$result = $radio->render($data, $this->context);
$this->assertHtml($expected, $result);
$data['val'] = true;
$result = $radio->render($data, $this->context);
$this->assertHtml($expected, $result);
}
/**
* Test that render() works with the required attribute.
*
* @return void
*/
public function testRenderRequiredAndFormAttribute()
{
$label = new NestingLabelWidget($this->templates);
$radio = new RadioWidget($this->templates, $label);
$data = [
'name' => 'published',
'options' => ['option A', 'option B'],
'required' => true,
'form' => 'my-form',
];
$result = $radio->render($data, $this->context);
$expected = [
['label' => ['for' => 'published-0']],
['input' => ['type' => 'radio', 'name' => 'published', 'value' => '0',
'id' => 'published-0', 'required' => 'required', 'form' => 'my-form']],
'option A',
'/label',
['label' => ['for' => 'published-1']],
['input' => ['type' => 'radio', 'name' => 'published', 'value' => '1',
'id' => 'published-1', 'required' => 'required', 'form' => 'my-form']],
'option B',
'/label',
];
$this->assertHtml($expected, $result);
}
/**
* Test rendering the empty option.
*
* @return void
*/
public function testRenderEmptyOption()
{
$label = new NestingLabelWidget($this->templates);
$radio = new RadioWidget($this->templates, $label);
$data = [
'name' => 'Crayons[color]',
'options' => ['r' => 'Red'],
'empty' => true,
];
$result = $radio->render($data, $this->context);
$expected = [
['label' => ['for' => 'crayons-color']],
['input' => [
'type' => 'radio',
'name' => 'Crayons[color]',
'value' => '',
'id' => 'crayons-color',
]],
'empty',
'/label',
['label' => ['for' => 'crayons-color-r']],
['input' => [
'type' => 'radio',
'name' => 'Crayons[color]',
'value' => 'r',
'id' => 'crayons-color-r',
]],
'Red',
'/label',
];
$this->assertHtml($expected, $result);
$data['empty'] = 'Choose one';
$result = $radio->render($data, $this->context);
$expected = [
['label' => ['for' => 'crayons-color']],
['input' => [
'type' => 'radio',
'name' => 'Crayons[color]',
'value' => '',
'id' => 'crayons-color',
]],
'Choose one',
'/label',
['label' => ['for' => 'crayons-color-r']],
['input' => [
'type' => 'radio',
'name' => 'Crayons[color]',
'value' => 'r',
'id' => 'crayons-color-r',
]],
'Red',
'/label',
];
$this->assertHtml($expected, $result);
}
/**
* Test rendering the input inside the label.
*
* @return void
*/
public function testRenderInputInsideLabel()
{
$this->templates->add([
'label' => '',
'radioWrapper' => '{{label}}',
]);
$label = new NestingLabelWidget($this->templates);
$radio = new RadioWidget($this->templates, $label);
$data = [
'name' => 'Crayons[color]',
'options' => ['r' => 'Red'],
];
$result = $radio->render($data, $this->context);
$expected = [
['label' => ['for' => 'crayons-color-r']],
['input' => [
'type' => 'radio',
'name' => 'Crayons[color]',
'value' => 'r',
'id' => 'crayons-color-r',
]],
'Red',
'/label',
];
$this->assertHtml($expected, $result);
}
/**
* test render() and selected inputs.
*
* @return void
*/
public function testRenderSelected()
{
$label = new NestingLabelWidget($this->templates);
$radio = new RadioWidget($this->templates, $label);
$data = [
'name' => 'Versions[ver]',
'val' => '1',
'options' => [
1 => 'one',
'1x' => 'one x',
'2' => 'two',
],
];
$result = $radio->render($data, $this->context);
$expected = [
['label' => ['for' => 'versions-ver-1']],
['input' => [
'id' => 'versions-ver-1',
'name' => 'Versions[ver]',
'type' => 'radio',
'value' => '1',
'checked' => 'checked',
]],
'one',
'/label',
['label' => ['for' => 'versions-ver-1x']],
['input' => [
'id' => 'versions-ver-1x',
'name' => 'Versions[ver]',
'type' => 'radio',
'value' => '1x',
]],
'one x',
'/label',
['label' => ['for' => 'versions-ver-2']],
['input' => [
'id' => 'versions-ver-2',
'name' => 'Versions[ver]',
'type' => 'radio',
'value' => '2',
]],
'two',
'/label',
];
$this->assertHtml($expected, $result);
}
/**
* Test rendering with disable inputs
*
* @return void
*/
public function testRenderDisabled()
{
$label = new NestingLabelWidget($this->templates);
$radio = new RadioWidget($this->templates, $label);
$data = [
'name' => 'Versions[ver]',
'options' => [
1 => 'one',
'1x' => 'one x',
'2' => 'two',
],
'disabled' => true,
];
$result = $radio->render($data, $this->context);
$expected = [
['label' => ['for' => 'versions-ver-1']],
['input' => [
'id' => 'versions-ver-1',
'name' => 'Versions[ver]',
'type' => 'radio',
'value' => '1',
'disabled' => 'disabled',
]],
'one',
'/label',
['label' => ['for' => 'versions-ver-1x']],
['input' => [
'id' => 'versions-ver-1x',
'name' => 'Versions[ver]',
'type' => 'radio',
'value' => '1x',
'disabled' => 'disabled',
]],
'one x',
'/label',
];
$this->assertHtml($expected, $result);
$data['disabled'] = 'a string';
$result = $radio->render($data, $this->context);
$this->assertHtml($expected, $result);
$data['disabled'] = ['1'];
$result = $radio->render($data, $this->context);
$expected = [
['label' => ['for' => 'versions-ver-1']],
['input' => [
'id' => 'versions-ver-1',
'name' => 'Versions[ver]',
'type' => 'radio',
'value' => '1',
'disabled' => 'disabled',
]],
'one',
'/label',
['label' => ['for' => 'versions-ver-1x']],
['input' => [
'id' => 'versions-ver-1x',
'name' => 'Versions[ver]',
'type' => 'radio',
'value' => '1x',
]],
'one x',
'/label',
];
$this->assertHtml($expected, $result);
}
/**
* Test rendering with label options.
*
* @return void
*/
public function testRenderLabelOptions()
{
$label = new NestingLabelWidget($this->templates);
$radio = new RadioWidget($this->templates, $label);
$data = [
'name' => 'Versions[ver]',
'options' => [
1 => 'one',
'1x' => 'one x',
'2' => 'two',
],
'label' => false,
];
$result = $radio->render($data, $this->context);
$expected = [
['input' => [
'id' => 'versions-ver-1',
'name' => 'Versions[ver]',
'type' => 'radio',
'value' => '1',
]],
['input' => [
'id' => 'versions-ver-1x',
'name' => 'Versions[ver]',
'type' => 'radio',
'value' => '1x',
]],
];
$this->assertHtml($expected, $result);
$data = [
'name' => 'Versions[ver]',
'options' => [
1 => 'one',
'1x' => 'one x',
'2' => 'two',
],
'label' => [
'class' => 'my-class',
],
];
$result = $radio->render($data, $this->context);
$expected = [
['label' => ['class' => 'my-class', 'for' => 'versions-ver-1']],
['input' => [
'id' => 'versions-ver-1',
'name' => 'Versions[ver]',
'type' => 'radio',
'value' => '1',
]],
'one',
'/label',
['label' => ['class' => 'my-class', 'for' => 'versions-ver-1x']],
['input' => [
'id' => 'versions-ver-1x',
'name' => 'Versions[ver]',
'type' => 'radio',
'value' => '1x',
]],
'one x',
'/label',
];
$this->assertHtml($expected, $result);
}
/**
* Ensure that the input + label are composed with
* a template.
*
* @return void
*/
public function testRenderContainerTemplate()
{
$this->templates->add([
'radioWrapper' => '
{{input}}{{label}}
',
]);
$label = new NestingLabelWidget($this->templates);
$radio = new RadioWidget($this->templates, $label);
$data = [
'name' => 'Versions[ver]',
'options' => [
1 => 'one',
'1x' => 'one x',
'2' => 'two',
],
];
$result = $radio->render($data, $this->context);
$this->assertContains(
'assertContains(
'
',
$result
);
}
/**
* Ensure that template vars work.
*
* @return void
*/
public function testRenderTemplateVars()
{
$this->templates->add([
'radioWrapper' => '{{label}}
',
'radio' => '',
'nestingLabel' => '',
]);
$label = new NestingLabelWidget($this->templates);
$radio = new RadioWidget($this->templates, $label);
$data = [
'name' => 'Versions[ver]',
'options' => [
['value' => '1x', 'text' => 'one x', 'templateVars' => ['labelVar' => 'l-var', 'inputVar' => 'i-var']],
'2' => 'two',
],
'templateVars' => [
'wrapperVar' => 'wrap-var',
],
];
$result = $radio->render($data, $this->context);
$this->assertContains('data-var="wrap-var">', $result);
$this->assertContains('two wrap-var', $result);
}
/**
* testRenderCustomAttributes method
*
* Test render with custom attributes.
*
* @return void
*/
public function testRenderCustomAttributes()
{
$label = new NestingLabelWidget($this->templates);
$radio = new RadioWidget($this->templates, $label);
$result = $radio->render([
'name' => 'Model[field]',
'label' => null,
'options' => ['option A', 'option B'],
'class' => 'my-class',
'data-ref' => 'custom-attr',
], $this->context);
$expected = [
['label' => ['for' => 'model-field-0']],
[
'input' => [
'type' => 'radio',
'name' => 'Model[field]',
'value' => '0',
'id' => 'model-field-0',
'class' => 'my-class',
'data-ref' => 'custom-attr',
],
],
'option A',
'/label',
['label' => ['for' => 'model-field-1']],
[
'input' => [
'type' => 'radio',
'name' => 'Model[field]',
'value' => '1',
'id' => 'model-field-1',
'class' => 'my-class',
'data-ref' => 'custom-attr',
],
],
'option B',
'/label',
];
$this->assertHtml($expected, $result);
}
/**
* testRenderExplicitId method
*
* Test that the id passed is actually used
* Issue: https://github.com/cakephp/cakephp/issues/13342
*
* @return void
*/
public function testRenderExplicitId()
{
$label = new NestingLabelWidget($this->templates);
$input = new RadioWidget($this->templates, $label);
$data = [
'name' => 'field',
'options' => ['value1', 'value2', -1 => 'negative'],
'id' => 'alternative-id',
'idPrefix' => 'willBeIgnored',
];
$result = $input->render($data, $this->context);
$expected = [
[
'label' => ['for' => 'alternative-id-0'],
'input' => ['type' => 'radio', 'name' => 'field', 'value' => '0', 'id' => 'alternative-id-0'],
],
'value1',
'/label',
[
'label' => ['for' => 'alternative-id-1'],
'input' => ['type' => 'radio', 'name' => 'field', 'value' => '1', 'id' => 'alternative-id-1'],
],
'value2',
'/label',
[
'label' => ['for' => 'alternative-id--1'],
'input' => ['type' => 'radio', 'name' => 'field', 'value' => '-1', 'id' => 'alternative-id--1'],
],
'negative',
'/label',
];
$this->assertHtml($expected, $result);
$data = [
'name' => 'field',
'options' => ['value1', 'value2'],
'idPrefix' => 'formprefix',
];
$result = $input->render($data, $this->context);
$expected = [
[
'label' => ['for' => 'formprefix-field-0'],
'input' => ['type' => 'radio', 'name' => 'field', 'value' => '0', 'id' => 'formprefix-field-0'],
],
'value1',
'/label',
[
'label' => ['for' => 'formprefix-field-1'],
'input' => ['type' => 'radio', 'name' => 'field', 'value' => '1', 'id' => 'formprefix-field-1'],
],
'value2',
'/label',
];
$this->assertHtml($expected, $result);
}
/**
* testRenderSelectedClass method
*
* Test that the custom selected class is passed to label
* Issue: https://github.com/cakephp/cakephp/issues/11249
*
* @return void
*/
public function testRenderSelectedClass()
{
$this->templates->add(['selectedClass' => 'active']);
$label = new NestingLabelWidget($this->templates);
$input = new RadioWidget($this->templates, $label);
$data = [
'name' => 'field',
'options' => ['value1' => 'title1'],
'val' => 'value1',
'label' => ['title' => 'my label'],
];
$result = $input->render($data, $this->context);
$expected = [
['label' => [
'title' => 'my label',
'class' => 'active',
'for' => 'field-value1',
]],
];
$this->assertHtml($expected, $result);
}
}