class BaseTest(TestCase):

    def assertEqual_(self, html, expected):
        document_root = lxml_html.fromstring(html)
        h = etree.tostring(document_root, encoding='unicode',
                           pretty_print=True)
        document_root = lxml_html.fromstring(expected)
        e = etree.tostring(document_root, encoding='unicode',
                           pretty_print=True)
        self.maxDiff = None
        self.assertEqual(h, e) def cleanup(value):
def parse_element(value):
def parse_entity(value):
def split_list(lis, cols):
def parse_attribute(value):
def dtd_to_dict_v2(dtd):
def _parse_elts(elts):
def _create_new_class(class_dict, name, required, islist, conditionals,
                      inlist=False, inchoice=False):
def _create_class_dict(dtd_dict):
def _create_classes(dtd_dict): def create(root_tag, dtd_url=None, dtd_str=None):
def load(filename, validate=True):
def load_string(xml_str, validate=True):
def generate_form(filename, form_action=None, form_filename=None, validate=True):
def generate_form_from_obj(obj, form_action=None, form_filename=None,
                           validate=True, form_attrs=None):
def update(filename, data, validate=True, transform=None):
def new(dtd_url, root_tag, form_action=None, form_attrs=None):
def getElementData(elt_id, data):
def _get_obj_from_str_id(str_id, dtd_url=None, dtd_str=None, data=None):
def _get_parent_to_add_obj(elt_id, tagname, data, dtd_url=None, dtd_str=None):
def _get_data_for_html_display(obj):
def _add_new_element_from_id(elt_id, data, clipboard_data, dtd_url=None,
                             dtd_str=None, skip_extra=False):
def get_new_element_data_for_html_display(*args, **kw):
def get_data_from_str_id_for_html_display(str_id, dtd_url=None, dtd_str=None,
                                          html_renderer=None): def attrs_to_str(attrs):
    def __init__(self, extra_attrs_func=None):
    def add_add_button(self):
    def add_delete_button(self):
    def add_comment(self):
    def text_element_to_html(self, obj, attrs, value):
    def __init__(self, extra_attrs_func=None, extra_div_attrs_func=None):
    def cleanup_value(self, value):
    def text_element_to_html(self, obj, attrs, value):
    def cleanup_value(self, value):
    def add_add_button(self):
    def add_delete_button(self):
    def add_comment(self):
    def text_element_to_html(self, obj, attrs, value):
class Render(object):
class ContenteditableRender(Render):
class CKeditorRender(ContenteditableRender):
class ReadonlyRender(Render): class ValidationError(Exception):
class DTD(object):
    def __init__(self, url, path=None):
    def _get_dtd_url(self):
    def _fetch(self):
    def content(self):
    def validate(self):
    def _parse(self):
    def parse(self):
    def validate_xml(self, xml_obj): class EmptyElement(object):
    """This object is used in the ListElement to keep the good index.
    """
    def __init__(self, parent_obj):
        self._parent_obj = parent_obj
        self._auto_added = False def escape_attr(s):
    """Escape attributes ':' and '.' since it's not supported by jQuery
    """
    return s.replace(':', '\\:').replace('.', '\\.') def get_data_from_str_id_for_html_display(str_id, dtd_url=None, dtd_str=None,
                                          html_renderer=None):
    """Get the sub object corresponding to the given str_id and returns the
    data to display it.
    """
    obj = _get_obj_from_str_id(str_id, dtd_url, dtd_str)
    if not obj:
        return None
    obj.root.html_renderer = html_renderer
    return _get_data_for_html_display(obj) def _get_data_for_html_display(obj):
    """Returns the data need to display the object in HTML.
    """
    return {
        'jstree_data': obj.to_jstree_dict(),
        'previous': obj.get_previous_js_selectors(),
        'html': obj.to_html(),
        'elt_id': ':'.join(obj.prefixes),
    } def unflatten_params(params):
    """This performs the first stage of validation. It takes a dictionary where
    some keys will be compound names, such as "form:subform:field" and converts
    this into a nested dict/list structure. It also performs unicode decoding.
    """
    if isinstance(params, webob.MultiDict):
        params = params.mixed()
    # TODO: the encoding can be in the given params, use it!
    enc = 'utf-8'
    for p in params:
        if isinstance(params[p], str) and six.PY2:
            # Can raise an exception!
            params[p] = params[p].decode(enc)

    out = {}
    for pname in params:
        dct = out
        elements = pname.split(':')
        for e in elements[:-1]:
            dct = dct.setdefault(e, {})
        dct[elements[-1]] = params[pname]

    numdict_to_list(out)
    return out MOVIE_DTD = u'''
<!ELEMENT Movie (is-publish?, name, year, directors, actors, resume?, critique*)>

<!-- My comment
that should be removed
<!ELEMENT fake (skipme+)>
-->
<!ENTITY % person "name, firstname" >
<!ELEMENT is-publish EMPTY>
<!ELEMENT directors (director+)>
<!ELEMENT actors (actor+)>
<!ELEMENT name (#PCDATA)>
<!ELEMENT firstname (#PCDATA)>
<!ELEMENT year (#PCDATA)>
<!ELEMENT director (%person;)>
<!ELEMENT actor (%person;)>
<!ELEMENT resume (#PCDATA)>
<!ELEMENT critique (#PCDATA)>
''' MOVIE_XML_TITANIC_COMMENTS = b'''<?xml version='1.0' encoding='UTF-8'?>
<!-- Movie comment -->
<Movie>
  <!-- name comment -->
  <name>Titanic</name>
  <!-- year comment -->
  <year>1997</year>
  <!-- directors comment -->
  <directors>
    <!-- director comment -->
    <director>
      <!-- director name comment -->
      <name>Cameron</name>
      <!-- director firstname comment -->
      <firstname>James</firstname>
    </director>
  </directors>
  <!-- actors comment -->
  <actors>
    <!-- actor 1 comment -->
    <actor>
      <!-- actor 1 name comment -->
      <name>DiCaprio</name>
      <!-- actor 1 firstname comment -->
      <firstname>Leonardo</firstname>
    </actor>
    <!-- actor 2 comment -->
    <actor>
      <!-- actor 2 name comment -->
      <name>Winslet</name>
      <!-- actor 2 firstname comment -->
      <firstname>Kate</firstname>
    </actor>
    <!-- actor 3 comment -->
    <actor>
      <!-- actor 3 name comment -->
      <name>Zane</name>
      <!-- actor 3 firstname comment -->
      <firstname>Billy</firstname>
    </actor>
  </actors>
  <!-- resume comment -->
  <resume>
     Resume of the movie
  </resume>
  <!-- critique 1 comment -->
  <critique>critique1</critique>
  <!-- critique 2 comment -->
  <critique>critique2</critique>
</Movie>
'''
import six
import json
import os.path
from io import StringIO
from unittest import TestCase
from xmltool.testbase import BaseTest
from lxml import etree, html
from xmltool import dtd_parser, factory, render, dtd
from xmltool.elements import (
    EmptyElement,
    escape_attr,
)
from xmltool.factory import (
    get_data_from_str_id_for_html_display,
    _get_data_for_html_display,
)
from xmltool.utils import unflatten_params
from ..test_dtd_parser import (
    MOVIE_DTD,
    MOVIE_XML_TITANIC_COMMENTS,
)
        input_html = generate_html_block(
            obj._get_html_add_button(index=0),
            'dom-input'
        )
        expected_html = generate_html_block(
            obj._get_html_add_button(index=1),
            'dom-expected'
        )
        test_button_html = generate_html_block(
            input_html + expected_html,
            'dom-test',
            ' prefix="%(tn)s:0:" newprefix="%(tn)s:1:"' % {
                'tn': obj._prefix_str,
            }
        )
        return test_html + test_button_html


