if [[ -z "$1" ]]
  then
    echo "Must have a first parameter with the version (e.g. 0.5.4) not in quotes!"
    exit 1
  fi

command="java -jar target/zprint-filter-$1"
if [[ $2 != "uberjar" ]]
  then
    command="./zprintm-$1"
    if [[ $2 != "graalvm-mac" ]]
      then
	command="./zprintl-$1"
	if [[ $2 != "graalvm-linux" ]]
	  then
	    echo "Second argument must be uberjar or graalvm-mac or graalvm-linux!"
	    exit 1
	fi
    fi
fi


#
# Output something to format
#
# These will be cleaned up later
#

echo "{:this :is :a :test :thix :is :only :a :test :foo :bar :baz}" > test_config.map.clj
echo "\"Hello World!\"" > test_config.string.clj

#
# Save ~/.zprintrc and ./.zprintrc
#


if [[ -f "$HOME/.zprintrc" ]]
  then
    echo "Saving ~/.zprintrc as ~/.zprintrc.save"
    mv ~/.zprintrc ~/.zprintrc.save
fi

if [[ -f "./.zprintrc" ]]
  then
    echo "Saving ./.zprintrc ./.zprintrc.save"
    mv ./.zprintrc ./.zprintrc.save
fi

if [[ -f "./.zprint.edn" ]]
  then
    echo "Saving ./.zprint.edn ./.zprint.edn.save"
    mv ./.zprint.edn ./.zprint.edn.save
fi

echo "If you ^c out of this test, be sure and clean up ~/.zprintrc, ./.zprintrc and ./.zprint.edn!"

#
# Create new, narrow, ~/.zprintrc
# and color local ./.zprintrc
#

echo "{:width 40 :url {:cache-dir \"configurldir\" :cache-secs 9}}" > ~/.zprintrc
echo "{:color? true}" > ./.zprintrc

# Make a test config file

echo "{:color? true}" > test_config.edn

# Remove any previously cached url

rm -rf ~/.zprint/configurldir

###############################
# 
# Start of Tests
#

#
# Set up for testing --url and --url-only
#

# Start a web-server

#python -m SimpleHTTPServer 8081  >/dev/null 2&>1 &
./bbfiles/http-server.bb -p 8081 >/dev/null 2&>1 &

# Let it come up

sleep 5

#
# Try --url
#
# It should do the map in 6 lines in color.  
#  6 lines from ~/.zprintrc width 40
#  color from config_test.edn
#  197 means 6 lines in color
#   71 means 6 lines w/out color
#  192 means 1 line w/color
#


echo "...........  --url"

output_length=`$command --url 'http://127.0.0.1:8081/test_config.edn' <test_config.map.clj | wc -c`
output_length=`echo "${output_length}" | sed -e 's/^[[:space:]]*//'`
#echo "length is $output_length"

expected_length=197

if [[ $output_length != $expected_length ]]
  then
    echo "--url test failed to have correct count of chars, should be $expected_length, was: $output_length"
    $command --url 'http://127.0.0.1:8081/test_config.edn' <test_config.map.clj 

fi

#
# Remove file that is the target of --url, see if cache works
#

rm -rf test_config.edn

echo "...........  --url, with URL missing, see if cache works"

output_length=`$command --url 'http://127.0.0.1:8081/test_config.edn' <test_config.map.clj | wc -c`
output_length=`echo "${output_length}" | sed -e 's/^[[:space:]]*//'`
#echo "length is $output_length"

expected_length=197

if [[ $output_length != $expected_length ]]
  then
    echo "--url test failed to have correct count of chars, should be $expected_length, was: $output_length"
    $command --url 'http://127.0.0.1:8081/test_config.edn' <test_config.map.clj 

fi

sleep 10

echo "...........  --url, with URL missing, see if expired cache works"

output_length=`$command --url 'http://127.0.0.1:8081/test_config.edn' <test_config.map.clj 2>&1 | wc -c`
output_length=`echo "${output_length}" | sed -e 's/^[[:space:]]*//'`
#echo "length is $output_length"

expected_length=323

if [[ $output_length != $expected_length ]]
  then
    echo "--url test failed to have correct count of chars, should be $expected_length, was: $output_length"
    $command --url 'http://127.0.0.1:8081/test_config.edn' <test_config.map.clj 

fi

rm -rf ~/.zprint/configurldir

echo "...........  --url, with URL missing, and no cache"

output_length=`$command --url 'http://127.0.0.1:8081/test_config.edn' <test_config.map.clj 2>&1 | grep ERROR | wc -c`
output_length=`echo "${output_length}" | sed -e 's/^[[:space:]]*//'`
#echo "length is $output_length"

expected_length=214

if [[ $output_length != $expected_length ]]
  then
    echo "--url test failed to have correct count of chars, should be $expected_length, was: $output_length"
    $command --url 'http://127.0.0.1:8081/test_config.edn' <test_config.map.clj 

fi

#
# The URL is there, but not a valid Clojure map
#

# Make a test config file that is not a Clojure map

