Zsh Mailing List Archive
Messages sorted by: Reverse Date, Date, Thread, Author

[PATCH 2/2] Consolidated nofork substitution tests



Note the last test (break N propagates) references the as-yet-unfixed
bug from workers/52151.
diff --git a/Test/D10nofork.ztst b/Test/D10nofork.ztst
new file mode 100644
index 000000000..024b8ffcc
--- /dev/null
+++ b/Test/D10nofork.ztst
@@ -0,0 +1,448 @@
+# Tests for "nofork" command substitution.
+
+%prep
+  mkdir nofork.tmp
+  touch nofork.tmp/file{1,2}.txt
+
+  purr() { print -r -- "$@" }
+  purl() { print -rl -- "$@" }
+
+%test
+
+  REPLY=OUTER
+  purr ${| REPLY=INNER } $REPLY
+0:Basic substitution and REPLY scoping
+>INNER OUTER
+
+  purr ${| REPLY=first}:${| REPLY=second}:$REPLY
+0:re-scoping of REPLY in one statement
+>first:second:OUTER
+
+  purr BEGIN${| printf -v REPLY '%s\n' one two three ; }END
+0:Adjacent words
+>BEGINone
+>two
+>three
+>END
+
+  purr "BEGIN${| printf -v REPLY '%s\n' one two three }END"
+0:Adjacent words and quoting, part 1
+>BEGINone
+>two
+>three
+>END
+
+  purr BEGIN"${| printf -v REPLY '%s\n' one two three }"END
+0:Adjacent words and quoting, part 2
+>BEGINone
+>two
+>three
+>END
+
+  purr BEGIN"${|
+   printf -v REPLY '%s\n'\
+    one two three
+  }"END
+0:Embedded newlines
+>BEGINone
+>two
+>three
+>END
+
+  purr BEGIN"${|
+   printf -v REPLY $'%s\n' one two three
+  }"END
+0:Embedded newlines and $'...'
+>BEGINone
+>two
+>three
+>END
+
+  purl ${| print -v REPLY one word here; setopt shwordsplit }
+  purl ${| print -v REPLY three words here }
+  purl "and ${| print -v REPLY one word here }"
+  unsetopt shwordsplit
+0:test word splitting on result
+F:setting option inside is too late for that substitution
+>one word here
+>three
+>words
+>here
+>and one word here
+
+ (
+  cd nofork.tmp
+  setopt globsubst
+  purr ${| REPLY=f* }
+  purr ${| REPLY=f? }*
+  unsetopt globsubst
+  purr ${| REPLY=f* }
+  purr ${| REPLY=f? }*
+ )
+1:globsubst on result
+>file1.txt file2.txt
+>file1.txt file2.txt
+>f*
+?(eval):8: no matches found: f?*
+
+  purr ${| REPLY=$'trailing newlines remain\n\n' }
+0:newline removal should not occur
+>trailing newlines remain
+>
+>
+
+  () {
+   purr ${| REPLY=$* ; shift 2 }
+   purr $*
+  } these are arguments
+0:access to context $argv
+>these are arguments
+>arguments
+
+  purr ${:-${| REPLY=${REPLY:-buried}}}
+  purr ${:-"${| REPLY=${REPLY:-more buried}}"}
+0:nofork inside parameter scope
+>buried
+>more buried
+
+  : ${(e):-'${| REPLY=oops'}
+1:unclosed braces are sometimes a bad substitution
+F:This seems silly, but see A01grammar ${(e):-'${'} test
+?(eval):1: bad substitution
+
+  purr ${| REPLY=oops
+1:other times lack of closing brace is merely unexpected
+F:Why not use this error in the previous case as well?
+?(eval):1: closing brace expected
+
+# Next tests check that the PS2 stack is properly managed on error
+
+  purr ${| REPLY=${REPLY:-buried}}}
+1:unbalanced braces, part 0
+?(eval):1: parse error near `}'
+
+  purr ${:-${| REPLY=${REPLY:-buried}}
+1:unbalanced braces, part 1
+?(eval):1: closing brace expected
+
+  purr ${:-"${| REPLY=${REPLY:-more buried}"}
+1:unbalanced braces, part 2
+?(eval):1: unmatched "
+
+  purr ${:-"${| REPLY=${REPLY:-more buried"}}}
+1:unbalanced braces, part 3
+?(eval):1: unmatched "
+
+  purr ${:-"${| REPLY=${REPLY:-more buried}}}"
+1:unbalanced braces, part 4
+?(eval):1: closing brace expected
+
+# Same tests with leading space (future-proofing)
+
+  purr ${ purr ${REPLY:-buried}}}
+1:unbalanced braces, part 0+
+?(eval):1: parse error near `}'
+
+  purr ${:-${ purr ${REPLY:-buried}}
+1:unbalanced braces, part 1+
+?(eval):1: closing brace expected
+
+  purr ${:-"${ purr ${REPLY:-more buried}"}
+1:unbalanced braces, part 2+
+?(eval):1: unmatched "
+
+  purr ${:-"${ purr ${REPLY:-more buried"}}}
+1:unbalanced braces, part 3+
+?(eval):1: unmatched "
+
+  purr ${:-"${ purr ${REPLY:-more buried}}}"
+1:unbalanced braces, part 4+
+?(eval):1: closing brace expected
+
+  purr ${ purr STDOUT }
+0:capture stdout
+>STDOUT
+>
+
+# end PS2 stack tests 
+
+  purr $(purr outside ${| REPLY=inside })
+  purr BEGIN$(purr outside ${| REPLY=inside })END
+  purr "BEGIN$(purr outside ${| REPLY=inside })END"
+  purr outside ${| REPLY=$(purr inside)}
+  purr "outside ${| REPLY=$(purr inside)}"
+0:mixing with forking cmdsubst
+>outside inside
+>BEGINoutside insideEND
+>BEGINoutside insideEND
+>outside inside
+>outside inside
+
+  purr `purr outside ${| REPLY=inside }`
+  purr "outside `purr ${| REPLY=inside }`"
+  purr outside ${| REPLY=`purr inside`}
+  purr "outside ${| REPLY=`purr inside`}"
+  purr outside "`purr ${| REPLY="${:-inside}"}`"
+  purr "outside ${| REPLY=`purr ${:-inside}`}"
+0:mixing with backticks
+>outside inside
+>outside inside
+>outside inside
+>outside inside
+>outside inside
+>outside inside
+
+  purr ${| REPLY=$(( 9 + 17 )) }
+  purr $(( 9 + ${| REPLY=17 } ))
+0:mixing with arithemetic
+>26
+>26
+
+  unset reply
+  purl ${|reply| reply=(1 2 ${| REPLY=3 } 4) }
+  typeset -p reply
+0:array behavior with global assignment
+>1
+>2
+>3
+>4
+>typeset -g -a reply=( 1 2 3 4 )
+
+  unset outer
+  purr "${|
+   outer=OUTER
+   REPLY=INNER
+   return 7
+   OUTER=NOTREACHED
+  } $outer $?"
+0:return statement inside, part 1
+F:status of "print" should hide return
+>INNER OUTER 7
+
+  unset outer
+  outer=${| REPLY=${| return 7}}
+7:return status propages in assignment like $(...)
+
+  unset outer
+  purr "${|
+   outer=OUTER
+   REPLY=INNER
+   return 7
+   OUTER=NOTREACHED
+  } $outer $?"
+  print REACHED $OUTER
+0:return statement inside, part 2
+>INNER OUTER 7
+>REACHED
+
+  unset outer
+  purr "${|
+   # Localoptions needed to avoid breaking test harness?
+   # The setopt command affects surrounding context
+   setopt localoptions errreturn
+   outer=OUTER
+   REPLY=INNER
+   false
+   OUTER=NOTREACHED
+  } $outer $?"
+  print REACHED $OUTER ${options[errreturn]}
+0:errreturn works inside and remains outside
+>INNER OUTER 1
+>REACHED on
+
+ (
+  unset outer
+  purr "${|
+   outer=OUTER
+   REPLY=INNER
+   exit 7
+   OUTER=NOTREACHED
+  } $outer $OUTER $?"
+  print NOT REACHED
+ )
+7:exit statement inside
+
+ (
+  unset outer
+  purr "${|
+   setopt errexit
+   outer=OUTER
+   REPLY=INNER
+   false
+   OUTER=NOTREACHED
+  } $outer $?"
+  print NOT REACHED
+ )
+1:errexit inside
+
+  outer=GLOBAL
+  purr "${|
+   local outer=LOCAL
+   REPLY=INNER
+  } $outer $?"
+0:local declaration inside
+>INNER GLOBAL 0
+
+  unset zz
+  outer=GLOBAL
+  purr "${|zz|
+   local outer=LOCAL
+   zz=NONLOCAL
+  } $outer $?"
+  print $zz
+0:local declaration, global assignment, part 1
+>NONLOCAL GLOBAL 0
+>NONLOCAL
+
+  unset zz
+  outer=GLOBAL
+  purr "${${|
+   local outer=LOCAL
+   zz=NONLOCAL
+  }:-$zz} $outer $?"
+0:local declaration, global assignment, part 2 (evaluation order)
+>NONLOCAL GLOBAL 0
+
+  : ${| fn1() { () { print -v REPLY $'Defined Function' ;} ;} }
+  print "IN${| fn2() { () { print "${:-Second }${|fn1}" ;} ;} }OUT"
+  fn2
+0:function definition, brace nesting, quote nesting
+>INOUT
+>Second Defined Function
+
+  <<-EOF
+	${| REPLY=$'in a here document\n' }
+	EOF
+0:here-document behavior
+F:Fiddly here to get EOF past the test syntax
+>in a here document
+>
+
+  <<<${| REPLY="in a here string" }
+0:here-string behavior
+>in a here string
+
+  <<<${ purr $'stdout as a here string' }
+0:another capture stdout
+>stdout as a here string
+>
+
+  wrap=${| REPLY="REPLY in environment assignment" } typeset -p wrap
+  wrap=${ purr "capture in environment assignment" } typeset -p wrap
+0:assignment context
+>typeset -g wrap='REPLY in environment assignment'
+>typeset -g wrap=$'capture in environment assignment\n'
+
+# Repeat return and exit tests with stdout capture
+
+  purr "${
+   print INNER
+   return 7
+  } $?"
+0:return statement inside, part 1+
+F:status of "print" should hide return
+>INNER
+> 7
+
+  unset outer
+  outer=${ return 7 }
+7:return status propages in stdout capture
+
+  unset outer
+  purr "${
+   outer=OUTER
+   print INNER
+   return 7
+   OUTER=NOTREACHED
+  } $outer $?"
+  print REACHED $OUTER
+0:return statement inside, part 2+
+>INNER
+> OUTER 7
+>REACHED
+
+  unset outer
+  purr "${
+   # Localoptions needed to avoid breaking test harness?
+   # The setopt command affects surrounding context
+   setopt localoptions errreturn
+   outer=OUTER
+   print INNER
+   false
+   OUTER=NOTREACHED
+  } $outer $?"
+  print REACHED $OUTER ${options[errreturn]}
+0:errreturn works inside stdout capture
+>INNER
+> OUTER 1
+>REACHED on
+
+ (
+  unset outer
+  purr "${
+   outer=OUTER
+   print INNER
+   exit 7
+   OUTER=NOTREACHED
+  } $outer $OUTER $?"
+  print NOT REACHED
+ )
+7:exit statement inside stdout capture
+
+ (
+  unset outer
+  purr "${
+   setopt errexit
+   outer=OUTER
+   print INNER
+   false
+   OUTER=NOTREACHED
+  } $outer $?"
+  print NOT REACHED
+ )
+1:errexit inside stdout capture
+
+  setopt ignorebraces
+0:dummy test to set option soon enough
+F:must do this before evaluating the next test block
+
+  purr ${| REPLY=${REPLY:-buried}}}
+0:ignored braces, part 1
+>buried}
+
+  purr ${ purr ${REPLY:-buried}}}
+0:ignored braces, part 2
+>buried
+>}
+
+  purr ${ { echo nested ;} }
+0:ignored braces, part 3
+>nested
+>
+
+  purr ${ { echo nested } } DONE
+1:ignored braces, part 4
+?(eval):1: parse error near `}'
+
+  # "break" blocks function calls in outer loop
+  # Could use print, but that might get fixed
+  repeat 3 do purr ${
+   for x in 1 2 3 4
+    do (( x == 3 )) && break 2
+     # use error output to confirm loop count
+     print -u 2 $x
+    done
+   } XX
+  done
+0:break N propagates
+?1
+?2
+
+  print -u $ZTST_fd ${ZTST_testname}: TEST COMPLETE
+0:make sure we got to the end
+F:some tests might silently break the test harness
+
+%clean
+
+  unfunction purr purl
+  unsetopt ignorebraces


Messages sorted by: Reverse Date, Date, Thread, Author