diff --git a/test/arrays.bats b/test/arrays.bats index cfee54f..bdbf7e1 100755 --- a/test/arrays.bats +++ b/test/arrays.bats @@ -91,7 +91,12 @@ teardown() { } @test "_inArray_: success" { - run _inArray_ one "${A[@]}" + run _inArray_ "one" "${A[@]}" + assert_success +} + +@test "_inArray_: success and ignore case" { + run _inArray_ -i "ONE" "${A[@]}" assert_success } diff --git a/test/strings.bats b/test/strings.bats index 3ab7219..546b1d5 100755 --- a/test/strings.bats +++ b/test/strings.bats @@ -57,6 +57,7 @@ setup() { set -o errtrace set -o nounset set -o pipefail + shopt -u nocasematch } teardown() { @@ -90,20 +91,30 @@ teardown() { } @test "_stringContains_: failure" { - run _stringContains_ "hello world!" "zebra" + run _stringContains_ "hello world!" "LO" assert_failure } +@test "_stringContains_: success, case insensitive" { + run _stringContains_ -i "hello world!" "LO" + assert_success +} + @test "_stringRegex_: success" { - run _stringRegex_ "hello world!" "[a-z].*!$" + run _stringRegex_ "hello world!" "^h[a-z ]+!$" assert_success } @test "_stringRegex_: failure" { - run _stringRegex_ "hello world!" "^.*[0-9]+" + run _stringRegex_ "Hello World!" "^h[a-z ]+!$" assert_failure } +@test "_stringRegex_: success, case insensitive" { + run _stringRegex_ -i "Hello World!" "^h[a-z ]+!$" + assert_success +} + _testCleanString_() { @@ -280,8 +291,21 @@ _testStopWords_ assert_output "#FFFFFF" } -@test "_regexCapture_: failure" { +@test "_regexCapture_: success, case insensitive" { + run _regexCapture_ -i "#FFFFFF" '^(#?([a-f0-9]{6}|[a-f0-9]{3}))$' || echo "no match found" + + assert_success + assert_output "#FFFFFF" +} + +@test "_regexCapture_: failure, no match found" { run _regexCapture_ "gggggg" '^(#?([a-fA-F0-9]{6}|[a-fA-F0-9]{3}))$' assert_failure } + +@test "_regexCapture_: failure, would only match with case insensitive" { + run _regexCapture_ "#FFFFFF" '^(#?([a-f0-9]{6}|[a-f0-9]{3}))$' || echo "no match found" + + assert_failure +} diff --git a/utilities/arrays.bash b/utilities/arrays.bash index 53ea523..d7e7f74 100644 --- a/utilities/arrays.bash +++ b/utilities/arrays.bash @@ -98,7 +98,7 @@ _forEachValidate_() { _forEachFind_() { # DESC: - # Iterates over elements, returning the first value that is validated by a function + # Iterates over elements, returning success and printing the first value that is validated by a function # ARGS: # $1 (Required) - Function name to pass each item to for validation. (Must return 0 on success) # OUTS: @@ -236,6 +236,8 @@ _inArray_() { # ARGS: # $1 (Required) - Value to search for # $2 (Required) - Array written as ${ARRAY[@]} + # OPTIONS: + # -i (Optional) - Ignore case # OUTS: # 0 if true # 1 if untrue @@ -248,11 +250,14 @@ _inArray_() { [[ $# -lt 2 ]] && fatal "Missing required argument to ${FUNCNAME[0]}" local opt - local _case_insensitive=false local OPTIND=1 while getopts ":iI" opt; do case ${opt} in - i | I) _case_insensitive=true ;; + i | I) + #shellcheck disable=SC2064 + trap "$(shopt -p nocasematch)" RETURN # reset nocasematch when function exits + shopt -s nocasematch # Use case-insensitive regex + ;; *) fatal "Unrecognized option '${1}' passed to ${FUNCNAME[0]}. Exiting." ;; esac done @@ -262,11 +267,7 @@ _inArray_() { local _value="${1}" shift for _array_item in "$@"; do - if [ ${_case_insensitive} = true ]; then - _value="$(echo "${_value}" | tr '[:upper:]' '[:lower:]')" - _array_item="$(echo "${_array_item}" | tr '[:upper:]' '[:lower:]')" - fi - [[ ${_array_item} == "${_value}" ]] && return 0 + [[ ${_array_item} =~ ^${_value}$ ]] && return 0 done return 1 } diff --git a/utilities/checks.bash b/utilities/checks.bash index 62fbe55..05d0afe 100644 --- a/utilities/checks.bash +++ b/utilities/checks.bash @@ -115,6 +115,11 @@ _isEmail_() { # _isEmail_ "somename+test@gmail.com" [[ $# == 0 ]] && fatal "Missing required argument to ${FUNCNAME[0]}" + + #shellcheck disable=SC2064 + trap "$(shopt -p nocasematch)" RETURN # reset nocasematch when function exits + shopt -s nocasematch # Use case-insensitive regex + local _emailRegex _emailRegex="^[a-z0-9!#\$%&'*+/=?^_\`{|}~-]+(\.[a-z0-9!#$%&'*+/=?^_\`{|}~-]+)*@([a-z0-9]([a-z0-9-]*[a-z0-9])?\.)+[a-z0-9]([a-z0-9-]*[a-z0-9])?\$" [[ ${1} =~ ${_emailRegex} ]] && return 0 || return 1 diff --git a/utilities/dates.bash b/utilities/dates.bash index 23a442f..94c4a5c 100644 --- a/utilities/dates.bash +++ b/utilities/dates.bash @@ -228,7 +228,9 @@ _parseDate_() { PARSE_DATE_FOUND="" PARSE_DATE_YEAR="" PARSE_DATE_MONTH="" PARSE_DATE_MONTH_NAME="" PARSE_DATE_DAY="" PARSE_DATE_HOUR="" PARSE_DATE_MINUTE="" - shopt -s nocasematch #Use case-insensitive regex + #shellcheck disable=SC2064 + trap "$(shopt -p nocasematch)" RETURN # reset nocasematch when function exits + shopt -s nocasematch # Use case-insensitive regex debug "_parseDate_() input ${tan}$date${purple}" diff --git a/utilities/strings.bash b/utilities/strings.bash index 3570862..ec986fd 100644 --- a/utilities/strings.bash +++ b/utilities/strings.bash @@ -236,6 +236,8 @@ _regexCapture_() { # ARGS: # $1 (Required) - Input String # $2 (Required) - Regex pattern + # OPTIONS: + # -i (Optional) - Ignore case # OUTS: # 0 - Regex matched # 1 - Regex did not match @@ -248,6 +250,20 @@ _regexCapture_() { # CREDIT: # https://github.com/dylanaraps/pure-bash-bible + local opt + local OPTIND=1 + while getopts ":iI" opt; do + case ${opt} in + i | I) + #shellcheck disable=SC2064 + trap "$(shopt -p nocasematch)" RETURN # reset nocasematch when function exits + shopt -s nocasematch # Use case-insensitive regex + ;; + *) fatal "Unrecognized option '${1}' passed to ${FUNCNAME[0]}. Exiting." ;; + esac + done + shift $((OPTIND - 1)) + [[ $# -lt 2 ]] && fatal "Missing required argument to ${FUNCNAME[0]}" if [[ $1 =~ $2 ]]; then @@ -300,12 +316,28 @@ _stringContains_() { # ARGS: # $1 (Required) - String to be tested # $2 (Required) - Substring to be tested for + # OPTIONS: + # -i (Optional) - Ignore case # OUTS: # 0 - Search pattern found # 1 - Pattern not found # USAGE: # _stringContains_ "Hello World!" "lo" + local opt + local OPTIND=1 + while getopts ":iI" opt; do + case ${opt} in + i | I) + #shellcheck disable=SC2064 + trap "$(shopt -p nocasematch)" RETURN # reset nocasematch when function exits + shopt -s nocasematch # Use case-insensitive searching + ;; + *) fatal "Unrecognized option '${1}' passed to ${FUNCNAME[0]}. Exiting." ;; + esac + done + shift $((OPTIND - 1)) + [[ $# -lt 2 ]] && fatal "Missing required argument to ${FUNCNAME[0]}" if [[ ${1} == *${2}* ]]; then @@ -321,11 +353,28 @@ _stringRegex_() { # ARGS: # $1 (Required) - String to be tested # $2 (Required) - Regex pattern to be tested for + # OPTIONS: + # -i (Optional) - Ignore case # OUTS: # 0 - Search pattern found # 1 - Pattern not found # USAGE: # _stringContains_ "HELLO" "^[A-Z]*$" + # _stringContains_ -i "HELLO" "^[a-z]*$" + + local opt + local OPTIND=1 + while getopts ":iI" opt; do + case ${opt} in + i | I) + #shellcheck disable=SC2064 + trap "$(shopt -p nocasematch)" RETURN # reset nocasematch when function exits + shopt -s nocasematch # Use case-insensitive regex + ;; + *) fatal "Unrecognized option '${1}' passed to ${FUNCNAME[0]}. Exiting." ;; + esac + done + shift $((OPTIND - 1)) [[ $# -lt 2 ]] && fatal "Missing required argument to ${FUNCNAME[0]}"