def test_read_element(self): stream = Stream( '%angular:ng-repeat.my-class#my-id(class="test")></= Hello \n.next-element' ) element = read_element(stream, Compiler()) self.assertEqual(element.tag, 'angular:ng-repeat') self.assertEqual(element.id, 'my-id') self.assertEqual(element.classes, ['test', 'my-class']) self.assertEqual(dict(element.attributes), {'class': "test"}) self.assertEqual(element.nuke_outer_whitespace, True) self.assertEqual(element.nuke_inner_whitespace, True) self.assertEqual(element.self_close, True) self.assertEqual(element.django_variable, True) self.assertEqual(element.inline_content, "Hello") self.assertEqual(stream.text[stream.ptr:], '.next-element') stream = Stream('%input{required} ') element = read_element(stream, Compiler()) self.assertEqual(element.tag, 'input') self.assertEqual(element.id, None) self.assertEqual(element.classes, []) self.assertEqual(dict(element.attributes), {'required': True}) self.assertEqual(element.nuke_outer_whitespace, False) self.assertEqual(element.nuke_inner_whitespace, False) self.assertEqual(element.self_close, True) # input is implicitly self-closing self.assertEqual(element.django_variable, False) self.assertEqual(element.inline_content, '') self.assertEqual(stream.text[stream.ptr:], '')
def test_read_line(self): stream = Stream('line1\n line2\n\nline4\n\n') assert read_line(stream) == 'line1' assert read_line(stream) == ' line2' assert read_line(stream) == '' assert read_line(stream) == 'line4' assert read_line(stream) == '' assert read_line(stream) is None assert read_line(Stream('last line ')) == 'last line '
def test_quoted_string(self): stream = Stream("'hello'---") assert read_quoted_string(stream) == "hello" assert stream.text[stream.ptr:] == '---' stream = Stream('"this don\'t \\"x\\" hmm" not in string') assert read_quoted_string(stream) == 'this don\'t \"x\" hmm' assert stream.text[stream.ptr:] == ' not in string' self.assertRaises(ParseException, read_quoted_string, Stream('"no end quote...'))
def test_read_filter_node(self): stream = Stream(':python\n print("hello")\n') node = read_filter_node(stream, '', Compiler()) assert node.filter_name == 'python' assert node.content == ' print("hello")' assert stream.text[stream.ptr:] == '' stream = Stream(':javascript\n var i = 0;\n var j = 1;\n%span') node = read_filter_node(stream, '', Compiler()) assert node.filter_name == 'javascript' assert node.content == ' var i = 0;\n var j = 1;' assert stream.text[stream.ptr:] == '%span'
def test_read_number(self): stream = Stream('123"') assert read_number(stream) == '123' assert stream.text[stream.ptr:] == '"' stream = Stream('123.4xx') assert read_number(stream) == '123.4' assert stream.text[stream.ptr:] == 'xx' stream = Stream('0.0001 ') assert read_number(stream) == '0.0001' assert stream.text[stream.ptr:] == ' '
def test_read_word(self): stream = Stream('foo_bar') assert read_word(stream) == 'foo_bar' assert stream.text[stream.ptr:] == '' stream = Stream('foo_bar ') assert read_word(stream) == 'foo_bar' assert stream.text[stream.ptr:] == ' ' stream = Stream('ng-repeat(') assert read_word(stream) == 'ng' assert stream.text[stream.ptr:] == '-repeat(' stream = Stream('ng-repeat(') assert read_word(stream, ('-', )) == 'ng-repeat' assert stream.text[stream.ptr:] == '(' stream = Stream('これはテストです...') assert read_word(stream) == 'これはテストです' assert stream.text[stream.ptr:] == '...'
def test_read_whitespace(self): stream = Stream(' \t foo \n bar ') assert read_whitespace(stream) == ' \t ' assert stream.text[stream.ptr:] == 'foo \n bar ' stream.ptr += 3 # skip over foo assert read_whitespace(stream) == ' ' assert stream.text[stream.ptr:] == '\n bar ' assert read_whitespace(stream, include_newlines=True) == '\n ' assert stream.text[stream.ptr:] == 'bar ' stream.ptr += 3 # skip over bar assert read_whitespace(stream) == ' ' assert stream.text[stream.ptr:] == ''
def process(self, haml): """ Converts the given string of Haml to a regular Django HTML """ stream = Stream(haml) root = Node.create_root(self) node = None while True: node = read_node(stream, prev=node, compiler=self) if not node: break root.add_node(node) if self.options.debug_tree: # pragma: no cover return root.debug_tree() else: return root.render()
def _read_element(text): return read_element(Stream(text), Compiler())
def test_read_tag(self): stream = Stream('angular:ng-repeat(') self.assertEqual(read_tag(stream), 'angular:ng-repeat') self.assertEqual(stream.text[stream.ptr:], '(')
def test_read_ruby_style_attribute_dict(self): # empty dict stream = Stream("{}><") assert dict(read_attribute_dict(stream, Compiler())) == {} assert stream.text[stream.ptr:] == '><' # string values assert dict(self._parse("{'class': 'test'} =Test")) == { 'class': 'test' } assert dict(self._parse("{'class': 'test', 'id': 'something'}")) == { 'class': 'test', 'id': 'something' } # integer values assert dict(self._parse("{'data-number': 0}")) == {'data-number': '0'} assert dict(self._parse("{'data-number': 12345}")) == { 'data-number': '12345' } # float values assert dict(self._parse("{'data-number': 123.456}")) == { 'data-number': '123.456' } assert dict(self._parse("{'data-number': 0.001}")) == { 'data-number': '0.001' } # None value assert dict(self._parse("{'controls': None}")) == {'controls': None} # boolean attributes assert dict( self._parse( "{disabled, class:'test', data-number : 123,\n foo:\"bar\"}") ) == { 'disabled': True, 'class': 'test', 'data-number': '123', 'foo': 'bar' } assert dict( self._parse( "{class:'test', data-number : 123,\n foo:\"bar\", \t disabled}" )) == { 'disabled': True, 'class': 'test', 'data-number': '123', 'foo': 'bar' } # attribute name has colon assert dict(self._parse("{'xml:lang': 'en'}")) == {'xml:lang': 'en'} # attribute value has colon or commas assert dict(self._parse("{'lang': 'en:g'}")) == {'lang': 'en:g'} assert dict( self._parse( '{name:"viewport", content:"width:device-width, initial-scale:1, minimum-scale:1, maximum-scale:1"}' ) ) == { 'name': 'viewport', 'content': 'width:device-width, initial-scale:1, minimum-scale:1, maximum-scale:1' } # double quotes assert dict(self._parse('{"class": "test", "id": "something"}')) == { 'class': 'test', 'id': 'something' } # no quotes for key assert dict(self._parse("{class: 'test', id: 'something'}")) == { 'class': 'test', 'id': 'something' } # whitespace is ignored assert dict( self._parse( "{ class \t : 'test', data-number: 123 }") ) == { 'class': 'test', 'data-number': '123' } # trailing commas are fine assert dict(self._parse("{class: 'test', data-number: 123,}")) == { 'class': 'test', 'data-number': '123' } # attributes split onto multiple lines assert dict( self._parse("{class: 'test',\n data-number: 123}")) == { 'class': 'test', 'data-number': '123' } # old style Ruby assert dict(self._parse("{:class => 'test', :data-number=>123}")) == { 'class': 'test', 'data-number': '123' } # list attribute values assert dict( self._parse( "{'class': [ 'a', 'b', 'c' ], data-list:[1, 2, 3]}")) == { 'class': ['a', 'b', 'c'], 'data-list': ['1', '2', '3'] } # tuple attribute values assert dict( self._parse( "{:class=>( 'a', 'b', 'c' ), :data-list => (1, 2, 3)}")) == { 'class': ['a', 'b', 'c'], 'data-list': ['1', '2', '3'] } # attribute order is maintained assert self._parse( "{'class': 'test', 'id': 'something', foo: 'bar'}") == OrderedDict( [('class', 'test'), ('id', 'something'), ('foo', 'bar')]) # attribute values can be multi-line Haml assert dict( self._parse("""{ 'class': - if forloop.first link-first \x20 - else - if forloop.last link-last 'href': - url 'some_view' }""") ) == { 'class': '{% if forloop.first %} link-first {% else %} {% if forloop.last %} link-last {% endif %} {% endif %}', # noqa 'href': "{% url 'some_view' %}" } # non-ascii attribute values assert dict(self._parse("{class: 'test\u1234'}")) == { 'class': 'test\u1234' }
def _parse(text): return read_attribute_dict(Stream(text), Compiler())
def _read_node(haml): return read_node(Stream(haml), None, Compiler())
def test_read_symbol(self): stream = Stream('=> bar') assert read_symbol(stream, ['=>', ':']) == '=>' assert stream.text[stream.ptr:] == ' bar' self.assertRaises(ParseException, read_symbol, Stream('foo'), ['=>'])
def test_peek_indentation(self): assert peek_indentation(Stream('content')) == 0 assert peek_indentation(Stream(' content')) == 2 assert peek_indentation(Stream('\n')) is None assert peek_indentation(Stream(' \n')) is None