`f:{unshift,push}-args' added

master
Mike Gerwitz 2014-12-01 00:34:52 -05:00
parent 18c1614777
commit c526fa2925
2 changed files with 183 additions and 0 deletions

View File

@ -174,6 +174,10 @@
increasing the argument count of @var{fnref} will @emph{decrease}
the arity of the resulting reference and vice versa.
@emph{No validations are performed on arity}—if there exist more
arguments than the number of target function parameters, no error
will be raised.
@var{fnref} must be a valid dynamic function reference.
-->
<function name="f:set-args" as="item()+">
@ -202,4 +206,32 @@
<sequence select="$args" />
</function>
<!--
Pushes @var{args} onto the argument list of @var{fnref}
This operates just as @code{f:set-args}, but retains existing arguments.
-->
<function name="f:push-args" as="item()+">
<param name="fnref" as="item()+" />
<param name="args" as="item()*" />
<sequence select="f:set-args($fnref,
(f:args( $fnref ), $args) )" />
</function>
<!--
Unshifts @var{args} onto the argument list of @var{fnref}
This operates just as @code{f:set-args}, but retains existing arguments.
-->
<function name="f:unshift-args" as="item()+">
<param name="fnref" as="item()+" />
<param name="args" as="item()*" />
<sequence select="f:set-args($fnref,
($args, f:args( $fnref )) )" />
</function>
</stylesheet>

View File

@ -43,6 +43,7 @@
<foo:a />
<foo:b />
<foo:c />
<foo:d />
</foo:args>
</variable>
@ -396,4 +397,154 @@
test="count( $x:result ) = 2" />
</scenario>
</scenario>
<scenario label="f:push-args mutator">
<scenario label="pushing arguments onto empty reference list">
<call function="f:push-args">
<param name="fnref"
select="$test-fn" />
<param name="args"
select="$args/foo:a,
$args/foo:b" />
</call>
<expect label="retains target QName"
test="f:QName( $x:result ) = f:QName( $test-fn )" />
<expect label="reduces arity by number of arguments, relative to
target function"
test="f:arity( $x:result ) = f:arity( $test-fn ) - 2" />
<expect label="sets arguments by reference"
test="f:args( $x:result )[ 1 ] is $args/foo:a
and f:args( $x:result )[ 2 ] is $args/foo:b" />
</scenario>
<scenario label="pushing arguments onto populated reference
list">
<call function="f:push-args">
<param name="fnref"
select="f:set-args( $test-fn,
($args/foo:a,
$args/foo:b) )" />
<param name="args"
select="$args/foo:c,
$args/foo:d" />
</call>
<expect label="retains target QName"
test="f:QName( $x:result ) = f:QName( $test-fn )" />
<expect label="reduces arity by number of arguments, relative to
previous arity"
test="f:arity( $x:result ) = f:arity( $test-fn ) - 4" />
<expect label="retains previous arguments by reference"
test="f:args( $x:result )[ 1 ] is $args/foo:a
and f:args( $x:result )[ 2 ] is $args/foo:b" />
<expect label="pushes new arguments by reference"
test="f:args( $x:result )[ 3 ] is $args/foo:c
and f:args( $x:result )[ 4 ] is $args/foo:d" />
</scenario>
<scenario label="pushing empty argument list onto populated
reference list">
<call function="f:push-args">
<param name="fnref"
select="f:set-args( $test-fn,
($args/foo:a,
$args/foo:b) )" />
<param name="args" select="()" />
</call>
<expect label="retains target QName"
test="f:QName( $x:result ) = f:QName( $test-fn )" />
<expect label="retains previous reference arity"
test="f:arity( $x:result ) = f:arity( $test-fn ) - 2" />
<expect label="retains previous arguments by reference"
test="f:args( $x:result )[ 1 ] is $args/foo:a
and f:args( $x:result )[ 2 ] is $args/foo:b" />
</scenario>
</scenario>
<scenario label="f:unshift-args mutator">
<scenario label="unshifting arguments onto empty reference list">
<call function="f:unshift-args">
<param name="fnref"
select="$test-fn" />
<param name="args"
select="$args/foo:a,
$args/foo:b" />
</call>
<expect label="retains target QName"
test="f:QName( $x:result ) = f:QName( $test-fn )" />
<expect label="reduces arity by number of arguments, relative to
target function"
test="f:arity( $x:result ) = f:arity( $test-fn ) - 2" />
<expect label="sets arguments by reference"
test="f:args( $x:result )[ 1 ] is $args/foo:a
and f:args( $x:result )[ 2 ] is $args/foo:b" />
</scenario>
<scenario label="unshifting arguments onto populated reference
list">
<call function="f:unshift-args">
<param name="fnref"
select="f:set-args( $test-fn,
($args/foo:a,
$args/foo:b) )" />
<param name="args"
select="$args/foo:c,
$args/foo:d" />
</call>
<expect label="retains target QName"
test="f:QName( $x:result ) = f:QName( $test-fn )" />
<expect label="reduces arity by number of arguments, relative to
previous arity"
test="f:arity( $x:result ) = f:arity( $test-fn ) - 4" />
<expect label="retains previous arguments by reference"
test="f:args( $x:result )[ 3 ] is $args/foo:a
and f:args( $x:result )[ 4 ] is $args/foo:b" />
<expect label="unshifts new arguments by reference"
test="f:args( $x:result )[ 1 ] is $args/foo:c
and f:args( $x:result )[ 2 ] is $args/foo:d" />
</scenario>
<scenario label="unshifting empty argument list onto populated
reference list">
<call function="f:unshift-args">
<param name="fnref"
select="f:set-args( $test-fn,
($args/foo:a,
$args/foo:b) )" />
<param name="args" select="()" />
</call>
<expect label="retains target QName"
test="f:QName( $x:result ) = f:QName( $test-fn )" />
<expect label="retains previous reference arity"
test="f:arity( $x:result ) = f:arity( $test-fn ) - 2" />
<expect label="retains previous arguments by reference"
test="f:args( $x:result )[ 1 ] is $args/foo:a
and f:args( $x:result )[ 2 ] is $args/foo:b" />
</scenario>
</scenario>
</description>