Work at SourceForge, help us to make it a better place! We have an immediate need for a Support Technician in our San Francisco or Denver office.

Close

Commit [21b554] Maximize Restore History

Merge branch 't34_valid_html_css' into 42cc

Yaroslav Luzin Yaroslav Luzin 2012-04-03

1 2 > >> (Page 1 of 2)
removed Allura/allura/lib/ordereddict.py
changed Allura/allura/controllers/auth.py
changed Allura/allura/controllers/project.py
changed Allura/allura/ext/admin/templates/project_admin.html
changed Allura/allura/lib/widgets/forms.py
changed Allura/allura/lib/widgets/project_list.py
changed Allura/allura/lib/custom_middleware.py
changed Allura/allura/lib/gravatar.py
changed Allura/allura/lib/macro.py
changed Allura/allura/lib/security.py
changed Allura/allura/model/neighborhood.py
changed Allura/allura/model/project.py
changed Allura/allura/nf/allura/css/site_style.css
changed Allura/allura/templates/jinja_master/lib.html
changed Allura/allura/templates/jinja_master/master.html
changed Allura/allura/templates/jinja_master/top_nav.html
changed Allura/allura/templates/widgets/repo/revision.html
changed Allura/allura/templates/widgets/project_list_widget.html
changed Allura/allura/templates/widgets/project_summary.html
changed Allura/allura/tests/functional/test_gravatar.py
changed Allura/allura/tests/functional/test_neighborhood.py
changed Allura/allura/tests/model/test_neighborhood.py
changed Allura/allura/tests/unit/patches.py
copied Allura/allura/lib/htmltruncate.py -> Allura/allura/tests/functional/test_wiki_macro.py
Allura/allura/controllers/auth.py Diff Switch to side-by-side view
Loading...
Allura/allura/controllers/project.py Diff Switch to side-by-side view
Loading...
Allura/allura/ext/admin/templates/project_admin.html Diff Switch to side-by-side view
Loading...
Allura/allura/lib/widgets/forms.py Diff Switch to side-by-side view
Loading...
Allura/allura/lib/widgets/project_list.py Diff Switch to side-by-side view
Loading...
Allura/allura/lib/custom_middleware.py Diff Switch to side-by-side view
Loading...
Allura/allura/lib/gravatar.py Diff Switch to side-by-side view
Loading...
Allura/allura/lib/macro.py Diff Switch to side-by-side view
Loading...
Allura/allura/lib/security.py Diff Switch to side-by-side view
Loading...
Allura/allura/model/neighborhood.py Diff Switch to side-by-side view
Loading...
Allura/allura/model/project.py Diff Switch to side-by-side view
Loading...
Allura/allura/nf/allura/css/site_style.css Diff Switch to side-by-side view
Loading...
Allura/allura/templates/jinja_master/lib.html Diff Switch to side-by-side view
Loading...
Allura/allura/templates/jinja_master/master.html Diff Switch to side-by-side view
Loading...
Allura/allura/templates/jinja_master/top_nav.html Diff Switch to side-by-side view
Loading...
Allura/allura/templates/widgets/repo/revision.html Diff Switch to side-by-side view
Loading...
Allura/allura/templates/widgets/project_list_widget.html Diff Switch to side-by-side view
Loading...
Allura/allura/templates/widgets/project_summary.html Diff Switch to side-by-side view
Loading...
Allura/allura/tests/functional/test_gravatar.py Diff Switch to side-by-side view
Loading...
Allura/allura/tests/functional/test_neighborhood.py Diff Switch to side-by-side view
Loading...
Allura/allura/tests/model/test_neighborhood.py Diff Switch to side-by-side view
Loading...
Allura/allura/tests/unit/patches.py Diff Switch to side-by-side view
Loading...
Allura/allura/lib/htmltruncate.py to Allura/allura/tests/functional/test_wiki_macro.py
--- a/Allura/allura/lib/htmltruncate.py
+++ b/Allura/allura/tests/functional/test_wiki_macro.py
@@ -1,134 +1,113 @@
-#!/usr/bin/env python
+from allura import model as M
+from allura.tests import TestController
+from allura.tests import decorators as td
 