class TestJavascript(TestCase):

    def test_updatePrefixAttrs(self):
        lis = []
        dtd_str = u'''
            <!ELEMENT texts (text+)>
            <!ELEMENT text (#PCDATA)>
            '''
        xml = b'''<?xml version='1.0' encoding='UTF-8'?>
<texts>
  <text>Tag 1</text>
</texts>
'''
        lis += [generate_javascript_unittest(xml, dtd_str, 'text')]

        dtd_str = u'''
            <!ELEMENT texts (text+)>
            <!ELEMENT text (subtext)>
            <!ELEMENT subtext (#PCDATA)>
            '''
        xml = b'''<?xml version='1.0' encoding='UTF-8'?>
<texts>
  <text>
    <subtext>Hello</subtext>
  </text>
</texts>
'''
        lis += [generate_javascript_unittest(xml, dtd_str, 'text')]

        dtd_str = u'''
        <!ELEMENT texts ((text1|text2)+)>
        <!ELEMENT text1 (#PCDATA)>
        <!ELEMENT text2 (#PCDATA)>
        '''
        xml = b'''<?xml version='1.0' encoding='UTF-8'?>
<texts>
  <text1>Tag 1</text1>
</texts>
'''
        lis += [generate_javascript_unittest(xml, dtd_str, 'list__text1_text2')]

        dtd_str = u'''
        <!ELEMENT texts ((text1|text2)+)>
        <!ELEMENT text1 (subtext)>
        <!ELEMENT text2 (subtext)>
        <!ELEMENT subtext (#PCDATA)>
        '''
        xml = b'''<?xml version='1.0' encoding='UTF-8'?>
<texts>
  <text1>
    <subtext>Tag 1</subtext>
  </text1>
</texts>
'''
        lis += [generate_javascript_unittest(xml, dtd_str, 'list__text1_text2')]

        filename = 'webmedia/js/test/fixtures/updatePrefixAttrs.html'
        document_root = html.fromstring(''.join(lis))
        h = etree.tostring(document_root, encoding='unicode',
                           pretty_print=True)
        open(filename, 'w').write(h)

    def test_jstree_utils(self):
        dtd_str = u'''
            <!ELEMENT texts (text+)>
            <!ELEMENT text (subtext)>
            <!ELEMENT subtext (#PCDATA)>
            '''
        xml = b'''<?xml version='1.0' encoding='UTF-8'?>
<texts>
  <text>
    <subtext>Hello</subtext>
  </text>
</texts>
'''
        root = etree.fromstring(xml)
        dic = dtd.DTD(StringIO(dtd_str)).parse()
        obj = dic[root.tag]()
        obj.load_from_xml(root)

        h = '''<div id="tree"></div><div id="form-container">
        <form id="xmltool-form">%s</form>
        </div>''' % obj.to_html()
        document_root = html.fromstring(h)
        h = etree.tostring(document_root, encoding='unicode',
                           pretty_print=True)
        filename = 'webmedia/js/test/fixtures/jstree_utils.html'
        open(filename, 'w').write(h)

        js = json.dumps(obj.to_jstree_dict())
        filename = 'webmedia/js/test/fixtures/jstree_utils.json'
        open(filename, 'w').write(js)

        text = obj.add('text')
        subtext = text.add('subtext')
        subtext.text = 'World'
        dic = _get_data_for_html_display(text)

        filename = 'webmedia/js/test/fixtures/paste.json'
        open(filename, 'w').write(json.dumps(dic))

        filename = 'webmedia/js/test/fixtures/paste_expected.json'

        dic = _get_data_for_html_display(obj)