Главная » XSLT » Встраивание тестовых данных в служебные таблицы стилей

0

Задача

Требуется включить в один пакет с таблицами стилей тестовые данные для них, чтобы в любой момент можно было прогнать тесты.

Решение

Предполагается, что следующая таблица будет использоваться как служеб­ная. Но ее можно протестировать автономно, указав в качестве тестовых входных данных ее саму:

<!– math.max.xslt –>

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"

xmlns:math="http://www.exslt.org/math" exclude-result-prefixes="math" xmlns:test="http://www.ora.com/XSLTCookbook/test" id="math:math.max">

<xsl:template name="math:max">

<xsl:param name="nodes" select="/.."/> <xsl:param name="max"/> <xsl:variable name="count" select="count($nodes)"/>

<xsl:variable name="aNode" select="$nodes[ceiling($count div 2)]"/> <xsl:choose>

<xsl:when test="not($count)">

<xsl:value-of select="number($max)"/> </xsl:when>

<xsl:when test="number($aNode) != number($aNode)"> <xsl:value-of select="number($aNode)"/> </xsl:when> <xsl:otherwise> <xsl:call-template name="math:max">

<xsl:with-param name="nodes" select="$nodes[not(. &lt; = number($aNode))]"/>

<xsl:with-param name="max"> <xsl:choose>

<xsl:when test="not($max) or $aNode > $max">

<xsl:value-of select="$aNode"/> </xsl:when> <xsl:otherwise>

<xsl:value-of select="$max"/> </xsl:otherwise> </xsl:choose>

</xsl:with-param> </xsl:call-template> </xsl:otherwise> </xsl:choose> </xsl:template>

<!— ТЕСТЫ: HE УДАЛЯТЬ! —>

<xsl:template match="/xsl:stylesheet[@id=’math:math.max’] |

xsl:include[@href=’math.

max.xslt’] " priority="-10 0 0">

<xsl:message>

ТЕСТИРУЕТСЯ math.max

</xsl:message>

<xsl:for-each select="document(”)/*/test:test"> <xsl:variable name="ans">

<xsl:call-template name="math:max">

<xsl:with-param name="nodes" select="test:data"/> </xsl:call-template> </xsl:variable> <xsl:if test="$ans != @ans"> <xsl:message>

ТЕСТ math:max <xsl:value-of select="@num"/> HE ПРОШЕЛ [<xsl:value-of select="$ans"/>] </xsl:message> </xsl:if> </xsl:for-each>

<!– Тест с Infinity –> <xsl:variable name="ans1">

<xsl:call-template name="math:max">

<xsl:with-param name="nodes" select="document(”)/*/ test:test[@num=1]/test:data"/>

<xsl:with-param name="max" select="1 div 0"/> </xsl:call-template> </xsl:variable>

<xsl:if test="$ans1 != Infinity"> <xsl:message>

ТЕСТ math:max с Infinity НЕ ПРОШЕЛ [<xsl:value-of select="$ans1"/>] </xsl:message> </xsl:if>

<!– Тест с -Infinity –> <xsl:variable name="ans2">

<xsl:call-template name="math:max">

<xsl:with-param name="nodes" select="document(”)/*/ test:test[@num=1]/test:data"/>

<xsl:with-param name="max" select="-1 div 0"/> </xsl:call-template> </xsl:variable>

<xsl:if test="$ans2 != document(”)/*/test:test[@num=1]/@ans"> <xsl:message>

ТЕСТ math:max с -Infinity HE ПРОШЕЛ [<xsl:value-of select="$ans2"/>] </xsl:message> </xsl:if>

</xsl:template>

<test:test num="1" ans="9" xmlns="http://www.ora.com/XSLTCookbook/test"> <data>9</data> <data>8</data> <data>7</data> <data>6</data> <data>5</data> <data>4</data> <data>3</data> <data>2</data> <data>1</data> </test:test>

<test:test num="2" ans="1" xmlns="http://www.ora.com/XSLTCookbook/test">

<data>1</data> </test:test>

<test:test num="3" ans="1" xmlns="http://www.ora.com/XSLTCookbook/test"> <data>-1</data> <data>1</data> </test:test>

<test:test num="4" ans="0" xmlns="http://www.ora.com/XSLTCookbook/test"> <data>0</data> <data>0</data> </test:test>

<test:test num="5" ans="NaN" xmlns="http://www.ora.com/XSLTCookbook/ test">

<data>foo</data> <data>1</data>

</test:test>

<test:test num="6" ans="NaN" xmlns="http://www.ora.com/XSLTCookbook/test"> <data>1</data> <data>foo</data> </test:test>

<test:test num="7" ans="NaN" xmlns="http://www.ora.com/XSLTCookbook/test"> </test:test>

</xsl:stylesheet>

Обсуждение