echo "{:color? true" > test_config.edn

echo "...........  --url, with URL not a valid Clojure map, and no cache"

output_length=`$command --url 'http://127.0.0.1:8081/test_config.edn' <test_config.map.clj 2>&1 | grep ERROR | wc -c`
output_length=`echo "${output_length}" | sed -e 's/^[[:space:]]*//'`
#echo "length is $output_length"

expected_length=226

if [[ $output_length != $expected_length ]]
  then
    echo "--url test failed to have correct count of chars, should be $expected_length, was: $output_length"
    $command --url 'http://127.0.0.1:8081/test_config.edn' <test_config.map.clj 

fi

#
# Valid Clojure map, but not valid zprint options map
#

echo "{:colorx? true}" > test_config.edn

echo "...........  --url, with URL not a valid zprint options map, and no cache"

output_length=`$command --url 'http://127.0.0.1:8081/test_config.edn' <test_config.map.clj 2>&1 | grep ERROR | wc -c`
output_length=`echo "${output_length}" | sed -e 's/^[[:space:]]*//'`
#echo "length is $output_length"

expected_length=396

if [[ $output_length != $expected_length ]]
  then
    echo "--url test failed to have correct count of chars, should be $expected_length, was: $output_length"
    $command --url 'http://127.0.0.1:8081/test_config.edn' <test_config.map.clj 

fi

#
# Fix URL file
#

echo "{:color? true}" > test_config.edn

echo "...........  --url-only, with valid URL and no cache"

output_length=`$command --url-only 'http://127.0.0.1:8081/test_config.edn' <test_config.map.clj 2>&1 | wc -c`
output_lines=`$command --url-only 'http://127.0.0.1:8081/test_config.edn' <test_config.map.clj 2>&1 | wc -l`
output_length=`echo "${output_length}" | sed -e 's/^[[:space:]]*//'`
output_lines=`echo "${output_lines}" | sed -e 's/^[[:space:]]*//'`
#echo "length is $output_length"
#echo "lines is $output_lines"

expected_length=192

if [[ $output_length != $expected_length ]]
  then
    echo "--url test failed to have correct count of chars, should be $expected_length, was: $output_length"
    $command --url-only 'http://127.0.0.1:8081/test_config.edn' <test_config.map.clj 

fi

expected_line_length=1

if [[ $output_lines != $expected_line_length ]]
  then
    echo "--url test failed to have correct count of lines, should be $expected_line_length, was: $output_lines"
    $command --url-only 'http://127.0.0.1:8081/test_config.edn' <test_config.map.clj 

fi


#
# URL file with fn included, should pass as of 1.1
#

# remove cache
rm -rf ~/.zprint/configurldir

# URL config file containing fn, which should now work since we use sci
echo "{:vector {:option-fn-first (fn [x y] {})}}" > test_config.edn

echo "...........  --url-only, with valid URL, file w/fn, and no cache"

output_length=`$command --url-only 'http://127.0.0.1:8081/test_config.edn' <test_config.map.clj 2>&1 | wc -c`
output_length=`echo "${output_length}" | sed -e 's/^[[:space:]]*//'`
#echo "length is $output_length"

expected_length=66

if [[ $output_length != $expected_length ]]
  then
    echo "--url with fn test failed to have correct count of characters, should be $expected_length, was: $output_length"
    $command --url-only 'http://127.0.0.1:8081/test_config.edn' <test_config.map.clj 

fi




#
# End of URL tests, kill webserver
#

{ kill %1 && wait %1; } 2>/dev/null
sleep 2


#
# Try basic config and see if that works.
#

echo "...........  basic config test."

output_length=`$command <test_config.string.clj 2>&1 | wc -c`
output_length=`echo "${output_length}" | sed -e 's/^[[:space:]]*//'`
#echo "length is $output_length"

expected_length=15

if [[ $output_length != $expected_length ]]
  then
    echo "basic config test failed to have correct count of chars, should be $expected_length, was: $output_length"
    $command <test_config.string.clj 

fi

# 
# Set up for comment in zprintrc test
#

echo "{:width 40 :url {:cache-dir \"configurldir\" ;test
:cache-secs 9}}" > ~/.zprintrc


#
# Try basic config with a comment in .zprintrc
#

echo "...........  basic config with comment in ~/.zprintrc test."

output_length=`$command <test_config.string.clj 2>&1 | wc -c`
output_length=`echo "${output_length}" | sed -e 's/^[[:space:]]*//'`
#echo "length is $output_length"

expected_length=15

if [[ $output_length != $expected_length ]]
  then
    echo "basic config with comment in zprintrc test failed to have correct count of chars, should be $expected_length, was: $output_length"
    $command <test_config.string.clj 

fi

#
# put zprintrc back w/out a comment 
#

echo "{:width 40 :url {:cache-dir \"configurldir\" :cache-secs 9}}" > ~/.zprintrc


# Make a local .zprintrc

echo "{:color? true}" > .zprintrc

#
# See if we can get {:cwd-zprintrc? true} to be recognized on the command line
#

