#! /bin/sh
# vim:et:ft=sh:sts=2:sw=2
#
# shFlags unit test for the flag definition methods

# load test helpers
. ./shflags_test_helpers

#------------------------------------------------------------------------------
# suite tests
#

testFlagsDefine()
{
  # no arguments
  _flags_define >"${stdoutF}" 2>"${stderrF}"
  assertFalse '_flags_define() with no arguments should have failed.' $?
  assertErrorMsg '' 'no arguments'

  # one argument
  _flags_define arg1 >"${stdoutF}" 2>"${stderrF}"
  assertFalse '_flags_define() call with one argument should fail' $?
  assertErrorMsg '' 'one argument'

  # two arguments
  _flags_define arg1 arg2 >"${stdoutF}" 2>"${stderrF}"
  assertFalse '_flags_define() call with two arguments should fail' $?
  assertErrorMsg '' 'two arguments'

  # three arguments
  _flags_define arg1 arg2 arg3 >"${stdoutF}" 2>"${stderrF}"
  assertFalse '_flags_define() call with three arguments should fail' $?
  assertErrorMsg '' 'three arguments'

  # multiple definition -- assumes working boolean definition (tested elsewhere)
  _flags_define ${__FLAGS_TYPE_BOOLEAN} multiDefBool true 'multi def #1' m
  _flags_define ${__FLAGS_TYPE_BOOLEAN} multiDefBool false 'multi def #2' m \
      >"${stdoutF}" 2>"${stderrF}"
  assertFalse '_flags_define() with existing flag name should fail' $?
  assertTrue \
      '_flags_define() should not overwrite previously defined default.' \
      "${FLAGS_multiDefBool:-}"
  assertWarnMsg '' 'existing flag'

  # duplicate dashed and underscored definition
  _flags_define ${__FLAGS_TYPE_STRING} long-name 'foo' 'dashed name' l
  _flags_define ${__FLAGS_TYPE_STRING} long_name 'bar' 'underscored name' l \
      >"${stdoutF}" 2>"${stderrF}"
  assertFalse '_flags_define() with existing flag name should fail' $?
  assertEquals \
      '_flags_define() should not overwrite previously defined default.' \
      "${FLAGS_long_name}" 'foo'
  assertWarnMsg '' 'already exists'

  # TODO(kward): test requirement of enhanced getopt

  # invalid type
  _flags_define invalid arg2 arg3 arg4 i >"${stdoutF}" 2>"${stderrF}"
  assertFalse '_flags_define() with "invalid" type should have failed.' $?
  assertErrorMsg 'unrecognized flag type' 'invalid type'
}

testBoolean()
{
  # test true defaults
  for default in 'true' 't' 0; do
    flags_reset
    DEFINE_boolean boolVal "${default}" 'my boolean' b
    rtrn=$?
    assertTrue \
        "DEFINE_boolean() call with default of '${default}' failed." \
        "${FLAGS_boolVal:-}"
    assertTrue \
        "DEFINE_boolean() call with default of '${default}' returned faliure." \
        ${rtrn}
  done

  # test false defaults
  for default in 'false' 'f' 1; do
    flags_reset
    DEFINE_boolean boolVal "${default}" 'my boolean' b
    rtrn=$?
    assertFalse \
        "DEFINE_boolean() call with default of '${default}' failed." \
        "${FLAGS_boolVal:-}"
    assertTrue \
        "DEFINE_boolean() call with default of '${default}' returned faliure." \
        ${rtrn}
  done

  # test invalid default
  flags_reset
  DEFINE_boolean boolVal 'invalid' 'my boolean' b >"${stdoutF}" 2>"${stderrF}"
  assertFalse 'DEFINE_boolean() call with invalid default did not fail.' $?
  assertErrorMsg
}

testFloat()
{
  # test valid defaults
  for default in ${TH_FLOAT_VALID}; do
    flags_reset
    DEFINE_float floatVal ${default} "float: ${default}" f
    rtrn=$?
    assertSame "DEFINE_float() call with valid default failed." \
        ${default} "${FLAGS_floatVal:-}"
    assertTrue \
        "DEFINE_float() call with valid default of '${default}' returned faliure." \
        ${rtrn}
  done

  # test invalid defaults
  flags_reset
  DEFINE_float floatVal 'invalid' 'invalid float: string' f \
      >"${stdoutF}" 2>"${stderrF}"
  assertFalse 'DEFINE_float() call with string value default did not fail.' $?
  assertErrorMsg
}

testInteger()
{
  # test valid defaults
  for default in ${TH_INT_VALID}; do
    flags_reset
    DEFINE_integer intVal ${default} "integer: ${default}" i
    rtrn=$?
    assertSame \
        "DEFINE_integer() call with valid default failed." \
        ${default} "${FLAGS_intVal:-}"
    assertTrue \
        "DEFINE_integer() call with valid default of '${default}' returned failure." \
        ${rtrn}
  done

  # test invalid defaults
  flags_reset
  DEFINE_integer intVal 1.234 'invalid integer: float' i \
      >"${stdoutF}" 2>"${stderrF}"
  assertFalse 'DEFINE_integer() call with float value default did not fail.' $?
  assertErrorMsg 'invalid default' 'float default'

  DEFINE_integer intVal -1.234 'invalid integer: negative float' i \
      >"${stdoutF}" 2>"${stderrF}"
  assertFalse \
      'DEFINE_integer() call with negative float value default did not fail.' \
      $?
  assertErrorMsg 'invalid default' 'negative float default'

  DEFINE_integer intVal 'invalid' 'invalid integer: string' i \
      >"${stdoutF}" 2>"${stderrF}"
  assertFalse \
      'DEFINE_integer() call with string value default did not fail.' \
      $?
  assertErrorMsg 'invalid default' 'string default'
}

testString()
{
  # test valid defaults
  for default in \
      ${TH_BOOL_VALID} \
      ${TH_FLOAT_VALID} \
      ${TH_INT_VALID} \
      'also valid'
  do
    flags_reset
    DEFINE_string strVal "${default}" "string: ${default}" s
    rtrn=$?
    assertSame \
        "DEFINE_string() call with valid default failed." \
        "${default}" "${FLAGS_strVal:-}"
    assertTrue \
        "DEFINE_string() call with valid default of '${default}' returned faliure." \
        ${rtrn}
  done

  # test "empty" strings
  flags_reset
  DEFINE_string str '' "string: empty single quotes" s
  rtrn=$?
  assertSame \
      "DEFINE_string() call with valid default failed." \
      '' "${FLAGS_str:-}"
}

testShortNameLength()
{
  # make sure short names are no longer than a single character
  :
}

testFlagNameIsReserved()
{
  ( DEFINE_string TRUE '' 'true is a reserved flag name' t \
      >"${stdoutF}" 2>"${stderrF}" )
  rtrn=$?
  assertEquals ${FLAGS_ERROR} ${rtrn}
  assertErrorMsg 'flag name (TRUE) is reserved'
}

#------------------------------------------------------------------------------
# suite functions
#

oneTimeSetUp()
{
  th_oneTimeSetUp
}

tearDown()
{
  flags_reset
}

# load and run shUnit2
[ -n "${ZSH_VERSION:-}" ] && SHUNIT_PARENT=$0
. ${TH_SHUNIT}
