1
0
Fork 0
mirror of git://git.code.sf.net/p/zsh/code synced 2024-04-30 05:45:16 +02:00
zsh/Test/V10private.ztst

557 lines
11 KiB
Plaintext

# Tests for the zsh/param/private module
%prep
if ! zmodload zsh/param/private 2>/dev/null; then
ZTST_unimplemented="can't load the zsh/param/private module for testing"
else
# Do not use .tmp here, ztst.zsh will remove it too soon (see %cleanup)
mkdir private.TMP
sed -e 's,# test_zsh_param_private,zmodload zsh/param/private,' < $ZTST_srcdir/B02typeset.ztst > private.TMP/B02
fi
setopt TYPESET_TO_UNSET
%test
(zmodload -u zsh/param/private && zmodload zsh/param/private)
0:unload and reload the module without crashing
typeset scalar_test=toplevel
() {
print $scalar_test
private scalar_test
typeset +m scalar_test
unset scalar_test
print $+scalar_test
}
print $scalar_test
0:basic scope hiding
>toplevel
>local hide scalar_test
>0
>toplevel
typeset scalar_test=toplevel
print $scalar_test
() {
private scalar_test=function
print $scalar_test
}
print $scalar_test
0:enter and exit a scope
>toplevel
>function
>toplevel
print $+unset_test
() {
private unset_test
typeset +m unset_test
unset_test=setme
print $unset_test
}
print $+unset_test
0:variable defined only in scope
>0
>local hide unset_test
>setme
>0
# Depends on zsh-5.0.9 typeset keyword
typeset -a array_test=(top level)
() {
local -Pa array_test=(in function)
() {
private array_test
typeset +m array_test
}
print $array_test
}
print $array_test
0:nested scope with different type, correctly restored
>local hide array_test
>in function
>top level
typeset -a array_test=(top level)
() {
private array_test
array_test=(in function)
}
1:type of private may not be changed by assignment
?(anon):2: array_test: attempt to assign array value to non-array
typeset -A hash_test=(top level)
() {
setopt localoptions noglob
private hash_test[top]
}
1:associative array fields may not be private
?(anon):private:2: hash_test[top]: can't create local array elements
() {
private path
}
1:tied params may not be private, part 1
?(anon):private:1: can't change scope of existing param: path
() {
private PATH
}
1:tied params may not be private, part 2
?(anon):private:1: can't change scope of existing param: PATH
() {
private -h path
print X$path
}
0:privates may hide tied parameters
>X
# Deliberate type mismatch here
typeset -a hash_test=(top level)
typeset -p hash_test
inner () {
typeset -p hash_test
print ${(t)hash_test} ${(kv)hash_test}
}
outer () {
local -PA hash_test=(in function)
private + hash_test
inner
}
outer
print ${(kv)hash_test}
0:private hides value from surrounding scope in nested scope
>typeset -a hash_test=( top level )
>hash_test=( [in]=function )
>typeset -g -a hash_test=( top level )
>array-local top level
>top level
F:note "typeset" rather than "private" in output from outer
() {
private -a array_test
local array_test=scalar
}
1:private cannot be re-declared as local
?(anon):local:2: array_test: inconsistent type for assignment
() {
local hash_test=scalar
private -A hash_test
}
1:local cannot be re-declared as private
?(anon):private:2: can't change scope of existing param: hash_test
inner () {
print $+scalar_test
$ZTST_testdir/../Src/zsh -fc 'print X $scalar_test'
}
() {
private -x scalar_test=whaat
$ZTST_testdir/../Src/zsh -fc 'print X $scalar_test'
inner
print Y $scalar_test
}
0:exported private behaves like a local, part 1
>X whaat
>0
>X whaat
>Y whaat
inner () {
typeset -p array_test
$ZTST_testdir/../Src/zsh -fc 'print X $array_test'
}
() {
local -Pax array_test=(whaat)
print Y $array_test
$ZTST_testdir/../Src/zsh -fc 'print X $array_test'
inner
}
0:exported private behaves like a local, part 2 (arrays do not export)
?inner:typeset:1: no such variable: array_test
>Y whaat
>X
>X
inner () {
print $+scalar_test
$ZTST_testdir/../Src/zsh -fc 'print X $scalar_test'
}
() {
private scalar_test=whaat
export scalar_test
$ZTST_testdir/../Src/zsh -fc 'print X $scalar_test'
inner
() {
print $+scalar_test
$ZTST_testdir/../Src/zsh -fc 'print X $scalar_test'
}
print Y $scalar_test
}
0:exported private behaves like a local, part 3 (export does not change scope)
>X whaat
>0
>X whaat
>0
>X whaat
>Y whaat
typeset -A hash_test=(top level)
() {
local -PA hash_test=(in function)
() {
print X ${(kv)hash_test}
}
print Y ${(kv)hash_test}
}
print ${(kv)hash_test}
0:privates are not visible in anonymous functions, part 1
>X top level
>Y in function
>top level
typeset -A hash_test=(top level)
() {
local -PA hash_test=(in function)
() {
print X ${(kv)hash_test}
hash_test[in]=deeper
}
print Y ${(kv)hash_test}
}
print ${(okv)hash_test}
0:privates are not visible in anonymous functions, part 2
>X top level
>Y in function
>deeper in level top
typeset -A hash_test=(top level)
() {
local -Pa array_test=(in function)
local -PA hash_test=($array_test)
() {
print X ${(kv)hash_test}
hash_test=(even deeper)
{
array_test+=(${(kv)hash_test})
} always {
print ${array_test-array_test not set} ${(t)array_test}
}
}
print Y ${(kv)hash_test} Z $array_test
}
print ${(kv)hash_test} ${(t)array_test}
1:privates are not visible in anonymous functions, part 3
>X top level
>array_test not set
?(anon):4: array_test: can't modify read-only parameter
F:future revision will create a global with this assignment
typeset -a array_test
typeset -A hash_test=(top level)
() {
local -Pa array_test=(in function)
local -PA hash_test=($array_test)
() {
print X ${(kv)hash_test}
hash_test=(even deeper)
array_test+=(${(kv)hash_test})
}
print Y ${(kv)hash_test} Z $array_test
}
print ${(kv)hash_test} $array_test
0:privates are not visible in anonymous functions, part 4
>X top level
>Y in function Z in function
>even deeper even deeper
typeset -A hash_test=(top level)
() {
local -PA hash_test=(in function)
() {
print X ${(kv)hash_test}
unset hash_test
}
print Y ${(kv)hash_test}
}
print ${(t)hash_test} ${(kv)hash_test}
0:privates are not visible in anonymous functions, part 5
>X top level
>Y in function
>
# Subshell because otherwise this silently dumps core when broken
( () { private SECONDS } )
1:special parameters cannot be made private
?(anon):private: can't change scope of existing param: SECONDS
() { private -h SECONDS }
0:private parameter may hide a special parameter
if (( UID )); then
ZTST_verbose=0 $ZTST_exe +Z -f $ZTST_srcdir/ztst.zsh private.TMP/B02
else
ZTST_skip="cannot re-run typeset tests when tests run as superuser"
fi
0:typeset still works with zsh/param/private module loaded
*>*
*>*
typeset top=TOP
() {
local -P -n test=top
print $top
() { print UP: $test }
}
0:nameref can be declared private
>TOP
>UP:
() {
typeset -a ary
local -P -n ref=ary
{
(){
ref=XX # Should be an error
typeset -p ary ref
}
} always {
TRY_BLOCK_ERROR=0
typeset -p ary ref
}
}
typeset -p ary
1:assignment to private nameref in wrong scope, part 1
>typeset -a ary
>typeset -hn ref=ary
*?*ref: can't modify read-only parameter
*?*no such variable: ary
() {
typeset -a ary
local -P -n ref=ary
{
(){
typeset ref=XX # Should create a local
typeset -p ary ref
}
} always {
TRY_BLOCK_ERROR=0
typeset -p ary ref
}
}
typeset -p ary
1:assignment to private nameref in wrong scope, part 2
>typeset -g -a ary
>typeset ref=XX
>typeset -a ary
>typeset -hn ref=ary
*?*no such variable: ary
() {
typeset -n ptr1=ptr2
private -n ptr2 # TYPESET_TO_UNSET makes this not a "placeholder"
typeset -p ptr1 ptr2
typeset val=LOCAL
() {
ptr1=val # Test dies here as ptr2 is private and unset
typeset -n
printf "%s=%s\n" ptr1 "$ptr1" ptr2 "$ptr2"
}
typeset -p ptr1 ptr2
}
typeset -p ptr2
1:up-reference for private namerefs, end unset and not in scope
F:See K01nameref.ztst up-reference part 5
F:Here ptr1 finds private ptr2 by scope mismatch
>typeset -n ptr1=ptr2
>typeset -hn ptr2
*?*read-only variable: ptr2
() {
typeset -n ptr1=ptr2
private -n ptr2= # Assignment makes this a placeholder, not unset
typeset -p ptr1 ptr2
typeset val=LOCAL
() {
ptr1=val || print -u2 ptr1: assignment failed
typeset -n
printf "%s=%s\n" ptr1 "$ptr1" ptr2 "$ptr2"
}
typeset -p ptr1 ptr2
}
typeset -p ptr2
1:up-reference for private namerefs, end not in scope
F:See K01nameref.ztst up-reference part 5
F:Here ptr1 finds private ptr2 by scope mismatch
>typeset -n ptr1=ptr2
>typeset -hn ptr2=''
>ptr1=ptr2
>ptr1=
>ptr2=
>typeset -n ptr1=ptr2
>typeset -hn ptr2=''
*?*ptr1: assignment failed
*?*no such variable: ptr2
typeset ptr2
() {
typeset -n ptr1=ptr2
private -n ptr2 # Set/unset is irrelevant, not referenced
typeset -p ptr1 ptr2
typeset val=LOCAL
() {
ptr1=val
typeset -n
printf "%s=%s\n" ptr1 "$ptr1" ptr2 "$ptr2"
}
typeset -p ptr1 ptr2
}
typeset -p ptr2
0:up-reference for private namerefs, end is in scope
F:See K01typeset.ztst up-reference part 5
F:Here ptr1 points to global ptr2 so assignment succeeds
>typeset -n ptr1=ptr2
>typeset -hn ptr2
>ptr1=ptr2
>ptr2=val
>ptr1=val
>ptr2=val
>typeset -n ptr1=ptr2
>typeset -hn ptr2
>typeset ptr2=val
() {
setopt localoptions errreturn
private -n ptr2
typeset -n ptr1=ptr2
typeset -p ptr1 ptr2
typeset val=LOCAL
() {
ptr1=val
typeset -n
printf "v %s=%s\n" ptr1 "$ptr1" ptr2 "$ptr2"
}
typeset -p ptr1 ptr2
}
typeset -p ptr1 ptr2
1:up-reference for private namerefs, end is in scope but private
F:Should we allow "public" namerefs to private parameters?
*?*ptr2: invalid reference
*?*no such variable: ptr1
*?*no such variable: ptr2
() {
private x=1
unset x
x=2
}
0:regression test for unset private
() {
private x=1
unset x
private x=2
print $x
}
0:private may be called twice
>2
() {
private x=1
private -a x
print $x
}
1:private may not change parameter type
?(anon):private:2: can't change type of private param: x
() {
private fd1 fd2
exec {fd1}>&1
print OK
() { exec {fd2}>&2 }
print BAD $fd2
}
1:redirection cannot assign private in wrong scope
F:Better if caught in checkclobberparam() but exec.c doesn't know scope
>OK
?(anon): fd2: can't modify read-only parameter
() {
private z=outer
print ${(t)z} $z
print ${|
print ${(t)z} $z
REPLY=$z
}
}
0:nofork may read private in calling function
>scalar-local-hide-special outer
>scalar-local-hide-special outer
>outer
() {
private z=outer
print ${(t)z} $z
print ${| REPLY=${{z} z=nofork} }
print ${(t)z} $z
}
0:nofork may write to private in calling function
>scalar-local-hide-special outer
>nofork
>scalar-local-hide-special nofork
() {
local q=outer
print ${|
private q=nofork
REPLY=${| REPLY=$q}
}
}
0:nofork cannot see private in surrounding nofork
>outer
() {
private z=outer
print ${(t)z} $z
print ${{z}
private q
z=${{q} q=nofork}
}
print ${(t)z} $z
}
1:nofork may not change private in surrounding nofork
>scalar-local-hide-special outer
*?*: q: can't modify read-only parameter
() {
private q=outer
print ${|
() { REPLY="{$q}" }
}
print ${{q}
() { q=nofork }
}
}
1:function may not access private from inside nofork
>{}
*?*: q: can't modify read-only parameter
() {
print ${|
private q
() { q=nofork }
}
}
1:function may not access private declared in nofork
*?*: q: can't modify read-only parameter
%clean
unsetopt TYPESET_TO_UNSET
rm -r private.TMP