From b583135a0bb3a8ab894482db62372173491fedc2 Mon Sep 17 00:00:00 2001 From: Sean N Date: Fri, 28 Nov 2025 22:12:00 +0200 Subject: [PATCH 1/3] Cleaning up the README file and formatting / linting the PHP code with PHP-CS-Fixer --- .gitignore | 1 + .php-cs-fixer.php | 22 +++ README.md | 161 +++++++++--------- ci/boot.php | 31 ++-- ci/check_filters_docs.php | 1 + ci/check_validators_docs.php | 1 + ci/check_validators_translations.php | 5 +- ci/coverage.php | 33 ++-- ci/dump_filters_docs.php | 15 +- ci/dump_validators_docs.php | 10 +- ci/generate_phpunit_config.php | 3 +- composer.json | 7 +- gump.class.php | 112 ++++++------ lang/de.php | 4 +- lang/el.php | 4 +- lang/en.php | 4 +- lang/eo.php | 4 +- lang/es.php | 4 +- lang/fa.php | 4 +- lang/fr.php | 6 +- lang/he.php | 4 +- lang/hu.php | 4 +- lang/id.php | 4 +- lang/it.php | 4 +- lang/ja.php | 4 +- lang/nl.php | 5 +- lang/pt-br.php | 4 +- lang/ru.php | 4 +- lang/tr.php | 4 +- lang/uk.php | 5 +- lang/vi.php | 4 +- lang/zh-CN.php | 4 +- src/ArrayHelpers.php | 2 +- src/EnvHelpers.php | 1 + tests/BaseTestCase.php | 17 +- tests/ConstructorTest.php | 5 +- tests/FilterTest.php | 116 ++++++------- tests/Filters/BasicTagsFilterTest.php | 8 +- tests/Filters/BooleanFilterTest.php | 12 +- tests/Filters/HtmlencodeFilterTest.php | 6 +- tests/Filters/LowercaseFilterTest.php | 8 +- tests/Filters/MsWordCharactersFilterTest.php | 6 +- tests/Filters/NoiseWordsFilterTest.php | 6 +- tests/Filters/RmpunctuationFilterTest.php | 6 +- tests/Filters/SanitizeEmailFilterTest.php | 6 +- tests/Filters/SanitizeFloatsFilterTest.php | 6 +- tests/Filters/SanitizeNumbersFilterTest.php | 4 +- tests/Filters/SanitizeStringFilterTest.php | 4 +- tests/Filters/SlugFilterTest.php | 6 +- tests/Filters/UpperCaseFilterTest.php | 26 ++- tests/Filters/UrlencodeFilterTest.php | 6 +- tests/Filters/WholeNumberFilterTest.php | 6 +- tests/GetErrorsArrayTest.php | 64 +++---- tests/GetReadableErrorsTest.php | 43 +++-- tests/Helpers/ArrayHelpersTest.php | 94 +++++----- tests/Integration/WorkflowTest.php | 72 ++++---- tests/RunTest.php | 81 +++++---- tests/SanitizeTest.php | 9 +- tests/StaticAddFilterTest.php | 8 +- tests/StaticAddValidatorTest.php | 8 +- tests/StaticFieldTest.php | 8 +- tests/StaticFilterInputTest.php | 7 +- tests/StaticHasFilterTest.php | 2 +- tests/StaticHasValidatorTest.php | 2 +- tests/StaticIsValidTest.php | 15 +- tests/StaticSetErrorMessagesTest.php | 23 ++- tests/StaticSetFieldNameTest.php | 9 +- tests/ValidateTest.php | 126 +++++++------- tests/Validators/AlphaDashValidatorTest.php | 6 +- .../AlphaNumericDashValidatorTest.php | 6 +- .../AlphaNumericSpaceValidatorTest.php | 6 +- .../Validators/AlphaNumericValidatorTest.php | 6 +- tests/Validators/AlphaSpaceValidatorTest.php | 6 +- tests/Validators/AlphaValidatorTest.php | 6 +- tests/Validators/BetweenLenValidatorTest.php | 4 +- tests/Validators/BooleanValidatorTest.php | 10 +- tests/Validators/CamelCaseValidatorTest.php | 16 +- .../Validators/ContainsListValidatorTest.php | 4 +- tests/Validators/ContainsValidatorTest.php | 4 +- tests/Validators/DateValidatorTest.php | 6 +- .../DoesntContainListValidatorTest.php | 4 +- tests/Validators/EqualsFieldValidatorTest.php | 12 +- tests/Validators/ExactLenValidatorTest.php | 7 +- tests/Validators/ExtensionValidatorTest.php | 12 +- tests/Validators/FloatValidatorTest.php | 10 +- tests/Validators/FutureDateValidatorTest.php | 24 +-- tests/Validators/Guidv4ValidatorTest.php | 6 +- tests/Validators/HexColorValidatorTest.php | 28 +-- tests/Validators/IbanValidatorTest.php | 6 +- tests/Validators/IntegerValidatorTest.php | 8 +- tests/Validators/JwtTokenValidatorTest.php | 20 +-- tests/Validators/LatitudeValidatorTest.php | 32 ++-- tests/Validators/MacAddressValidatorTest.php | 28 +-- tests/Validators/MaxLenValidatorTest.php | 7 +- tests/Validators/MaxNumericValidatorTest.php | 4 +- tests/Validators/MinAgeValidatorTest.php | 16 +- tests/Validators/MinLenValidatorTest.php | 7 +- tests/Validators/MinNumericValidatorTest.php | 6 +- tests/Validators/NumericValidatorTest.php | 6 +- tests/Validators/PhoneNumberValidatorTest.php | 8 +- tests/Validators/PrimeValidatorTest.php | 28 +-- tests/Validators/RegexValidatorTest.php | 16 +- .../Validators/RequiredFileValidatorTest.php | 12 +- tests/Validators/RequiredValidatorTest.php | 16 +- tests/Validators/StartsValidatorTest.php | 8 +- .../Validators/StreetAddressValidatorTest.php | 8 +- .../StrongPasswordValidatorTest.php | 28 +-- tests/Validators/UrlExistsValidatorTest.php | 11 +- tests/Validators/UuidValidatorTest.php | 28 +-- .../ValidArraySizeEqualValidatorTest.php | 6 +- .../ValidArraySizeGreaterValidatorTest.php | 28 ++- .../ValidArraySizeLesserValidatorTest.php | 6 +- tests/Validators/ValidCcValidatorTest.php | 9 +- tests/Validators/ValidEmailValidatorTest.php | 8 +- tests/Validators/ValidIpValidatorTest.php | 8 +- tests/Validators/ValidIpv4ValidatorTest.php | 8 +- tests/Validators/ValidIpv6ValidatorTest.php | 10 +- .../ValidJsonStringValidatorTest.php | 6 +- tests/Validators/ValidNameValidatorTest.php | 8 +- tests/Validators/ValidUrlValidatorTest.php | 10 +- tests/bootstrap.php | 1 + 121 files changed, 906 insertions(+), 998 deletions(-) create mode 100644 .php-cs-fixer.php diff --git a/.gitignore b/.gitignore index 55794ef3..3ff5c4cb 100644 --- a/.gitignore +++ b/.gitignore @@ -13,5 +13,6 @@ vendor coverage build .phpunit.result.cache +.php-cs-fixer.cache user.env composer.lock \ No newline at end of file diff --git a/.php-cs-fixer.php b/.php-cs-fixer.php new file mode 100644 index 00000000..30b26d8b --- /dev/null +++ b/.php-cs-fixer.php @@ -0,0 +1,22 @@ +in(__DIR__) + ->exclude('vendor') + ->exclude('dev') + ->name('*.php'); + +return (new PhpCsFixer\Config()) + ->setRules([ + '@PSR12' => true, + 'array_syntax' => ['syntax' => 'short'], + 'no_unused_imports' => true, + 'ordered_imports' => ['sort_algorithm' => 'alpha'], + 'single_quote' => true, + 'trailing_comma_in_multiline' => ['elements' => ['arrays']], + 'no_extra_blank_lines' => true, + 'no_whitespace_in_blank_line' => true, + 'blank_line_before_statement' => ['statements' => ['return']], + ]) + ->setFinder($finder) + ->setRiskyAllowed(false); diff --git a/README.md b/README.md index 017c445e..dfe2dd46 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@ [![Coverage Status](https://coveralls.io/repos/github/Wixel/GUMP/badge.svg?branch=master)](https://coveralls.io/github/Wixel/GUMP?branch=master) [![License](https://poser.pugx.org/wixel/gump/license)](https://packagist.org/packages/wixel/gump) -## 🚀 Overview +## Overview GUMP is a standalone PHP data validation and filtering library that makes validating any data easy and painless without the reliance on a framework. GUMP has been serving the PHP community since **2013** and is trusted by thousands of @@ -14,33 +14,32 @@ developers worldwide. ### Key Features -- **🔒 Zero Dependencies** - Pure PHP, no external dependencies required -- **🌍 19 Languages** - Built-in internationalization support -- **⚡ High Performance** - Lightweight and fast validation processing -- **🔧 Extensible** - Easy to add custom validators and filters -- **📋 76 Validators** - Comprehensive set of validation rules out of the box -- **🛡️ Security Focused** - Built-in XSS protection and data sanitization -- **🎯 Framework Agnostic** - Works with any PHP project or framework -- **📱 Modern PHP** - Supports PHP 7.1 to 8.4+ +- **Zero Dependencies** - Pure PHP, no external dependencies required +- **19 Languages** - Built-in internationalization support +- **High Performance** - Lightweight and fast validation processing +- **Extensible** - Easy to add custom validators and filters +- **76 Validators** - Comprehensive set of validation rules out of the box +- **Security Focused** - Built-in XSS protection and data sanitization +- **Framework Agnostic** - Works with any PHP project or framework +- **Modern PHP** - Supports PHP 7.1 to 8.4+ ## Table of Contents -- [Installation](#-installation) -- [Requirements](#-requirements) -- [Quick Start](#-quick-start) -- [Usage Examples](#-usage-examples) -- [Available Validators](#-available-validators) -- [Available Filters](#-available-filters) -- [Advanced Usage](#-advanced-usage) -- [Internationalization](#-internationalization) -- [Custom Validators & Filters](#-custom-validators--filters) -- [Configuration](#-configuration) -- [Testing](#-testing) -- [Contributing](#-contributing) -- [Security](#-security) -- [Changelog](#-changelog) -- [Support](#-support) -- [License](#-license) +- [Installation](#installation) +- [Requirements](#requirements) +- [Quick Start](#quick-start) +- [Usage Examples](#usage-examples) +- [Available Validators](#available-validators) +- [Available Filters](#available-filters) +- [Advanced Usage](#advanced-usage) +- [Internationalization](#internationalization) +- [Custom Validators & Filters](#custom-validators--filters) +- [Configuration](#configuration) +- [Testing](#testing) +- [Contributing](#contributing) +- [Security](#security) +- [Support](#support) +- [License](#license) ## Installation @@ -88,11 +87,11 @@ $is_valid = GUMP::is_valid([ ]); if ($is_valid === true) { - echo "✅ All data is valid!"; + echo "All data is valid!"; } else { // Display validation errors foreach ($is_valid as $error) { - echo "❌ " . $error . "\n"; + echo "Error: " . $error . "\n"; } } ``` @@ -446,23 +445,23 @@ $rules = [ ]; ``` -> **💡 Pro Tips**: +> **Pro Tips**: > > **Parameter Conflicts**: When using pipe (`|`) or semicolon (`;`) in validator parameters, use array format: > ```php -> // ❌ Wrong - will break parsing +> // Wrong - will break parsing > 'field' => 'regex,/part|of;pattern/' -> -> // ✅ Correct - use array format +> +> // Correct - use array format > 'field' => ['regex' => '/part|of;pattern/'] > ``` > > **Performance**: Put faster validators first in chains: > ```php -> // ✅ Good - required fails fast for empty values +> // Good - required fails fast for empty values > 'email' => 'required|valid_email|max_len,255' -> -> // ❌ Less efficient - validates email format on empty values +> +> // Less efficient - validates email format on empty values > 'email' => 'valid_email|required|max_len,255' > ``` > @@ -522,6 +521,42 @@ $filtered = GUMP::filter_input([ ## Advanced Usage +### Singleton Pattern + +GUMP supports a singleton pattern for cases where you want to reuse the same instance across your application: + +```php +// Get the singleton instance +$gump = GUMP::get_instance(); + +// Subsequent calls return the same instance +$sameGump = GUMP::get_instance(); + +// Both variables reference the same object +var_dump($gump === $sameGump); // true +``` + +### Field Helper Method + +The `field()` static method provides safe array access with a default fallback: + +```php +// Safely get a value from an array with a default +$username = GUMP::field('username', $_POST, 'guest'); + +// Returns 'guest' if 'username' key doesn't exist +$email = GUMP::field('email', $_POST); // Returns null if not set + +// Useful for optional form fields +$data = [ + 'name' => 'John', + 'age' => 25 +]; + +$name = GUMP::field('name', $data); // 'John' +$country = GUMP::field('country', $data, 'US'); // 'US' (default) +``` + ### Instance Methods ```php @@ -750,11 +785,11 @@ We welcome contributions! Please read our [Contributing Guidelines](CONTRIBUTING ### Areas We Need Help With -- 🌍 **Translations** - Help us support more languages -- 🧪 **Test Coverage** - Add more edge case tests -- 📚 **Documentation** - Improve examples and guides -- 🚀 **Performance** - Optimize validation algorithms -- 🛡️ **Security** - Security audits and improvements +- **Translations** - Help us support more languages +- **Test Coverage** - Add more edge case tests +- **Documentation** - Improve examples and guides +- **Performance** - Optimize validation algorithms +- **Security** - Security audits and improvements ## Security @@ -779,51 +814,9 @@ We welcome contributions! Please read our [Contributing Guidelines](CONTRIBUTING ### Community Support -- 🐛 **Bug Reports**: [GitHub Issues](https://github.com/wixel/gump/issues) -- 💡 **Feature Requests**: [GitHub Discussions](https://github.com/wixel/gump/discussions) -- 📚 **Documentation**: [GitHub Wiki](https://github.com/wixel/gump/wiki) - -## Statistics - -- ⭐ **GitHub Stars**: 1000+ -- 📦 **Downloads**: 1M+ via Packagist -- 🏭 **Production Use**: Thousands of projects -- 🌍 **Languages**: 19 supported languages -- ⚡ **Performance**: <1ms validation time for typical forms -- 🧪 **Test Coverage**: 100% - -## Why Choose GUMP? - -### ✅ Battle-Tested - -- **10+ years** in production -- **Trusted** by thousands of developers -- **Proven** in high-traffic applications - -### ⚡ Performance First - -- **Zero dependencies** - no bloat -- **Optimized algorithms** - fast validation -- **Memory efficient** - low resource usage - -### 🔒 Security Focused - -- **XSS protection** built-in -- **Regular security audits** -- **Secure defaults** everywhere - -### 🌍 Global Ready - -- **19 languages** supported -- **UTF-8 compatible** -- **Timezone aware** date validation - -### 🛠️ Developer Friendly - -- **Clean, simple API** -- **Excellent documentation** -- **Extensive examples** -- **Framework agnostic** +- **Bug Reports**: [GitHub Issues](https://github.com/wixel/gump/issues) +- **Feature Requests**: [GitHub Discussions](https://github.com/wixel/gump/discussions) +- **Documentation**: [GitHub Wiki](https://github.com/wixel/gump/wiki) ## License diff --git a/ci/boot.php b/ci/boot.php index 6d761312..98ec9843 100644 --- a/ci/boot.php +++ b/ci/boot.php @@ -1,4 +1,5 @@ getMethods(), function($method) { + $validators = array_filter($reflect->getMethods(), function ($method) { return strpos($method->name, VALIDATORS_PREFIX) !== false; }); @@ -22,7 +24,7 @@ function get_gump_validators() { $ruleExampleParameter = $docblock->getTag('example_parameter'); $item = [ - 'description' => $ruleDescription + 'description' => $ruleDescription, ]; if (!is_null($ruleExampleParameter)) { @@ -37,7 +39,8 @@ function get_gump_validators() { return $result; } -function get_docs_validators(string $readmePath) { +function get_docs_validators(string $readmePath) +{ $readmeContents = file_get_contents($readmePath); preg_match_all('/
(.*?)<.div>/ms', $readmeContents, $outerMatches); @@ -56,19 +59,20 @@ function get_docs_validators(string $readmePath) { $result[$ruleMatch[1]] = [ 'rule' => $rawRule, - 'description' => trim($matches[2][$key]) + 'description' => trim($matches[2][$key]), ]; } return $result; } -function get_gump_filters() { - $reflect = new ReflectionClass("GUMP"); +function get_gump_filters() +{ + $reflect = new ReflectionClass('GUMP'); $methodsToIgnore = ['filter_input', 'filter_rules', 'filter_to_method']; - $filters = array_filter($reflect->getMethods(), function($method) use($methodsToIgnore) { + $filters = array_filter($reflect->getMethods(), function ($method) use ($methodsToIgnore) { return strpos($method->name, FILTERS_PREFIX) === 0 && !in_array($method->name, $methodsToIgnore); }); @@ -81,7 +85,7 @@ function get_gump_filters() { $ruleExampleParameter = $docblock->getTag('example_parameter'); $item = [ - 'description' => $ruleDescription + 'description' => $ruleDescription, ]; if (!is_null($ruleExampleParameter)) { @@ -96,8 +100,8 @@ function get_gump_filters() { return $result; } - -function get_docs_filters(string $readmePath) { +function get_docs_filters(string $readmePath) +{ $readmeContents = file_get_contents($readmePath); preg_match_all('/
(.*?)<.div>/ms', $readmeContents, $outerMatches); @@ -116,10 +120,9 @@ function get_docs_filters(string $readmePath) { $result[$ruleMatch[1]] = [ 'rule' => $rawRule, - 'description' => trim($matches[2][$key]) + 'description' => trim($matches[2][$key]), ]; } return $result; } - diff --git a/ci/check_filters_docs.php b/ci/check_filters_docs.php index da9bc6e9..c5e3b45f 100644 --- a/ci/check_filters_docs.php +++ b/ci/check_filters_docs.php @@ -1,4 +1,5 @@ XML; - + file_put_contents('build/logs/clover.xml', $placeholderXml); - + echo "✅ Created placeholder coverage file for Coveralls compatibility\n"; echo "ℹ️ To enable real coverage, install xdebug or pcov extension\n"; } -echo "Coverage workflow completed successfully\n"; \ No newline at end of file +echo "Coverage workflow completed successfully\n"; diff --git a/ci/dump_filters_docs.php b/ci/dump_filters_docs.php index 5b318073..b0dc93e8 100644 --- a/ci/dump_filters_docs.php +++ b/ci/dump_filters_docs.php @@ -1,24 +1,24 @@ '**trim**', - 'description' => 'Remove spaces from the beginning and end of strings (PHP).' - ] + 'description' => 'Remove spaces from the beginning and end of strings (PHP).', + ], ]; -$rows = array_map(function($v) { +$rows = array_map(function ($v) { return [$v['rule'], $v['description']]; }, array_merge(get_gump_filters(), $extraRules)); - $tableBuilder = new \MaddHatter\MarkdownTable\Builder(); $tableBuilder - ->headers(['Filter','Description']) - ->align(['L','L']) - ->rows($rows); + ->headers(['Filter','Description']) + ->align(['L','L']) + ->rows($rows); $readme = file_get_contents(README_FILE); @@ -29,4 +29,3 @@ file_put_contents(README_FILE, $replaced); print('Filters docs updated!'.PHP_EOL); - diff --git a/ci/dump_validators_docs.php b/ci/dump_validators_docs.php index efe50837..4abfedbd 100644 --- a/ci/dump_validators_docs.php +++ b/ci/dump_validators_docs.php @@ -1,16 +1,17 @@ headers(['Rule','Description']) - ->align(['L','L']) - ->rows($rows); + ->headers(['Rule','Description']) + ->align(['L','L']) + ->rows($rows); $readme = file_get_contents(README_FILE); @@ -21,4 +22,3 @@ file_put_contents(README_FILE, $replaced); print('Validators docs updated!'.PHP_EOL); - diff --git a/ci/generate_phpunit_config.php b/ci/generate_phpunit_config.php index e5ade1e2..94101194 100644 --- a/ci/generate_phpunit_config.php +++ b/ci/generate_phpunit_config.php @@ -1,4 +1,5 @@ =7.1", @@ -39,6 +40,8 @@ "scripts": { "test": "php ./vendor/bin/phpunit", "dump": "php ./ci/dump_filters_docs.php && php ./ci/dump_validators_docs.php", - "check": "php ./ci/check_filters_docs.php && php ./ci/check_validators_docs.php && php ./ci/check_validators_translations.php" + "check": "php ./ci/check_filters_docs.php && php ./ci/check_validators_docs.php && php ./ci/check_validators_translations.php", + "lint": "php ./vendor/bin/php-cs-fixer fix --dry-run --diff", + "lint:fix": "php ./vendor/bin/php-cs-fixer fix" } } diff --git a/gump.class.php b/gump.class.php index 4299fe6b..9f1f740c 100644 --- a/gump.class.php +++ b/gump.class.php @@ -5,18 +5,18 @@ /** * GUMP - A Fast PHP Data Validation & Filtering Library - * - * GUMP is a standalone PHP data validation and filtering library that makes validating - * any data easy and painless without the reliance on a framework. Supports 41 validators, - * 15+ filters, internationalization (19 languages), and custom validators/filters. - * + * + * GUMP is a standalone PHP data validation and filtering library that makes validating + * any data easy and painless without the reliance on a framework. Supports 76 validators, + * 16 filters, internationalization (19 languages), and custom validators/filters. + * * @package GUMP * @version 1.x * @author Sean Nieuwoudt * @copyright 2013-2025 Sean Nieuwoudt * @license MIT * @link https://github.com/wixel/gump - * + * * @since 1.0 */ class GUMP @@ -106,14 +106,14 @@ public static function get_instance() /** * Basic HTML tags allowed in the basic_tags filter. - * + * * @var string */ public static $basic_tags = '


## Comprehensive Validator Reference @@ -448,6 +449,7 @@ $rules = [ > **Pro Tips**: > > **Parameter Conflicts**: When using pipe (`|`) or semicolon (`;`) in validator parameters, use array format: +> > ```php > // Wrong - will break parsing > 'field' => 'regex,/part|of;pattern/' @@ -457,6 +459,7 @@ $rules = [ > ``` > > **Performance**: Put faster validators first in chains: +> > ```php > // Good - required fails fast for empty values > 'email' => 'required|valid_email|max_len,255' @@ -466,6 +469,7 @@ $rules = [ > ``` > > **Boolean Values**: The `boolean` filter accepts various formats: +> > ```php > // All these become TRUE: '1', 1, 'true', true, 'yes', 'on' > // All these become FALSE: '0', 0, 'false', false, 'no', 'off', null, '' @@ -479,7 +483,7 @@ GUMP includes 16 filters for data sanitization and transformation: | Filter | Description | |------------------------|-----------------------------------------------------------------------------------------------------------------------| -| **noise_words** | Replace noise words in a string (http://tax.cchgroup.com/help/Avoiding_noise_words_in_your_search.htm). | +| **noise_words** | Replace noise words in a string (). | | **rmpunctuation** | Remove all known punctuation from a string. | | **urlencode** | Sanitize the string by urlencoding characters. | | **htmlencode** | Sanitize the string by converting HTML characters to their HTML entities. | @@ -495,6 +499,7 @@ GUMP includes 16 filters for data sanitization and transformation: | **upper_case** | Converts to uppercase. | | **slug** | Converts value to url-web-slugs. | | **trim** | Remove spaces from the beginning and end of strings. | +
### Filter Chaining Example @@ -791,6 +796,12 @@ We welcome contributions! Please read our [Contributing Guidelines](CONTRIBUTING - **Performance** - Optimize validation algorithms - **Security** - Security audits and improvements +### Contributors + + + + + ## Security ### Security Best Practices diff --git a/coverage.xml b/coverage.xml new file mode 100644 index 00000000..7362153e --- /dev/null +++ b/coverage.xml @@ -0,0 +1,640 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tests/Validators/Base64ValidatorTest.php b/tests/Validators/Base64ValidatorTest.php new file mode 100644 index 00000000..8e4913fc --- /dev/null +++ b/tests/Validators/Base64ValidatorTest.php @@ -0,0 +1,73 @@ +assertTrue(GUMP::is_valid([ + 'data' => 'SGVsbG8gV29ybGQ=', + ], [ + 'data' => 'base64', + ])); + } + + public function testSuccessWhenValidBase64WithPadding() + { + $this->assertTrue(GUMP::is_valid([ + 'data' => 'dGVzdA==', + ], [ + 'data' => 'base64', + ])); + } + + public function testSuccessWhenValidBase64NoPadding() + { + // Base64 without proper padding may not round-trip correctly + $this->assertTrue(GUMP::is_valid([ + 'data' => 'dGVzdGluZzE=', // "testing1" properly padded + ], [ + 'data' => 'base64', + ])); + } + + public function testSuccessWhenEmptyEncodesEmpty() + { + $this->assertTrue(GUMP::is_valid([ + 'data' => '', + ], [ + 'data' => 'base64', + ])); + } + + public function testErrorWhenInvalidBase64() + { + $this->assertNotSame(true, GUMP::is_valid([ + 'data' => 'invalid!!!', + ], [ + 'data' => 'base64', + ])); + } + + public function testErrorWhenInvalidCharacters() + { + $this->assertNotSame(true, GUMP::is_valid([ + 'data' => 'SGVsbG8@V29ybGQ=', + ], [ + 'data' => 'base64', + ])); + } + + public function testErrorWhenInvalidPadding() + { + $this->assertNotSame(true, GUMP::is_valid([ + 'data' => 'SGVsbG8gV29ybGQ===', + ], [ + 'data' => 'base64', + ])); + } +} diff --git a/tests/Validators/BusinessDayValidatorTest.php b/tests/Validators/BusinessDayValidatorTest.php new file mode 100644 index 00000000..396517af --- /dev/null +++ b/tests/Validators/BusinessDayValidatorTest.php @@ -0,0 +1,81 @@ +assertTrue(GUMP::is_valid([ + 'date' => '2024-01-08', // Monday + ], [ + 'date' => 'business_day', + ])); + } + + public function testSuccessWhenTuesday() + { + $this->assertTrue(GUMP::is_valid([ + 'date' => '2024-01-09', // Tuesday + ], [ + 'date' => 'business_day', + ])); + } + + public function testSuccessWhenWednesday() + { + $this->assertTrue(GUMP::is_valid([ + 'date' => '2024-01-10', // Wednesday + ], [ + 'date' => 'business_day', + ])); + } + + public function testSuccessWhenThursday() + { + $this->assertTrue(GUMP::is_valid([ + 'date' => '2024-01-11', // Thursday + ], [ + 'date' => 'business_day', + ])); + } + + public function testSuccessWhenFriday() + { + $this->assertTrue(GUMP::is_valid([ + 'date' => '2024-01-12', // Friday + ], [ + 'date' => 'business_day', + ])); + } + + public function testErrorWhenSaturday() + { + $this->assertNotSame(true, GUMP::is_valid([ + 'date' => '2024-01-13', // Saturday + ], [ + 'date' => 'business_day', + ])); + } + + public function testErrorWhenSunday() + { + $this->assertNotSame(true, GUMP::is_valid([ + 'date' => '2024-01-14', // Sunday + ], [ + 'date' => 'business_day', + ])); + } + + public function testErrorWhenInvalidDate() + { + $this->assertNotSame(true, GUMP::is_valid([ + 'date' => 'not-a-date', + ], [ + 'date' => 'business_day', + ])); + } +} diff --git a/tests/Validators/CoordinatesValidatorTest.php b/tests/Validators/CoordinatesValidatorTest.php new file mode 100644 index 00000000..211e736a --- /dev/null +++ b/tests/Validators/CoordinatesValidatorTest.php @@ -0,0 +1,111 @@ +assertTrue(GUMP::is_valid([ + 'coords' => '40.7128, -74.0060', + ], [ + 'coords' => 'coordinates', + ])); + } + + public function testSuccessWhenEquator() + { + $this->assertTrue(GUMP::is_valid([ + 'coords' => '0, 0', + ], [ + 'coords' => 'coordinates', + ])); + } + + public function testSuccessWhenNegativeCoordinates() + { + $this->assertTrue(GUMP::is_valid([ + 'coords' => '-33.8688, 151.2093', + ], [ + 'coords' => 'coordinates', + ])); + } + + public function testSuccessWhenBoundaryCoordinates() + { + $this->assertTrue(GUMP::is_valid([ + 'coords' => '90, 180', + ], [ + 'coords' => 'coordinates', + ])); + + $this->assertTrue(GUMP::is_valid([ + 'coords' => '-90, -180', + ], [ + 'coords' => 'coordinates', + ])); + } + + public function testSuccessWhenNoSpaceAfterComma() + { + $this->assertTrue(GUMP::is_valid([ + 'coords' => '40.7128,-74.0060', + ], [ + 'coords' => 'coordinates', + ])); + } + + public function testErrorWhenLatitudeTooHigh() + { + $this->assertNotSame(true, GUMP::is_valid([ + 'coords' => '91, 0', + ], [ + 'coords' => 'coordinates', + ])); + } + + public function testErrorWhenLatitudeTooLow() + { + $this->assertNotSame(true, GUMP::is_valid([ + 'coords' => '-91, 0', + ], [ + 'coords' => 'coordinates', + ])); + } + + public function testErrorWhenLongitudeTooHigh() + { + $this->assertNotSame(true, GUMP::is_valid([ + 'coords' => '0, 181', + ], [ + 'coords' => 'coordinates', + ])); + } + + public function testErrorWhenLongitudeTooLow() + { + $this->assertNotSame(true, GUMP::is_valid([ + 'coords' => '0, -181', + ], [ + 'coords' => 'coordinates', + ])); + } + + public function testErrorWhenInvalidFormat() + { + $this->assertNotSame(true, GUMP::is_valid([ + 'coords' => '40.7128', + ], [ + 'coords' => 'coordinates', + ])); + + $this->assertNotSame(true, GUMP::is_valid([ + 'coords' => 'invalid', + ], [ + 'coords' => 'coordinates', + ])); + } +} diff --git a/tests/Validators/CountryCodeValidatorTest.php b/tests/Validators/CountryCodeValidatorTest.php new file mode 100644 index 00000000..ab703f0f --- /dev/null +++ b/tests/Validators/CountryCodeValidatorTest.php @@ -0,0 +1,96 @@ +assertTrue(GUMP::is_valid([ + 'country' => 'US', + ], [ + 'country' => 'country_code', + ])); + + $this->assertTrue(GUMP::is_valid([ + 'country' => 'GB', + ], [ + 'country' => 'country_code', + ])); + + $this->assertTrue(GUMP::is_valid([ + 'country' => 'DE', + ], [ + 'country' => 'country_code', + ])); + + $this->assertTrue(GUMP::is_valid([ + 'country' => 'FR', + ], [ + 'country' => 'country_code', + ])); + + $this->assertTrue(GUMP::is_valid([ + 'country' => 'JP', + ], [ + 'country' => 'country_code', + ])); + } + + public function testErrorWhenLowercase() + { + $this->assertNotSame(true, GUMP::is_valid([ + 'country' => 'us', + ], [ + 'country' => 'country_code', + ])); + } + + public function testErrorWhenMixedCase() + { + $this->assertNotSame(true, GUMP::is_valid([ + 'country' => 'Us', + ], [ + 'country' => 'country_code', + ])); + } + + public function testErrorWhenSingleLetter() + { + $this->assertNotSame(true, GUMP::is_valid([ + 'country' => 'U', + ], [ + 'country' => 'country_code', + ])); + } + + public function testErrorWhenThreeLetters() + { + $this->assertNotSame(true, GUMP::is_valid([ + 'country' => 'USA', + ], [ + 'country' => 'country_code', + ])); + } + + public function testErrorWhenNumeric() + { + $this->assertNotSame(true, GUMP::is_valid([ + 'country' => '12', + ], [ + 'country' => 'country_code', + ])); + } + + public function testErrorWhenEmptyAndRequired() + { + $this->assertNotSame(true, GUMP::is_valid([ + 'country' => '', + ], [ + 'country' => 'required|country_code', + ])); + } +} diff --git a/tests/Validators/CurrencyCodeValidatorTest.php b/tests/Validators/CurrencyCodeValidatorTest.php new file mode 100644 index 00000000..711dc118 --- /dev/null +++ b/tests/Validators/CurrencyCodeValidatorTest.php @@ -0,0 +1,91 @@ +assertTrue(GUMP::is_valid([ + 'currency' => $currency, + ], [ + 'currency' => 'currency_code', + ]), "Failed asserting that $currency is valid"); + } + } + + public function testSuccessWhenLessCommonCurrency() + { + $this->assertTrue(GUMP::is_valid([ + 'currency' => 'RUB', + ], [ + 'currency' => 'currency_code', + ])); + + $this->assertTrue(GUMP::is_valid([ + 'currency' => 'ZAR', + ], [ + 'currency' => 'currency_code', + ])); + } + + public function testErrorWhenInvalidCurrencyCode() + { + $this->assertNotSame(true, GUMP::is_valid([ + 'currency' => 'XXX', + ], [ + 'currency' => 'currency_code', + ])); + } + + public function testErrorWhenLowercase() + { + $this->assertNotSame(true, GUMP::is_valid([ + 'currency' => 'usd', + ], [ + 'currency' => 'currency_code', + ])); + } + + public function testErrorWhenMixedCase() + { + $this->assertNotSame(true, GUMP::is_valid([ + 'currency' => 'Usd', + ], [ + 'currency' => 'currency_code', + ])); + } + + public function testErrorWhenWithSpaces() + { + $this->assertNotSame(true, GUMP::is_valid([ + 'currency' => 'US D', + ], [ + 'currency' => 'currency_code', + ])); + } + + public function testErrorWhenEmptyAndRequired() + { + $this->assertNotSame(true, GUMP::is_valid([ + 'currency' => '', + ], [ + 'currency' => 'required|currency_code', + ])); + } + + public function testErrorWhenNumeric() + { + $this->assertNotSame(true, GUMP::is_valid([ + 'currency' => '840', + ], [ + 'currency' => 'currency_code', + ])); + } +} diff --git a/tests/Validators/DateRangeValidatorTest.php b/tests/Validators/DateRangeValidatorTest.php new file mode 100644 index 00000000..5261b12e --- /dev/null +++ b/tests/Validators/DateRangeValidatorTest.php @@ -0,0 +1,72 @@ +assertTrue(GUMP::is_valid([ + 'date' => '2024-06-15', + ], [ + 'date' => 'date_range,2024-01-01;2024-12-31', + ])); + } + + public function testSuccessWhenDateAtStartBoundary() + { + $this->assertTrue(GUMP::is_valid([ + 'date' => '2024-01-01', + ], [ + 'date' => 'date_range,2024-01-01;2024-12-31', + ])); + } + + public function testSuccessWhenDateAtEndBoundary() + { + $this->assertTrue(GUMP::is_valid([ + 'date' => '2024-12-31', + ], [ + 'date' => 'date_range,2024-01-01;2024-12-31', + ])); + } + + public function testErrorWhenDateBeforeRange() + { + $this->assertNotSame(true, GUMP::is_valid([ + 'date' => '2023-12-31', + ], [ + 'date' => 'date_range,2024-01-01;2024-12-31', + ])); + } + + public function testErrorWhenDateAfterRange() + { + $this->assertNotSame(true, GUMP::is_valid([ + 'date' => '2025-01-01', + ], [ + 'date' => 'date_range,2024-01-01;2024-12-31', + ])); + } + + public function testErrorWhenInvalidDateFormat() + { + $this->assertNotSame(true, GUMP::is_valid([ + 'date' => 'not-a-date', + ], [ + 'date' => 'date_range,2024-01-01;2024-12-31', + ])); + } + + public function testErrorWhenMissingParameter() + { + $this->assertNotSame(true, GUMP::is_valid([ + 'date' => '2024-06-15', + ], [ + 'date' => 'date_range,2024-01-01', + ])); + } +} diff --git a/tests/Validators/DomainNameValidatorTest.php b/tests/Validators/DomainNameValidatorTest.php new file mode 100644 index 00000000..6d41682b --- /dev/null +++ b/tests/Validators/DomainNameValidatorTest.php @@ -0,0 +1,108 @@ +assertTrue(GUMP::is_valid([ + 'domain' => 'example.com', + ], [ + 'domain' => 'domain_name', + ])); + } + + public function testSuccessWhenValidSubdomain() + { + $this->assertTrue(GUMP::is_valid([ + 'domain' => 'subdomain.example.com', + ], [ + 'domain' => 'domain_name', + ])); + } + + public function testSuccessWhenMultipleSubdomains() + { + $this->assertTrue(GUMP::is_valid([ + 'domain' => 'a.b.c.example.com', + ], [ + 'domain' => 'domain_name', + ])); + } + + public function testSuccessWhenDomainWithHyphen() + { + $this->assertTrue(GUMP::is_valid([ + 'domain' => 'my-domain.com', + ], [ + 'domain' => 'domain_name', + ])); + } + + public function testSuccessWhenLongTld() + { + $this->assertTrue(GUMP::is_valid([ + 'domain' => 'example.museum', + ], [ + 'domain' => 'domain_name', + ])); + } + + public function testErrorWhenNoTld() + { + $this->assertNotSame(true, GUMP::is_valid([ + 'domain' => 'example', + ], [ + 'domain' => 'domain_name', + ])); + } + + public function testErrorWhenWithProtocol() + { + $this->assertNotSame(true, GUMP::is_valid([ + 'domain' => 'http://example.com', + ], [ + 'domain' => 'domain_name', + ])); + } + + public function testErrorWhenStartsWithHyphen() + { + $this->assertNotSame(true, GUMP::is_valid([ + 'domain' => '-example.com', + ], [ + 'domain' => 'domain_name', + ])); + } + + public function testErrorWhenEndsWithHyphen() + { + $this->assertNotSame(true, GUMP::is_valid([ + 'domain' => 'example-.com', + ], [ + 'domain' => 'domain_name', + ])); + } + + public function testErrorWhenWithUnderscore() + { + $this->assertNotSame(true, GUMP::is_valid([ + 'domain' => 'example_domain.com', + ], [ + 'domain' => 'domain_name', + ])); + } + + public function testErrorWhenEmptyAndRequired() + { + $this->assertNotSame(true, GUMP::is_valid([ + 'domain' => '', + ], [ + 'domain' => 'required|domain_name', + ])); + } +} diff --git a/tests/Validators/EvenValidatorTest.php b/tests/Validators/EvenValidatorTest.php new file mode 100644 index 00000000..811d51db --- /dev/null +++ b/tests/Validators/EvenValidatorTest.php @@ -0,0 +1,93 @@ +assertTrue(GUMP::is_valid([ + 'number' => (string)$even, + ], [ + 'number' => 'even', + ]), "Failed asserting that $even is even"); + } + } + + public function testSuccessWhenNegativeEvenNumber() + { + $this->assertTrue(GUMP::is_valid([ + 'number' => '-2', + ], [ + 'number' => 'even', + ])); + + $this->assertTrue(GUMP::is_valid([ + 'number' => '-4', + ], [ + 'number' => 'even', + ])); + } + + public function testSuccessWhenZero() + { + $this->assertTrue(GUMP::is_valid([ + 'number' => '0', + ], [ + 'number' => 'even', + ])); + } + + public function testErrorWhenOddNumber() + { + $oddNumbers = [1, 3, 5, 7, 9, 11, 99, 101]; + + foreach ($oddNumbers as $odd) { + $this->assertNotSame(true, GUMP::is_valid([ + 'number' => (string)$odd, + ], [ + 'number' => 'even', + ]), "Failed asserting that $odd is not even"); + } + } + + public function testErrorWhenNegativeOddNumber() + { + $this->assertNotSame(true, GUMP::is_valid([ + 'number' => '-1', + ], [ + 'number' => 'even', + ])); + + $this->assertNotSame(true, GUMP::is_valid([ + 'number' => '-3', + ], [ + 'number' => 'even', + ])); + } + + public function testErrorWhenNotNumeric() + { + $this->assertNotSame(true, GUMP::is_valid([ + 'number' => 'abc', + ], [ + 'number' => 'even', + ])); + } + + public function testSuccessWhenFloat() + { + // Floats are cast to int, so 2.5 becomes 2 which is even + $this->assertTrue(GUMP::is_valid([ + 'number' => '2.5', + ], [ + 'number' => 'even', + ])); + } +} diff --git a/tests/Validators/ExtensionValidatorTest.php b/tests/Validators/ExtensionValidatorTest.php index e1224c33..a90c1832 100644 --- a/tests/Validators/ExtensionValidatorTest.php +++ b/tests/Validators/ExtensionValidatorTest.php @@ -73,4 +73,43 @@ public function testItFailsWhenFileWasNotSuccessfullyUploaded() $this->assertNotTrue($this->validate(self::RULE, $input)); } + + public function testItFailsWhenUploadErrorOccurred() + { + // Error code 1 = UPLOAD_ERR_INI_SIZE (file exceeds upload_max_filesize) + $input = [ + 'name' => 'screenshot.png', + 'type' => 'image/png', + 'tmp_name' => '/tmp/phphjatI9', + 'error' => 1, + 'size' => 0, + ]; + + $this->assertNotTrue($this->validate(self::RULE, $input)); + } + + public function testItFailsWhenPartialUploadErrorOccurred() + { + // Error code 3 = UPLOAD_ERR_PARTIAL (file was only partially uploaded) + $input = [ + 'name' => 'screenshot.png', + 'type' => 'image/png', + 'tmp_name' => '/tmp/phphjatI9', + 'error' => 3, + 'size' => 1000, + ]; + + $this->assertNotTrue($this->validate(self::RULE, $input)); + } + + public function testItFailsWhenInputIsNotArray() + { + $result = $this->gump->validate([ + 'test' => 'not-an-array', + ], [ + 'test' => self::RULE, + ]); + + $this->assertNotTrue($result); + } } diff --git a/tests/Validators/HashValidatorTest.php b/tests/Validators/HashValidatorTest.php new file mode 100644 index 00000000..a29cd70f --- /dev/null +++ b/tests/Validators/HashValidatorTest.php @@ -0,0 +1,99 @@ +assertTrue(GUMP::is_valid([ + 'hash' => 'd41d8cd98f00b204e9800998ecf8427e', + ], [ + 'hash' => 'hash,md5', + ])); + } + + public function testSuccessWhenValidMd5Uppercase() + { + $this->assertTrue(GUMP::is_valid([ + 'hash' => 'D41D8CD98F00B204E9800998ECF8427E', + ], [ + 'hash' => 'hash,md5', + ])); + } + + public function testSuccessWhenValidSha1() + { + $this->assertTrue(GUMP::is_valid([ + 'hash' => 'da39a3ee5e6b4b0d3255bfef95601890afd80709', + ], [ + 'hash' => 'hash,sha1', + ])); + } + + public function testSuccessWhenValidSha256() + { + $this->assertTrue(GUMP::is_valid([ + 'hash' => 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855', + ], [ + 'hash' => 'hash,sha256', + ])); + } + + public function testSuccessWhenValidSha512() + { + $this->assertTrue(GUMP::is_valid([ + 'hash' => 'cf83e1357eefb8bdf1542850d66d8007d620e4050b5715dc83f4a921d36ce9ce47d0d13c5d85f2b0ff8318d2877eec2f63b931bd47417a81a538327af927da3e', + ], [ + 'hash' => 'hash,sha512', + ])); + } + + public function testSuccessWhenDefaultMd5() + { + $this->assertTrue(GUMP::is_valid([ + 'hash' => 'd41d8cd98f00b204e9800998ecf8427e', + ], [ + 'hash' => 'hash', + ])); + } + + public function testErrorWhenHashTooShort() + { + $this->assertNotSame(true, GUMP::is_valid([ + 'hash' => 'd41d8cd98f00b204', + ], [ + 'hash' => 'hash,md5', + ])); + } + + public function testErrorWhenHashTooLong() + { + $this->assertNotSame(true, GUMP::is_valid([ + 'hash' => 'd41d8cd98f00b204e9800998ecf8427e00', + ], [ + 'hash' => 'hash,md5', + ])); + } + + public function testErrorWhenContainsNonHexCharacters() + { + $this->assertNotSame(true, GUMP::is_valid([ + 'hash' => 'g41d8cd98f00b204e9800998ecf8427e', + ], [ + 'hash' => 'hash,md5', + ])); + } + + public function testErrorWhenUnsupportedAlgorithm() + { + $this->assertNotSame(true, GUMP::is_valid([ + 'hash' => 'd41d8cd98f00b204e9800998ecf8427e', + ], [ + 'hash' => 'hash,unsupported', + ])); + } +} diff --git a/tests/Validators/LanguageCodeValidatorTest.php b/tests/Validators/LanguageCodeValidatorTest.php new file mode 100644 index 00000000..41e7b931 --- /dev/null +++ b/tests/Validators/LanguageCodeValidatorTest.php @@ -0,0 +1,117 @@ +assertTrue(GUMP::is_valid([ + 'lang' => 'en', + ], [ + 'lang' => 'language_code', + ])); + + $this->assertTrue(GUMP::is_valid([ + 'lang' => 'fr', + ], [ + 'lang' => 'language_code', + ])); + + $this->assertTrue(GUMP::is_valid([ + 'lang' => 'de', + ], [ + 'lang' => 'language_code', + ])); + + $this->assertTrue(GUMP::is_valid([ + 'lang' => 'ja', + ], [ + 'lang' => 'language_code', + ])); + } + + public function testSuccessWhenValidWithCountryCode() + { + $this->assertTrue(GUMP::is_valid([ + 'lang' => 'en-US', + ], [ + 'lang' => 'language_code', + ])); + + $this->assertTrue(GUMP::is_valid([ + 'lang' => 'fr-FR', + ], [ + 'lang' => 'language_code', + ])); + + $this->assertTrue(GUMP::is_valid([ + 'lang' => 'zh-CN', + ], [ + 'lang' => 'language_code', + ])); + } + + public function testErrorWhenUppercaseLanguage() + { + $this->assertNotSame(true, GUMP::is_valid([ + 'lang' => 'EN', + ], [ + 'lang' => 'language_code', + ])); + } + + public function testErrorWhenSingleLetter() + { + $this->assertNotSame(true, GUMP::is_valid([ + 'lang' => 'e', + ], [ + 'lang' => 'language_code', + ])); + } + + public function testErrorWhenThreeLetters() + { + $this->assertNotSame(true, GUMP::is_valid([ + 'lang' => 'eng', + ], [ + 'lang' => 'language_code', + ])); + } + + public function testErrorWhenWrongCaseFormat() + { + $this->assertNotSame(true, GUMP::is_valid([ + 'lang' => 'En-us', + ], [ + 'lang' => 'language_code', + ])); + + $this->assertNotSame(true, GUMP::is_valid([ + 'lang' => 'EN-US', + ], [ + 'lang' => 'language_code', + ])); + } + + public function testErrorWhenUnderscoreSeparator() + { + $this->assertNotSame(true, GUMP::is_valid([ + 'lang' => 'en_US', + ], [ + 'lang' => 'language_code', + ])); + } + + public function testErrorWhenEmptyAndRequired() + { + $this->assertNotSame(true, GUMP::is_valid([ + 'lang' => '', + ], [ + 'lang' => 'required|language_code', + ])); + } +} diff --git a/tests/Validators/LongitudeValidatorTest.php b/tests/Validators/LongitudeValidatorTest.php new file mode 100644 index 00000000..3bf4cd3d --- /dev/null +++ b/tests/Validators/LongitudeValidatorTest.php @@ -0,0 +1,75 @@ +assertTrue(GUMP::is_valid([ + 'lng' => '74.0060', + ], [ + 'lng' => 'longitude', + ])); + } + + public function testSuccessWhenValidNegativeLongitude() + { + $this->assertTrue(GUMP::is_valid([ + 'lng' => '-74.0060', + ], [ + 'lng' => 'longitude', + ])); + } + + public function testSuccessWhenValidBoundaryLongitude() + { + $this->assertTrue(GUMP::is_valid([ + 'lng' => '180', + ], [ + 'lng' => 'longitude', + ])); + + $this->assertTrue(GUMP::is_valid([ + 'lng' => '-180', + ], [ + 'lng' => 'longitude', + ])); + + $this->assertTrue(GUMP::is_valid([ + 'lng' => '0', + ], [ + 'lng' => 'longitude', + ])); + } + + public function testErrorWhenLongitudeTooHigh() + { + $this->assertNotSame(true, GUMP::is_valid([ + 'lng' => '181', + ], [ + 'lng' => 'longitude', + ])); + } + + public function testErrorWhenLongitudeTooLow() + { + $this->assertNotSame(true, GUMP::is_valid([ + 'lng' => '-181', + ], [ + 'lng' => 'longitude', + ])); + } + + public function testErrorWhenNotNumeric() + { + $this->assertNotSame(true, GUMP::is_valid([ + 'lng' => 'not-a-number', + ], [ + 'lng' => 'longitude', + ])); + } +} diff --git a/tests/Validators/NoSqlInjectionValidatorTest.php b/tests/Validators/NoSqlInjectionValidatorTest.php new file mode 100644 index 00000000..cea999b9 --- /dev/null +++ b/tests/Validators/NoSqlInjectionValidatorTest.php @@ -0,0 +1,153 @@ +assertTrue(GUMP::is_valid([ + 'input' => 'normal_input', + ], [ + 'input' => 'no_sql_injection', + ])); + } + + public function testSuccessWhenSafeStringWithNumbers() + { + $this->assertTrue(GUMP::is_valid([ + 'input' => 'user123', + ], [ + 'input' => 'no_sql_injection', + ])); + } + + public function testErrorWhenSelectKeyword() + { + $this->assertNotSame(true, GUMP::is_valid([ + 'input' => 'SELECT * FROM users', + ], [ + 'input' => 'no_sql_injection', + ])); + } + + public function testErrorWhenInsertKeyword() + { + $this->assertNotSame(true, GUMP::is_valid([ + 'input' => 'INSERT INTO users', + ], [ + 'input' => 'no_sql_injection', + ])); + } + + public function testErrorWhenUpdateKeyword() + { + $this->assertNotSame(true, GUMP::is_valid([ + 'input' => 'UPDATE users SET', + ], [ + 'input' => 'no_sql_injection', + ])); + } + + public function testErrorWhenDeleteKeyword() + { + $this->assertNotSame(true, GUMP::is_valid([ + 'input' => 'DELETE FROM users', + ], [ + 'input' => 'no_sql_injection', + ])); + } + + public function testErrorWhenDropKeyword() + { + $this->assertNotSame(true, GUMP::is_valid([ + 'input' => 'DROP TABLE users', + ], [ + 'input' => 'no_sql_injection', + ])); + } + + public function testErrorWhenUnionKeyword() + { + $this->assertNotSame(true, GUMP::is_valid([ + 'input' => 'UNION SELECT password', + ], [ + 'input' => 'no_sql_injection', + ])); + } + + public function testErrorWhenOrCondition() + { + $this->assertNotSame(true, GUMP::is_valid([ + 'input' => 'OR 1=1', + ], [ + 'input' => 'no_sql_injection', + ])); + } + + public function testErrorWhenAndCondition() + { + $this->assertNotSame(true, GUMP::is_valid([ + 'input' => 'AND 0=0', + ], [ + 'input' => 'no_sql_injection', + ])); + } + + public function testErrorWhenSingleQuote() + { + $this->assertNotSame(true, GUMP::is_valid([ + 'input' => "test'value", + ], [ + 'input' => 'no_sql_injection', + ])); + } + + public function testErrorWhenDoubleQuote() + { + $this->assertNotSame(true, GUMP::is_valid([ + 'input' => 'test"value', + ], [ + 'input' => 'no_sql_injection', + ])); + } + + public function testErrorWhenSemicolon() + { + $this->assertNotSame(true, GUMP::is_valid([ + 'input' => 'value;', + ], [ + 'input' => 'no_sql_injection', + ])); + } + + public function testErrorWhenSqlComment() + { + $this->assertNotSame(true, GUMP::is_valid([ + 'input' => 'value--comment', + ], [ + 'input' => 'no_sql_injection', + ])); + } + + public function testErrorWhenBlockComment() + { + $this->assertNotSame(true, GUMP::is_valid([ + 'input' => 'value/*comment*/', + ], [ + 'input' => 'no_sql_injection', + ])); + } + + public function testErrorWhenMixedCase() + { + $this->assertNotSame(true, GUMP::is_valid([ + 'input' => 'select * from users', + ], [ + 'input' => 'no_sql_injection', + ])); + } +} diff --git a/tests/Validators/NoXssValidatorTest.php b/tests/Validators/NoXssValidatorTest.php new file mode 100644 index 00000000..636cac78 --- /dev/null +++ b/tests/Validators/NoXssValidatorTest.php @@ -0,0 +1,126 @@ +assertTrue(GUMP::is_valid([ + 'input' => 'normal text', + ], [ + 'input' => 'no_xss', + ])); + } + + public function testSuccessWhenSafeHtml() + { + $this->assertTrue(GUMP::is_valid([ + 'input' => '

Hello World

', + ], [ + 'input' => 'no_xss', + ])); + } + + public function testErrorWhenScriptTag() + { + $this->assertNotSame(true, GUMP::is_valid([ + 'input' => '', + ], [ + 'input' => 'no_xss', + ])); + } + + public function testErrorWhenJavascriptProtocol() + { + $this->assertNotSame(true, GUMP::is_valid([ + 'input' => 'javascript:alert("xss")', + ], [ + 'input' => 'no_xss', + ])); + } + + public function testErrorWhenOnclickHandler() + { + $this->assertNotSame(true, GUMP::is_valid([ + 'input' => '
', + ], [ + 'input' => 'no_xss', + ])); + } + + public function testErrorWhenOnloadHandler() + { + $this->assertNotSame(true, GUMP::is_valid([ + 'input' => '', + ], [ + 'input' => 'no_xss', + ])); + } + + public function testErrorWhenOnerrorHandler() + { + $this->assertNotSame(true, GUMP::is_valid([ + 'input' => '', + ], [ + 'input' => 'no_xss', + ])); + } + + public function testErrorWhenIframeTag() + { + $this->assertNotSame(true, GUMP::is_valid([ + 'input' => '', + ], [ + 'input' => 'no_xss', + ])); + } + + public function testErrorWhenObjectTag() + { + $this->assertNotSame(true, GUMP::is_valid([ + 'input' => '', + ], [ + 'input' => 'no_xss', + ])); + } + + public function testErrorWhenEmbedTag() + { + $this->assertNotSame(true, GUMP::is_valid([ + 'input' => '', + ], [ + 'input' => 'no_xss', + ])); + } + + public function testErrorWhenCssExpression() + { + $this->assertNotSame(true, GUMP::is_valid([ + 'input' => 'expression(alert("xss"))', + ], [ + 'input' => 'no_xss', + ])); + } + + public function testErrorWhenVbscriptProtocol() + { + $this->assertNotSame(true, GUMP::is_valid([ + 'input' => 'vbscript:alert("xss")', + ], [ + 'input' => 'no_xss', + ])); + } + + public function testErrorWhenMixedCase() + { + $this->assertNotSame(true, GUMP::is_valid([ + 'input' => '', + ], [ + 'input' => 'no_xss', + ])); + } +} diff --git a/tests/Validators/OddValidatorTest.php b/tests/Validators/OddValidatorTest.php new file mode 100644 index 00000000..764792f9 --- /dev/null +++ b/tests/Validators/OddValidatorTest.php @@ -0,0 +1,94 @@ +assertTrue(GUMP::is_valid([ + 'number' => (string)$odd, + ], [ + 'number' => 'odd', + ]), "Failed asserting that $odd is odd"); + } + } + + public function testErrorWhenNegativeOddNumber() + { + // In PHP, -1 % 2 = -1, not 1, so negative odd numbers fail this validator + $this->assertNotSame(true, GUMP::is_valid([ + 'number' => '-1', + ], [ + 'number' => 'odd', + ])); + + $this->assertNotSame(true, GUMP::is_valid([ + 'number' => '-3', + ], [ + 'number' => 'odd', + ])); + } + + public function testErrorWhenEvenNumber() + { + $evenNumbers = [0, 2, 4, 6, 8, 10, 100]; + + foreach ($evenNumbers as $even) { + $this->assertNotSame(true, GUMP::is_valid([ + 'number' => (string)$even, + ], [ + 'number' => 'odd', + ]), "Failed asserting that $even is not odd"); + } + } + + public function testErrorWhenNegativeEvenNumber() + { + $this->assertNotSame(true, GUMP::is_valid([ + 'number' => '-2', + ], [ + 'number' => 'odd', + ])); + + $this->assertNotSame(true, GUMP::is_valid([ + 'number' => '-4', + ], [ + 'number' => 'odd', + ])); + } + + public function testErrorWhenZero() + { + $this->assertNotSame(true, GUMP::is_valid([ + 'number' => '0', + ], [ + 'number' => 'odd', + ])); + } + + public function testErrorWhenNotNumeric() + { + $this->assertNotSame(true, GUMP::is_valid([ + 'number' => 'abc', + ], [ + 'number' => 'odd', + ])); + } + + public function testSuccessWhenFloat() + { + // Floats are cast to int, so 3.5 becomes 3 which is odd + $this->assertTrue(GUMP::is_valid([ + 'number' => '3.5', + ], [ + 'number' => 'odd', + ])); + } +} diff --git a/tests/Validators/PastDateValidatorTest.php b/tests/Validators/PastDateValidatorTest.php new file mode 100644 index 00000000..26329258 --- /dev/null +++ b/tests/Validators/PastDateValidatorTest.php @@ -0,0 +1,65 @@ +assertTrue(GUMP::is_valid([ + 'date' => '2020-01-01', + ], [ + 'date' => 'past_date', + ])); + } + + public function testSuccessWhenFarPastDate() + { + $this->assertTrue(GUMP::is_valid([ + 'date' => '1990-06-15', + ], [ + 'date' => 'past_date', + ])); + } + + public function testSuccessWhenYesterday() + { + $yesterday = date('Y-m-d', strtotime('-1 day')); + $this->assertTrue(GUMP::is_valid([ + 'date' => $yesterday, + ], [ + 'date' => 'past_date', + ])); + } + + public function testErrorWhenFutureDate() + { + $this->assertNotSame(true, GUMP::is_valid([ + 'date' => '2099-12-31', + ], [ + 'date' => 'past_date', + ])); + } + + public function testErrorWhenTomorrow() + { + $tomorrow = date('Y-m-d', strtotime('+1 day')); + $this->assertNotSame(true, GUMP::is_valid([ + 'date' => $tomorrow, + ], [ + 'date' => 'past_date', + ])); + } + + public function testErrorWhenInvalidDate() + { + $this->assertNotSame(true, GUMP::is_valid([ + 'date' => 'not-a-date', + ], [ + 'date' => 'past_date', + ])); + } +} diff --git a/tests/Validators/PortNumberValidatorTest.php b/tests/Validators/PortNumberValidatorTest.php new file mode 100644 index 00000000..2aff620c --- /dev/null +++ b/tests/Validators/PortNumberValidatorTest.php @@ -0,0 +1,106 @@ +assertTrue(GUMP::is_valid([ + 'port' => '80', + ], [ + 'port' => 'port_number', + ])); + + $this->assertTrue(GUMP::is_valid([ + 'port' => '443', + ], [ + 'port' => 'port_number', + ])); + + $this->assertTrue(GUMP::is_valid([ + 'port' => '8080', + ], [ + 'port' => 'port_number', + ])); + + $this->assertTrue(GUMP::is_valid([ + 'port' => '3306', + ], [ + 'port' => 'port_number', + ])); + } + + public function testSuccessWhenMinimumPort() + { + $this->assertTrue(GUMP::is_valid([ + 'port' => '1', + ], [ + 'port' => 'port_number', + ])); + } + + public function testSuccessWhenMaximumPort() + { + $this->assertTrue(GUMP::is_valid([ + 'port' => '65535', + ], [ + 'port' => 'port_number', + ])); + } + + public function testErrorWhenPortZero() + { + $this->assertNotSame(true, GUMP::is_valid([ + 'port' => '0', + ], [ + 'port' => 'port_number', + ])); + } + + public function testErrorWhenNegativePort() + { + $this->assertNotSame(true, GUMP::is_valid([ + 'port' => '-1', + ], [ + 'port' => 'port_number', + ])); + } + + public function testErrorWhenPortTooHigh() + { + $this->assertNotSame(true, GUMP::is_valid([ + 'port' => '65536', + ], [ + 'port' => 'port_number', + ])); + + $this->assertNotSame(true, GUMP::is_valid([ + 'port' => '99999', + ], [ + 'port' => 'port_number', + ])); + } + + public function testErrorWhenNotNumeric() + { + $this->assertNotSame(true, GUMP::is_valid([ + 'port' => 'abc', + ], [ + 'port' => 'port_number', + ])); + } + + public function testSuccessWhenFloat() + { + // Floats are numeric and within range, so they pass + $this->assertTrue(GUMP::is_valid([ + 'port' => '8080.5', + ], [ + 'port' => 'port_number', + ])); + } +} diff --git a/tests/Validators/PostalCodeValidatorTest.php b/tests/Validators/PostalCodeValidatorTest.php new file mode 100644 index 00000000..4df5a456 --- /dev/null +++ b/tests/Validators/PostalCodeValidatorTest.php @@ -0,0 +1,126 @@ +assertTrue(GUMP::is_valid([ + 'zip' => '12345', + ], [ + 'zip' => 'postal_code,US', + ])); + } + + public function testSuccessWhenValidUSPostalCodeWithExtension() + { + $this->assertTrue(GUMP::is_valid([ + 'zip' => '12345-6789', + ], [ + 'zip' => 'postal_code,US', + ])); + } + + public function testSuccessWhenValidCanadianPostalCode() + { + $this->assertTrue(GUMP::is_valid([ + 'zip' => 'K1A 0B1', + ], [ + 'zip' => 'postal_code,CA', + ])); + + $this->assertTrue(GUMP::is_valid([ + 'zip' => 'K1A0B1', + ], [ + 'zip' => 'postal_code,CA', + ])); + } + + public function testSuccessWhenValidUKPostalCode() + { + $this->assertTrue(GUMP::is_valid([ + 'zip' => 'SW1A 1AA', + ], [ + 'zip' => 'postal_code,UK', + ])); + + $this->assertTrue(GUMP::is_valid([ + 'zip' => 'B33 8TH', + ], [ + 'zip' => 'postal_code,UK', + ])); + } + + public function testSuccessWhenValidGermanPostalCode() + { + $this->assertTrue(GUMP::is_valid([ + 'zip' => '10115', + ], [ + 'zip' => 'postal_code,DE', + ])); + } + + public function testSuccessWhenValidFrenchPostalCode() + { + $this->assertTrue(GUMP::is_valid([ + 'zip' => '75001', + ], [ + 'zip' => 'postal_code,FR', + ])); + } + + public function testSuccessWhenValidAustralianPostalCode() + { + $this->assertTrue(GUMP::is_valid([ + 'zip' => '2000', + ], [ + 'zip' => 'postal_code,AU', + ])); + } + + public function testSuccessWhenValidJapanesePostalCode() + { + $this->assertTrue(GUMP::is_valid([ + 'zip' => '100-0001', + ], [ + 'zip' => 'postal_code,JP', + ])); + } + + public function testSuccessWhenDefaultUS() + { + $this->assertTrue(GUMP::is_valid([ + 'zip' => '12345', + ], [ + 'zip' => 'postal_code', + ])); + } + + public function testErrorWhenInvalidUSPostalCode() + { + $this->assertNotSame(true, GUMP::is_valid([ + 'zip' => '1234', + ], [ + 'zip' => 'postal_code,US', + ])); + + $this->assertNotSame(true, GUMP::is_valid([ + 'zip' => '12345-678', + ], [ + 'zip' => 'postal_code,US', + ])); + } + + public function testErrorWhenInvalidCountryCode() + { + $this->assertNotSame(true, GUMP::is_valid([ + 'zip' => '12345', + ], [ + 'zip' => 'postal_code,XX', + ])); + } +} diff --git a/tests/Validators/RgbColorValidatorTest.php b/tests/Validators/RgbColorValidatorTest.php new file mode 100644 index 00000000..3d132acf --- /dev/null +++ b/tests/Validators/RgbColorValidatorTest.php @@ -0,0 +1,117 @@ +assertTrue(GUMP::is_valid([ + 'color' => 'rgb(255, 128, 0)', + ], [ + 'color' => 'rgb_color', + ])); + } + + public function testSuccessWhenBlack() + { + $this->assertTrue(GUMP::is_valid([ + 'color' => 'rgb(0, 0, 0)', + ], [ + 'color' => 'rgb_color', + ])); + } + + public function testSuccessWhenWhite() + { + $this->assertTrue(GUMP::is_valid([ + 'color' => 'rgb(255, 255, 255)', + ], [ + 'color' => 'rgb_color', + ])); + } + + public function testSuccessWhenExtraSpaces() + { + $this->assertTrue(GUMP::is_valid([ + 'color' => 'rgb( 255 , 128 , 0 )', + ], [ + 'color' => 'rgb_color', + ])); + } + + public function testSuccessWhenMixedCase() + { + $this->assertTrue(GUMP::is_valid([ + 'color' => 'RGB(255, 128, 0)', + ], [ + 'color' => 'rgb_color', + ])); + } + + public function testErrorWhenRedTooHigh() + { + $this->assertNotSame(true, GUMP::is_valid([ + 'color' => 'rgb(256, 128, 0)', + ], [ + 'color' => 'rgb_color', + ])); + } + + public function testErrorWhenGreenTooHigh() + { + $this->assertNotSame(true, GUMP::is_valid([ + 'color' => 'rgb(255, 256, 0)', + ], [ + 'color' => 'rgb_color', + ])); + } + + public function testErrorWhenBlueTooHigh() + { + $this->assertNotSame(true, GUMP::is_valid([ + 'color' => 'rgb(255, 128, 256)', + ], [ + 'color' => 'rgb_color', + ])); + } + + public function testErrorWhenHexFormat() + { + $this->assertNotSame(true, GUMP::is_valid([ + 'color' => '#FF8000', + ], [ + 'color' => 'rgb_color', + ])); + } + + public function testErrorWhenMissingRgb() + { + $this->assertNotSame(true, GUMP::is_valid([ + 'color' => '(255, 128, 0)', + ], [ + 'color' => 'rgb_color', + ])); + } + + public function testErrorWhenNonNumeric() + { + $this->assertNotSame(true, GUMP::is_valid([ + 'color' => 'rgb(a, b, c)', + ], [ + 'color' => 'rgb_color', + ])); + } + + public function testErrorWhenRgba() + { + $this->assertNotSame(true, GUMP::is_valid([ + 'color' => 'rgba(255, 128, 0, 1)', + ], [ + 'color' => 'rgb_color', + ])); + } +} diff --git a/tests/Validators/SnakeCaseValidatorTest.php b/tests/Validators/SnakeCaseValidatorTest.php new file mode 100644 index 00000000..f93295b5 --- /dev/null +++ b/tests/Validators/SnakeCaseValidatorTest.php @@ -0,0 +1,114 @@ +assertTrue(GUMP::is_valid([ + 'name' => 'hello_world', + ], [ + 'name' => 'snake_case', + ])); + } + + public function testSuccessWhenSingleWord() + { + $this->assertTrue(GUMP::is_valid([ + 'name' => 'hello', + ], [ + 'name' => 'snake_case', + ])); + } + + public function testSuccessWhenMultipleUnderscores() + { + $this->assertTrue(GUMP::is_valid([ + 'name' => 'my_variable_name', + ], [ + 'name' => 'snake_case', + ])); + } + + public function testSuccessWhenWithNumbers() + { + $this->assertTrue(GUMP::is_valid([ + 'name' => 'var_123', + ], [ + 'name' => 'snake_case', + ])); + + $this->assertTrue(GUMP::is_valid([ + 'name' => 'test_1_2_3', + ], [ + 'name' => 'snake_case', + ])); + } + + public function testErrorWhenCamelCase() + { + $this->assertNotSame(true, GUMP::is_valid([ + 'name' => 'helloWorld', + ], [ + 'name' => 'snake_case', + ])); + } + + public function testErrorWhenPascalCase() + { + $this->assertNotSame(true, GUMP::is_valid([ + 'name' => 'HelloWorld', + ], [ + 'name' => 'snake_case', + ])); + } + + public function testErrorWhenStartsWithNumber() + { + $this->assertNotSame(true, GUMP::is_valid([ + 'name' => '1_hello', + ], [ + 'name' => 'snake_case', + ])); + } + + public function testErrorWhenStartsWithUppercase() + { + $this->assertNotSame(true, GUMP::is_valid([ + 'name' => 'Hello_world', + ], [ + 'name' => 'snake_case', + ])); + } + + public function testErrorWhenWithHyphen() + { + $this->assertNotSame(true, GUMP::is_valid([ + 'name' => 'hello-world', + ], [ + 'name' => 'snake_case', + ])); + } + + public function testErrorWhenWithSpace() + { + $this->assertNotSame(true, GUMP::is_valid([ + 'name' => 'hello world', + ], [ + 'name' => 'snake_case', + ])); + } + + public function testErrorWhenEmptyAndRequired() + { + $this->assertNotSame(true, GUMP::is_valid([ + 'name' => '', + ], [ + 'name' => 'required|snake_case', + ])); + } +} diff --git a/tests/Validators/SocialHandleValidatorTest.php b/tests/Validators/SocialHandleValidatorTest.php new file mode 100644 index 00000000..80c72be7 --- /dev/null +++ b/tests/Validators/SocialHandleValidatorTest.php @@ -0,0 +1,141 @@ +assertTrue(GUMP::is_valid([ + 'handle' => 'username', + ], [ + 'handle' => 'social_handle', + ])); + } + + public function testSuccessWhenWithAtSymbol() + { + $this->assertTrue(GUMP::is_valid([ + 'handle' => '@username', + ], [ + 'handle' => 'social_handle', + ])); + } + + public function testSuccessWhenWithUnderscore() + { + $this->assertTrue(GUMP::is_valid([ + 'handle' => 'user_name', + ], [ + 'handle' => 'social_handle', + ])); + + $this->assertTrue(GUMP::is_valid([ + 'handle' => '@user_name', + ], [ + 'handle' => 'social_handle', + ])); + } + + public function testSuccessWhenWithNumbers() + { + $this->assertTrue(GUMP::is_valid([ + 'handle' => 'user123', + ], [ + 'handle' => 'social_handle', + ])); + + $this->assertTrue(GUMP::is_valid([ + 'handle' => '@user_123', + ], [ + 'handle' => 'social_handle', + ])); + } + + public function testSuccessWhenMinLength() + { + $this->assertTrue(GUMP::is_valid([ + 'handle' => 'a', + ], [ + 'handle' => 'social_handle', + ])); + + $this->assertTrue(GUMP::is_valid([ + 'handle' => '@a', + ], [ + 'handle' => 'social_handle', + ])); + } + + public function testSuccessWhenMaxLength() + { + $this->assertTrue(GUMP::is_valid([ + 'handle' => '123456789012345', // 15 chars + ], [ + 'handle' => 'social_handle', + ])); + } + + public function testErrorWhenTooLong() + { + $this->assertNotSame(true, GUMP::is_valid([ + 'handle' => '1234567890123456', // 16 chars + ], [ + 'handle' => 'social_handle', + ])); + } + + public function testErrorWhenEmptyAndRequired() + { + $this->assertNotSame(true, GUMP::is_valid([ + 'handle' => '', + ], [ + 'handle' => 'required|social_handle', + ])); + } + + public function testErrorWhenSpecialChars() + { + $this->assertNotSame(true, GUMP::is_valid([ + 'handle' => 'user!', + ], [ + 'handle' => 'social_handle', + ])); + + $this->assertNotSame(true, GUMP::is_valid([ + 'handle' => 'user#name', + ], [ + 'handle' => 'social_handle', + ])); + } + + public function testErrorWhenWithSpace() + { + $this->assertNotSame(true, GUMP::is_valid([ + 'handle' => 'user name', + ], [ + 'handle' => 'social_handle', + ])); + } + + public function testErrorWhenWithHyphen() + { + $this->assertNotSame(true, GUMP::is_valid([ + 'handle' => 'user-name', + ], [ + 'handle' => 'social_handle', + ])); + } + + public function testErrorWhenAtInMiddle() + { + $this->assertNotSame(true, GUMP::is_valid([ + 'handle' => 'user@name', + ], [ + 'handle' => 'social_handle', + ])); + } +} diff --git a/tests/Validators/TimezoneValidatorTest.php b/tests/Validators/TimezoneValidatorTest.php new file mode 100644 index 00000000..1c44a696 --- /dev/null +++ b/tests/Validators/TimezoneValidatorTest.php @@ -0,0 +1,81 @@ +assertTrue(GUMP::is_valid([ + 'tz' => 'America/New_York', + ], [ + 'tz' => 'timezone', + ])); + } + + public function testSuccessWhenValidEuropeanTimezone() + { + $this->assertTrue(GUMP::is_valid([ + 'tz' => 'Europe/London', + ], [ + 'tz' => 'timezone', + ])); + } + + public function testSuccessWhenValidAsianTimezone() + { + $this->assertTrue(GUMP::is_valid([ + 'tz' => 'Asia/Tokyo', + ], [ + 'tz' => 'timezone', + ])); + } + + public function testSuccessWhenUTC() + { + $this->assertTrue(GUMP::is_valid([ + 'tz' => 'UTC', + ], [ + 'tz' => 'timezone', + ])); + } + + public function testSuccessWhenAustralianTimezone() + { + $this->assertTrue(GUMP::is_valid([ + 'tz' => 'Australia/Sydney', + ], [ + 'tz' => 'timezone', + ])); + } + + public function testErrorWhenInvalidTimezone() + { + $this->assertNotSame(true, GUMP::is_valid([ + 'tz' => 'America/Invalid_City', + ], [ + 'tz' => 'timezone', + ])); + } + + public function testErrorWhenPartialTimezone() + { + $this->assertNotSame(true, GUMP::is_valid([ + 'tz' => 'New York', + ], [ + 'tz' => 'timezone', + ])); + } + + public function testErrorWhenEmptyAndRequired() + { + $this->assertNotSame(true, GUMP::is_valid([ + 'tz' => '', + ], [ + 'tz' => 'required|timezone', + ])); + } +} diff --git a/tests/Validators/UrlSlugValidatorTest.php b/tests/Validators/UrlSlugValidatorTest.php new file mode 100644 index 00000000..1c81f26c --- /dev/null +++ b/tests/Validators/UrlSlugValidatorTest.php @@ -0,0 +1,129 @@ +assertTrue(GUMP::is_valid([ + 'slug' => 'hello-world', + ], [ + 'slug' => 'url_slug', + ])); + } + + public function testSuccessWhenSingleWord() + { + $this->assertTrue(GUMP::is_valid([ + 'slug' => 'hello', + ], [ + 'slug' => 'url_slug', + ])); + } + + public function testSuccessWhenMultipleHyphens() + { + $this->assertTrue(GUMP::is_valid([ + 'slug' => 'my-awesome-post', + ], [ + 'slug' => 'url_slug', + ])); + } + + public function testSuccessWhenWithNumbers() + { + $this->assertTrue(GUMP::is_valid([ + 'slug' => 'test123', + ], [ + 'slug' => 'url_slug', + ])); + + $this->assertTrue(GUMP::is_valid([ + 'slug' => 'hello-world-123', + ], [ + 'slug' => 'url_slug', + ])); + } + + public function testSuccessWhenSingleCharacter() + { + $this->assertTrue(GUMP::is_valid([ + 'slug' => 'a', + ], [ + 'slug' => 'url_slug', + ])); + + $this->assertTrue(GUMP::is_valid([ + 'slug' => '9', + ], [ + 'slug' => 'url_slug', + ])); + } + + public function testErrorWhenUppercase() + { + $this->assertNotSame(true, GUMP::is_valid([ + 'slug' => 'Hello-World', + ], [ + 'slug' => 'url_slug', + ])); + } + + public function testErrorWhenStartsWithHyphen() + { + $this->assertNotSame(true, GUMP::is_valid([ + 'slug' => '-hello-world', + ], [ + 'slug' => 'url_slug', + ])); + } + + public function testErrorWhenEndsWithHyphen() + { + $this->assertNotSame(true, GUMP::is_valid([ + 'slug' => 'hello-world-', + ], [ + 'slug' => 'url_slug', + ])); + } + + public function testErrorWhenConsecutiveHyphens() + { + $this->assertNotSame(true, GUMP::is_valid([ + 'slug' => 'hello--world', + ], [ + 'slug' => 'url_slug', + ])); + } + + public function testErrorWhenWithSpace() + { + $this->assertNotSame(true, GUMP::is_valid([ + 'slug' => 'hello world', + ], [ + 'slug' => 'url_slug', + ])); + } + + public function testErrorWhenWithUnderscore() + { + $this->assertNotSame(true, GUMP::is_valid([ + 'slug' => 'hello_world', + ], [ + 'slug' => 'url_slug', + ])); + } + + public function testErrorWhenEmptyAndRequired() + { + $this->assertNotSame(true, GUMP::is_valid([ + 'slug' => '', + ], [ + 'slug' => 'required|url_slug', + ])); + } +} diff --git a/tests/Validators/ValidTimeValidatorTest.php b/tests/Validators/ValidTimeValidatorTest.php new file mode 100644 index 00000000..c9d6e469 --- /dev/null +++ b/tests/Validators/ValidTimeValidatorTest.php @@ -0,0 +1,120 @@ +assertTrue(GUMP::is_valid([ + 'time' => '12:30', + ], [ + 'time' => 'valid_time', + ])); + } + + public function testSuccessWhenValidTimeHHMMSS() + { + $this->assertTrue(GUMP::is_valid([ + 'time' => '12:30:45', + ], [ + 'time' => 'valid_time', + ])); + } + + public function testSuccessWhenMidnight() + { + $this->assertTrue(GUMP::is_valid([ + 'time' => '00:00', + ], [ + 'time' => 'valid_time', + ])); + + $this->assertTrue(GUMP::is_valid([ + 'time' => '00:00:00', + ], [ + 'time' => 'valid_time', + ])); + } + + public function testSuccessWhenEndOfDay() + { + $this->assertTrue(GUMP::is_valid([ + 'time' => '23:59', + ], [ + 'time' => 'valid_time', + ])); + + $this->assertTrue(GUMP::is_valid([ + 'time' => '23:59:59', + ], [ + 'time' => 'valid_time', + ])); + } + + public function testSuccessWhenSingleDigitHour() + { + $this->assertTrue(GUMP::is_valid([ + 'time' => '9:30', + ], [ + 'time' => 'valid_time', + ])); + } + + public function testErrorWhenHourTooHigh() + { + $this->assertNotSame(true, GUMP::is_valid([ + 'time' => '24:00', + ], [ + 'time' => 'valid_time', + ])); + + $this->assertNotSame(true, GUMP::is_valid([ + 'time' => '25:00', + ], [ + 'time' => 'valid_time', + ])); + } + + public function testErrorWhenMinuteTooHigh() + { + $this->assertNotSame(true, GUMP::is_valid([ + 'time' => '12:60', + ], [ + 'time' => 'valid_time', + ])); + } + + public function testErrorWhenSecondTooHigh() + { + $this->assertNotSame(true, GUMP::is_valid([ + 'time' => '12:30:60', + ], [ + 'time' => 'valid_time', + ])); + } + + public function testErrorWhenInvalidFormat() + { + $this->assertNotSame(true, GUMP::is_valid([ + 'time' => '12', + ], [ + 'time' => 'valid_time', + ])); + + $this->assertNotSame(true, GUMP::is_valid([ + 'time' => '12.30', + ], [ + 'time' => 'valid_time', + ])); + + $this->assertNotSame(true, GUMP::is_valid([ + 'time' => '1230', + ], [ + 'time' => 'valid_time', + ])); + } +} diff --git a/tests/Validators/WordCountValidatorTest.php b/tests/Validators/WordCountValidatorTest.php new file mode 100644 index 00000000..08ce6f17 --- /dev/null +++ b/tests/Validators/WordCountValidatorTest.php @@ -0,0 +1,99 @@ +assertTrue(GUMP::is_valid([ + 'text' => 'hello world this is a test', + ], [ + 'text' => 'word_count,min;1;max;10', + ])); + } + + public function testSuccessWhenAtMinBoundary() + { + $this->assertTrue(GUMP::is_valid([ + 'text' => 'hello', + ], [ + 'text' => 'word_count,min;1', + ])); + } + + public function testSuccessWhenAtMaxBoundary() + { + $this->assertTrue(GUMP::is_valid([ + 'text' => 'one two three', + ], [ + 'text' => 'word_count,max;3', + ])); + } + + public function testSuccessWhenNoConstraints() + { + $this->assertTrue(GUMP::is_valid([ + 'text' => 'any text here', + ], [ + 'text' => 'word_count', + ])); + } + + public function testSuccessWhenOnlyMin() + { + $this->assertTrue(GUMP::is_valid([ + 'text' => 'hello world', + ], [ + 'text' => 'word_count,min;2', + ])); + } + + public function testSuccessWhenOnlyMax() + { + $this->assertTrue(GUMP::is_valid([ + 'text' => 'hello', + ], [ + 'text' => 'word_count,max;5', + ])); + } + + public function testErrorWhenBelowMin() + { + $this->assertNotSame(true, GUMP::is_valid([ + 'text' => 'hello', + ], [ + 'text' => 'word_count,min;5', + ])); + } + + public function testErrorWhenAboveMax() + { + $this->assertNotSame(true, GUMP::is_valid([ + 'text' => 'one two three four five', + ], [ + 'text' => 'word_count,max;4', + ])); + } + + public function testSuccessWhenEmptyWithMinZero() + { + $this->assertTrue(GUMP::is_valid([ + 'text' => '', + ], [ + 'text' => 'word_count,min;0', + ])); + } + + public function testErrorWhenEmptyWithMinOneAndRequired() + { + $this->assertNotSame(true, GUMP::is_valid([ + 'text' => '', + ], [ + 'text' => 'required|word_count,min;1', + ])); + } +} From 3d4eb858112a09eef8fb31c7e834c1db7dffb3dd Mon Sep 17 00:00:00 2001 From: Sean N Date: Fri, 28 Nov 2025 22:31:12 +0200 Subject: [PATCH 3/3] Fixed angle bracket added by the linter --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 75168d37..d8915f73 100644 --- a/README.md +++ b/README.md @@ -483,7 +483,7 @@ GUMP includes 16 filters for data sanitization and transformation: | Filter | Description | |------------------------|-----------------------------------------------------------------------------------------------------------------------| -| **noise_words** | Replace noise words in a string (). | +| **noise_words** | Replace noise words in a string (http://tax.cchgroup.com/help/Avoiding_noise_words_in_your_search.htm). | | **rmpunctuation** | Remove all known punctuation from a string. | | **urlencode** | Sanitize the string by urlencoding characters. | | **htmlencode** | Sanitize the string by converting HTML characters to their HTML entities. |