#!/bin/sh
#
# Copyright (c) 2005 Jonas Fonseca
#

test_description='Test the very basic parsing of SGML documents.

This test runs very basic features, like checking that nodes are placed
correctly in the DOM tree.
'

. "$TEST_LIB"

test_output_equals () {
	desc="$1"; shift
	src="$1"; shift
	out="$1"; shift

	URI="test:$(normalize "$desc")"

	sgml-parser --uri "$URI" --src "$src" > output
	echo "#document: $URI" > expected
	printf "%s\n" "$out" | sed -n '2,$p' | sed 's/^/  /' >> expected

	test_expect_success "$desc" 'cmp output expected' 
}


################################################################
# Parse various SGML node types.

test_output_equals \
'Parse a small document.' \
'<html><body><p>Hello World!</p></body></html>' \
'
element: html
  element: body
    element: p
      #text: Hello World!'

test_output_equals \
'Parse elements.' \
'<root><child attr="value" /><child2></><child3 >a</></root>' \
'
element: root
  element: child
    attribute: attr -> value
  element: child2
  element: child3
    #text: a'

test_output_equals \
'Parse tag soup elements. (I)' \
'<parent attr="value" <child:1></><child:2</>a</parent>' \
'
element: parent
  attribute: attr -> value
  element: child:1
  element: child:2
  #text: a'

test_output_equals \
'Parse tag soup elements. (II)' \
'< a >< b < c / >< / >' \
'
element: a
  element: b
    element: c'

test_output_equals \
'Parse an enclosed comment.' \
'<root><!-- Hello World! --></root>' \
'
element: root
  #comment:  Hello World! '

test_output_equals \
'Parse comment combinations. (I)' \
'<root><!-- <!-- -- > --><!--foo--><!----></root>' \
'
element: root
  #comment:  <!-- -- > 
  #comment: foo
  #comment: '

test_output_equals \
'Parse comment combinations. (II).' \
'<! -- comment -->s<!-->-->t<!----->u' \
'
#comment:  comment 
#text: s
#comment: >
#text: t
#comment: -
#text: u'

test_output_equals \
'Parse bad comment. (I)' \
'<!--->s' \
'
#comment: ->s'

test_output_equals \
'Parse bad comment. (II)' \
'<!--a--!>bad comment' \
'
#comment: a
#text: bad comment'

test_output_equals \
'Parse empty notation.' \
'<!>s' \
'
#text: s'

test_output_equals \
'Parse an enclosed CDATA section.' \
'<root><![CDATA[...] ]>...]]></root>' \
'
element: root
  #cdata-section: ...] ]>...'

test_output_equals \
'Parse non-enclosed CDATA section.' \
'<![CDATA[...]]>' \
'
#cdata-section: ...'

test_output_equals \
'Parse a bad CDATA section.' \
'<![CDATA[...' \
'
#cdata-section: ...'

test_output_equals \
'Parse attributes.' \
'<root lang="fr" attr name="value with &foo; <stuff"></root>' \
'
element: root
  attribute: lang -> fr
  attribute: attr -> 
  attribute: name -> value with &foo; <stuff'

test_output_equals \
'Parse attributes with garbage.' \
"<root a=b c='d' e'f' g= h i = j k =></root>" \
'
element: root
  attribute: a -> b
  attribute: c -> d
  attribute: g -> h
  attribute: i -> j
  attribute: k -> ' 

test_output_equals \
'Parse attribute with non-quoted values.' \
'<root color=#abc path=/to/%61-&\one";files/>...' \
'
element: root
  attribute: color -> #abc
  attribute: path -> /to/%61-&\one";files
#text: ...'

test_output_equals \
'Parse entity references.' \
'&amp;-&#42;' \
'
entity-reference: amp
#text: -
entity-reference: #42'

# Just how these should be gracefully handled is not clear to me.
test_output_equals \
'Parse badly formatted entity references.' \
'& m33p;-&.:-copy;-&;-&#;-&#xx;' \
'
#text: & m33p;
#text: -
entity-reference: .:-copy
#text: -
#text: &;
#text: -
entity-reference: #
#text: -
entity-reference: #xx'

test_output_equals \
'Parse processing instructions.' \
'<?xml encoding="UTF8"?>
...
<?ecmascript
var val=2;
?>' \
'
proc-instruction: xml -> encoding="UTF8"
  attribute: encoding -> UTF8
#text: \n...\n
proc-instruction: ecmascript -> var val=2;\n'

test_output_equals \
'Parse XML processing instructions.' \
'<?xml version="1.0" />?><?xml />-' \
'
proc-instruction: xml -> version="1.0" />
  attribute: version -> 1.0
proc-instruction: xml -> />-'

test_output_equals \
'Parse XML stylesheet processing instructions.' \
'<?xml-stylesheet type="text/xsl" href="url"?>' \
'
proc-instruction: xml-stylesheet -> type="text/xsl" href="url"
  attribute: type -> text/xsl
  attribute: href -> url'

test_output_equals \
'Parse exotic processing instructions.' \
'<?xml ?+>+?>-?>-<?js?>-<??>-' \
'
proc-instruction: xml -> ?+>+
#text: -?>-
proc-instruction: js -> 
#text: -
proc-instruction:  -> 
#text: -'

test_output_equals \
'Parse incorrect processing instructions. (I)' \
'<?js<?>-<?<??>-<?xml <=";&?>-<?' \
'
proc-instruction: js -> <
#text: -
proc-instruction:  -> <?
#text: -
proc-instruction: xml -> <=";&
#text: -'

test_output_equals \
'Parse incorrect processing instructions (II).' \
'<?><?' \
'
proc-instruction:  -> ><?'

test_output_equals \
'Skip spaces not inside text.' \
'<
root
ns:attr                      
=
"value"
><?	
	target	
 data?><	/	root	>' \
'
element: root
  attribute: ns:attr -> value
  proc-instruction: target -> data'

test_done