echo "...........  {:cwd-zprintrc? true} on command line test"

output_length=`$command '{:cwd-zprintrc? true}' <test_config.string.clj 2>&1 | wc -c`
output_length=`echo "${output_length}" | sed -e 's/^[[:space:]]*//'`
#echo "length is $output_length"

expected_length=24

if [[ $output_length != $expected_length ]]
  then
    echo "{:cwd-zprintrc? true} test failed to have correct count of chars, should be $expected_length, was: $output_length"
    $command '{:cwd-zprintrc? true}' <test_config.string.clj 

fi

#
# See if we can get {:search-config? true} to be recognized on the command line
#

echo "...........  {:search-config? true} on command line test"

output_length=`$command '{:search-config? true}' <test_config.string.clj 2>&1 | wc -c`
output_length=`echo "${output_length}" | sed -e 's/^[[:space:]]*//'`
#echo "length is $output_length"

expected_length=24

if [[ $output_length != $expected_length ]]
  then
    echo "{:search-config? true} test failed to have correct count of chars, should be $expected_length, was: $output_length"
    $command '{:search-config? true}' <test_config.string.clj 

fi

#
# Is ~/.zprintrc being used at all?
#

echo "...........  ~/.zprintrc being used test"

output_length=`$command <test_config.map.clj 2>&1 | wc -c`
output_length=`echo "${output_length}" | sed -e 's/^[[:space:]]*//'`
#echo "length is $output_length"

expected_length=71

if [[ $output_length != $expected_length ]]
  then
    echo "~/.zprintrc being used test failed to have correct count of chars, should be $expected_length, was: $output_length"
    $command <test_config.map.clj 

fi

#
# Is .zprintrc being used at all?
#

# Use alternative (it is restored after this test)
echo "(def a :b) (def c :d)" > test_config.string.clj

# Make a local .zprintrc

echo "{:parse {:interpose \"\nxxx\n\"}}" > .zprintrc

# Set up a  ~/.zprintrc where it will read the local .zprintrc
echo "{:search-config? true}" > ~/.zprintrc

echo "...........  .zprintrc being used test"

output_length=`$command  <test_config.string.clj 2>&1| grep "xxx" | wc -l`
char_length=`$command <test_config.string.clj 2>&1| grep "xxx" | wc -c`
output_length=`echo "${output_length}" | sed -e 's/^[[:space:]]*//'`
char_length=`echo "${char_length}" | sed -e 's/^[[:space:]]*//'`
#echo "length is $output_length"
#echo "char count is $char_length"

expected_length=1
expected_chars=4

if [[ $output_length != $expected_length ]]
  then
    echo ".zprintrc being used test failed to have correct count of lines after grep for 'xxx' added by {:parse {:interpose ...}}, should be $expected_length, was: $output_length"
    $command  <test_config.string.clj 
fi

if [[ $char_length != $expected_chars ]]
  then
    echo ".zprintrc being used test failed to have correct count of chars after grep for 'xxx' added by {:parse {:interpose ...}}, should be $expected_chars, was: $char_length"
    $command  <test_config.string.clj 
fi



# Restore test_config.string.clj
echo "\"Hello World!\"" > test_config.string.clj
# Restore ~/.zprintrc
echo "{:width 40 :url {:cache-dir \"configurldir\" :cache-secs 9}}" > ~/.zprintrc
# Remove .zprintrc
rm .zprintrc


#
# ~/.zprintrc should not be used now, since this is -d
#

echo "...........  -d test -- ~/.zprintrc should not be used"

output_length=`$command -d <test_config.map.clj 2>&1 | wc -c`
output_length=`echo "${output_length}" | sed -e 's/^[[:space:]]*//'`
#echo "length is $output_length"

expected_length=66

if [[ $output_length != $expected_length ]]
  then
    echo "-d test -- ~/.zprintrc should not be used test failed to have correct count of chars, should be $expected_length, was: $output_length"
    $command -d <test_config.map.clj 

fi


#
# Try bad basic ~/.zprintrc
#
#  This is not a valid Clojure map (missing last '}'")
#

echo "{:width 40 :url {:cache-dir \"configurldir\" :cache-secs 9}" > ~/.zprintrc

echo "...........  bad ~/.zprintrc, invalid Clojure map test"

output_length=`$command <test_config.string.clj 2>&1| grep "EOF while reading" | wc -l`
output_length=`echo "${output_length}" | sed -e 's/^[[:space:]]*//'`
#echo "length is $output_length"

expected_length=1

if [[ $output_length != $expected_length ]]
  then
    echo "bad ~/.zprintrc (invalid Clojure map) test failed to have correct count of lines after grep for 'EOF while reading', should be $expected_length, was: $output_length"
    $command <test_config.string.clj 

fi

#
# Try another bad basic ~/.zprintrc
#
#  This is a valid Clojure map, but not a valid zprint options map
#

echo "{:widthxxx 40 :url {:cache-dir \"configurldir\" :cache-secs 9}}" > ~/.zprintrc