-# Code pulled from https://github.com/eentzel/htmltruncate.py
+class TestNeighborhood(TestController):
 
-import sys
+    @staticmethod
+    def get_project_names(r):
+        """
+        Extracts a list of project names from a wiki page HTML.
+        """
+        # projects short names are in h2 elements without any attributes
+        # there is one more h2 element, but it has `class` attribute
+        return [e.text for e in r.html.findAll('h2') if not e.attrs]
 
+    @staticmethod
+    def get_projects_property_in_the_same_order(names, prop):
+        """
+        Returns a list of projects properties `prop` in the same order as
+        project `names`.
+        It is required because results of the query are not in the same order as names.
+        """
+        projects = M.Project.query.find(dict(name={'$in': names})).all()
+        projects_dict = dict([(p['name'],p[prop]) for p in projects])
+        return [projects_dict[name] for name in names]
 
-END = -1
+    @td.with_wiki
+    def test_sort_alpha(self):
+        r = self.app.post('/p/wiki/Home/update',
+                          params={
+                                  'title': 'Home',
+                                  'text': '[[projects sort=alpha]]'
+                                  },
+                          extra_environ=dict(username='root'), upload_files=[]).follow()
+        project_list = self.get_project_names(r)
+        assert project_list == sorted(project_list)
+    
+    @td.with_wiki
+    def test_sort_registered(self):
+        r = self.app.post('/p/wiki/Home/update',
+                          params={
+                                  'title': 'Home',
+                                  'text': '[[projects sort=last_registred]]'
+                                  },
+                          extra_environ=dict(username='root'), upload_files=[]).follow()
+        project_names = self.get_project_names(r)
+        ids = self.get_projects_property_in_the_same_order(project_names, '_id')
+        assert ids == sorted(ids, reverse=True)
 
-class UnbalancedError(Exception):
-    pass
+    @td.with_wiki
+    def test_sort_updated(self):
+        r = self.app.post('/p/wiki/Home/update',
+                          params={
+                                  'title': 'Home',
+                                  'text': '[[projects sort=last_updated]]'
+                                  },
+                          extra_environ=dict(username='root'), upload_files=[]).follow()
+        project_names = self.get_project_names(r)
+        updated_at = self.get_projects_property_in_the_same_order(project_names, 'last_updated') 
+        assert updated_at == sorted(updated_at, reverse=True)
 
-class OpenTag:
-    def __init__(self, tag, rest=''):
-        self.tag = tag
-        self.rest = rest
+    @td.with_wiki
+    def test_projects_makro(self):
+        # test columns
+        two_column_style = 'width: 330px;'
+        r = self.app.post('/p/wiki/Home/update',
+                          params={
+                                  'title': 'Home',
+                                  'text': '[[projects display_mode=list columns=2]]'
+                                  },
+                          extra_environ=dict(username='root'), upload_files=[]).follow()
+        assert two_column_style in r
 
-    def as_string(self):
-        return '<' + self.tag + self.rest + '>'
-        
-class CloseTag(OpenTag):
-    def as_string(self):
-        return '</' + self.tag + '>'
+        r = self.app.post('/p/wiki/Home/update',
+                          params={
+                                  'title': 'Home',
+                                  'text': '[[projects display_mode=list columns=3]]'
+                                  },
+                          extra_environ=dict(username='root'), upload_files=[]).follow()
+        assert two_column_style not in r
 
-class SelfClosingTag(OpenTag):
-    pass
-    
-class Tokenizer:
-    def __init__(self, input):
-        self.input = input
-        self.counter = 0  # points at the next unconsumed character of the input
+        # test project icon
+        r = self.app.post('/p/wiki/Home/update',
+                          params={
+                                  'title': 'Home',
+                                  'text': '[[projects display_mode=list show_proj_icon=on]]'
+                                  },
+                          extra_environ=dict(username='root'), upload_files=[]).follow()
+        assert 'test Logo' in r
+        r = self.app.post('/p/wiki/Home/update',
+                          params={
+                                  'title': 'Home',
+                                  'text': '[[projects display_mode=list show_proj_icon=off]]'
+                                  },
+                          extra_environ=dict(username='root'), upload_files=[]).follow()
+        assert 'test Logo' not in r
 
