Fantom

 

//
// Copyright (c) 2007, Brian Frank and Andy Frank
// Licensed under the Academic Free License version 3.0
//
// History:
//   17 Feb 07  Brian Frank  Creation
//

**
** FandocTest
**
@Js
class FandocTest : Test
{

//////////////////////////////////////////////////////////////////////////
// Emphasis
//////////////////////////////////////////////////////////////////////////

  Void testEmphasis()
  {
    verifyDoc("*x*", ["<body>", ["<p>", ["<em>", "x"]]])
    verifyDoc("*foo*", ["<body>", ["<p>", ["<em>", "foo"]]])
    verifyDoc("\n*foo*", ["<body>", ["<p>", ["<em>", "foo"]]])
    verifyDoc("alpha *foo* beta", ["<body>", ["<p>", "alpha ", ["<em>", "foo"], " beta"]])

    verifyDoc("**x**", ["<body>", ["<p>", ["<strong>", "x"]]])
    verifyDoc("\n\n**x**", ["<body>", ["<p>", ["<strong>", "x"]]])
    verifyDoc("alpha **foo** beta", ["<body>", ["<p>", "alpha ", ["<strong>", "foo"], " beta"]])

    ph := FandocParser { parseHeader = false }.parseStr("\n**foo**")
    verifyDocNode(ph, ["<body>", ["<p>", ["<strong>", "foo"]]])

    // strong nested in emphasis
    verifyDoc("* **wow** *", ["<body>", ["<p>",  ["<em>", " ", ["<strong>", "wow"], " "]]])
    verifyDoc("You know, *winter\n**really, really**\nsucks*!", ["<body>", ["<p>", "You know, ",
      ["<em>", "winter ", ["<strong>", "really, really"], " sucks"], "!"]])

    // emphasis nested in strong
    verifyDoc("** *wow* **", ["<body>", ["<p>",  ["<strong>", " ", ["<em>", "wow"], " "]]])
    verifyDoc("You know, **winter\n*really, really*\nsucks**!", ["<body>", ["<p>", "You know, ",
      ["<strong>", "winter ", ["<em>", "really, really"], " sucks"], "!"]])

    verifyDoc("**`foo`**", ["<body>", ["<p>", ["<strong>", ["<a foo>", "foo"]]]])
    verifyDoc("**[some Foo]`foo`**", ["<body>", ["<p>", ["<strong>", ["<a foo>", "some Foo"]]]])

    /* dfn term retired
    verifyDoc("/term/", ["<body>", ["<p>", ["<dfn>", "term"]]])
    verifyDoc("/term/ what it is", ["<body>", ["<p>", ["<dfn>", "term"], " what it is"]])
    verifyDoc("/`#jump`/", ["<body>", ["<p>", ["<dfn>", ["<a #jump>", "#jump"]]]])
    verifyDoc("/[JUMP]`#jump`/", ["<body>", ["<p>", ["<dfn>", ["<a #jump>", "JUMP"]]]])
    */

    // these are normal paragraphs because the symbol
    // isn't prefixed with a space
    verifyDoc("a*b", ["<body>", ["<p>", "a*b"]])
    verifyDoc("a**b", ["<body>", ["<p>", "a**b"]])
    verifyDoc("a/b", ["<body>", ["<p>", "a/b"]])

    // these are normal paragraphs because the symbol is followed by space
    verifyDoc("a * b",  ["<body>", ["<p>", "a * b"]])
    verifyDoc("a / b",  ["<body>", ["<p>", "a / b"]])
    /*verifyDoc("a ** b", ["<body>", ["<p>", "a ** b"]])*/
  }

  Void testEmphasisErr()
  {
    verifyDoc("Alpha beta\ngamma * in *.java,\ndelta.",
      ["<body>", ["<p>", "Alpha beta gamma * in *.java, delta."]])
  }

//////////////////////////////////////////////////////////////////////////
// Code
//////////////////////////////////////////////////////////////////////////

