Skip to content

Commit

Permalink
Wrapper created and some bug fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
MaestroError committed Feb 27, 2024
1 parent 83c48f2 commit d421e94
Show file tree
Hide file tree
Showing 7 changed files with 299 additions and 10 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ on:
# branches: [main]

jobs:
build:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
Expand Down
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,10 +48,10 @@ Examples: `->exact("hello world", false, "1+")`

- Add facade for Laravel
- Wrap Builder in class for static start
- "string" and "source" for builder start
- "start" and "pattern" for builderPattern start
- "string" and "source" for builder start✔️
- "start" and "pattern" for builderPattern start✔️
- Write documentation (add credit for https://regexr.com/ and ChatGPT)
- Add automated tests on PR creation or on marging to main branch
- Add automated tests on PR creation or on marging to main branch ✔️

##### Coming next

Expand Down
5 changes: 3 additions & 2 deletions src/Builder.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@
use Maestroerror\EloquentRegex\Contracts\BuilderContract;
use Maestroerror\EloquentRegex\OptionsManager;
use Maestroerror\EloquentRegex\OptionsBuilder;
use Maestroerror\EloquentRegex\Traits\BuilderPatternTraits\BuilderPatternMethods;
use Maestroerror\EloquentRegex\Traits\BuilderTraits\BuilderPatternMethods;
use Maestroerror\EloquentRegex\Traits\BuilderTraits\InitMethods;
use Maestroerror\EloquentRegex\Patterns\TextOrNumbersPattern;
use Maestroerror\EloquentRegex\Patterns\EmailPattern;
use Maestroerror\EloquentRegex\Patterns\UrlPattern;
Expand All @@ -26,7 +27,7 @@

class Builder implements BuilderContract {

use BuilderPatternMethods;
use BuilderPatternMethods, InitMethods;

/**
* The string to be processed with regex.
Expand Down
29 changes: 29 additions & 0 deletions src/EloquentRegex.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
<?php

namespace Maestroerror\EloquentRegex;

use Maestroerror\EloquentRegex\Builder;


class EloquentRegex {

public static function string(string $str) {
return (new Builder)->source($str);
}

public static function source(string $str) {
return (new Builder)->source($str);
}

public static function start(string $str) {
return (new Builder)->source($str)->start();
}

public static function customPattern(string $str) {
return (new Builder)->source($str)->start();
}

public static function builder() {
return new Builder;
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<?php

namespace Maestroerror\EloquentRegex\Traits\BuilderPatternTraits;
namespace Maestroerror\EloquentRegex\Traits\BuilderTraits;

use Maestroerror\EloquentRegex\Patterns\BuilderPattern;
use Maestroerror\EloquentRegex\Contracts\BuilderContract;
Expand Down Expand Up @@ -38,15 +38,15 @@ public function start(): BuilderPattern {
* @param callable|null $callback A callback function that receives a BuilderPattern instance to define the regex pattern.
* @return BuilderContract|BuilderPattern Returns the main Builder instance after the pattern is defined.
*/
public function pattern(callable|null $callback): BuilderContract|BuilderPattern {
public function pattern(callable|null $callback = null): BuilderContract|BuilderPattern {
if (is_null($callback)) {
return $this->start();
}
// Pass the current Builder instance to the BuilderPattern
$this->pattern = new BuilderPattern($this);
// Run callback to create pattern
$builderPattern = $callback($this->pattern);
$callback($this->pattern);
// return back the Builder object
return $builderPattern->end();
return $this->pattern->end();
}
}
19 changes: 19 additions & 0 deletions src/Traits/BuilderTraits/InitMethods.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<?php

namespace Maestroerror\EloquentRegex\Traits\BuilderTraits;

use Maestroerror\EloquentRegex\Patterns\BuilderPattern;
use Maestroerror\EloquentRegex\Contracts\BuilderContract;

/**
* trait BuilderPatternMethods
*
* Used in Maestroerror\EloquentRegex\Builder class to enhance it with starting methods
*/
trait InitMethods {

public function source(string $str): self {
$this->setString($str);
return $this;
}
}
240 changes: 240 additions & 0 deletions tests/Feature/EloquentRegexTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,240 @@
<?php

use Maestroerror\EloquentRegex\EloquentRegex;

// Custom Pattern tests:

it('reproduces alt prefix pattern from HSA using facade', function () {
$regex = EloquentRegex::builder()->start()
->exact("alt=")
->group(function ($pattern) {
$pattern->doubleQuote()->orPattern(function ($pattern) {
$pattern->singleQuote();
});
})->toRegex();

expect($regex)->toBe("alt\=(\"|')");
});

it('reproduces hashtag prefix pattern from HSA using facade', function () {
$regex = EloquentRegex::builder()->start()
->lookBehind(function ($pattern) {
$pattern->charSet(function ($pattern) {
$pattern->doubleQuote()->closeAngleBracket()->addRawRegex("\\s");
});
})->hash()->toRegex();

expect($regex)->toBe('(?<=["\>\s])\#');
});

it('reproduces Text suffix pattern from HSA using facade', function () {
$regex = EloquentRegex::builder()->start()
->openAngleBracket()->slash()->alphanumericRange(0, 10)->closeAngleBracket()
->toRegex();

expect($regex)->toBe('\<\/[a-zA-Z0-9]{0,10}\>');
});

it('constructs regex for simple email validation using facade', function () {
$regex = EloquentRegex::builder()->start()
->textLowercase()
->atSymbol()
->textLowercase()
->dot()
->textLowercaseRange(2, 4)
->toRegex();

expect($regex)->toBe('[a-z]+@[a-z]+\.[a-z]{2,4}');
});

it('constructs regex for URL validation using facade', function () {
$regex = EloquentRegex::builder()->pattern()
->exact(['http', 'https'])
->colon()
->doubleSlash()
->text()
->dot()
->text()
->toRegex();

expect($regex)->toBe('(http|https)\:\/\/[a-zA-Z]+\.[a-zA-Z]+');
});

it('constructs regex for specific phone number format using facade', function () {
$regex = EloquentRegex::builder()->pattern(function ($p) {
$p->openParenthesis()->digits(3)->closeParenthesis()
->space()
->digits(3)->dash()->digits(4);
})->toRegex();

expect($regex)->toBe('\(\d{3}\) \d{3}\-\d{4}');
});

it('extracts dates in specific format from text using facade', function () {
$matches = EloquentRegex::customPattern("Meeting on 2021-09-15 and 2021-10-20")
->digits(4)
->dash()
->digits(2)
->dash()
->digits(2)
->get();

expect($matches)->toEqual(['2021-09-15', '2021-10-20']);
});

it('validates usernames in a string using facade', function () {
$check = EloquentRegex::customPattern("Users: user_123, JohnDoe99")
->alphanumeric()
->underscore("?")
->digitsRange(0, 2)
->checkString();

expect($check)->toBeTrue();
});

it('extracts hashtags from text using facade', function () {
$matches = EloquentRegex::start("#hello #world This is a #test")
->hash()
->text()
->get();

expect($matches)->toEqual(['#hello', '#world', '#test']);
});

it('extracts secret coded messages from text using facade', function () {
$text = "Normal text {secret: message one} more text {secret: another hidden text} end";
$matches = EloquentRegex::start($text)
->lookBehind(function ($pattern) {
$pattern->openCurlyBrace()->exact('secret: ');
})
->lazy()->anyChar()
->lookAhead(function ($pattern) {
$pattern->closeCurlyBrace();
})
->get();

expect($matches)->toEqual(['message one', 'another hidden text']);
});

// Ready-to-use pattern tests:

// TextOrNumbersPattern
it('validates text with numbers correctly', function () {
$builder = EloquentRegex::source("Text123");

$check = $builder->textOrNumbers()->check();

expect($check)->toBeTrue();
});

// EmailPattern
it('validates an email address correctly', function () {
$builder = EloquentRegex::source("[email protected]");

$check = $builder->email()->check();

expect($check)->toBeTrue();
});

// DomainNamePattern
it('validates a domain name correctly', function () {
$builder = EloquentRegex::string("example.com");

$check = $builder->domainName()->check();

expect($check)->toBeTrue();
});

// DatePattern
it('validates a date format correctly', function () {
$builder = EloquentRegex::string("2023-01-01");

$check = $builder->date('Y-m-d')->check();

expect($check)->toBeTrue();
});

// TimePattern
it('validates a time format correctly', function () {
$builder = EloquentRegex::string("23:59");

$check = $builder->time('H:i')->check();

expect($check)->toBeTrue();
});

// IPAddressPattern
it('validates an IPv4 address correctly', function () {
$builder = EloquentRegex::string("192.168.1.1");

$check = $builder->ipAddress()->check();

expect($check)->toBeTrue();
});

// IPv6AddressPattern
it('validates an IPv6 address correctly', function () {
$builder = EloquentRegex::string("2001:0db8:85a3:0000:0000:8a2e:0370:7334");

$check = $builder->ipv6Address()->check();

expect($check)->toBeTrue();
});

// CreditCardNumberPattern
it('validates a credit card number correctly', function () {
$builder = EloquentRegex::source("4111111111111111"); // A common Visa test number

$check = $builder->creditCardNumber()->check();

expect($check)->toBeTrue();
});

// PhonePattern
it('validates a phone number correctly', function () {
$builder = EloquentRegex::string("+1 (123) 456-7890");

$check = $builder->phone()->check();

expect($check)->toBeTrue();
});

// UsernamePattern
it('validates a username correctly', function () {
$builder = EloquentRegex::string("user_123");

$check = $builder->username()->check();

expect($check)->toBeTrue();
});

// HtmlTagPattern
it('identifies HTML content correctly', function () {
$builder = EloquentRegex::source("<div>example</div>");

$check = $builder->htmlTag()->check();

expect($check)->toBeTrue();
});

// CurrencyPattern
it('validates currency format correctly', function () {
$builder = EloquentRegex::string("$100.00");

$check = $builder->currency()->check();

expect($check)->toBeTrue();
});

// FilePathPattern
it('validates a Unix file path correctly', function () {
$string = "/user/directory/file.txt";
$builder = EloquentRegex::string($string);

$check = $builder->filePath([
"isDirectory" => false,
"isFile" => "txt",
])->check();

expect($check)->toBeTrue();
});

0 comments on commit d421e94

Please sign in to comment.