########################################################################
# $Header: /var/local/cvsroot/4Suite/test/Xml/Xslt/Exslt/test_common.py,v 1.3 2005/02/23 19:21:35 mbrown Exp $
"""Tests for EXSLT Common"""

from Xml.Xslt import test_harness

import tempfile, os
from Ft.Lib import Uri

SRC1 = """<dummy/>"""

SRC2 = """\
<?xml version="1.0"?>
<foo>
  <a/>
  <b/>
  <c/>
</foo>"""

TESTS = []

# exsl:node-set()
def test_NodeSet(tester):
    sheet_1 = """<?xml version="1.0"?>
<xsl:stylesheet
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns:exsl="http://exslt.org/common"
  version="1.0"
>

  <xsl:output method="text"/>

  <xsl:template match="/">
    <xsl:variable name='spam'>
      <eggs/>
    </xsl:variable>
    <xsl:value-of select='count(exsl:node-set($spam)/*)'/>
    <xsl:text> </xsl:text>
    <xsl:value-of select='name(exsl:node-set($spam)/*)'/>
  </xsl:template>

</xsl:stylesheet>
"""

    expected_1 = '1 eggs'

    # 4XSLT used to die a horrible death when computing the union of
    # two node-sets that were created with exslt:node-set().
    sheet_2 = """\
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0"
xmlns:exsl="http://exslt.org/common"
exclude-result-prefixes="exsl">

  <xsl:output method="xml" indent="yes"/>

  <xsl:template match="/">

    <xsl:variable name="rtf1">
      <a/><b/><c/>
    </xsl:variable>

    <xsl:variable name="rtf2">
      <x/><y/><z/>
    </xsl:variable>

    <xsl:variable name="set1" select="$rtf1"/>
    <xsl:variable name="set2" select="$rtf2"/>

    <results>
      <xsl:variable name="rtf-union" select="exsl:node-set($rtf1)|exsl:node-set($rtf2)"/>
      <result info="$rtf1">
        <xsl:copy-of select="$rtf1"/>
      </result>
      <result info="$rtf2">
        <xsl:copy-of select="$rtf2"/>
      </result>
      <result info="$rtf-union">
        <xsl:for-each select="$rtf-union/*">
          <xsl:sort select="local-name()"/>
          <xsl:copy/>
        </xsl:for-each>
      </result>
    </results>

  </xsl:template>

</xsl:stylesheet>"""

    expected_2 = """<?xml version="1.0" encoding="UTF-8"?>
<results>
  <result info="$rtf1">
    <a/>
    <b/>
    <c/>
  </result>
  <result info="$rtf2">
    <x/>
    <y/>
    <z/>
  </result>
  <result info="$rtf-union">
    <a/>
    <b/>
    <c/>
    <x/>
    <y/>
    <z/>
  </result>
</results>"""

    sheet_3 = """\
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0"
xmlns:exsl="http://exslt.org/common"
exclude-result-prefixes="exsl">

  <xsl:output method="xml" indent="yes"/>

  <xsl:template match="/">

    <xsl:variable name="rtf1">
      <a/><b/><c/>
    </xsl:variable>

    <xsl:variable name="rtf2">
      <x/><y/><z/>
    </xsl:variable>

    <xsl:variable name="set1" select="exsl:node-set($rtf1)"/>
    <xsl:variable name="set2" select="exsl:node-set($rtf2)"/>

    <results>
      <xsl:variable name="set-union" select="$set1|$set2"/>
      <result info="$set1">
        <xsl:copy-of select="$set1"/>
      </result>
      <result info="$set2">
        <xsl:copy-of select="$set2"/>
      </result>
      <result info="$set-union">
        <xsl:for-each select="$set-union/*">
          <xsl:sort select="local-name()"/>
          <xsl:copy/>
        </xsl:for-each>
      </result>
    </results>

  </xsl:template>

</xsl:stylesheet>"""

    expected_3 = """<?xml version="1.0" encoding="UTF-8"?>
<results>
  <result info="$rtf1">
    <a/>
    <b/>
    <c/>
  </result>
  <result info="$rtf2">
    <x/>
    <y/>
    <z/>
  </result>
  <result info="$set-union">
    <a/>
    <b/>
    <c/>
    <x/>
    <y/>
    <z/>
  </result>
</results>"""

    sheet_4 = """\
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0"
xmlns:exsl="http://exslt.org/common"
exclude-result-prefixes="exsl">

  <xsl:output method="xml" indent="yes"/>

  <xsl:template match="/">

    <xsl:variable name="rtf2">
      <x/><y/><z/>
    </xsl:variable>

    <xsl:variable name="set1" select="/foo/*"/>
    <xsl:variable name="set2" select="exsl:node-set($rtf2)"/>

    <results>
      <xsl:variable name="set-union" select="$set1|$set2"/>
      <result info="$set1">
        <xsl:copy-of select="$set1"/>
      </result>
      <result info="$set2">
        <xsl:copy-of select="$set2"/>
      </result>
      <result info="$set-union">
        <xsl:for-each select="$set-union|$set-union/*">
          <xsl:sort select="local-name()"/>
          <xsl:copy/>
        </xsl:for-each>
      </result>
    </results>

  </xsl:template>

</xsl:stylesheet>"""

    expected_4 = expected_3

    sheet_5 = """\
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0"
xmlns:exsl="http://exslt.org/common"
exclude-result-prefixes="exsl">

  <xsl:output method="xml" indent="no"/>

  <xsl:template match="/">
    <xsl:variable name="set" select="exsl:node-set('foo')"/>
    <results>
      <!-- make sure it's not a root or element node with a text node child -->
      <result>
        <xsl:copy-of select="$set/node()"/>
      </result>
      <result nodes="count($set)">
        <xsl:copy-of select="$set"/>
      </result>
    </results>
  </xsl:template>

</xsl:stylesheet>"""

    expected_5 = """<?xml version="1.0" encoding="UTF-8"?>
<results><result/><result nodes="1">foo</result></results>"""

    source = test_harness.FileInfo(string=SRC1)
    sheet = test_harness.FileInfo(string=sheet_1)
    test_harness.XsltTest(tester, source, [sheet], expected_1,
                          title='exsl:node-set()')

    source = test_harness.FileInfo(string=SRC1)
    sheet = test_harness.FileInfo(string=sheet_2)
    test_harness.XsltTest(tester, source, [sheet], expected_2,
                          title='exsl:node-set() union 1')

    source = test_harness.FileInfo(string=SRC1)
    sheet = test_harness.FileInfo(string=sheet_3)
    test_harness.XsltTest(tester, source, [sheet], expected_3,
                          title='exsl:node-set() union 2')

    source = test_harness.FileInfo(string=SRC2)
    sheet = test_harness.FileInfo(string=sheet_4)
    test_harness.XsltTest(tester, source, [sheet], expected_4,
                          title='exsl:node-set() union 3')

    source = test_harness.FileInfo(string=SRC2)
    sheet = test_harness.FileInfo(string=sheet_5)
    test_harness.XsltTest(tester, source, [sheet], expected_5,
                          title='exsl:node-set() on string arg')
    return