  Void testCode()
  {
    verifyDoc("Brian's", ["<body>", ["<p>", "Brian's"]])
    verifyDoc("'x'", ["<body>", ["<p>", ["<code>", "x"]]])
    verifyDoc("a 'x'", ["<body>", ["<p>", "a ", ["<code>", "x"]]])
    verifyDoc("a 'x' b", ["<body>", ["<p>", "a ", ["<code>", "x"], " b"]])
    verifyDoc(" 'x' b ", ["<body>", ["<p>", ["<code>", "x"], " b"]])
    verifyDoc("'x * y / z [`foo`]'", ["<body>", ["<p>", ["<code>", "x * y / z [`foo`]"]]])

    // test emphasis symbols in code block
    verifyDoc("'*a*'",    ["<body>", ["<p>", ["<code>", "*a*"]]])
    verifyDoc("'**a**'",  ["<body>", ["<p>", ["<code>", "**a**"]]])
    verifyDoc("'/foo/'",  ["<body>", ["<p>", ["<code>", "/foo/"]]])
  }

//////////////////////////////////////////////////////////////////////////
// Links
//////////////////////////////////////////////////////////////////////////

  Void testLinks()
  {
    verifyDoc("`uri`", ["<body>", ["<p>", ["<a uri>", "uri"]]])
    verifyDoc("a `uri`", ["<body>", ["<p>", "a ", ["<a uri>", "uri"]]])
    verifyDoc("a `uri` b", ["<body>", ["<p>", "a ", ["<a uri>", "uri"], " b"]])
    verifyDoc("`uri` b", ["<body>", ["<p>", ["<a uri>", "uri"], " b"]])
    verifyDoc("Foo `one` bar `two`.", ["<body>", ["<p>", "Foo ", ["<a one>", "one"], " bar ", ["<a two>", "two"], "."]])

    verifyDoc("[cool site]`http://cool/`", ["<body>", ["<p>", ["<a http://cool/>", "cool site"]]])
    verifyDoc("Check [cool site]`http://cool/`!", ["<body>", ["<p>", "Check ", ["<a http://cool/>", "cool site"], "!"]])
    verifyDoc("([cool site]`http://cool/`)", ["<body>", ["<p>", "(", ["<a http://cool/>", "cool site"], ")"]])

    // empty [] are normal text
    verifyDoc("[]", ["<body>", ["<p>", "[]"]])
    verifyDoc("x [] y", ["<body>", ["<p>", "x [] y"]])
  }

//////////////////////////////////////////////////////////////////////////
// Image
//////////////////////////////////////////////////////////////////////////

  Void testImage()
  {
    verifyDoc("![cool image]`cool.png`", ["<body>", ["<p>", ["<img cool image;cool.png>"]]])
    verifyDoc("![cool image][100x200]`cool.png`", ["<body>", ["<p>", ["<img cool image;cool.png;100x200>"]]])
    verifyDoc("![Brian's Idea]`http://foo/idea.gif`", ["<body>", ["<p>", ["<img Brian's Idea;http://foo/idea.gif>"]]])
    verifyDoc("alpha ![x]`img.png` beta", ["<body>", ["<p>", "alpha ", ["<img x;img.png>"], " beta"]])
    verifyDoc("[![x]`img.png`]`#link`", ["<body>", ["<p>", ["<a>", ["<img x;img.png>"]]]])
  }

//////////////////////////////////////////////////////////////////////////
// AnchorIds
//////////////////////////////////////////////////////////////////////////

  Void testAnchorIds()
  {
    doc := verifyDoc("[#xyz]some text\nthe end.", ["<body>", ["<p>", "some text the end."]])
    verifyEq(doc.children.first->anchorId, "xyz")

    doc = verifyDoc("Chapter Two [#ch2]\n=======\nblah blah", ["<body>", ["<h3>", "Chapter Two"], ["<p>", "blah blah"]])
    verifyEq(doc.children.first->anchorId, "ch2")

    doc = verifyDoc("[#ch2]Chapter Two\n=======\nblah blah", ["<body>", ["<h3>", "Chapter Two"], ["<p>", "blah blah"]])
    verifyEq(doc.children.first->anchorId, "ch2")
  }

//////////////////////////////////////////////////////////////////////////
// Para
//////////////////////////////////////////////////////////////////////////

