Files
oleibman 2c8177a319 Eliminate Unneeded Separate Process Tests
The tests stay; they just no longer run in separate processes. I think that only 2 tests still require separate processes - Helper/SampleTest and Tcpdf/NoDieTest. Aside from a new internal method in IOFactory, all the changes here are to test members.
2025-12-07 23:15:01 -08:00

208 lines
9.0 KiB
PHP

<?php
declare(strict_types=1);
namespace PhpOffice\PhpSpreadsheetTests\Style\NumberFormat\Wizard;
use NumberFormatter;
use PhpOffice\PhpSpreadsheet\Exception;
use PhpOffice\PhpSpreadsheet\Shared\StringHelper;
use PhpOffice\PhpSpreadsheet\Style\NumberFormat\Formatter;
use PhpOffice\PhpSpreadsheet\Style\NumberFormat\Wizard\Accounting;
use PhpOffice\PhpSpreadsheet\Style\NumberFormat\Wizard\Currency;
use PhpOffice\PhpSpreadsheet\Style\NumberFormat\Wizard\CurrencyNegative;
use PhpOffice\PhpSpreadsheet\Style\NumberFormat\Wizard\Number;
use PHPUnit\Framework\Attributes\DataProvider;
use PHPUnit\Framework\TestCase;
use ReflectionMethod;
class CurrencyTest extends TestCase
{
protected function tearDown(): void
{
StringHelper::setCurrencyCode(null);
StringHelper::setThousandsSeparator(null);
StringHelper::setDecimalSeparator(null);
}
#[DataProvider('providerCurrency')]
public function testCurrency(
string $expectedResultPositive,
string $expectedResultNegative,
string $expectedResultZero,
string $currencyCode,
int $decimals,
bool $thousandsSeparator,
bool $currencySymbolPosition,
bool $currencySymbolSpacing,
CurrencyNegative $negative = CurrencyNegative::minus
): void {
$wizard = new Currency($currencyCode, $decimals, $thousandsSeparator, $currencySymbolPosition, $currencySymbolSpacing, negative: $negative);
self::assertSame($expectedResultPositive, Formatter::toFormattedString(1234.56, $wizard->format()));
self::assertSame($expectedResultNegative, Formatter::toFormattedString(-1234.56, $wizard->format()));
self::assertSame($expectedResultZero, Formatter::toFormattedString(0, $wizard->format()));
}
public static function providerCurrency(): array
{
return [
[' $1235 ', ' -$1235', ' $0 ', '$', 0, Number::WITHOUT_THOUSANDS_SEPARATOR, Currency::LEADING_SYMBOL, Currency::SYMBOL_WITH_SPACING],
[' $1,235 ', ' -$1,235', ' $0 ', '$', 0, Number::WITH_THOUSANDS_SEPARATOR, Currency::LEADING_SYMBOL, Currency::SYMBOL_WITH_SPACING],
[' $1,235 ', ' -$1,235', ' $0 ', '$', 0, Number::WITH_THOUSANDS_SEPARATOR, Currency::LEADING_SYMBOL, Currency::SYMBOL_WITHOUT_SPACING],
[' 1234.56€ ', ' -1234.56€ ', ' 0.00€ ', '€', 2, Number::WITHOUT_THOUSANDS_SEPARATOR, Currency::TRAILING_SYMBOL, Currency::SYMBOL_WITH_SPACING],
[' 1,234.56€ ', ' -1,234.56€ ', ' 0.00€ ', '€', 2, Number::WITH_THOUSANDS_SEPARATOR, Currency::TRAILING_SYMBOL, Currency::SYMBOL_WITH_SPACING],
[' 1234.56€ ', ' -1234.56€ ', ' 0.00€ ', '€', 2, Number::WITHOUT_THOUSANDS_SEPARATOR, Currency::TRAILING_SYMBOL, Currency::SYMBOL_WITHOUT_SPACING],
[' 1234.56€ ', ' (1234.56)€ ', ' 0.00€ ', '€', 2, Number::WITHOUT_THOUSANDS_SEPARATOR, Currency::TRAILING_SYMBOL, Currency::SYMBOL_WITHOUT_SPACING, CurrencyNegative::parentheses],
[' 1234.56 GBP ', ' (1234.56) GBP ', ' 0.00GBP ', 'GBP', 2, Number::WITHOUT_THOUSANDS_SEPARATOR, Currency::TRAILING_SYMBOL, Currency::SYMBOL_WITHOUT_SPACING, CurrencyNegative::parentheses],
];
}
public function testSetNegative(): void
{
$expectedResultNegative = ' (1234.56)€ ';
$currencyCode = '€';
$decimals = 2;
$thousandsSeparator = Number::WITHOUT_THOUSANDS_SEPARATOR;
$currencySymbolPosition = Currency::TRAILING_SYMBOL;
$currencySymbolSpacing = Currency::SYMBOL_WITHOUT_SPACING;
$negative = CurrencyNegative::parentheses;
$wizard = new Currency($currencyCode, $decimals, $thousandsSeparator, $currencySymbolPosition, $currencySymbolSpacing);
$wizard->setNegative($negative);
self::assertSame($expectedResultNegative, Formatter::toFormattedString(-1234.56, $wizard->format()));
}
#[DataProvider('providerCurrencyLocale')]
public function testCurrencyLocale(
string $expectedResult,
string $currencyCode,
string $locale,
?bool $stripRLM = null
): void {
if (class_exists(NumberFormatter::class) === false) {
self::markTestSkipped('Intl extension is not available');
}
$wizard = new Currency($currencyCode);
if ($stripRLM !== null) {
$wizard->setStripLeadingRLM($stripRLM);
}
$wizard->setLocale($locale);
self::assertSame($expectedResult, (string) $wizard);
}
public static function providerCurrencyLocale(): array
{
// \u{a0} is non-breaking space
// \u{200e} is LRM (left-to-right mark)
return [
["[\$€-fy-NL]\u{a0}#,##0.00;[\$€-fy-NL]\u{a0}#,##0.00-", '€', 'fy-NL'], // Trailing negative
["[\$€-nl-NL]\u{a0}#,##0.00;[\$€-nl-NL]\u{a0}-#,##0.00", '€', 'nl-NL'], // Sign between currency and value
["[\$€-nl-BE]\u{a0}#,##0.00;[\$€-nl-BE]\u{a0}-#,##0.00", '€', 'NL-BE'], // Sign between currency and value
["#,##0.00\u{a0}[\$€-fr-BE]", '€', 'fr-be'], // Trailing currency code
["#,##0.00\u{a0}[\$€-el-GR]", '€', 'el-gr'], // Trailing currency code
['[$$-en-CA]#,##0.00', '$', 'en-ca'],
["#,##0.00\u{a0}[\$\$-fr-CA]", '$', 'fr-ca'], // Trailing currency code
['[$¥-ja-JP]#,##0', '¥', 'ja-JP'], // No decimals
["#,##0.000\u{a0}[\$د.ب\u{200e}-ar-BH]", "د.ب\u{200e}", 'ar-BH', true], // 3 decimals
];
}
public function testIcu721(): void
{
if (class_exists(NumberFormatter::class) === false) {
self::markTestSkipped('Intl extension is not available');
}
$currencyCode = "د.ب\u{200e}";
$locale = 'ar-BH';
$wizardFalse = new Currency($currencyCode);
$wizardFalse->setStripLeadingRLM(false);
$wizardFalse->setLocale($locale);
$stringFalse = (string) $wizardFalse;
$wizardTrue = new Currency($currencyCode);
$wizardTrue->setStripLeadingRLM(true);
$wizardTrue->setLocale($locale);
$stringTrue = (string) $wizardTrue;
$version = Accounting::icuVersion();
if ($version < 72.1) {
self::assertSame($stringFalse, $stringTrue);
} else {
self::assertSame("\u{200f}$stringTrue", $stringFalse);
}
}
#[DataProvider('providerCurrencyLocaleNoDecimals')]
public function testCurrencyLocaleNoDecimals(
string $expectedResult,
string $currencyCode,
string $locale,
?bool $stripRLM = null
): void {
if (class_exists(NumberFormatter::class) === false) {
self::markTestSkipped('Intl extension is not available');
}
$wizard = new Currency($currencyCode, 0);
if ($stripRLM !== null) {
$wizard->setStripLeadingRLM($stripRLM);
}
$wizard->setLocale($locale);
self::assertSame($expectedResult, (string) $wizard);
}
public static function providerCurrencyLocaleNoDecimals(): array
{
// \u{a0} is non-breaking space
// \u{200e} is LRM (left-to-right mark)
return [
["[\$€-fy-NL]\u{a0}#,##0;[\$€-fy-NL]\u{a0}#,##0-", '€', 'fy-NL'], // Trailing negative
["[\$€-nl-NL]\u{a0}#,##0;[\$€-nl-NL]\u{a0}-#,##0", '€', 'nl-NL'], // Sign between currency and value
["[\$€-nl-BE]\u{a0}#,##0;[\$€-nl-BE]\u{a0}-#,##0", '€', 'NL-BE'], // Sign between currency and value
["#,##0\u{a0}[\$€-fr-BE]", '€', 'fr-be'], // Trailing currency code
["#,##0\u{a0}[\$€-el-GR]", '€', 'el-gr'], // Trailing currency code
['[$$-en-CA]#,##0', '$', 'en-ca'],
["#,##0\u{a0}[\$\$-fr-CA]", '$', 'fr-ca'], // Trailing currency code
['[$¥-ja-JP]#,##0', '¥', 'ja-JP'], // No decimals to truncate
["#,##0\u{a0}[\$د.ب\u{200e}-ar-BH]", "د.ب\u{200e}", 'ar-BH', true], // 3 decimals truncated to none
];
}
public function testCurrencyLocaleInvalidFormat(): void
{
if (class_exists(NumberFormatter::class) === false) {
self::markTestSkipped('Intl extension is not available');
}
$locale = 'en-usa';
$this->expectException(Exception::class);
$this->expectExceptionMessage("Invalid locale code '{$locale}'");
$wizard = new Currency('€');
$wizard->setLocale($locale);
}
public function testCurrencyLocaleInvalidCode(): void
{
if (class_exists(NumberFormatter::class) === false) {
self::markTestSkipped('Intl extension is not available');
}
$locale = 'nl-GB';
$this->expectException(Exception::class);
$this->expectExceptionMessage("Unable to read locale data for '{$locale}'");
$wizard = new Currency('€');
$wizard->setLocale($locale);
}
public function testLocaleNull3(): void
{
$wizard = new Currency('$', 2);
$reflectionMethod = new ReflectionMethod($wizard, 'formatCurrencyCode');
$result = $reflectionMethod->invokeArgs($wizard, []);
self::assertSame('$', $result);
}
}