zsh-workers
 help / color / mirror / code / Atom feed
From: Bart Schaefer <schaefer@brasslantern.com>
To: Zsh hackers list <zsh-workers@zsh.org>
Subject: [PATCH 2/3] Tests for named references
Date: Sun, 5 Feb 2023 18:24:58 -0800	[thread overview]
Message-ID: <CAH+w=7aMXx7dewojkF+9nqwi1QdgHdBn0g1vMcgYqGc1mY7Gow@mail.gmail.com> (raw)

[-- Attachment #1: Type: text/plain, Size: 201 bytes --]

Forgot to mention in patch #1 email that I decided not to create a
"nameref" built-in yet.

Here are the test cases, I covered everything I could think of.  If
you see something I missed, let me know.

[-- Attachment #2: nameref-2-tests.txt --]
[-- Type: text/plain, Size: 11520 bytes --]

diff --git a/Test/K01nameref.ztst b/Test/K01nameref.ztst
new file mode 100644
index 000000000..b38831100
--- /dev/null
+++ b/Test/K01nameref.ztst
@@ -0,0 +1,439 @@
+# Tests for the zsh/param/private module
+
+%prep
+
+ # Required in order to declare an unset hash for substitution test
+ setopt TYPESET_TO_UNSET
+
+ : ${ZTST_continue:=1}
+
+%test
+
+ typeset -n ptr
+ typeset -n
+0:minimal declaration
+>ptr
+
+ typeset -n ptr=
+ typeset -n
+0:nameref placeholder
+>ptr=''
+
+ typeset -n ptr
+ ptr=var
+ typeset -n
+0:assign nameref placeholder
+>ptr=var
+
+ typeset -n ptr=var
+ typeset +n ptr
+ typeset -p ptr
+0:remove nameref attribute
+>typeset ptr=var
+
+  typeset -n ptr
+  typeset -t ptr
+  typeset -p ptr
+0:change type of a placeholder
+F:Other type changes are fatal errors, should this also be?
+>typeset -n ptr=''
+*?*ptr: can't change type of a named reference
+
+ typeset -n ptr=var
+ typeset -t ptr
+ typeset -p ptr var
+0:change type of referenced var
+>typeset -n ptr=var
+>typeset -t var
+
+ typeset -n ptr[1]=var
+1:illegal nameref name
+*?*reference variable cannot be an array
+
+ typeset var=value
+ typeset -n ptr=var
+ print $ptr
+0:basic nameref expansion
+>value
+
+ typeset var=(val1 val2)
+ typeset -n ptr=var
+ print $ptr
+0:nameref array expansion
+>val1 val2
+
+ typeset -A var=(val1 val2)
+ typeset -n ptr=var
+ print ${(kv)ptr}
+0:nameref hash expansion
+>val1 val2
+
+ typeset -n ptr=var
+ typeset var=value
+ typeset -p ptr var
+ ptr=newvalue
+ typeset -p ptr var
+0:assign existing scalar via nameref
+>typeset -n ptr=var
+>typeset var=value
+>typeset -n ptr=var
+>typeset var=newvalue
+
+ typeset -n ptr=var
+ typeset var=value
+ unset ptr
+ typeset -p var
+0:unset via nameref
+
+ typeset -n ptr=var
+ typeset var=value
+ typeset -p ptr var
+ typeset ptr=newvalue
+ typeset -p ptr var
+0:typeset existing scalar via nameref
+>typeset -n ptr=var
+>typeset var=value
+>typeset -n ptr=var
+>typeset var=newvalue
+
+ typeset -n ptr=var
+ ptr=value
+ typeset -p var ptr
+ unset var	# for next test
+0:assign new scalar via nameref
+>typeset -g var=value
+>typeset -n ptr=var
+
+ typeset -n ptr=var
+ typeset var=(val1 val2)
+ typeset -p ptr var
+ ptr=(new1 new2)
+ typeset -p ptr var
+0:assign existing array via nameref
+>typeset -n ptr=var
+>typeset -a var=( val1 val2 )
+>typeset -n ptr=var
+>typeset -a var=( new1 new2 )
+
+ typeset -p ptr1 ptr2 var
+1:check state of paramtab ONE
+F:unexpected side-effects of previous tests
+*?*no such variable: ptr1
+*?*no such variable: ptr2
+*?*no such variable: var
+
+ typeset -n ptr=var
+ ptr=(val1 val2)
+ typeset -p var ptr
+ unset var	# for next test
+0:assign new array via nameref
+>typeset -g -a var=( val1 val2 )
+>typeset -n ptr=var
+
+ typeset -n ptr2=var
+ typeset -n ptr1=ptr2
+ typeset var=value
+ typeset -p ptr1 ptr2 var
+ print $ptr1
+0:indirect nameref expansion
+>typeset -n ptr1=ptr2
+>typeset -n ptr2=var
+>typeset var=value
+>value
+
+ typeset -p ptr1 ptr2 var
+1:check state of paramtab TWO
+F:unexpected side-effects of previous tests
+*?*no such variable: ptr1
+*?*no such variable: ptr2
+*?*no such variable: var
+
+ typeset var
+ typeset -n ptr2=var
+ typeset -n ptr1=ptr2
+ typeset ptr1=newvalue
+ typeset -p ptr1 ptr2 var
+0:typeset existing parameter indirectly
+>typeset -n ptr1=ptr2
+>typeset -n ptr2=var
+>typeset var=newvalue
+
+ typeset var=value
+ typeset -n ptr2=var
+ typeset -n ptr1=ptr2
+ unset ptr1
+ typeset -p ptr1 ptr2 var
+0:unset parameter indirectly
+>typeset -n ptr1=ptr2
+>typeset -n ptr2=var
+
+ typeset -n ptr2=var
+ typeset -n ptr1=ptr2
+ typeset ptr1=newvalue
+ typeset -p ptr1 ptr2 var
+ unset var	# for next test
+0:typeset new parameter indirectly
+>typeset -n ptr1=ptr2
+>typeset -n ptr2=var
+>typeset var=newvalue
+
+ typeset -n ptr2=var
+ typeset -n ptr1=ptr2
+ typeset var=value
+ typeset -p ptr1 ptr2 var
+ ptr1=newvalue
+ typeset -p ptr1 ptr2 var
+0:assign new parameter indirectly
+>typeset -n ptr1=ptr2
+>typeset -n ptr2=var
+>typeset var=value
+>typeset -n ptr1=ptr2
+>typeset -n ptr2=var
+>typeset var=newvalue
+
+ typeset -p ptr1 ptr2 var
+1:check state of paramtab THREE
+F:unexpected side-effects of previous tests
+*?*no such variable: ptr1
+*?*no such variable: ptr2
+*?*no such variable: var
+
+ typeset -a var
+ typeset -n ptr2=var
+ typeset -n ptr1=ptr2
+ typeset ptr1=(val1 val2)
+ typeset -p ptr1 ptr2 var
+0:typeset existing array indirectly
+>typeset -n ptr1=ptr2
+>typeset -n ptr2=var
+>typeset -a var=( val1 val2 )
+
+ typeset -n ptr2=var
+ typeset -n ptr1=ptr2
+ typeset ptr1=(val1 val2)
+ typeset -p ptr1 ptr2 var
+ unset var	# for next test
+0:typeset new array indirectly
+>typeset -n ptr1=ptr2
+>typeset -n ptr2=var
+>typeset -a var=( val1 val2 )
+
+ typeset -p ptr1 ptr2 var
+1:check state of paramtab FOUR
+F:unexpected side-effects of previous tests
+*?*no such variable: ptr1
+*?*no such variable: ptr2
+*?*no such variable: var
+
+ typeset -n ptr2=var
+ typeset -n ptr1=ptr2
+ ptr1=(val1 val2)
+ typeset -p ptr1 ptr2 var
+0:assign new array indirectly
+>typeset -n ptr1=ptr2
+>typeset -n ptr2=var
+>typeset -g -a var=( val1 val2 )
+
+ typeset -n ptr1=ptr2
+ typeset -n ptr2=ptr1
+1:direct nameref loop not allowed
+*?*invalid self reference
+
+ typeset -n ptr1=ptr2
+ typeset -n ptr2=ptr3
+ typeset -n ptr3=ptr1
+1:indirect nameref loop not allowed
+*?*invalid self reference
+
+ typeset -n ptr2='path[2]'
+ print -r -- $ptr2
+0d:nameref to array element
+>${path[2]}
+
+ typeset -A hash=(x MISS y HIT)
+ typeset -n ptr1='hash[y]'
+ print -r -- $ptr1
+0:nameref to hash element
+>HIT
+
+ typeset -a ary=(1 2)
+ typeset -n ptr2='ary[2]'
+ ptr2=TWO
+ typeset -p ary
+0:assign array element by nameref
+>typeset -a ary=( 1 TWO )
+
+ typeset -n ptr2='ary[2]'
+ ptr2=TWO
+ typeset -p ary
+0f:create array element by nameref
+F:ksh93 does not implement this either
+>typeset -a ary=( '' TWO )
+
+ typeset -A hash=(x MISS y MISS)
+ typeset -n ptr1='hash[y]'
+ ptr1=HIT
+ typeset -p hash
+0:assign to hash element by nameref
+>typeset -A hash=( [x]=MISS [y]=HIT )
+
+ typeset -A hash
+ typeset -n ptr1='hash[y]'
+ ptr1=HIT
+ typeset -p hash
+0f:create hash by element nameref
+F:ksh93 does not implement this either
+>typeset -A hash=( [y]=HIT )
+
+ typeset -n ptr1='not good'
+1:invalid nameref
+*?*invalid variable name: not good
+
+ typeset -A hash
+ typeset -n ptr1='hash[y]'
+ print ${ptr1::=HIT}
+ typeset -p ptr1 hash
+0f:create hash by element substitution
+>HIT
+>typeset -n ptr1='hash[y]'
+>typeset -A hash=( [y]=HIT )
+
+ typeset -n ptr=gval
+ gval=global
+ () { local gval=local; print $ptr; typeset -p ptr gval }
+ unset gval	# for next test
+0:up-reference part 1
+>global
+>typeset -g -n ptr=gval
+>typeset gval=local
+
+ typeset -p ptr ptr1 ptr2 val gval
+1:check state of paramtab FIVE
+F:unexpected side-effects of previous tests
+*?*no such variable: ptr
+*?*no such variable: ptr1
+*?*no such variable: ptr2
+*?*no such variable: val
+*?*no such variable: gval
+
+ typeset -n ptr1=gval
+ typeset gval
+ () { typeset gval=local; ptr1=global }
+ typeset -p ptr1 gval
+0:up-reference assignment part 1
+F:All tests run inside a function, so "typeset gval" creates a local;
+F:if that were omitted, ptr1= assignment would create a true global
+F:and the output below would change to "typeset -g gval=global"
+>typeset -n ptr1=gval
+>typeset gval=global
+
+ typeset -p ptr ptr1 ptr2 val gval
+1:check state of paramtab SIX
+F:unexpected side-effects of previous tests
+*?*no such variable: ptr
+*?*no such variable: ptr1
+*?*no such variable: ptr2
+*?*no such variable: val
+*?*no such variable: gval
+
+ typeset gval=global
+ () {
+   typeset -n ptr=gval
+   local gval=local
+   print $ptr
+ }
+ typeset -p ptr gval
+1:up-reference part 2
+>global
+*?*no such variable: ptr
+>typeset gval=global
+
+ typeset -n ptr=gval
+ () {
+    local lval=local
+    typeset -n ptr=lval
+    ptr=LOCAL
+    typeset -p lval gval ptr
+  }
+ typeset -p ptr
+0:localized namerefs hide global namerefs
+*?*no such variable: gval
+>typeset lval=LOCAL
+>typeset -n ptr=lval
+>typeset -n ptr=gval
+
+ () {
+   zmodload -u zsh/parameter
+   typeset -n myself=parameters[myself]
+   local -h parameters
+   print -r -- $myself
+   typeset -p parameters
+ }
+0:up-reference part 3, autoloading with hidden special
+>nameref-local
+>typeset parameters
+
+ () {
+   typeset notdef
+   unset notdef
+   () {
+     typeset -n ptr=notdef
+     ptr=(DEFINED)
+   }
+   typeset -p notdef
+ }
+0:up-reference part 4, unset local and type change
+>typeset -a notdef=( DEFINED )
+
+ () {
+   typeset -n ptr1=ptr2
+   typeset -n ptr2
+   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
+1:up-reference part 5, stacked namerefs, end not in scope
+F:What is the correct behavior for the scope of ptr1?
+>typeset -n ptr1=ptr2
+>typeset -n ptr2=''
+>ptr1=ptr2
+>ptr2=val
+>ptr1=LOCAL
+>ptr2=LOCAL
+>typeset -n ptr1=ptr2
+>typeset -n ptr2=val
+*?*no such variable: ptr2
+
+ typeset ptr2
+ () {
+   typeset -n ptr1=ptr2
+   typeset -n ptr2
+   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 part 6, stacked namerefs, end is in scope
+F:Same test, should part 5 output look like this?
+>typeset -n ptr1=ptr2
+>typeset -n ptr2=''
+>ptr1=ptr2
+>ptr2=''
+>ptr1=val
+>ptr2=
+>typeset -n ptr1=ptr2
+>typeset -n ptr2=''
+>typeset ptr2=val
+
+%clean
diff --git a/Test/V10private.ztst b/Test/V10private.ztst
index 56ffbc5b4..b191afcb7 100644
--- a/Test/V10private.ztst
+++ b/Test/V10private.ztst
@@ -299,6 +299,84 @@ F:future revision will create a global with this assignment
 *>*
 *>*
 
+ typeset top=TOP
+ () {
+  local -P -n test=top
+  print $top
+  () { print UP: $test }
+ }
+0:nameref can be declared private
+>TOP
+>UP:
+
+ () {
+   typeset -n ptr1=ptr2
+   private -n ptr2
+   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
+1:up-reference for private namerefs, end not in scope
+F:See K01typeset.ztst up-reference part 5
+F:Here ptr1 finds private ptr2 by scope mismatch, assignment silently fails
+>typeset -n ptr1=ptr2
+>ptr1=ptr2
+>ptr1=
+>ptr2=
+>typeset -n ptr1=ptr2
+*?*no such variable: ptr2
+
+ typeset ptr2
+ () {
+   typeset -n ptr1=ptr2
+   private -n ptr2
+   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
+>ptr1=ptr2
+>ptr2=val
+>ptr1=val
+>ptr2=val
+>typeset -n ptr1=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
+
 %clean
 
   rm -r private.TMP

             reply	other threads:[~2023-02-06  2:25 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-02-06  2:24 Bart Schaefer [this message]
2023-02-07  0:33 ` Daniel Shahaf
2023-02-07  3:24   ` Bart Schaefer
2023-02-07  9:28     ` Daniel Shahaf

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to='CAH+w=7aMXx7dewojkF+9nqwi1QdgHdBn0g1vMcgYqGc1mY7Gow@mail.gmail.com' \
    --to=schaefer@brasslantern.com \
    --cc=zsh-workers@zsh.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this public inbox

	https://git.vuxu.org/mirror/zsh/

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).