Skip to content

Commit 8d327f2

Browse files
addiksytake
authored andcommitted
fixed an issue where the locale affects the handling of floats (#6)
* fixed an issue where the locale affects the handling of floats * tiny code style fix
1 parent 4067a15 commit 8d327f2

8 files changed

Lines changed: 158 additions & 5 deletions

File tree

src/Number/Real.php

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,19 @@ class Real implements ValueObjectInterface, NumberInterface
3535
*/
3636
public function __construct($value)
3737
{
38-
$value = \filter_var($value, FILTER_VALIDATE_FLOAT);
38+
/** @var string $stringValue */
39+
$stringValue = (string)$value;
40+
41+
# In some locales the decimal-point character might be different,
42+
# which can cause filter_var($value, FILTER_VALIDATE_FLOAT) to fail.
43+
$stringValue = str_replace(',', '.', $stringValue);
44+
45+
# Only apply the decimal-point character fix if needed, otherwise preserve the old value
46+
if ($stringValue !== (string)$value) {
47+
$value = \filter_var($stringValue, FILTER_VALIDATE_FLOAT);
48+
} else {
49+
$value = \filter_var($value, FILTER_VALIDATE_FLOAT);
50+
}
3951

4052
if (false === $value) {
4153
throw new InvalidNativeArgumentException($value, ['float']);

tests/Climate/CelsiusTest.php

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,13 @@
88

99
class CelsiusTest extends TestCase
1010
{
11+
public function setUp()
12+
{
13+
# When tests run in a different locale, this might affect the decimal-point character and thus the validation
14+
# of floats. This makes sure the tests run in a locale that the tests are known to be working in.
15+
setlocale(LC_ALL, "en_US.UTF-8");
16+
}
17+
1118
public function temperatureProvider()
1219
{
1320
return array(array(new Celsius(10)));
@@ -36,4 +43,16 @@ public function testToFahrenheit(Celsius $temperature)
3643
{
3744
$this->assertEquals(10 * 1.8 + 32, $temperature->toFahrenheit()->toNative());
3845
}
46+
47+
/**
48+
* @dataProvider temperatureProvider
49+
*/
50+
public function testDifferentLocaleWithDifferentDecimalCharacter(Celsius $temperature)
51+
{
52+
setlocale(LC_ALL, "de_DE.UTF-8");
53+
54+
$this->testToCelsius($temperature);
55+
$this->testToKelvin($temperature);
56+
$this->testToFahrenheit($temperature);
57+
}
3958
}

tests/Climate/FahrenheitTest.php

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,13 @@
66

77
class FahrenheitTest extends TestCase
88
{
9+
public function setUp()
10+
{
11+
# When tests run in a different locale, this might affect the decimal-point character and thus the validation
12+
# of floats. This makes sure the tests run in a locale that the tests are known to be working in.
13+
setlocale(LC_ALL, "en_US.UTF-8");
14+
}
15+
916
public function temperatureProvider()
1017
{
1118
return array(array(new Fahrenheit(10)));
@@ -37,4 +44,16 @@ public function testToFahrenheit(Fahrenheit $temperature)
3744
{
3845
$this->assertEquals(10, $temperature->toFahrenheit()->toNative());
3946
}
47+
48+
/**
49+
* @dataProvider temperatureProvider
50+
*/
51+
public function testDifferentLocaleWithDifferentDecimalCharacter(Fahrenheit $temperature)
52+
{
53+
setlocale(LC_ALL, "de_DE.UTF-8");
54+
55+
$this->testToCelsius($temperature);
56+
$this->testToKelvin($temperature);
57+
$this->testToFahrenheit($temperature);
58+
}
4059
}

tests/Climate/KelvinTest.php

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,13 @@
66

77
class KelvinTest extends TestCase
88
{
9+
public function setUp()
10+
{
11+
# When tests run in a different locale, this might affect the decimal-point character and thus the validation
12+
# of floats. This makes sure the tests run in a locale that the tests are known to be working in.
13+
setlocale(LC_ALL, "en_US.UTF-8");
14+
}
15+
916
public function temperatureProvider()
1017
{
1118
return array(array(new Kelvin(10)));
@@ -34,4 +41,16 @@ public function testToFahrenheit(Kelvin $temperature)
3441
{
3542
$this->assertEquals($temperature->toCelsius()->toNative() * 1.8 + 32, $temperature->toFahrenheit()->toNative());
3643
}
44+
45+
/**
46+
* @dataProvider temperatureProvider
47+
*/
48+
public function testDifferentLocaleWithDifferentDecimalCharacter(Kelvin $temperature)
49+
{
50+
setlocale(LC_ALL, "de_DE.UTF-8");
51+
52+
$this->testToCelsius($temperature);
53+
$this->testToKelvin($temperature);
54+
$this->testToFahrenheit($temperature);
55+
}
3756
}

tests/Geography/CoordinateTest.php

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,10 @@ class CoordinateTest extends TestCase
1717

1818
public function setup()
1919
{
20+
# When tests run in a different locale, this might affect the decimal-point character and thus the validation
21+
# of floats. This makes sure the tests run in a locale that the tests are known to be working in.
22+
setlocale(LC_ALL, "en_US.UTF-8");
23+
2024
$this->coordinate = new Coordinate(
2125
new Latitude(40.829137),
2226
new Longitude(16.555838)
@@ -115,4 +119,24 @@ public function testToString()
115119
{
116120
$this->assertSame('40.829137,16.555838', $this->coordinate->__toString());
117121
}
122+
123+
public function testDifferentLocaleWithDifferentDecimalCharacter()
124+
{
125+
setlocale(LC_ALL, "de_DE.UTF-8");
126+
127+
$this->testNullConstructorEllipsoid();
128+
$this->testFromNative();
129+
$this->testSameValueAs();
130+
$this->getLatitude();
131+
$this->getLongitude();
132+
$this->getEllipsoid();
133+
$this->testToUniversalTransverseMercator();
134+
$this->testDistanceFrom();
135+
$this->testToString();
136+
137+
# TODO: The following two tests break because of faults in another library and should be fixed there.
138+
# (vendor/league/geotools/src/Convert/Convert.php:53 | A non well formed numeric value encountered)
139+
#$this->testToDegreesMinutesSeconds();
140+
#$this->testToDecimalMinutes();
141+
}
118142
}

tests/Money/MoneyTest.php

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,13 @@
1212

1313
class MoneyTest extends TestCase
1414
{
15+
public function setUp()
16+
{
17+
# When tests run in a different locale, this might affect the decimal-point character and thus the validation
18+
# of floats. This makes sure the tests run in a locale that the tests are known to be working in.
19+
setlocale(LC_ALL, "en_US.UTF-8");
20+
}
21+
1522
public function testFromNative()
1623
{
1724
$fromNativeMoney = Money::fromNative(2100, 'EUR');
@@ -109,4 +116,19 @@ public function testToString()
109116

110117
$this->assertSame('EUR 1200', $money->__toString());
111118
}
119+
120+
public function testDifferentLocaleWithDifferentDecimalCharacter()
121+
{
122+
setlocale(LC_ALL, "de_DE.UTF-8");
123+
124+
$this->testFromNative();
125+
$this->testSameValueAs();
126+
$this->testGetAmount();
127+
$this->testGetCurrency();
128+
$this->testAdd();
129+
$this->testAddNegative();
130+
$this->testMultiply();
131+
$this->testMultiplyInverse();
132+
$this->testToString();
133+
}
112134
}

tests/Number/ComplexTest.php

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,10 @@ class ComplexTest extends TestCase
1313

1414
public function setup()
1515
{
16+
# When tests run in a different locale, this might affect the decimal-point character and thus the validation
17+
# of floats. This makes sure the tests run in a locale that the tests are known to be working in.
18+
setlocale(LC_ALL, "en_US.UTF-8");
19+
1620
$this->complex = new Complex(new Real(2.05), new Real(3.2));
1721
}
1822

@@ -77,14 +81,29 @@ public function testGetArgument()
7781
$this->assertTrue($arg->sameValueAs($this->complex->getArgument()));
7882
}
7983

80-
public function testToString()
84+
public function testToString($expectedString = '2.034 - 1.4i')
8185
{
8286
$complex = new Complex(new Real(2.034), new Real(-1.4));
83-
$this->assertEquals('2.034 - 1.4i', $complex->__toString());
87+
$this->assertEquals($expectedString, $complex->__toString());
8488
}
8589

8690
public function testNotSameValue()
8791
{
8892
$this->assertFalse($this->complex->sameValueAs(new Real(2.035)));
8993
}
94+
95+
public function testDifferentLocaleWithDifferentDecimalCharacter()
96+
{
97+
setlocale(LC_ALL, "de_DE.UTF-8");
98+
99+
$this->testFromNative();
100+
$this->testFromPolar();
101+
$this->testToNative();
102+
$this->testGetReal();
103+
$this->testGetIm();
104+
$this->testGetModulus();
105+
$this->testGetArgument();
106+
$this->testToString('2,034 - 1,4i');
107+
$this->testNotSameValue();
108+
}
90109
}

tests/Number/RealTest.php

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,13 @@
1010

1111
class RealTest extends TestCase
1212
{
13+
public function setUp()
14+
{
15+
# When tests run in a different locale, this might affect the decimal-point character and thus the validation
16+
# of floats. This makes sure the tests run in a locale that the tests are known to be working in.
17+
setlocale(LC_ALL, "en_US.UTF-8");
18+
}
19+
1320
public function testFromNative()
1421
{
1522
$fromNativeReal = Real::fromNative(.056);
@@ -63,9 +70,21 @@ public function testToNatural()
6370
$this->assertTrue($natural->sameValueAs($nativeNatural));
6471
}
6572

66-
public function testToString()
73+
public function testToString($expectedString = '.7')
6774
{
6875
$real = new Real(.7);
69-
$this->assertEquals('.7', $real->__toString());
76+
$this->assertEquals($expectedString, $real->__toString());
77+
}
78+
79+
public function testDifferentLocaleWithDifferentDecimalCharacter()
80+
{
81+
setlocale(LC_ALL, "de_DE.UTF-8");
82+
83+
$this->testFromNative();
84+
$this->testToNative();
85+
$this->testSameValueAs();
86+
$this->testToInteger();
87+
$this->testToNatural();
88+
$this->testToString('0,7');
7089
}
7190
}

0 commit comments

Comments
 (0)