Skip to content

Commit

Permalink
Add new futures
Browse files Browse the repository at this point in the history
  • Loading branch information
goloop committed Jul 4, 2023
1 parent efd1a4c commit f4bdf0f
Show file tree
Hide file tree
Showing 10 changed files with 399 additions and 22 deletions.
15 changes: 9 additions & 6 deletions bank_card.go
Original file line number Diff line number Diff line change
Expand Up @@ -169,12 +169,9 @@ func cardChecker(n string, regex *regexp.Regexp) bool {
ten = 57
)

// Remove all chracaters except numbers, and check if the result matches
// the given regex.
clean := g.Preserve(n, g.Numbers)
if !regex.MatchString(clean) {
return false
}
// We remove only the delimiters that can be in the card:
// a space and a dash (-) symbol.
clean := g.Weed(n, " -")

// Luhn algorithm.
p := len(clean) % 2
Expand All @@ -199,5 +196,11 @@ func cardChecker(n string, regex *regexp.Regexp) bool {
return false
}

// Additionally check for a regular expression, because different
// banks can have different initial codes.
if !regex.MatchString(clean) {
return false
}

return true
}
50 changes: 50 additions & 0 deletions bank_card_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,56 @@ import (
"testing"
)

// TestCardChecker tests the cardChecker function.
func TestCardChecker(t *testing.T) {
tests := []struct {
name string
in string
want bool
}{
{
name: "Card number with non-numeric characters",
in: "1234-5678-9012-abcd",
want: false,
},
{
name: "Card number with numeric characters out of range",
in: "1234-5678-9012-123:4",
want: false,
},
{
name: "Card number with slash",
in: "1234-5678-9012-123/4",
want: false,
},
{
name: "Card number with characters less than zero ASCII code",
in: "1234-5678-9012-123/",
want: false,
},
{
name: "Card number with characters greater than ten ASCII code",
in: "1234-5678-9012-123:",
want: false,
},
{
name: "Valid card number",
in: "4111-1111-1111-1111",
want: true,
},
}

regex := regexp.MustCompile(`^\d{16}$`)
for _, tc := range tests {
t.Run(tc.name, func(t *testing.T) {
got := cardChecker(tc.in, regex)
if got != tc.want {
t.Errorf("cardChecker(%q) = %v; want %v", tc.in, got, tc.want)
}
})
}
}

// TestBankCard tests the BankCard function.
func TestBankCard(t *testing.T) {
tests := []struct {
Expand Down
37 changes: 37 additions & 0 deletions bank_iban_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,43 @@ import (
"github.com/goloop/g"
)

func TestMapLetterToNumber(t *testing.T) {
tests := []struct {
name string
in rune
want int
}{
{
name: "Maps letter A to 10",
in: 'A',
want: 10,
},
{
name: "Maps letter B to 11",
in: 'B',
want: 11,
},
{
name: "Maps letter Z to 35",
in: 'Z',
want: 35,
},
{
name: "Maps undefined letter to 0",
in: '!',
want: 0,
},
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if got := mapLetterToNumber(tt.in); got != tt.want {
t.Errorf("mapLetterToNumber() = %v, want %v", got, tt.want)
}
})
}
}