echo "...........  invalid zprint options map in ~/.zprintrc"

output_length=`$command <test_config.string.clj 2>&1| grep "the key :widthxxx was not recognized as valid" | wc -l`

output_length=`echo "${output_length}" | sed -e 's/^[[:space:]]*//'`
#echo "length is $output_length"

expected_length=1

if [[ $output_length != $expected_length ]]
  then
    echo "invalid zprint options map in ~/.zprintrc test failed to have correct count of chars, should be $expected_length, was: $output_length"
    $command <test_config.string.clj 

fi


#
# Put back a reasonable ~/.zprintrc
#

echo "{:width 40 :url {:cache-dir \"configurldir\" :cache-secs 9}}" > ~/.zprintrc


#
# Test -v switch (version output)
#

echo "...........  -v test"

zprint_version=`$command -v 2>&1 >/dev/null`
if [[ $zprint_version != "zprint-$1" ]]
  then
    echo "-v test failed to have correct version, should be zprint-$1, was: $zprint-version"
    $command -v
fi

#
# Test -h switch (help output)
#
#   Of course, it needs to be fixed when we change the help output
#

echo "...........  -h test"

output_length=`$command -h 2>&1 >/dev/null | wc -l`
output_length=`echo "${output_length}" | sed -e 's/^[[:space:]]*//'`
#echo "length is $output_length"

expected_length=69

if [[ $output_length != $expected_length ]]
  then
    echo "-h test failed to have correct count of chars, should be $expected_length, was: $output_length"
    $command -h
fi

#
# Test --explain-all switch (explain output)
#
#   Of course, it needs to be fixed when we change the config options map
#

echo "...........  --explain-all test"

output_length=`$command --explain-all 2>&1 >/dev/null | wc -l`
output_length=`echo "${output_length}" | sed -e 's/^[[:space:]]*//'`
#echo "length is $output_length"

expected_length=829

if [[ $output_length != $expected_length ]]
  then
    echo "--explain-all test failed to have correct count of lines, should be $expected_length, was: $output_length"
    $command --explain-all
fi

echo "...........  --explain test"

output_length=`$command '{:color? false}' --explain 2>&1 >/dev/null | wc -l`
output_length=`echo "${output_length}" | sed -e 's/^[[:space:]]*//'`
#echo "length is $output_length"

expected_length=16

if [[ $output_length != $expected_length ]]
  then
    echo "--explain test failed to have correct count of lines, should be $expected_length, was: $output_length"
    $command '{:color? false}' --explain
fi


#
# Test :coerce-to-false
#

#
# Configure some strange .zprintrc files to test coerce-to-false
#

echo "...........  :coerce-to-false test"

echo "{:cwd-zprintrc? 1 :coerce-to-false 0 :parallel? \"junk\"}" > ~/.zprintrc

echo "{:parallel? :stuff :coerce-to-false :stuff :width 500}" > ./.zprintrc


output_length=`$command --explain-all 2>&1| grep :parallel? | grep ":value false" | wc -l`
output_length=`echo "${output_length}" | sed -e 's/^[[:space:]]*//'`
#echo "length is $output_length"

expected_length=1

if [[ $output_length != $expected_length ]]
  then
    echo ":coerce-to-false test failed to have correct count of lines, should be $expected_length, was: $output_length"
    $command --explain-all
fi

#
# Configure some strange .zprintrc files to test fns in zprintrc files
#

echo "...........  fn using (fn ...) in ~/.zprintrc file test"

# ~/.zprintrc gets a fn
echo "{:vector {:option-fn-first (fn [x y] {})}}" > ~/.zprintrc
# no ./.zprintrc
rm -rf ./.zprintrc

output_length=`$command --explain-all 2>&1| grep -A 3 :option-fn-first | grep ":set-by" | wc -l`
output_length=`echo "${output_length}" | sed -e 's/^[[:space:]]*//'`
#echo "length is $output_length"

# As of 1.1, we expect this to work in both uberjar and graalvm versions
expected_length=1

if [[ $output_length != $expected_length ]]
  then
    echo "fn in ~/.zprintrc test failed to have correct count of lines, should be $expected_length, was: $output_length"
    $command --explain-all
fi

echo "...........  fn using #(...) in ~/.zprintrc file test"

# ~/.zprintrc gets a fn
echo "{:vector {:option-fn-first #(do (nil? %1) (nil? %2) {})}}" > ~/.zprintrc
# no ./.zprintrc
rm -rf ./.zprintrc

output_length=`$command --explain-all 2>&1| grep -A 3 :option-fn-first | grep ":set-by" | wc -l`
output_length=`echo "${output_length}" | sed -e 's/^[[:space:]]*//'`
#echo "length is $output_length"

# As of 1.1, we expect this to work in both uberjar and graalvm versions
expected_length=1

if [[ $output_length != $expected_length ]]
  then
    echo "fn in ~/.zprintrc test failed to have correct count of lines, should be $expected_length, was: $output_length"
    $command --explain-all
fi