  Void testPara()
  {
    verifyDoc("", ["<body>"])
    verifyDoc("  \n  \n", ["<body>"])
    verifyDoc("a", ["<body>", ["<p>", "a"]])
    verifyDoc("\na", ["<body>", ["<p>", "a"]])
    verifyDoc("\n\na b c\nd e f.", ["<body>", ["<p>", "a b c d e f."]])
    verifyDoc("a b c\n\nd e f.  ", ["<body>", ["<p>", "a b c"], ["<p>", "d e f."]])
    verifyDoc("alpha\r\nbeta\r\n\r\ngamma\r\n", ["<body>", ["<p>", "alpha beta"], ["<p>", "gamma"]])
    verifyDoc("NOTE: that's right", ["<body>", ["<p NOTE>", "that's right"]])
    verifyDoc("TODO: that's right\nkeep it!", ["<body>", ["<p TODO>", "that's right keep it!"]])
    verifyDoc("Note: that's right", ["<body>", ["<p>", "Note: that's right"]])
  }

//////////////////////////////////////////////////////////////////////////
// Pre
//////////////////////////////////////////////////////////////////////////

  Void testPre()
  {
    verifyDoc("  a+b", ["<body>", ["<pre>", "a+b"]])
    verifyDoc("a\n\n  foo\n  bar\n\nb", ["<body>", ["<p>", "a"], ["<pre>", "foo\nbar"], ["<p>", "b"],])

    verifyDoc(
     "  class A
        {
          Int x()
          {
            return 3
          }
        }


        class B {}
      ",
         ["<body>", ["<pre>", "class A\n{\n  Int x()\n  {\n    return 3\n  }\n}\n\n\nclass B {}"]])

    verifyDoc("Code:\n  [,]", ["<body>", ["<p>", "Code:"], ["<pre>", "[,]"]])
  }

//////////////////////////////////////////////////////////////////////////
// PreExplicit
//////////////////////////////////////////////////////////////////////////

