pronamic /
wp-money
| 1 | <?php |
||
| 2 | /** |
||
| 3 | * Money |
||
| 4 | * |
||
| 5 | * @author Pronamic <[email protected]> |
||
| 6 | * @copyright 2005-2021 Pronamic |
||
| 7 | * @license GPL-3.0-or-later |
||
| 8 | * @package Pronamic\WordPress\Money |
||
| 9 | */ |
||
| 10 | |||
| 11 | namespace Pronamic\WordPress\Money; |
||
| 12 | |||
| 13 | use WP_Locale; |
||
| 14 | use WP_UnitTestCase; |
||
| 15 | |||
| 16 | /** |
||
| 17 | * Money |
||
| 18 | * |
||
| 19 | * @author Remco Tolsma |
||
| 20 | * @version 1.2.2 |
||
| 21 | * @since 1.0.0 |
||
| 22 | */ |
||
| 23 | class MoneyTest extends WP_UnitTestCase { |
||
| 24 | /** |
||
| 25 | * Setup. |
||
| 26 | */ |
||
| 27 | public function setUp() { |
||
| 28 | parent::setUp(); |
||
| 29 | |||
| 30 | if ( version_compare( PHP_VERSION, '5.4', '<' ) ) { |
||
| 31 | add_filter( 'number_format_i18n', array( $this, 'maybe_fix_multibyte_number_format' ), 10, 3 ); |
||
| 32 | } |
||
| 33 | } |
||
| 34 | |||
| 35 | /** |
||
| 36 | * Maybe fix multibyte number format. |
||
| 37 | * |
||
| 38 | * @link https://github.com/WordPress/WordPress/blob/4.9.6/wp-includes/functions.php#L206-L237 |
||
| 39 | * |
||
| 40 | * @param string $formatted Formatted number. |
||
| 41 | * @param float $number The number to convert based on locale. |
||
| 42 | * @param int $decimals Optional. Precision of the number of decimal places. Default 0. |
||
| 43 | * |
||
| 44 | * @return string Converted number in string format. |
||
| 45 | * @global WP_Locale $wp_locale |
||
| 46 | */ |
||
| 47 | public function maybe_fix_multibyte_number_format( $formatted, $number, $decimals ) { |
||
| 48 | global $wp_locale; |
||
| 49 | |||
| 50 | if ( empty( $wp_locale ) ) { |
||
| 51 | return $formatted; |
||
| 52 | } |
||
| 53 | |||
| 54 | $dec_point = $wp_locale->number_format['decimal_point']; |
||
| 55 | $thousands_sep = $wp_locale->number_format['thousands_sep']; |
||
| 56 | |||
| 57 | if ( 1 === strlen( $dec_point ) && 1 === strlen( $thousands_sep ) ) { |
||
| 58 | return $formatted; |
||
| 59 | } |
||
| 60 | |||
| 61 | $formatted = number_format( $number, $decimals, 'd', 't' ); |
||
| 62 | |||
| 63 | $formatted = strtr( |
||
| 64 | $formatted, |
||
| 65 | array( |
||
| 66 | 'd' => $dec_point, |
||
| 67 | 't' => $thousands_sep, |
||
| 68 | ) |
||
| 69 | ); |
||
| 70 | |||
| 71 | return $formatted; |
||
| 72 | } |
||
| 73 | |||
| 74 | /** |
||
| 75 | * Test default format. |
||
| 76 | * |
||
| 77 | * @link https://github.com/WordPress/WordPress/blob/4.9.5/wp-includes/l10n.php |
||
| 78 | * |
||
| 79 | * @dataProvider default_format_provider |
||
| 80 | * |
||
| 81 | * @param string $locale Locale to test. |
||
| 82 | * @param string $expected Expected default format. |
||
| 83 | */ |
||
| 84 | public function test_default_format( $locale, $expected ) { |
||
| 85 | switch_to_locale( $locale ); |
||
| 86 | |||
| 87 | $value = Money::get_default_format(); |
||
| 88 | |||
| 89 | $this->assertEquals( $locale, get_locale() ); |
||
| 90 | $this->assertEquals( $expected, $value ); |
||
| 91 | } |
||
| 92 | |||
| 93 | /** |
||
| 94 | * Default format provider. |
||
| 95 | * |
||
| 96 | * @return array |
||
| 97 | */ |
||
| 98 | public function default_format_provider() { |
||
| 99 | return array( |
||
| 100 | array( 'en_US', '%1$s%2$s %3$s' ), |
||
| 101 | array( 'fr_FR', '%1$s%2$s %3$s' ), |
||
| 102 | array( 'nl_NL', '%1$s %2$s' ), |
||
| 103 | ); |
||
| 104 | } |
||
| 105 | |||
| 106 | /** |
||
| 107 | * Test format i18n. |
||
| 108 | * |
||
| 109 | * @link https://github.com/WordPress/WordPress/blob/4.9.5/wp-includes/l10n.php |
||
| 110 | * |
||
| 111 | * @param string $locale Locale. |
||
| 112 | * @param string $currency Money currency. |
||
| 113 | * @param float $value Money value. |
||
| 114 | * @param string $expected Expected format. |
||
| 115 | * |
||
| 116 | * @dataProvider format_i18n_provider |
||
| 117 | */ |
||
| 118 | public function test_format_i18n( $locale, $currency, $value, $expected ) { |
||
| 119 | switch_to_locale( $locale ); |
||
| 120 | |||
| 121 | $money = new Money( $value, $currency ); |
||
| 122 | |||
| 123 | $string = $money->format_i18n(); |
||
| 124 | |||
| 125 | $this->assertEquals( $locale, get_locale() ); |
||
| 126 | /* translators: 1: currency symbol, 2: amount value, 3: currency code, note: use non-breaking space! */ |
||
| 127 | $this->assertEquals( $expected, $string, 'Locale: ' . get_locale() . ' Money format: ' . Money::get_default_format() . ' Test: ' . _x( '%1$s%2$s %3$s', 'money format', 'pronamic-money' ) ); |
||
| 128 | } |
||
| 129 | |||
| 130 | /** |
||
| 131 | * Format i18n provider. |
||
| 132 | * |
||
| 133 | * @return array |
||
| 134 | */ |
||
| 135 | public function format_i18n_provider() { |
||
| 136 | return array( |
||
| 137 | // Dutch. |
||
| 138 | array( 'nl_NL', 'EUR', 49.7512, '€ 49,75' ), |
||
| 139 | array( 'nl_NL', 'NLG', 49.7512, 'G 49,7512' ), |
||
| 140 | array( 'nl_NL', 'USD', 49.7512, '$ 49,75' ), |
||
| 141 | array( 'nl_NL', 'USD', 1234567890.1234, '$ 1.234.567.890,12' ), |
||
| 142 | |||
| 143 | // English. |
||
| 144 | array( 'en_US', 'EUR', 49.7512, '€49.75 EUR' ), |
||
| 145 | array( 'en_US', 'USD', 1234567890.1234, '$1,234,567,890.12 USD' ), |
||
| 146 | |||
| 147 | // French. |
||
| 148 | array( 'fr_FR', 'USD', 1234567890.1234, '$1 234 567 890,12 USD' ), |
||
| 149 | ); |
||
| 150 | } |
||
| 151 | |||
| 152 | /** |
||
| 153 | * Test format i18n without trailing zeros. |
||
| 154 | * |
||
| 155 | * @link https://github.com/WordPress/WordPress/blob/4.9.5/wp-includes/l10n.php |
||
| 156 | * |
||
| 157 | * @param string $locale Locale. |
||
| 158 | * @param string $currency Money currency. |
||
| 159 | * @param float $value Money value. |
||
| 160 | * @param string $expected Expected format. |
||
| 161 | * |
||
| 162 | * @dataProvider format_i18n_non_trailing_zeros_provider |
||
| 163 | */ |
||
| 164 | public function test_format_i18n_non_trailing_zeros( $locale, $currency, $value, $expected ) { |
||
| 165 | switch_to_locale( $locale ); |
||
| 166 | |||
| 167 | $money = new Money( $value, $currency ); |
||
| 168 | |||
| 169 | $string = $money->format_i18n_non_trailing_zeros(); |
||
| 170 | |||
| 171 | $this->assertEquals( $locale, get_locale() ); |
||
| 172 | |||
| 173 | /* translators: 1: currency symbol, 2: amount value, 3: currency code, note: use non-breaking space! */ |
||
| 174 | $this->assertEquals( $expected, $string, 'Locale: ' . get_locale() . ' Money format: ' . Money::get_default_format() . ' Test: ' . _x( '%1$s%2$s %3$s', 'money format', 'pronamic-money' ) ); |
||
| 175 | } |
||
| 176 | |||
| 177 | /** |
||
| 178 | * Format i18n without trailing zeros provider. |
||
| 179 | * |
||
| 180 | * @return array |
||
| 181 | */ |
||
| 182 | public function format_i18n_non_trailing_zeros_provider() { |
||
| 183 | return array( |
||
| 184 | // Dutch. |
||
| 185 | array( 'nl_NL', 'EUR', 49.7512, '€ 49,75' ), |
||
| 186 | array( 'nl_NL', 'NLG', 49, 'G 49' ), |
||
| 187 | array( 'nl_NL', 'USD', 49.00, '$ 49' ), |
||
| 188 | array( 'nl_NL', 'USD', 1234567890.00, '$ 1.234.567.890' ), |
||
| 189 | |||
| 190 | // English. |
||
| 191 | array( 'en_US', 'EUR', 49.7512, '€49.75 EUR' ), |
||
| 192 | array( 'en_US', 'USD', 1234567890.00, '$1,234,567,890 USD' ), |
||
| 193 | |||
| 194 | // French. |
||
| 195 | array( 'fr_FR', 'USD', 1234567890, '$1 234 567 890 USD' ), |
||
| 196 | ); |
||
| 197 | } |
||
| 198 | |||
| 199 | /** |
||
| 200 | * Test minor units. |
||
| 201 | * |
||
| 202 | * @since 1.2.1 |
||
| 203 | * |
||
| 204 | * @dataProvider minor_units_provider |
||
| 205 | * |
||
| 206 | * @param string $currency Currency. |
||
| 207 | * @param int|float $value Money value to test. |
||
| 208 | * @param int $expected Expected value. |
||
| 209 | */ |
||
| 210 | public function test_minor_units( $currency, $value, $expected ) { |
||
| 211 | $money = new Money( $value, $currency ); |
||
| 212 | |||
| 213 | $this->assertSame( $expected, $money->get_minor_units()->to_int() ); |
||
| 214 | } |
||
| 215 | |||
| 216 | /** |
||
| 217 | * Minor units provider. |
||
| 218 | * |
||
| 219 | * @since 1.2.1 |
||
| 220 | * |
||
| 221 | * @return array |
||
| 222 | */ |
||
| 223 | public function minor_units_provider() { |
||
| 224 | return array( |
||
| 225 | // Value 10. |
||
| 226 | array( 'JPY', 10, 10 ), |
||
| 227 | array( 'EUR', 10, 1000 ), |
||
| 228 | array( 'BHD', 10, 10000 ), |
||
| 229 | array( 'NLG', 10, 100000 ), |
||
| 230 | |||
| 231 | // Value 100.65. |
||
| 232 | array( 'JPY', 100.65, 100 ), |
||
| 233 | array( 'EUR', 100.65, 10065 ), |
||
| 234 | array( 'BHD', 100.65, 100650 ), |
||
| 235 | array( 'NLG', 100.65, 1006500 ), |
||
| 236 | |||
| 237 | // Value 100.655. |
||
| 238 | array( 'JPY', 100.655, 100 ), |
||
| 239 | array( 'EUR', 100.655, 10065 ), |
||
| 240 | array( 'BHD', 100.655, 100655 ), |
||
| 241 | array( 'NLG', 100.655, 1006550 ), |
||
| 242 | |||
| 243 | // Value 0.00010. |
||
| 244 | array( 'JPY', 0.00010, 0 ), |
||
| 245 | array( 'EUR', 0.00010, 0 ), |
||
| 246 | array( 'BHD', 0.00010, 0 ), |
||
| 247 | array( 'NLG', 0.00010, 1 ), |
||
| 248 | ); |
||
| 249 | } |
||
| 250 | |||
| 251 | /** |
||
| 252 | * Test add. |
||
| 253 | * |
||
| 254 | * @since 1.3.0 |
||
| 255 | */ |
||
| 256 | public function test_add() { |
||
| 257 | $money_1 = new Money( 99.75, 'EUR' ); |
||
| 258 | |||
| 259 | $money_2 = new Money( 0.25, 'EUR' ); |
||
| 260 | |||
| 261 | $money_3 = $money_1->add( $money_2 ); |
||
| 262 | |||
| 263 | $this->assertEquals( 100, $money_3->get_value() ); |
||
| 264 | } |
||
| 265 | |||
| 266 | /** |
||
| 267 | * Test JSON. |
||
| 268 | */ |
||
| 269 | public function test_json() { |
||
| 270 | $money = new Money( 99.75, 'EUR' ); |
||
| 271 | |||
| 272 | $this->assertJsonStringEqualsJsonString( |
||
| 273 | ' |
||
| 274 | { |
||
| 275 | "value": "99.75", |
||
| 276 | "currency": "EUR" |
||
| 277 | } |
||
| 278 | ', |
||
| 279 | \wp_json_encode( $money ) |
||
|
0 ignored issues
–
show
Bug
introduced
by
Loading history...
|
|||
| 280 | ); |
||
| 281 | } |
||
| 282 | |||
| 283 | /** |
||
| 284 | * Test number format. |
||
| 285 | */ |
||
| 286 | public function test_number_format() { |
||
| 287 | $money = new Money( 12345678.90, 'EUR' ); |
||
| 288 | |||
| 289 | $this->assertSame( '12345678.90', $money->number_format( null, '.', '' ) ); |
||
| 290 | $this->assertSame( '12,345,678.90', $money->number_format( null, '.', ',' ) ); |
||
| 291 | $this->assertSame( '12345678.9', $money->number_format( 1, '.', '' ) ); |
||
| 292 | } |
||
| 293 | |||
| 294 | /** |
||
| 295 | * Test number format i18n. |
||
| 296 | */ |
||
| 297 | public function test_number_format_i18n() { |
||
| 298 | \switch_to_locale( 'en_US' ); |
||
| 299 | |||
| 300 | $money = new Money( 12345678.90, 'EUR' ); |
||
| 301 | |||
| 302 | $this->assertSame( '12,345,678.90', $money->number_format_i18n( null ) ); |
||
| 303 | $this->assertSame( '12,345,678.9', $money->number_format_i18n( 1 ) ); |
||
| 304 | } |
||
| 305 | |||
| 306 | /** |
||
| 307 | * Test multiply. |
||
| 308 | */ |
||
| 309 | public function test_multiply() { |
||
| 310 | $money = new Money( '123', 'EUR' ); |
||
| 311 | |||
| 312 | $money_2 = $money->multiply( 2 ); |
||
| 313 | |||
| 314 | $this->assertSame( '246.00', $money_2->number_format( null, '.', '' ) ); |
||
| 315 | } |
||
| 316 | |||
| 317 | /** |
||
| 318 | * Test divide. |
||
| 319 | */ |
||
| 320 | public function test_divide() { |
||
| 321 | $money = new Money( '246', 'EUR' ); |
||
| 322 | |||
| 323 | $money_2 = $money->divide( 2 ); |
||
| 324 | |||
| 325 | $this->assertSame( '123.00', $money_2->number_format( null, '.', '' ) ); |
||
| 326 | } |
||
| 327 | |||
| 328 | /** |
||
| 329 | * Test absolute. |
||
| 330 | */ |
||
| 331 | public function test_absolute() { |
||
| 332 | $money = new Money( '-123', 'EUR' ); |
||
| 333 | |||
| 334 | $this->assertSame( '-123.00', $money->number_format( null, '.', '' ) ); |
||
| 335 | |||
| 336 | $money_2 = $money->absolute(); |
||
| 337 | |||
| 338 | $this->assertSame( '123.00', $money_2->number_format( null, '.', '' ) ); |
||
| 339 | } |
||
| 340 | |||
| 341 | /** |
||
| 342 | * Test to string. |
||
| 343 | */ |
||
| 344 | public function test_to_string() { |
||
| 345 | $money = new Money( '-123', 'EUR' ); |
||
| 346 | |||
| 347 | $string = (string) $money; |
||
| 348 | |||
| 349 | $this->assertSame( 'EUR -123.00', $string ); |
||
| 350 | |||
| 351 | } |
||
| 352 | } |
||
| 353 |