NumericFieldTest.php
5.37 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
<?php
/**
* @package framework
* @subpackage tests
*/
class NumericFieldTest extends SapphireTest {
protected $usesDatabase = false;
/**
* In some cases and locales, validation expects non-breaking spaces.
*
* Duplicates non-public NumericField::clean method
*
* @param string $input
* @return string The input value, with all spaces replaced with non-breaking spaces
*/
protected function clean($input) {
$nbsp = html_entity_decode(' ', null, 'UTF-8');
return str_replace(' ', $nbsp, trim($input));
}
protected function checkInputValidation($locale, $tests) {
i18n::set_locale($locale);
$field = new NumericField('Number');
$validator = new RequiredFields('Number');
foreach($tests as $input => $output) {
// Both decimal and thousands B
$field->setValue($input);
if($output === false) {
$this->assertFalse(
$field->validate($validator),
"Expect validation to fail for input $input in locale $locale"
);
$this->assertEquals(
0,
$field->dataValue(),
"Expect invalid value to be rewritten to 0 in locale $locale"
);
// Even invalid values shouldn't be rewritten
$this->assertEquals(
$this->clean($input),
$field->Value(),
"Expected input $input to be saved in the field in locale $locale"
);
} else {
$this->assertTrue(
$field->validate($validator),
"Expect validation to succeed for $input in locale $locale"
);
$this->assertEquals(
$output,
$field->dataValue(),
"Expect value $input to be mapped to $output in locale $locale"
);
}
}
}
/**
* Test that data loaded in via Form::loadDataFrom(DataObject) will populate the field correctly,
* and can format the database value appropriately for the frontend
*
* @param string $locale
* @param array $tests
*/
public function checkDataFormatting($locale, $tests) {
i18n::set_locale($locale);
$field = new NumericField('Number');
$form = new Form(new Controller(), 'Form', new FieldList($field), new FieldList());
$dataObject = new NumericFieldTest_Object();
foreach($tests as $input => $output) {
// Given a dataobject as a context, the field should assume the field value is not localised
$dataObject->Number = (string)$input;
$form->loadDataFrom($dataObject, Form::MERGE_CLEAR_MISSING);
// Test value
$this->assertEquals(
$input,
$field->dataValue(),
"Expected $input loaded via dataobject to be left intact in locale $locale"
);
// Test expected formatted value (Substitute nbsp for spaces)
$this->assertEquals(
$this->clean($output),
$field->Value(),
"Expected $input to be formatted as $output in locale $locale"
);
}
}
/**
* German locale values (same as dutch)
*/
public function testGermanLocales() {
$this->checkDataFormatting('de_DE', $formatting = array(
'13000' => "13.000",
'15' => '15',
'12.0' => '12,0',
'12.1' => '12,1',
'14000.5' => "14.000,5",
));
$this->checkDataFormatting('nl_NL', $formatting);
$this->checkInputValidation('de_DE', $validation = array(
'13000' => 13000,
'12,00' => 12.00,
'12.00' => false,
'11 000' => false,
'11.000' => 11000,
'11,000' => 11.0,
'15 000,5' => false,
'15 000.5' => false,
'15.000,5' => 15000.5,
'15,000.5' => false,
));
$this->checkInputValidation('nl_NL', $validation);
}
/**
* French locale values
*/
public function testFrenchLocales() {
$this->checkDataFormatting('fr_FR', array(
'13000' => "13 000",
'15' => '15',
'12.0' => '12,0',
'12.1' => '12,1',
'14000.5' => "14 000,5",
));
$this->checkInputValidation('fr_FR', array(
'13000' => 13000,
'12,00' => 12.00,
'12.00' => false,
'11 000' => 11000,
'11.000' => false,
'11,000' => 11.000,
'15 000,5' => 15000.5,
'15 000.5' => false,
'15.000,5' => false,
'15,000.5' => false,
));
}
/**
* US locale values
*/
public function testUSLocales() {
$this->checkDataFormatting('en_US', array(
'13000' => "13,000",
'15' => '15',
'12.0' => '12.0',
'12.1' => '12.1',
'14000.5' => "14,000.5",
));
$this->checkInputValidation('en_US', array(
'13000' => 13000,
'12,00' => false,
'12.00' => 12.00,
'11 000' => false,
'11.000' => 11.0,
'11,000' => 11000,
'15 000,5' => false,
'15 000.5' => false,
'15.000,5' => false,
'15,000.5' => 15000.5,
));
}
/**
* Test empty values
*/
public function testEmptyValidator() {
i18n::set_locale('en_US');
$field = new NumericField('Number');
$validator = new RequiredFields('Number');
// Treats '0' as given for the sake of required fields
$field->setValue('0');
$this->assertTrue($field->validate($validator));
$this->assertEquals(0, $field->dataValue());
// Treat literal 0
$field->setValue(0);
$this->assertTrue($field->validate($validator));
$this->assertEquals(0, $field->dataValue());
// Should fail the 'required but not given' test
$field->setValue('');
$this->assertFalse($field->validate($validator));
$field->setValue(false);
$this->assertFalse($field->validate($validator));
}
public function testReadonly() {
i18n::set_locale('en_US');
$field = new NumericField('Number');
$this->assertRegExp("#<span[^>]+>\s*0\s*<\/span>#", "".$field->performReadonlyTransformation()->Field()."");
}
}
class NumericFieldTest_Object extends DataObject implements TestOnly {
private static $db = array(
'Number' => 'Float'
);
}