  Void testPreExplicit()
  {
    verifyDoc(
     "pre>
        - a

        - b
      <pre
      ", ["<body>", ["<pre>", "- a\n\n- b\n"]])

    verifyDoc(
     "pre>
        a
       b
      c
      <pre
      ", ["<body>", ["<pre>", "  a\n b\nc\n"]])

    verifyDoc(
     "pre>
         3
        2
           5
          4
      <pre
      ", ["<body>", ["<pre>", " 3\n2\n   5\n  4\n"]])
  }

//////////////////////////////////////////////////////////////////////////
// Headings
//////////////////////////////////////////////////////////////////////////

  Void testHeadings()
  {
    verifyDoc(
     "Chapter 1
      *********

      1.1
      ===
      Alpha
      Beta

      1. 1.1
      -----
        Foo

      New Book
      ########
      Chapter 2
      *********

      Roger - chapter two!
      ", ["<body>",
            ["<h2>", "Chapter 1"],
            ["<h3>", "1.1"],
            ["<p>", "Alpha Beta"],
            ["<h4>", "1. 1.1"],
            ["<pre>", "Foo"],
            ["<h1>", "New Book"],
            ["<h2>", "Chapter 2"],
            ["<p>", "Roger - chapter two!"],
          ])

    verifyDoc("a\n\n####\nb", ["<body>", ["<p>", "a"], ["<p>", "#### b"]])
    verifyDoc("a\n\n===\n\nb", ["<body>", ["<p>", "a"], ["<p>", "==="], ["<p>", "b"]])
    verifyDoc("\n\n------\n", ["<body>", ["<hr>"]])
  }

//////////////////////////////////////////////////////////////////////////
// HR
//////////////////////////////////////////////////////////////////////////

  Void testHr()
  {
    verifyDoc("Foo\n\n---\nBar", ["<body>", ["<p>", "Foo"], ["<hr>"], ["<p>", "Bar"]])
    verifyDoc("\n\n---", ["<body>", ["<hr>"]])
    verifyDoc("\n\n---\n", ["<body>", ["<hr>"]])
  }

//////////////////////////////////////////////////////////////////////////
// BlockQuotes
//////////////////////////////////////////////////////////////////////////

  Void testBlockQuotes()
  {
    verifyDoc("> a", ["<body>", ["<blockquote>", ["<p>", "a"]]])
    verifyDoc("> a\n> b c\n> d", ["<body>", ["<blockquote>", ["<p>", "a b c d"]]])
    verifyDoc("> a\nb c\nd\n\np2", ["<body>", ["<blockquote>", ["<p>", "a b c d"]], ["<p>", "p2"]])
    verifyDoc("> a\nb\n\n> c\nd\ne\n\nf", ["<body>", ["<blockquote>", ["<p>", "a b"], ["<p>", "c d e"]], ["<p>", "f"]])
    verifyDoc("> a\n> b\n\n> c\n> d\n> e\n\nf", ["<body>", ["<blockquote>", ["<p>", "a b"], ["<p>", "c d e"]], ["<p>", "f"]])
  }

//////////////////////////////////////////////////////////////////////////
// UL
//////////////////////////////////////////////////////////////////////////

  Void testUL()
  {
    verifyDoc(
     "- a

      heading
      ----", ["<body>", ["<ul>", ["<li>", "a"]], ["<h4>", "heading"]])

    verifyDoc("- a", ["<body>", ["<ul>", ["<li>", "a"]]])

    verifyDoc(
     "- a
      - b
      - c
      ",
    ["<body>", ["<ul>", ["<li>", "a"], ["<li>", "b"], ["<li>", "c"]]])

    verifyDoc(
     "- li [link]`uri` text
      - li", ["<body>", ["<ul>", ["<li>", "li ", ["<a uri>", "link"], " text"], ["<li>", "li"]]])

    verifyDoc(
     "- one
        - a
        - b
      - two
        - c
        - d
      ",
    ["<body>",
      ["<ul>",
        ["<li>", "one", ["<ul>", ["<li>", "a"], ["<li>", "b"]]],
        ["<li>", "two", ["<ul>", ["<li>", "c"], ["<li>", "d"]]]]])

    verifyDoc(
     "- one
        - a
          - i
          - j
        - b
      - two
        - c
        - d
          - k
      ",
    ["<body>",
      ["<ul>",
        ["<li>", "one", ["<ul>",
          ["<li>", "a", ["<ul>", ["<li>", "i"], ["<li>", "j"]]],
          ["<li>", "b"]]],
        ["<li>", "two", ["<ul>",
          ["<li>", "c"],
          ["<li>", "d", ["<ul>", ["<li>", "k"]]]
        ]]]])

    verifyDoc(
     "  - a b c
          d e f
        - g h i j k
      l m n o
        - p q
            r s
      ",
    ["<body>", ["<ul>", ["<li>", "a b c d e f"], ["<li>", "g h i j k l m n o"], ["<li>", "p q", ["<pre>", "r s"]]]])

    verifyDoc(
     "- 1-a
        1-b
      - 2-a
        2-b
      ",
      ["<body>", ["<ul>", ["<li>", "1-a 1-b"], ["<li>", "2-a 2-b"]]])

    verifyDoc(
     "- one
        line 2

        one para 2
        more

      - two

          Int x()
            {
              return x
            }

          Int y

        two para another
      ",
    ["<body>", ["<ul>",
      ["<li>", "one line 2", ["<p>", "one para 2 more"]],
      ["<li>", "two", ["<pre>", "Int x()\n  {\n    return x\n  }\n\nInt y"], ["<p>", "two para another"]]]])
  }

//////////////////////////////////////////////////////////////////////////
// OL
//////////////////////////////////////////////////////////////////////////

  Void testOL()
  {
    // these are not lists
    verifyDoc("This is\nit. Right?", ["<body>", ["<p>", "This is it. Right?"]])

    verifyDoc("1. one\n2. two", ["<body>", ["<ol 1>", ["<li>", "one"], ["<li>", "two"]]])
    verifyDoc("  A. one\n  B. two", ["<body>", ["<ol A>", ["<li>", "one"], ["<li>", "two"]]])
    verifyDoc("a. one\ntwo\nthree", ["<body>", ["<ol a>", ["<li>", "one two three"]]])
    verifyDoc("I. one\nII. two\nIII. three", ["<body>", ["<ol I>", ["<li>", "one"], ["<li>", "two"], ["<li>", "three"]]])
    verifyDoc("i. one\nii. two", ["<body>", ["<ol i>", ["<li>", "one"], ["<li>", "two"]]])

    verifyDoc(
     "I. ONE
        A. alpha
          i. one
          ii. two
        B. beta
      II. TWO
        A. gamma
        B. delta

             - a
             - b
             - c

           delta continues
           again

             some code
               -> foo

           delta another para

      ",
    ["<body>",
      ["<ol I>",
        ["<li>", "ONE", ["<ol A>",
          ["<li>", "alpha", ["<ol i>",
                            ["<li>", "one"], ["<li>", "two"]]],
          ["<li>", "beta"]]],
        ["<li>", "TWO", ["<ol A>",
          ["<li>", "gamma"],
          ["<li>", "delta", ["<ul>", ["<li>", "a"], ["<li>", "b"], ["<li>", "c"]],
                            ["<p>", "delta continues again"],
                            ["<pre>", "some code\n  -> foo"],
                            ["<p>", "delta another para"]]
        ]]]])


    verifyDoc(
     "1. 1-a
         1-b
      2. 2-a
         2-b

         2-c
         2-d
      ",
      ["<body>", ["<ol 1>", ["<li>", "1-a 1-b"], ["<li>", "2-a 2-b", ["<p>", "2-c 2-d"]]]])

    verifyDoc(
      "i. 1-a
          1-b
       ii. 2-a
           2-b
       iii. 3-a
            3-b
       ",
      ["<body>", ["<ol i>", ["<li>", "1-a 1-b"], ["<li>", "2-a 2-b"], ["<li>", "3-a 3-b"]]])
  }

//////////////////////////////////////////////////////////////////////////
// Meta
//////////////////////////////////////////////////////////////////////////

  Void testMeta()
  {
    doc := verifyDoc(
     "**************************************
      ** a: b
      ** title: Rocking test here!
      **************************************

      head
      ***

      para", ["<body>", ["<h2>", "head"], ["<p>", "para"]])


     verifyEq(doc.meta.size, 2)
     verifyEq(doc.meta["a"], "b")
     verifyEq(doc.meta["title"], "Rocking test here!")
  }

//////////////////////////////////////////////////////////////////////////
// Errors
//////////////////////////////////////////////////////////////////////////

  Void testErrs()
  {
    verifyErrs("*i",
     ["<body>", ["<p>", "*i"]],
     [1, "Invalid *emphasis*"])

    verifyErrs("a\nb\n**i",
     ["<body>", ["<p>", "a b **i"]],
     [3, "Invalid **strong**"])

    verifyErrs("aaaa\nbbbb bbb\n\nccc\n**i",
     ["<body>", ["<p>", "aaaa bbbb bbb"], ["<p>", "ccc **i"]],
     [5, "Invalid **strong**"])

    verifyErrs(
    "abc `foo

     1. ok
     2. *bad
     3. **worse
     ",
     ["<body>", ["<p>", "abc `foo"], ["<ol 1>", ["<li>", "ok"], ["<li>", "*bad"], ["<li>", "**worse"]]],
     [
       1, "Invalid uri",
       4, "Invalid *emphasis*",
       5, "Invalid **strong**",
     ])

    verifyErrs("------\na\n- one\n- two",
     ["<body>", ["<pre>", "------\na\n- one\n- two"]],
     [1, "Invalid line 1"])
  }

  Void verifyErrs(Str str, Obj[] expected, Obj[] errs)
  {
    parser := FandocParser { silent = true }
    doc := parser.parse("Test", str.in)
    verifyDocNode(doc, expected)
    // echo("======")
    // parser.errs.each |Err e| { echo(e) }
    verifyEq(parser.errs.size, errs.size/2)
    parser.errs.each |FandocErr e, Int i|
    {
      verifyEq(e.file, "Test")
      verifyEq(e.line, errs[i*2])
      verifyEq(e.msg,  errs[i*2+1])
    }

  }

//////////////////////////////////////////////////////////////////////////
// ListItem
//////////////////////////////////////////////////////////////////////////

  Void testToB26()
  {
    li := ListIndex(OrderedListStyle.lowerAlpha)
    verifyEq(li.toStr, "a. ")
    verifyEq(li.increment.toStr, "b. ")
    verifyEq(li.increment.toStr, "c. ")
    verifyEq(li.increment.toStr, "d. ")
    verifyEq(li.increment.toStr, "e. ")
    verifyEq(li.increment.toStr, "f. ")
    verifyEq(li.increment.toStr, "g. ")

    li.index = 25
    verifyEq(li.toStr, "y. ")
    verifyEq(li.increment.toStr, "z. ")
    verifyEq(li.increment.toStr, "aa. ")
    verifyEq(li.increment.toStr, "ab. ")
    verifyEq(li.increment.toStr, "ac. ")

    li = ListIndex(OrderedListStyle.upperAlpha)
    verifyEq(li.toStr, "A. ")
    verifyEq(li.increment.toStr, "B. ")
    verifyEq(li.increment.toStr, "C. ")
    verifyEq(li.increment.toStr, "D. ")
    verifyEq(li.increment.toStr, "E. ")
    verifyEq(li.increment.toStr, "F. ")
    verifyEq(li.increment.toStr, "G. ")

    li.index = 26
    verifyEq(li.toStr, "Z. ")
    verifyEq(li.increment.toStr, "AA. ")
    verifyEq(li.increment.toStr, "AB. ")
    verifyEq(li.increment.toStr, "AC. ")
  }

  Void testToRoman()
  {
    li := ListIndex(OrderedListStyle.lowerRoman)
    verifyEq(li.toStr, "i. ")
    verifyEq(li.increment.toStr, "ii. ")
    verifyEq(li.increment.toStr, "iii. ")
    verifyEq(li.increment.toStr, "iv. ")
    verifyEq(li.increment.toStr, "v. ")
    verifyEq(li.increment.toStr, "vi. ")
    verifyEq(li.increment.toStr, "vii. ")

    li.index = 26
    verifyEq(li.toStr, "xxvi. ")
    verifyEq(li.increment.toStr, "xxvii. ")
    verifyEq(li.increment.toStr, "xxviii. ")
    verifyEq(li.increment.toStr, "xxix. ")

    li = ListIndex(OrderedListStyle.upperRoman)
    verifyEq(li.toStr, "I. ")
    verifyEq(li.increment.toStr, "II. ")
    verifyEq(li.increment.toStr, "III. ")
    verifyEq(li.increment.toStr, "IV. ")
    verifyEq(li.increment.toStr, "V. ")
    verifyEq(li.increment.toStr, "VI. ")
    verifyEq(li.increment.toStr, "VII. ")

    li.index = 26
    verifyEq(li.toStr, "XXVI. ")
    verifyEq(li.increment.toStr, "XXVII. ")
    verifyEq(li.increment.toStr, "XXVIII. ")
    verifyEq(li.increment.toStr, "XXIX. ")
  }

//////////////////////////////////////////////////////////////////////////
// VerifyDoc
//////////////////////////////////////////////////////////////////////////

  Doc verifyDoc(Str str, Obj[] expected)
  {
    parser := FandocParser { silent = true }
    doc := parser.parse("Test", str.in)

    // echo("__________________\n$str\n\n")
    // doc.write(HtmlDocWriter())

    verifyDocNode(doc, expected)

    roundtrip := StrBuf()
    doc.write(FandocDocWriter(roundtrip.out))
    // echo; echo(roundtrip.toStr)
    doc2 := parser.parse("Test-2", roundtrip.toStr.in)
    verifyDocNode(doc2, expected)

    return doc
  }

  Void verifyDocNode(DocElem actual, Obj[] expected)
  {
    // first item is <elem>, rest are children nodes
    expectedElem := expected.first
    expectedKids := expected[1..-1]

    elemName := expectedElem.toStr[1..-2]
    olStyle := OrderedListStyle.number
    if (elemName.startsWith("ol"))
    {
      olStyle = OrderedListStyle.fromFirstChar(elemName[-1])
      elemName = "ol"
      verifyEq(actual->style, olStyle)
    }
    else if (elemName.startsWith("p "))
    {
      admonition := elemName[2..-1]
      elemName = "p"
      verifyEq(actual->admonition, admonition)
    }
    else if (elemName.startsWith("a "))
    {
      uri := elemName[2..-1]
      elemName = "a"
      verifyEq(actual->uri, uri)
    }
    else if (elemName.startsWith("img "))
    {
      body := elemName[4..-1]
      elemName = "img"
      verifyEq(actual->alt, body.split(';')[0])
      verifyEq(actual->uri, body.split(';')[1])
      verifyEq(actual->size, body.split(';').getSafe(2))
    }

    verifyEq(actual.htmlName, elemName)
    if (actual.children.size != expectedKids.size)
    {
      echo("")
      echo("actual   = $actual.children")
      echo("expected = $expectedKids")
    }
    verifyEq(actual.children.size, expectedKids.size)
    actual.children.size.times |Int i|
    {
      a := actual.children[i]
      e := expectedKids[i]
      if (a is DocElem)
      {
        verifyDocNode((DocElem)a, (Obj[])e)
      }
      else
      {
        verifyType(a, DocText#)
        if (a->str != e) {
            Env.cur.err.printLine("-----")
            Env.cur.err.printLine(a->str)
            Env.cur.err.printLine(" != ")
            Env.cur.err.printLine(e)
            Env.cur.err.printLine("-----")
        }
        verifyEq(a->str, e)
      }
    }
  }

}