Failed Conditions
Push — develop ( e1eaf3...e2a320 )
by Remco
04:21
created

tests/src/MoneyTest.php (1 issue)

Labels
Severity
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
It seems like wp_json_encode($money) can also be of type false; however, parameter $actualJson of PHPUnit\Framework\Assert...tringEqualsJsonString() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

279
			/** @scrutinizer ignore-type */ \wp_json_encode( $money )
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