Skip to content

Commit

Permalink
implement explode() and improve unit test
Browse files Browse the repository at this point in the history
  • Loading branch information
zamronypj committed Nov 16, 2022
1 parent a5928f3 commit 9a5966f
Show file tree
Hide file tree
Showing 12 changed files with 267 additions and 48 deletions.
78 changes: 76 additions & 2 deletions src/Helpers/StringUtils.pas
Original file line number Diff line number Diff line change
Expand Up @@ -46,11 +46,25 @@ interface
*-----------------------------------------------*)
function slug(const originalStr : string) : string;

(*!------------------------------------------------
* explode string by delimiter as array of string
*-----------------------------------------------
* @param cDelimiter string to separate each
* @param sValues string to explode
* @param iCount max number string to return, 0 means find all string.
* @return array of string
*------------------------------------------------
* @credit https://www.matthewhipkin.co.uk/codelib/cgi-mailform-using-freepascal/
* @credit http://www.jasonwhite.co.uk/delphi-explode-function-like-php-explode/
*-----------------------------------------------*)
function explode(const cDelimiter, sValue : string; iCount : integer = 0) : TStringArray;

implementation

uses

regexpr;
regexpr,
strutils;

(*!------------------------------------------------
* join array of string with a delimiter
Expand Down Expand Up @@ -101,9 +115,69 @@ implementation
function slug(const originalStr : string) : string;
begin
result := trim(originalStr);
if (result <> '') then
if (result = '') then
begin
exit;
end;

//bugfix for FPC 3.0.4 which does not support \W
{$IF FPC_FULLVERSION > 30004}
result := ReplaceRegExpr('[\W\s]+', lowercase(result), '-', true);
{$ELSE}
result := ReplaceRegExpr(
'[~!@#$%^&*()_\-+={}\[\]|\\:;"''<>,.?/\s]+',
lowercase(result),
'-',
true
);
{$ENDIF}

// remove - from beginning if any
if pos('-', result) = 1 then
begin
result := copy(result, 2, length(result) - 1);
end;

// remove - from end if any
if rpos('-', result) = length(result) then
begin
result := copy(result, 1, length(result) - 1);
end;
end;

(*!------------------------------------------------
* explode string by delimiter as array of string
*-----------------------------------------------
* @param cDelimiter string to separate each
* @param sValues string to explode
* @param iCount max number string to return, 0 means find all string.
* @return array of string
*------------------------------------------------
* @credit https://www.matthewhipkin.co.uk/codelib/cgi-mailform-using-freepascal/
* @credit http://www.jasonwhite.co.uk/delphi-explode-function-like-php-explode/
*-----------------------------------------------*)
function explode(const cDelimiter, sValue : string; iCount : integer = 0) : TStringArray;
var
s : string;
i, p: integer;
begin
s := sValue;
i := 0;
result := nil;
while length(s) > 0 do
begin
inc(i);
SetLength(result, i);
p := pos(cDelimiter, s);
if (p > 0) and ((i < iCount) or (iCount=0)) then
begin
result[i-1] := copy(s, 0, p-1);
s := copy(s, p + length(cDelimiter), length(s));
end else
begin
result[i-1] := s;
s := '';
end;
end;
end;
end.
23 changes: 23 additions & 0 deletions src/Helpers/Tests/HelpersTest.pas
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
{*!
* Fano Web Framework (https://fanoframework.github.io)
*
* @link https://github.com/fanoframework/fano
* @copyright Copyright (c) 2018 - 2022 Zamrony P. Juhara
* @license https://github.com/fanoframework/fano/blob/master/LICENSE (MIT)
*}

unit HelpersTest;

interface

{$MODE OBJFPC}
{$H+}

uses

fpcunit,
testregistry,
StringUtilsTest;

implementation
end.
120 changes: 120 additions & 0 deletions src/Helpers/Tests/StringUtilsTest.pas
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
{*!
* Fano Web Framework (https://fanoframework.github.io)
*
* @link https://github.com/fanoframework/fano
* @copyright Copyright (c) 2018 - 2022 Zamrony P. Juhara
* @license https://github.com/fanoframework/fano/blob/master/LICENSE (MIT)
*}

unit StringUtilsTest;

interface

{$MODE OBJFPC}
{$H+}

uses

fpcunit,
testregistry,
SysUtils,
StringUtils;

type

(*!------------------------------------------------
* string utilities test case
*--------------------------------------------------
* @author Zamrony P. Juhara <[email protected]>
*-------------------------------------------------*)
TStringUtilsTest = class(TTestCase)
protected
procedure Setup(); override;
procedure TearDown(); override;
published
procedure TestJoinMultipleShouldPass();
procedure TestJoinSingleShouldPass();
procedure TestJoinEmptyShouldPass();
procedure TestExplodeEmptyShouldPass();
procedure TestExplodeSingleShouldPass();
procedure TestExplodeMultipleShouldPass();
procedure TestSlugShouldReturnCorrectSlug();
end;

implementation


procedure TStringUtilsTest.Setup();
begin
end;

procedure TStringUtilsTest.TearDown();
begin
end;

procedure TStringUtilsTest.TestJoinMultipleShouldPass();
var joinedStr : string;
begin
joinedStr := join('&', [ 'a=b', 'c=d', 'e=f']);
AssertEquals('a=b&c=d&e=f', joinedStr);
end;

procedure TStringUtilsTest.TestJoinEmptyShouldPass();
var joinedStr : string;
begin
joinedStr := join('&', []);
AssertEquals('', joinedStr);
end;

procedure TStringUtilsTest.TestJoinSingleShouldPass();
var joinedStr : string;
begin
joinedStr := join('&', [ 'a=b']);
AssertEquals('a=b', joinedStr);
end;

procedure TStringUtilsTest.TestExplodeEmptyShouldPass();
var explodedStr : TStringArray;
len : integer;
begin
explodedStr := explode('&', '');
len := length(explodedStr);
AssertEquals(0, len);
end;

procedure TStringUtilsTest.TestExplodeSingleShouldPass();
var explodedStr : TStringArray;
len : integer;
begin
explodedStr := explode('&', 'a=b');
len := length(explodedStr);
AssertEquals(len, 1);
AssertEquals('a=b', explodedStr[0]);
end;

procedure TStringUtilsTest.TestExplodeMultipleShouldPass();
var explodedStr : TStringArray;
len : integer;
begin
explodedStr := explode('&', 'a=b&c=d&e=f');
len := length(explodedStr);
AssertEquals(3, len);
AssertEquals('a=b', explodedStr[0]);
AssertEquals('c=d', explodedStr[1]);
AssertEquals('e=f', explodedStr[2]);
end;

procedure TStringUtilsTest.TestSlugShouldReturnCorrectSlug();
begin
AssertEquals('', slug(''));
AssertEquals('', slug(' '));
AssertEquals('test-hei-slug-to-slug-10', slug('test hei$#@slug to Slug 10'));
AssertEquals('test-hei-slug-to-slug-10', slug(' test hei$#@slug to Slug 10 '));
AssertEquals('test-hei-slug-to-slug-10', slug('@#@!test hei$#@slug to Slug 10#@@'));
AssertEquals('test-hei-slug-to-slug-10', slug('@#@!test---hei$#@slug-to Slug 10#@@'));
AssertEquals('test-hei-slug-to-slug-10', slug('@#@!test--^-hei$#@slug-to Slug 10#@@'));
end;

initialization
RegisterTest(TStringUtilsTest);
end.
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,6 @@ TLongitudeValidator = LongitudeValidatorImpl.TLongitudeValidator;
TAtLeastOneAlphaValidator = AtLeastOneAlphaValidatorImpl.TAtLeastOneAlphaValidator;
TAtLeastOneLowerAlphaValidator = AtLeastOneLowerAlphaValidatorImpl.TAtLeastOneLowerAlphaValidator;
TAtLeastOneUpperAlphaValidator = AtLeastOneUpperAlphaValidatorImpl.TAtLeastOneUpperAlphaValidator;
TAtLeastOneDigitValidator = AtLeastOneDigitValidatorImpl.TAtLeastDigitAlphaValidator;
TAtLeastOneSymbolValidator = AtLeastOneSymbolValidatorImpl.TAtLeastSymbolAlphaValidator;
TAtLeastOneDigitValidator = AtLeastOneDigitValidatorImpl.TAtLeastOneDigitValidator;
TAtLeastOneSymbolValidator = AtLeastOneSymbolValidatorImpl.TAtLeastOneSymbolValidator;
TMixedCapsValidator = MixedCapsValidatorImpl.TMixedCapsValidator;
Original file line number Diff line number Diff line change
Expand Up @@ -124,3 +124,10 @@ EndWithValidatorImpl,

LatitudeValidatorImpl,
LongitudeValidatorImpl,

AtLeastOneAlphaValidatorImpl,
AtLeastOneDigitValidatorImpl,
AtLeastOneLowerAlphaValidatorImpl,
AtLeastOneUpperAlphaValidatorImpl,
AtLeastOneSymbolValidatorImpl,
MixedCapsValidatorImpl,
Original file line number Diff line number Diff line change
Expand Up @@ -60,47 +60,46 @@ implementation
var resValid : boolean;
begin
resValid := fValidator.isValid('my_key', fData, fRequest);
AssertEquals(resValid, true)
AssertEquals(true, resValid);
end;

procedure TAtLeastOneAlphaValidatorTest.TestInputContainsDigitsShouldFails();
var resValid : boolean;
begin
resValid := fValidator.isValid('my_digit', fData, fRequest);
AssertEquals(resValid, false)
AssertEquals(false, resValid);
end;

procedure TAtLeastOneAlphaValidatorTest.TestSymbolOnlyInputShouldFails();
var resValid : boolean;
begin
resValid := fValidator.isValid('my_symbol', fData, fRequest);
AssertEquals(resValid, false)
AssertEquals(false, resValid);
end;

procedure TAtLeastOneAlphaValidatorTest.TestSymbolWithAlphaInputShouldPass();
var resValid : boolean;
begin
resValid := fValidator.isValid('my_letter_symbol', fData, fRequest);
AssertEquals(resValid, true)
AssertEquals(true, resValid);
end;

procedure TAtLeastOneAlphaValidatorTest.TestOneAlphaInputShouldPass();
var resValid : boolean;
begin
resValid := fValidator.isValid('my_a', fData, fRequest);
AssertEquals(resValid, true)
AssertEquals(true, resValid);
end;

procedure TAtLeastOneAlphaValidatorTest.TestMixedAlphaCapsInputShouldPass();
var resValid : boolean;
begin
resValid := fValidator.isValid('my_abcd', fData, fRequest);
AssertEquals(resValid, true)
AssertEquals(true, resValid);
end;

initialization

RegisterTest(TAtLeastOneAlphaValidatorTest);

end.

Original file line number Diff line number Diff line change
Expand Up @@ -58,37 +58,36 @@ implementation

procedure TAtLeastOneDigitValidatorTest.TestInputContainsAlphaShouldFails();
begin
AssertEquals(fValidator.isValid('my_key', fData, fRequest), false);
AssertEquals(false, fValidator.isValid('my_key', fData, fRequest));
end;

procedure TAtLeastOneDigitValidatorTest.TestInputContainsDigitsShouldPass();
begin
AssertEquals(fValidator.isValid('my_digit', fData, fRequest), true);
AssertEquals(true, fValidator.isValid('my_digit', fData, fRequest));
end;

procedure TAtLeastOneDigitValidatorTest.TestSymbolOnlyInputShouldFails();
begin
AssertEquals(fValidator.isValid('my_symbol', fData, fRequest), false);
AssertEquals(false, fValidator.isValid('my_symbol', fData, fRequest));
end;

procedure TAtLeastOneDigitValidatorTest.TestSymbolWithAlphaInputShouldFails();
begin
AssertEquals(fValidator.isValid('my_letter_symbol', fData, fRequest), false);
AssertEquals(false, fValidator.isValid('my_letter_symbol', fData, fRequest));
end;

procedure TAtLeastOneDigitValidatorTest.TestOneAlphaInputShouldFails();
begin
AssertEquals(fValidator.isValid('my_a', fData, fRequest), false);
AssertEquals(false, fValidator.isValid('my_a', fData, fRequest));
end;

procedure TAtLeastOneDigitValidatorTest.TestMixedAlphaCapsInputShouldFails();
begin
AssertEquals(fValidator.isValid('my_abcd', fData, fRequest), false);
AssertEquals(false, fValidator.isValid('my_abcd', fData, fRequest));
end;

initialization

RegisterTest(TAtLeastOneDigitValidatorTest);

end.

Loading

0 comments on commit 9a5966f

Please sign in to comment.