-    def __next_char(self):
-        self.counter += 1
-        return self.input[self.counter]
-        
-    def next_token(self):
-        try:
-            char = self.input[self.counter]
-            self.counter += 1
-            if char == '&':
-                return self.__entity()
-            elif char != '<':
-                return char
-            elif self.input[self.counter] == '/':
-                self.counter += 1
-                return self.__close_tag()
-            else:
-                return self.__open_tag()
-        except IndexError:
-            return END
+        # test project download button
+        r = self.app.post('/p/wiki/Home/update',
+                          params={
+                                  'title': 'Home',
+                                  'text': '[[projects display_mode=list show_download_button=on]]'
+                                  },
+                          extra_environ=dict(username='root'), upload_files=[]).follow()
+        assert 'download-button' in r
 
-    def __entity(self):
-        """Return a token representing an HTML character entity.
-        Precondition: self.counter points at the charcter after the &
-        Postcondition: self.counter points at the character after the ;
-        """
-        char = self.input[self.counter]
-        entity = ['&']
-        while char != ';':
-            entity.append(char)
-            char = self.__next_char()
-        entity.append(';')
-        self.counter += 1
-        return ''.join(entity)
-        
-    def __open_tag(self):
-        """Return an open/close tag token.
-        Precondition: self.counter points at the first character of the tag name
-        Postcondition: self.counter points at the character after the <tag>
-        """
-        char = self.input[self.counter]
-        tag = []
-        rest = []
-        while char != '>' and char != ' ':
-            tag.append(char)
-            char = self.__next_char()
-        while char != '>':
-            rest.append(char)
-            char = self.__next_char()
-        if self.input[self.counter - 1] == '/':
-            self.counter += 1
-            return SelfClosingTag( ''.join(tag), ''.join(rest) )
-        else:
-            self.counter += 1
-            return OpenTag( ''.join(tag), ''.join(rest) )
-
-    def __close_tag(self):
-        """Return an open/close tag token.
-        Precondition: self.counter points at the first character of the tag name
-        Postcondition: self.counter points at the character after the <tag>
-        """
-        char = self.input[self.counter]
-        tag = []
-        while char != '>':
-            tag.append(char)
-            char = self.__next_char()
-        self.counter += 1
-        return CloseTag( ''.join(tag) )
-
-def truncate(str, target_len, ellipsis = ''):
-    """Returns a copy of str truncated to target_len characters,
-    preserving HTML markup (which does not count towards the length).
-    Any tags that would be left open by truncation will be closed at
-    the end of the returned string.  Optionally append ellipsis if
-    the string was truncated."""
-    stack = []   # open tags are pushed on here, then popped when the matching close tag is found
-    retval = []  # string to be returned
-    length = 0   # number of characters (not counting markup) placed in retval so far
-    tokens = Tokenizer(str)
-    tok = tokens.next_token()
-    while tok != END and length < target_len:
-        if tok.__class__.__name__ == 'OpenTag':
-            stack.append(tok)
-            retval.append( tok.as_string() )
-        elif tok.__class__.__name__ == 'CloseTag':
-            if stack[-1].tag == tok.tag:
-                stack.pop()
-                retval.append( tok.as_string() )
-            else:
-                raise UnbalancedError( tok.as_string() )
-        elif tok.__class__.__name__ == 'SelfClosingTag':
-            retval.append( tok.as_string() )
-        else:
-            retval.append(tok)
-            length += 1
-        tok = tokens.next_token()
-    while len(stack) > 0:
-        tok = CloseTag( stack.pop().tag )
-        retval.append( tok.as_string() )
-    if length == target_len:
-        return ''.join(retval) + ellipsis
-    else:
-        return ''.join(retval)+        r = self.app.post('/p/wiki/Home/update',
+                          params={
+                                  'title': 'Home',
+                                  'text': '[[projects display_mode=list show_download_button=off]]'
+                                  },
+                          extra_environ=dict(username='root'), upload_files=[]).follow()
+        assert 'download-button' not in r
1 2 > >> (Page 1 of 2)