TESTS.append(test_NodeSet)


# exsl:object-type()
def test_ObjectType(tester):
    sheet_1 = """\
<?xml version="1.0"?>
<xsl:stylesheet
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns:exsl="http://exslt.org/common"
  version="1.0"
>

  <xsl:output method="text"/>

  <xsl:template match="/">
    <xsl:variable name='spam'>
      <eggs/>
    </xsl:variable>
    <xsl:value-of select='exsl:object-type($spam)'/>
    <xsl:text> </xsl:text>
    <xsl:value-of select='exsl:object-type(.)'/>
    <xsl:text> </xsl:text>
    <xsl:value-of select='exsl:object-type("1")'/>
    <xsl:text> </xsl:text>
    <xsl:value-of select='exsl:object-type(1)'/>
    <xsl:text> </xsl:text>
    <xsl:value-of select='exsl:object-type(1=1)'/>
  </xsl:template>

</xsl:stylesheet>
"""

    expected_1 = "RTF node-set string number boolean"

    source = test_harness.FileInfo(string=SRC1)
    sheet = test_harness.FileInfo(string=sheet_1)
    test_harness.XsltTest(tester, source, [sheet], expected_1,
                          title='exsl:object-type()')
    return
TESTS.append(test_ObjectType)


# <exsl:document>
def test_Document(tester):
    sty = """\
<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"
    xmlns:exsl="http://exslt.org/common"
    extension-element-prefixes="exsl">

<xsl:output method="xml" indent="yes" encoding="ISO-8859-1"/>
<xsl:param name="filebase"/>

<xsl:template match="/">
  <xsl:apply-templates select="test"/>
</xsl:template>

<xsl:template match="test">
  <testout>
    <xsl:apply-templates select="data"/>
  </testout>
</xsl:template>

<xsl:template match="data">
  <xsl:variable name="file" select="concat($filebase, ., '.xml')"/>
  <datafile>
    <xsl:text>Writing data file </xsl:text>
    <xsl:value-of select="."/>
  </datafile>
  <exsl:document href="{$file}" method="xml" indent="yes" encoding="ISO-8859-1">
        <datatree>
          <name><xsl:value-of select="."/></name>
          <what>test</what>
        </datatree>
  </exsl:document>
</xsl:template>

</xsl:stylesheet>"""

    src = """\
<?xml version="1.0" encoding="ISO-8859-1"?>

<test>
  <data>11</data>
  <data>12</data>
  <data>13</data>
  <data>14</data>
  <data>15</data>
</test>
"""

    expected = """<?xml version="1.0" encoding="ISO-8859-1"?>
<testout>
  <datafile>Writing data file 11</datafile>
  <datafile>Writing data file 12</datafile>
  <datafile>Writing data file 13</datafile>
  <datafile>Writing data file 14</datafile>
  <datafile>Writing data file 15</datafile>
</testout>"""

    file_expected = """<?xml version="1.0" encoding="ISO-8859-1"?>
<datatree>
  <name>%s</name>
  <what>test</what>
</datatree>"""

    tester.startGroup("exsl:document")

    fileName = tempfile.mktemp()
    fileUri = Uri.OsPathToUri(fileName)

    source = test_harness.FileInfo(string=src)
    sheet = test_harness.FileInfo(string=sty)
    test_harness.XsltTest(tester, source, [sheet], expected,
                          topLevelParams={'filebase' : fileUri},
                          title='<exsl:document>')

    tester.startTest("<exsl:document> results")
    for data in range(11, 16):
        file = '%s%d.xml' % (fileName, data)
        tester.compare(1, os.path.exists(file))
        fileData = open(file,'r').read()
        tester.compare(file_expected % data, fileData)
        if os.path.exists(file):
            os.unlink(file)
    tester.testDone()

    tester.groupDone()
    return
TESTS.append(test_Document)


def Test(tester):
    tester.startGroup('Common')
    for test in TESTS:
        test(tester)
    tester.groupDone()
    return
