const xslt_functions = [
  "QName",
  "abs",
  "accumulator-after",
  "accumulator-before",
  "adjust-date-to-timezone",
  "adjust-dateTime-to-timezone",
  "adjust-time-to-timezone",
  "analyze-string",
  "apply",
  "available-environment-variables",
  "available-system-properties",
  "avg",
  "base-uri",
  "boolean",
  "ceiling",
  "codepoint-equal",
  "codepoints-to-string",
  "collation-key",
  "collection",
  "compare",
  "concat",
  "contains",
  "contains-token",
  "copy-of",
  "count",
  "current",
  "current-date",
  "current-dateTime",
  "current-group",
  "current-grouping-key",
  "current-merge-group",
  "current-merge-key",
  "current-output-uri",
  "current-time",
  "data",
  "dateTime",
  "day-from-date",
  "day-from-dateTime",
  "days-from-duration",
  "deep-equal",
  "default-collation",
  "default-language",
  "distinct-values",
  "doc",
  "doc-available",
  "document",
  "document-uri",
  "element-available",
  "element-with-id",
  "empty",
  "encode-for-uri",
  "ends-with",
  "environment-variable",
  "error",
  "escape-html-uri",
  "exactly-one",
  "exists",
  "false",
  "filter",
  "floor",
  "fold-left",
  "fold-right",
  "for-each",
  "for-each-pair",
  "format-date",
  "format-dateTime",
  "format-integer",
  "format-number",
  "format-time",
  "function-arity",
  "function-available",
  "function-lookup",
  "function-name",
  "generate-id",
  "has-children",
  "head",
  "hours-from-dateTime",
  "hours-from-duration",
  "hours-from-time",
  "id",
  "idref",
  "implicit-timezone",
  "in-scope-prefixes",
  "index-of",
  "innermost",
  "insert-before",
  "iri-to-uri",
  "json-doc",
  "json-to-xml",
  "key",
  "lang",
  "last",
  "load-xquery-module",
  "local-name",
  "local-name-from-QName",
  "lower-case",
  "matches",
  "max",
  "min",
  "minutes-from-dateTime",
  "minutes-from-duration",
  "minutes-from-time",
  "month-from-date",
  "month-from-dateTime",
  "months-from-duration",
  "name",
  "namespace-uri",
  "namespace-uri-for-prefix",
  "namespace-uri-from-QName",
  "nilled",
  "node-name",
  "normalize-space",
  "normalize-unicode",
  "not",
  "number",
  "one-or-more",
  "outermost",
  "parse-ietf-date",
  "parse-json",
  "parse-xml",
  "parse-xml-fragment",
  "path",
  "position",
  "prefix-from-QName",
  "put",
  "random-number-generator",
  "regex-group",
  "remove",
  "replace",
  "resolve-QName",
  "resolve-uri",
  "reverse",
  "root",
  "round",
  "round-half-to-even",
  "seconds-from-dateTime",
  "seconds-from-duration",
  "seconds-from-time",
  "serialize",
  "snapshot",
  "sort",
  "starts-with",
  "static-base-uri",
  "stream-available",
  "string",
  "string-join",
  "string-length",
  "string-to-codepoints",
  "subsequence",
  "substring",
  "substring-after",
  "substring-before",
  "sum",
  "system-property",
  "tail",
  "timezone-from-date",
  "timezone-from-dateTime",
  "timezone-from-time",
  "tokenize",
  "trace",
  "transform",
  "translate",
  "true",
  "type-available",
  "unordered",
  "unparsed-entity-public-id",
  "unparsed-entity-uri",
  "unparsed-text",
  "unparsed-text-available",
  "unparsed-text-lines",
  "upper-case",
  "uri-collection",
  "xml-to-json",
  "year-from-date",
  "year-from-dateTime",
  "years-from-duration",
  "zero-or-one",
];

const xslt1_functions = [
  "boolean",
  "ceiling",
  "concat",
  "contains",
  "count",
  "current",
  "document",
  "element-available",
  "false",
  "floor",
  "format-number",
  "function-available",
  "generate-id",
  "id",
  "key",
  "lang",
  "last",
  "local-name",
  "name",
  "namespace-uri",
  "normalize-space",
  "not",
  "number",
  "position",
  "round",
  "starts-with",
  "string",
  "string-length",
  "substring",
  "substring-after",
  "substring-before",
  "sum",
  "system-property",
  "translate",
  "true",
  "unparsed-entity-uri",
];

for (const fn of xslt_functions) {
  test(() => {
    const xsltSrc = `<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="html" encoding="utf-8" version="5"/>
<xsl:template match="/">
      <xsl:choose>
        <xsl:when test='function-available("${fn}")'>
          <div>available</div>
        </xsl:when>
        <xsl:otherwise>
          <div>unavailable</div>
        </xsl:otherwise>
      </xsl:choose>
</xsl:template>
</xsl:stylesheet>`;

    const processor = new XSLTProcessor();
    const parser = new DOMParser();
    processor.importStylesheet(
      parser.parseFromString(xsltSrc, "application/xml")
    );
    const output = processor.transformToFragment(
      parser.parseFromString("<x/>", "application/xml"),
      document
    );

    // Note we only expect functions defined in XSLT 1.0 to be defined.
    assert_equals(
      output.textContent.trim(),
      xslt1_functions.indexOf(fn) >= 0 ? "available" : "unavailable"
    );
  }, fn);
}
