summary refs log tree commit diff stats
path: root/tests/stdlib/thtmlparser.nim
blob: ccf2f620266578123d1cf24f8582b542ac1cd378 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
pre { line-height: 125%; }
td.linenos .normal { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; }
span.linenos { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; }
td.linenos .special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; }
span.linenos.special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; }
.highlight .hll { background-color: #ffffcc }
.highlight .c { color: #888888 } /* Comment */
.highlight .err { color: #a61717; background-color: #e3d2d2 } /* Error */
.highlight .k { color: #008800; font-weight: bold } /* Keyword */
.highlight .ch { color: #888888 } /* Comment.Hashbang */
.highlight .cm { color: #888888 } /* Comment.Multiline */
.highlight .cp { color: #cc0000; font-weight: bold } /* Comment.Preproc */
.highlight .cpf { color: #888888 } /* Comment.PreprocFile */
.highlight .c1 { color: #888888 } /* Comment.Single */
.highlight .cs { color: #cc0000; font-weight: bold; background-color: #fff0f0 } /* Comment.Special */
.highlight .gd { color: #000000; background-color: #ffdddd } /* Generic.Deleted */
.highlight .ge { font-style: italic } /* Generic.Emph */
.highlight .ges { font-weight: bold; font-style: italic } /* Generic.EmphStrong */
.highlight .gr { color: #aa0000 } /* Generic.Error */
.highlight .gh { color: #333333 } /* Generic.Heading */
.highlight .gi { color: #000000; background-color: #ddffdd } /* Generic.Inserted */
.highlight .go { color: #888888 } /* Generic.Output */
.highlight .gp { color: #555555 } /* Generic.Prompt */
.highlight .gs { font-weight: bold } /* Generic.Strong */
.highlight .gu { color: #666666 } /* Generic.Subheading */
.highlight .gt { color: #aa0000 } /* Generic.Traceback */
.highlight .kc { color: #008800; font-weight: bold } /* Keyword.Constant */
.highlight .kd { color: #008800; font-weight: bold } /* Keyword.Declaration */
.highlight .kn { color: #008800; font-weight: bold } /* Keyword.Namespace */
.highlight .kp { color: #008800 } /* Keyword.Pseudo */
.highlight .kr { color: #008800; font-weight: bold } /* Keyword.Reserved */
.highlight .kt { color: #888888; font-weight: bold } /* Keyword.Type */
.highlight .m { color: #0000DD; font-weight: bold } /* Literal.Number */
.highlight .s { color: #dd2200; background-color: #fff0f0 } /* Literal.String */
.highlight .na { color: #336699 } /* Name.Attribute */
.highlight .nb { color: #003388 } /* Name.Builtin */
.highlight .nc { color: #bb0066; font-weight: bold } /* Name.Class */
.highlight .no { color: #003366; font-weight: bold } /* Name.Constant */
.highlight .nd { color: #555555 } /* Name.Decorator */
.highlight .ne { color: #bb0066; font-weight: bold } /* Name.Exception */
.highlight .nf { color: #0066bb; font-weight: bold } /* Name.Function */
.highlight .nl { color: #336699; font-style: italic } /* Name.Label */
.highlight .nn { color: #bb0066; font-weight: bold } /* Name.Namespace */
.highlight .py { color: #336699; font-weight: bold } /* Name.Property */
.highlight .nt { color: #bb0066; font-weight: bold } /* Name.Tag */
.highlight .nv { color: #336699 } /* Name.Variable */
.highlight .ow { color: #008800 } /* Operator.Word */
.highlight .w { color: #bbbbbb } /* Text.Whitespace */
.highlight .mb { color: #0000DD; font-weight: bold } /* Literal.Number.Bin */
.highlight .mf { color: #0000DD; font-weight: bold } /* Literal.Number.Float */
.highlight .mh { color: #0000DD; font-weight: bold } /* Literal.Number.Hex */
.highlight .mi { color: #0000DD; font-weight: bold } /* Literal.Number.Integer */
.highlight .mo { color: #0000DD; font-weight: bold } /* Literal.Number.Oct */
.highlight .sa { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Affix */
.highlight .sb { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Backtick */
.highlight .sc { color: #dd
discard """
  output: '''
@[]
true
https://example.com/test?format=jpg&name=orig##
https://example.com/test?format=jpg&name=orig##text
https://example.com/test?format=jpg##text
'''
"""
import htmlparser
import xmltree
import strutils
from streams import newStringStream


block t2813:
  const
    html = """
    <html>
      <head>
        <title>Test</title>
      </head>
      <body>
        <table>
          <thead>
            <tr><td>A</td></tr>
            <tr><td>B</td></tr>
          </thead>
          <tbody>
            <tr><td></td>A<td></td></tr>
            <tr><td></td>B<td></td></tr>
            <tr><td></td>C<td></td></tr>
          </tbody>
          <tfoot>
            <tr><td>A</td></tr>
          </tfoot>
        </table>
      </body>
    </html>
    """
  var errors: seq[string] = @[]
  let tree = parseHtml(newStringStream(html), "test.html", errors)
  echo errors # Errors: </thead> expected,...

  var len = tree.findAll("tr").len # len = 6
  var rows: seq[XmlNode] = @[]
  for n in tree.findAll("table"):
    n.findAll("tr", rows)  # len = 2
    break
  assert tree.findAll("tr").len == rows.len


block t2814:
  ## builds the two cases below and test that
  ## ``//[dd,li]`` has "<p>that</p>" as children
  ##
  ##  <dl>
  ##    <dt>this</dt>
  ##    <dd>
  ##      <p>that</p>
  ##    </dd>
  ##  </dl>

  ##
  ## <ul>
  ##   <li>
  ##     <p>that</p>
  ##   </li>
  ## </ul>
  for ltype in [["dl","dd"], ["ul","li"]]:
    let desc_item = if ltype[0]=="dl": "<dt>this</dt>" else: ""
    let item = "$1<$2><p>that</p></$2>" % [desc_item, ltype[1]]
    let list = """ <$1>
     $2
  </$1> """ % [ltype[0], item]

    var errors : seq[string] = @[]
    let parseH = parseHtml(newStringStream(list),"statichtml", errors =errors)

    if $parseH.findAll(ltype[1])[0].child("p") != "<p>that</p>":
      echo "case " & ltype[0] & " failed !"
      quit(2)
  echo "true"

block t6154:
  let foo = """
  <!DOCTYPE html>
  <html>
      <head>
        <title> foobar </title>
      </head>
      <body>
        <p class=foo id=bar></p>
        <p something=&#9;foo&#9;bar&#178;></p>
        <p something=  &#9;foo&#9;bar&#178; foo  =bloo></p>
        <p class="foo2" id="bar2"></p>
        <p wrong= ></p>
        <p data-foo data-bar="correct!" enabled  ></p>
        <p quux whatever></p>
      </body>
  </html>
  """

  var errors: seq[string] = @[]
  let html = parseHtml(newStringStream(foo), "statichtml", errors=errors)
  doAssert "statichtml(11, 18) Error: attribute value expected" in errors
  let ps = html.findAll("p")
  doAssert ps.len == 7

  doAssert ps[0].attrsLen == 2
  doAssert ps[0].attr("class") == "foo"
  doAssert ps[0].attr("id") == "bar"
  doassert ps[0].len == 0

  doAssert ps[1].attrsLen == 1
  doAssert ps[1].attr("something") == "\tfoo\tbar²"
  doassert ps[1].len == 0

  doAssert ps[2].attrsLen == 2
  doAssert ps[2].attr("something") == "\tfoo\tbar²"
  doAssert ps[2].attr("foo") == "bloo"
  doassert ps[2].len == 0

  doAssert ps[3].attrsLen == 2
  doAssert ps[3].attr("class") == "foo2"
  doAssert ps[3].attr("id") == "bar2"
  doassert ps[3].len == 0

  doAssert ps[4].attrsLen == 1
  doAssert ps[4].attr("wrong") == ""

  doAssert ps[5].attrsLen == 3
  doAssert ps[5].attr("data-foo") == ""
  doAssert ps[5].attr("data-bar") == "correct!"
  doAssert ps[5].attr("enabled") == ""
  doassert ps[5].len == 0

  doAssert ps[6].attrsLen == 2
  doAssert ps[6].attr("quux") == ""
  doAssert ps[6].attr("whatever") == ""
  doassert ps[6].len == 0

# bug #11713, #1034
var content = """
# with &
<img src="https://example.com/test?format=jpg&name=orig" alt="">
<img src="https://example.com/test?format=jpg&name=orig" alt="text">

# without &
<img src="https://example.com/test?format=jpg" alt="text">
"""

var
  stream = newStringStream(content)
  body = parseHtml(stream)

for y in body.findAll("img"):
  echo y.attr("src"), "##", y.attr("alt")