# Path: crmsh/parse.py
# def parse(self, cmd):
#     "Called by do_parse(). Raises ParseError if parsing fails."
#     raise NotImplementedError
# 
# Path: crmsh/utils.py
# def lines2cli(s):
#     '''
#     Convert a string into a list of lines. Replace continuation
#     characters. Strip white space, left and right. Drop empty lines.
#     '''
#     cl = []
#     l = s.split('\n')
#     cum = []
#     for p in l:
#         p = p.strip()
#         if p.endswith('\\'):
#             p = p.rstrip('\\')
#             cum.append(p)
#         else:
#             cum.append(p)
#             cl.append(''.join(cum).strip())
#             cum = []
#     if cum:  # in case s ends with backslash
#         cl.append(''.join(cum))
#     return [x for x in cl if x]
# 
# Path: crmsh/xmlutil.py
# def xml_tostring(*args, **kwargs):
#     """
#     Python 2/3 conversion utility:
#     etree.tostring returns a bytestring, but
#     we need actual Python strings.
#     """
#     return etree.tostring(*args, **kwargs).decode('utf-8')


    from unittest import mock
from builtins import zip
from crmsh import parse
from crmsh.utils import lines2cli
from crmsh.xmlutil import xml_tostring
from lxml import etree
    import mock
import unittest
import shlex
        out = self._parse('alert alert1 /tmp/foo.sh to /tmp/bar.log')
        self.assertEqual(out.get('id'), 'alert1')
        self.assertEqual(['/tmp/foo.sh'],
                         out.xpath('/alert/@path'))
        self.assertEqual(['/tmp/bar.log'],
                         out.xpath('/alert/recipient/@value'))

    def test_alerts_brackets(self):
        "Test alerts w/ brackets (1.1.15+)"
        out = self._parse('alert alert2 /tmp/foo.sh to { /tmp/bar.log meta timeout=10s }')
        self.assertEqual(out.get('id'), 'alert2')
        self.assertEqual(['/tmp/foo.sh'],
                         out.xpath('/alert/@path'))
        self.assertEqual(['/tmp/bar.log'],
                         out.xpath('/alert/recipient/@value'))
        self.assertEqual(['10s'],
                         out.xpath('/alert/recipient/meta_attributes/nvpair[@name="timeout"]/@value'))

    def test_alerts_selectors(self):
        "Test alerts w/ selectors (1.1.17+)"
        out = self._parse('alert alert3 /tmp/foo.sh select nodes fencing attributes { standby shutdown } to { /tmp/bar.log meta timeout=10s }')
        self.assertEqual(out.get('id'), 'alert3')
        self.assertEqual(1, len(out.xpath('/alert/select/select_nodes')))
        self.assertEqual(1, len(out.xpath('/alert/select/select_fencing')))
        self.assertEqual(['standby', 'shutdown'],
                         out.xpath('/alert/select/select_attributes/attribute/@name'))


    def _parse_lines(self, lines):
        out = []

# Path: crmsh/parse.py
# def parse(self, cmd):
#     "Called by do_parse(). Raises ParseError if parsing fails."
#     raise NotImplementedError
# 
# Path: crmsh/utils.py
# def lines2cli(s):
#     '''
#     Convert a string into a list of lines. Replace continuation
#     characters. Strip white space, left and right. Drop empty lines.
#     '''
#     cl = []
#     l = s.split('\n')
#     cum = []
#     for p in l:
#         p = p.strip()
#         if p.endswith('\\'):
#             p = p.rstrip('\\')
#             cum.append(p)
#         else:
#             cum.append(p)
#             cl.append(''.join(cum).strip())
#             cum = []
#     if cum:  # in case s ends with backslash
#         cl.append(''.join(cum))
#     return [x for x in cl if x]
# 
# Path: crmsh/xmlutil.py
# def xml_tostring(*args, **kwargs):
#     """
#     Python 2/3 conversion utility:
#     etree.tostring returns a bytestring, but
#     we need actual Python strings.
#     """
#     return etree.tostring(*args, **kwargs).decode('utf-8')


# Path: test/unittests/test_parse.py
    from unittest import mock
from builtins import zip
from crmsh import parse
from crmsh.utils import lines2cli
from crmsh.xmlutil import xml_tostring
from lxml import etree
    import mock
import unittest
import shlex

        out = self._parse('alert alert1 /tmp/foo.sh to /tmp/bar.log')
        self.assertEqual(out.get('id'), 'alert1')
        self.assertEqual(['/tmp/foo.sh'],
                         out.xpath('/alert/@path'))
        self.assertEqual(['/tmp/bar.log'],
                         out.xpath('/alert/recipient/@value'))

    def test_alerts_brackets(self):
        "Test alerts w/ brackets (1.1.15+)"
        out = self._parse('alert alert2 /tmp/foo.sh to { /tmp/bar.log meta timeout=10s }')
        self.assertEqual(out.get('id'), 'alert2')
        self.assertEqual(['/tmp/foo.sh'],
                         out.xpath('/alert/@path'))
        self.assertEqual(['/tmp/bar.log'],
                         out.xpath('/alert/recipient/@value'))
        self.assertEqual(['10s'],
                         out.xpath('/alert/recipient/meta_attributes/nvpair[@name="timeout"]/@value'))

    def test_alerts_selectors(self):
        "Test alerts w/ selectors (1.1.17+)"
        out = self._parse('alert alert3 /tmp/foo.sh select nodes fencing attributes { standby shutdown } to { /tmp/bar.log meta timeout=10s }')
        self.assertEqual(out.get('id'), 'alert3')
        self.assertEqual(1, len(out.xpath('/alert/select/select_nodes')))
        self.assertEqual(1, len(out.xpath('/alert/select/select_fencing')))
        self.assertEqual(['standby', 'shutdown'],
                         out.xpath('/alert/select/select_attributes/attribute/@name'))


    def _parse_lines(self, lines):
        out = []

        for line in lines2cli(lines):