У элемента xsl:stylesheet есть необязательный атрибут id. Он иденти­фицирует таблицы стилей, внедренные в объемлющий документ. Однако этот ат­рибут можно использовать и для тестирования. Наша задача – упаковать код тес­тирования вместе с таблицей стилей, но так, чтобы он не мешал нормальному использованию этой таблицы. Для этого создаем шаблон, который сопоставляет­ся только тогда, когда таблица обрабатывает саму себя:

<xsl:template match="/xsl:stylesheet[@id=’math:math.max’] | xsl:include[@href=’math.max.xslt’]">

Это        объясняет,                    зачем                   нужна                    конструкция

/xsl:stylesheet[@id=’math:math.max’], но осталось непонятным, что де­лает часть xsl:include[@href=’math.max.xslt’]. Чтобы разобраться в этом, рассмотрим таблицу стилей, которая упаковывает все математические шаблоны в один файл, так его будет легче включать. Хотелось бы иметь простой способ и для тестирования всего пакета:

<!– math.xslt –>

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:math="http://exslt.org/math"

extension-element-prefixes="math" id="math:math">

<xsl:include href="math.abs.xslt"/> <xsl:include href="math.constant.xslt"/> <xsl:include href="math.exp.xslt"/> <xsl:include href="math.highest.xslt"/> <xsl:include href="math.log.xslt"/> <xsl:include href="math.lowest.xslt"/> <xsl:include href="math.max.xslt"/> <xsl:include href="math.min.xslt"/> <xsl:include href="math.power.xslt"/>

<xsl:include href="math.sqrt.xslt"/> <!— ТЕСТ –>

<xsl:template match="xsl:stylesheet[@id=’math:math’] | xsl:include[@href=’math.xslt’]">

<xsl:message> ТЕСТИРУЕТСЯ math </xsl:message>

<xsl:for-each select="document(”)/*/xsl:include">

<xsl:apply-templates select="."/> </xsl:for-each> </xsl:template>

<xsl:template match="xsl:include" priority="-10"> <xsl:message>

ПРЕДУПРЕЖДЕНИЕ: для <xsl:value-of select="@href"/> нет теста. </xsl:message> </xsl:template>

</xsl:stylesheet>

Как видите, тестовый код для всего пакета просто перебирает элементы xsl:include и применяет к ним шаблоны. Благодаря наличию вышеупомяну­той части xsl:include[@href=’filename’] будет произведено тестирова­ние всех включенных таблиц стилей.

Обратите внимание на шаблон <xsl: template match= "xsl: include" priority="-10">. Он выдает предупреждение, если для какого-то из включен­ных файлов нет теста. Это важно с точки зрения контроля качества, чтобы случай­но не забыть включить какой-нибудь тест.

Если идея включения тестов в исполняемый код вам не по душе, то того же результата можно достичь путем создания отдельного тестового файла для каж­дой служебной таблицы. В таком случае необходимость в атрибуте id отпадает, достаточно простого сопоставления с корнем:

<!– math.max.test.xslt–>

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:math="http://www.exslt.org/math" exclude-result-prefixes="math" xmlns:test="http://www.ora.com/XSLTCookbook/test">

<xsl:include href="../math/math.max.xslt"/>

<!— ТЕСТ: НЕ УДАЛЯТЬ! —>

<xsl:template match="/ | xsl:include[@href=’math.max.test.xslt’]">

<xsl:message> ТЕСТИРУЕТСЯ math.max </xsl:message>

<xsl:for-each select="document(”)/*/test:test"> <xsl:variable name="ans">

<xsl:call-template name="math:max">

<xsl:with-param name="nodes" select="test:data"/> </xsl:call-template> </xsl:variable> <xsl:if test="$ans != @ans"> <xsl:message>

math:max ТЕСТ <xsl:value-of select="@num"/> НЕ ПРОШЕЛ [<xsl:value-of select="$ans"/>] </xsl:message> </xsl:if> </xsl:for-each>

<!– … То же, что в math.max.xslt выше … –> </xsl:stylesheet>

Затем надо создать отдельные тестовые пакеты:

<!– math.test.xslt –>

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:math="http://exslt.org/math" extension-element-prefixes="math">

<xsl:include href="math.max.test.xslt"/> <xsl:include href="math.min.test.xslt"/>

<!– … То же, что в math.max.xslt выше … –>

</xsl:stylesheet>

Если вы решите таким образом отделить тесты от кода, не забудьте включить их в состав дистрибутивного пакета. Тогда клиенты смогут сами прогнать тесты. Заодно тестовый код показывает, как предполагается использовать шаблоны.

Мангано Сэл  XSLT. Сборник рецептов. – М.: ДМК Пресс, СПБ.: БХВ-Петербург, 2008. – 864 с.: ил.

По теме:

  • Комментарии