From 91f8671384eda44e2a294c33b097ffa989b1964e Mon Sep 17 00:00:00 2001 From: Jake Barnby Date: Tue, 18 Jun 2024 12:35:14 +1200 Subject: [PATCH 01/24] Make tests Kotlin specific --- tests/Android14Java11Test.php | 36 ------------------- ...Test.php => Android14Java17KotlinTest.php} | 4 +-- ...8Test.php => Android14Java8KotlinTest.php} | 6 ++-- ...7Test.php => Android5Java17KotlinTest.php} | 2 +- 4 files changed, 5 insertions(+), 43 deletions(-) delete mode 100644 tests/Android14Java11Test.php rename tests/{Android14Java17Test.php => Android14Java17KotlinTest.php} (91%) rename tests/{Android14Java8Test.php => Android14Java8KotlinTest.php} (88%) rename tests/{Android5Java17Test.php => Android5Java17KotlinTest.php} (96%) diff --git a/tests/Android14Java11Test.php b/tests/Android14Java11Test.php deleted file mode 100644 index 4d3860788..000000000 --- a/tests/Android14Java11Test.php +++ /dev/null @@ -1,36 +0,0 @@ - Date: Tue, 18 Jun 2024 12:35:22 +1200 Subject: [PATCH 02/24] Add java specific test --- tests/Android14Java17JavaTest.php | 34 +++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) create mode 100644 tests/Android14Java17JavaTest.php diff --git a/tests/Android14Java17JavaTest.php b/tests/Android14Java17JavaTest.php new file mode 100644 index 000000000..c212bf3ad --- /dev/null +++ b/tests/Android14Java17JavaTest.php @@ -0,0 +1,34 @@ + Date: Tue, 18 Jun 2024 12:35:45 +1200 Subject: [PATCH 03/24] Update composer packages --- composer.json | 17 +- composer.lock | 1397 ++++++++++++------------------------------------- 2 files changed, 330 insertions(+), 1084 deletions(-) diff --git a/composer.json b/composer.json index f59602c73..0a8cef41f 100644 --- a/composer.json +++ b/composer.json @@ -3,14 +3,7 @@ "description": "Appwrite PHP library for generating API SDKs for multiple programming languages and platforms", "type": "library", "license": "MIT", - "minimum-stability": "dev", "prefer-stable": true, - "authors": [ - { - "name": "Eldad Fux", - "email": "eldad@appwrite.io" - } - ], "scripts": { "test": "vendor/bin/phpunit", "lint": "vendor/bin/phpcs", @@ -26,19 +19,17 @@ "psr-4": {"Tests\\": "tests"} }, "require": { - "php": ">=8.0", + "php": "8.*", "ext-curl": "*", "ext-mbstring": "*", "ext-json": "*", - "twig/twig": "v3.8.*", + "twig/twig": "v3.10.*", "matthiasmullie/minify": "1.3.*" }, "require-dev": { - "phpunit/phpunit": "10.5.*", - "brianium/paratest": "v7.4.*", - "squizlabs/php_codesniffer": "3.9.*" + "phpunit/phpunit": "11.*" }, "platform": { - "php": "8.2" + "php": "8.3" } } diff --git a/composer.lock b/composer.lock index ad6ab16c8..31b9175d0 100644 --- a/composer.lock +++ b/composer.lock @@ -4,20 +4,20 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "05fda1f077af4fd406e116aaa2c06314", + "content-hash": "74a969755862c5ec3e5e54ebfe166bc9", "packages": [ { "name": "matthiasmullie/minify", - "version": "1.3.71", + "version": "1.3.73", "source": { "type": "git", "url": "https://github.com/matthiasmullie/minify.git", - "reference": "ae42a47d7fecc1fbb7277b2f2d84c37a33edc3b1" + "reference": "cb7a9297b4ab070909cefade30ee95054d4ae87a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/matthiasmullie/minify/zipball/ae42a47d7fecc1fbb7277b2f2d84c37a33edc3b1", - "reference": "ae42a47d7fecc1fbb7277b2f2d84c37a33edc3b1", + "url": "https://api.github.com/repos/matthiasmullie/minify/zipball/cb7a9297b4ab070909cefade30ee95054d4ae87a", + "reference": "cb7a9297b4ab070909cefade30ee95054d4ae87a", "shasum": "" }, "require": { @@ -67,7 +67,7 @@ ], "support": { "issues": "https://github.com/matthiasmullie/minify/issues", - "source": "https://github.com/matthiasmullie/minify/tree/1.3.71" + "source": "https://github.com/matthiasmullie/minify/tree/1.3.73" }, "funding": [ { @@ -75,7 +75,7 @@ "type": "github" } ], - "time": "2023-04-25T20:33:03+00:00" + "time": "2024-03-15T10:27:10+00:00" }, { "name": "matthiasmullie/path-converter", @@ -130,6 +130,73 @@ }, "time": "2019-02-05T23:41:09+00:00" }, + { + "name": "symfony/deprecation-contracts", + "version": "v3.5.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/deprecation-contracts.git", + "reference": "0e0d29ce1f20deffb4ab1b016a7257c4f1e789a1" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/0e0d29ce1f20deffb4ab1b016a7257c4f1e789a1", + "reference": "0e0d29ce1f20deffb4ab1b016a7257c4f1e789a1", + "shasum": "" + }, + "require": { + "php": ">=8.1" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "3.5-dev" + }, + "thanks": { + "name": "symfony/contracts", + "url": "https://github.com/symfony/contracts" + } + }, + "autoload": { + "files": [ + "function.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "A generic function and convention to trigger deprecation notices", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/deprecation-contracts/tree/v3.5.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-04-18T09:32:20+00:00" + }, { "name": "symfony/polyfill-ctype", "version": "v1.29.0", @@ -371,30 +438,37 @@ }, { "name": "twig/twig", - "version": "v3.8.0", + "version": "v3.10.3", "source": { "type": "git", "url": "https://github.com/twigphp/Twig.git", - "reference": "9d15f0ac07f44dc4217883ec6ae02fd555c6f71d" + "reference": "67f29781ffafa520b0bbfbd8384674b42db04572" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/twigphp/Twig/zipball/9d15f0ac07f44dc4217883ec6ae02fd555c6f71d", - "reference": "9d15f0ac07f44dc4217883ec6ae02fd555c6f71d", + "url": "https://api.github.com/repos/twigphp/Twig/zipball/67f29781ffafa520b0bbfbd8384674b42db04572", + "reference": "67f29781ffafa520b0bbfbd8384674b42db04572", "shasum": "" }, "require": { "php": ">=7.2.5", + "symfony/deprecation-contracts": "^2.5|^3", "symfony/polyfill-ctype": "^1.8", "symfony/polyfill-mbstring": "^1.3", "symfony/polyfill-php80": "^1.22" }, "require-dev": { "psr/container": "^1.0|^2.0", - "symfony/phpunit-bridge": "^5.4.9|^6.3|^7.0" + "symfony/phpunit-bridge": "^5.4.9|^6.4|^7.0" }, "type": "library", "autoload": { + "files": [ + "src/Resources/core.php", + "src/Resources/debug.php", + "src/Resources/escaper.php", + "src/Resources/string_loader.php" + ], "psr-4": { "Twig\\": "src/" } @@ -427,7 +501,7 @@ ], "support": { "issues": "https://github.com/twigphp/Twig/issues", - "source": "https://github.com/twigphp/Twig/tree/v3.8.0" + "source": "https://github.com/twigphp/Twig/tree/v3.10.3" }, "funding": [ { @@ -439,236 +513,22 @@ "type": "tidelift" } ], - "time": "2023-11-21T18:54:41+00:00" + "time": "2024-05-16T10:04:27+00:00" } ], "packages-dev": [ - { - "name": "brianium/paratest", - "version": "v7.4.3", - "source": { - "type": "git", - "url": "https://github.com/paratestphp/paratest.git", - "reference": "64fcfd0e28a6b8078a19dbf9127be2ee645b92ec" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/paratestphp/paratest/zipball/64fcfd0e28a6b8078a19dbf9127be2ee645b92ec", - "reference": "64fcfd0e28a6b8078a19dbf9127be2ee645b92ec", - "shasum": "" - }, - "require": { - "ext-dom": "*", - "ext-pcre": "*", - "ext-reflection": "*", - "ext-simplexml": "*", - "fidry/cpu-core-counter": "^1.1.0", - "jean85/pretty-package-versions": "^2.0.5", - "php": "~8.2.0 || ~8.3.0", - "phpunit/php-code-coverage": "^10.1.11 || ^11.0.0", - "phpunit/php-file-iterator": "^4.1.0 || ^5.0.0", - "phpunit/php-timer": "^6.0.0 || ^7.0.0", - "phpunit/phpunit": "^10.5.9 || ^11.0.3", - "sebastian/environment": "^6.0.1 || ^7.0.0", - "symfony/console": "^6.4.3 || ^7.0.3", - "symfony/process": "^6.4.3 || ^7.0.3" - }, - "require-dev": { - "doctrine/coding-standard": "^12.0.0", - "ext-pcov": "*", - "ext-posix": "*", - "phpstan/phpstan": "^1.10.58", - "phpstan/phpstan-deprecation-rules": "^1.1.4", - "phpstan/phpstan-phpunit": "^1.3.15", - "phpstan/phpstan-strict-rules": "^1.5.2", - "squizlabs/php_codesniffer": "^3.9.0", - "symfony/filesystem": "^6.4.3 || ^7.0.3" - }, - "bin": [ - "bin/paratest", - "bin/paratest.bat", - "bin/paratest_for_phpstorm" - ], - "type": "library", - "autoload": { - "psr-4": { - "ParaTest\\": [ - "src/" - ] - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Brian Scaturro", - "email": "scaturrob@gmail.com", - "role": "Developer" - }, - { - "name": "Filippo Tessarotto", - "email": "zoeslam@gmail.com", - "role": "Developer" - } - ], - "description": "Parallel testing for PHP", - "homepage": "https://github.com/paratestphp/paratest", - "keywords": [ - "concurrent", - "parallel", - "phpunit", - "testing" - ], - "support": { - "issues": "https://github.com/paratestphp/paratest/issues", - "source": "https://github.com/paratestphp/paratest/tree/v7.4.3" - }, - "funding": [ - { - "url": "https://github.com/sponsors/Slamdunk", - "type": "github" - }, - { - "url": "https://paypal.me/filippotessarotto", - "type": "paypal" - } - ], - "time": "2024-02-20T07:24:02+00:00" - }, - { - "name": "fidry/cpu-core-counter", - "version": "1.1.0", - "source": { - "type": "git", - "url": "https://github.com/theofidry/cpu-core-counter.git", - "reference": "f92996c4d5c1a696a6a970e20f7c4216200fcc42" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/theofidry/cpu-core-counter/zipball/f92996c4d5c1a696a6a970e20f7c4216200fcc42", - "reference": "f92996c4d5c1a696a6a970e20f7c4216200fcc42", - "shasum": "" - }, - "require": { - "php": "^7.2 || ^8.0" - }, - "require-dev": { - "fidry/makefile": "^0.2.0", - "fidry/php-cs-fixer-config": "^1.1.2", - "phpstan/extension-installer": "^1.2.0", - "phpstan/phpstan": "^1.9.2", - "phpstan/phpstan-deprecation-rules": "^1.0.0", - "phpstan/phpstan-phpunit": "^1.2.2", - "phpstan/phpstan-strict-rules": "^1.4.4", - "phpunit/phpunit": "^8.5.31 || ^9.5.26", - "webmozarts/strict-phpunit": "^7.5" - }, - "type": "library", - "autoload": { - "psr-4": { - "Fidry\\CpuCoreCounter\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Théo FIDRY", - "email": "theo.fidry@gmail.com" - } - ], - "description": "Tiny utility to get the number of CPU cores.", - "keywords": [ - "CPU", - "core" - ], - "support": { - "issues": "https://github.com/theofidry/cpu-core-counter/issues", - "source": "https://github.com/theofidry/cpu-core-counter/tree/1.1.0" - }, - "funding": [ - { - "url": "https://github.com/theofidry", - "type": "github" - } - ], - "time": "2024-02-07T09:43:46+00:00" - }, - { - "name": "jean85/pretty-package-versions", - "version": "2.0.6", - "source": { - "type": "git", - "url": "https://github.com/Jean85/pretty-package-versions.git", - "reference": "f9fdd29ad8e6d024f52678b570e5593759b550b4" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/Jean85/pretty-package-versions/zipball/f9fdd29ad8e6d024f52678b570e5593759b550b4", - "reference": "f9fdd29ad8e6d024f52678b570e5593759b550b4", - "shasum": "" - }, - "require": { - "composer-runtime-api": "^2.0.0", - "php": "^7.1|^8.0" - }, - "require-dev": { - "friendsofphp/php-cs-fixer": "^3.2", - "jean85/composer-provided-replaced-stub-package": "^1.0", - "phpstan/phpstan": "^1.4", - "phpunit/phpunit": "^7.5|^8.5|^9.4", - "vimeo/psalm": "^4.3" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.x-dev" - } - }, - "autoload": { - "psr-4": { - "Jean85\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Alessandro Lai", - "email": "alessandro.lai85@gmail.com" - } - ], - "description": "A library to get pretty versions strings of installed dependencies", - "keywords": [ - "composer", - "package", - "release", - "versions" - ], - "support": { - "issues": "https://github.com/Jean85/pretty-package-versions/issues", - "source": "https://github.com/Jean85/pretty-package-versions/tree/2.0.6" - }, - "time": "2024-03-08T09:58:59+00:00" - }, { "name": "myclabs/deep-copy", - "version": "1.11.1", + "version": "1.12.0", "source": { "type": "git", "url": "https://github.com/myclabs/DeepCopy.git", - "reference": "7284c22080590fb39f2ffa3e9057f10a4ddd0e0c" + "reference": "3a6b9a42cd8f8771bd4295d13e1423fa7f3d942c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/7284c22080590fb39f2ffa3e9057f10a4ddd0e0c", - "reference": "7284c22080590fb39f2ffa3e9057f10a4ddd0e0c", + "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/3a6b9a42cd8f8771bd4295d13e1423fa7f3d942c", + "reference": "3a6b9a42cd8f8771bd4295d13e1423fa7f3d942c", "shasum": "" }, "require": { @@ -676,11 +536,12 @@ }, "conflict": { "doctrine/collections": "<1.6.8", - "doctrine/common": "<2.13.3 || >=3,<3.2.2" + "doctrine/common": "<2.13.3 || >=3 <3.2.2" }, "require-dev": { "doctrine/collections": "^1.6.8", "doctrine/common": "^2.13.3 || ^3.2.2", + "phpspec/prophecy": "^1.10", "phpunit/phpunit": "^7.5.20 || ^8.5.23 || ^9.5.13" }, "type": "library", @@ -706,7 +567,7 @@ ], "support": { "issues": "https://github.com/myclabs/DeepCopy/issues", - "source": "https://github.com/myclabs/DeepCopy/tree/1.11.1" + "source": "https://github.com/myclabs/DeepCopy/tree/1.12.0" }, "funding": [ { @@ -714,7 +575,7 @@ "type": "tidelift" } ], - "time": "2023-03-08T13:26:56+00:00" + "time": "2024-06-12T14:39:25+00:00" }, { "name": "nikic/php-parser", @@ -894,35 +755,35 @@ }, { "name": "phpunit/php-code-coverage", - "version": "10.1.13", + "version": "11.0.3", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-code-coverage.git", - "reference": "d51c3aec14896d5e80b354fad58e998d1980f8f8" + "reference": "7e35a2cbcabac0e6865fd373742ea432a3c34f92" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/d51c3aec14896d5e80b354fad58e998d1980f8f8", - "reference": "d51c3aec14896d5e80b354fad58e998d1980f8f8", + "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/7e35a2cbcabac0e6865fd373742ea432a3c34f92", + "reference": "7e35a2cbcabac0e6865fd373742ea432a3c34f92", "shasum": "" }, "require": { "ext-dom": "*", "ext-libxml": "*", "ext-xmlwriter": "*", - "nikic/php-parser": "^4.18 || ^5.0", - "php": ">=8.1", - "phpunit/php-file-iterator": "^4.0", - "phpunit/php-text-template": "^3.0", - "sebastian/code-unit-reverse-lookup": "^3.0", - "sebastian/complexity": "^3.0", - "sebastian/environment": "^6.0", - "sebastian/lines-of-code": "^2.0", - "sebastian/version": "^4.0", + "nikic/php-parser": "^5.0", + "php": ">=8.2", + "phpunit/php-file-iterator": "^5.0", + "phpunit/php-text-template": "^4.0", + "sebastian/code-unit-reverse-lookup": "^4.0", + "sebastian/complexity": "^4.0", + "sebastian/environment": "^7.0", + "sebastian/lines-of-code": "^3.0", + "sebastian/version": "^5.0", "theseer/tokenizer": "^1.2.0" }, "require-dev": { - "phpunit/phpunit": "^10.1" + "phpunit/phpunit": "^11.0" }, "suggest": { "ext-pcov": "PHP extension that provides line coverage", @@ -931,7 +792,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "10.1-dev" + "dev-main": "11.0-dev" } }, "autoload": { @@ -960,7 +821,7 @@ "support": { "issues": "https://github.com/sebastianbergmann/php-code-coverage/issues", "security": "https://github.com/sebastianbergmann/php-code-coverage/security/policy", - "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/10.1.13" + "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/11.0.3" }, "funding": [ { @@ -968,32 +829,32 @@ "type": "github" } ], - "time": "2024-03-09T16:54:15+00:00" + "time": "2024-03-12T15:35:40+00:00" }, { "name": "phpunit/php-file-iterator", - "version": "4.1.0", + "version": "5.0.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-file-iterator.git", - "reference": "a95037b6d9e608ba092da1b23931e537cadc3c3c" + "reference": "99e95c94ad9500daca992354fa09d7b99abe2210" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/a95037b6d9e608ba092da1b23931e537cadc3c3c", - "reference": "a95037b6d9e608ba092da1b23931e537cadc3c3c", + "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/99e95c94ad9500daca992354fa09d7b99abe2210", + "reference": "99e95c94ad9500daca992354fa09d7b99abe2210", "shasum": "" }, "require": { - "php": ">=8.1" + "php": ">=8.2" }, "require-dev": { - "phpunit/phpunit": "^10.0" + "phpunit/phpunit": "^11.0" }, "type": "library", "extra": { "branch-alias": { - "dev-main": "4.0-dev" + "dev-main": "5.0-dev" } }, "autoload": { @@ -1021,7 +882,7 @@ "support": { "issues": "https://github.com/sebastianbergmann/php-file-iterator/issues", "security": "https://github.com/sebastianbergmann/php-file-iterator/security/policy", - "source": "https://github.com/sebastianbergmann/php-file-iterator/tree/4.1.0" + "source": "https://github.com/sebastianbergmann/php-file-iterator/tree/5.0.0" }, "funding": [ { @@ -1029,28 +890,28 @@ "type": "github" } ], - "time": "2023-08-31T06:24:48+00:00" + "time": "2024-02-02T06:05:04+00:00" }, { "name": "phpunit/php-invoker", - "version": "4.0.0", + "version": "5.0.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-invoker.git", - "reference": "f5e568ba02fa5ba0ddd0f618391d5a9ea50b06d7" + "reference": "5d8d9355a16d8cc5a1305b0a85342cfa420612be" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-invoker/zipball/f5e568ba02fa5ba0ddd0f618391d5a9ea50b06d7", - "reference": "f5e568ba02fa5ba0ddd0f618391d5a9ea50b06d7", + "url": "https://api.github.com/repos/sebastianbergmann/php-invoker/zipball/5d8d9355a16d8cc5a1305b0a85342cfa420612be", + "reference": "5d8d9355a16d8cc5a1305b0a85342cfa420612be", "shasum": "" }, "require": { - "php": ">=8.1" + "php": ">=8.2" }, "require-dev": { "ext-pcntl": "*", - "phpunit/phpunit": "^10.0" + "phpunit/phpunit": "^11.0" }, "suggest": { "ext-pcntl": "*" @@ -1058,7 +919,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "4.0-dev" + "dev-main": "5.0-dev" } }, "autoload": { @@ -1084,7 +945,8 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/php-invoker/issues", - "source": "https://github.com/sebastianbergmann/php-invoker/tree/4.0.0" + "security": "https://github.com/sebastianbergmann/php-invoker/security/policy", + "source": "https://github.com/sebastianbergmann/php-invoker/tree/5.0.0" }, "funding": [ { @@ -1092,32 +954,32 @@ "type": "github" } ], - "time": "2023-02-03T06:56:09+00:00" + "time": "2024-02-02T06:05:50+00:00" }, { "name": "phpunit/php-text-template", - "version": "3.0.1", + "version": "4.0.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-text-template.git", - "reference": "0c7b06ff49e3d5072f057eb1fa59258bf287a748" + "reference": "d38f6cbff1cdb6f40b03c9811421561668cc133e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/0c7b06ff49e3d5072f057eb1fa59258bf287a748", - "reference": "0c7b06ff49e3d5072f057eb1fa59258bf287a748", + "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/d38f6cbff1cdb6f40b03c9811421561668cc133e", + "reference": "d38f6cbff1cdb6f40b03c9811421561668cc133e", "shasum": "" }, "require": { - "php": ">=8.1" + "php": ">=8.2" }, "require-dev": { - "phpunit/phpunit": "^10.0" + "phpunit/phpunit": "^11.0" }, "type": "library", "extra": { "branch-alias": { - "dev-main": "3.0-dev" + "dev-main": "4.0-dev" } }, "autoload": { @@ -1144,7 +1006,7 @@ "support": { "issues": "https://github.com/sebastianbergmann/php-text-template/issues", "security": "https://github.com/sebastianbergmann/php-text-template/security/policy", - "source": "https://github.com/sebastianbergmann/php-text-template/tree/3.0.1" + "source": "https://github.com/sebastianbergmann/php-text-template/tree/4.0.0" }, "funding": [ { @@ -1152,32 +1014,32 @@ "type": "github" } ], - "time": "2023-08-31T14:07:24+00:00" + "time": "2024-02-02T06:06:56+00:00" }, { "name": "phpunit/php-timer", - "version": "6.0.0", + "version": "7.0.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-timer.git", - "reference": "e2a2d67966e740530f4a3343fe2e030ffdc1161d" + "reference": "8a59d9e25720482ee7fcdf296595e08795b84dc5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/e2a2d67966e740530f4a3343fe2e030ffdc1161d", - "reference": "e2a2d67966e740530f4a3343fe2e030ffdc1161d", + "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/8a59d9e25720482ee7fcdf296595e08795b84dc5", + "reference": "8a59d9e25720482ee7fcdf296595e08795b84dc5", "shasum": "" }, "require": { - "php": ">=8.1" + "php": ">=8.2" }, "require-dev": { - "phpunit/phpunit": "^10.0" + "phpunit/phpunit": "^11.0" }, "type": "library", "extra": { "branch-alias": { - "dev-main": "6.0-dev" + "dev-main": "7.0-dev" } }, "autoload": { @@ -1203,7 +1065,8 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/php-timer/issues", - "source": "https://github.com/sebastianbergmann/php-timer/tree/6.0.0" + "security": "https://github.com/sebastianbergmann/php-timer/security/policy", + "source": "https://github.com/sebastianbergmann/php-timer/tree/7.0.0" }, "funding": [ { @@ -1211,20 +1074,20 @@ "type": "github" } ], - "time": "2023-02-03T06:57:52+00:00" + "time": "2024-02-02T06:08:01+00:00" }, { "name": "phpunit/phpunit", - "version": "10.5.12", + "version": "11.2.2", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/phpunit.git", - "reference": "41a9886b85ac7bf3929853baf96b95361cd69d2b" + "reference": "3e1843a58adc9c433ee6170bdee7d615f7ccc20b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/41a9886b85ac7bf3929853baf96b95361cd69d2b", - "reference": "41a9886b85ac7bf3929853baf96b95361cd69d2b", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/3e1843a58adc9c433ee6170bdee7d615f7ccc20b", + "reference": "3e1843a58adc9c433ee6170bdee7d615f7ccc20b", "shasum": "" }, "require": { @@ -1237,23 +1100,22 @@ "myclabs/deep-copy": "^1.10.1", "phar-io/manifest": "^2.0.3", "phar-io/version": "^3.0.2", - "php": ">=8.1", - "phpunit/php-code-coverage": "^10.1.5", - "phpunit/php-file-iterator": "^4.0", - "phpunit/php-invoker": "^4.0", - "phpunit/php-text-template": "^3.0", - "phpunit/php-timer": "^6.0", - "sebastian/cli-parser": "^2.0", - "sebastian/code-unit": "^2.0", - "sebastian/comparator": "^5.0", - "sebastian/diff": "^5.0", - "sebastian/environment": "^6.0", - "sebastian/exporter": "^5.1", - "sebastian/global-state": "^6.0.1", - "sebastian/object-enumerator": "^5.0", - "sebastian/recursion-context": "^5.0", - "sebastian/type": "^4.0", - "sebastian/version": "^4.0" + "php": ">=8.2", + "phpunit/php-code-coverage": "^11.0", + "phpunit/php-file-iterator": "^5.0", + "phpunit/php-invoker": "^5.0", + "phpunit/php-text-template": "^4.0", + "phpunit/php-timer": "^7.0", + "sebastian/cli-parser": "^3.0", + "sebastian/code-unit": "^3.0", + "sebastian/comparator": "^6.0", + "sebastian/diff": "^6.0", + "sebastian/environment": "^7.0", + "sebastian/exporter": "^6.0", + "sebastian/global-state": "^7.0", + "sebastian/object-enumerator": "^6.0", + "sebastian/type": "^5.0", + "sebastian/version": "^5.0" }, "suggest": { "ext-soap": "To be able to generate mocks based on WSDL files" @@ -1264,7 +1126,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "10.5-dev" + "dev-main": "11.2-dev" } }, "autoload": { @@ -1296,7 +1158,7 @@ "support": { "issues": "https://github.com/sebastianbergmann/phpunit/issues", "security": "https://github.com/sebastianbergmann/phpunit/security/policy", - "source": "https://github.com/sebastianbergmann/phpunit/tree/10.5.12" + "source": "https://github.com/sebastianbergmann/phpunit/tree/11.2.2" }, "funding": [ { @@ -1312,85 +1174,32 @@ "type": "tidelift" } ], - "time": "2024-03-09T12:04:07+00:00" - }, - { - "name": "psr/container", - "version": "2.0.2", - "source": { - "type": "git", - "url": "https://github.com/php-fig/container.git", - "reference": "c71ecc56dfe541dbd90c5360474fbc405f8d5963" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/php-fig/container/zipball/c71ecc56dfe541dbd90c5360474fbc405f8d5963", - "reference": "c71ecc56dfe541dbd90c5360474fbc405f8d5963", - "shasum": "" - }, - "require": { - "php": ">=7.4.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.0.x-dev" - } - }, - "autoload": { - "psr-4": { - "Psr\\Container\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "PHP-FIG", - "homepage": "https://www.php-fig.org/" - } - ], - "description": "Common Container Interface (PHP FIG PSR-11)", - "homepage": "https://github.com/php-fig/container", - "keywords": [ - "PSR-11", - "container", - "container-interface", - "container-interop", - "psr" - ], - "support": { - "issues": "https://github.com/php-fig/container/issues", - "source": "https://github.com/php-fig/container/tree/2.0.2" - }, - "time": "2021-11-05T16:47:00+00:00" + "time": "2024-06-15T09:14:53+00:00" }, { "name": "sebastian/cli-parser", - "version": "2.0.1", + "version": "3.0.1", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/cli-parser.git", - "reference": "c34583b87e7b7a8055bf6c450c2c77ce32a24084" + "reference": "00a74d5568694711f0222e54fb281e1d15fdf04a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/cli-parser/zipball/c34583b87e7b7a8055bf6c450c2c77ce32a24084", - "reference": "c34583b87e7b7a8055bf6c450c2c77ce32a24084", + "url": "https://api.github.com/repos/sebastianbergmann/cli-parser/zipball/00a74d5568694711f0222e54fb281e1d15fdf04a", + "reference": "00a74d5568694711f0222e54fb281e1d15fdf04a", "shasum": "" }, "require": { - "php": ">=8.1" + "php": ">=8.2" }, "require-dev": { - "phpunit/phpunit": "^10.0" + "phpunit/phpunit": "^11.0" }, "type": "library", "extra": { "branch-alias": { - "dev-main": "2.0-dev" + "dev-main": "3.0-dev" } }, "autoload": { @@ -1414,7 +1223,7 @@ "support": { "issues": "https://github.com/sebastianbergmann/cli-parser/issues", "security": "https://github.com/sebastianbergmann/cli-parser/security/policy", - "source": "https://github.com/sebastianbergmann/cli-parser/tree/2.0.1" + "source": "https://github.com/sebastianbergmann/cli-parser/tree/3.0.1" }, "funding": [ { @@ -1422,32 +1231,32 @@ "type": "github" } ], - "time": "2024-03-02T07:12:49+00:00" + "time": "2024-03-02T07:26:58+00:00" }, { "name": "sebastian/code-unit", - "version": "2.0.0", + "version": "3.0.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/code-unit.git", - "reference": "a81fee9eef0b7a76af11d121767abc44c104e503" + "reference": "6634549cb8d702282a04a774e36a7477d2bd9015" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/code-unit/zipball/a81fee9eef0b7a76af11d121767abc44c104e503", - "reference": "a81fee9eef0b7a76af11d121767abc44c104e503", + "url": "https://api.github.com/repos/sebastianbergmann/code-unit/zipball/6634549cb8d702282a04a774e36a7477d2bd9015", + "reference": "6634549cb8d702282a04a774e36a7477d2bd9015", "shasum": "" }, "require": { - "php": ">=8.1" + "php": ">=8.2" }, "require-dev": { - "phpunit/phpunit": "^10.0" + "phpunit/phpunit": "^11.0" }, "type": "library", "extra": { "branch-alias": { - "dev-main": "2.0-dev" + "dev-main": "3.0-dev" } }, "autoload": { @@ -1470,7 +1279,8 @@ "homepage": "https://github.com/sebastianbergmann/code-unit", "support": { "issues": "https://github.com/sebastianbergmann/code-unit/issues", - "source": "https://github.com/sebastianbergmann/code-unit/tree/2.0.0" + "security": "https://github.com/sebastianbergmann/code-unit/security/policy", + "source": "https://github.com/sebastianbergmann/code-unit/tree/3.0.0" }, "funding": [ { @@ -1478,32 +1288,32 @@ "type": "github" } ], - "time": "2023-02-03T06:58:43+00:00" + "time": "2024-02-02T05:50:41+00:00" }, { "name": "sebastian/code-unit-reverse-lookup", - "version": "3.0.0", + "version": "4.0.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/code-unit-reverse-lookup.git", - "reference": "5e3a687f7d8ae33fb362c5c0743794bbb2420a1d" + "reference": "df80c875d3e459b45c6039e4d9b71d4fbccae25d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/code-unit-reverse-lookup/zipball/5e3a687f7d8ae33fb362c5c0743794bbb2420a1d", - "reference": "5e3a687f7d8ae33fb362c5c0743794bbb2420a1d", + "url": "https://api.github.com/repos/sebastianbergmann/code-unit-reverse-lookup/zipball/df80c875d3e459b45c6039e4d9b71d4fbccae25d", + "reference": "df80c875d3e459b45c6039e4d9b71d4fbccae25d", "shasum": "" }, "require": { - "php": ">=8.1" + "php": ">=8.2" }, "require-dev": { - "phpunit/phpunit": "^10.0" + "phpunit/phpunit": "^11.0" }, "type": "library", "extra": { "branch-alias": { - "dev-main": "3.0-dev" + "dev-main": "4.0-dev" } }, "autoload": { @@ -1525,7 +1335,8 @@ "homepage": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/", "support": { "issues": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/issues", - "source": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/tree/3.0.0" + "security": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/security/policy", + "source": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/tree/4.0.0" }, "funding": [ { @@ -1533,36 +1344,36 @@ "type": "github" } ], - "time": "2023-02-03T06:59:15+00:00" + "time": "2024-02-02T05:52:17+00:00" }, { "name": "sebastian/comparator", - "version": "5.0.1", + "version": "6.0.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/comparator.git", - "reference": "2db5010a484d53ebf536087a70b4a5423c102372" + "reference": "bd0f2fa5b9257c69903537b266ccb80fcf940db8" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/2db5010a484d53ebf536087a70b4a5423c102372", - "reference": "2db5010a484d53ebf536087a70b4a5423c102372", + "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/bd0f2fa5b9257c69903537b266ccb80fcf940db8", + "reference": "bd0f2fa5b9257c69903537b266ccb80fcf940db8", "shasum": "" }, "require": { "ext-dom": "*", "ext-mbstring": "*", - "php": ">=8.1", - "sebastian/diff": "^5.0", - "sebastian/exporter": "^5.0" + "php": ">=8.2", + "sebastian/diff": "^6.0", + "sebastian/exporter": "^6.0" }, "require-dev": { - "phpunit/phpunit": "^10.3" + "phpunit/phpunit": "^11.0" }, "type": "library", "extra": { "branch-alias": { - "dev-main": "5.0-dev" + "dev-main": "6.0-dev" } }, "autoload": { @@ -1602,7 +1413,7 @@ "support": { "issues": "https://github.com/sebastianbergmann/comparator/issues", "security": "https://github.com/sebastianbergmann/comparator/security/policy", - "source": "https://github.com/sebastianbergmann/comparator/tree/5.0.1" + "source": "https://github.com/sebastianbergmann/comparator/tree/6.0.0" }, "funding": [ { @@ -1610,33 +1421,33 @@ "type": "github" } ], - "time": "2023-08-14T13:18:12+00:00" + "time": "2024-02-02T05:53:45+00:00" }, { "name": "sebastian/complexity", - "version": "3.2.0", + "version": "4.0.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/complexity.git", - "reference": "68ff824baeae169ec9f2137158ee529584553799" + "reference": "88a434ad86150e11a606ac4866b09130712671f0" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/complexity/zipball/68ff824baeae169ec9f2137158ee529584553799", - "reference": "68ff824baeae169ec9f2137158ee529584553799", + "url": "https://api.github.com/repos/sebastianbergmann/complexity/zipball/88a434ad86150e11a606ac4866b09130712671f0", + "reference": "88a434ad86150e11a606ac4866b09130712671f0", "shasum": "" }, "require": { - "nikic/php-parser": "^4.18 || ^5.0", - "php": ">=8.1" + "nikic/php-parser": "^5.0", + "php": ">=8.2" }, "require-dev": { - "phpunit/phpunit": "^10.0" + "phpunit/phpunit": "^11.0" }, "type": "library", "extra": { "branch-alias": { - "dev-main": "3.2-dev" + "dev-main": "4.0-dev" } }, "autoload": { @@ -1660,7 +1471,7 @@ "support": { "issues": "https://github.com/sebastianbergmann/complexity/issues", "security": "https://github.com/sebastianbergmann/complexity/security/policy", - "source": "https://github.com/sebastianbergmann/complexity/tree/3.2.0" + "source": "https://github.com/sebastianbergmann/complexity/tree/4.0.0" }, "funding": [ { @@ -1668,33 +1479,33 @@ "type": "github" } ], - "time": "2023-12-21T08:37:17+00:00" + "time": "2024-02-02T05:55:19+00:00" }, { "name": "sebastian/diff", - "version": "5.1.1", + "version": "6.0.1", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/diff.git", - "reference": "c41e007b4b62af48218231d6c2275e4c9b975b2e" + "reference": "ab83243ecc233de5655b76f577711de9f842e712" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/c41e007b4b62af48218231d6c2275e4c9b975b2e", - "reference": "c41e007b4b62af48218231d6c2275e4c9b975b2e", + "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/ab83243ecc233de5655b76f577711de9f842e712", + "reference": "ab83243ecc233de5655b76f577711de9f842e712", "shasum": "" }, "require": { - "php": ">=8.1" + "php": ">=8.2" }, "require-dev": { - "phpunit/phpunit": "^10.0", - "symfony/process": "^6.4" + "phpunit/phpunit": "^11.0", + "symfony/process": "^4.2 || ^5" }, "type": "library", "extra": { "branch-alias": { - "dev-main": "5.1-dev" + "dev-main": "6.0-dev" } }, "autoload": { @@ -1727,7 +1538,7 @@ "support": { "issues": "https://github.com/sebastianbergmann/diff/issues", "security": "https://github.com/sebastianbergmann/diff/security/policy", - "source": "https://github.com/sebastianbergmann/diff/tree/5.1.1" + "source": "https://github.com/sebastianbergmann/diff/tree/6.0.1" }, "funding": [ { @@ -1735,27 +1546,27 @@ "type": "github" } ], - "time": "2024-03-02T07:15:17+00:00" + "time": "2024-03-02T07:30:33+00:00" }, { "name": "sebastian/environment", - "version": "6.0.1", + "version": "7.1.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/environment.git", - "reference": "43c751b41d74f96cbbd4e07b7aec9675651e2951" + "reference": "4eb3a442574d0e9d141aab209cd4aaf25701b09a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/43c751b41d74f96cbbd4e07b7aec9675651e2951", - "reference": "43c751b41d74f96cbbd4e07b7aec9675651e2951", + "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/4eb3a442574d0e9d141aab209cd4aaf25701b09a", + "reference": "4eb3a442574d0e9d141aab209cd4aaf25701b09a", "shasum": "" }, "require": { - "php": ">=8.1" + "php": ">=8.2" }, "require-dev": { - "phpunit/phpunit": "^10.0" + "phpunit/phpunit": "^11.0" }, "suggest": { "ext-posix": "*" @@ -1763,7 +1574,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "6.0-dev" + "dev-main": "7.1-dev" } }, "autoload": { @@ -1791,7 +1602,7 @@ "support": { "issues": "https://github.com/sebastianbergmann/environment/issues", "security": "https://github.com/sebastianbergmann/environment/security/policy", - "source": "https://github.com/sebastianbergmann/environment/tree/6.0.1" + "source": "https://github.com/sebastianbergmann/environment/tree/7.1.0" }, "funding": [ { @@ -1799,34 +1610,34 @@ "type": "github" } ], - "time": "2023-04-11T05:39:26+00:00" + "time": "2024-03-23T08:56:34+00:00" }, { "name": "sebastian/exporter", - "version": "5.1.2", + "version": "6.0.3", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/exporter.git", - "reference": "955288482d97c19a372d3f31006ab3f37da47adf" + "reference": "1d978d75456094ec0c67692bca1d4662d5ce9c9f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/955288482d97c19a372d3f31006ab3f37da47adf", - "reference": "955288482d97c19a372d3f31006ab3f37da47adf", + "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/1d978d75456094ec0c67692bca1d4662d5ce9c9f", + "reference": "1d978d75456094ec0c67692bca1d4662d5ce9c9f", "shasum": "" }, "require": { "ext-mbstring": "*", - "php": ">=8.1", - "sebastian/recursion-context": "^5.0" + "php": ">=8.2", + "sebastian/recursion-context": "^6.0" }, "require-dev": { - "phpunit/phpunit": "^10.0" + "phpunit/phpunit": "^11.2" }, "type": "library", "extra": { "branch-alias": { - "dev-main": "5.1-dev" + "dev-main": "6.1-dev" } }, "autoload": { @@ -1869,7 +1680,7 @@ "support": { "issues": "https://github.com/sebastianbergmann/exporter/issues", "security": "https://github.com/sebastianbergmann/exporter/security/policy", - "source": "https://github.com/sebastianbergmann/exporter/tree/5.1.2" + "source": "https://github.com/sebastianbergmann/exporter/tree/6.0.3" }, "funding": [ { @@ -1877,35 +1688,35 @@ "type": "github" } ], - "time": "2024-03-02T07:17:12+00:00" + "time": "2024-06-17T07:48:18+00:00" }, { "name": "sebastian/global-state", - "version": "6.0.2", + "version": "7.0.1", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/global-state.git", - "reference": "987bafff24ecc4c9ac418cab1145b96dd6e9cbd9" + "reference": "c3a307e832f2e69c7ef869e31fc644fde0e7cb3e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/987bafff24ecc4c9ac418cab1145b96dd6e9cbd9", - "reference": "987bafff24ecc4c9ac418cab1145b96dd6e9cbd9", + "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/c3a307e832f2e69c7ef869e31fc644fde0e7cb3e", + "reference": "c3a307e832f2e69c7ef869e31fc644fde0e7cb3e", "shasum": "" }, "require": { - "php": ">=8.1", - "sebastian/object-reflector": "^3.0", - "sebastian/recursion-context": "^5.0" + "php": ">=8.2", + "sebastian/object-reflector": "^4.0", + "sebastian/recursion-context": "^6.0" }, "require-dev": { "ext-dom": "*", - "phpunit/phpunit": "^10.0" + "phpunit/phpunit": "^11.0" }, "type": "library", "extra": { "branch-alias": { - "dev-main": "6.0-dev" + "dev-main": "7.0-dev" } }, "autoload": { @@ -1931,7 +1742,7 @@ "support": { "issues": "https://github.com/sebastianbergmann/global-state/issues", "security": "https://github.com/sebastianbergmann/global-state/security/policy", - "source": "https://github.com/sebastianbergmann/global-state/tree/6.0.2" + "source": "https://github.com/sebastianbergmann/global-state/tree/7.0.1" }, "funding": [ { @@ -1939,33 +1750,33 @@ "type": "github" } ], - "time": "2024-03-02T07:19:19+00:00" + "time": "2024-03-02T07:32:10+00:00" }, { "name": "sebastian/lines-of-code", - "version": "2.0.2", + "version": "3.0.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/lines-of-code.git", - "reference": "856e7f6a75a84e339195d48c556f23be2ebf75d0" + "reference": "376c5b3f6b43c78fdc049740bca76a7c846706c0" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/lines-of-code/zipball/856e7f6a75a84e339195d48c556f23be2ebf75d0", - "reference": "856e7f6a75a84e339195d48c556f23be2ebf75d0", + "url": "https://api.github.com/repos/sebastianbergmann/lines-of-code/zipball/376c5b3f6b43c78fdc049740bca76a7c846706c0", + "reference": "376c5b3f6b43c78fdc049740bca76a7c846706c0", "shasum": "" }, "require": { - "nikic/php-parser": "^4.18 || ^5.0", - "php": ">=8.1" + "nikic/php-parser": "^5.0", + "php": ">=8.2" }, "require-dev": { - "phpunit/phpunit": "^10.0" + "phpunit/phpunit": "^11.0" }, "type": "library", "extra": { "branch-alias": { - "dev-main": "2.0-dev" + "dev-main": "3.0-dev" } }, "autoload": { @@ -1989,7 +1800,7 @@ "support": { "issues": "https://github.com/sebastianbergmann/lines-of-code/issues", "security": "https://github.com/sebastianbergmann/lines-of-code/security/policy", - "source": "https://github.com/sebastianbergmann/lines-of-code/tree/2.0.2" + "source": "https://github.com/sebastianbergmann/lines-of-code/tree/3.0.0" }, "funding": [ { @@ -1997,34 +1808,34 @@ "type": "github" } ], - "time": "2023-12-21T08:38:20+00:00" + "time": "2024-02-02T06:00:36+00:00" }, { "name": "sebastian/object-enumerator", - "version": "5.0.0", + "version": "6.0.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/object-enumerator.git", - "reference": "202d0e344a580d7f7d04b3fafce6933e59dae906" + "reference": "f75f6c460da0bbd9668f43a3dde0ec0ba7faa678" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/202d0e344a580d7f7d04b3fafce6933e59dae906", - "reference": "202d0e344a580d7f7d04b3fafce6933e59dae906", + "url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/f75f6c460da0bbd9668f43a3dde0ec0ba7faa678", + "reference": "f75f6c460da0bbd9668f43a3dde0ec0ba7faa678", "shasum": "" }, "require": { - "php": ">=8.1", - "sebastian/object-reflector": "^3.0", - "sebastian/recursion-context": "^5.0" + "php": ">=8.2", + "sebastian/object-reflector": "^4.0", + "sebastian/recursion-context": "^6.0" }, "require-dev": { - "phpunit/phpunit": "^10.0" + "phpunit/phpunit": "^11.0" }, "type": "library", "extra": { "branch-alias": { - "dev-main": "5.0-dev" + "dev-main": "6.0-dev" } }, "autoload": { @@ -2046,7 +1857,8 @@ "homepage": "https://github.com/sebastianbergmann/object-enumerator/", "support": { "issues": "https://github.com/sebastianbergmann/object-enumerator/issues", - "source": "https://github.com/sebastianbergmann/object-enumerator/tree/5.0.0" + "security": "https://github.com/sebastianbergmann/object-enumerator/security/policy", + "source": "https://github.com/sebastianbergmann/object-enumerator/tree/6.0.0" }, "funding": [ { @@ -2054,32 +1866,32 @@ "type": "github" } ], - "time": "2023-02-03T07:08:32+00:00" + "time": "2024-02-02T06:01:29+00:00" }, { "name": "sebastian/object-reflector", - "version": "3.0.0", + "version": "4.0.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/object-reflector.git", - "reference": "24ed13d98130f0e7122df55d06c5c4942a577957" + "reference": "bb2a6255d30853425fd38f032eb64ced9f7f132d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/object-reflector/zipball/24ed13d98130f0e7122df55d06c5c4942a577957", - "reference": "24ed13d98130f0e7122df55d06c5c4942a577957", + "url": "https://api.github.com/repos/sebastianbergmann/object-reflector/zipball/bb2a6255d30853425fd38f032eb64ced9f7f132d", + "reference": "bb2a6255d30853425fd38f032eb64ced9f7f132d", "shasum": "" }, "require": { - "php": ">=8.1" + "php": ">=8.2" }, "require-dev": { - "phpunit/phpunit": "^10.0" + "phpunit/phpunit": "^11.0" }, "type": "library", "extra": { "branch-alias": { - "dev-main": "3.0-dev" + "dev-main": "4.0-dev" } }, "autoload": { @@ -2101,7 +1913,8 @@ "homepage": "https://github.com/sebastianbergmann/object-reflector/", "support": { "issues": "https://github.com/sebastianbergmann/object-reflector/issues", - "source": "https://github.com/sebastianbergmann/object-reflector/tree/3.0.0" + "security": "https://github.com/sebastianbergmann/object-reflector/security/policy", + "source": "https://github.com/sebastianbergmann/object-reflector/tree/4.0.0" }, "funding": [ { @@ -2109,32 +1922,32 @@ "type": "github" } ], - "time": "2023-02-03T07:06:18+00:00" + "time": "2024-02-02T06:02:18+00:00" }, { "name": "sebastian/recursion-context", - "version": "5.0.0", + "version": "6.0.1", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/recursion-context.git", - "reference": "05909fb5bc7df4c52992396d0116aed689f93712" + "reference": "2f15508e17af4ea35129bbc32ce28a814d9c7426" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/05909fb5bc7df4c52992396d0116aed689f93712", - "reference": "05909fb5bc7df4c52992396d0116aed689f93712", + "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/2f15508e17af4ea35129bbc32ce28a814d9c7426", + "reference": "2f15508e17af4ea35129bbc32ce28a814d9c7426", "shasum": "" }, "require": { - "php": ">=8.1" + "php": ">=8.2" }, "require-dev": { - "phpunit/phpunit": "^10.0" + "phpunit/phpunit": "^11.0" }, "type": "library", "extra": { "branch-alias": { - "dev-main": "5.0-dev" + "dev-main": "6.0-dev" } }, "autoload": { @@ -2164,7 +1977,8 @@ "homepage": "https://github.com/sebastianbergmann/recursion-context", "support": { "issues": "https://github.com/sebastianbergmann/recursion-context/issues", - "source": "https://github.com/sebastianbergmann/recursion-context/tree/5.0.0" + "security": "https://github.com/sebastianbergmann/recursion-context/security/policy", + "source": "https://github.com/sebastianbergmann/recursion-context/tree/6.0.1" }, "funding": [ { @@ -2172,32 +1986,32 @@ "type": "github" } ], - "time": "2023-02-03T07:05:40+00:00" + "time": "2024-06-17T05:22:57+00:00" }, { "name": "sebastian/type", - "version": "4.0.0", + "version": "5.0.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/type.git", - "reference": "462699a16464c3944eefc02ebdd77882bd3925bf" + "reference": "b8502785eb3523ca0dd4afe9ca62235590020f3f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/type/zipball/462699a16464c3944eefc02ebdd77882bd3925bf", - "reference": "462699a16464c3944eefc02ebdd77882bd3925bf", + "url": "https://api.github.com/repos/sebastianbergmann/type/zipball/b8502785eb3523ca0dd4afe9ca62235590020f3f", + "reference": "b8502785eb3523ca0dd4afe9ca62235590020f3f", "shasum": "" }, "require": { - "php": ">=8.1" + "php": ">=8.2" }, "require-dev": { - "phpunit/phpunit": "^10.0" + "phpunit/phpunit": "^11.0" }, "type": "library", "extra": { "branch-alias": { - "dev-main": "4.0-dev" + "dev-main": "5.0-dev" } }, "autoload": { @@ -2220,7 +2034,8 @@ "homepage": "https://github.com/sebastianbergmann/type", "support": { "issues": "https://github.com/sebastianbergmann/type/issues", - "source": "https://github.com/sebastianbergmann/type/tree/4.0.0" + "security": "https://github.com/sebastianbergmann/type/security/policy", + "source": "https://github.com/sebastianbergmann/type/tree/5.0.0" }, "funding": [ { @@ -2228,29 +2043,29 @@ "type": "github" } ], - "time": "2023-02-03T07:10:45+00:00" + "time": "2024-02-02T06:09:34+00:00" }, { "name": "sebastian/version", - "version": "4.0.1", + "version": "5.0.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/version.git", - "reference": "c51fa83a5d8f43f1402e3f32a005e6262244ef17" + "reference": "13999475d2cb1ab33cb73403ba356a814fdbb001" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/c51fa83a5d8f43f1402e3f32a005e6262244ef17", - "reference": "c51fa83a5d8f43f1402e3f32a005e6262244ef17", + "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/13999475d2cb1ab33cb73403ba356a814fdbb001", + "reference": "13999475d2cb1ab33cb73403ba356a814fdbb001", "shasum": "" }, "require": { - "php": ">=8.1" + "php": ">=8.2" }, "type": "library", "extra": { "branch-alias": { - "dev-main": "4.0-dev" + "dev-main": "5.0-dev" } }, "autoload": { @@ -2273,7 +2088,8 @@ "homepage": "https://github.com/sebastianbergmann/version", "support": { "issues": "https://github.com/sebastianbergmann/version/issues", - "source": "https://github.com/sebastianbergmann/version/tree/4.0.1" + "security": "https://github.com/sebastianbergmann/version/security/policy", + "source": "https://github.com/sebastianbergmann/version/tree/5.0.0" }, "funding": [ { @@ -2281,568 +2097,7 @@ "type": "github" } ], - "time": "2023-02-07T11:34:05+00:00" - }, - { - "name": "squizlabs/php_codesniffer", - "version": "3.9.0", - "source": { - "type": "git", - "url": "https://github.com/PHPCSStandards/PHP_CodeSniffer.git", - "reference": "d63cee4890a8afaf86a22e51ad4d97c91dd4579b" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/PHPCSStandards/PHP_CodeSniffer/zipball/d63cee4890a8afaf86a22e51ad4d97c91dd4579b", - "reference": "d63cee4890a8afaf86a22e51ad4d97c91dd4579b", - "shasum": "" - }, - "require": { - "ext-simplexml": "*", - "ext-tokenizer": "*", - "ext-xmlwriter": "*", - "php": ">=5.4.0" - }, - "require-dev": { - "phpunit/phpunit": "^4.0 || ^5.0 || ^6.0 || ^7.0 || ^8.0 || ^9.3.4" - }, - "bin": [ - "bin/phpcbf", - "bin/phpcs" - ], - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.x-dev" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Greg Sherwood", - "role": "Former lead" - }, - { - "name": "Juliette Reinders Folmer", - "role": "Current lead" - }, - { - "name": "Contributors", - "homepage": "https://github.com/PHPCSStandards/PHP_CodeSniffer/graphs/contributors" - } - ], - "description": "PHP_CodeSniffer tokenizes PHP, JavaScript and CSS files and detects violations of a defined set of coding standards.", - "homepage": "https://github.com/PHPCSStandards/PHP_CodeSniffer", - "keywords": [ - "phpcs", - "standards", - "static analysis" - ], - "support": { - "issues": "https://github.com/PHPCSStandards/PHP_CodeSniffer/issues", - "security": "https://github.com/PHPCSStandards/PHP_CodeSniffer/security/policy", - "source": "https://github.com/PHPCSStandards/PHP_CodeSniffer", - "wiki": "https://github.com/PHPCSStandards/PHP_CodeSniffer/wiki" - }, - "funding": [ - { - "url": "https://github.com/PHPCSStandards", - "type": "github" - }, - { - "url": "https://github.com/jrfnl", - "type": "github" - }, - { - "url": "https://opencollective.com/php_codesniffer", - "type": "open_collective" - } - ], - "time": "2024-02-16T15:06:51+00:00" - }, - { - "name": "symfony/console", - "version": "v7.0.4", - "source": { - "type": "git", - "url": "https://github.com/symfony/console.git", - "reference": "6b099f3306f7c9c2d2786ed736d0026b2903205f" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/console/zipball/6b099f3306f7c9c2d2786ed736d0026b2903205f", - "reference": "6b099f3306f7c9c2d2786ed736d0026b2903205f", - "shasum": "" - }, - "require": { - "php": ">=8.2", - "symfony/polyfill-mbstring": "~1.0", - "symfony/service-contracts": "^2.5|^3", - "symfony/string": "^6.4|^7.0" - }, - "conflict": { - "symfony/dependency-injection": "<6.4", - "symfony/dotenv": "<6.4", - "symfony/event-dispatcher": "<6.4", - "symfony/lock": "<6.4", - "symfony/process": "<6.4" - }, - "provide": { - "psr/log-implementation": "1.0|2.0|3.0" - }, - "require-dev": { - "psr/log": "^1|^2|^3", - "symfony/config": "^6.4|^7.0", - "symfony/dependency-injection": "^6.4|^7.0", - "symfony/event-dispatcher": "^6.4|^7.0", - "symfony/http-foundation": "^6.4|^7.0", - "symfony/http-kernel": "^6.4|^7.0", - "symfony/lock": "^6.4|^7.0", - "symfony/messenger": "^6.4|^7.0", - "symfony/process": "^6.4|^7.0", - "symfony/stopwatch": "^6.4|^7.0", - "symfony/var-dumper": "^6.4|^7.0" - }, - "type": "library", - "autoload": { - "psr-4": { - "Symfony\\Component\\Console\\": "" - }, - "exclude-from-classmap": [ - "/Tests/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Eases the creation of beautiful and testable command line interfaces", - "homepage": "https://symfony.com", - "keywords": [ - "cli", - "command-line", - "console", - "terminal" - ], - "support": { - "source": "https://github.com/symfony/console/tree/v7.0.4" - }, - "funding": [ - { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" - } - ], - "time": "2024-02-22T20:27:20+00:00" - }, - { - "name": "symfony/polyfill-intl-grapheme", - "version": "v1.29.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/polyfill-intl-grapheme.git", - "reference": "32a9da87d7b3245e09ac426c83d334ae9f06f80f" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-intl-grapheme/zipball/32a9da87d7b3245e09ac426c83d334ae9f06f80f", - "reference": "32a9da87d7b3245e09ac426c83d334ae9f06f80f", - "shasum": "" - }, - "require": { - "php": ">=7.1" - }, - "suggest": { - "ext-intl": "For best performance" - }, - "type": "library", - "extra": { - "thanks": { - "name": "symfony/polyfill", - "url": "https://github.com/symfony/polyfill" - } - }, - "autoload": { - "files": [ - "bootstrap.php" - ], - "psr-4": { - "Symfony\\Polyfill\\Intl\\Grapheme\\": "" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Symfony polyfill for intl's grapheme_* functions", - "homepage": "https://symfony.com", - "keywords": [ - "compatibility", - "grapheme", - "intl", - "polyfill", - "portable", - "shim" - ], - "support": { - "source": "https://github.com/symfony/polyfill-intl-grapheme/tree/v1.29.0" - }, - "funding": [ - { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" - } - ], - "time": "2024-01-29T20:11:03+00:00" - }, - { - "name": "symfony/polyfill-intl-normalizer", - "version": "v1.29.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/polyfill-intl-normalizer.git", - "reference": "bc45c394692b948b4d383a08d7753968bed9a83d" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/bc45c394692b948b4d383a08d7753968bed9a83d", - "reference": "bc45c394692b948b4d383a08d7753968bed9a83d", - "shasum": "" - }, - "require": { - "php": ">=7.1" - }, - "suggest": { - "ext-intl": "For best performance" - }, - "type": "library", - "extra": { - "thanks": { - "name": "symfony/polyfill", - "url": "https://github.com/symfony/polyfill" - } - }, - "autoload": { - "files": [ - "bootstrap.php" - ], - "psr-4": { - "Symfony\\Polyfill\\Intl\\Normalizer\\": "" - }, - "classmap": [ - "Resources/stubs" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Symfony polyfill for intl's Normalizer class and related functions", - "homepage": "https://symfony.com", - "keywords": [ - "compatibility", - "intl", - "normalizer", - "polyfill", - "portable", - "shim" - ], - "support": { - "source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.29.0" - }, - "funding": [ - { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" - } - ], - "time": "2024-01-29T20:11:03+00:00" - }, - { - "name": "symfony/process", - "version": "v7.0.4", - "source": { - "type": "git", - "url": "https://github.com/symfony/process.git", - "reference": "0e7727191c3b71ebec6d529fa0e50a01ca5679e9" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/process/zipball/0e7727191c3b71ebec6d529fa0e50a01ca5679e9", - "reference": "0e7727191c3b71ebec6d529fa0e50a01ca5679e9", - "shasum": "" - }, - "require": { - "php": ">=8.2" - }, - "type": "library", - "autoload": { - "psr-4": { - "Symfony\\Component\\Process\\": "" - }, - "exclude-from-classmap": [ - "/Tests/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Executes commands in sub-processes", - "homepage": "https://symfony.com", - "support": { - "source": "https://github.com/symfony/process/tree/v7.0.4" - }, - "funding": [ - { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" - } - ], - "time": "2024-02-22T20:27:20+00:00" - }, - { - "name": "symfony/service-contracts", - "version": "v3.4.1", - "source": { - "type": "git", - "url": "https://github.com/symfony/service-contracts.git", - "reference": "fe07cbc8d837f60caf7018068e350cc5163681a0" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/service-contracts/zipball/fe07cbc8d837f60caf7018068e350cc5163681a0", - "reference": "fe07cbc8d837f60caf7018068e350cc5163681a0", - "shasum": "" - }, - "require": { - "php": ">=8.1", - "psr/container": "^1.1|^2.0" - }, - "conflict": { - "ext-psr": "<1.1|>=2" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "3.4-dev" - }, - "thanks": { - "name": "symfony/contracts", - "url": "https://github.com/symfony/contracts" - } - }, - "autoload": { - "psr-4": { - "Symfony\\Contracts\\Service\\": "" - }, - "exclude-from-classmap": [ - "/Test/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Generic abstractions related to writing services", - "homepage": "https://symfony.com", - "keywords": [ - "abstractions", - "contracts", - "decoupling", - "interfaces", - "interoperability", - "standards" - ], - "support": { - "source": "https://github.com/symfony/service-contracts/tree/v3.4.1" - }, - "funding": [ - { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" - } - ], - "time": "2023-12-26T14:02:43+00:00" - }, - { - "name": "symfony/string", - "version": "v7.0.4", - "source": { - "type": "git", - "url": "https://github.com/symfony/string.git", - "reference": "f5832521b998b0bec40bee688ad5de98d4cf111b" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/string/zipball/f5832521b998b0bec40bee688ad5de98d4cf111b", - "reference": "f5832521b998b0bec40bee688ad5de98d4cf111b", - "shasum": "" - }, - "require": { - "php": ">=8.2", - "symfony/polyfill-ctype": "~1.8", - "symfony/polyfill-intl-grapheme": "~1.0", - "symfony/polyfill-intl-normalizer": "~1.0", - "symfony/polyfill-mbstring": "~1.0" - }, - "conflict": { - "symfony/translation-contracts": "<2.5" - }, - "require-dev": { - "symfony/error-handler": "^6.4|^7.0", - "symfony/http-client": "^6.4|^7.0", - "symfony/intl": "^6.4|^7.0", - "symfony/translation-contracts": "^2.5|^3.0", - "symfony/var-exporter": "^6.4|^7.0" - }, - "type": "library", - "autoload": { - "files": [ - "Resources/functions.php" - ], - "psr-4": { - "Symfony\\Component\\String\\": "" - }, - "exclude-from-classmap": [ - "/Tests/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Provides an object-oriented API to strings and deals with bytes, UTF-8 code points and grapheme clusters in a unified way", - "homepage": "https://symfony.com", - "keywords": [ - "grapheme", - "i18n", - "string", - "unicode", - "utf-8", - "utf8" - ], - "support": { - "source": "https://github.com/symfony/string/tree/v7.0.4" - }, - "funding": [ - { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" - } - ], - "time": "2024-02-01T13:17:36+00:00" + "time": "2024-02-02T06:10:47+00:00" }, { "name": "theseer/tokenizer", @@ -2901,7 +2156,7 @@ "prefer-stable": true, "prefer-lowest": false, "platform": { - "php": ">=8.0", + "php": "8.*", "ext-curl": "*", "ext-mbstring": "*", "ext-json": "*" From 1e1a50147d554b961102867e301cdaaae226b3b9 Mon Sep 17 00:00:00 2001 From: Jake Barnby Date: Tue, 18 Jun 2024 12:36:23 +1200 Subject: [PATCH 04/24] Fix Java endpoint setter --- mock-server/app/http.php | 2 +- .../src/main/java/io/package/Client.kt.twig | 18 ++++++++++++------ .../src/main/kotlin/io/appwrite/Client.kt.twig | 14 ++++++++++---- 3 files changed, 23 insertions(+), 11 deletions(-) diff --git a/mock-server/app/http.php b/mock-server/app/http.php index 467cb48b8..26911f8b6 100644 --- a/mock-server/app/http.php +++ b/mock-server/app/http.php @@ -64,7 +64,7 @@ ->label('sdk.response.type', Response::CONTENT_TYPE_JSON) ->inject('response') ->action(function (UtopiaSwooleResponse $response) { - $response->json([ 'version' => '1.0.0' ]); + $response->json([ 'version' => '1.5.7' ]); }); // Mock Routes diff --git a/templates/android/library/src/main/java/io/package/Client.kt.twig b/templates/android/library/src/main/java/io/package/Client.kt.twig index 1bd7d0c16..1352b2bc1 100644 --- a/templates/android/library/src/main/java/io/package/Client.kt.twig +++ b/templates/android/library/src/main/java/io/package/Client.kt.twig @@ -36,12 +36,7 @@ import javax.net.ssl.X509TrustManager import kotlin.coroutines.CoroutineContext import kotlin.coroutines.resume -class Client @JvmOverloads constructor( - context: Context, - var endpoint: String = "{{spec.endpoint}}", - var endpointRealtime: String? = null, - private var selfSigned: Boolean = false -) : CoroutineScope { +class Client(context: Context) : CoroutineScope { companion object { internal const val CHUNK_SIZE = 5*1024*1024; // 5MB @@ -49,6 +44,17 @@ class Client @JvmOverloads constructor( internal const val COOKIE_PREFS = "myCookie" } + private var _endpoint: String = "" + var endpoint: String + get() = _endpoint + private set(value) { + _endpoint = value + } + + private var endpointRealtime: String? = null + + private var selfSigned: Boolean = false + override val coroutineContext: CoroutineContext get() = Dispatchers.Main + job diff --git a/templates/kotlin/src/main/kotlin/io/appwrite/Client.kt.twig b/templates/kotlin/src/main/kotlin/io/appwrite/Client.kt.twig index d970c5101..a7b92d2ef 100644 --- a/templates/kotlin/src/main/kotlin/io/appwrite/Client.kt.twig +++ b/templates/kotlin/src/main/kotlin/io/appwrite/Client.kt.twig @@ -31,15 +31,21 @@ import javax.net.ssl.X509TrustManager import kotlin.coroutines.CoroutineContext import kotlin.coroutines.resume -class Client @JvmOverloads constructor( - var endPoint: String = "{{spec.endpoint}}", - private var selfSigned: Boolean = false -) : CoroutineScope { +class Client: CoroutineScope { companion object { const val CHUNK_SIZE = 5*1024*1024; // 5MB } + private var _endpoint: String = "" + var endpoint: String + get() = _endpoint + private set(value) { + _endpoint = value + } + + private var selfSigned: Boolean = false + override val coroutineContext: CoroutineContext get() = Dispatchers.Main + job From b2578de3786731042d96ba092c9805ae054f0af6 Mon Sep 17 00:00:00 2001 From: Jake Barnby Date: Tue, 18 Jun 2024 12:37:54 +1200 Subject: [PATCH 05/24] Add Java test class --- tests/languages/android/Tests.java | 254 +++++++++++++++++++++++++++++ 1 file changed, 254 insertions(+) create mode 100644 tests/languages/android/Tests.java diff --git a/tests/languages/android/Tests.java b/tests/languages/android/Tests.java new file mode 100644 index 000000000..ebfecebf6 --- /dev/null +++ b/tests/languages/android/Tests.java @@ -0,0 +1,254 @@ +package io.appwrite; + +import androidx.test.core.app.ApplicationProvider; +import androidx.test.ext.junit.runners.AndroidJUnit4; + +import com.google.gson.Gson; + +import io.appwrite.exceptions.AppwriteException; +import io.appwrite.Permission; +import io.appwrite.Role; +import io.appwrite.ID; +import io.appwrite.Query; +import io.appwrite.enums.MockType; +import io.appwrite.extensions.GsonExtensionsKt; +import io.appwrite.models.Error; +import io.appwrite.models.InputFile; +import io.appwrite.models.Mock; +import io.appwrite.services.Bar; +import io.appwrite.services.Foo; +import io.appwrite.services.General; +import io.appwrite.services.Realtime; + +import kotlinx.coroutines.Dispatchers; +import kotlinx.coroutines.ExperimentalCoroutinesApi; +import kotlinx.coroutines.delay; +import kotlinx.coroutines.runBlocking; +import kotlinx.coroutines.test.TestCoroutineDispatcher; +import kotlinx.coroutines.test.TestCoroutineScope; + +import okhttp3.Response; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.robolectric.annotation.Config; + +import java.io.File; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.nio.file.StandardOpenOption; +import java.util.List; +import java.util.Map; + +import static kotlinx.coroutines.test.TestCoroutineScopeKt.*; + +class TestPayload { + private String response; + + public String getResponse() { + return response; + } + + public void setResponse(String response) { + this.response = response; + } +} + +@Config(manifest = Config.NONE) +@RunWith(AndroidJUnit4.class) +public class ServiceTest { + + private final String filename = "result.txt"; + + @Before + @ExperimentalCoroutinesApi + public void setUp() throws IOException { + Dispatchers.setMain(new TestCoroutineDispatcher()); + Files.deleteIfExists(Paths.get(filename)); + writeToFile("Test Started"); + } + + @After + @ExperimentalCoroutinesApi + public void tearDown() { + Dispatchers.resetMain(); + } + + @Test + @Throws(IOException.class) + public void test() throws IOException { + Client client = new Client(ApplicationProvider.getApplicationContext()) + .setEndpointRealtime("wss://demo.appwrite.io/v1") + .setProject("console") + .addHeader("Origin", "http://localhost") + .setSelfSigned(true); + + Foo foo = new Foo(client); + Bar bar = new Bar(client); + General general = new General(client); + Realtime realtime = new Realtime(client); + String realtimeResponse = "Realtime failed!"; + + realtime.subscribe("tests", TestPayload.class, payload -> { + realtimeResponse = payload.getResponse(); + return null; + }); + + runBlocking(new TestCoroutineScope(), () -> { + Mock mock; + // Foo Tests + mock = foo.get("string", 123, List.of("string in array")); + writeToFile(mock.getResult()); + mock = foo.post("string", 123, List.of("string in array")); + writeToFile(mock.getResult()); + mock = foo.put("string", 123, List.of("string in array")); + writeToFile(mock.getResult()); + mock = foo.patch("string", 123, List.of("string in array")); + writeToFile(mock.getResult()); + mock = foo.delete("string", 123, List.of("string in array")); + writeToFile(mock.getResult()); + + // Bar Tests + mock = bar.get("string", 123, List.of("string in array")); + writeToFile(mock.getResult()); + mock = bar.post("string", 123, List.of("string in array")); + writeToFile(mock.getResult()); + mock = bar.put("string", 123, List.of("string in array")); + writeToFile(mock.getResult()); + mock = bar.patch("string", 123, List.of("string in array")); + writeToFile(mock.getResult()); + mock = bar.delete("string", 123, List.of("string in array")); + writeToFile(mock.getResult()); + + // General Tests + Object result = general.redirect(); + writeToFile((String) ((Map) result).get("result")); + + try { + mock = general.upload("string", 123, List.of("string in array"), InputFile.fromPath("../../../resources/file.png")); + writeToFile(mock.getResult()); + } catch (Exception ex) { + writeToFile(ex.toString()); + } + + try { + mock = general.upload("string", 123, List.of("string in array"), InputFile.fromPath("../../../resources/large_file.mp4")); + writeToFile(mock.getResult()); + } catch (Exception ex) { + writeToFile(ex.toString()); + } + + try { + byte[] bytes = Files.readAllBytes(Paths.get("../../../resources/file.png")); + mock = general.upload("string", 123, List.of("string in array"), InputFile.fromBytes(bytes, "file.png", "image/png")); + writeToFile(mock.getResult()); + } catch (Exception ex) { + writeToFile(ex.toString()); + } + + try { + byte[] bytes = Files.readAllBytes(Paths.get("../../../resources/large_file.mp4")); + mock = general.upload("string", 123, List.of("string in array"), InputFile.fromBytes(bytes, "large_file.mp4", "video/mp4")); + writeToFile(mock.getResult()); + } catch (Exception ex) { + writeToFile(ex.toString()); + } + + mock = general.enum(MockType.FIRST); + writeToFile(mock.getResult()); + + try { + general.error400(); + } catch (AppwriteException e) { + writeToFile(e.getMessage()); + } + + try { + general.error500(); + } catch (AppwriteException e) { + writeToFile(e.getMessage()); + } + + try { + general.error502(); + } catch (AppwriteException e) { + writeToFile(e.getMessage()); + } + + delay(5000); + writeToFile(realtimeResponse); + + // mock = general.setCookie(); + // writeToFile(mock.getResult()); + + // mock = general.getCookie(); + // writeToFile(mock.getResult()); + + general.empty(); + + // Query helper tests + writeToFile(Query.Companion.equal("released", List.of(true)).toString()); + writeToFile(Query.Companion.equal("title", List.of("Spiderman", "Dr. Strange")).toString()); + writeToFile(Query.Companion.notEqual("title", "Spiderman").toString()); + writeToFile(Query.Companion.lessThan("releasedYear", 1990).toString()); + writeToFile(Query.Companion.greaterThan("releasedYear", 1990).toString()); + writeToFile(Query.Companion.search("name", "john").toString()); + writeToFile(Query.Companion.isNull("name").toString()); + writeToFile(Query.Companion.isNotNull("name").toString()); + writeToFile(Query.Companion.between("age", 50, 100).toString()); + writeToFile(Query.Companion.between("age", 50.5, 100.5).toString()); + writeToFile(Query.Companion.between("name", "Anna", "Brad").toString()); + writeToFile(Query.Companion.startsWith("name", "Ann").toString()); + writeToFile(Query.Companion.endsWith("name", "nne").toString()); + writeToFile(Query.Companion.select(List.of("name", "age")).toString()); + writeToFile(Query.Companion.orderAsc("title").toString()); + writeToFile(Query.Companion.orderDesc("title").toString()); + writeToFile(Query.Companion.cursorAfter("my_movie_id").toString()); + writeToFile(Query.Companion.cursorBefore("my_movie_id").toString()); + writeToFile(Query.Companion.limit(50).toString()); + writeToFile(Query.Companion.offset(20).toString()); + writeToFile(Query.Companion.contains("title", List.of("Spider")).toString()); + writeToFile(Query.Companion.contains("labels", List.of("first")).toString()); + writeToFile(Query.Companion.or(List.of(Query.Companion.equal("released", List.of(true)), Query.Companion.lessThan("releasedYear", 1990))).toString()); + writeToFile(Query.Companion.and(List.of(Query.Companion.equal("released", List.of(false)), Query.Companion.greaterThan("releasedYear", 2015))).toString()); + + // Permission & Roles helper tests + writeToFile(Permission.Companion.read(Role.Companion.any()).toString()); + writeToFile(Permission.Companion.write(Role.Companion.user(ID.custom("userid"))).toString()); + writeToFile(Permission.Companion.create(Role.Companion.users()).toString()); + writeToFile(Permission.Companion.update(Role.Companion.guests()).toString()); + writeToFile(Permission.Companion.delete(Role.Companion.team("teamId", "owner")).toString()); + writeToFile(Permission.Companion.delete(Role.Companion.team("teamId")).toString()); + writeToFile(Permission.Companion.create(Role.Companion.member("memberId")).toString()); + writeToFile(Permission.Companion.update(Role.Companion.users("verified")).toString()); + writeToFile(Permission.Companion.update(Role.Companion.user(ID.custom("userid"), "unverified")).toString()); + writeToFile(Permission.Companion.create(Role.Companion.label("admin")).toString()); + + // ID helper tests + writeToFile(ID.unique().toString()); + writeToFile(ID.custom("custom_id").toString()); + + mock = general.headers(); + writeToFile(mock.getResult()); + + return null; + }); + } + + private void writeToFile(String string) { + String text = (string != null ? string : "") + "\n"; + try { + Files.writeString( + Paths.get(filename), + text, + StandardOpenOption.APPEND + ); + } catch (IOException e) { + e.printStackTrace(); + } + } +} From 8734244da90d9dfcfe4560c53afbfd07b022f91d Mon Sep 17 00:00:00 2001 From: Jake Barnby Date: Tue, 18 Jun 2024 13:37:21 +1200 Subject: [PATCH 06/24] Fix imports --- tests/languages/android/Tests.java | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/tests/languages/android/Tests.java b/tests/languages/android/Tests.java index ebfecebf6..7fc0a72ee 100644 --- a/tests/languages/android/Tests.java +++ b/tests/languages/android/Tests.java @@ -3,16 +3,13 @@ import androidx.test.core.app.ApplicationProvider; import androidx.test.ext.junit.runners.AndroidJUnit4; -import com.google.gson.Gson; - +import io.appwrite.coroutines.CoroutineCallback; import io.appwrite.exceptions.AppwriteException; import io.appwrite.Permission; import io.appwrite.Role; import io.appwrite.ID; import io.appwrite.Query; import io.appwrite.enums.MockType; -import io.appwrite.extensions.GsonExtensionsKt; -import io.appwrite.models.Error; import io.appwrite.models.InputFile; import io.appwrite.models.Mock; import io.appwrite.services.Bar; @@ -27,8 +24,6 @@ import kotlinx.coroutines.test.TestCoroutineDispatcher; import kotlinx.coroutines.test.TestCoroutineScope; -import okhttp3.Response; - import org.junit.After; import org.junit.Before; import org.junit.Test; @@ -44,7 +39,10 @@ import java.util.List; import java.util.Map; -import static kotlinx.coroutines.test.TestCoroutineScopeKt.*; +import kotlin.coroutines.Continuation; +import kotlin.coroutines.CoroutineContext; +import kotlin.coroutines.Result; +import kotlin.jvm.JvmOverloads; class TestPayload { private String response; From dac65a0e6bbe939ec0c2799ca62e10cf81156ea7 Mon Sep 17 00:00:00 2001 From: Jake Barnby Date: Tue, 18 Jun 2024 13:37:41 +1200 Subject: [PATCH 07/24] Fix effectively final lambda capture --- tests/languages/android/Tests.java | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/tests/languages/android/Tests.java b/tests/languages/android/Tests.java index 7fc0a72ee..1d6f71be7 100644 --- a/tests/languages/android/Tests.java +++ b/tests/languages/android/Tests.java @@ -77,7 +77,6 @@ public void tearDown() { } @Test - @Throws(IOException.class) public void test() throws IOException { Client client = new Client(ApplicationProvider.getApplicationContext()) .setEndpointRealtime("wss://demo.appwrite.io/v1") @@ -89,10 +88,10 @@ public void test() throws IOException { Bar bar = new Bar(client); General general = new General(client); Realtime realtime = new Realtime(client); - String realtimeResponse = "Realtime failed!"; + String[] realtimeResponse = {"Realtime failed!"}; realtime.subscribe("tests", TestPayload.class, payload -> { - realtimeResponse = payload.getResponse(); + realtimeResponse[0] = payload.getResponse(); return null; }); From 522904cc952f60fc011b529fafaffa7b5bbe2778 Mon Sep 17 00:00:00 2001 From: Jake Barnby Date: Tue, 18 Jun 2024 13:38:01 +1200 Subject: [PATCH 08/24] Fix companion usages --- tests/languages/android/Tests.java | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/tests/languages/android/Tests.java b/tests/languages/android/Tests.java index 1d6f71be7..c3926a895 100644 --- a/tests/languages/android/Tests.java +++ b/tests/languages/android/Tests.java @@ -213,21 +213,19 @@ public void test() throws IOException { writeToFile(Query.Companion.or(List.of(Query.Companion.equal("released", List.of(true)), Query.Companion.lessThan("releasedYear", 1990))).toString()); writeToFile(Query.Companion.and(List.of(Query.Companion.equal("released", List.of(false)), Query.Companion.greaterThan("releasedYear", 2015))).toString()); - // Permission & Roles helper tests writeToFile(Permission.Companion.read(Role.Companion.any()).toString()); - writeToFile(Permission.Companion.write(Role.Companion.user(ID.custom("userid"))).toString()); + writeToFile(Permission.Companion.write(Role.Companion.user(ID.Companion.custom("userid"))).toString()); writeToFile(Permission.Companion.create(Role.Companion.users()).toString()); writeToFile(Permission.Companion.update(Role.Companion.guests()).toString()); writeToFile(Permission.Companion.delete(Role.Companion.team("teamId", "owner")).toString()); writeToFile(Permission.Companion.delete(Role.Companion.team("teamId")).toString()); writeToFile(Permission.Companion.create(Role.Companion.member("memberId")).toString()); writeToFile(Permission.Companion.update(Role.Companion.users("verified")).toString()); - writeToFile(Permission.Companion.update(Role.Companion.user(ID.custom("userid"), "unverified")).toString()); + writeToFile(Permission.Companion.update(Role.Companion.user(ID.Companion.custom("userid"), "unverified")).toString()); writeToFile(Permission.Companion.create(Role.Companion.label("admin")).toString()); - // ID helper tests - writeToFile(ID.unique().toString()); - writeToFile(ID.custom("custom_id").toString()); + writeToFile(ID.Companion.unique().toString()); + writeToFile(ID.Companion.custom("custom_id").toString()); mock = general.headers(); writeToFile(mock.getResult()); From 0f4f45d05387437fb7e33d73548ba51ef78bac66 Mon Sep 17 00:00:00 2001 From: Jake Barnby Date: Tue, 18 Jun 2024 13:38:22 +1200 Subject: [PATCH 09/24] Fix outputs --- tests/languages/android/Tests.java | 88 ++++++++++++------------------ 1 file changed, 36 insertions(+), 52 deletions(-) diff --git a/tests/languages/android/Tests.java b/tests/languages/android/Tests.java index c3926a895..73ed1ee5b 100644 --- a/tests/languages/android/Tests.java +++ b/tests/languages/android/Tests.java @@ -95,68 +95,52 @@ public void test() throws IOException { return null; }); - runBlocking(new TestCoroutineScope(), () -> { - Mock mock; - // Foo Tests - mock = foo.get("string", 123, List.of("string in array")); - writeToFile(mock.getResult()); - mock = foo.post("string", 123, List.of("string in array")); - writeToFile(mock.getResult()); - mock = foo.put("string", 123, List.of("string in array")); - writeToFile(mock.getResult()); - mock = foo.patch("string", 123, List.of("string in array")); - writeToFile(mock.getResult()); - mock = foo.delete("string", 123, List.of("string in array")); - writeToFile(mock.getResult()); - - // Bar Tests - mock = bar.get("string", 123, List.of("string in array")); - writeToFile(mock.getResult()); - mock = bar.post("string", 123, List.of("string in array")); - writeToFile(mock.getResult()); - mock = bar.put("string", 123, List.of("string in array")); - writeToFile(mock.getResult()); - mock = bar.patch("string", 123, List.of("string in array")); - writeToFile(mock.getResult()); - mock = bar.delete("string", 123, List.of("string in array")); - writeToFile(mock.getResult()); - - // General Tests - Object result = general.redirect(); - writeToFile((String) ((Map) result).get("result")); + runBlocking(Dispatchers.getDefault(), (Continuation) continuation -> { + foo.get("string", 123, List.of("string in array"), new CoroutineCallback<>(this::writeMockResult)); + foo.post("string", 123, List.of("string in array"), new CoroutineCallback<>(this::writeMockResult)); + foo.put("string", 123, List.of("string in array"), new CoroutineCallback<>(this::writeMockResult)); + foo.patch("string", 123, List.of("string in array"), new CoroutineCallback<>(this::writeMockResult)); + foo.delete("string", 123, List.of("string in array"), new CoroutineCallback<>(this::writeMockResult)); + + bar.get("string", 123, List.of("string in array"), new CoroutineCallback<>(this::writeMockResult)); + bar.post("string", 123, List.of("string in array"), new CoroutineCallback<>(this::writeMockResult)); + bar.put("string", 123, List.of("string in array"), new CoroutineCallback<>(this::writeMockResult)); + bar.patch("string", 123, List.of("string in array"), new CoroutineCallback<>(this::writeMockResult)); + bar.delete("string", 123, List.of("string in array"), new CoroutineCallback<>(this::writeMockResult)); + + general.redirect(new CoroutineCallback<>((result, error) -> { + if (result != null) { + writeToFile(((Map) result).get("result").toString()); + } + })); try { - mock = general.upload("string", 123, List.of("string in array"), InputFile.fromPath("../../../resources/file.png")); - writeToFile(mock.getResult()); + general.upload("string", 123, List.of("string in array"), InputFile.fromPath("../../../resources/file.png"), new CoroutineCallback<>(this::writeMockResult)); } catch (Exception ex) { writeToFile(ex.toString()); } try { - mock = general.upload("string", 123, List.of("string in array"), InputFile.fromPath("../../../resources/large_file.mp4")); - writeToFile(mock.getResult()); + general.upload("string", 123, List.of("string in array"), InputFile.fromPath("../../../resources/large_file.mp4"), new CoroutineCallback<>(this::writeMockResult)); } catch (Exception ex) { writeToFile(ex.toString()); } try { byte[] bytes = Files.readAllBytes(Paths.get("../../../resources/file.png")); - mock = general.upload("string", 123, List.of("string in array"), InputFile.fromBytes(bytes, "file.png", "image/png")); - writeToFile(mock.getResult()); + general.upload("string", 123, List.of("string in array"), InputFile.fromBytes(bytes, "file.png", "image/png"), new CoroutineCallback<>(this::writeMockResult)); } catch (Exception ex) { writeToFile(ex.toString()); } try { byte[] bytes = Files.readAllBytes(Paths.get("../../../resources/large_file.mp4")); - mock = general.upload("string", 123, List.of("string in array"), InputFile.fromBytes(bytes, "large_file.mp4", "video/mp4")); - writeToFile(mock.getResult()); + general.upload("string", 123, List.of("string in array"), InputFile.fromBytes(bytes, "large_file.mp4", "video/mp4"), new CoroutineCallback<>(this::writeMockResult)); } catch (Exception ex) { writeToFile(ex.toString()); } - mock = general.enum(MockType.FIRST); - writeToFile(mock.getResult()); + general.enum(MockType.FIRST, new CoroutineCallback<>(this::writeMockResult)); try { general.error400(); @@ -176,18 +160,8 @@ public void test() throws IOException { writeToFile(e.getMessage()); } - delay(5000); - writeToFile(realtimeResponse); - - // mock = general.setCookie(); - // writeToFile(mock.getResult()); - - // mock = general.getCookie(); - // writeToFile(mock.getResult()); - general.empty(); - // Query helper tests writeToFile(Query.Companion.equal("released", List.of(true)).toString()); writeToFile(Query.Companion.equal("title", List.of("Spiderman", "Dr. Strange")).toString()); writeToFile(Query.Companion.notEqual("title", "Spiderman").toString()); @@ -227,13 +201,23 @@ public void test() throws IOException { writeToFile(ID.Companion.unique().toString()); writeToFile(ID.Companion.custom("custom_id").toString()); - mock = general.headers(); - writeToFile(mock.getResult()); + general.headers(new CoroutineCallback<>(this::writeMockResult)); - return null; + delay(5000, continuation); + writeToFile(realtimeResponse[0]); + + return Unit.INSTANCE; }); } + private void writeMockResult(Mock result, Throwable error) { + if (result != null) { + writeToFile(result.getResult()); + } else { + writeToFile(error.toString()); + } + } + private void writeToFile(String string) { String text = (string != null ? string : "") + "\n"; try { From 0a1b2418692276dcd64306c4445cf51e81abb156 Mon Sep 17 00:00:00 2001 From: Jake Barnby Date: Tue, 18 Jun 2024 13:38:44 +1200 Subject: [PATCH 10/24] Add new test to workflow --- .github/workflows/tests.yml | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 31171c845..956e395f7 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -12,10 +12,12 @@ jobs: strategy: fail-fast: false matrix: - php-version: ['8.2'] + php-version: ['8.3'] sdk: [ - Android5Java17, - Android14Java17, + Android5Java17Kotlin, + Android14Java8Kotlin, + Android14Java17Kotlin, + Android14Java17Java CLINode16, CLINode18, DartBeta, From 5f83fb97d1c1bd6d586fb94932b3070b58974ceb Mon Sep 17 00:00:00 2001 From: Jake Barnby Date: Tue, 18 Jun 2024 15:07:36 +1200 Subject: [PATCH 11/24] Fix access modifier --- .../android/library/src/main/java/io/package/Client.kt.twig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/templates/android/library/src/main/java/io/package/Client.kt.twig b/templates/android/library/src/main/java/io/package/Client.kt.twig index 1352b2bc1..def2d3131 100644 --- a/templates/android/library/src/main/java/io/package/Client.kt.twig +++ b/templates/android/library/src/main/java/io/package/Client.kt.twig @@ -51,7 +51,7 @@ class Client(context: Context) : CoroutineScope { _endpoint = value } - private var endpointRealtime: String? = null + internal var endpointRealtime: String? = null private var selfSigned: Boolean = false From ba081c262e83490554362b1833023cab9610e813 Mon Sep 17 00:00:00 2001 From: Jake Barnby Date: Tue, 18 Jun 2024 15:07:46 +1200 Subject: [PATCH 12/24] Fix name --- templates/kotlin/src/main/kotlin/io/appwrite/Client.kt.twig | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/templates/kotlin/src/main/kotlin/io/appwrite/Client.kt.twig b/templates/kotlin/src/main/kotlin/io/appwrite/Client.kt.twig index a7b92d2ef..00b50acd0 100644 --- a/templates/kotlin/src/main/kotlin/io/appwrite/Client.kt.twig +++ b/templates/kotlin/src/main/kotlin/io/appwrite/Client.kt.twig @@ -158,8 +158,8 @@ class Client: CoroutineScope { * * @return this */ - fun setEndpoint(endPoint: String): Client { - this.endPoint = endPoint + fun setEndpoint(endpoint: String): Client { + this.endpoint = endpoint return this } @@ -199,7 +199,7 @@ class Client: CoroutineScope { .addAll(headers.toHeaders()) .build() - val httpBuilder = (endPoint + path).toHttpUrl().newBuilder() + val httpBuilder = (endpoint + path).toHttpUrl().newBuilder() if ("GET" == method) { filteredParams.forEach { From 3df1fed432e1293f428e65ab92e2b7328d70d4eb Mon Sep 17 00:00:00 2001 From: Jake Barnby Date: Tue, 18 Jun 2024 15:37:35 +1200 Subject: [PATCH 13/24] Fix default endpoint --- .../android/library/src/main/java/io/package/Client.kt.twig | 2 +- templates/kotlin/src/main/kotlin/io/appwrite/Client.kt.twig | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/templates/android/library/src/main/java/io/package/Client.kt.twig b/templates/android/library/src/main/java/io/package/Client.kt.twig index def2d3131..2256db2d2 100644 --- a/templates/android/library/src/main/java/io/package/Client.kt.twig +++ b/templates/android/library/src/main/java/io/package/Client.kt.twig @@ -44,7 +44,7 @@ class Client(context: Context) : CoroutineScope { internal const val COOKIE_PREFS = "myCookie" } - private var _endpoint: String = "" + private var _endpoint: String = "{{spec.endpoint}}" var endpoint: String get() = _endpoint private set(value) { diff --git a/templates/kotlin/src/main/kotlin/io/appwrite/Client.kt.twig b/templates/kotlin/src/main/kotlin/io/appwrite/Client.kt.twig index 00b50acd0..aedf4ac97 100644 --- a/templates/kotlin/src/main/kotlin/io/appwrite/Client.kt.twig +++ b/templates/kotlin/src/main/kotlin/io/appwrite/Client.kt.twig @@ -37,7 +37,7 @@ class Client: CoroutineScope { const val CHUNK_SIZE = 5*1024*1024; // 5MB } - private var _endpoint: String = "" + private var _endpoint: String = "{{spec.endpoint}}" var endpoint: String get() = _endpoint private set(value) { From 2bd3eb222de50d548ec4dabdf3d5858e85835372 Mon Sep 17 00:00:00 2001 From: Jake Barnby Date: Tue, 18 Jun 2024 16:34:05 +1200 Subject: [PATCH 14/24] Workflow fixes --- .github/workflows/tests.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 956e395f7..5c3ea1b4b 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -15,9 +15,8 @@ jobs: php-version: ['8.3'] sdk: [ Android5Java17Kotlin, - Android14Java8Kotlin, Android14Java17Kotlin, - Android14Java17Java + Android14Java17Java, CLINode16, CLINode18, DartBeta, From 11065226dc7a7a8d700c32a1efcb75c09dc58749 Mon Sep 17 00:00:00 2001 From: Jake Barnby Date: Tue, 18 Jun 2024 17:44:24 +1200 Subject: [PATCH 15/24] Fix kotlin java method name escape --- .../library/src/main/java/io/package/services/Service.kt.twig | 2 +- .../main/kotlin/io/appwrite/services/ServiceTemplate.kt.twig | 2 +- tests/languages/android/Tests.java | 2 +- tests/languages/android/Tests.kt | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/templates/android/library/src/main/java/io/package/services/Service.kt.twig b/templates/android/library/src/main/java/io/package/services/Service.kt.twig index 05de594d6..dd54b515e 100644 --- a/templates/android/library/src/main/java/io/package/services/Service.kt.twig +++ b/templates/android/library/src/main/java/io/package/services/Service.kt.twig @@ -43,7 +43,7 @@ class {{ service.name | caseUcfirst }}(client: Client) : Service(client) { {%~ if method.parameters.all | reduce((carry, param) => carry or not param.required) %} @JvmOverloads {%~ endif %} - suspend fun {% if method.responseModel | hasGenericType(spec) %}{{ '' | raw }} {% endif %}{{ method.name | caseCamel }}( + suspend fun {% if method.responseModel | hasGenericType(spec) %}{{ '' | raw }} {% endif %}{{ method.name | caseCamel | escapeKeyword }}( {%~ if method.type == "webAuth" %} activity: ComponentActivity, {%~ endif %} diff --git a/templates/kotlin/src/main/kotlin/io/appwrite/services/ServiceTemplate.kt.twig b/templates/kotlin/src/main/kotlin/io/appwrite/services/ServiceTemplate.kt.twig index c5add5d0f..e274fcf95 100644 --- a/templates/kotlin/src/main/kotlin/io/appwrite/services/ServiceTemplate.kt.twig +++ b/templates/kotlin/src/main/kotlin/io/appwrite/services/ServiceTemplate.kt.twig @@ -36,7 +36,7 @@ class {{ service.name | caseUcfirst }}(client: Client) : Service(client) { @JvmOverloads {%~ endif %} @Throws({{ spec.title | caseUcfirst }}Exception::class) - suspend fun {% if method.responseModel | hasGenericType(spec) %}{{ '' | raw }} {% endif %}{{ method.name | caseCamel }}( + suspend fun {% if method.responseModel | hasGenericType(spec) %}{{ '' | raw }} {% endif %}{{ method.name | caseCamel | escapeKeyword }}( {%~ for parameter in method.parameters.all %} {{ parameter.name | caseCamel }}: {{ parameter | typeName }}{%~ if not parameter.required or parameter.nullable %}? = null{% endif %}, {%~ endfor %} diff --git a/tests/languages/android/Tests.java b/tests/languages/android/Tests.java index 73ed1ee5b..0bc41d98b 100644 --- a/tests/languages/android/Tests.java +++ b/tests/languages/android/Tests.java @@ -140,7 +140,7 @@ public void test() throws IOException { writeToFile(ex.toString()); } - general.enum(MockType.FIRST, new CoroutineCallback<>(this::writeMockResult)); + general.xenum(MockType.FIRST, new CoroutineCallback<>(this::writeMockResult)); try { general.error400(); diff --git a/tests/languages/android/Tests.kt b/tests/languages/android/Tests.kt index e98ce59d1..7537c982b 100644 --- a/tests/languages/android/Tests.kt +++ b/tests/languages/android/Tests.kt @@ -135,7 +135,7 @@ class ServiceTest { writeToFile(ex.toString()) } - mock = general.enum(MockType.FIRST) + mock = general.xenum(MockType.FIRST) writeToFile(mock.result) try { From f040bdc344b9c144124705cec05f82b7b18f7fc2 Mon Sep 17 00:00:00 2001 From: Jake Barnby Date: Wed, 19 Jun 2024 16:23:02 +1200 Subject: [PATCH 16/24] Package updates --- templates/android/library/build.gradle.twig | 22 ++++++++++----------- templates/kotlin/build.gradle.twig | 8 ++------ 2 files changed, 13 insertions(+), 17 deletions(-) diff --git a/templates/android/library/build.gradle.twig b/templates/android/library/build.gradle.twig index 9be37d280..bbda3b3f2 100644 --- a/templates/android/library/build.gradle.twig +++ b/templates/android/library/build.gradle.twig @@ -56,25 +56,25 @@ android { dependencies { implementation("org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version") - api("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.7.1") - api("org.jetbrains.kotlinx:kotlinx-coroutines-android:1.7.1") + api("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.8.1") + api("org.jetbrains.kotlinx:kotlinx-coroutines-android:1.8.1") implementation("com.squareup.okhttp3:okhttp:4.12.0") implementation("com.google.code.gson:gson:2.10.1") - implementation("androidx.lifecycle:lifecycle-runtime-ktx:2.7.0") - implementation("androidx.lifecycle:lifecycle-common-java8:2.7.0") - implementation("androidx.appcompat:appcompat:1.6.1") - implementation("androidx.fragment:fragment-ktx:1.6.2") - implementation("androidx.activity:activity-ktx:1.8.2") - implementation("androidx.browser:browser:1.7.0") - implementation("androidx.core:core-ktx:1.12.0") + implementation("androidx.lifecycle:lifecycle-runtime-ktx:2.8.2") + implementation("androidx.lifecycle:lifecycle-common-java8:2.8.2") + implementation("androidx.appcompat:appcompat:1.7.0") + implementation("androidx.fragment:fragment-ktx:1.8.0") + implementation("androidx.activity:activity-ktx:1.9.0") + implementation("androidx.browser:browser:1.8.0") + implementation("androidx.core:core-ktx:1.13.1") testImplementation("junit:junit:4.13.2") testImplementation("androidx.test.ext:junit-ktx:1.1.5") testImplementation("androidx.test:core-ktx:1.5.0") - testImplementation("org.robolectric:robolectric:4.11.1") - testApi("org.jetbrains.kotlinx:kotlinx-coroutines-test:1.7.1") + testImplementation("org.robolectric:robolectric:4.12") + testImplementation("org.jetbrains.kotlinx:kotlinx-coroutines-test:1.8.1") } apply from: "${rootProject.projectDir}/scripts/publish-module.gradle" diff --git a/templates/kotlin/build.gradle.twig b/templates/kotlin/build.gradle.twig index b5feaed62..b078e1730 100644 --- a/templates/kotlin/build.gradle.twig +++ b/templates/kotlin/build.gradle.twig @@ -29,13 +29,9 @@ repositories { } dependencies { - api("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.7.1") + api("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.8.1") - api(platform("com.squareup.okhttp3:okhttp-bom:4.12.0")) - api("com.squareup.okhttp3:okhttp") - - implementation("com.squareup.okhttp3:okhttp-urlconnection") - implementation("com.squareup.okhttp3:logging-interceptor") + implementation("com.squareup.okhttp3:okhttp:4.12.0") implementation("com.google.code.gson:gson:2.9.0") testImplementation("org.jetbrains.kotlin:kotlin-test-junit") From bf66c923f76deb96736ed32c889129c6c42930b6 Mon Sep 17 00:00:00 2001 From: Jake Barnby Date: Wed, 19 Jun 2024 16:23:37 +1200 Subject: [PATCH 17/24] Add @JvmStatic to object methods to allow avoiding `.Companion.` in Java calls --- .../src/main/java/io/package/ID.kt.twig | 36 ++-- .../main/java/io/package/Permission.kt.twig | 55 ++++-- .../src/main/java/io/package/Query.kt.twig | 159 ++++++++++++++++++ .../src/main/java/io/package/Role.kt.twig | 7 + .../src/main/kotlin/io/appwrite/ID.kt.twig | 39 +++-- .../kotlin/io/appwrite/Permission.kt.twig | 55 ++++-- .../src/main/kotlin/io/appwrite/Query.kt.twig | 159 ++++++++++++++++++ .../src/main/kotlin/io/appwrite/Role.kt.twig | 7 + 8 files changed, 458 insertions(+), 59 deletions(-) diff --git a/templates/android/library/src/main/java/io/package/ID.kt.twig b/templates/android/library/src/main/java/io/package/ID.kt.twig index c0411d090..14c3c67c8 100644 --- a/templates/android/library/src/main/java/io/package/ID.kt.twig +++ b/templates/android/library/src/main/java/io/package/ID.kt.twig @@ -1,32 +1,40 @@ package {{ sdk.namespace | caseDot }} -import java.time.Instant -import kotlin.math.floor import kotlin.random.Random class ID { companion object { - // Generate an hex ID based on timestamp - // Recreated from https://www.php.net/manual/en/function.uniqid.php + /** + * Generate a unique ID based on timestamp + */ private fun hexTimestamp(): String { - val now = Instant.now() - val sec = now.epochSecond + val now = System.currentTimeMillis() / 1000 val usec = (System.nanoTime() / 1000) % 1000 - - val hexTimestamp = "%08x%05x".format(sec, usec) + val hexTimestamp = "%08x%05x".format(now, usec) return hexTimestamp } - fun custom(id: String): String - = id + /** + * Generate a custom ID + * + * @param id The custom ID + */ + @JvmStatic + fun custom(id: String) = id - // Generate a unique ID with padding to have a longer ID + /** + * Generate a unique ID with padding to have a longer ID + * + * @param padding The length of the padding + */ + @JvmStatic fun unique(padding: Int = 7): String { val baseId = hexTimestamp() - val randomPadding = (1..padding) - .map { Random.nextInt(0, 16).toString(16) } - .joinToString("") + + val randomPadding = (1..padding).joinToString("") { + Random.nextInt(0, 16).toString(16) + } return baseId + randomPadding } diff --git a/templates/android/library/src/main/java/io/package/Permission.kt.twig b/templates/android/library/src/main/java/io/package/Permission.kt.twig index 33e5b741c..c50d31981 100644 --- a/templates/android/library/src/main/java/io/package/Permission.kt.twig +++ b/templates/android/library/src/main/java/io/package/Permission.kt.twig @@ -2,20 +2,45 @@ package {{ sdk.namespace | caseDot }} class Permission { companion object { - fun read(role: String): String { - return "read(\"${role}\")" - } - fun write(role: String): String { - return "write(\"${role}\")" - } - fun create(role: String): String { - return "create(\"${role}\")" - } - fun update(role: String): String { - return "update(\"${role}\")" - } - fun delete(role: String): String { - return "delete(\"${role}\")" - } + + /** + * Create a read permission string for the given role + * + * @param role The role to create the permission for + */ + @JvmStatic + fun read(role: String)= "read(\"${role}\")" + + /** + * Create a write permission string for the given role + * + * @param role The role to create the permission for + */ + @JvmStatic + fun write(role: String) = "write(\"${role}\")" + + /** + * Create a create permission string for the given role + * + * @param role The role to create the permission for + */ + @JvmStatic + fun create(role: String) = "create(\"${role}\")" + + /** + * Create a update permission string for the given role + * + * @param role The role to create the permission for + */ + @JvmStatic + fun update(role: String) = "update(\"${role}\")" + + /** + * Create a delete permission string for the given role + * + * @param role The role to create the permission for + */ + @JvmStatic + fun delete(role: String) = "delete(\"${role}\")" } } \ No newline at end of file diff --git a/templates/android/library/src/main/java/io/package/Query.kt.twig b/templates/android/library/src/main/java/io/package/Query.kt.twig index d83ff3c7d..b8800f109 100644 --- a/templates/android/library/src/main/java/io/package/Query.kt.twig +++ b/templates/android/library/src/main/java/io/package/Query.kt.twig @@ -4,55 +4,214 @@ import {{ sdk.namespace | caseDot }}.extensions.toJson import {{ sdk.namespace | caseDot }}.extensions.fromJson class Query( + /** + * Query method + */ val method: String, + + /** + * The attribute the query is targeting + */ val attribute: String? = null, + + /** + * The values to check against + */ val values: List? = null, ) { override fun toString() = this.toJson() companion object { + + /** + * Create a new query to check if the attribute is equal to any of the values + * + * @param attribute The attribute to check + * @param value The value or values to check against + */ + @JvmStatic fun equal(attribute: String, value: Any) = Query("equal", attribute, parseValue(value)).toJson() + /** + * Create a new query to check if the attribute is not equal to the value + * + * @param attribute The attribute to check + * @param value The value to check against + */ + @JvmStatic fun notEqual(attribute: String, value: Any) = Query("notEqual", attribute, parseValue(value)).toJson() + /** + * Create a new query to check if the attribute is less than the value + * + * @param attribute The attribute to check + * @param value The value to check against + */ + @JvmStatic fun lessThan(attribute: String, value: Any) = Query("lessThan", attribute, parseValue(value)).toJson() + /** + * Create a new query to check if the attribute is less than or equal to the value + * + * @param attribute The attribute to check + * @param value The value to check against + */ + @JvmStatic fun lessThanEqual(attribute: String, value: Any) = Query("lessThanEqual", attribute, parseValue(value)).toJson() + /** + * Create a new query to check if the attribute is greater than the value + * + * @param attribute The attribute to check + * @param value The value to check against + */ + @JvmStatic fun greaterThan(attribute: String, value: Any) = Query("greaterThan", attribute, parseValue(value)).toJson() + /** + * Create a new query to check if the attribute is greater than or equal to the value + * + * @param attribute The attribute to check + * @param value The value to check against + */ + @JvmStatic fun greaterThanEqual(attribute: String, value: Any) = Query("greaterThanEqual", attribute, parseValue(value)).toJson() + /** + * Create a new query to check if the attribute contains part of the value, ignoring case + * + * @param attribute The attribute to check + * @param value The value to check against + */ + @JvmStatic fun search(attribute: String, value: String) = Query("search", attribute, listOf(value)).toJson() + /** + * Create a new query to check if the attribute is null + * + * @param attribute The attribute to check + */ + @JvmStatic fun isNull(attribute: String) = Query("isNull", attribute).toJson() + /** + * Create a new query to check if the attribute is not null + * + * @param attribute The attribute to check + */ + @JvmStatic fun isNotNull(attribute: String) = Query("isNotNull", attribute).toJson() + /** + * Create a new query to check if the attribute is between the start and end values + * + * @param attribute The attribute to check + * @param start The start value + * @param end The end value + */ + @JvmStatic fun between(attribute: String, start: Any, end: Any) = Query("between", attribute, listOf(start, end)).toJson() + /** + * Create a new query to check if the attribute starts with the value + * + * @param attribute The attribute to check + * @param value The value to check against + */ + @JvmStatic fun startsWith(attribute: String, value: String) = Query("startsWith", attribute, listOf(value)).toJson() + /** + * Create a new query to check if the attribute ends with the value + * + * @param attribute The attribute to check + * @param value The value to check against + */ + @JvmStatic fun endsWith(attribute: String, value: String) = Query("endsWith", attribute, listOf(value)).toJson() + /** + * Create a new query to fetch only the provided attributes + * + * @param attributes The attributes to fetch + */ + @JvmStatic fun select(attributes: List) = Query("select", null, attributes).toJson() + /** + * Create a new query to order the results in ascending order + * + * @param attribute The attribute to order by + */ + @JvmStatic fun orderAsc(attribute: String) = Query("orderAsc", attribute).toJson() + /** + * Create a new query to order the results in descending order + * + * @param attribute The attribute to order by + */ + @JvmStatic fun orderDesc(attribute: String) = Query("orderDesc", attribute).toJson() + /** + * Create a new query to fetch documents before the provided document ID + * + * @param documentId The document ID to fetch before + */ + @JvmStatic fun cursorBefore(documentId: String) = Query("cursorBefore", null, listOf(documentId)).toJson() + /** + * Create a new query to fetch documents after the provided document ID + * + * @param documentId The document ID to fetch after + */ + @JvmStatic fun cursorAfter(documentId: String) = Query("cursorAfter", null, listOf(documentId)).toJson() + /** + * Create a new query to limit the number of results + * + * @param limit The number of results to limit to + */ + @JvmStatic fun limit(limit: Int) = Query("limit", null, listOf(limit)).toJson() + /** + * Create a new query to offset the results + * + * @param offset The number of results to offset by + */ + @JvmStatic fun offset(offset: Int) = Query("offset", null, listOf(offset)).toJson() + /** + * Create a new query to check if the attribute contains the value. + * + * If the attribute is an array, this will check if the array contains the exact value. + * If the attribute is a string, this will check if the string contains the value. + * + * @param attribute The attribute to check + * @param value The value to check against + */ + @JvmStatic fun contains(attribute: String, value: Any) = Query("contains", attribute, parseValue(value)).toJson() + /** + * Create a new query that groups multiple queries together using OR logic + * + * @param queries The queries to group + */ + @JvmStatic fun or(queries: List) = Query("or", null, queries.map { it.fromJson() }).toJson() + /** + * Create a new query that groups multiple queries together using AND logic + * + * @param queries The queries to group + */ + @JvmStatic fun and(queries: List) = Query("and", null, queries.map { it.fromJson() }).toJson() private fun parseValue(value: Any): List { diff --git a/templates/android/library/src/main/java/io/package/Role.kt.twig b/templates/android/library/src/main/java/io/package/Role.kt.twig index 2e4de9861..c2bab1c9f 100644 --- a/templates/android/library/src/main/java/io/package/Role.kt.twig +++ b/templates/android/library/src/main/java/io/package/Role.kt.twig @@ -11,6 +11,7 @@ class Role { * * This includes authenticated and unauthenticated users. */ + @JvmStatic fun any(): String = "any" /** @@ -19,6 +20,7 @@ class Role { * You can optionally pass verified or unverified for * [status] to target specific types of users. */ + @JvmStatic fun user(id: String, status: String = ""): String = if(status.isEmpty()) { "user:$id" } else { @@ -31,6 +33,7 @@ class Role { * You can optionally pass verified or unverified for * [status] to target specific types of users. */ + @JvmStatic fun users(status: String = ""): String = if(status.isEmpty()) { "users" } else { @@ -42,6 +45,7 @@ class Role { * * Authenticated users don't have access to this role. */ + @JvmStatic fun guests(): String = "guests" /** @@ -50,6 +54,7 @@ class Role { * You can optionally pass a role for [role] to target * team members with the specified role. */ + @JvmStatic fun team(id: String, role: String = ""): String = if(role.isEmpty()) { "team:$id" } else { @@ -62,11 +67,13 @@ class Role { * When the member is removed from the team, they will * no longer have access. */ + @JvmStatic fun member(id: String): String = "member:$id" /** * Grants access to a user with the specified label. */ + @JvmStatic fun label(name: String): String = "label:$name" } } \ No newline at end of file diff --git a/templates/kotlin/src/main/kotlin/io/appwrite/ID.kt.twig b/templates/kotlin/src/main/kotlin/io/appwrite/ID.kt.twig index a9b59a825..14c3c67c8 100644 --- a/templates/kotlin/src/main/kotlin/io/appwrite/ID.kt.twig +++ b/templates/kotlin/src/main/kotlin/io/appwrite/ID.kt.twig @@ -1,31 +1,40 @@ package {{ sdk.namespace | caseDot }} -import java.time.Instant -import kotlin.math.floor import kotlin.random.Random class ID { companion object { - // Generate an hex ID based on timestamp - // Recreated from https://www.php.net/manual/en/function.uniqid.php + /** + * Generate a unique ID based on timestamp + */ private fun hexTimestamp(): String { - val now = Instant.now() - val sec = now.epochSecond + val now = System.currentTimeMillis() / 1000 val usec = (System.nanoTime() / 1000) % 1000 - - val hexTimestamp = "%08x%05x".format(sec, usec) + val hexTimestamp = "%08x%05x".format(now, usec) return hexTimestamp } - fun custom(id: String): String - = id - // Generate a unique ID with padding to have a longer ID + /** + * Generate a custom ID + * + * @param id The custom ID + */ + @JvmStatic + fun custom(id: String) = id + + /** + * Generate a unique ID with padding to have a longer ID + * + * @param padding The length of the padding + */ + @JvmStatic fun unique(padding: Int = 7): String { - val baseId = ID.hexTimestamp() - val randomPadding = (1..padding) - .map { Random.nextInt(0, 16).toString(16) } - .joinToString("") + val baseId = hexTimestamp() + + val randomPadding = (1..padding).joinToString("") { + Random.nextInt(0, 16).toString(16) + } return baseId + randomPadding } diff --git a/templates/kotlin/src/main/kotlin/io/appwrite/Permission.kt.twig b/templates/kotlin/src/main/kotlin/io/appwrite/Permission.kt.twig index 33e5b741c..c50d31981 100644 --- a/templates/kotlin/src/main/kotlin/io/appwrite/Permission.kt.twig +++ b/templates/kotlin/src/main/kotlin/io/appwrite/Permission.kt.twig @@ -2,20 +2,45 @@ package {{ sdk.namespace | caseDot }} class Permission { companion object { - fun read(role: String): String { - return "read(\"${role}\")" - } - fun write(role: String): String { - return "write(\"${role}\")" - } - fun create(role: String): String { - return "create(\"${role}\")" - } - fun update(role: String): String { - return "update(\"${role}\")" - } - fun delete(role: String): String { - return "delete(\"${role}\")" - } + + /** + * Create a read permission string for the given role + * + * @param role The role to create the permission for + */ + @JvmStatic + fun read(role: String)= "read(\"${role}\")" + + /** + * Create a write permission string for the given role + * + * @param role The role to create the permission for + */ + @JvmStatic + fun write(role: String) = "write(\"${role}\")" + + /** + * Create a create permission string for the given role + * + * @param role The role to create the permission for + */ + @JvmStatic + fun create(role: String) = "create(\"${role}\")" + + /** + * Create a update permission string for the given role + * + * @param role The role to create the permission for + */ + @JvmStatic + fun update(role: String) = "update(\"${role}\")" + + /** + * Create a delete permission string for the given role + * + * @param role The role to create the permission for + */ + @JvmStatic + fun delete(role: String) = "delete(\"${role}\")" } } \ No newline at end of file diff --git a/templates/kotlin/src/main/kotlin/io/appwrite/Query.kt.twig b/templates/kotlin/src/main/kotlin/io/appwrite/Query.kt.twig index d83ff3c7d..b8800f109 100644 --- a/templates/kotlin/src/main/kotlin/io/appwrite/Query.kt.twig +++ b/templates/kotlin/src/main/kotlin/io/appwrite/Query.kt.twig @@ -4,55 +4,214 @@ import {{ sdk.namespace | caseDot }}.extensions.toJson import {{ sdk.namespace | caseDot }}.extensions.fromJson class Query( + /** + * Query method + */ val method: String, + + /** + * The attribute the query is targeting + */ val attribute: String? = null, + + /** + * The values to check against + */ val values: List? = null, ) { override fun toString() = this.toJson() companion object { + + /** + * Create a new query to check if the attribute is equal to any of the values + * + * @param attribute The attribute to check + * @param value The value or values to check against + */ + @JvmStatic fun equal(attribute: String, value: Any) = Query("equal", attribute, parseValue(value)).toJson() + /** + * Create a new query to check if the attribute is not equal to the value + * + * @param attribute The attribute to check + * @param value The value to check against + */ + @JvmStatic fun notEqual(attribute: String, value: Any) = Query("notEqual", attribute, parseValue(value)).toJson() + /** + * Create a new query to check if the attribute is less than the value + * + * @param attribute The attribute to check + * @param value The value to check against + */ + @JvmStatic fun lessThan(attribute: String, value: Any) = Query("lessThan", attribute, parseValue(value)).toJson() + /** + * Create a new query to check if the attribute is less than or equal to the value + * + * @param attribute The attribute to check + * @param value The value to check against + */ + @JvmStatic fun lessThanEqual(attribute: String, value: Any) = Query("lessThanEqual", attribute, parseValue(value)).toJson() + /** + * Create a new query to check if the attribute is greater than the value + * + * @param attribute The attribute to check + * @param value The value to check against + */ + @JvmStatic fun greaterThan(attribute: String, value: Any) = Query("greaterThan", attribute, parseValue(value)).toJson() + /** + * Create a new query to check if the attribute is greater than or equal to the value + * + * @param attribute The attribute to check + * @param value The value to check against + */ + @JvmStatic fun greaterThanEqual(attribute: String, value: Any) = Query("greaterThanEqual", attribute, parseValue(value)).toJson() + /** + * Create a new query to check if the attribute contains part of the value, ignoring case + * + * @param attribute The attribute to check + * @param value The value to check against + */ + @JvmStatic fun search(attribute: String, value: String) = Query("search", attribute, listOf(value)).toJson() + /** + * Create a new query to check if the attribute is null + * + * @param attribute The attribute to check + */ + @JvmStatic fun isNull(attribute: String) = Query("isNull", attribute).toJson() + /** + * Create a new query to check if the attribute is not null + * + * @param attribute The attribute to check + */ + @JvmStatic fun isNotNull(attribute: String) = Query("isNotNull", attribute).toJson() + /** + * Create a new query to check if the attribute is between the start and end values + * + * @param attribute The attribute to check + * @param start The start value + * @param end The end value + */ + @JvmStatic fun between(attribute: String, start: Any, end: Any) = Query("between", attribute, listOf(start, end)).toJson() + /** + * Create a new query to check if the attribute starts with the value + * + * @param attribute The attribute to check + * @param value The value to check against + */ + @JvmStatic fun startsWith(attribute: String, value: String) = Query("startsWith", attribute, listOf(value)).toJson() + /** + * Create a new query to check if the attribute ends with the value + * + * @param attribute The attribute to check + * @param value The value to check against + */ + @JvmStatic fun endsWith(attribute: String, value: String) = Query("endsWith", attribute, listOf(value)).toJson() + /** + * Create a new query to fetch only the provided attributes + * + * @param attributes The attributes to fetch + */ + @JvmStatic fun select(attributes: List) = Query("select", null, attributes).toJson() + /** + * Create a new query to order the results in ascending order + * + * @param attribute The attribute to order by + */ + @JvmStatic fun orderAsc(attribute: String) = Query("orderAsc", attribute).toJson() + /** + * Create a new query to order the results in descending order + * + * @param attribute The attribute to order by + */ + @JvmStatic fun orderDesc(attribute: String) = Query("orderDesc", attribute).toJson() + /** + * Create a new query to fetch documents before the provided document ID + * + * @param documentId The document ID to fetch before + */ + @JvmStatic fun cursorBefore(documentId: String) = Query("cursorBefore", null, listOf(documentId)).toJson() + /** + * Create a new query to fetch documents after the provided document ID + * + * @param documentId The document ID to fetch after + */ + @JvmStatic fun cursorAfter(documentId: String) = Query("cursorAfter", null, listOf(documentId)).toJson() + /** + * Create a new query to limit the number of results + * + * @param limit The number of results to limit to + */ + @JvmStatic fun limit(limit: Int) = Query("limit", null, listOf(limit)).toJson() + /** + * Create a new query to offset the results + * + * @param offset The number of results to offset by + */ + @JvmStatic fun offset(offset: Int) = Query("offset", null, listOf(offset)).toJson() + /** + * Create a new query to check if the attribute contains the value. + * + * If the attribute is an array, this will check if the array contains the exact value. + * If the attribute is a string, this will check if the string contains the value. + * + * @param attribute The attribute to check + * @param value The value to check against + */ + @JvmStatic fun contains(attribute: String, value: Any) = Query("contains", attribute, parseValue(value)).toJson() + /** + * Create a new query that groups multiple queries together using OR logic + * + * @param queries The queries to group + */ + @JvmStatic fun or(queries: List) = Query("or", null, queries.map { it.fromJson() }).toJson() + /** + * Create a new query that groups multiple queries together using AND logic + * + * @param queries The queries to group + */ + @JvmStatic fun and(queries: List) = Query("and", null, queries.map { it.fromJson() }).toJson() private fun parseValue(value: Any): List { diff --git a/templates/kotlin/src/main/kotlin/io/appwrite/Role.kt.twig b/templates/kotlin/src/main/kotlin/io/appwrite/Role.kt.twig index 2e4de9861..c2bab1c9f 100644 --- a/templates/kotlin/src/main/kotlin/io/appwrite/Role.kt.twig +++ b/templates/kotlin/src/main/kotlin/io/appwrite/Role.kt.twig @@ -11,6 +11,7 @@ class Role { * * This includes authenticated and unauthenticated users. */ + @JvmStatic fun any(): String = "any" /** @@ -19,6 +20,7 @@ class Role { * You can optionally pass verified or unverified for * [status] to target specific types of users. */ + @JvmStatic fun user(id: String, status: String = ""): String = if(status.isEmpty()) { "user:$id" } else { @@ -31,6 +33,7 @@ class Role { * You can optionally pass verified or unverified for * [status] to target specific types of users. */ + @JvmStatic fun users(status: String = ""): String = if(status.isEmpty()) { "users" } else { @@ -42,6 +45,7 @@ class Role { * * Authenticated users don't have access to this role. */ + @JvmStatic fun guests(): String = "guests" /** @@ -50,6 +54,7 @@ class Role { * You can optionally pass a role for [role] to target * team members with the specified role. */ + @JvmStatic fun team(id: String, role: String = ""): String = if(role.isEmpty()) { "team:$id" } else { @@ -62,11 +67,13 @@ class Role { * When the member is removed from the team, they will * no longer have access. */ + @JvmStatic fun member(id: String): String = "member:$id" /** * Grants access to a user with the specified label. */ + @JvmStatic fun label(name: String): String = "label:$name" } } \ No newline at end of file From 6a27ab96faecb46d2b667c867b09297d5eaf2521 Mon Sep 17 00:00:00 2001 From: Jake Barnby Date: Wed, 19 Jun 2024 18:47:58 +1200 Subject: [PATCH 18/24] Fix missing JvmStatic --- .../java/io/package/models/InputFile.kt.twig | 23 +++++++++++++++++++ .../io/appwrite/models/InputFile.kt.twig | 20 ++++++++++++++++ .../appwrite/services/ServiceTemplate.kt.twig | 1 - 3 files changed, 43 insertions(+), 1 deletion(-) diff --git a/templates/android/library/src/main/java/io/package/models/InputFile.kt.twig b/templates/android/library/src/main/java/io/package/models/InputFile.kt.twig index 382267a0d..a18224d76 100644 --- a/templates/android/library/src/main/java/io/package/models/InputFile.kt.twig +++ b/templates/android/library/src/main/java/io/package/models/InputFile.kt.twig @@ -1,5 +1,7 @@ package {{ sdk.namespace | caseDot }}.models +import android.os.Build +import androidx.annotation.RequiresApi import java.io.File import java.net.URLConnection import java.nio.file.Files @@ -14,6 +16,13 @@ class InputFile private constructor() { lateinit var data: Any companion object { + /** + * Create a new InputFile from a file + * + * @param file The file to create the InputFile from + */ + @JvmStatic + @RequiresApi(Build.VERSION_CODES.O) fun fromFile(file: File) = InputFile().apply { path = file.canonicalPath filename = file.name @@ -23,10 +32,24 @@ class InputFile private constructor() { sourceType = "file" } + /** + * Create a new InputFile from a file path + * + * @param path The path to the file to create the InputFile from + */ + @JvmStatic fun fromPath(path: String): InputFile = fromFile(File(path)).apply { sourceType = "path" } + /** + * Create a new InputFile from a byte array + * + * @param bytes The byte array to create the InputFile from + * @param filename The filename of the file + * @param mimeType The mime type of the file + */ + @JvmStatic fun fromBytes(bytes: ByteArray, filename: String = "", mimeType: String = "") = InputFile().apply { this.filename = filename this.mimeType = mimeType diff --git a/templates/kotlin/src/main/kotlin/io/appwrite/models/InputFile.kt.twig b/templates/kotlin/src/main/kotlin/io/appwrite/models/InputFile.kt.twig index 382267a0d..5d9d5951d 100644 --- a/templates/kotlin/src/main/kotlin/io/appwrite/models/InputFile.kt.twig +++ b/templates/kotlin/src/main/kotlin/io/appwrite/models/InputFile.kt.twig @@ -14,6 +14,12 @@ class InputFile private constructor() { lateinit var data: Any companion object { + /** + * Create a new InputFile from a file + * + * @param file The file to create the InputFile from + */ + @JvmStatic fun fromFile(file: File) = InputFile().apply { path = file.canonicalPath filename = file.name @@ -23,10 +29,24 @@ class InputFile private constructor() { sourceType = "file" } + /** + * Create a new InputFile from a file path + * + * @param path The path to the file to create the InputFile from + */ + @JvmStatic fun fromPath(path: String): InputFile = fromFile(File(path)).apply { sourceType = "path" } + /** + * Create a new InputFile from a byte array + * + * @param bytes The byte array to create the InputFile from + * @param filename The filename of the file + * @param mimeType The mime type of the file + */ + @JvmStatic fun fromBytes(bytes: ByteArray, filename: String = "", mimeType: String = "") = InputFile().apply { this.filename = filename this.mimeType = mimeType diff --git a/templates/kotlin/src/main/kotlin/io/appwrite/services/ServiceTemplate.kt.twig b/templates/kotlin/src/main/kotlin/io/appwrite/services/ServiceTemplate.kt.twig index e274fcf95..1b80c2781 100644 --- a/templates/kotlin/src/main/kotlin/io/appwrite/services/ServiceTemplate.kt.twig +++ b/templates/kotlin/src/main/kotlin/io/appwrite/services/ServiceTemplate.kt.twig @@ -35,7 +35,6 @@ class {{ service.name | caseUcfirst }}(client: Client) : Service(client) { {%~ if method.parameters.all | reduce((carry, param) => carry or not param.required) %} @JvmOverloads {%~ endif %} - @Throws({{ spec.title | caseUcfirst }}Exception::class) suspend fun {% if method.responseModel | hasGenericType(spec) %}{{ '' | raw }} {% endif %}{{ method.name | caseCamel | escapeKeyword }}( {%~ for parameter in method.parameters.all %} {{ parameter.name | caseCamel }}: {{ parameter | typeName }}{%~ if not parameter.required or parameter.nullable %}? = null{% endif %}, From bb8dd99d6a81fdb72e3984bebf82852559ddc05f Mon Sep 17 00:00:00 2001 From: Jake Barnby Date: Wed, 19 Jun 2024 18:48:25 +1200 Subject: [PATCH 19/24] Add JvmOverloads to helpers --- templates/android/library/src/main/java/io/package/ID.kt.twig | 1 + .../android/library/src/main/java/io/package/Role.kt.twig | 3 +++ templates/kotlin/src/main/kotlin/io/appwrite/ID.kt.twig | 1 + templates/kotlin/src/main/kotlin/io/appwrite/Role.kt.twig | 3 +++ 4 files changed, 8 insertions(+) diff --git a/templates/android/library/src/main/java/io/package/ID.kt.twig b/templates/android/library/src/main/java/io/package/ID.kt.twig index 14c3c67c8..0970235e8 100644 --- a/templates/android/library/src/main/java/io/package/ID.kt.twig +++ b/templates/android/library/src/main/java/io/package/ID.kt.twig @@ -29,6 +29,7 @@ class ID { * @param padding The length of the padding */ @JvmStatic + @JvmOverloads fun unique(padding: Int = 7): String { val baseId = hexTimestamp() diff --git a/templates/android/library/src/main/java/io/package/Role.kt.twig b/templates/android/library/src/main/java/io/package/Role.kt.twig index c2bab1c9f..b1e4af27c 100644 --- a/templates/android/library/src/main/java/io/package/Role.kt.twig +++ b/templates/android/library/src/main/java/io/package/Role.kt.twig @@ -21,6 +21,7 @@ class Role { * [status] to target specific types of users. */ @JvmStatic + @JvmOverloads fun user(id: String, status: String = ""): String = if(status.isEmpty()) { "user:$id" } else { @@ -34,6 +35,7 @@ class Role { * [status] to target specific types of users. */ @JvmStatic + @JvmOverloads fun users(status: String = ""): String = if(status.isEmpty()) { "users" } else { @@ -55,6 +57,7 @@ class Role { * team members with the specified role. */ @JvmStatic + @JvmOverloads fun team(id: String, role: String = ""): String = if(role.isEmpty()) { "team:$id" } else { diff --git a/templates/kotlin/src/main/kotlin/io/appwrite/ID.kt.twig b/templates/kotlin/src/main/kotlin/io/appwrite/ID.kt.twig index 14c3c67c8..0970235e8 100644 --- a/templates/kotlin/src/main/kotlin/io/appwrite/ID.kt.twig +++ b/templates/kotlin/src/main/kotlin/io/appwrite/ID.kt.twig @@ -29,6 +29,7 @@ class ID { * @param padding The length of the padding */ @JvmStatic + @JvmOverloads fun unique(padding: Int = 7): String { val baseId = hexTimestamp() diff --git a/templates/kotlin/src/main/kotlin/io/appwrite/Role.kt.twig b/templates/kotlin/src/main/kotlin/io/appwrite/Role.kt.twig index c2bab1c9f..b1e4af27c 100644 --- a/templates/kotlin/src/main/kotlin/io/appwrite/Role.kt.twig +++ b/templates/kotlin/src/main/kotlin/io/appwrite/Role.kt.twig @@ -21,6 +21,7 @@ class Role { * [status] to target specific types of users. */ @JvmStatic + @JvmOverloads fun user(id: String, status: String = ""): String = if(status.isEmpty()) { "user:$id" } else { @@ -34,6 +35,7 @@ class Role { * [status] to target specific types of users. */ @JvmStatic + @JvmOverloads fun users(status: String = ""): String = if(status.isEmpty()) { "users" } else { @@ -55,6 +57,7 @@ class Role { * team members with the specified role. */ @JvmStatic + @JvmOverloads fun team(id: String, role: String = ""): String = if(role.isEmpty()) { "team:$id" } else { From b31c603850e2f7bf18a46dc74bdb0afe323cdef6 Mon Sep 17 00:00:00 2001 From: Jake Barnby Date: Wed, 19 Jun 2024 18:48:38 +1200 Subject: [PATCH 20/24] Update tests --- tests/languages/android/ServiceTest.java | 224 ++++++++++++++++++++++ tests/languages/android/Tests.java | 233 ----------------------- 2 files changed, 224 insertions(+), 233 deletions(-) create mode 100644 tests/languages/android/ServiceTest.java delete mode 100644 tests/languages/android/Tests.java diff --git a/tests/languages/android/ServiceTest.java b/tests/languages/android/ServiceTest.java new file mode 100644 index 000000000..3a2cb3e73 --- /dev/null +++ b/tests/languages/android/ServiceTest.java @@ -0,0 +1,224 @@ +package io.appwrite; + +import static io.appwrite.CoroutineTestUtils.resetTestMainDispatcher; +import static io.appwrite.CoroutineTestUtils.scopeFor; +import static io.appwrite.CoroutineTestUtils.setTestMainDispatcher; +import static kotlinx.coroutines.DelayKt.delay; + +import androidx.test.core.app.ApplicationProvider; +import androidx.test.ext.junit.runners.AndroidJUnit4; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.robolectric.annotation.Config; + +import java.io.IOException; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.Paths; +import java.nio.file.StandardOpenOption; +import java.util.Arrays; +import java.util.Collections; +import java.util.Map; + +import io.appwrite.coroutines.CoroutineCallback; +import io.appwrite.enums.MockType; +import io.appwrite.models.Error; +import io.appwrite.models.InputFile; +import io.appwrite.models.Mock; +import io.appwrite.services.Bar; +import io.appwrite.services.Foo; +import io.appwrite.services.General; +import io.appwrite.services.Realtime; +import kotlin.Unit; +import kotlinx.coroutines.ExperimentalCoroutinesApi; +import kotlinx.coroutines.test.TestScope; + +class TestPayload { + private String response; + + public String getResponse() { + return response; + } + + public void setResponse(String response) { + this.response = response; + } +} + +@Config(manifest = Config.NONE) +@RunWith(AndroidJUnit4.class) +public class ServiceTest { + private TestScope testScope; + + private final String filename = "result.txt"; + + @Before + @ExperimentalCoroutinesApi + public void setUp() throws IOException { + testScope = scopeFor(setTestMainDispatcher()); + Files.deleteIfExists(Paths.get(filename)); + writeToFile("Test Started"); + } + + @After + @ExperimentalCoroutinesApi + public void tearDown() { + resetTestMainDispatcher(); + } + + @Test + public void test() throws IOException { + Client client = new Client(ApplicationProvider.getApplicationContext()) + .setEndpointRealtime("wss://demo.appwrite.io/v1") + .setProject("console") + .addHeader("Origin", "http://localhost") + .setSelfSigned(true); + + Foo foo = new Foo(client); + Bar bar = new Bar(client); + General general = new General(client); + Realtime realtime = new Realtime(client); + String[] realtimeResponse = {"Realtime failed!"}; + + realtime.subscribe(new String[]{"tests"}, TestPayload.class, payload -> { + realtimeResponse[0] = payload.getPayload().getResponse(); + return Unit.INSTANCE; + }); + + CoroutineTestUtils.runTest(testScope, continuation -> { + foo.get("string", 123, Collections.singletonList("string in array"), new CoroutineCallback<>(this::writeMockResult)); + foo.post("string", 123, Collections.singletonList("string in array"), new CoroutineCallback<>(this::writeMockResult)); + foo.put("string", 123, Collections.singletonList("string in array"), new CoroutineCallback<>(this::writeMockResult)); + foo.patch("string", 123, Collections.singletonList("string in array"), new CoroutineCallback<>(this::writeMockResult)); + foo.delete("string", 123, Collections.singletonList("string in array"), new CoroutineCallback<>(this::writeMockResult)); + + bar.get("string", 123, Collections.singletonList("string in array"), new CoroutineCallback<>(this::writeMockResult)); + bar.post("string", 123, Collections.singletonList("string in array"), new CoroutineCallback<>(this::writeMockResult)); + bar.put("string", 123, Collections.singletonList("string in array"), new CoroutineCallback<>(this::writeMockResult)); + bar.patch("string", 123, Collections.singletonList("string in array"), new CoroutineCallback<>(this::writeMockResult)); + bar.delete("string", 123, Collections.singletonList("string in array"), new CoroutineCallback<>(this::writeMockResult)); + + general.redirect(new CoroutineCallback<>((result, error) -> { + if (result != null) { + writeToFile(((Map) result).get("result").toString()); + } + })); + + general.upload("string", 123, Collections.singletonList("string in array"), InputFile.fromPath("../../../resources/file.png"), null, new CoroutineCallback<>(this::writeMockResult)); + general.upload("string", 123, Collections.singletonList("string in array"), InputFile.fromPath("../../../resources/large_file.mp4"), null, new CoroutineCallback<>(this::writeMockResult)); + + byte[] bytes; + try { + bytes = Files.readAllBytes(Paths.get("../../../resources/file.png")); + } catch (IOException e) { + throw new RuntimeException(e); + } + general.upload("string", 123, Collections.singletonList("string in array"), InputFile.fromBytes(bytes, "file.png", "image/png"), null, new CoroutineCallback<>(this::writeMockResult)); + + try { + bytes = Files.readAllBytes(Paths.get("../../../resources/large_file.mp4")); + } catch (IOException e) { + throw new RuntimeException(e); + } + general.upload("string", 123, Collections.singletonList("string in array"), InputFile.fromBytes(bytes, "large_file.mp4", "video/mp4"), null, new CoroutineCallback<>(this::writeMockResult)); + + general.xenum(MockType.FIRST, new CoroutineCallback<>(this::writeMockResult)); + + general.error400(new CoroutineCallback<>(this::writeErrorResult)); + general.error500(new CoroutineCallback<>(this::writeErrorResult)); + general.error502(new CoroutineCallback<>(this::writeObjectResult)); + + general.empty(new CoroutineCallback<>((result, error) -> { + // No-op + })); + + writeToFile(Query.equal("released", Collections.singletonList(true))); + writeToFile(Query.equal("title", Arrays.asList("Spiderman", "Dr. Strange"))); + writeToFile(Query.notEqual("title", "Spiderman")); + writeToFile(Query.lessThan("releasedYear", 1990)); + writeToFile(Query.greaterThan("releasedYear", 1990)); + writeToFile(Query.search("name", "john")); + writeToFile(Query.isNull("name")); + writeToFile(Query.isNotNull("name")); + writeToFile(Query.between("age", 50, 100)); + writeToFile(Query.between("age", 50.5, 100.5)); + writeToFile(Query.between("name", "Anna", "Brad")); + writeToFile(Query.startsWith("name", "Ann")); + writeToFile(Query.endsWith("name", "nne")); + writeToFile(Query.select(Arrays.asList("name", "age"))); + writeToFile(Query.orderAsc("title")); + writeToFile(Query.orderDesc("title")); + writeToFile(Query.cursorAfter("my_movie_id")); + writeToFile(Query.cursorBefore("my_movie_id")); + writeToFile(Query.limit(50)); + writeToFile(Query.offset(20)); + writeToFile(Query.contains("title", Collections.singletonList("Spider"))); + writeToFile(Query.contains("labels", Collections.singletonList("first"))); + writeToFile(Query.or(Arrays.asList(Query.equal("released", Collections.singletonList(true)), Query.lessThan("releasedYear", 1990)))); + writeToFile(Query.and(Arrays.asList(Query.equal("released", Collections.singletonList(false)), Query.greaterThan("releasedYear", 2015)))); + + writeToFile(Permission.read(Role.any())); + writeToFile(Permission.write(Role.user(ID.custom("userid")))); + writeToFile(Permission.create(Role.users())); + writeToFile(Permission.update(Role.guests())); + writeToFile(Permission.delete(Role.team("teamId", "owner"))); + writeToFile(Permission.delete(Role.team("teamId"))); + writeToFile(Permission.create(Role.member("memberId"))); + writeToFile(Permission.update(Role.users("verified"))); + writeToFile(Permission.update(Role.user(ID.custom("userid"), "unverified"))); + writeToFile(Permission.create(Role.label("admin"))); + + writeToFile(ID.unique()); + writeToFile(ID.custom("custom_id")); + + general.headers(new CoroutineCallback<>(this::writeMockResult)); + + delay(5000, new CoroutineCallback<>((result, error) -> { + writeToFile(realtimeResponse[0]); + continuation.resumeWith(Unit.INSTANCE); + })); + + return null; + }); + } + + private void writeMockResult(Mock result, Throwable error) { + if (result != null) { + writeToFile(result.getResult()); + } else { + writeToFile(error.toString()); + } + } + + private void writeErrorResult(Error result, Throwable error) { + if (result != null) { + writeToFile(result.getMessage()); + } else { + writeToFile(error.getMessage()); + } + } + + private void writeObjectResult(Object result, Throwable error) { + if (result != null) { + writeToFile(result.toString()); + } else { + writeToFile(error.getMessage()); + } + } + + private void writeToFile(String string) { + String text = (string != null ? string : "") + "\n"; + try { + Files.write( + Paths.get(filename), + text.getBytes(StandardCharsets.UTF_8), + StandardOpenOption.APPEND + ); + } catch (IOException e) { + e.printStackTrace(); + } + } +} diff --git a/tests/languages/android/Tests.java b/tests/languages/android/Tests.java deleted file mode 100644 index 0bc41d98b..000000000 --- a/tests/languages/android/Tests.java +++ /dev/null @@ -1,233 +0,0 @@ -package io.appwrite; - -import androidx.test.core.app.ApplicationProvider; -import androidx.test.ext.junit.runners.AndroidJUnit4; - -import io.appwrite.coroutines.CoroutineCallback; -import io.appwrite.exceptions.AppwriteException; -import io.appwrite.Permission; -import io.appwrite.Role; -import io.appwrite.ID; -import io.appwrite.Query; -import io.appwrite.enums.MockType; -import io.appwrite.models.InputFile; -import io.appwrite.models.Mock; -import io.appwrite.services.Bar; -import io.appwrite.services.Foo; -import io.appwrite.services.General; -import io.appwrite.services.Realtime; - -import kotlinx.coroutines.Dispatchers; -import kotlinx.coroutines.ExperimentalCoroutinesApi; -import kotlinx.coroutines.delay; -import kotlinx.coroutines.runBlocking; -import kotlinx.coroutines.test.TestCoroutineDispatcher; -import kotlinx.coroutines.test.TestCoroutineScope; - -import org.junit.After; -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.robolectric.annotation.Config; - -import java.io.File; -import java.io.IOException; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.Paths; -import java.nio.file.StandardOpenOption; -import java.util.List; -import java.util.Map; - -import kotlin.coroutines.Continuation; -import kotlin.coroutines.CoroutineContext; -import kotlin.coroutines.Result; -import kotlin.jvm.JvmOverloads; - -class TestPayload { - private String response; - - public String getResponse() { - return response; - } - - public void setResponse(String response) { - this.response = response; - } -} - -@Config(manifest = Config.NONE) -@RunWith(AndroidJUnit4.class) -public class ServiceTest { - - private final String filename = "result.txt"; - - @Before - @ExperimentalCoroutinesApi - public void setUp() throws IOException { - Dispatchers.setMain(new TestCoroutineDispatcher()); - Files.deleteIfExists(Paths.get(filename)); - writeToFile("Test Started"); - } - - @After - @ExperimentalCoroutinesApi - public void tearDown() { - Dispatchers.resetMain(); - } - - @Test - public void test() throws IOException { - Client client = new Client(ApplicationProvider.getApplicationContext()) - .setEndpointRealtime("wss://demo.appwrite.io/v1") - .setProject("console") - .addHeader("Origin", "http://localhost") - .setSelfSigned(true); - - Foo foo = new Foo(client); - Bar bar = new Bar(client); - General general = new General(client); - Realtime realtime = new Realtime(client); - String[] realtimeResponse = {"Realtime failed!"}; - - realtime.subscribe("tests", TestPayload.class, payload -> { - realtimeResponse[0] = payload.getResponse(); - return null; - }); - - runBlocking(Dispatchers.getDefault(), (Continuation) continuation -> { - foo.get("string", 123, List.of("string in array"), new CoroutineCallback<>(this::writeMockResult)); - foo.post("string", 123, List.of("string in array"), new CoroutineCallback<>(this::writeMockResult)); - foo.put("string", 123, List.of("string in array"), new CoroutineCallback<>(this::writeMockResult)); - foo.patch("string", 123, List.of("string in array"), new CoroutineCallback<>(this::writeMockResult)); - foo.delete("string", 123, List.of("string in array"), new CoroutineCallback<>(this::writeMockResult)); - - bar.get("string", 123, List.of("string in array"), new CoroutineCallback<>(this::writeMockResult)); - bar.post("string", 123, List.of("string in array"), new CoroutineCallback<>(this::writeMockResult)); - bar.put("string", 123, List.of("string in array"), new CoroutineCallback<>(this::writeMockResult)); - bar.patch("string", 123, List.of("string in array"), new CoroutineCallback<>(this::writeMockResult)); - bar.delete("string", 123, List.of("string in array"), new CoroutineCallback<>(this::writeMockResult)); - - general.redirect(new CoroutineCallback<>((result, error) -> { - if (result != null) { - writeToFile(((Map) result).get("result").toString()); - } - })); - - try { - general.upload("string", 123, List.of("string in array"), InputFile.fromPath("../../../resources/file.png"), new CoroutineCallback<>(this::writeMockResult)); - } catch (Exception ex) { - writeToFile(ex.toString()); - } - - try { - general.upload("string", 123, List.of("string in array"), InputFile.fromPath("../../../resources/large_file.mp4"), new CoroutineCallback<>(this::writeMockResult)); - } catch (Exception ex) { - writeToFile(ex.toString()); - } - - try { - byte[] bytes = Files.readAllBytes(Paths.get("../../../resources/file.png")); - general.upload("string", 123, List.of("string in array"), InputFile.fromBytes(bytes, "file.png", "image/png"), new CoroutineCallback<>(this::writeMockResult)); - } catch (Exception ex) { - writeToFile(ex.toString()); - } - - try { - byte[] bytes = Files.readAllBytes(Paths.get("../../../resources/large_file.mp4")); - general.upload("string", 123, List.of("string in array"), InputFile.fromBytes(bytes, "large_file.mp4", "video/mp4"), new CoroutineCallback<>(this::writeMockResult)); - } catch (Exception ex) { - writeToFile(ex.toString()); - } - - general.xenum(MockType.FIRST, new CoroutineCallback<>(this::writeMockResult)); - - try { - general.error400(); - } catch (AppwriteException e) { - writeToFile(e.getMessage()); - } - - try { - general.error500(); - } catch (AppwriteException e) { - writeToFile(e.getMessage()); - } - - try { - general.error502(); - } catch (AppwriteException e) { - writeToFile(e.getMessage()); - } - - general.empty(); - - writeToFile(Query.Companion.equal("released", List.of(true)).toString()); - writeToFile(Query.Companion.equal("title", List.of("Spiderman", "Dr. Strange")).toString()); - writeToFile(Query.Companion.notEqual("title", "Spiderman").toString()); - writeToFile(Query.Companion.lessThan("releasedYear", 1990).toString()); - writeToFile(Query.Companion.greaterThan("releasedYear", 1990).toString()); - writeToFile(Query.Companion.search("name", "john").toString()); - writeToFile(Query.Companion.isNull("name").toString()); - writeToFile(Query.Companion.isNotNull("name").toString()); - writeToFile(Query.Companion.between("age", 50, 100).toString()); - writeToFile(Query.Companion.between("age", 50.5, 100.5).toString()); - writeToFile(Query.Companion.between("name", "Anna", "Brad").toString()); - writeToFile(Query.Companion.startsWith("name", "Ann").toString()); - writeToFile(Query.Companion.endsWith("name", "nne").toString()); - writeToFile(Query.Companion.select(List.of("name", "age")).toString()); - writeToFile(Query.Companion.orderAsc("title").toString()); - writeToFile(Query.Companion.orderDesc("title").toString()); - writeToFile(Query.Companion.cursorAfter("my_movie_id").toString()); - writeToFile(Query.Companion.cursorBefore("my_movie_id").toString()); - writeToFile(Query.Companion.limit(50).toString()); - writeToFile(Query.Companion.offset(20).toString()); - writeToFile(Query.Companion.contains("title", List.of("Spider")).toString()); - writeToFile(Query.Companion.contains("labels", List.of("first")).toString()); - writeToFile(Query.Companion.or(List.of(Query.Companion.equal("released", List.of(true)), Query.Companion.lessThan("releasedYear", 1990))).toString()); - writeToFile(Query.Companion.and(List.of(Query.Companion.equal("released", List.of(false)), Query.Companion.greaterThan("releasedYear", 2015))).toString()); - - writeToFile(Permission.Companion.read(Role.Companion.any()).toString()); - writeToFile(Permission.Companion.write(Role.Companion.user(ID.Companion.custom("userid"))).toString()); - writeToFile(Permission.Companion.create(Role.Companion.users()).toString()); - writeToFile(Permission.Companion.update(Role.Companion.guests()).toString()); - writeToFile(Permission.Companion.delete(Role.Companion.team("teamId", "owner")).toString()); - writeToFile(Permission.Companion.delete(Role.Companion.team("teamId")).toString()); - writeToFile(Permission.Companion.create(Role.Companion.member("memberId")).toString()); - writeToFile(Permission.Companion.update(Role.Companion.users("verified")).toString()); - writeToFile(Permission.Companion.update(Role.Companion.user(ID.Companion.custom("userid"), "unverified")).toString()); - writeToFile(Permission.Companion.create(Role.Companion.label("admin")).toString()); - - writeToFile(ID.Companion.unique().toString()); - writeToFile(ID.Companion.custom("custom_id").toString()); - - general.headers(new CoroutineCallback<>(this::writeMockResult)); - - delay(5000, continuation); - writeToFile(realtimeResponse[0]); - - return Unit.INSTANCE; - }); - } - - private void writeMockResult(Mock result, Throwable error) { - if (result != null) { - writeToFile(result.getResult()); - } else { - writeToFile(error.toString()); - } - } - - private void writeToFile(String string) { - String text = (string != null ? string : "") + "\n"; - try { - Files.writeString( - Paths.get(filename), - text, - StandardOpenOption.APPEND - ); - } catch (IOException e) { - e.printStackTrace(); - } - } -} From 004c0d3a66d61ac8e479a6f1247fe521e98b756e Mon Sep 17 00:00:00 2001 From: Jake Barnby Date: Wed, 19 Jun 2024 18:48:45 +1200 Subject: [PATCH 21/24] Add coroutine test helper --- .../languages/android/CoroutineTestHelper.kt | 36 +++++++++++++++++++ 1 file changed, 36 insertions(+) create mode 100644 tests/languages/android/CoroutineTestHelper.kt diff --git a/tests/languages/android/CoroutineTestHelper.kt b/tests/languages/android/CoroutineTestHelper.kt new file mode 100644 index 000000000..c1ac3bac3 --- /dev/null +++ b/tests/languages/android/CoroutineTestHelper.kt @@ -0,0 +1,36 @@ +package io.appwrite + + +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.ExperimentalCoroutinesApi +import kotlinx.coroutines.test.StandardTestDispatcher +import kotlinx.coroutines.test.TestDispatcher +import kotlinx.coroutines.test.TestScope +import kotlinx.coroutines.test.resetMain +import kotlinx.coroutines.test.runTest +import kotlinx.coroutines.test.setMain + +object CoroutineTestUtils { + + private lateinit var dispatcher: TestDispatcher + + @JvmStatic + @OptIn(ExperimentalCoroutinesApi::class) + fun setTestMainDispatcher(): TestDispatcher { + dispatcher = StandardTestDispatcher() + Dispatchers.setMain(dispatcher) + return dispatcher + } + + @JvmStatic + @OptIn(ExperimentalCoroutinesApi::class) + fun resetTestMainDispatcher() = Dispatchers.resetMain() + + @JvmStatic + fun scopeFor(dispatcher: TestDispatcher) = TestScope(dispatcher) + + @JvmStatic + fun runTest(scope: TestScope, block: suspend () -> Unit) { + scope.runTest { block() } + } +} From 4191bd6b5c44d68f367fa3debff76e14844617c2 Mon Sep 17 00:00:00 2001 From: Jake Barnby Date: Wed, 19 Jun 2024 18:48:54 +1200 Subject: [PATCH 22/24] Copy new files --- tests/Android14Java17JavaTest.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/Android14Java17JavaTest.php b/tests/Android14Java17JavaTest.php index c212bf3ad..2238435b2 100644 --- a/tests/Android14Java17JavaTest.php +++ b/tests/Android14Java17JavaTest.php @@ -13,7 +13,8 @@ class Android14Java17JavaTest extends Base protected string $class = 'Appwrite\SDK\Language\Android'; protected array $build = [ 'mkdir -p tests/sdks/android/library/src/test/java', - 'cp tests/languages/android/Tests.java tests/sdks/android/library/src/test/java/Tests.java', + 'cp tests/languages/android/ServiceTest.java tests/sdks/android/library/src/test/java/io/appwrite/ServiceTest.java', + 'cp tests/languages/android/CoroutineTestHelper.kt tests/sdks/android/library/src/test/java/io/appwrite/CoroutineTestHelper.kt', 'chmod +x tests/sdks/android/gradlew', ]; protected string $command = From 4c7fdb9a99197e2563c55f06547aa9ff964c1376 Mon Sep 17 00:00:00 2001 From: Jake Barnby Date: Wed, 19 Jun 2024 18:52:02 +1200 Subject: [PATCH 23/24] Fix invalid ref --- templates/kotlin/src/main/kotlin/io/appwrite/Client.kt.twig | 1 - 1 file changed, 1 deletion(-) diff --git a/templates/kotlin/src/main/kotlin/io/appwrite/Client.kt.twig b/templates/kotlin/src/main/kotlin/io/appwrite/Client.kt.twig index aedf4ac97..603b42334 100644 --- a/templates/kotlin/src/main/kotlin/io/appwrite/Client.kt.twig +++ b/templates/kotlin/src/main/kotlin/io/appwrite/Client.kt.twig @@ -15,7 +15,6 @@ import okhttp3.HttpUrl.Companion.toHttpUrl import okhttp3.MediaType.Companion.toMediaType import okhttp3.RequestBody.Companion.asRequestBody import okhttp3.RequestBody.Companion.toRequestBody -import okhttp3.logging.HttpLoggingInterceptor import java.io.BufferedInputStream import java.io.BufferedReader import java.io.File From 892fcf5a239f7379f3f8063000797ade95980d5e Mon Sep 17 00:00:00 2001 From: Jake Barnby Date: Wed, 19 Jun 2024 18:58:59 +1200 Subject: [PATCH 24/24] Fix enum method ref --- tests/languages/kotlin/Tests.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/languages/kotlin/Tests.kt b/tests/languages/kotlin/Tests.kt index 13044b210..ac68a7073 100644 --- a/tests/languages/kotlin/Tests.kt +++ b/tests/languages/kotlin/Tests.kt @@ -101,7 +101,7 @@ class ServiceTest { writeToFile(ex.toString()) } - mock = general.enum(MockType.FIRST) + mock = general.xenum(MockType.FIRST) writeToFile(mock.result) try {