echo "...........  fn #(...) in .zprintrc, unused, no :cwd-zprintrc?/:search-config?"

# .zprintrc gets a fn
echo "{:vector {:option-fn-first #(do (nil? %1) (nil? %2) {})}}" >.zprintrc
# no ~/.zprintrc
rm -rf ~/.zprintrc

output_length=`$command --explain-all 2>&1| grep -A 3 :option-fn-first | grep ":set-by" | wc -l`
output_length=`echo "${output_length}" | sed -e 's/^[[:space:]]*//'`
#echo "length is $output_length"

expected_length=0

if [[ $output_length != $expected_length ]]
  then
    echo "fn in ~/.zprintrc test failed to have correct count of lines, should be $expected_length, was: $output_length"
    $command --explain-all
fi

# .zprintrc gets a fn
echo "{:vector {:option-fn-first #(do (nil? %1) (nil? %2) {})}}" >.zprintrc
echo "{:search-config? true}" > ~/.zprintrc

output_length=`$command --explain-all 2>&1| grep -A 3 :option-fn-first | grep ":set-by" | wc -l`
output_length=`echo "${output_length}" | sed -e 's/^[[:space:]]*//'`
#echo "length is $output_length"

# As of 1.1, we expect this to work in both uberjar and graalvm versions
expected_length=1

if [[ $output_length != $expected_length ]]
  then
    echo "fn in ~/.zprintrc test failed to have correct count of lines, should be $expected_length, was: $output_length"
    $command --explain-all
fi

echo "...........  fn #(...) in .zprintrc found since :cwd-zprintrc?"

# .zprintrc gets a fn
echo "{:vector {:option-fn-first #(do (nil? %1) (nil? %2) {})}}" >.zprintrc
echo "{:cwd-zprintrc? true}" > ~/.zprintrc

output_length=`$command --explain-all 2>&1| grep -A 3 :option-fn-first | grep ":set-by" | wc -l`
output_length=`echo "${output_length}" | sed -e 's/^[[:space:]]*//'`
#echo "length is $output_length"

# As of 1.1, we expect this to work in both uberjar and graalvm versions
expected_length=1

if [[ $output_length != $expected_length ]]
  then
    echo "fn in ~/.zprintrc test failed to have correct count of lines, should be $expected_length, was: $output_length"
    $command --explain-all
fi


echo "...........  local .zprintrc file that does not parse found with :search-config?"

# .zprintrc gets a bad file
echo "{:vector :stuff {:option-fn-first #(do (nil? %1) (nil? %2) {})}}" >.zprintrc
echo "{:search-config? true}" > ~/.zprintrc

output_length=`$command --explain-all 2>&1| grep "Unable to read configuration from file" | wc -l`
output_length=`echo "${output_length}" | sed -e 's/^[[:space:]]*//'`
#echo "length is $output_length"

expected_length=1

if [[ $output_length != $expected_length ]]
  then
    echo "fn in ~/.zprintrc test failed to have correct count of lines, should be $expected_length, was: $output_length"
    $command --explain-all
fi


echo "...........  local .zprintrc file that does not parse found with :cwd-zprintrc?"

# .zprintrc gets a bad file
echo "{:vector :stuff {:option-fn-first #(do (nil? %1) (nil? %2) {})}}" >.zprintrc
echo "{:cwd-zprintrc? true}" > ~/.zprintrc

output_length=`$command --explain-all 2>&1| grep "Unable to read configuration from file" | wc -l`
output_length=`echo "${output_length}" | sed -e 's/^[[:space:]]*//'`
#echo "length is $output_length"

expected_length=1

if [[ $output_length != $expected_length ]]
  then
    echo "fn in ~/.zprintrc test failed to have correct count of lines, should be $expected_length, was: $output_length"
    $command --explain-all
fi

echo "...........  local .zprintrc file with bad data found with :search-config?"

# .zprintrc gets a bad file
echo "{:vectorxxx {:option-fn-first #(do (nil? %1) (nil? %2) {})}}" >.zprintrc
echo "{:search-config? true}" > ~/.zprintrc

output_length=`$command --explain-all 2>&1| grep "was not recognized as valid" | wc -l`
output_length=`echo "${output_length}" | sed -e 's/^[[:space:]]*//'`
#echo "length is $output_length"

expected_length=1

if [[ $output_length != $expected_length ]]
  then
    echo "fn in ~/.zprintrc test failed to have correct count of lines, should be $expected_length, was: $output_length"
    $command --explain-all
fi


echo "...........  local .zprintrc file with bad data found with :cwd-zprintrc?"

# .zprintrc gets a bad file
echo "{:vectorxxx {:option-fn-first #(do (nil? %1) (nil? %2) {})}}" >.zprintrc
echo "{:cwd-zprintrc? true}" > ~/.zprintrc

output_length=`$command --explain-all 2>&1| grep "was not recognized as valid" | wc -l`
output_length=`echo "${output_length}" | sed -e 's/^[[:space:]]*//'`
#echo "length is $output_length"

