From 12f75e415fd7c3e68d70c2164c369804776d002f Mon Sep 17 00:00:00 2001 From: edwmurph Date: Wed, 30 May 2018 17:53:39 -0400 Subject: [PATCH] significantly increased test coverage; fixed a couple edge cases --- nvm.sh | 51 ++-- .../Unit tests/nvm_get_node_from_pkg_json | 252 ++++-------------- .../fast/Unit tests/nvm_interpret_node_semver | 67 +++++ test/fast/Unit tests/nvm_interpret_semver | 38 --- test/fast/Unit tests/nvm_is_valid_semver | 57 ++-- test/fast/Unit tests/nvm_string_equals_regexp | 26 +- ...vm_trim_and_reduce_whitespace_to_one_space | 28 ++ test/fast/Unit tests/nvm_validate_semver | 17 +- .../Unit tests/sharedTestResources/semvers | 187 +++++++++++++ 9 files changed, 433 insertions(+), 290 deletions(-) create mode 100755 test/fast/Unit tests/nvm_interpret_node_semver delete mode 100755 test/fast/Unit tests/nvm_interpret_semver create mode 100755 test/fast/Unit tests/nvm_trim_and_reduce_whitespace_to_one_space create mode 100755 test/fast/Unit tests/sharedTestResources/semvers diff --git a/nvm.sh b/nvm.sh index c57d43d..fddc939 100644 --- a/nvm.sh +++ b/nvm.sh @@ -299,6 +299,7 @@ nvm_find_up() { nvm_echo "${path_}" } +# NOTE: this function only validates across one line nvm_string_contains_regexp() { local string string="${1-}" @@ -324,6 +325,16 @@ nvm_is_valid_semver() { fi } +# TODO figure out if the commented out logic is needed anywhere +nvm_trim_and_reduce_whitespace_to_one_space() { + command printf "%s" "${1-}" | + command tr -d '\n\r' | + command tr '\t' ' ' | + command tr -s ' ' | + command sed 's/^ //; s/ $//; s/^ //' +} + +# TODO rename this function to 'nvm_normalize_semver' # Attempts to convert given semver to the following grammar: # # semver ::= comparator_set ( ' || ' comparator_set )* @@ -332,7 +343,7 @@ nvm_is_valid_semver() { nvm_validate_semver() { # split the semantic version into comparator_set's local semver - semver=$(command printf "%s" "${1-}" | command tr '||' '\n') + semver=$(nvm_trim_and_reduce_whitespace_to_one_space "${1-}" | command tr '||' '\n') if [ -z "$semver" ]; then return 1 fi @@ -354,6 +365,9 @@ nvm_validate_semver() { # normalize all wildcards to x s/X|\*/x/g; + # space out numbers surrounding '-' + s/ ?- ?/ - /g; + # ' 1 ' => ' 1.x.x ' # ' x ' => ' x.x.x ' s/ ([0-9]+|x) / \1.x.x /g; @@ -373,10 +387,12 @@ nvm_validate_semver() { # ' = 1.2.3 ' => ' =1.2.3 ' # ' ~ 1.2.3 ' => ' ~1.2.3 ' # ' ^ 1.2.3 ' => ' ^1.2.3 ' - s/ (<|>|<=|>=|=|~|\^) (([0-9]+|x)\.([0-9]+|x)\.([0-9]+|x)) / \1\2 /g; + # ' v 1.2.3 ' => ' v1.2.3 ' + s/ (v|<|>|<=|>=|=|~|\^) (([0-9]+|x)\.([0-9]+|x)\.([0-9]+|x)) / \1\2 /g; # ' =1.2.3 ' => ' 1.2.3 ' - s/ =//g; + # ' v1.2.3 ' => ' 1.2.3 ' + s/ (=|v)//g; " \ | command awk '{ # handle conversions of comparators with '^' or '~' or 'x' into required grammar @@ -506,7 +522,7 @@ nvm_interpret_complex_semver() { # - Add discovered version to highest_compatible_versions and stop iterating through versions for current_comparator_set. while [ -n "$version_list_copy" ]; do local current_version - current_version=$(command printf "%s" "$version_list_copy" | command tail -n1 | command sed -E 's/^ +//;s/ +$//' | nvm_grep -o '[0-9]\+\.[0-9]\+\.[0-9]\+$') + current_version=$(command printf "%s" "$version_list_copy" | command tail -n1 | command sed -E 's/^ +//;s/ +$//' | nvm_grep -o '^[0-9]\+\.[0-9]\+\.[0-9]\+$') version_list_copy=$(command printf "%s" "$version_list_copy" | command sed '$d') [ -n "$current_version" ] || continue @@ -635,16 +651,18 @@ nvm_interpret_simple_semver() { return 1 fi local stripped_version_from_semver - stripped_version_from_semver="$(command printf "%s" "$semver" | nvm_grep -o '[0-9]\+\.[0-9]\+\.[0-9]\+$')" + stripped_version_from_semver="$(command printf "%s" "$semver" | nvm_grep -o '^[0-9]\+\.[0-9]\+\.[0-9]\+$')" local newest_version_from_list - newest_version_from_list=$(command printf "%s" "$version_list" | tail -n 1 | nvm_grep -o '[0-9]\+\.[0-9]\+\.[0-9]\+$') + newest_version_from_list=$(command printf "%s" "$version_list" | tail -n 1 | nvm_grep -o '^[0-9]\+\.[0-9]\+\.[0-9]\+$') if [ -z "$stripped_version_from_semver" ] || [ -z "$newest_version_from_list" ]; then return 1 fi + local retrieved_version # if the semver is looking for an exact match, and it exists in the provided list of versions, resolve to that version if nvm_string_contains_regexp "$semver" '^[0-9]+\.[0-9]+\.[0-9]+$'; then - if nvm_string_contains_regexp "$version_list" "^v$stripped_version_from_semver$"; then - command printf "%s" "$stripped_version_from_semver" + retrieved_version=$(command printf "%s" "$version_list" | nvm_grep "^$stripped_version_from_semver$") + if [ -n "$retrieved_version" ]; then + command printf "%s" "$retrieved_version" return 0 else # TODO we know it's not worth doing the complex semver interpratation at this point @@ -653,11 +671,12 @@ nvm_interpret_simple_semver() { # Semver is looking for the newest version that is <= to a sepcific version, and the version exists in the provided list of versions, resolve to that version elif nvm_string_contains_regexp "$semver" '^<=[0-9]+\.[0-9]+\.[0-9]+$'; then - if nvm_string_contains_regexp "$version_list" "^v$stripped_version_from_semver$"; then - command printf "%s" "$stripped_version_from_semver" + retrieved_version=$(command printf "%s" "$version_list" | nvm_grep "^$stripped_version_from_semver$") + if [ -n "$retrieved_version" ]; then + command printf "%s" "$retrieved_version" return 0 else - return 1 + return 1 # go on to try complex semver interpretation fi # Semver is looking for the newest version >= a specific version, and the newest version in the provided list of versions is >= the specified version, resolve to that version. @@ -701,7 +720,7 @@ nvm_interpret_node_semver() { # list of node versions is sorted from oldest to newest local remote_node_versions - remote_node_versions=$(nvm_ls_remote | nvm_grep -o 'v[0-9]\+\.[0-9]\+\.[0-9]\+') + remote_node_versions=$(nvm_ls_remote | nvm_grep -o 'v[0-9]\+\.[0-9]\+\.[0-9]\+' | sed 's/^v//g') if [ -z "$remote_node_versions" ]; then return 1 fi @@ -747,11 +766,7 @@ nvm_get_node_from_pkg_json() { closed_brackets=0 # a counter variable local in_quotes in_quotes=1 # a true/false variable - - command printf "%s" "$package_json_contents" \ - | command tr -d '\n\r' \ - | command tr '\t' ' ' \ - | command tr -s ' ' \ + nvm_trim_and_reduce_whitespace_to_one_space "$package_json_contents" \ | nvm_grep -o '"engines": \?{ \?".*' \ | nvm_grep -o '{.*' \ | nvm_grep -o . \ @@ -4067,7 +4082,7 @@ nvm() { nvm_curl_libz_support nvm_command_info \ nvm_get_node_from_pkg_json nvm_find_package_json nvm_package_json_version \ nvm_interpret_node_semver nvm_interpret_simple_semver nvm_interpret_complex_semver nvm_validate_semver \ - nvm_is_valid_semver nvm_string_contains_regexp \ + nvm_is_valid_semver nvm_string_contains_regexp nvm_trim_and_reduce_whitespace_to_one_space \ > /dev/null 2>&1 unset NVM_RC_VERSION NVM_NODEJS_ORG_MIRROR NVM_IOJS_ORG_MIRROR NVM_DIR \ NVM_CD_FLAGS NVM_BIN NVM_MAKE_JOBS \ diff --git a/test/fast/Unit tests/nvm_get_node_from_pkg_json b/test/fast/Unit tests/nvm_get_node_from_pkg_json index fee0f9f..8d57d07 100755 --- a/test/fast/Unit tests/nvm_get_node_from_pkg_json +++ b/test/fast/Unit tests/nvm_get_node_from_pkg_json @@ -3,144 +3,31 @@ die () { printf "$@" ; exit 1; } \. ../../../nvm.sh - -BASIC_VERSIONS='1.2.3 -10.21.32 -x.x.x -X.X.X -*.*.* -1.2 -10.21 -x.x -X.X -*.* -1 -10 -x -* -X' - -SEMVER_OPERATORS='v -= -< -> -<= ->= -~ -^' - - - -# Dynamically generate list of semver expressions to test inside each package.json template. -# Each semver added to this list is paired with the expected output when executed with nvm_get_node_from_pkg_json. -# Most valid semvers will expecte the output to be the same as the input but there are some valid semvers with certain -# sequences of tabs/spaces whose outputs are slightly different from their inputs (documented below). - -# Format for test cases is input and expected output separated by a colon -# INPUT:EXPECTED_OUTPUT -TEST_SEMVERS='' - -BASIC_VERSIONS_COPY=$(echo "$BASIC_VERSIONS") -while [ -n "$BASIC_VERSIONS_COPY" ]; do - BASIC_VERSION=$(echo "$BASIC_VERSIONS_COPY" | head -n1) - BASIC_VERSIONS_COPY=$(echo "$BASIC_VERSIONS_COPY" | tail -n +2) - - # add test semver with just the version and no comparator - TEST_SEMVERS="$TEST_SEMVERS -$BASIC_VERSION:$BASIC_VERSION" - - SEMVER_OPERATORS_COPY=$(echo "$SEMVER_OPERATORS") - while [ -n "$SEMVER_OPERATORS_COPY" ]; do - SEMVER_OPERATOR=$(echo "$SEMVER_OPERATORS_COPY" | head -n1) - SEMVER_OPERATORS_COPY=$(echo "$SEMVER_OPERATORS_COPY" | tail -n +2) - - # add test semver with version adjacent to operator - # add test semver with version separated from operator by one space - TEST_SEMVERS="$TEST_SEMVERS -$SEMVER_OPERATOR$BASIC_VERSION:$SEMVER_OPERATOR$BASIC_VERSION -$SEMVER_OPERATOR $BASIC_VERSION:$SEMVER_OPERATOR $BASIC_VERSION" - done -done - -# add valid basic test semvers with hyphen ranges -TEST_SEMVERS="$TEST_SEMVERS -1.2.3 - 1.2.4:1.2.3 - 1.2.4 -10.21.32 - 10.21.33:10.21.32 - 10.21.33 -1.2 - 1.3:1.2 - 1.3 -10.21 - 10.22:10.21 - 10.22 -1 - 2:1 - 2 -10 - 11:10 - 11" - -# add more complex test semvers with just one comparator set -TEST_SEMVERS="$TEST_SEMVERS -1.2.3 1.2.4:1.2.3 1.2.4 -1.2 1.3:1.2 1.3 -1 2:1 2 ->1.2.3 <=1.3.0:>1.2.3 <=1.3.0" - -# add test semvers with multiple comparator sets -TEST_SEMVERS="$TEST_SEMVERS -1.2.3 || 1.2.4:1.2.3 || 1.2.4 -1.2 || 1.3:1.2 || 1.3 -1 || 2:1 || 2" - -# add test semvers that will be successfully extracted from package.json -# but will be marked invalid upon going through nvm_validate_semver -TEST_SEMVERS="$TEST_SEMVERS -1.2.3||1.2.4:1.2.3||1.2.4 -1.2||1.3:1.2||1.3 -1||2:1||2 -<1.2.3>:<1.2.3> -<1.2>:<1.2> -<1>:<1> ->>1:>>1 -<<1:<<1 -==1:==1 -**:** -xx:xx -^^1:^^1 -~~1:~~1 -1.2.3-1.2.4:1.2.3-1.2.4 -10.21.32-10.21.33:10.21.32-10.21.33 -1.2-1.3:1.2-1.3 -10.21-10.22:10.21-10.22 -1-2:1-2 -10-11:10-11" - -# add test semvers with tabs inside them -# These semvers are intended to: -# - validate that semvers can include tabs -# - validate that all tabs or consecutive tabs are reduced to one space -# - validate that leading trailing spaces and tabs are removed -TEST_SEMVERS="$TEST_SEMVERS - 1 1 :1 1 - 2 2 :2 2" +\. sharedTestResources/semvers # POSITIVE TEST CASES # (TEST SET #1) uses valid TEST_SEMVER's and valid package.json templates -TEST_SEMVERS_COPY=$(echo "$TEST_SEMVERS") -PREV_TEST_SEMVER='' -for TEMPLATE_NAME in package_json_templates/_valid_*; do - while [ -n "$TEST_SEMVERS_COPY" ]; do - LINE=$(echo "$TEST_SEMVERS_COPY" | head -n1) - TEST_SEMVERS_COPY=$(echo "$TEST_SEMVERS_COPY" | tail -n +2) - [ -n "$LINE" ] || continue - TEST_SEMVER_INPUT=$(echo "$LINE" | awk -F: '{ print $1 }') - EXPECTED_OUTPUT=$(echo "$LINE" | awk -F: '{ print $2 }') +test_semvers_copy="$VALID_SEMVERS_FOR_PKG_JSON" +prev_semver='' +for template_file_name in package_json_templates/_valid_*; do + while [ -n "$test_semvers_copy" ]; do + semver=$(echo "$test_semvers_copy" | head -n1) + test_semvers_copy=$(echo "$test_semvers_copy" | tail -n +2) + [ -n "$semver" ] || continue + expectedOutput=$(nvm_trim_and_reduce_whitespace_to_one_space "$semver") - if [ "$PREV_TEST_SEMVER" = "$TEST_SEMVER_INPUT" ]; then - die "Problem iterating through TEST_SEMVERS_COPY (TEST SET #1). Encountered the same value twice in a row. PREV_TEST_SEMVER='$PREV_TEST_SEMVER' TEST_SEMVER_INPUT='$TEST_SEMVER_INPUT'.\n" + if [ "$prev_semver" = "$semver" ]; then + die "Problem iterating through test_semvers_copy (TEST SET #1). Encountered the same value twice in a row. prev_semver='$prev_semver' semver='$semver'.\n" fi - PREV_TEST_SEMVER=$(printf "%s" "$TEST_SEMVER_INPUT") + prev_semver="$semver" - PKG_JSON_CONTENTS=$(sed 's/NODE_SEMVER/'"$TEST_SEMVER_INPUT"'/g' "$TEMPLATE_NAME" | tail -n +3) - ACTUAL_OUTPUT=$(nvm_get_node_from_pkg_json "$PKG_JSON_CONTENTS") - - if [ "$ACTUAL_OUTPUT" != "$EXPECTED_OUTPUT" ] || [ -z "$ACTUAL_OUTPUT" ] || [ -z "$PKG_JSON_CONTENTS" ]; then - die "'nvm_get_node_from_pkg_json' POSITIVE test case failed (TEST SET #1). Expected '$EXPECTED_OUTPUT' but got '$ACTUAL_OUTPUT' when given input template '$TEMPLATE_NAME':\n$PKG_JSON_CONTENTS" + pkg_json_contents=$(sed 's/NODE_SEMVER/'"$semver"'/g' "$template_file_name" | tail -n +3) + actual_output=$(nvm_get_node_from_pkg_json "$pkg_json_contents") + if [ "$actual_output" != "$expectedOutput" ] || [ -z "$actual_output" ] || [ -z "$pkg_json_contents" ]; then + die "'nvm_get_node_from_pkg_json' POSITIVE test case failed (TEST SET #1). Expected '$expectedOutput' but got '$actual_output' when given input '$semver' and template '$template_file_name':\n$pkg_json_contents" fi done done @@ -150,90 +37,69 @@ done # (TEST SET #2) uses valid TEST_SEMVER's but invalid package.json templates -TEST_SEMVERS_COPY=$(echo "$TEST_SEMVERS") -PREV_TEST_SEMVER='' -for TEMPLATE_NAME in package_json_templates/_invalid_*; do - while [ -n "$TEST_SEMVERS_COPY" ]; do - LINE=$(echo "$TEST_SEMVERS_COPY" | head -n1) - TEST_SEMVERS_COPY=$(echo "$TEST_SEMVERS_COPY" | tail -n +2) - [ -n "$LINE" ] || continue - TEST_SEMVER_INPUT=$(echo "$LINE" | awk -F: '{ print $1 }') +test_semvers_copy="$VALID_SEMVERS_FOR_PKG_JSON" +prev_semver='' +for template_file_name in package_json_templates/_invalid_*; do + while [ -n "$test_semvers_copy" ]; do + semver=$(echo "$test_semvers_copy" | head -n1) + test_semvers_copy=$(echo "$test_semvers_copy" | tail -n +2) + [ -n "$semver" ] || continue - if [ "$PREV_TEST_SEMVER" = "$TEST_SEMVER_INPUT" ]; then - die "Problem iterating through TEST_SEMVERS_COPY (TEST SET #2). Encountered the same value twice in a row. PREV_TEST_SEMVER='$PREV_TEST_SEMVER' TEST_SEMVER_INPUT='$TEST_SEMVER_INPUT'.\n" + if [ "$prev_semver" = "$semver" ]; then + die "Problem iterating through test_semvers_copy (TEST SET #2). Encountered the same value twice in a row. prev_semver='$prev_semver' semver='$semver'.\n" fi - PREV_TEST_SEMVER=$(printf "%s" "$TEST_SEMVER_INPUT") + prev_semver="$semver" - PKG_JSON_CONTENTS=$(sed 's/NODE_SEMVER/'"$TEST_SEMVER_INPUT"'/g' "$TEMPLATE_NAME" | tail -n +3) - ACTUAL_OUTPUT=$(nvm_get_node_from_pkg_json "$PKG_JSON_CONTENTS") - - if [ "$ACTUAL_OUTPUT" != "" ] || [ -z "$TEST_SEMVER_INPUT" ] || [ -z "$PKG_JSON_CONTENTS" ]; then - die "'nvm_get_node_from_pkg_json' NEGATIVE test case failed (TEST SET #2). Expected to get empty string but got '$ACTUAL_OUTPUT' when given input template '$TEMPLATE_NAME':\n$PKG_JSON_CONTENTS" + pkg_json_contents=$(sed 's/NODE_SEMVER/'"$semver"'/g' "$template_file_name" | tail -n +3) + actual_output=$(nvm_get_node_from_pkg_json "$pkg_json_contents") + if [ "$actual_output" != "" ] || [ -z "$semver" ] || [ -z "$pkg_json_contents" ]; then + die "'nvm_get_node_from_pkg_json' NEGATIVE test case failed (TEST SET #2). Expected to get empty string but got '$actual_output' when given input template '$template_file_name':\n$pkg_json_contents" fi done done -# invalid test semvers -TEST_SEMVERS='&1 -@1 -#1 -$1 -%s -1) -1( -1_ -1+ -1] -1[ -1" -1: -1? -1` -1!' - # (TEST SET #3) uses invalid TEST_SEMVER's but valid package.json templates -TEST_SEMVERS_COPY=$(echo "$TEST_SEMVERS") -PREV_TEST_SEMVER='' -for TEMPLATE_NAME in package_json_templates/_valid_*; do - while [ -n "$TEST_SEMVERS_COPY" ]; do - TEST_SEMVER_INPUT=$(echo "$TEST_SEMVERS_COPY" | head -n1) - [ -n "$TEST_SEMVER_INPUT" ] || continue - TEST_SEMVERS_COPY=$(echo "$TEST_SEMVERS_COPY" | tail -n +2) +test_semvers_copy="$INVALID_SEMVERS_FOR_PKG_JSON" +prev_semver='' +for template_file_name in package_json_templates/_valid_*; do + while [ -n "$test_semvers_copy" ]; do + semver=$(echo "$test_semvers_copy" | head -n1) + [ -n "$semver" ] || continue + test_semvers_copy=$(echo "$test_semvers_copy" | tail -n +2) - if [ "$PREV_TEST_SEMVER" = "$TEST_SEMVER_INPUT" ]; then - die "Problem iterating through TEST_SEMVERS_COPY (TEST SET #3). Encountered the same value twice in a row. PREV_TEST_SEMVER='$PREV_TEST_SEMVER' TEST_SEMVER_INPUT='$TEST_SEMVER_INPUT'.\n" + if [ "$prev_semver" = "$semver" ]; then + die "Problem iterating through test_semvers_copy (TEST SET #3). Encountered the same value twice in a row. prev_semver='$prev_semver' semver='$semver'.\n" fi - PREV_TEST_SEMVER=$(printf "%s" "$TEST_SEMVER_INPUT") + prev_semver=$(printf "%s" "$semver") - PKG_JSON_CONTENTS=$(sed 's/NODE_SEMVER/'"$TEST_SEMVER_INPUT"'/g' "$TEMPLATE_NAME" | tail -n +3) - ACTUAL_OUTPUT=$(nvm_get_node_from_pkg_json "$PKG_JSON_CONTENTS") - - if [ "$ACTUAL_OUTPUT" != "" ] || [ -z "$TEST_SEMVER_INPUT" ] || [ -z "$PKG_JSON_CONTENTS" ]; then - die "'nvm_get_node_from_pkg_json' NEGATIVE test case failed (TEST SET #3). Expected to get empty string but got '$ACTUAL_OUTPUT' when given input template '$TEMPLATE_NAME':\n$PKG_JSON_CONTENTS" + pkg_json_contents=$(sed 's/NODE_SEMVER/'"$semver"'/g' "$template_file_name" | tail -n +3) + actual_output=$(nvm_get_node_from_pkg_json "$pkg_json_contents") + if [ "$actual_output" != "" ] || [ -z "$semver" ] || [ -z "$pkg_json_contents" ]; then + die "'nvm_get_node_from_pkg_json' NEGATIVE test case failed (TEST SET #3). Expected to get empty string but got '$actual_output' when given input template '$template_file_name':\n$pkg_json_contents" fi done done # (TEST SET #4) uses invalid TEST_SEMVER's and invalid package.json templates -TEST_SEMVERS_COPY=$(echo "$TEST_SEMVERS") -PREV_TEST_SEMVER='' -for TEMPLATE_NAME in package_json_templates/_invalid_*; do - while [ -n "$TEST_SEMVERS_COPY" ]; do - TEST_SEMVER_INPUT=$(echo "$TEST_SEMVERS_COPY" | head -n1) - [ -n "$TEST_SEMVER_INPUT" ] || continue - TEST_SEMVERS_COPY=$(echo "$TEST_SEMVERS_COPY" | tail -n +2) +test_semvers_copy="$INVALID_SEMVERS_FOR_PKG_JSON" +prev_semver='' +for template_file_name in package_json_templates/_invalid_*; do + while [ -n "$test_semvers_copy" ]; do + semver=$(echo "$test_semvers_copy" | head -n1) + [ -n "$semver" ] || continue + test_semvers_copy=$(echo "$test_semvers_copy" | tail -n +2) - if [ "$PREV_TEST_SEMVER" = "$TEST_SEMVER_INPUT" ]; then - die "Problem iterating through TEST_SEMVERS_COPY (TEST SET #4). Encountered the same value twice in a row. PREV_TEST_SEMVER='$PREV_TEST_SEMVER' TEST_SEMVER_INPUT='$TEST_SEMVER_INPUT'.\n" + if [ "$prev_semver" = "$semver" ]; then + die "Problem iterating through test_semvers_copy (TEST SET #4). Encountered the same value twice in a row. prev_semver='$prev_semver' semver='$semver'.\n" fi - PREV_TEST_SEMVER=$(printf "%s" "$TEST_SEMVER_INPUT") + prev_semver=$(printf "%s" "$semver") - PKG_JSON_CONTENTS=$(sed 's/NODE_SEMVER/'"$TEST_SEMVER_INPUT"'/g' "$TEMPLATE_NAME" | tail -n +3) - ACTUAL_OUTPUT=$(nvm_get_node_from_pkg_json "$PKG_JSON_CONTENTS") - - if [ "$ACTUAL_OUTPUT" != "" ] || [ -z "$TEST_SEMVER_INPUT" ] || [ -z "$PKG_JSON_CONTENTS" ]; then - die "'nvm_get_node_from_pkg_json' NEGATIVE test case failed (TEST SET #4). Expected to get empty string but got '$ACTUAL_OUTPUT' when given input template '$TEMPLATE_NAME':\n$PKG_JSON_CONTENTS" + pkg_json_contents=$(sed 's/NODE_SEMVER/'"$semver"'/g' "$template_file_name" | tail -n +3) + actual_output=$(nvm_get_node_from_pkg_json "$pkg_json_contents") + if [ "$actual_output" != "" ] || [ -z "$semver" ] || [ -z "$pkg_json_contents" ]; then + die "'nvm_get_node_from_pkg_json' NEGATIVE test case failed (TEST SET #4). Expected to get empty string but got '$actual_output' when given input template '$template_file_name':\n$pkg_json_contents" fi done done + diff --git a/test/fast/Unit tests/nvm_interpret_node_semver b/test/fast/Unit tests/nvm_interpret_node_semver new file mode 100755 index 0000000..28a00b1 --- /dev/null +++ b/test/fast/Unit tests/nvm_interpret_node_semver @@ -0,0 +1,67 @@ +#!/bin/sh + +# TODO this test currently takes about 16 minutes so it should not be in the "fast" test directory and maybe is too long regardless. + +die () { printf "$@" ; exit 1; } + +\. ../../../nvm.sh +\. sharedTestResources/semvers + +# Verify that all generated valid normalized semvers produce some result +test_cases="$VALID_SEMVERS" +while [ -n "$test_cases" ]; do + semver=$(echo "$test_cases" | head -n1) + test_cases=$(echo "$test_cases" | tail -n +2) + + output=$(nvm_interpret_node_semver "$semver") + if [ -z "$semver" ] || [ -z "$output" ] || ! nvm_string_contains_regexp "$output" '^[0-9]+\.[0-9]+\.[0-9]+$'; then + die "nvm_interpret_node_semver generated positive test case failed expecting a version to be outputted: semver: '$semver' output: '$output'" + fi +done + +# Verify that all generated invalid normalized semvers do not produce a result +test_cases="$INVALID_SEMVERS" +while [ -n "$test_cases" ]; do + semver=$(echo "$test_cases" | head -n1) + test_cases=$(echo "$test_cases" | tail -n +2) + + output=$(nvm_interpret_node_semver "$semver") + if [ -z "$semver" ] || [ -n "$output" ]; then + die "nvm_interpret_node_semver generated negative test case failed: semver: '$semver' output: '$output'" + fi +done + +# TODO add more test cases here +# Verify actual outputs given some inputs +# input:expected_output +test_cases="*:$NEWEST_NODE_VERSION +5:$NEWEST_NODE_VERSION_5 +x:$NEWEST_NODE_VERSION +X:$NEWEST_NODE_VERSION +0.12.18:0.12.18 +0.11.16:0.11.16 +222.22.2: +>0.12.18:$NEWEST_NODE_VERSION +>=0.11.16:$NEWEST_NODE_VERSION +7.1.0 || 7.3.0 || 7.2.0:7.3.0 +7.1.0 7.3.0 7.2.0: +5:$NEWEST_NODE_VERSION_5 +5.x:$NEWEST_NODE_VERSION_5 +5.x.x:$NEWEST_NODE_VERSION_5 +5.X:$NEWEST_NODE_VERSION_5 +5.X.X:$NEWEST_NODE_VERSION_5 +7.5.0:7.5.0" + +while [ -n "$test_cases" ]; do + line=$(echo "$test_cases" | head -n1) + input=$(echo "$line" | awk -F: '{ print $1 }') + expected_output=$(echo "$line" | awk -F: '{ print $2 }') + test_cases=$(echo "$test_cases" | tail -n +2) + + actualOutput=$(nvm_interpret_node_semver "$input") + if [ "$actualOutput" != "$expected_output" ] || [ -z "$input" ]; then + die "nvm_interpret_node_semver input/output test case failed. Expected output: '$expected_output'. Actual output: '$actualOutput'. Input: '$input'.\n" + fi +done +exit 0 + diff --git a/test/fast/Unit tests/nvm_interpret_semver b/test/fast/Unit tests/nvm_interpret_semver deleted file mode 100755 index b853b39..0000000 --- a/test/fast/Unit tests/nvm_interpret_semver +++ /dev/null @@ -1,38 +0,0 @@ -#!/bin/sh - -# TODO this test currently takes about 1 minute and will take even longer with the rest of the needed test cases so maybe it shouldn't live in the "fast" tests directory. - -die () { printf "$@" ; exit 1; } - -\. ../../../nvm.sh - -newest_node=$(nvm_remote_version | grep -o '[0-9]\+\.[0-9]\+\.[0-9]\+') -x5='5.12.0' - -# POSITIVE TEST CASES - -# INPUT:EXPECTED_OUTPUT -test_cases="*:$newest_node -5:$x5 -x:$newest_node -X:$newest_node -7.1.0 || 7.3.0 || 7.2.0:7.3.0 -7.1.0 7.3.0 7.2.0: -5:$x5 -5.x:$x5 -5.x.x:$x5 -5.X:$x5 -5.X.X:$x5 -7.5.0:7.5.0" - -while [ -n "$test_cases" ]; do - LINE=$(echo "$test_cases" | head -n1) - INPUT=$(echo "$LINE" | awk -F: '{ print $1 }') - EXPECTED_OUTPUT=$(echo "$LINE" | awk -F: '{ print $2 }') - ACTUAL_OUTPUT=$(nvm_interpret_node_semver "$INPUT") - if [ "$ACTUAL_OUTPUT" != "$EXPECTED_OUTPUT" ] || [ -z "$INPUT" ]; then - die "Expected output: '$EXPECTED_OUTPUT'. Actual output: '$ACTUAL_OUTPUT'. Input: '$INPUT'.\n" - fi - test_cases=$(echo "$test_cases" | tail -n +2) -done -exit 0 diff --git a/test/fast/Unit tests/nvm_is_valid_semver b/test/fast/Unit tests/nvm_is_valid_semver index 8239251..88f841c 100755 --- a/test/fast/Unit tests/nvm_is_valid_semver +++ b/test/fast/Unit tests/nvm_is_valid_semver @@ -3,39 +3,52 @@ die () { printf "$@" ; exit 1; } \. ../../../nvm.sh +\. sharedTestResources/semvers -valid_semver_regexp='^( ?(<|<=|>|>=|=|~|\^)?([0-9]+|x)\.([0-9]+|x)\.([0-9]+|x))+$' +# nvm_is_valid_semver validates that given semvers adhere to the following grammer +# +# semver ::= comparator_set ( ' || ' comparator_set )* +# comparator_set ::= comparator ( ' ' comparator )* +# comparator ::= ( '<' | '<=' | '>' | '>=' | '' ) [0-9]+ '.' [0-9]+ '.' [0-9]+ # POSITIVE TEST CASES -# STRING:REGEXP -test_cases="1.2.3:$valid_semver_regexp -11.22.33:$valid_semver_regexp" +positive_test_cases="$VALID_NORMALIZED_SEMVERS" +if [ -z "$positive_test_cases" ]; then + die "positive test cases are empty" +fi -while [ -n "$test_cases" ]; do - LINE=$(echo "$test_cases" | head -n1) - STRING=$(echo "$LINE" | awk -F: '{ print $1 }') - REGEXP=$(echo "$LINE" | awk -F: '{ print $2 }') - if [ -z "$REGEXP" ] || [ -z "$STRING" ] || ! nvm_string_contains_regexp "$STRING" "$REGEXP"; then - die "nvm_string_contains_regexp POSITIVE test case failed. REGEXP: '$REGEXP'. STRING: '$STRING'.\n" +prev_semver='' +while [ -n "$positive_test_cases" ]; do + semver=$(echo "$positive_test_cases" | head -n1) + if [ -z "$semver" ] || ! nvm_is_valid_semver "$semver"; then + die "nvm_string_contains_regexp POSITIVE test case failed. semver: '$semver'.\n" fi - test_cases=$(echo "$test_cases" | tail -n +2) + if [ "$prev_semver" = "$semver" ]; then + die "something is wrong. positive test cases received the same test case twice in a row. semver: '$semver'" + fi + prev_semver="$semver" + positive_test_cases=$(echo "$positive_test_cases" | tail -n +2) done # NEGATIVE TEST CASES -# STRING:REGEXP -test_cases="1.2.a:$valid_semver_regexp -:$valid_semver_regexp -11.22.a:$valid_semver_regexp" +negative_test_cases="$VALID_NON_NORMALIZED_SEMVERS" +if [ -z "$negative_test_cases" ]; then + die "negative test cases are empty" +fi -while [ -n "$test_cases" ]; do - LINE=$(echo "$test_cases" | head -n1) - STRING=$(echo "$LINE" | awk -F: '{ print $1 }') - REGEXP=$(echo "$LINE" | awk -F: '{ print $2 }') - if [ -z "$REGEXP" ] || nvm_string_contains_regexp "$STRING" "$REGEXP"; then - die "nvm_string_contains_regexp NEGATIVE test case failed. REGEXP: '$REGEXP'. STRING: '$STRING'.\n" +prev_semver='initialized to non empty string' +while [ -n "$negative_test_cases" ]; do + semver=$(echo "$negative_test_cases" | head -n1) + if nvm_is_valid_semver "$semver"; then + die "nvm_string_contains_regexp NEGATIVE test case failed. semver: '$semver'.\n" fi - test_cases=$(echo "$test_cases" | tail -n +2) + if [ "$prev_semver" = "$semver" ]; then + die "something is wrong. negative test cases received the same test case twice in a row. semver: '$semver'" + fi + prev_semver="$semver" + negative_test_cases=$(echo "$negative_test_cases" | tail -n +2) done exit 0 + diff --git a/test/fast/Unit tests/nvm_string_equals_regexp b/test/fast/Unit tests/nvm_string_equals_regexp index 8239251..a43f30a 100755 --- a/test/fast/Unit tests/nvm_string_equals_regexp +++ b/test/fast/Unit tests/nvm_string_equals_regexp @@ -8,34 +8,36 @@ valid_semver_regexp='^( ?(<|<=|>|>=|=|~|\^)?([0-9]+|x)\.([0-9]+|x)\.([0-9]+|x))+ # POSITIVE TEST CASES -# STRING:REGEXP +# TODO add more test cases +# string:regexp test_cases="1.2.3:$valid_semver_regexp 11.22.33:$valid_semver_regexp" while [ -n "$test_cases" ]; do - LINE=$(echo "$test_cases" | head -n1) - STRING=$(echo "$LINE" | awk -F: '{ print $1 }') - REGEXP=$(echo "$LINE" | awk -F: '{ print $2 }') - if [ -z "$REGEXP" ] || [ -z "$STRING" ] || ! nvm_string_contains_regexp "$STRING" "$REGEXP"; then - die "nvm_string_contains_regexp POSITIVE test case failed. REGEXP: '$REGEXP'. STRING: '$STRING'.\n" + line=$(echo "$test_cases" | head -n1) + string=$(echo "$line" | awk -F: '{ print $1 }') + regexp=$(echo "$line" | awk -F: '{ print $2 }') + if [ -z "$regexp" ] || [ -z "$string" ] || ! nvm_string_contains_regexp "$string" "$regexp"; then + die "nvm_string_contains_regexp POSITIVE test case failed. regexp: '$regexp'. string: '$string'.\n" fi test_cases=$(echo "$test_cases" | tail -n +2) done # NEGATIVE TEST CASES -# STRING:REGEXP +# string:regexp test_cases="1.2.a:$valid_semver_regexp :$valid_semver_regexp 11.22.a:$valid_semver_regexp" while [ -n "$test_cases" ]; do - LINE=$(echo "$test_cases" | head -n1) - STRING=$(echo "$LINE" | awk -F: '{ print $1 }') - REGEXP=$(echo "$LINE" | awk -F: '{ print $2 }') - if [ -z "$REGEXP" ] || nvm_string_contains_regexp "$STRING" "$REGEXP"; then - die "nvm_string_contains_regexp NEGATIVE test case failed. REGEXP: '$REGEXP'. STRING: '$STRING'.\n" + line=$(echo "$test_cases" | head -n1) + string=$(echo "$line" | awk -F: '{ print $1 }') + regexp=$(echo "$line" | awk -F: '{ print $2 }') + if [ -z "$regexp" ] || nvm_string_contains_regexp "$string" "$regexp"; then + die "nvm_string_contains_regexp NEGATIVE test case failed. regexp: '$regexp'. string: '$string'.\n" fi test_cases=$(echo "$test_cases" | tail -n +2) done exit 0 + diff --git a/test/fast/Unit tests/nvm_trim_and_reduce_whitespace_to_one_space b/test/fast/Unit tests/nvm_trim_and_reduce_whitespace_to_one_space new file mode 100755 index 0000000..52f5f0a --- /dev/null +++ b/test/fast/Unit tests/nvm_trim_and_reduce_whitespace_to_one_space @@ -0,0 +1,28 @@ +#!/bin/sh + +die () { printf "$@" ; exit 1; } + +\. ../../../nvm.sh + +# TODO add more test cases +# input:expected_output +test_cases="1.2.3:$valid_semver_regexp +11.22.33:$valid_semver_regexp" + +test_cases='1:1 + 1.2.3:1.2.3 + 1 1 :1 1 + 2 2 :2 2' + +while [ -n "$test_cases" ]; do + line=$(echo "$test_cases" | head -n1) + input=$(echo "$line" | awk -F: '{ print $1 }') + expected_output=$(echo "$line" | awk -F: '{ print $2 }') + actual_output=$(nvm_trim_and_reduce_whitespace_to_one_space "$input") + if [ -z "$input" ] || [ -z "$expected_output" ] || [ "$expected_output" != "$actual_output" ]; then + die "nvm_reduce_whitespace_to_one_space test case failed. expected_output: '$expected_output'. actual_output: '$actual_output'.\n" + fi + test_cases=$(echo "$test_cases" | tail -n +2) +done +exit 0 + diff --git a/test/fast/Unit tests/nvm_validate_semver b/test/fast/Unit tests/nvm_validate_semver index a5cc64b..44b0374 100755 --- a/test/fast/Unit tests/nvm_validate_semver +++ b/test/fast/Unit tests/nvm_validate_semver @@ -4,7 +4,9 @@ die () { printf "$@" ; exit 1; } \. ../../../nvm.sh -# INPUT:EXPECTED_OUTPUT +# TODO add more test cases here +# Some test cases should just test that valid semvers from sharedTestResources/semvers just produce some result +# input:expected_output test_cases="1.2.3:1.2.3 1.2.3 - 1.2.4:>=1.2.3 <=1.2.4 1.2.3-1.2.4:>=1.2.3 <=1.2.4 @@ -41,13 +43,14 @@ a || 1.2.3: 11.22.33:11.22.33" while [ -n "$test_cases" ]; do - LINE=$(echo "$test_cases" | head -n1) - INPUT=$(echo "$LINE" | awk -F: '{ print $1 }') - EXPECTED_OUTPUT=$(echo "$LINE" | awk -F: '{ print $2 }') - ACTUAL_OUTPUT=$(nvm_validate_semver "$INPUT") - if [ -z "$INPUT" ] || [ "$ACTUAL_OUTPUT" != "$EXPECTED_OUTPUT" ]; then - die "nvm_validate_semver test case failed. Expected output: '$EXPECTED_OUTPUT'. Actual output: '$ACTUAL_OUTPUT'. Input: '$INPUT'.\n" + line=$(echo "$test_cases" | head -n1) + input=$(echo "$line" | awk -F: '{ print $1 }') + expected_output=$(echo "$line" | awk -F: '{ print $2 }') + actual_output=$(nvm_validate_semver "$input") + if [ -z "$input" ] || [ "$actual_output" != "$expected_output" ]; then + die "nvm_validate_semver test case failed. Expected output: '$expected_output'. Actual output: '$actual_output'. Input: '$input'.\n" fi test_cases=$(echo "$test_cases" | tail -n +2) done exit 0 + diff --git a/test/fast/Unit tests/sharedTestResources/semvers b/test/fast/Unit tests/sharedTestResources/semvers new file mode 100755 index 0000000..9f1f891 --- /dev/null +++ b/test/fast/Unit tests/sharedTestResources/semvers @@ -0,0 +1,187 @@ +#!/bin/sh + +NEWEST_NODE_VERSION=$(nvm_remote_version | grep -o '[0-9]\+\.[0-9]\+\.[0-9]\+') +NEWEST_NODE_VERSION_5='5.12.0' + +# The only operators prefixing versions that would be acceptable inputs to the semver interpretation logic. +VALID_NORMALIZED_SEMVER_OPERATORS='< +> +<= +>=' + +# Valid semver operators that would be acceptable to find prefixing a semver in a package.json file, but would need to be validated/normalized before interpretting. +VALID_NON_NORMALIZED_SEMVER_OPERATORS='v += +~ +^' + +# Versions (stripped of any operators) that are considered valid inputs to the semver interpretation logic. +VALID_NORMALIZED_VERSIONS='4.1.0 +0.12.18 +0.11.16 +6.11.4 +10.0.0' + +# Semvers that won't be pulled from package.json files because they contain characters that are not included in valid semvers +INVALID_SEMVERS_FOR_PKG_JSON='&1 +# +$ +@ +! +% +& +) +( ++ +@1 +#1 +$1 +%s +1) +1( +1_ +1+ +1] +1[ +1" +1: +1? +1` +1!' + +# Semvers that won't resolve to a node version +INVALID_SEMVERS="$INVALID_SEMVERS_FOR_PKG_JSON +~1 +^1 +- += +^ +1 +a +asdf +1111 +1 1 +1. +1.1 +1.* +1.2 +11.222 +1.2.a +1.*.* +1.x.x +11.22.a +=1.2.3 +~1.2.3 +^1.2.3 +1.1.1 2.2.2 +>1.1.1 <1.1.0 +1.2 - 1.3 +10.221.32 - 10.21.33 +10.212 - 10.22 +1.2.3 - 1.2.4 +1.2.3-1.2.4 +1.2 1.3 +1 2 +1.2.3||1.2.4 +1.2||1.3 +1||2 +>1000 +<0" + +# Valid semvers that should resolve to a node version and are slightly more complex than the [operator][version] structure +VALID_NORMALIZED_COMPLEX_SEMVERS='10.3.0 || 8.1.1 || 4.1.0 +7.7.2 || >=9.0.0 <=8.9.0 || <8.2.1 +8.2.0 8.2.0 +>4.0.0 <=5.0.0 +8.0.0 || <6.12.0' + +# Valid semvers that should resolve to a node version but need to be validated/normalized before interpretting. +VALID_NON_NORMALIZED_SEMVERS='x +X +* +x.x +X.X +*.* +x.x.x +X.X.X +x.X.* +*.x.X +x.1.2 +>1.1.1 <6.2.2 +> 1.1.1 <6.2.2 +10 - 11 +10-11 +4.2.2||8.1.1 +4.2 || 1.3 +4 || 2' + +# Strings that should be extracted from a package.json engines.node value but don't need to resolve to a node version. +VALID_COMPLEX_SEMVERS_FOR_PKG_JSON="$VALID_NORMALIZED_COMPLEX_SEMVERS +<1.2.3> +<1.2> +<1> +>>1 +<<1 +==1 +** +xx +^^1 +~~1 +10.211.32-10.211.33 +10.211-10.222 + 1 1 + 2 2 " + +die () { printf "$@" ; exit 1; } + +generate_semvers() { + versions="${1-}" + operators="${2-}" + should_add_spacing_permutations=${3-1} + if [ -z "$versions" ] || [ -z "$operators" ]; then + die "Problem generating semvers: Given invalid parameters. versions: '$versions' operators: '$operators'" + fi + while [ -n "$versions" ]; do + version=$(echo "$versions" | head -n1) + versions=$(echo "$versions" | tail -n +2) + + operators_copy="$operators" + while [ -n "$operators_copy" ]; do + operator=$(echo "$operators_copy" | head -n1) + operators_copy=$(echo "$operators_copy" | tail -n +2) + if [ -z "$semvers" ]; then + # NOTE: the third spacing permutation of the operator has a tab between the operator and version. + if [ $should_add_spacing_permutations -eq 0 ]; then + semvers=$(printf "%s\n%s\n%s" "${operator}${version}" "${operator} ${version}" "${operator} ${version}") + else + semvers="${operator}${version}" + fi + else + # NOTE: the third spacing permutation of the operator has a tab between the operator and version. + if [ $should_add_spacing_permutations -eq 0 ]; then + semvers=$(printf "%s\n%s\n%s\n%s" "$semvers" "${operator}${version}" "${operator} ${version}" "${operator} ${version}") + else + semvers=$(printf "%s\n%s" "$semvers" "${operator}${version}") + fi + fi + done + done + echo "$semvers" +} + +VALID_NORMALIZED_SEMVERS=$(printf "%s\n%s\n%s" \ + "$VALID_NORMALIZED_COMPLEX_SEMVERS" \ + "$VALID_NORMALIZED_VERSIONS" \ + "$(generate_semvers "$VALID_NORMALIZED_VERSIONS" "$VALID_NORMALIZED_SEMVER_OPERATORS")" \ +) + +VALID_SEMVERS=$(printf "%s\n%s\n%s" \ + "$VALID_NORMALIZED_SEMVERS" \ + "$VALID_NON_NORMALIZED_SEMVERS" \ + "$(generate_semvers "$VALID_NORMALIZED_VERSIONS" "$VALID_NON_NORMALIZED_SEMVER_OPERATORS" 0)" \ +) + +VALID_SEMVERS_FOR_PKG_JSON=$(printf "%s\n%s" \ + "$VALID_SEMVERS" \ + "$VALID_COMPLEX_SEMVERS_FOR_PKG_JSON" \ +)