mirror of
https://github.com/firefly-iii/firefly-iii.git
synced 2025-10-15 16:57:09 +00:00
Compare commits
11 Commits
develop-20
...
develop-20
Author | SHA1 | Date | |
---|---|---|---|
|
56bac9fc97 | ||
|
b93cfc5de2 | ||
|
d41f5b1090 | ||
|
40322813c9 | ||
|
4a98927e32 | ||
|
193e529803 | ||
|
fbf20ef2c2 | ||
|
54de829c8a | ||
|
131b987561 | ||
|
dce6754c62 | ||
|
f4bca90080 |
12
.ci/php-cs-fixer/composer.lock
generated
12
.ci/php-cs-fixer/composer.lock
generated
@@ -406,16 +406,16 @@
|
||||
},
|
||||
{
|
||||
"name": "friendsofphp/php-cs-fixer",
|
||||
"version": "v3.69.1",
|
||||
"version": "v3.70.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer.git",
|
||||
"reference": "13b0c0eede38c11cd674b080f2b485d0f14ffa9f"
|
||||
"reference": "2ecd5aae0edc937f0d5aa4a22d1d705c6b2e084e"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/PHP-CS-Fixer/PHP-CS-Fixer/zipball/13b0c0eede38c11cd674b080f2b485d0f14ffa9f",
|
||||
"reference": "13b0c0eede38c11cd674b080f2b485d0f14ffa9f",
|
||||
"url": "https://api.github.com/repos/PHP-CS-Fixer/PHP-CS-Fixer/zipball/2ecd5aae0edc937f0d5aa4a22d1d705c6b2e084e",
|
||||
"reference": "2ecd5aae0edc937f0d5aa4a22d1d705c6b2e084e",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -497,7 +497,7 @@
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/issues",
|
||||
"source": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/tree/v3.69.1"
|
||||
"source": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/tree/v3.70.0"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@@ -505,7 +505,7 @@
|
||||
"type": "github"
|
||||
}
|
||||
],
|
||||
"time": "2025-02-18T23:57:43+00:00"
|
||||
"time": "2025-02-22T23:30:51+00:00"
|
||||
},
|
||||
{
|
||||
"name": "psr/container",
|
||||
|
8
.github/workflows/release.yml
vendored
8
.github/workflows/release.yml
vendored
@@ -225,7 +225,7 @@ jobs:
|
||||
sudo chown -R runner:docker output.txt
|
||||
echo "Weekly development release of Firefly III with the latest fixes, translations and features. Docker users can find this release under the \`develop\` tag." >> output.txt
|
||||
echo "" >> output.txt
|
||||
echo "This release was created on **$(date +'%Y-%m-%d')** and may contain unexpected bugs. Data loss is rare but is not impossible. The releases are signed, and you can verify them using the [Firefly III releases PGP key](https://docs.firefly-iii.org/explanation/more-information/signatures/)." >> output.txt
|
||||
echo "This release was created on **$(date +'%Y-%m-%d %H:%M')** and may contain unexpected bugs. Data loss is rare but is not impossible. The releases are signed, and you can verify them using the [Firefly III releases PGP key](https://docs.firefly-iii.org/explanation/more-information/signatures/)." >> output.txt
|
||||
echo "" >> output.txt
|
||||
echo "* Please read the installation instructions for [Docker](https://docs.firefly-iii.org/how-to/firefly-iii/installation/docker/), [Portainer](https://docs.firefly-iii.org/how-to/firefly-iii/installation/portainer/), [Kubernetes](https://docs.firefly-iii.org/how-to/firefly-iii/installation/kubernetes/) or [self-managed servers](https://docs.firefly-iii.org/how-to/firefly-iii/installation/self-managed/)" >> output.txt
|
||||
echo "* Or read the upgrade instructions for [Docker](https://docs.firefly-iii.org/how-to/firefly-iii/upgrade/docker/), [Kubernetes](https://docs.firefly-iii.org/how-to/firefly-iii/upgrade/kubernetes/) or [self-managed servers](https://docs.firefly-iii.org/how-to/firefly-iii/upgrade/self-managed/)" >> output.txt
|
||||
@@ -240,7 +240,7 @@ jobs:
|
||||
sudo chown -R runner:docker output.txt
|
||||
echo "Irregular BRANCH release of Firefly III. This release contains specific features or changes. Docker users can find this release under the \`$version\` tag." >> output.txt
|
||||
echo "" >> output.txt
|
||||
echo "This release was created on **$(date +'%Y-%m-%d')** and may contain unexpected bugs. Data loss is rare but is not impossible. The releases are signed, and you can verify them using the [Firefly III releases PGP key](https://docs.firefly-iii.org/explanation/more-information/signatures/)." >> output.txt
|
||||
echo "This release was created on **$(date +'%Y-%m-%d %H:%M')** and may contain unexpected bugs. Data loss is rare but is not impossible. The releases are signed, and you can verify them using the [Firefly III releases PGP key](https://docs.firefly-iii.org/explanation/more-information/signatures/)." >> output.txt
|
||||
echo "" >> output.txt
|
||||
echo "* Please read the installation instructions for [Docker](https://docs.firefly-iii.org/how-to/firefly-iii/installation/docker/), [Portainer](https://docs.firefly-iii.org/how-to/firefly-iii/installation/portainer/), [Kubernetes](https://docs.firefly-iii.org/how-to/firefly-iii/installation/kubernetes/) or [self-managed servers](https://docs.firefly-iii.org/how-to/firefly-iii/installation/self-managed/)" >> output.txt
|
||||
echo "* Or read the upgrade instructions for [Docker](https://docs.firefly-iii.org/how-to/firefly-iii/upgrade/docker/), [Kubernetes](https://docs.firefly-iii.org/how-to/firefly-iii/upgrade/kubernetes/) or [self-managed servers](https://docs.firefly-iii.org/how-to/firefly-iii/upgrade/self-managed/)" >> output.txt
|
||||
@@ -268,7 +268,7 @@ jobs:
|
||||
sudo chown -R runner:docker output.txt
|
||||
echo "Very early ALPHA release of Firefly III. This release contains specific features or changes. Docker users can find this release under the \`$version\` tag." >> output.txt
|
||||
echo '' >> output.txt
|
||||
echo "This release was created on **$(date +'%Y-%m-%d')** and may contain unexpected bugs. Data loss is rare but is not impossible. The releases are signed, and you can verify them using the [Firefly III releases PGP key](https://docs.firefly-iii.org/explanation/more-information/signatures/)." >> output.txt
|
||||
echo "This release was created on **$(date +'%Y-%m-%d %H:%M')** and may contain unexpected bugs. Data loss is rare but is not impossible. The releases are signed, and you can verify them using the [Firefly III releases PGP key](https://docs.firefly-iii.org/explanation/more-information/signatures/)." >> output.txt
|
||||
echo '' >> output.txt
|
||||
echo '### Instructions' >> output.txt
|
||||
echo '' >> output.txt
|
||||
@@ -286,7 +286,7 @@ jobs:
|
||||
sudo chown -R runner:docker output.txt
|
||||
echo "Very early BETA release of Firefly III. This release contains specific features or changes. Docker users can find this release under the \`$version\` tag." >> output.txt
|
||||
echo '' >> output.txt
|
||||
echo "This release was created on **$(date +'%Y-%m-%d')** and may contain unexpected bugs. Data loss is rare but is not impossible. The releases are signed, and you can verify them using the [Firefly III releases PGP key](https://docs.firefly-iii.org/explanation/more-information/signatures/)." >> output.txt
|
||||
echo "This release was created on **$(date +'%Y-%m-%d %H:%M')** and may contain unexpected bugs. Data loss is rare but is not impossible. The releases are signed, and you can verify them using the [Firefly III releases PGP key](https://docs.firefly-iii.org/explanation/more-information/signatures/)." >> output.txt
|
||||
echo '' >> output.txt
|
||||
echo '### Instructions' >> output.txt
|
||||
echo '' >> output.txt
|
||||
|
@@ -185,8 +185,8 @@ class BasicController extends Controller
|
||||
'currency_decimal_places' => $currency->decimal_places,
|
||||
'value_parsed' => app('amount')->formatAnything($currency, $sums[$currencyId] ?? '0', false),
|
||||
'local_icon' => 'balance-scale',
|
||||
'sub_title' => app('amount')->formatAnything($currency, $expenses[$currencyId] ?? '0', false).
|
||||
' + '.app('amount')->formatAnything($currency, $incomes[$currencyId] ?? '0', false),
|
||||
'sub_title' => app('amount')->formatAnything($currency, $expenses[$currencyId] ?? '0', false)
|
||||
.' + '.app('amount')->formatAnything($currency, $incomes[$currencyId] ?? '0', false),
|
||||
];
|
||||
$return[] = [
|
||||
'key' => sprintf('spent-in-%s', $currency->code),
|
||||
|
@@ -49,9 +49,9 @@ class DestroyRequest extends FormRequest
|
||||
*/
|
||||
public function rules(): array
|
||||
{
|
||||
$valid = 'budgets,bills,piggy_banks,rules,recurring,categories,tags,object_groups'.
|
||||
',accounts,asset_accounts,expense_accounts,revenue_accounts,liabilities,transactions,withdrawals,deposits,transfers'.
|
||||
',not_assets_liabilities';
|
||||
$valid = 'budgets,bills,piggy_banks,rules,recurring,categories,tags,object_groups'
|
||||
.',accounts,asset_accounts,expense_accounts,revenue_accounts,liabilities,transactions,withdrawals,deposits,transfers'
|
||||
.',not_assets_liabilities';
|
||||
|
||||
return [
|
||||
'objects' => sprintf('required|max:255|min:1|string|in:%s', $valid),
|
||||
|
@@ -48,8 +48,8 @@ class BillFactory
|
||||
{
|
||||
app('log')->debug(sprintf('Now in %s', __METHOD__), $data);
|
||||
$factory = app(TransactionCurrencyFactory::class);
|
||||
$currency = $factory->find((int) ($data['currency_id'] ?? null), (string) ($data['currency_code'] ?? null)) ??
|
||||
app('amount')->getNativeCurrencyByUserGroup($this->user->userGroup);
|
||||
$currency = $factory->find((int) ($data['currency_id'] ?? null), (string) ($data['currency_code'] ?? null))
|
||||
?? app('amount')->getNativeCurrencyByUserGroup($this->user->userGroup);
|
||||
|
||||
try {
|
||||
$skip = array_key_exists('skip', $data) ? $data['skip'] : 0;
|
||||
|
@@ -225,9 +225,10 @@ class ReconcileController extends Controller
|
||||
]
|
||||
);
|
||||
$submission = [
|
||||
'user' => auth()->user()->id,
|
||||
'group_title' => null,
|
||||
'transactions' => [
|
||||
'user' => auth()->user(),
|
||||
'user_group' => auth()->user()->userGroup,
|
||||
'group_title' => null,
|
||||
'transactions' => [
|
||||
[
|
||||
'user' => auth()->user(),
|
||||
'user_group' => auth()->user()->userGroup,
|
||||
|
@@ -141,8 +141,8 @@ class MassController extends Controller
|
||||
// reverse amounts
|
||||
foreach ($journals as $index => $journal) {
|
||||
$journals[$index]['amount'] = app('steam')->bcround(app('steam')->positive($journal['amount']), $journal['currency_decimal_places']);
|
||||
$journals[$index]['foreign_amount'] = null === $journal['foreign_amount'] ?
|
||||
null : app('steam')->positive($journal['foreign_amount']);
|
||||
$journals[$index]['foreign_amount'] = null === $journal['foreign_amount']
|
||||
? null : app('steam')->positive($journal['foreign_amount']);
|
||||
}
|
||||
|
||||
$this->rememberPreviousUrl('transactions.mass-edit.url');
|
||||
|
@@ -33,11 +33,11 @@ class TrustProxies extends Middleware
|
||||
{
|
||||
// After...
|
||||
protected $headers
|
||||
= Request::HEADER_X_FORWARDED_FOR |
|
||||
Request::HEADER_X_FORWARDED_HOST |
|
||||
Request::HEADER_X_FORWARDED_PORT |
|
||||
Request::HEADER_X_FORWARDED_PROTO |
|
||||
Request::HEADER_X_FORWARDED_AWS_ELB;
|
||||
= Request::HEADER_X_FORWARDED_FOR
|
||||
| Request::HEADER_X_FORWARDED_HOST
|
||||
| Request::HEADER_X_FORWARDED_PORT
|
||||
| Request::HEADER_X_FORWARDED_PROTO
|
||||
| Request::HEADER_X_FORWARDED_AWS_ELB;
|
||||
|
||||
/**
|
||||
* TrustProxies constructor.
|
||||
|
@@ -54,8 +54,8 @@ class BillUpdateService
|
||||
|
||||
if (array_key_exists('currency_id', $data) || array_key_exists('currency_code', $data)) {
|
||||
$factory = app(TransactionCurrencyFactory::class);
|
||||
$currency = $factory->find((int) ($data['currency_id'] ?? null), $data['currency_code'] ?? null) ??
|
||||
app('amount')->getNativeCurrencyByUserGroup($bill->user->userGroup);
|
||||
$currency = $factory->find((int) ($data['currency_id'] ?? null), $data['currency_code'] ?? null)
|
||||
?? app('amount')->getNativeCurrencyByUserGroup($bill->user->userGroup);
|
||||
|
||||
// enable the currency if it isn't.
|
||||
$currency->enabled = true;
|
||||
|
@@ -703,8 +703,8 @@ class JournalUpdateService
|
||||
// find currency in data array
|
||||
$newForeignId = $this->data['foreign_currency_id'] ?? null;
|
||||
$newForeignCode = $this->data['foreign_currency_code'] ?? null;
|
||||
$foreignCurrency = $this->currencyRepository->findCurrencyNull($newForeignId, $newForeignCode) ??
|
||||
$foreignCurrency;
|
||||
$foreignCurrency = $this->currencyRepository->findCurrencyNull($newForeignId, $newForeignCode)
|
||||
?? $foreignCurrency;
|
||||
|
||||
// not the same as normal currency
|
||||
if (null !== $foreignCurrency && $foreignCurrency->id === $this->transactionJournal->transaction_currency_id) {
|
||||
|
14
changelog.md
14
changelog.md
@@ -3,6 +3,20 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
This project adheres to [Semantic Versioning](http://semver.org/).
|
||||
|
||||
## 6.2.9 - 2025-02-22
|
||||
|
||||
### Fixed
|
||||
|
||||
- [Issue 9861](https://github.com/firefly-iii/firefly-iii/issues/9861) (lower piggy amount when full creates double audit log entry) reported by @4e868df3
|
||||
- [Issue 9862](https://github.com/firefly-iii/firefly-iii/issues/9862) (Can't retrieve all accounts with the same name via API) reported by @Toshik1978
|
||||
- [Issue 9863](https://github.com/firefly-iii/firefly-iii/issues/9863) (User preferences reset after restart) reported by @mico28
|
||||
- [Issue 9868](https://github.com/firefly-iii/firefly-iii/issues/9868) (API: `TransactionSplit` -> `transaction_journal_id` returns int, not String) reported by @dreautall
|
||||
- [Issue 9871](https://github.com/firefly-iii/firefly-iii/issues/9871) (include net worth is ignored in the API - from PICO developer) reported by @fate8383
|
||||
- [Issue 9882](https://github.com/firefly-iii/firefly-iii/issues/9882) (Reconciliation bug on Docker instance) reported by @benjaminteyssier
|
||||
- [Issue 9884](https://github.com/firefly-iii/firefly-iii/issues/9884) (Data import, currency #0 not found) reported by @ragnarkarlsson
|
||||
- [Issue 9885](https://github.com/firefly-iii/firefly-iii/issues/9885) (Invalid server configuration: missing required package) reported by @EricVanCaenenberghe
|
||||
- [Issue 9887](https://github.com/firefly-iii/firefly-iii/issues/9887) (Creating a Liability Account Throws TypeError in TransactionJournalFactory::setUser()) reported by @mikeashi
|
||||
|
||||
## 6.2.8 - 2025-02-22
|
||||
|
||||
### Fixed
|
||||
|
18
composer.lock
generated
18
composer.lock
generated
@@ -11135,16 +11135,16 @@
|
||||
},
|
||||
{
|
||||
"name": "phpmyadmin/sql-parser",
|
||||
"version": "5.10.3",
|
||||
"version": "5.11.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/phpmyadmin/sql-parser.git",
|
||||
"reference": "5346664973d10cf1abff20837fb1183f3c11a055"
|
||||
"reference": "07044bc8c13abd542756c3fd34dc66a5d6dee8e4"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/phpmyadmin/sql-parser/zipball/5346664973d10cf1abff20837fb1183f3c11a055",
|
||||
"reference": "5346664973d10cf1abff20837fb1183f3c11a055",
|
||||
"url": "https://api.github.com/repos/phpmyadmin/sql-parser/zipball/07044bc8c13abd542756c3fd34dc66a5d6dee8e4",
|
||||
"reference": "07044bc8c13abd542756c3fd34dc66a5d6dee8e4",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -11159,9 +11159,11 @@
|
||||
"phpbench/phpbench": "^1.1",
|
||||
"phpmyadmin/coding-standard": "^3.0",
|
||||
"phpmyadmin/motranslator": "^4.0 || ^5.0",
|
||||
"phpstan/extension-installer": "^1.1",
|
||||
"phpstan/phpstan": "^1.9.12",
|
||||
"phpstan/phpstan-phpunit": "^1.3.3",
|
||||
"phpstan/extension-installer": "^1.4",
|
||||
"phpstan/phpstan": "^1.12",
|
||||
"phpstan/phpstan-deprecation-rules": "^1.2",
|
||||
"phpstan/phpstan-phpunit": "^1.4",
|
||||
"phpstan/phpstan-strict-rules": "^1.6",
|
||||
"phpunit/phpunit": "^8.5 || ^9.6",
|
||||
"psalm/plugin-phpunit": "^0.16.1",
|
||||
"vimeo/psalm": "^4.11",
|
||||
@@ -11218,7 +11220,7 @@
|
||||
"type": "other"
|
||||
}
|
||||
],
|
||||
"time": "2025-01-19T04:14:02+00:00"
|
||||
"time": "2025-02-22T20:00:59+00:00"
|
||||
},
|
||||
{
|
||||
"name": "phpstan/extension-installer",
|
||||
|
@@ -81,7 +81,7 @@ return [
|
||||
'running_balance_column' => env('USE_RUNNING_BALANCE', false),
|
||||
// see cer.php for exchange rates feature flag.
|
||||
],
|
||||
'version' => 'develop/2025-02-22',
|
||||
'version' => 'develop/2025-02-24',
|
||||
'api_version' => '2.1.0', // field is no longer used.
|
||||
'db_version' => 25,
|
||||
|
||||
|
12
package-lock.json
generated
12
package-lock.json
generated
@@ -6491,18 +6491,18 @@
|
||||
}
|
||||
},
|
||||
"node_modules/get-intrinsic": {
|
||||
"version": "1.2.7",
|
||||
"resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.7.tgz",
|
||||
"integrity": "sha512-VW6Pxhsrk0KAOqs3WEd0klDiF/+V7gQOpAvY1jVU/LHmaD/kQO4523aiJuikX/QAKYiW6x8Jh+RJej1almdtCA==",
|
||||
"version": "1.3.0",
|
||||
"resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz",
|
||||
"integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"call-bind-apply-helpers": "^1.0.1",
|
||||
"call-bind-apply-helpers": "^1.0.2",
|
||||
"es-define-property": "^1.0.1",
|
||||
"es-errors": "^1.3.0",
|
||||
"es-object-atoms": "^1.0.0",
|
||||
"es-object-atoms": "^1.1.1",
|
||||
"function-bind": "^1.1.2",
|
||||
"get-proto": "^1.0.0",
|
||||
"get-proto": "^1.0.1",
|
||||
"gopd": "^1.2.0",
|
||||
"has-symbols": "^1.1.0",
|
||||
"hasown": "^2.0.2",
|
||||
|
@@ -1,8 +1,8 @@
|
||||
{
|
||||
"firefly": {
|
||||
"administrations_page_title": "Financial administrations",
|
||||
"administrations_index_menu": "Financial administrations",
|
||||
"temp_administrations_introduction": "Firefly III will soon get the ability to manage multiple financial administrations. Right now, you only have the one. You can set the title of this administration and its native currency. This replaces the previous setting where you would set your \"default currency\". This setting is now tied to the financial administration and can be different per administration.",
|
||||
"administrations_page_title": "\u8d22\u52a1\u7ba1\u7406",
|
||||
"administrations_index_menu": "\u8d22\u52a1\u7ba1\u7406",
|
||||
"temp_administrations_introduction": "Firefly III \u4e0d\u4e45\u5c06\u80fd\u591f\u7ba1\u7406\u591a\u4e2a\u8d22\u52a1\u7ba1\u7406\u3002 \u73b0\u5728\uff0c\u4f60\u53ea\u80fd\u6709\u4e00\u4e2a\u8d22\u52a1\u7ba1\u7406\u3002\u4f60\u53ef\u4ee5\u8bbe\u7f6e\u8fd9\u4e2a\u8d22\u52a1\u7ba1\u7406\u7684\u6807\u9898\u53ca\u5176\u5f53\u5730\u8d27\u5e01\u3002 \u8fd9\u5c06\u53d6\u4ee3\u60a8\u5148\u524d\u8bbe\u7f6e\u7684\u201c\u9ed8\u8ba4\u8d27\u5e01\u201d\u3002 \u8fd9\u79cd\u8bbe\u7f6e\u73b0\u5728\u4e0e\u8d22\u52a1\u7ba1\u7406\u6302\u94a9\uff0c\u6bcf\u4e2a\u7ba1\u7406\u53ef\u4ee5\u6709\u4e0d\u540c\u7684\u8bbe\u7f6e\u3002",
|
||||
"administration_currency_form_help": "It may take a long time for the page to load if you change the native currency because transaction may need to be converted to your (new) native currency.",
|
||||
"administrations_page_edit_sub_title_js": "Edit financial administration \"{title}\"",
|
||||
"table": "\u8868\u683c",
|
||||
@@ -19,7 +19,7 @@
|
||||
"split": "\u62c6\u5206",
|
||||
"single_split": "\u62c6\u5206",
|
||||
"not_enough_currencies": "Not enough currencies",
|
||||
"not_enough_currencies_enabled": "If you have just one currency enabled, there is no need to add exchange rates.",
|
||||
"not_enough_currencies_enabled": "\u5982\u679c\u60a8\u53ea\u542f\u7528\u4e86\u4e00\u79cd\u8d27\u5e01\uff0c\u5c31\u4e0d\u9700\u8981\u6dfb\u52a0\u6c47\u7387\u3002",
|
||||
"transaction_stored_link": "<a href=\"transactions\/show\/{ID}\">\u4ea4\u6613 #{ID} (\u201c{title}\u201d)<\/a> \u5df2\u4fdd\u5b58\u3002",
|
||||
"webhook_stored_link": "<a href=\"webhooks\/show\/{ID}\">\u63a8\u9001 #{ID} (\"{title}\")<\/a> \u5df2\u4fdd\u5b58.",
|
||||
"webhook_updated_link": "<a href=\"webhooks\/show\/{ID}\">\u63a8\u9001 #{ID}<\/a> (\"{title}\") \u5df2\u66f4\u65b0.",
|
||||
@@ -45,7 +45,7 @@
|
||||
"is_reconciled_fields_dropped": "Because this transaction is reconciled, you will not be able to update the accounts, nor the amount(s) unless you remove the reconciliation flag.",
|
||||
"tags": "\u6807\u7b7e",
|
||||
"no_budget": "(\u65e0\u9884\u7b97)",
|
||||
"no_bill": "(no subscription)",
|
||||
"no_bill": "(\u65e0\u8ba2\u9605)",
|
||||
"category": "\u5206\u7c7b",
|
||||
"attachments": "\u9644\u4ef6",
|
||||
"notes": "\u5907\u6ce8",
|
||||
@@ -146,8 +146,8 @@
|
||||
"header_exchange_rates_rates": "\u6c47\u7387",
|
||||
"header_exchange_rates_table": "Table with exchange rates",
|
||||
"help_rate_form": "On this day, how many {to} will you get for one {from}?",
|
||||
"add_new_rate": "Add a new exchange rate",
|
||||
"save_new_rate": "Save new rate"
|
||||
"add_new_rate": "\u6dfb\u52a0\u65b0\u6c47\u7387",
|
||||
"save_new_rate": "\u4fdd\u5b58\u65b0\u6c47\u7387"
|
||||
},
|
||||
"form": {
|
||||
"url": "\u7f51\u5740",
|
||||
@@ -182,6 +182,6 @@
|
||||
},
|
||||
"config": {
|
||||
"html_language": "zh-cn",
|
||||
"date_time_fns": "YYYY\u5e74M\u6708D\u65e5 HH:mm:ss"
|
||||
"date_time_fns": "yyyy\u5e74M\u6708d\u65e5 HH:mm:ss"
|
||||
}
|
||||
}
|
@@ -45,6 +45,17 @@ final class BillDateCalculatorTest extends TestCase
|
||||
$this->calculator = new BillDateCalculator();
|
||||
}
|
||||
|
||||
/**
|
||||
* Stupid long method names I'm not going to do that.
|
||||
*
|
||||
* @dataProvider provideDates
|
||||
*/
|
||||
public function testGivenSomeDataItWorks(Carbon $earliest, Carbon $latest, Carbon $billStart, string $period, int $skip, ?Carbon $lastPaid, array $expected): void
|
||||
{
|
||||
$result = $this->calculator->getPayDates($earliest, $latest, $billStart, $period, $skip, $lastPaid);
|
||||
self::assertSame($expected, $result);
|
||||
}
|
||||
|
||||
public static function provideDates(): iterable
|
||||
{
|
||||
// Carbon $earliest, Carbon $latest, Carbon $billStart, string $period, int $skip, ?Carbon $lastPaid
|
||||
@@ -66,15 +77,4 @@ final class BillDateCalculatorTest extends TestCase
|
||||
'1Ya' => ['earliest' => Carbon::parse('2023-11-01'), 'latest' => Carbon::parse('2023-11-30'), 'billStart' => Carbon::parse('2021-05-01'), 'period' => 'yearly', 'skip' => 0, 'lastPaid' => Carbon::parse('2023-05-02'), 'expected' => ['2024-05-01']],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Stupid long method names I'm not going to do that.
|
||||
*
|
||||
* @dataProvider provideDates
|
||||
*/
|
||||
public function testGivenSomeDataItWorks(Carbon $earliest, Carbon $latest, Carbon $billStart, string $period, int $skip, ?Carbon $lastPaid, array $expected): void
|
||||
{
|
||||
$result = $this->calculator->getPayDates($earliest, $latest, $billStart, $period, $skip, $lastPaid);
|
||||
self::assertSame($expected, $result);
|
||||
}
|
||||
}
|
||||
|
@@ -50,6 +50,32 @@ use Tests\unit\Support\Calendar\Periodicity\YearlyTest;
|
||||
*/
|
||||
final class CalculatorTest extends TestCase
|
||||
{
|
||||
private static function convert(Periodicity $periodicity, array $intervals): array
|
||||
{
|
||||
$periodicityIntervals = [];
|
||||
|
||||
/** @var IntervalProvider $interval */
|
||||
foreach ($intervals as $index => $interval) {
|
||||
$calculator = CalculatorProvider::from($periodicity, $interval);
|
||||
|
||||
$periodicityIntervals["#{$index} {$calculator->label}"] = [$calculator];
|
||||
}
|
||||
|
||||
return $periodicityIntervals;
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider provideAllPeriodicity
|
||||
*
|
||||
* @throws IntervalException
|
||||
*/
|
||||
public function testGivenADailyPeriodicityWhenCallTheNextDateByIntervalMethodThenReturnsTheExpectedDateSuccessful(CalculatorProvider $provider): void
|
||||
{
|
||||
$calculator = new Calculator();
|
||||
$period = $calculator->nextDateByInterval($provider->epoch(), $provider->periodicity);
|
||||
self::assertSame($provider->expected()->toDateString(), $period->toDateString());
|
||||
}
|
||||
|
||||
public static function provideAllPeriodicity(): iterable
|
||||
{
|
||||
$intervals = [];
|
||||
@@ -68,37 +94,6 @@ final class CalculatorTest extends TestCase
|
||||
}
|
||||
}
|
||||
|
||||
private static function convert(Periodicity $periodicity, array $intervals): array
|
||||
{
|
||||
$periodicityIntervals = [];
|
||||
|
||||
/** @var IntervalProvider $interval */
|
||||
foreach ($intervals as $index => $interval) {
|
||||
$calculator = CalculatorProvider::from($periodicity, $interval);
|
||||
|
||||
$periodicityIntervals["#{$index} {$calculator->label}"] = [$calculator];
|
||||
}
|
||||
|
||||
return $periodicityIntervals;
|
||||
}
|
||||
|
||||
public static function provideSkippedIntervals(): iterable
|
||||
{
|
||||
return CalculatorProvider::providePeriodicityWithSkippedIntervals();
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider provideAllPeriodicity
|
||||
*
|
||||
* @throws IntervalException
|
||||
*/
|
||||
public function testGivenADailyPeriodicityWhenCallTheNextDateByIntervalMethodThenReturnsTheExpectedDateSuccessful(CalculatorProvider $provider): void
|
||||
{
|
||||
$calculator = new Calculator();
|
||||
$period = $calculator->nextDateByInterval($provider->epoch(), $provider->periodicity);
|
||||
self::assertSame($provider->expected()->toDateString(), $period->toDateString());
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider provideSkippedIntervals
|
||||
*
|
||||
@@ -110,4 +105,9 @@ final class CalculatorTest extends TestCase
|
||||
$period = $calculator->nextDateByInterval($provider->epoch(), $provider->periodicity, $provider->skip);
|
||||
self::assertSame($provider->expected()->toDateString(), $period->toDateString());
|
||||
}
|
||||
|
||||
public static function provideSkippedIntervals(): iterable
|
||||
{
|
||||
return CalculatorProvider::providePeriodicityWithSkippedIntervals();
|
||||
}
|
||||
}
|
||||
|
@@ -29,16 +29,6 @@ use Tests\integration\TestCase;
|
||||
|
||||
abstract class IntervalTestCase extends TestCase
|
||||
{
|
||||
public static function provider(): iterable
|
||||
{
|
||||
$intervals = static::provideIntervals();
|
||||
|
||||
/** @var IntervalProvider $interval */
|
||||
foreach ($intervals as $interval) {
|
||||
yield "{$interval->label}" => [$interval];
|
||||
}
|
||||
}
|
||||
|
||||
abstract public static function provideIntervals(): array;
|
||||
|
||||
/**
|
||||
@@ -50,5 +40,15 @@ abstract class IntervalTestCase extends TestCase
|
||||
self::assertSame($provider->expected->toDateString(), $period->toDateString());
|
||||
}
|
||||
|
||||
public static function provider(): iterable
|
||||
{
|
||||
$intervals = static::provideIntervals();
|
||||
|
||||
/** @var IntervalProvider $interval */
|
||||
foreach ($intervals as $interval) {
|
||||
yield "{$interval->label}" => [$interval];
|
||||
}
|
||||
}
|
||||
|
||||
abstract public static function factory(): Interval;
|
||||
}
|
||||
|
@@ -48,74 +48,13 @@ final class NavigationAddPeriodTest extends TestCase
|
||||
$this->navigation = new Navigation();
|
||||
}
|
||||
|
||||
public static function provideFrequencies(): iterable
|
||||
/**
|
||||
* @dataProvider providePeriodsWithSkippingParam
|
||||
*/
|
||||
public function testGivenAFrequencyAndSkipIntervalWhenCalculateTheDateThenReturnsTheSkippedDateSuccessful(int $skip, string $frequency, Carbon $from, Carbon $expected): void
|
||||
{
|
||||
return [
|
||||
Periodicity::Daily->name => ['periodicity' => Periodicity::Daily, 'from' => Carbon::now(), 'expected' => Carbon::tomorrow()],
|
||||
Periodicity::Weekly->name => ['periodicity' => Periodicity::Weekly, 'from' => Carbon::now(), 'expected' => Carbon::now()->addWeeks(1)],
|
||||
Periodicity::Fortnightly->name => ['periodicity' => Periodicity::Fortnightly, 'from' => Carbon::now(), 'expected' => Carbon::now()->addWeeks(2)],
|
||||
Periodicity::Monthly->name => ['periodicity' => Periodicity::Monthly, 'from' => Carbon::now(), 'expected' => Carbon::now()->addMonthsNoOverflow(1)],
|
||||
'2019-01-01 to 2019-02-01' => ['periodicity' => Periodicity::Monthly, 'from' => Carbon::parse('2019-01-01'), 'expected' => Carbon::parse('2019-02-01')],
|
||||
'2019-01-29 to 2019-02-28' => ['periodicity' => Periodicity::Monthly, 'from' => Carbon::parse('2019-01-29'), 'expected' => Carbon::parse('2019-02-28')],
|
||||
'2019-01-30 to 2019-02-28' => ['periodicity' => Periodicity::Monthly, 'from' => Carbon::parse('2019-01-30'), 'expected' => Carbon::parse('2019-02-28')],
|
||||
'2019-01-31 to 2019-02-28' => ['periodicity' => Periodicity::Monthly, 'from' => Carbon::parse('2019-01-31'), 'expected' => Carbon::parse('2019-02-28')],
|
||||
'2023-03-31 to 2023-04-30' => ['periodicity' => Periodicity::Monthly, 'from' => Carbon::parse('2023-03-31'), 'expected' => Carbon::parse('2023-04-30')],
|
||||
'2023-05-31 to 2023-06-30' => ['periodicity' => Periodicity::Monthly, 'from' => Carbon::parse('2023-05-31'), 'expected' => Carbon::parse('2023-06-30')],
|
||||
'2023-08-31 to 2023-09-30' => ['periodicity' => Periodicity::Monthly, 'from' => Carbon::parse('2023-08-31'), 'expected' => Carbon::parse('2023-09-30')],
|
||||
'2023-10-31 to 2023-11-30' => ['periodicity' => Periodicity::Monthly, 'from' => Carbon::parse('2023-10-31'), 'expected' => Carbon::parse('2023-11-30')],
|
||||
Periodicity::Quarterly->name => ['periodicity' => Periodicity::Quarterly, 'from' => Carbon::now(), 'expected' => Carbon::now()->addMonthsNoOverflow(3)],
|
||||
'2019-01-29 to 2020-04-29' => ['periodicity' => Periodicity::Quarterly, 'from' => Carbon::parse('2019-01-29'), 'expected' => Carbon::parse('2019-04-29')],
|
||||
'2019-01-30 to 2020-04-30' => ['periodicity' => Periodicity::Quarterly, 'from' => Carbon::parse('2019-01-30'), 'expected' => Carbon::parse('2019-04-30')],
|
||||
'2019-01-31 to 2020-04-30' => ['periodicity' => Periodicity::Quarterly, 'from' => Carbon::parse('2019-01-31'), 'expected' => Carbon::parse('2019-04-30')],
|
||||
Periodicity::HalfYearly->name => ['periodicity' => Periodicity::HalfYearly, 'from' => Carbon::now(), 'expected' => Carbon::now()->addMonthsNoOverflow(6)],
|
||||
'2019-01-31 to 2020-07-29' => ['periodicity' => Periodicity::HalfYearly, 'from' => Carbon::parse('2019-01-29'), 'expected' => Carbon::parse('2019-07-29')],
|
||||
'2019-01-31 to 2020-07-30' => ['periodicity' => Periodicity::HalfYearly, 'from' => Carbon::parse('2019-01-30'), 'expected' => Carbon::parse('2019-07-30')],
|
||||
'2019-01-31 to 2020-07-31' => ['periodicity' => Periodicity::HalfYearly, 'from' => Carbon::parse('2019-01-31'), 'expected' => Carbon::parse('2019-07-31')],
|
||||
Periodicity::Yearly->name => ['periodicity' => Periodicity::Yearly, 'from' => Carbon::now(), 'expected' => Carbon::now()->addYears(1)],
|
||||
'2020-02-29 to 2021-02-28' => ['periodicity' => Periodicity::Yearly, 'from' => Carbon::parse('2020-02-29'), 'expected' => Carbon::parse('2021-02-28')],
|
||||
];
|
||||
}
|
||||
|
||||
public static function provideMonthPeriods(): iterable
|
||||
{
|
||||
return [
|
||||
'1M' => ['frequency' => '1M', 'from' => Carbon::parse('2023-06-25'), 'expected' => Carbon::parse('2023-06-25')->addMonthsNoOverflow(1)],
|
||||
'month' => ['frequency' => 'month', 'from' => Carbon::parse('2023-06-25'), 'expected' => Carbon::parse('2023-06-25')->addMonthsNoOverflow(1)],
|
||||
'monthly' => ['frequency' => 'monthly', 'from' => Carbon::parse('2023-06-25'), 'expected' => Carbon::parse('2023-06-25')->addMonthsNoOverflow(1)],
|
||||
'2019-01-29 to 2019-02-28' => ['frequency' => 'monthly', 'from' => Carbon::parse('2019-01-29'), 'expected' => Carbon::parse('2019-02-28')],
|
||||
'2019-01-30 to 2019-02-28' => ['frequency' => 'monthly', 'from' => Carbon::parse('2019-01-30'), 'expected' => Carbon::parse('2019-02-28')],
|
||||
'2019-01-31 to 2019-02-28' => ['frequency' => 'monthly', 'from' => Carbon::parse('2019-01-31'), 'expected' => Carbon::parse('2019-02-28')],
|
||||
'2023-03-31 to 2023-04-30' => ['frequency' => 'monthly', 'from' => Carbon::parse('2023-03-31'), 'expected' => Carbon::parse('2023-04-30')],
|
||||
'2023-05-31 to 2023-06-30' => ['frequency' => 'monthly', 'from' => Carbon::parse('2023-05-31'), 'expected' => Carbon::parse('2023-06-30')],
|
||||
'2023-08-31 to 2023-09-30' => ['frequency' => 'monthly', 'from' => Carbon::parse('2023-08-31'), 'expected' => Carbon::parse('2023-09-30')],
|
||||
'2023-10-31 to 2023-11-30' => ['frequency' => 'monthly', 'from' => Carbon::parse('2023-10-31'), 'expected' => Carbon::parse('2023-11-30')],
|
||||
];
|
||||
}
|
||||
|
||||
public static function providePeriods(): iterable
|
||||
{
|
||||
return [
|
||||
'1D' => ['frequency' => '1D', 'from' => Carbon::now(), 'expected' => Carbon::tomorrow()],
|
||||
'daily' => ['frequency' => 'daily', 'from' => Carbon::now(), 'expected' => Carbon::tomorrow()],
|
||||
'1W' => ['frequency' => '1W', 'from' => Carbon::now(), 'expected' => Carbon::now()->addWeeks(1)],
|
||||
'weekly' => ['frequency' => 'weekly', 'from' => Carbon::now(), 'expected' => Carbon::now()->addWeeks(1)],
|
||||
'week' => ['frequency' => 'week', 'from' => Carbon::now(), 'expected' => Carbon::now()->addWeeks(1)],
|
||||
'3M' => ['frequency' => '3M', 'from' => Carbon::now(), 'expected' => Carbon::now()->addMonthsNoOverflow(3)],
|
||||
'quarter' => ['frequency' => 'quarter', 'from' => Carbon::now(), 'expected' => Carbon::now()->addMonthsNoOverflow(3)],
|
||||
'quarterly' => ['frequency' => 'quarterly', 'from' => Carbon::now(), 'expected' => Carbon::now()->addMonthsNoOverflow(3)],
|
||||
'6M' => ['frequency' => '6M', 'from' => Carbon::now(), 'expected' => Carbon::now()->addMonthsNoOverflow(6)],
|
||||
'half-year' => ['frequency' => 'half-year', 'from' => Carbon::now(), 'expected' => Carbon::now()->addMonthsNoOverflow(6)],
|
||||
'year' => ['frequency' => 'year', 'from' => Carbon::now(), 'expected' => Carbon::now()->addYears(1)],
|
||||
'yearly' => ['frequency' => 'yearly', 'from' => Carbon::now(), 'expected' => Carbon::now()->addYears(1)],
|
||||
'1Y' => ['frequency' => '1Y', 'from' => Carbon::now(), 'expected' => Carbon::now()->addYears(1)],
|
||||
'last7' => ['frequency' => 'last7', 'from' => Carbon::now(), 'expected' => Carbon::now()->addDays(7)],
|
||||
'last30' => ['frequency' => 'last30', 'from' => Carbon::now(), 'expected' => Carbon::now()->addMonthsNoOverflow(1)],
|
||||
'last90' => ['frequency' => 'last90', 'from' => Carbon::now(), 'expected' => Carbon::now()->addMonthsNoOverflow(3)],
|
||||
'last365' => ['frequency' => 'last365', 'from' => Carbon::now(), 'expected' => Carbon::now()->addYears(1)],
|
||||
'MTD' => ['frequency' => 'MTD', 'from' => Carbon::now(), 'expected' => Carbon::now()->addMonthsNoOverflow(1)],
|
||||
'QTD' => ['frequency' => 'QTD', 'from' => Carbon::now(), 'expected' => Carbon::now()->addMonthsNoOverflow(3)],
|
||||
'YTD' => ['frequency' => 'YTD', 'from' => Carbon::now(), 'expected' => Carbon::now()->addYears(1)],
|
||||
];
|
||||
$period = $this->navigation->addPeriod($from, $frequency, $skip);
|
||||
self::assertSame($expected->toDateString(), $period->toDateString());
|
||||
}
|
||||
|
||||
public static function providePeriodsWithSkippingParam(): iterable
|
||||
@@ -163,15 +102,6 @@ final class NavigationAddPeriodTest extends TestCase
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider providePeriodsWithSkippingParam
|
||||
*/
|
||||
public function testGivenAFrequencyAndSkipIntervalWhenCalculateTheDateThenReturnsTheSkippedDateSuccessful(int $skip, string $frequency, Carbon $from, Carbon $expected): void
|
||||
{
|
||||
$period = $this->navigation->addPeriod($from, $frequency, $skip);
|
||||
self::assertSame($expected->toDateString(), $period->toDateString());
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider providePeriods
|
||||
*/
|
||||
@@ -181,6 +111,32 @@ final class NavigationAddPeriodTest extends TestCase
|
||||
self::assertSame($expected->toDateString(), $period->toDateString());
|
||||
}
|
||||
|
||||
public static function providePeriods(): iterable
|
||||
{
|
||||
return [
|
||||
'1D' => ['frequency' => '1D', 'from' => Carbon::now(), 'expected' => Carbon::tomorrow()],
|
||||
'daily' => ['frequency' => 'daily', 'from' => Carbon::now(), 'expected' => Carbon::tomorrow()],
|
||||
'1W' => ['frequency' => '1W', 'from' => Carbon::now(), 'expected' => Carbon::now()->addWeeks(1)],
|
||||
'weekly' => ['frequency' => 'weekly', 'from' => Carbon::now(), 'expected' => Carbon::now()->addWeeks(1)],
|
||||
'week' => ['frequency' => 'week', 'from' => Carbon::now(), 'expected' => Carbon::now()->addWeeks(1)],
|
||||
'3M' => ['frequency' => '3M', 'from' => Carbon::now(), 'expected' => Carbon::now()->addMonthsNoOverflow(3)],
|
||||
'quarter' => ['frequency' => 'quarter', 'from' => Carbon::now(), 'expected' => Carbon::now()->addMonthsNoOverflow(3)],
|
||||
'quarterly' => ['frequency' => 'quarterly', 'from' => Carbon::now(), 'expected' => Carbon::now()->addMonthsNoOverflow(3)],
|
||||
'6M' => ['frequency' => '6M', 'from' => Carbon::now(), 'expected' => Carbon::now()->addMonthsNoOverflow(6)],
|
||||
'half-year' => ['frequency' => 'half-year', 'from' => Carbon::now(), 'expected' => Carbon::now()->addMonthsNoOverflow(6)],
|
||||
'year' => ['frequency' => 'year', 'from' => Carbon::now(), 'expected' => Carbon::now()->addYears(1)],
|
||||
'yearly' => ['frequency' => 'yearly', 'from' => Carbon::now(), 'expected' => Carbon::now()->addYears(1)],
|
||||
'1Y' => ['frequency' => '1Y', 'from' => Carbon::now(), 'expected' => Carbon::now()->addYears(1)],
|
||||
'last7' => ['frequency' => 'last7', 'from' => Carbon::now(), 'expected' => Carbon::now()->addDays(7)],
|
||||
'last30' => ['frequency' => 'last30', 'from' => Carbon::now(), 'expected' => Carbon::now()->addMonthsNoOverflow(1)],
|
||||
'last90' => ['frequency' => 'last90', 'from' => Carbon::now(), 'expected' => Carbon::now()->addMonthsNoOverflow(3)],
|
||||
'last365' => ['frequency' => 'last365', 'from' => Carbon::now(), 'expected' => Carbon::now()->addYears(1)],
|
||||
'MTD' => ['frequency' => 'MTD', 'from' => Carbon::now(), 'expected' => Carbon::now()->addMonthsNoOverflow(1)],
|
||||
'QTD' => ['frequency' => 'QTD', 'from' => Carbon::now(), 'expected' => Carbon::now()->addMonthsNoOverflow(3)],
|
||||
'YTD' => ['frequency' => 'YTD', 'from' => Carbon::now(), 'expected' => Carbon::now()->addYears(1)],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider provideFrequencies
|
||||
*/
|
||||
@@ -190,6 +146,34 @@ final class NavigationAddPeriodTest extends TestCase
|
||||
self::assertSame($expected->toDateString(), $period->toDateString());
|
||||
}
|
||||
|
||||
public static function provideFrequencies(): iterable
|
||||
{
|
||||
return [
|
||||
Periodicity::Daily->name => ['periodicity' => Periodicity::Daily, 'from' => Carbon::now(), 'expected' => Carbon::tomorrow()],
|
||||
Periodicity::Weekly->name => ['periodicity' => Periodicity::Weekly, 'from' => Carbon::now(), 'expected' => Carbon::now()->addWeeks(1)],
|
||||
Periodicity::Fortnightly->name => ['periodicity' => Periodicity::Fortnightly, 'from' => Carbon::now(), 'expected' => Carbon::now()->addWeeks(2)],
|
||||
Periodicity::Monthly->name => ['periodicity' => Periodicity::Monthly, 'from' => Carbon::now(), 'expected' => Carbon::now()->addMonthsNoOverflow(1)],
|
||||
'2019-01-01 to 2019-02-01' => ['periodicity' => Periodicity::Monthly, 'from' => Carbon::parse('2019-01-01'), 'expected' => Carbon::parse('2019-02-01')],
|
||||
'2019-01-29 to 2019-02-28' => ['periodicity' => Periodicity::Monthly, 'from' => Carbon::parse('2019-01-29'), 'expected' => Carbon::parse('2019-02-28')],
|
||||
'2019-01-30 to 2019-02-28' => ['periodicity' => Periodicity::Monthly, 'from' => Carbon::parse('2019-01-30'), 'expected' => Carbon::parse('2019-02-28')],
|
||||
'2019-01-31 to 2019-02-28' => ['periodicity' => Periodicity::Monthly, 'from' => Carbon::parse('2019-01-31'), 'expected' => Carbon::parse('2019-02-28')],
|
||||
'2023-03-31 to 2023-04-30' => ['periodicity' => Periodicity::Monthly, 'from' => Carbon::parse('2023-03-31'), 'expected' => Carbon::parse('2023-04-30')],
|
||||
'2023-05-31 to 2023-06-30' => ['periodicity' => Periodicity::Monthly, 'from' => Carbon::parse('2023-05-31'), 'expected' => Carbon::parse('2023-06-30')],
|
||||
'2023-08-31 to 2023-09-30' => ['periodicity' => Periodicity::Monthly, 'from' => Carbon::parse('2023-08-31'), 'expected' => Carbon::parse('2023-09-30')],
|
||||
'2023-10-31 to 2023-11-30' => ['periodicity' => Periodicity::Monthly, 'from' => Carbon::parse('2023-10-31'), 'expected' => Carbon::parse('2023-11-30')],
|
||||
Periodicity::Quarterly->name => ['periodicity' => Periodicity::Quarterly, 'from' => Carbon::now(), 'expected' => Carbon::now()->addMonthsNoOverflow(3)],
|
||||
'2019-01-29 to 2020-04-29' => ['periodicity' => Periodicity::Quarterly, 'from' => Carbon::parse('2019-01-29'), 'expected' => Carbon::parse('2019-04-29')],
|
||||
'2019-01-30 to 2020-04-30' => ['periodicity' => Periodicity::Quarterly, 'from' => Carbon::parse('2019-01-30'), 'expected' => Carbon::parse('2019-04-30')],
|
||||
'2019-01-31 to 2020-04-30' => ['periodicity' => Periodicity::Quarterly, 'from' => Carbon::parse('2019-01-31'), 'expected' => Carbon::parse('2019-04-30')],
|
||||
Periodicity::HalfYearly->name => ['periodicity' => Periodicity::HalfYearly, 'from' => Carbon::now(), 'expected' => Carbon::now()->addMonthsNoOverflow(6)],
|
||||
'2019-01-31 to 2020-07-29' => ['periodicity' => Periodicity::HalfYearly, 'from' => Carbon::parse('2019-01-29'), 'expected' => Carbon::parse('2019-07-29')],
|
||||
'2019-01-31 to 2020-07-30' => ['periodicity' => Periodicity::HalfYearly, 'from' => Carbon::parse('2019-01-30'), 'expected' => Carbon::parse('2019-07-30')],
|
||||
'2019-01-31 to 2020-07-31' => ['periodicity' => Periodicity::HalfYearly, 'from' => Carbon::parse('2019-01-31'), 'expected' => Carbon::parse('2019-07-31')],
|
||||
Periodicity::Yearly->name => ['periodicity' => Periodicity::Yearly, 'from' => Carbon::now(), 'expected' => Carbon::now()->addYears(1)],
|
||||
'2020-02-29 to 2021-02-28' => ['periodicity' => Periodicity::Yearly, 'from' => Carbon::parse('2020-02-29'), 'expected' => Carbon::parse('2021-02-28')],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider provideMonthPeriods
|
||||
*/
|
||||
@@ -198,4 +182,20 @@ final class NavigationAddPeriodTest extends TestCase
|
||||
$period = $this->navigation->addPeriod($from, $frequency, 0);
|
||||
self::assertSame($expected->toDateString(), $period->toDateString());
|
||||
}
|
||||
|
||||
public static function provideMonthPeriods(): iterable
|
||||
{
|
||||
return [
|
||||
'1M' => ['frequency' => '1M', 'from' => Carbon::parse('2023-06-25'), 'expected' => Carbon::parse('2023-06-25')->addMonthsNoOverflow(1)],
|
||||
'month' => ['frequency' => 'month', 'from' => Carbon::parse('2023-06-25'), 'expected' => Carbon::parse('2023-06-25')->addMonthsNoOverflow(1)],
|
||||
'monthly' => ['frequency' => 'monthly', 'from' => Carbon::parse('2023-06-25'), 'expected' => Carbon::parse('2023-06-25')->addMonthsNoOverflow(1)],
|
||||
'2019-01-29 to 2019-02-28' => ['frequency' => 'monthly', 'from' => Carbon::parse('2019-01-29'), 'expected' => Carbon::parse('2019-02-28')],
|
||||
'2019-01-30 to 2019-02-28' => ['frequency' => 'monthly', 'from' => Carbon::parse('2019-01-30'), 'expected' => Carbon::parse('2019-02-28')],
|
||||
'2019-01-31 to 2019-02-28' => ['frequency' => 'monthly', 'from' => Carbon::parse('2019-01-31'), 'expected' => Carbon::parse('2019-02-28')],
|
||||
'2023-03-31 to 2023-04-30' => ['frequency' => 'monthly', 'from' => Carbon::parse('2023-03-31'), 'expected' => Carbon::parse('2023-04-30')],
|
||||
'2023-05-31 to 2023-06-30' => ['frequency' => 'monthly', 'from' => Carbon::parse('2023-05-31'), 'expected' => Carbon::parse('2023-06-30')],
|
||||
'2023-08-31 to 2023-09-30' => ['frequency' => 'monthly', 'from' => Carbon::parse('2023-08-31'), 'expected' => Carbon::parse('2023-09-30')],
|
||||
'2023-10-31 to 2023-11-30' => ['frequency' => 'monthly', 'from' => Carbon::parse('2023-10-31'), 'expected' => Carbon::parse('2023-11-30')],
|
||||
];
|
||||
}
|
||||
}
|
||||
|
@@ -47,6 +47,15 @@ final class NavigationEndOfPeriodTest extends TestCase
|
||||
$this->navigation = new Navigation();
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider provideDates
|
||||
*/
|
||||
public function testGivenADateAndFrequencyWhenCalculateTheDateThenReturnsTheExpectedDateSuccessful(string $frequency, Carbon $from, Carbon $expected): void
|
||||
{
|
||||
$period = clone $this->navigation->endOfPeriod($from, $frequency);
|
||||
self::assertSame($expected->toDateString(), $period->toDateString());
|
||||
}
|
||||
|
||||
public static function provideDates(): iterable
|
||||
{
|
||||
return [
|
||||
@@ -78,24 +87,6 @@ final class NavigationEndOfPeriodTest extends TestCase
|
||||
];
|
||||
}
|
||||
|
||||
public static function provideUnknownFrequencies(): iterable
|
||||
{
|
||||
return [
|
||||
'1day' => ['frequency' => '1day', 'from' => Carbon::now(), 'expected' => Carbon::now()],
|
||||
'unknown' => ['frequency' => 'unknown', 'from' => Carbon::now(), 'expected' => Carbon::now()->startOfDay()],
|
||||
'empty' => ['frequency' => '', 'from' => Carbon::now(), 'expected' => Carbon::now()->startOfDay()],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider provideDates
|
||||
*/
|
||||
public function testGivenADateAndFrequencyWhenCalculateTheDateThenReturnsTheExpectedDateSuccessful(string $frequency, Carbon $from, Carbon $expected): void
|
||||
{
|
||||
$period = clone $this->navigation->endOfPeriod($from, $frequency);
|
||||
self::assertSame($expected->toDateString(), $period->toDateString());
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider provideUnknownFrequencies
|
||||
*/
|
||||
@@ -109,4 +100,13 @@ final class NavigationEndOfPeriodTest extends TestCase
|
||||
|
||||
Log::shouldHaveReceived('error', [$expectedMessage]);
|
||||
}
|
||||
|
||||
public static function provideUnknownFrequencies(): iterable
|
||||
{
|
||||
return [
|
||||
'1day' => ['frequency' => '1day', 'from' => Carbon::now(), 'expected' => Carbon::now()],
|
||||
'unknown' => ['frequency' => 'unknown', 'from' => Carbon::now(), 'expected' => Carbon::now()->startOfDay()],
|
||||
'empty' => ['frequency' => '', 'from' => Carbon::now(), 'expected' => Carbon::now()->startOfDay()],
|
||||
];
|
||||
}
|
||||
}
|
||||
|
@@ -46,6 +46,15 @@ final class NavigationPreferredCarbonFormatByPeriodTest extends TestCase
|
||||
$this->navigation = new Navigation();
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider providePeriods
|
||||
*/
|
||||
public function testGivenAPeriodWhenCallPreferredCarbonFormatByPeriodThenReturnsExpectedFormat(string $period, string $expected): void
|
||||
{
|
||||
$formatPeriod = $this->navigation->preferredCarbonFormatByPeriod($period);
|
||||
self::assertSame($expected, $formatPeriod);
|
||||
}
|
||||
|
||||
public static function providePeriods(): iterable
|
||||
{
|
||||
return [
|
||||
@@ -57,13 +66,4 @@ final class NavigationPreferredCarbonFormatByPeriodTest extends TestCase
|
||||
'yearly' => ['period' => '1Y', 'expected' => 'Y'],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider providePeriods
|
||||
*/
|
||||
public function testGivenAPeriodWhenCallPreferredCarbonFormatByPeriodThenReturnsExpectedFormat(string $period, string $expected): void
|
||||
{
|
||||
$formatPeriod = $this->navigation->preferredCarbonFormatByPeriod($period);
|
||||
self::assertSame($expected, $formatPeriod);
|
||||
}
|
||||
}
|
||||
|
@@ -47,6 +47,15 @@ final class NavigationPreferredCarbonFormatTest extends TestCase
|
||||
$this->navigation = new Navigation();
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider providePeriods
|
||||
*/
|
||||
public function testGivenStartAndEndDatesWhenCallPreferredCarbonFormatThenReturnsTheExpectedFormatSuccessful(Carbon $start, Carbon $end, string $expected): void
|
||||
{
|
||||
$carbonFormat = $this->navigation->preferredCarbonFormat($start, $end);
|
||||
self::assertSame($expected, $carbonFormat);
|
||||
}
|
||||
|
||||
public static function providePeriods(): iterable
|
||||
{
|
||||
return [
|
||||
@@ -64,13 +73,4 @@ final class NavigationPreferredCarbonFormatTest extends TestCase
|
||||
'2 years' => ['start' => Carbon::now(), 'end' => Carbon::now()->addYears(2), 'expected' => 'Y'],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider providePeriods
|
||||
*/
|
||||
public function testGivenStartAndEndDatesWhenCallPreferredCarbonFormatThenReturnsTheExpectedFormatSuccessful(Carbon $start, Carbon $end, string $expected): void
|
||||
{
|
||||
$carbonFormat = $this->navigation->preferredCarbonFormat($start, $end);
|
||||
self::assertSame($expected, $carbonFormat);
|
||||
}
|
||||
}
|
||||
|
@@ -47,6 +47,15 @@ final class NavigationPreferredEndOfPeriodTest extends TestCase
|
||||
$this->navigation = new Navigation();
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider providePeriods
|
||||
*/
|
||||
public function testGivenStartAndEndDatesWhenCallPreferredEndOfPeriodThenReturnsTheExpectedFormatSuccessful(Carbon $start, Carbon $end, string $expected): void
|
||||
{
|
||||
$formatPeriod = $this->navigation->preferredEndOfPeriod($start, $end);
|
||||
self::assertSame($expected, $formatPeriod);
|
||||
}
|
||||
|
||||
public static function providePeriods(): iterable
|
||||
{
|
||||
return [
|
||||
@@ -64,13 +73,4 @@ final class NavigationPreferredEndOfPeriodTest extends TestCase
|
||||
'2 years' => ['start' => Carbon::now(), 'end' => Carbon::now()->addYears(2), 'expected' => 'endOfYear'],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider providePeriods
|
||||
*/
|
||||
public function testGivenStartAndEndDatesWhenCallPreferredEndOfPeriodThenReturnsTheExpectedFormatSuccessful(Carbon $start, Carbon $end, string $expected): void
|
||||
{
|
||||
$formatPeriod = $this->navigation->preferredEndOfPeriod($start, $end);
|
||||
self::assertSame($expected, $formatPeriod);
|
||||
}
|
||||
}
|
||||
|
@@ -47,6 +47,15 @@ final class NavigationPreferredRangeFormatTest extends TestCase
|
||||
$this->navigation = new Navigation();
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider providePeriods
|
||||
*/
|
||||
public function testGivenStartAndEndDatesWhenCallPreferredRangeFormatThenReturnsTheExpectedFormatSuccessful(Carbon $start, Carbon $end, string $expected): void
|
||||
{
|
||||
$formatPeriod = $this->navigation->preferredRangeFormat($start, $end);
|
||||
self::assertSame($expected, $formatPeriod);
|
||||
}
|
||||
|
||||
public static function providePeriods(): iterable
|
||||
{
|
||||
return [
|
||||
@@ -64,13 +73,4 @@ final class NavigationPreferredRangeFormatTest extends TestCase
|
||||
'2 years' => ['start' => Carbon::now(), 'end' => Carbon::now()->addYears(2), 'expected' => '1Y'],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider providePeriods
|
||||
*/
|
||||
public function testGivenStartAndEndDatesWhenCallPreferredRangeFormatThenReturnsTheExpectedFormatSuccessful(Carbon $start, Carbon $end, string $expected): void
|
||||
{
|
||||
$formatPeriod = $this->navigation->preferredRangeFormat($start, $end);
|
||||
self::assertSame($expected, $formatPeriod);
|
||||
}
|
||||
}
|
||||
|
@@ -47,6 +47,15 @@ final class NavigationPreferredSqlFormatTest extends TestCase
|
||||
$this->navigation = new Navigation();
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider provideDates
|
||||
*/
|
||||
public function testGivenStartAndEndDatesWhenCallPreferredSqlFormatThenReturnsTheExpectedFormatSuccessful(Carbon $start, Carbon $end, string $expected): void
|
||||
{
|
||||
$formatPeriod = $this->navigation->preferredSqlFormat($start, $end);
|
||||
self::assertSame($expected, $formatPeriod);
|
||||
}
|
||||
|
||||
public static function provideDates(): iterable
|
||||
{
|
||||
return [
|
||||
@@ -64,13 +73,4 @@ final class NavigationPreferredSqlFormatTest extends TestCase
|
||||
'2 years' => ['start' => Carbon::now(), 'end' => Carbon::now()->addYears(2), 'expected' => '%Y'],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider provideDates
|
||||
*/
|
||||
public function testGivenStartAndEndDatesWhenCallPreferredSqlFormatThenReturnsTheExpectedFormatSuccessful(Carbon $start, Carbon $end, string $expected): void
|
||||
{
|
||||
$formatPeriod = $this->navigation->preferredSqlFormat($start, $end);
|
||||
self::assertSame($expected, $formatPeriod);
|
||||
}
|
||||
}
|
||||
|
@@ -48,6 +48,15 @@ final class NavigationStartOfPeriodTest extends TestCase
|
||||
$this->navigation = new Navigation();
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider provideDates
|
||||
*/
|
||||
public function testGivenADateAndFrequencyWhenCalculateTheDateThenReturnsTheExpectedDateSuccessful(string $frequency, Carbon $from, Carbon $expected): void
|
||||
{
|
||||
$period = $this->navigation->startOfPeriod($from, $frequency);
|
||||
self::assertSame($expected->toDateString(), $period->toDateString());
|
||||
}
|
||||
|
||||
public static function provideDates(): iterable
|
||||
{
|
||||
return [
|
||||
@@ -78,24 +87,6 @@ final class NavigationStartOfPeriodTest extends TestCase
|
||||
];
|
||||
}
|
||||
|
||||
public static function provideUnknownFrequencies(): iterable
|
||||
{
|
||||
return [
|
||||
'1day' => ['frequency' => '1day', 'from' => Carbon::now(), 'expected' => Carbon::now()],
|
||||
'unknown' => ['frequency' => 'unknown', 'from' => Carbon::now(), 'expected' => Carbon::now()->startOfDay()],
|
||||
'empty' => ['frequency' => '', 'from' => Carbon::now(), 'expected' => Carbon::now()->startOfDay()],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider provideDates
|
||||
*/
|
||||
public function testGivenADateAndFrequencyWhenCalculateTheDateThenReturnsTheExpectedDateSuccessful(string $frequency, Carbon $from, Carbon $expected): void
|
||||
{
|
||||
$period = $this->navigation->startOfPeriod($from, $frequency);
|
||||
self::assertSame($expected->toDateString(), $period->toDateString());
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider provideUnknownFrequencies
|
||||
*/
|
||||
@@ -111,4 +102,13 @@ final class NavigationStartOfPeriodTest extends TestCase
|
||||
$period = $this->navigation->startOfPeriod($from, $frequency);
|
||||
self::assertSame($expected->toDateString(), $period->toDateString());
|
||||
}
|
||||
|
||||
public static function provideUnknownFrequencies(): iterable
|
||||
{
|
||||
return [
|
||||
'1day' => ['frequency' => '1day', 'from' => Carbon::now(), 'expected' => Carbon::now()],
|
||||
'unknown' => ['frequency' => 'unknown', 'from' => Carbon::now(), 'expected' => Carbon::now()->startOfDay()],
|
||||
'empty' => ['frequency' => '', 'from' => Carbon::now(), 'expected' => Carbon::now()->startOfDay()],
|
||||
];
|
||||
}
|
||||
}
|
||||
|
@@ -15,6 +15,20 @@ abstract class AbstractQueryParserInterfaceParseQueryTester extends TestCase
|
||||
{
|
||||
abstract protected function createParser(): QueryParserInterface;
|
||||
|
||||
/**
|
||||
* @dataProvider queryDataProvider
|
||||
*
|
||||
* @param string $query The query string to parse
|
||||
* @param Node $expected The expected parse result
|
||||
*/
|
||||
public function testQueryParsing(string $query, Node $expected): void
|
||||
{
|
||||
$actual = $this->createParser()->parse($query);
|
||||
|
||||
self::assertObjectEquals($expected, $actual);
|
||||
|
||||
}
|
||||
|
||||
public static function queryDataProvider(): iterable
|
||||
{
|
||||
return [
|
||||
@@ -181,18 +195,4 @@ abstract class AbstractQueryParserInterfaceParseQueryTester extends TestCase
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider queryDataProvider
|
||||
*
|
||||
* @param string $query The query string to parse
|
||||
* @param Node $expected The expected parse result
|
||||
*/
|
||||
public function testQueryParsing(string $query, Node $expected): void
|
||||
{
|
||||
$actual = $this->createParser()->parse($query);
|
||||
|
||||
self::assertObjectEquals($expected, $actual);
|
||||
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user