New HOF test case for function closures
authorMichael Kay <mike@saxonica.com>
Fri, 04 Dec 2015 15:34:18 +0000
changeset 1191 635ce4a4a0f0
parent 1190 f78f6fbd9d31
child 1192 bee08af8dd04
New HOF test case for function closures
tests/expr/higher-order-functions/_higher-order-functions-test-set.xml
tests/expr/higher-order-functions/higher-order-functions-072.xsl
--- a/tests/expr/higher-order-functions/_higher-order-functions-test-set.xml	Fri Dec 04 09:51:17 2015 +0000
+++ b/tests/expr/higher-order-functions/_higher-order-functions-test-set.xml	Fri Dec 04 15:34:18 2015 +0000
@@ -920,7 +920,7 @@
    
    <test-case name="higher-order-functions-071">
       <description>
-         Inline function with closure referencing XSLT template parameters
+         Inline function with closure referencing XSLT template parameters (Saxon bug 2523)
       </description>
       <created by="Michael Kay" on="2015-12-04"/>
       <test>
@@ -930,6 +930,19 @@
          <assert>/out = '{"a":44,"b":46,"c":48,"d":50,"e":52,"f":54}'</assert>
       </result>
    </test-case>
+   
+   <test-case name="higher-order-functions-072">
+      <description>
+         Return a function with a closure referencing XSLT template parameters; nested inline functions (Saxon bug 2527)
+      </description>
+      <created by="Michael Kay" on="2015-12-04"/>
+      <test>
+         <stylesheet file="higher-order-functions-072.xsl"/>
+      </test>
+      <result>
+         <assert>/out = '{"a":44,"b":46,"c":48,"d":50,"e":52,"f":54}'</assert>
+      </result>
+   </test-case>
 </test-set>
 
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/expr/higher-order-functions/higher-order-functions-072.xsl	Fri Dec 04 15:34:18 2015 +0000
@@ -0,0 +1,44 @@
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+  xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:map="http://www.w3.org/2005/xpath-functions/map"
+  version="3.0" exclude-result-prefixes="xs map">
+
+  <xsl:template name="make-map-processor" as="function(map(*)) as map(*)">
+    <xsl:param name="operator" as="xs:string"/>
+    <xsl:param name="operand" as="xs:anyAtomicType"/>
+    <xsl:sequence
+      select="
+          function($m as map(*)) as map(*) {
+            map:merge(
+                map:for-each($m, function($k, $v) {
+                  map { $k : if ($operator eq '+') then $v + $operand
+                             else if ($operator eq '-') then $v - $operand
+                             else if ($operator eq '*') then $v * $operand
+                             else if ($operator eq '/') then $v div $operand
+                             else $v }
+                  }))}"
+    />
+  </xsl:template>
+
+  <xsl:template name="xsl:initial-template">
+    <xsl:variable name="f" as="function(map(*)) as map(*)">
+      <xsl:call-template name="make-map-processor">
+        <xsl:with-param name="operator" select="'*'"/>
+        <xsl:with-param name="operand" select="2"/>
+      </xsl:call-template>
+    </xsl:variable>
+    <xsl:variable name="map" as="map(*)">
+        <xsl:map>
+          <xsl:map-entry key="'a'" select="22"/>
+          <xsl:map-entry key="'b'" select="23"/>
+          <xsl:map-entry key="'c'" select="24"/>
+          <xsl:map-entry key="'d'" select="25"/>
+          <xsl:map-entry key="'e'" select="26"/>
+          <xsl:map-entry key="'f'" select="27"/>
+        </xsl:map>
+    </xsl:variable>
+    <out><xsl:value-of select="serialize($f($map), map{'method':'json'})"/></out>
+  </xsl:template>
+
+
+
+</xsl:stylesheet>