3 namespace Drupal\Tests\Core\Form;
5 use Drupal\Component\Utility\NestedArray;
6 use Drupal\Core\Form\FormState;
7 use Drupal\Core\Form\FormStateInterface;
8 use Drupal\Core\Form\SubformState;
9 use Drupal\Core\Form\SubformStateInterface;
10 use Drupal\Tests\UnitTestCase;
13 * @coversDefaultClass \Drupal\Core\Form\SubformState
17 class SubformStateTest extends UnitTestCase {
20 * The form state's values test fixture.
24 protected $formStateValues = [
27 'breed' => 'Pit bull',
37 protected $parentForm = [
40 '#parents' => ['foo'],
41 '#array_parents' => ['foo'],
44 '#parents' => ['dog'],
45 '#array_parents' => ['dog'],
47 '#parents' => ['dog', 'breed'],
48 '#array_parents' => ['dog', 'breed'],
51 '#parents' => ['dog', 'name'],
52 '#array_parents' => ['dog', 'name'],
59 * @covers ::getParents
61 * @dataProvider providerGetValues
63 * @param string[] $parents
64 * @param string $expected
66 public function testGetValues(array $parents, $expected) {
67 $parent_form_state = new FormState();
68 $parent_form_state->setValues($this->formStateValues);
70 $subform = NestedArray::getValue($this->parentForm, $parents);
71 $subform_state = SubformState::createForSubform($subform, $this->parentForm, $parent_form_state);
72 $subform_state_values = &$subform_state->getValues();
73 $this->assertSame($expected, $subform_state_values);
75 // Modify the retrieved values and confirm they are modified by reference in
76 // the parent form state.
77 $subform_state_values['fish'] = 'Jim';
78 $this->assertSame($subform_state_values, $subform_state->getValues());
82 * Provides data to self::testGetValues().
84 public function providerGetValues() {
88 $this->formStateValues['dog'],
96 * @covers ::getParents
98 * @dataProvider providerGetValuesBroken
100 * @param string[] $parents
101 * @param string $expected
103 public function testGetValuesBroken(array $parents, $expected) {
104 $this->setExpectedException(\UnexpectedValueException::class);
105 $this->testGetValues($parents, $expected);
109 * Provides data to self::testGetValuesBroken().
111 public function providerGetValuesBroken() {
115 $this->formStateValues['foo'],
128 * @dataProvider providerTestGetValue
130 public function testGetValue($parents, $key, $expected, $default = NULL) {
131 $parent_form_state = new FormState();
132 $parent_form_state->setValues($this->formStateValues);
134 $subform = NestedArray::getValue($this->parentForm, $parents);
135 $subform_state = SubformState::createForSubform($subform, $this->parentForm, $parent_form_state);
136 $subform_state_value = &$subform_state->getValue($key, $default);
137 $this->assertSame($expected, $subform_state_value);
139 // Modify the retrieved values and confirm they are modified by reference in
140 // the parent form state.
141 $subform_state_value = 'Jim';
142 $this->assertSame($subform_state_value, $subform_state->getValue($key));
146 * Provides data to self::testGetValue().
148 public function providerTestGetValue() {
162 * @dataProvider providerTestGetValueBroken
164 public function testGetValueBroken(array $parents, $key, $expected, $default = NULL) {
165 $this->setExpectedException(\UnexpectedValueException::class);
166 $this->testGetValue($parents, $key, $expected, $default);
170 * Provides data to self::testGetValueBroken().
172 public function providerTestGetValueBroken() {
184 * @covers ::setValues
186 * @dataProvider providerTestSetValues
188 public function testSetValues($parents, $new_values, $expected) {
189 $parent_form_state = new FormState();
190 $parent_form_state->setValues($this->formStateValues);
192 $subform = NestedArray::getValue($this->parentForm, $parents);
193 $subform_state = SubformState::createForSubform($subform, $this->parentForm, $parent_form_state);
194 $this->assertSame($subform_state, $subform_state->setValues($new_values));
195 $this->assertSame($expected, $parent_form_state->getValues());
199 * Provides data to self::testSetValues().
201 public function providerTestSetValues() {
215 * @covers ::setValues
217 * @dataProvider providerTestSetValuesBroken
219 public function testSetValuesBroken($parents, $new_values, $expected) {
220 $this->setExpectedException(\UnexpectedValueException::class);
221 $this->testSetValues($parents, $new_values, $expected);
225 * Provides data to self::testSetValuesBroken().
227 public function providerTestSetValuesBroken() {
234 'dog' => $this->formStateValues['dog'],
241 * @covers ::getCompleteFormState
243 public function testGetCompleteFormStateWithParentCompleteForm() {
244 $parent_form_state = $this->prophesize(FormStateInterface::class);
245 $subform_state = SubformState::createForSubform($this->parentForm['dog'], $this->parentForm, $parent_form_state->reveal());
246 $this->assertSame($parent_form_state->reveal(), $subform_state->getCompleteFormState());
250 * @covers ::getCompleteFormState
252 public function testGetCompleteFormStateWithParentSubform() {
253 $complete_form_state = $this->prophesize(FormStateInterface::class);
254 $parent_form_state = $this->prophesize(SubformStateInterface::class);
255 $parent_form_state->getCompleteFormState()
256 ->willReturn($complete_form_state->reveal())
258 $subform_state = SubformState::createForSubform($this->parentForm['dog'], $this->parentForm, $parent_form_state->reveal());
259 $this->assertSame($complete_form_state->reveal(), $subform_state->getCompleteFormState());
263 * @covers ::setLimitValidationErrors
265 public function testSetLimitValidationErrors() {
266 $parent_limit_validation_errors = ['dog', 'name'];
267 $limit_validation_errors = ['name'];
269 $parent_form_state = $this->prophesize(FormStateInterface::class);
270 $parent_form_state->setLimitValidationErrors($parent_limit_validation_errors)
273 $subform_state = SubformState::createForSubform($this->parentForm['dog'], $this->parentForm, $parent_form_state->reveal());
274 $this->assertSame($subform_state, $subform_state->setLimitValidationErrors($limit_validation_errors));
278 * @covers ::getLimitValidationErrors
280 public function testGetLimitValidationErrors() {
281 $parent_limit_validation_errors = ['dog', 'name'];
282 $limit_validation_errors = ['name'];
284 $parent_form_state = $this->prophesize(FormStateInterface::class);
285 $parent_form_state->getLimitValidationErrors()
286 ->willReturn($parent_limit_validation_errors)
289 $subform_state = SubformState::createForSubform($this->parentForm['dog'], $this->parentForm, $parent_form_state->reveal());
290 $this->assertSame($limit_validation_errors, $subform_state->getLimitValidationErrors());
294 * @covers ::setErrorByName
296 public function testSetErrorByName() {
297 $parent_form_error_name = 'dog][name';
298 $subform_error_name = 'name';
299 $message = 'De kat krabt de krullen van de trap.';
301 $parent_form_state = $this->prophesize(FormStateInterface::class);
302 $parent_form_state->setErrorByName($parent_form_error_name, $message)
305 $subform_state = SubformState::createForSubform($this->parentForm['dog'], $this->parentForm, $parent_form_state->reveal());
306 $this->assertSame($subform_state, $subform_state->setErrorByName($subform_error_name, $message));