Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Compiled test is invalid if select attribute of x:context/x:param uses syntax like map{'key': 'myvalue'} #538

Closed
galtm opened this issue Mar 5, 2019 · 2 comments · Fixed by #454
Assignees
Labels

Comments

@galtm
Copy link
Member

galtm commented Mar 5, 2019

If a scenario uses syntax like

    <x:context>
      <myelement/>
      <x:param name="myparam" select="map{'key': 'myvalue'}"/>
    </x:context>

then the compiled test is invalid. See sample code, below. The log includes these error messages:

run-xslt-test:
     [echo] Running XSLT Tests...
     [java] Syntax error at char 9 in {map{'key': 'myvalue'} in expression in x:param/@select on line 46 column 69 of map_param.xsl:
     [java]   XPST0003: Unexpected token ":" beyond end of expression
     [java] Syntax error at char 9 in {map{'key': 'myvalue'} in expression in x:param/@select on line 63 column 69 of map_param.xsl:
     [java]   XPST0003: Unexpected token ":" beyond end of expression
     [java] Errors were reported during stylesheet compilation

From a quick look, I think the bug may be related to the <xsl:template match="x:context | x:param" mode="x:report"> template in compiler/generate-xspec-tests.xsl. I suspect that the <xsl:template match="@select" mode="x:report"> template does not get reached for x:param inside x:context.

To reproduce problem:

XSpec code

<?xml version="1.0" encoding="UTF-8"?>
<x:description
  xmlns:x="http://www.jenitennison.com/xslt/xspec"
  xmlns:map="http://www.w3.org/2005/xpath-functions/map"
  xslt-version="3.0"
  stylesheet="map_param.xsl">

  <!-- Build failure if parameter passed to template rule uses map{'key': 'value'} syntax in @select -->

  <!-- The commented-out scenarios below are a problem. The uncommented scenarios
    represent a potential workaround followed by a similar usage that is not
    a problem. -->
  <!-- ======================================================================= -->

  <!-- The following scenarios have a build error in Oxygen, even if marked as pending.
  <x:scenario label="Testing a moded template with a map parameter" pending="error">
    <x:context mode="mymode">
      <myelement/>
      <x:param name="myparam" select="map{'key': 'myvalue'}"/>
    </x:context>
    <x:expect label="has a build error if map parameter uses map{} syntax">myvalue</x:expect>
  </x:scenario>

  <x:scenario label="Testing a template rule with a map parameter" pending="error">
    <x:context>
      <myelement/>
      <x:param name="myparam" select="map{'key': 'myvalue'}"/>
    </x:context>
    <x:expect label="has a build error if map parameter uses map{} syntax">myvalue</x:expect>
  </x:scenario>
  -->

  <x:scenario label="Testing a moded template with a map parameter">
    <x:context mode="mymode">
      <myelement/>
      <x:param name="myparam" select="map:merge((
        map:entry('key1','myvalue1'),
        map:entry('key2','myvalue2'),
        map:entry('key','myvalue')
        ))"/>
    </x:context>
    <x:expect label="succeeds if map parameter uses map:merge">myvalue</x:expect>
  </x:scenario>
  <x:scenario label="Testing a template rule with a map parameter">
    <x:context>
      <myelement/>
      <x:param name="myparam" select="map:merge((
        map:entry('key1','myvalue1'),
        map:entry('key2','myvalue2'),
        map:entry('key','myvalue')
        ))"/>
    </x:context>
    <x:expect label="succeeds if map parameter uses map:merge">myvalue</x:expect>
  </x:scenario>
  <x:scenario label="Testing a named template with a map parameter">
    <x:call template="mytemplate">
      <x:param name="myparam" select="map{'key': 'myvalue'}"/>
    </x:call>
    <x:expect label="succeeds">myvalue</x:expect>
  </x:scenario>

  <!-- In the XSLT file that results from compiling this XSpec file, the
    parameter of the named template appears as
    <x:param name="myparam" select="map{{'key': 'myvalue'}}"/>
    while the parameter of the moded template appears as
    <x:param name="myparam" select="map{'key': 'myvalue'}"/>
    without doubling the curly braces.
    -->
</x:description>

XSLT code

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns:xs="http://www.w3.org/2001/XMLSchema"
  xmlns:x="http://www.jenitennison.com/xslt/xspec"
  exclude-result-prefixes="xs"
  version="3.0">
  
  <xsl:template match="myelement" mode="mymode">
    <xsl:param name="myparam" as="map(*)"/>
    <!--<foo name="x" select="map{'a': 'b'}"/>-->
    <!-- If uncommented, the line above has a validation error (Saxon-PE 9.8.0.8). -->
    <xsl:value-of select="$myparam('key')"/>
  </xsl:template>

  <xsl:template match="myelement">
    <xsl:param name="myparam" as="map(*)"/>
    <xsl:value-of select="$myparam('key')"/>
  </xsl:template>

  <xsl:template name="mytemplate">
    <xsl:param name="myparam" as="map(*)"/>
    <xsl:value-of select="$myparam('key')"/>
  </xsl:template>

</xsl:stylesheet>
@AirQuick
Copy link
Member

AirQuick commented Mar 5, 2019

Thanks, @galtm
I added a slightly modified set of files (bff83d3) to #444. The problem was reproduced: Travis, AppVeyor
Then I removed the test files from #444 and added them to #454. The problem was not reproduced: Travis

So the bug was fixed in #454. I updated #454 to include #538 explicitly.

Compiled stylesheet before #454:

   <xsl:template name="x:d6e4">
      <xsl:message>Testing a moded template with a map parameter</xsl:message>
      <x:scenario>
         <x:label>Testing a moded template with a map parameter</x:label>
         <x:context mode="mymode">
            <x:param name="myparam" select="map{'key': 'myvalue'}"/>
            <myelement/>
         </x:context>

After #454:

   <xsl:template name="x:d6e3">
      <xsl:message>Testing a moded template with a map parameter</xsl:message>
      <x:scenario>
         <x:label>Testing a moded template with a map parameter</x:label>
         <x:context mode="mymode">
            <x:param>
               <xsl:attribute name="name">myparam</xsl:attribute>
               <xsl:attribute name="select">map{'key': 'myvalue'}</xsl:attribute>
            </x:param>
            <myelement/>
         </x:context>

<xsl:attribute name="select">map{'key': 'myvalue'}</xsl:attribute> is generated here.

@galtm
Copy link
Member Author

galtm commented Mar 5, 2019

Perfect. Glad to hear a fix is already on the way. Thanks, @AirQuick.

AirQuick added a commit that referenced this issue Apr 28, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
2 participants