@@ -134,4 +134,250 @@ public function it_returns_float_graphql_type_with_decimal_config()
134134
135135 $ this ->assertEquals ('Float ' , $ type ->name );
136136 }
137+
138+ #[Test]
139+ public function it_handles_locale_specific_comma_decimal_in_config ()
140+ {
141+ $ fieldtype = (new Range ())->setField (new Field ('test ' , [
142+ 'type ' => 'range ' ,
143+ 'min ' => 0 ,
144+ 'max ' => 100 ,
145+ 'step ' => '0,5 ' , // European format: 0.5
146+ ]));
147+
148+ $ result = $ fieldtype ->process ('7,5 ' );
149+
150+ $ this ->assertIsFloat ($ result );
151+ $ this ->assertEquals (7.5 , $ result );
152+ }
153+
154+ #[Test]
155+ public function it_handles_locale_specific_comma_decimal_in_value ()
156+ {
157+ $ fieldtype = (new Range ())->setField (new Field ('test ' , [
158+ 'type ' => 'range ' ,
159+ 'min ' => 0 ,
160+ 'max ' => 100 ,
161+ 'step ' => 0.1 ,
162+ ]));
163+
164+ $ result = $ fieldtype ->process ('3,14 ' );
165+
166+ $ this ->assertIsFloat ($ result );
167+ $ this ->assertEquals (3.14 , $ result );
168+ }
169+
170+ #[Test]
171+ public function it_handles_thousands_separator_with_decimal ()
172+ {
173+ $ fieldtype = (new Range ())->setField (new Field ('test ' , [
174+ 'type ' => 'range ' ,
175+ 'min ' => 0 ,
176+ 'max ' => 10000 ,
177+ 'step ' => 0.01 ,
178+ ]));
179+
180+ // Format: 1,234.56 (comma as thousands separator)
181+ $ result = $ fieldtype ->process ('1,234.56 ' );
182+
183+ $ this ->assertIsFloat ($ result );
184+ $ this ->assertEquals (1234.56 , $ result );
185+ }
186+
187+ #[Test]
188+ public function it_uses_number_formatter_for_locale_aware_parsing ()
189+ {
190+ if (! class_exists (\NumberFormatter::class)) {
191+ $ this ->markTestSkipped ('NumberFormatter (intl extension) not available ' );
192+ }
193+
194+ $ originalLocale = app ()->getLocale ();
195+ app ()->setLocale ('de_DE ' );
196+
197+ $ fieldtype = (new Range ())->setField (new Field ('test ' , [
198+ 'type ' => 'range ' ,
199+ 'min ' => 0 ,
200+ 'max ' => 10000 ,
201+ 'step ' => 0.01 ,
202+ ]));
203+
204+ // Test that NumberFormatter correctly parses German locale format
205+ // NumberFormatter will handle this according to locale rules
206+ $ result = $ fieldtype ->process ('1.234,56 ' );
207+
208+ app ()->setLocale ($ originalLocale );
209+
210+ $ this ->assertIsFloat ($ result );
211+ $ this ->assertEquals (1234.56 , $ result );
212+ }
213+
214+ #[Test]
215+ public function it_handles_french_format_space_as_thousands_separator ()
216+ {
217+ $ fieldtype = (new Range ())->setField (new Field ('test ' , [
218+ 'type ' => 'range ' ,
219+ 'min ' => 0 ,
220+ 'max ' => 100000 ,
221+ 'step ' => 0.01 ,
222+ ]));
223+
224+ // French (fr_FR): space as thousands separator, comma as decimal
225+ $ result = $ fieldtype ->process ('1 234,56 ' );
226+
227+ $ this ->assertIsFloat ($ result );
228+ $ this ->assertEquals (1234.56 , $ result );
229+ }
230+
231+ #[Test]
232+ public function it_handles_german_format_with_multiple_thousands ()
233+ {
234+ $ fieldtype = (new Range ())->setField (new Field ('test ' , [
235+ 'type ' => 'range ' ,
236+ 'min ' => 0 ,
237+ 'max ' => 10000000 ,
238+ 'step ' => 0.01 ,
239+ ]));
240+
241+ // German (de_DE): period as thousands, comma as decimal
242+ $ result = $ fieldtype ->process ('1.234.567,89 ' );
243+
244+ $ this ->assertIsFloat ($ result );
245+ $ this ->assertEquals (1234567.89 , $ result );
246+ }
247+
248+ #[Test]
249+ public function it_handles_swiss_german_apostrophe_separator ()
250+ {
251+ $ fieldtype = (new Range ())->setField (new Field ('test ' , [
252+ 'type ' => 'range ' ,
253+ 'min ' => 0 ,
254+ 'max ' => 10000000 ,
255+ 'step ' => 0.01 ,
256+ ]));
257+
258+ // Swiss German (de_CH): apostrophe as thousands, period as decimal
259+ $ result = $ fieldtype ->process ("1'234'567.89 " );
260+
261+ $ this ->assertIsFloat ($ result );
262+ $ this ->assertEquals (1234567.89 , $ result );
263+ }
264+
265+ #[Test]
266+ public function it_handles_swiss_format_with_comma_decimal ()
267+ {
268+ $ fieldtype = (new Range ())->setField (new Field ('test ' , [
269+ 'type ' => 'range ' ,
270+ 'min ' => 0 ,
271+ 'max ' => 100000 ,
272+ 'step ' => 0.01 ,
273+ ]));
274+
275+ // Swiss (some regions): apostrophe as thousands, comma as decimal
276+ $ result = $ fieldtype ->process ("12'345,67 " );
277+
278+ $ this ->assertIsFloat ($ result );
279+ $ this ->assertEquals (12345.67 , $ result );
280+ }
281+
282+ #[Test]
283+ public function it_handles_italian_format ()
284+ {
285+ $ fieldtype = (new Range ())->setField (new Field ('test ' , [
286+ 'type ' => 'range ' ,
287+ 'min ' => 0 ,
288+ 'max ' => 10000000 ,
289+ 'step ' => 0.01 ,
290+ ]));
291+
292+ // Italian (it_IT): period as thousands, comma as decimal
293+ $ result = $ fieldtype ->process ('2.500.000,75 ' );
294+
295+ $ this ->assertIsFloat ($ result );
296+ $ this ->assertEquals (2500000.75 , $ result );
297+ }
298+
299+ #[Test]
300+ public function it_handles_spanish_format ()
301+ {
302+ $ fieldtype = (new Range ())->setField (new Field ('test ' , [
303+ 'type ' => 'range ' ,
304+ 'min ' => 0 ,
305+ 'max ' => 100000 ,
306+ 'step ' => 0.01 ,
307+ ]));
308+
309+ // Spanish (es_ES): period as thousands, comma as decimal
310+ $ result = $ fieldtype ->process ('12.345,67 ' );
311+
312+ $ this ->assertIsFloat ($ result );
313+ $ this ->assertEquals (12345.67 , $ result );
314+ }
315+
316+ #[Test]
317+ public function it_handles_us_format ()
318+ {
319+ $ fieldtype = (new Range ())->setField (new Field ('test ' , [
320+ 'type ' => 'range ' ,
321+ 'min ' => 0 ,
322+ 'max ' => 10000000 ,
323+ 'step ' => 0.01 ,
324+ ]));
325+
326+ // US (en_US): comma as thousands, period as decimal
327+ $ result = $ fieldtype ->process ('9,876,543.21 ' );
328+
329+ $ this ->assertIsFloat ($ result );
330+ $ this ->assertEquals (9876543.21 , $ result );
331+ }
332+
333+ #[Test]
334+ public function it_handles_uk_format ()
335+ {
336+ $ fieldtype = (new Range ())->setField (new Field ('test ' , [
337+ 'type ' => 'range ' ,
338+ 'min ' => 0 ,
339+ 'max ' => 100000 ,
340+ 'step ' => 0.01 ,
341+ ]));
342+
343+ // UK (en_GB): comma as thousands, period as decimal
344+ $ result = $ fieldtype ->process ('54,321.98 ' );
345+
346+ $ this ->assertIsFloat ($ result );
347+ $ this ->assertEquals (54321.98 , $ result );
348+ }
349+
350+ #[Test]
351+ public function it_handles_simple_decimal_without_thousands ()
352+ {
353+ $ fieldtype = (new Range ())->setField (new Field ('test ' , [
354+ 'type ' => 'range ' ,
355+ 'min ' => 0 ,
356+ 'max ' => 1000 ,
357+ 'step ' => 0.01 ,
358+ ]));
359+
360+ // Simple decimal without thousands separator
361+ $ result = $ fieldtype ->process ('123.45 ' );
362+
363+ $ this ->assertIsFloat ($ result );
364+ $ this ->assertEquals (123.45 , $ result );
365+ }
366+
367+ #[Test]
368+ public function it_handles_simple_comma_decimal_without_thousands ()
369+ {
370+ $ fieldtype = (new Range ())->setField (new Field ('test ' , [
371+ 'type ' => 'range ' ,
372+ 'min ' => 0 ,
373+ 'max ' => 1000 ,
374+ 'step ' => 0.01 ,
375+ ]));
376+
377+ // Simple comma decimal without thousands separator (European)
378+ $ result = $ fieldtype ->process ('789,12 ' );
379+
380+ $ this ->assertIsFloat ($ result );
381+ $ this ->assertEquals (789.12 , $ result );
382+ }
137383}
0 commit comments