expected_length=1

if [[ $output_length != $expected_length ]]
  then
    echo "fn in ~/.zprintrc test failed to have correct count of lines, should be $expected_length, was: $output_length"
    $command --explain-all
fi







#
# Configure some strange .zprintrc files to test fns in zprintrc files
#

echo "...........  fn is valid in ./.zprintrc file test"

# ~/.zprintrc does not get a fn
echo "{:cwd-zprintrc? true :vector {:option-fn-first nil}}" > ~/.zprintrc

# ./.zprintrc gets a fn, which should pass as of 1.1
echo "{:vector {:option-fn-first (fn [x y] {})}}" > ./.zprintrc


output_length=`$command --explain-all 2>&1| grep -A 3 :option-fn-first | grep ":set-by" | wc -l`
output_length=`echo "${output_length}" | sed -e 's/^[[:space:]]*//'`
#echo "length is $output_length"

expected_length=1

if [[ $output_length != $expected_length ]]
  then
    echo "fn is valid in ./.zprintrc test failed to have correct count of lines, should be $expected_length, was: $output_length"
    $command --explain-all
fi

#
# Fns on the command line
#

echo "...........  fn using (fn [x y] ...) on command line test"

# ~/.zprintrc gets a fn
echo "{:vector {:option-fn-first (fn [x y] {})}}" > ~/.zprintrc

# No ./.zprintrc
rm -rf ./.zprintrc

output_length=`$command '{:vector {:option-fn-first (fn [x y] {})}}' <test_config.string.clj 2>&1| grep "Hello World!" |  wc -l`
output_length=`echo "${output_length}" | sed -e 's/^[[:space:]]*//'`
#echo "length is $output_length"

# As of 1.1, this should work for every version
expected_length=1

if [[ $output_length != $expected_length ]]
  then
    echo "fn on command line test failed to have correct count of lines, should be $expected_length, was: $output_length"
    $command '{:vector {:option-fn-first (fn [x y] {})}}' <test_config.string.clj 
fi

echo "...........  fn using #(...) on command line test"

# ~/.zprintrc gets a fn
echo "{:vector {:option-fn-first #(do (nil? %1) (nil? %2) {})}}" > ~/.zprintrc

# No ./.zprintrc
rm -rf ./.zprintrc

output_length=`$command '{:vector {:option-fn-first #(do (nil? %1) (nil? %2) {})}}' <test_config.string.clj 2>&1| grep "Hello World!" |  wc -l`
output_length=`echo "${output_length}" | sed -e 's/^[[:space:]]*//'`
#echo "length is $output_length"

# As of 1.1, this should work for every version
expected_length=1

if [[ $output_length != $expected_length ]]
  then
    echo "fn on command line test failed to have correct count of lines, should be $expected_length, was: $output_length"
    $command '{:vector {:option-fn-first (fn [x y] {})}}' <test_config.string.clj 
fi


#
# -w tests
#

# Put in a reasonable (and different than before) .zprintrc

echo "{:width 80}" > ~/.zprintrc

echo "...........  -w test with one file"

cp test_config.map.clj test_config.map1.clj
$command -w test_config.map1.clj 2> test_config.stderr.out > test_config.stdout.out
output_length=`cat test_config.map1.clj test_config.stderr.out test_config.stdout.out | wc -c`
output_length=`echo "${output_length}" | sed -e 's/^[[:space:]]*//'`
#echo "-w length is $output_length"

expected_length=66

if [[ $output_length != $expected_length ]]
  then
    echo "-w test failed to have correct count of chars, should be 66, was: $output_length"
    cat test_config.map1.clj test_config.stderr.out test_config.stdout.out
    wc -c test_config.map1.clj test_config.stderr.out test_config.stdout.out

fi
rm test_config.stdout.out
rm test_config.stderr.out
rm test_config.map1.clj

#
# -w with multiple files
#

echo "...........  -w test with two files"

cp test_config.map.clj test_config.map1.clj
cp test_config.map.clj test_config.map2.clj
$command -w test_config.map1.clj test_config.map2.clj 2> test_config.stderr.out > test_config.stdout.out
output_length=`cat test_config.map1.clj test_config.map2.clj test_config.stderr.out test_config.stdout.out | wc -c`
output_length=`echo "${output_length}" | sed -e 's/^[[:space:]]*//'`
#echo "-w length is $output_length"

expected_length=132

if [[ $output_length != $expected_length ]]
  then
    echo "-w test failed to have correct count of chars, should be $expected_length, was: $output_length"
    cat test_config.map1.clj test_config.map2.clj test_config.stderr.out test_config.stdout.out
    wc -c test_config.map1.clj test_config.map2.clj test_config.stderr.out test_config.stdout.out

fi
rm test_config.stdout.out
rm test_config.stderr.out
rm test_config.map1.clj
rm test_config.map2.clj

#
# -w with multiple files, one of which doesn't exist
#

echo "...........  -w test with three files, one of which doesn't exist"