// TestIBAN tests the IBAN function.
// Tests only IBAN function for large coverage.
func TestIBAN(t *testing.T) {
Expand Down
75 changes: 75 additions & 0 deletions code.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
package is

import "unicode"

// The varReservedWords holds a map of reserved words in Python, Go and C++.
// These words cannot be used as variable names.
var varReservedWords = map[string]struct{}{
"False": {}, "None": {}, "True": {}, "and": {}, "as": {}, "assert": {},
"async": {}, "await": {}, "break": {}, "class": {}, "continue": {},
"def": {}, "del": {}, "elif": {}, "else": {}, "except": {}, "finally": {},
"for": {}, "from": {}, "global": {}, "if": {}, "import": {}, "in": {},
"is": {}, "lambda": {}, "nonlocal": {}, "not": {}, "or": {}, "pass": {},
"raise": {}, "return": {}, "try": {}, "while": {}, "with": {}, "yield": {},
"default": {}, "func": {}, "interface": {}, "select": {}, "case": {},
"defer": {}, "go": {}, "map": {}, "struct": {}, "chan": {}, "goto": {},
"package": {}, "switch": {}, "const": {}, "fallthrough": {}, "range": {},
"type": {}, "var": {}, "asm": {}, "auto": {}, "bool": {}, "catch": {},
"char": {}, "const_cast": {}, "delete": {}, "do": {}, "double": {},
"dynamic_cast": {}, "enum": {}, "explicit": {}, "export": {}, "extern": {},
"float": {}, "friend": {}, "inline": {}, "int": {}, "long": {},
"mutable": {}, "namespace": {}, "new": {}, "operator": {}, "private": {},
"protected": {}, "public": {}, "register": {}, "reinterpret_cast": {},
"short": {}, "signed": {}, "sizeof": {}, "static": {}, "static_cast": {},
"template": {}, "this": {}, "throw": {}, "typedef": {}, "typeid": {},
"typename": {}, "union": {}, "unsigned": {}, "using": {}, "virtual": {},
"void": {}, "volatile": {}, "wchar_t": {},
}

// Var validates if the given string can be used as a variable
// name in most programming languages. The function checks if the
// name starts with a letter or underscore, if it doesn't contain
// any special characters or spaces, and if it's not a reserved
// word. Returns true if the given name is valid, false otherwise.
//
// Example usage:
//
// // Test a valid variable name
// fmt.Println(Var("myVar")) // Output: true
//
// // Test a name starting with a digit
// fmt.Println(Var("9myVar")) // Output: false
//
// // Test a name containing a space
// fmt.Println(Var("my Var")) // Output: false
//
// // Test a reserved word
// fmt.Println(Var("return")) // Output: false
func Var(v string) bool {
// Empty string is not a valid variable name.
if v == "" {
return false
}

// Split the string into runes.
r := []rune(v)

// Check if the name starts with a letter or underscore.
if !unicode.IsLetter(r[0]) && r[0] != '_' {
return false
}

// Check if the name doesn't contain any special characters or spaces.
for _, c := range r {
if !unicode.IsLetter(c) && !unicode.IsNumber(c) && c != '_' {
return false
}
}

// Check if the name is not a reserved word.
if _, ok := varReservedWords[v]; ok {
return false
}

return true
}
96 changes: 96 additions & 0 deletions code_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
package is

import "testing"

// TestVar tests the Var function.
func TestVar(t *testing.T) {
tests := []struct {
name string
in string
want bool
}{
{
name: "Standard variable name",
in: "myVar",
want: true,
},
{
name: "Variable name starting with underscore",
in: "_myVar",
want: true,
},
{
name: "Variable name with underscore",
in: "my_var",
want: true,
},
{
name: "Variable name with underscore and number",
in: "my_var_2",
want: true,
},
{
name: "Starts with a number",
in: "2myVar",
want: false,
},
{
name: "Contains space",
in: "my var",
want: false,
},
{
name: "Contains hyphen",
in: "my-var",
want: false,
},
{
name: "Contains special character",
in: "my@var",
want: false,
},
{
name: "Empty string",
in: "",
want: false,
},
{
name: "String with spaces",
in: " ",
want: false,
},
{
name: "Starts with a number, has underscore",
in: "_2",
want: true,
},
{
name: "Contains period",
in: "my.var",
want: false,
},
{
name: "Reserved keyword in Go",
in: "return",
want: false,
},
{
name: "Reserved keyword in Python",
in: "while",
want: false,
},
{
name: "Capitalized variable name",
in: "MyVar",
want: true,
},
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if got := Var(tt.in); got != tt.want {
t.Errorf("IsVarName() = %v, want %v", got, tt.want)
}
})
}
}
17 changes: 14 additions & 3 deletions hash.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,13 @@ var (
// - optionally, end with a sequence of 2 valid URL-safe Base64 characters
// followed by '==', or 3 valid URL-safe Base64 characters followed by
// '=', or 4 valid URL-safe Base64 characters.
//
// Note: all base64URL strings:
// `^(?:[A-Za-z0-9_-]{4})*((?:[A-Za-z0-9_-]{2,4})|` +
// `(?:[A-Za-z0-9+\\/]{2}==|[A-Za-z0-9+\\/]{3}=|` +
// `[A-Za-z0-9+\\/]{4}))$`
base64URLRegex = regexp.MustCompile(
`^(?:[A-Za-z0-9_-]{4})*((?:[A-Za-z0-9_-]{2,4})|` +
`(?:[A-Za-z0-9+\\/]{2}==|[A-Za-z0-9+\\/]{3}=|` +
`[A-Za-z0-9+\\/]{4}))$`,
`^([A-Za-z0-9_-]{4})*([A-Za-z0-9_-]{2}(==)?|[A-Za-z0-9_-]{3}=?)?$`,
)

// The hexRegex is a regex pattern used to validate hexadecimal strings.
Expand Down Expand Up @@ -77,6 +80,10 @@ var (
// Note: This function does not validate the content of the encoded data,
// just the format of Base64 strings.
func Base64(v string) bool {
if len(v) == 0 {
return false
}

return base64Regex.MatchString(v)
}

Expand Down Expand Up @@ -109,6 +116,10 @@ func Base64(v string) bool {
// Note: This function does not validate the content of the encoded data,
// just the format of URL-safe Base64 strings.
func Base64URL(v string) bool {
if len(v) == 0 {
return false
}

return base64URLRegex.MatchString(v)
}

Expand Down
Loading

0 comments on commit f4bdf0f

Please sign in to comment.