1 | <?php |
||
6 | class FormFieldTest extends SapphireTest { |
||
7 | |||
8 | protected $requiredExtensions = array( |
||
9 | 'FormField' => array('FormFieldTest_Extension') |
||
10 | ); |
||
11 | |||
12 | public function testDefaultClasses() { |
||
13 | Config::nest(); |
||
14 | |||
15 | Config::inst()->update('FormField', 'default_classes', array( |
||
16 | 'class1', |
||
17 | )); |
||
18 | |||
19 | $field = new FormField('MyField'); |
||
20 | |||
21 | $this->assertContains('class1', $field->extraClass(), 'Class list does not contain expected class'); |
||
22 | |||
23 | Config::inst()->update('FormField', 'default_classes', array( |
||
24 | 'class1', |
||
25 | 'class2', |
||
26 | )); |
||
27 | |||
28 | $field = new FormField('MyField'); |
||
29 | |||
30 | $this->assertContains('class1 class2', $field->extraClass(), 'Class list does not contain expected class'); |
||
31 | |||
32 | Config::inst()->update('FormField', 'default_classes', array( |
||
33 | 'class3', |
||
34 | )); |
||
35 | |||
36 | $field = new FormField('MyField'); |
||
37 | |||
38 | $this->assertContains('class3', $field->extraClass(), 'Class list does not contain expected class'); |
||
39 | |||
40 | $field->removeExtraClass('class3'); |
||
41 | |||
42 | $this->assertNotContains('class3', $field->extraClass(), 'Class list contains unexpected class'); |
||
43 | |||
44 | Config::inst()->update('TextField', 'default_classes', array( |
||
45 | 'textfield-class', |
||
46 | )); |
||
47 | |||
48 | $field = new TextField('MyField'); |
||
49 | |||
50 | //check default classes inherit |
||
51 | $this->assertContains('class3', $field->extraClass(), 'Class list does not contain inherited class'); |
||
52 | $this->assertContains('textfield-class', $field->extraClass(), 'Class list does not contain expected class'); |
||
53 | |||
54 | Config::unnest(); |
||
55 | } |
||
56 | |||
57 | public function testAddExtraClass() { |
||
58 | $field = new FormField('MyField'); |
||
59 | $field->addExtraClass('class1'); |
||
60 | $field->addExtraClass('class2'); |
||
61 | $this->assertStringEndsWith('class1 class2', $field->extraClass()); |
||
62 | } |
||
63 | |||
64 | public function testRemoveExtraClass() { |
||
65 | $field = new FormField('MyField'); |
||
66 | $field->addExtraClass('class1'); |
||
67 | $field->addExtraClass('class2'); |
||
68 | $this->assertStringEndsWith('class1 class2', $field->extraClass()); |
||
69 | $field->removeExtraClass('class1'); |
||
70 | $this->assertStringEndsWith('class2', $field->extraClass()); |
||
71 | } |
||
72 | |||
73 | public function testAddManyExtraClasses() { |
||
74 | $field = new FormField('MyField'); |
||
75 | //test we can split by a range of spaces and tabs |
||
76 | $field->addExtraClass('class1 class2 class3 class4 class5'); |
||
77 | $this->assertStringEndsWith( |
||
78 | 'class1 class2 class3 class4 class5', |
||
79 | $field->extraClass() |
||
80 | ); |
||
81 | //test that duplicate classes don't get added |
||
82 | $field->addExtraClass('class1 class2'); |
||
83 | $this->assertStringEndsWith( |
||
84 | 'class1 class2 class3 class4 class5', |
||
85 | $field->extraClass() |
||
86 | ); |
||
87 | } |
||
88 | |||
89 | public function testRemoveManyExtraClasses() { |
||
111 | |||
112 | public function testAttributes() { |
||
113 | $field = new FormField('MyField'); |
||
114 | $field->setAttribute('foo', 'bar'); |
||
115 | $this->assertEquals('bar', $field->getAttribute('foo')); |
||
116 | $attrs = $field->getAttributes(); |
||
117 | $this->assertArrayHasKey('foo', $attrs); |
||
118 | $this->assertEquals('bar', $attrs['foo']); |
||
119 | } |
||
120 | |||
121 | public function testAttributesHTML() { |
||
122 | $field = new FormField('MyField'); |
||
123 | |||
124 | $field->setAttribute('foo', 'bar'); |
||
125 | $this->assertContains('foo="bar"', $field->getAttributesHTML()); |
||
126 | |||
127 | $field->setAttribute('foo', null); |
||
128 | $this->assertNotContains('foo=', $field->getAttributesHTML()); |
||
129 | |||
130 | $field->setAttribute('foo', ''); |
||
131 | $this->assertNotContains('foo=', $field->getAttributesHTML()); |
||
132 | |||
133 | $field->setAttribute('foo', false); |
||
134 | $this->assertNotContains('foo=', $field->getAttributesHTML()); |
||
135 | |||
136 | $field->setAttribute('foo', true); |
||
137 | $this->assertContains('foo="foo"', $field->getAttributesHTML()); |
||
138 | |||
139 | $field->setAttribute('foo', 'false'); |
||
140 | $this->assertContains('foo="false"', $field->getAttributesHTML()); |
||
141 | |||
142 | $field->setAttribute('foo', 'true'); |
||
143 | $this->assertContains('foo="true"', $field->getAttributesHTML()); |
||
144 | |||
145 | $field->setAttribute('foo', 0); |
||
146 | $this->assertContains('foo="0"', $field->getAttributesHTML()); |
||
147 | |||
148 | $field->setAttribute('one', 1); |
||
149 | $field->setAttribute('two', 2); |
||
150 | $field->setAttribute('three', 3); |
||
151 | $this->assertNotContains('one="1"', $field->getAttributesHTML('one', 'two')); |
||
152 | $this->assertNotContains('two="2"', $field->getAttributesHTML('one', 'two')); |
||
153 | $this->assertContains('three="3"', $field->getAttributesHTML('one', 'two')); |
||
154 | } |
||
155 | |||
156 | public function testReadonly() { |
||
157 | $field = new FormField('MyField'); |
||
158 | $field->setReadonly(true); |
||
159 | $this->assertContains('readonly="readonly"', $field->getAttributesHTML()); |
||
160 | $field->setReadonly(false); |
||
161 | $this->assertNotContains('readonly="readonly"', $field->getAttributesHTML()); |
||
162 | } |
||
163 | |||
164 | public function testDisabled() { |
||
165 | $field = new FormField('MyField'); |
||
166 | $field->setDisabled(true); |
||
167 | $this->assertContains('disabled="disabled"', $field->getAttributesHTML()); |
||
168 | $field->setDisabled(false); |
||
169 | $this->assertNotContains('disabled="disabled"', $field->getAttributesHTML()); |
||
170 | } |
||
171 | |||
172 | public function testEveryFieldTransformsReadonlyAsClone() { |
||
173 | $fieldClasses = ClassInfo::subclassesFor('FormField'); |
||
174 | foreach($fieldClasses as $fieldClass) { |
||
|
|||
175 | $reflectionClass = new ReflectionClass($fieldClass); |
||
176 | if(!$reflectionClass->isInstantiable()) continue; |
||
177 | $constructor = $reflectionClass->getMethod('__construct'); |
||
178 | if($constructor->getNumberOfRequiredParameters() > 1) continue; |
||
179 | if($fieldClass == 'CompositeField' || is_subclass_of($fieldClass, 'CompositeField')) continue; |
||
180 | |||
181 | if ( $fieldClass = 'NullableField' ) { |
||
182 | $instance = new $fieldClass(new TextField("{$fieldClass}_instance")); |
||
183 | } else { |
||
184 | $instance = new $fieldClass("{$fieldClass}_instance"); |
||
185 | } |
||
186 | $isReadonlyBefore = $instance->isReadonly(); |
||
187 | $readonlyInstance = $instance->performReadonlyTransformation(); |
||
188 | $this->assertEquals( |
||
189 | $isReadonlyBefore, |
||
190 | $instance->isReadonly(), |
||
191 | "FormField class {$fieldClass} retains its readonly state after calling performReadonlyTransformation()" |
||
192 | ); |
||
193 | $this->assertTrue( |
||
194 | $readonlyInstance->isReadonly(), |
||
195 | "FormField class {$fieldClass} returns a valid readonly representation as of isReadonly()" |
||
196 | ); |
||
197 | $this->assertNotSame( |
||
198 | $readonlyInstance, |
||
199 | $instance, |
||
200 | "FormField class {$fieldClass} returns a valid cloned readonly representation" |
||
201 | ); |
||
202 | } |
||
203 | } |
||
204 | |||
205 | public function testEveryFieldTransformsDisabledAsClone() { |
||
206 | $fieldClasses = ClassInfo::subclassesFor('FormField'); |
||
207 | foreach($fieldClasses as $fieldClass) { |
||
208 | $reflectionClass = new ReflectionClass($fieldClass); |
||
209 | if(!$reflectionClass->isInstantiable()) continue; |
||
210 | $constructor = $reflectionClass->getMethod('__construct'); |
||
211 | if($constructor->getNumberOfRequiredParameters() > 1) continue; |
||
212 | if($fieldClass == 'CompositeField' || is_subclass_of($fieldClass, 'CompositeField')) continue; |
||
213 | |||
214 | if ( $fieldClass = 'NullableField' ) { |
||
215 | $instance = new $fieldClass(new TextField("{$fieldClass}_instance")); |
||
216 | } else { |
||
217 | $instance = new $fieldClass("{$fieldClass}_instance"); |
||
218 | } |
||
219 | |||
220 | $isDisabledBefore = $instance->isDisabled(); |
||
221 | $disabledInstance = $instance->performDisabledTransformation(); |
||
222 | $this->assertEquals( |
||
223 | $isDisabledBefore, |
||
224 | $instance->isDisabled(), |
||
225 | "FormField class {$fieldClass} retains its disabled state after calling performDisabledTransformation()" |
||
226 | ); |
||
227 | $this->assertTrue( |
||
228 | $disabledInstance->isDisabled(), |
||
229 | "FormField class {$fieldClass} returns a valid disabled representation as of isDisabled()" |
||
230 | ); |
||
231 | $this->assertNotSame( |
||
232 | $disabledInstance, |
||
233 | $instance, |
||
234 | "FormField class {$fieldClass} returns a valid cloned disabled representation" |
||
235 | ); |
||
236 | } |
||
237 | } |
||
238 | |||
239 | public function testUpdateAttributes() { |
||
243 | |||
244 | public function testSetSchemaComponent() { |
||
245 | $field = new FormField('MyField'); |
||
246 | $field = $field->setSchemaComponent('MyComponent'); |
||
247 | $component = $field->getSchemaComponent(); |
||
248 | $this->assertEquals('MyComponent', $component); |
||
249 | } |
||
250 | |||
251 | public function testGetSchemaDataDefaults() { |
||
252 | $field = new FormField('MyField'); |
||
253 | $schema = $field->getSchemaDataDefaults(); |
||
254 | $this->assertInternalType('array', $schema); |
||
256 | |||
257 | public function testGetSchemaData() { |
||
267 | |||
268 | public function testSetSchemaData() { |
||
281 | |||
282 | public function testGetSchemaState() { |
||
288 | |||
289 | public function testSetSchemaState() { |
||
302 | |||
303 | public function testGetSchemaStateWithFormValidation() { |
||
312 | } |
||
313 | |||
325 |
There are different options of fixing this problem.
If you want to be on the safe side, you can add an additional type-check:
If you are sure that the expression is traversable, you might want to add a doc comment cast to improve IDE auto-completion and static analysis:
Mark the issue as a false-positive: Just hover the remove button, in the top-right corner of this issue for more options.