cp test_config.map.clj test_config.map1.clj
cp test_config.map.clj test_config.map2.clj
$command -w test_config.map1.clj test_config.missing.clj test_config.map2.clj 2> test_config.stderr.out > test_config.stdout.out
output_length=`cat test_config.map1.clj test_config.map2.clj test_config.stderr.out test_config.stdout.out | wc -c`
output_length=`echo "${output_length}" | sed -e 's/^[[:space:]]*//'`
#echo "-w length is $output_length"

expected_length=268

if [[ $output_length != $expected_length ]]
  then
    echo "-w test failed to have correct count of chars, should be $expected_length, was: $output_length"
    cat test_config.map1.clj test_config.map2.clj test_config.stderr.out test_config.stdout.out
    wc -c test_config.map1.clj test_config.map2.clj test_config.stderr.out test_config.stdout.out

fi
rm test_config.stdout.out
rm test_config.stderr.out
rm test_config.map1.clj
rm test_config.map2.clj

#
# -w with two files, the first of which is read-only
#

echo "...........  -w test with two files, the first which is read-only"

cp test_config.map.clj test_config.map1.clj
chmod -w test_config.map1.clj
cp test_config.map.clj test_config.map2.clj
$command -w test_config.map1.clj test_config.map2.clj 2> test_config.stderr.out > test_config.stdout.out
cp test_config.stderr.out test_config.stderr.out.orig
rm test_config.stderr.out
# Remove stuff between parens at the end, which varies by operating system.
sed 's/([^()]*)//g' <test_config.stderr.out.orig >test_config.stderr.out
rm test_config.stderr.out.orig
output_length=`cat test_config.map1.clj test_config.map2.clj test_config.stderr.out test_config.stdout.out | wc -c`
output_length=`echo "${output_length}" | sed -e 's/^[[:space:]]*//'`
#echo "-w length is $output_length"

expected_length=238

if [[ $output_length != $expected_length ]]
  then
    echo "-w test failed to have correct count of chars, should be $expected_length, was: $output_length"
    cat test_config.map1.clj test_config.map2.clj test_config.stderr.out test_config.stdout.out
    wc -c test_config.map1.clj test_config.map2.clj test_config.stderr.out test_config.stdout.out

fi
rm test_config.stdout.out
rm test_config.stderr.out
rm -rf test_config.map1.clj
rm test_config.map2.clj

#
# -w with two files, the first of which fails to format
#

echo "...........  -w test with two files, the first which fails to format"

echo ";!zprint {:format" >test_config.map1.clj
echo "{:this :is :a :test :thix :is :only :a :test :foo :bar :baz}" >>test_config.map1.clj
cp test_config.map1.clj test_config.map1.clj.save
cp test_config.map.clj test_config.map2.clj
$command -w test_config.map1.clj test_config.map2.clj 2> test_config.stderr.out > test_config.stdout.out
diff test_config.map1.clj test_config.map1.clj.save >test_config.diff.out
output_length=`cat test_config.map1.clj test_config.diff.out test_config.map2.clj test_config.stderr.out test_config.stdout.out | wc -c`
output_length=`echo "${output_length}" | sed -e 's/^[[:space:]]*//'`
#echo "-w length is $output_length"

expected_length=580

if [[ $output_length != $expected_length ]]
  then
    echo "-w test failed to have correct count of chars, should be $expected_length, was: $output_length"
    cat test_config.map1.clj test_config.diff.out test_config.map2.clj test_config.stderr.out test_config.stdout.out
    wc -c test_config.map1.clj test_config.diff.out test_config.map2.clj test_config.stderr.out test_config.stdout.out

fi
rm test_config.stdout.out
rm test_config.stderr.out
rm test_config.diff.out
rm test_config.map1.clj
rm test_config.map1.clj.save
rm test_config.map2.clj

#
# local .zprintrc having a fn that is actually used
#

echo "...........  local .zprintrc having a fn that is used"

#
# Create necessary files
#

echo "(m/app :get  (m/app middle1 middle2 middle3" > test_config.source.clj
echo "                    [route] handler" >>test_config.source.clj
echo "                    [longer route]" >> test_config.source.clj
echo "        (handler this is a :test this :is only :a test))" >> test_config.source.clj
echo "       ; How do comments work here?" >> test_config.source.clj
echo "       true (should be paired with true)" >> test_config.source.clj
echo "       false (should be paired with false)" >> test_config.source.clj
echo "       6 (should be paired with 6)" >> test_config.source.clj
echo "       \"string\" (should be paired with \"string\")" >> test_config.source.clj
echo "       :post (m/app" >> test_config.source.clj
echo "                    [a really long route] handler" >> test_config.source.clj
echo "                    [route] " >> test_config.source.clj
echo "                    handler))" >> test_config.source.clj

echo "{:search-config? true}" > ~/.zprintrc

echo "{:fn-map {\"app\"," > .zprintrc
echo "          [:none" >> .zprintrc
echo "           {:list {:constant-pair-fn #(or (keyword? %)" >> .zprintrc
echo "                                          (string? %)" >> .zprintrc
echo "                                          (number? %)" >> .zprintrc
echo "                                          (= true %)" >> .zprintrc
echo "                                          (= false %)" >> .zprintrc
echo "                                          (vector? %))," >> .zprintrc
echo "                   :constant-pair-min 1}," >> .zprintrc
echo "            :next-inner {:list {:constant-pair-fn nil, :constant-pair-min 4}," >> .zprintrc
echo "                         :pair {:justify? false}}," >> .zprintrc
echo "            :pair {:justify? true}}]}}" >> .zprintrc

echo "(m/app :get     (m/app middle1" > test_config.out.clj
echo "                       middle2" >> test_config.out.clj
echo "                       middle3" >> test_config.out.clj
echo "                       [route]        handler" >> test_config.out.clj
echo "                       [longer route] (handler" >> test_config.out.clj
echo "                                        this" >> test_config.out.clj
echo "                                        is" >> test_config.out.clj
echo "                                        a" >> test_config.out.clj
echo "                                        :test this" >> test_config.out.clj
echo "                                        :is only" >> test_config.out.clj
echo "                                        :a test))" >> test_config.out.clj
echo "       ; How do comments work here?" >> test_config.out.clj
echo "       true     (should be paired with true)" >> test_config.out.clj
echo "       false    (should be paired with false)" >> test_config.out.clj
echo "       6        (should be paired with 6)" >> test_config.out.clj
echo "       \"string\" (should be paired with \"string\")" >> test_config.out.clj
echo "       :post    (m/app [a really long route] handler" >> test_config.out.clj
echo "                       [route] handler))" >> test_config.out.clj

#
# Do test
#

$command '{:width 60}' <test_config.source.clj 2> test_config.stderr.out > test_config.stdout.clj
diff test_config.stdout.clj test_config.out.clj >test_config.diff.out
output_length=`cat test_config.stdout.clj test_config.diff.out test_config.stderr.out | wc -c`
output_length=`echo "${output_length}" | sed -e 's/^[[:space:]]*//'`
#echo "length is $output_length"

expected_length=778

if [[ $output_length != $expected_length ]]
  then
    echo "local .zprintrc having a fn that is used failed to have correct count of chars, should be $expected_length, was: $output_length"
    cat test_config.stdout.clj test_config.diff.out test_config.stderr.out
    wc -c test_config.stdout.clj test_config.diff.out test_config.stderr.out

fi

#
# command line access to guide option-fn that is actually used
#

echo "...........  command line access to guide option-fn"

#
# Create necessary files
#

echo "(are [x y z] (= x y z) " >test_config.source.clj
echo "    3 (stuff y) (bother z) " >>test_config.source.clj
echo "   4 (foo y) (bar z)) " >>test_config.source.clj

echo "(are [x y z] (= x y z)" >test_config.out.clj
echo "  3 (stuff y) (bother z)" >>test_config.out.clj
echo "  4 (foo y) (bar z))" >>test_config.out.clj


#
# Do test
#

$command '{:width 80 :fn-map {"are" [:guided {:list {:option-fn (partial areguide {:justify? false})} :next-inner {:list {:option-fn nil}}}]}}' <test_config.source.clj 2> test_config.stderr.out > test_config.stdout.clj
diff test_config.stdout.clj test_config.out.clj >test_config.diff.out
output_length=`cat test_config.stdout.clj test_config.diff.out test_config.stderr.out | wc -c`
output_length=`echo "${output_length}" | sed -e 's/^[[:space:]]*//'`
#echo "length is $output_length"

expected_length=69

if [[ $output_length != $expected_length ]]
  then
    echo "command line access to guide option-fn failed to have correct count of chars, should be $expected_length, was: $output_length"
    cat test_config.stdout.clj test_config.diff.out test_config.stderr.out
    wc -c test_config.stdout.clj test_config.diff.out test_config.stderr.out

fi

rm test_config.stdout.clj
rm test_config.stderr.out
rm test_config.diff.out
rm test_config.source.clj
rm test_config.out.clj

#
# Clean up
#

rm -rf test_config.edn
rm -rf test_config.map.clj
rm -rf test_config.string.clj

#
# Restore ~/.zprintrc if we saved one
#

rm -rf ~/.zprintrc
if [[  -e "$HOME/.zprintrc.save" ]]
  then
    echo "Restoring ~/.zprintrc"
    mv ~/.zprintrc.save ~/.zprintrc
fi

#
# Restore ./.zprintrc if we saved one
#

rm -rf ./.zprintrc
if [[  -e "./.zprintrc.save" ]]
  then
    echo "Restoring ./.zprintrc"
    mv ./.zprintrc.save ./.zprintrc
fi

#
# Restore ./.zprint.edn if we saved one
#

rm -rf ./.zprint.edn
if [[  -e "./.zprint.edn.save" ]]
  then
    echo "Restoring ./.zprint.edn"
    mv ./.zprint.edn.save ./.zprint.edn
fi

#
# Get rid of any log files from the python server
#

rm -rf 1

