cubicweb/test/unittest_utils.py
changeset 11057 0b59724cb3f2
parent 10933 830f1ea52789
child 11078 de4367ef4e5e
equal deleted inserted replaced
11052:058bb3dc685f 11057:0b59724cb3f2
       
     1 # copyright 2003-2014 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
       
     2 # contact http://www.logilab.fr/ -- mailto:contact@logilab.fr
       
     3 #
       
     4 # This file is part of CubicWeb.
       
     5 #
       
     6 # CubicWeb is free software: you can redistribute it and/or modify it under the
       
     7 # terms of the GNU Lesser General Public License as published by the Free
       
     8 # Software Foundation, either version 2.1 of the License, or (at your option)
       
     9 # any later version.
       
    10 #
       
    11 # CubicWeb is distributed in the hope that it will be useful, but WITHOUT
       
    12 # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
       
    13 # FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more
       
    14 # details.
       
    15 #
       
    16 # You should have received a copy of the GNU Lesser General Public License along
       
    17 # with CubicWeb.  If not, see <http://www.gnu.org/licenses/>.
       
    18 """unit tests for module cubicweb.utils"""
       
    19 
       
    20 import re
       
    21 import decimal
       
    22 import datetime
       
    23 
       
    24 from six.moves import range
       
    25 
       
    26 from logilab.common.testlib import TestCase, DocTest, unittest_main
       
    27 
       
    28 from cubicweb.devtools.testlib import CubicWebTC
       
    29 from cubicweb.utils import (make_uid, UStringIO, RepeatList, HTMLHead,
       
    30                             QueryCache, parse_repo_uri)
       
    31 from cubicweb.entity import Entity
       
    32 
       
    33 try:
       
    34     from cubicweb.utils import CubicWebJsonEncoder, json
       
    35 except ImportError:
       
    36     json = None
       
    37 
       
    38 class MakeUidTC(TestCase):
       
    39     def test_1(self):
       
    40         self.assertNotEqual(make_uid('xyz'), make_uid('abcd'))
       
    41         self.assertNotEqual(make_uid('xyz'), make_uid('xyz'))
       
    42 
       
    43     def test_2(self):
       
    44         d = set()
       
    45         while len(d)<10000:
       
    46             uid = make_uid('xyz')
       
    47             if uid in d:
       
    48                 self.fail(len(d))
       
    49             if re.match('\d', uid):
       
    50                 self.fail('make_uid must not return something begining with '
       
    51                           'some numeric character, got %s' % uid)
       
    52             d.add(uid)
       
    53 
       
    54 
       
    55 class TestParseRepoUri(TestCase):
       
    56 
       
    57     def test_parse_repo_uri(self):
       
    58         self.assertEqual(('inmemory', None, 'myapp'),
       
    59                          parse_repo_uri('myapp'))
       
    60         self.assertEqual(('inmemory', None, 'myapp'),
       
    61                          parse_repo_uri('inmemory://myapp'))
       
    62         with self.assertRaises(NotImplementedError):
       
    63             parse_repo_uri('foo://bar')
       
    64 
       
    65 
       
    66 
       
    67 class TestQueryCache(TestCase):
       
    68     def test_querycache(self):
       
    69         c = QueryCache(ceiling=20)
       
    70         # write only
       
    71         for x in range(10):
       
    72             c[x] = x
       
    73         self.assertEqual(c._usage_report(),
       
    74                          {'transientcount': 0,
       
    75                           'itemcount': 10,
       
    76                           'permanentcount': 0})
       
    77         c = QueryCache(ceiling=10)
       
    78         # we should also get a warning
       
    79         for x in range(20):
       
    80             c[x] = x
       
    81         self.assertEqual(c._usage_report(),
       
    82                          {'transientcount': 0,
       
    83                           'itemcount': 10,
       
    84                           'permanentcount': 0})
       
    85         # write + reads
       
    86         c = QueryCache(ceiling=20)
       
    87         for n in range(4):
       
    88             for x in range(10):
       
    89                 c[x] = x
       
    90                 c[x]
       
    91         self.assertEqual(c._usage_report(),
       
    92                          {'transientcount': 10,
       
    93                           'itemcount': 10,
       
    94                           'permanentcount': 0})
       
    95         c = QueryCache(ceiling=20)
       
    96         for n in range(17):
       
    97             for x in range(10):
       
    98                 c[x] = x
       
    99                 c[x]
       
   100         self.assertEqual(c._usage_report(),
       
   101                          {'transientcount': 0,
       
   102                           'itemcount': 10,
       
   103                           'permanentcount': 10})
       
   104         c = QueryCache(ceiling=20)
       
   105         for n in range(17):
       
   106             for x in range(10):
       
   107                 c[x] = x
       
   108                 if n % 2:
       
   109                     c[x]
       
   110                 if x % 2:
       
   111                     c[x]
       
   112         self.assertEqual(c._usage_report(),
       
   113                          {'transientcount': 5,
       
   114                           'itemcount': 10,
       
   115                           'permanentcount': 5})
       
   116 
       
   117 class UStringIOTC(TestCase):
       
   118     def test_boolean_value(self):
       
   119         self.assertTrue(UStringIO())
       
   120 
       
   121 
       
   122 class RepeatListTC(TestCase):
       
   123 
       
   124     def test_base(self):
       
   125         l = RepeatList(3, (1, 3))
       
   126         self.assertEqual(l[0], (1, 3))
       
   127         self.assertEqual(l[2], (1, 3))
       
   128         self.assertEqual(l[-1], (1, 3))
       
   129         self.assertEqual(len(l), 3)
       
   130         # XXX
       
   131         self.assertEqual(l[4], (1, 3))
       
   132 
       
   133         self.assertFalse(RepeatList(0, None))
       
   134 
       
   135     def test_slice(self):
       
   136         l = RepeatList(3, (1, 3))
       
   137         self.assertEqual(l[0:1], [(1, 3)])
       
   138         self.assertEqual(l[0:4], [(1, 3)]*3)
       
   139         self.assertEqual(l[:], [(1, 3)]*3)
       
   140 
       
   141     def test_iter(self):
       
   142         self.assertEqual(list(RepeatList(3, (1, 3))),
       
   143                           [(1, 3)]*3)
       
   144 
       
   145     def test_add(self):
       
   146         l = RepeatList(3, (1, 3))
       
   147         self.assertEqual(l + [(1, 4)], [(1, 3)]*3  + [(1, 4)])
       
   148         self.assertEqual([(1, 4)] + l, [(1, 4)] + [(1, 3)]*3)
       
   149         self.assertEqual(l + RepeatList(2, (2, 3)), [(1, 3)]*3 + [(2, 3)]*2)
       
   150 
       
   151         x = l + RepeatList(2, (1, 3))
       
   152         self.assertIsInstance(x, RepeatList)
       
   153         self.assertEqual(len(x), 5)
       
   154         self.assertEqual(x[0], (1, 3))
       
   155 
       
   156         x = l + [(1, 3)] * 2
       
   157         self.assertEqual(x, [(1, 3)] * 5)
       
   158 
       
   159     def test_eq(self):
       
   160         self.assertEqual(RepeatList(3, (1, 3)),
       
   161                           [(1, 3)]*3)
       
   162 
       
   163     def test_pop(self):
       
   164         l = RepeatList(3, (1, 3))
       
   165         l.pop(2)
       
   166         self.assertEqual(l, [(1, 3)]*2)
       
   167 
       
   168 
       
   169 class JSONEncoderTC(TestCase):
       
   170     def setUp(self):
       
   171         if json is None:
       
   172             self.skipTest('json not available')
       
   173 
       
   174     def encode(self, value):
       
   175         return json.dumps(value, cls=CubicWebJsonEncoder)
       
   176 
       
   177     def test_encoding_dates(self):
       
   178         self.assertEqual(self.encode(datetime.datetime(2009, 9, 9, 20, 30)),
       
   179                           '"2009/09/09 20:30:00"')
       
   180         self.assertEqual(self.encode(datetime.date(2009, 9, 9)),
       
   181                           '"2009/09/09"')
       
   182         self.assertEqual(self.encode(datetime.time(20, 30)),
       
   183                           '"20:30:00"')
       
   184 
       
   185     def test_encoding_decimal(self):
       
   186         self.assertEqual(self.encode(decimal.Decimal('1.2')), '1.2')
       
   187 
       
   188     def test_encoding_bare_entity(self):
       
   189         e = Entity(None)
       
   190         e.cw_attr_cache['pouet'] = 'hop'
       
   191         e.eid = 2
       
   192         self.assertEqual(json.loads(self.encode(e)),
       
   193                           {'pouet': 'hop', 'eid': 2})
       
   194 
       
   195     def test_encoding_entity_in_list(self):
       
   196         e = Entity(None)
       
   197         e.cw_attr_cache['pouet'] = 'hop'
       
   198         e.eid = 2
       
   199         self.assertEqual(json.loads(self.encode([e])),
       
   200                           [{'pouet': 'hop', 'eid': 2}])
       
   201 
       
   202     def test_encoding_unknown_stuff(self):
       
   203         self.assertEqual(self.encode(TestCase), 'null')
       
   204 
       
   205 class HTMLHeadTC(CubicWebTC):
       
   206 
       
   207     def htmlhead(self, datadir_url):
       
   208         with self.admin_access.web_request() as req:
       
   209             base_url = u'http://test.fr/data/'
       
   210             req.datadir_url = base_url
       
   211             head = HTMLHead(req)
       
   212             return head
       
   213 
       
   214     def test_concat_urls(self):
       
   215         base_url = u'http://test.fr/data/'
       
   216         head = self.htmlhead(base_url)
       
   217         urls = [base_url + u'bob1.js',
       
   218                 base_url + u'bob2.js',
       
   219                 base_url + u'bob3.js']
       
   220         result = head.concat_urls(urls)
       
   221         expected = u'http://test.fr/data/??bob1.js,bob2.js,bob3.js'
       
   222         self.assertEqual(result, expected)
       
   223 
       
   224     def test_group_urls(self):
       
   225         base_url = u'http://test.fr/data/'
       
   226         head = self.htmlhead(base_url)
       
   227         urls_spec = [(base_url + u'bob0.js', None),
       
   228                      (base_url + u'bob1.js', None),
       
   229                      (u'http://ext.com/bob2.js', None),
       
   230                      (u'http://ext.com/bob3.js', None),
       
   231                      (base_url + u'bob4.css', 'all'),
       
   232                      (base_url + u'bob5.css', 'all'),
       
   233                      (base_url + u'bob6.css', 'print'),
       
   234                      (base_url + u'bob7.css', 'print'),
       
   235                      (base_url + u'bob8.css', ('all', u'[if IE 8]')),
       
   236                      (base_url + u'bob9.css', ('print', u'[if IE 8]'))
       
   237                      ]
       
   238         result = head.group_urls(urls_spec)
       
   239         expected = [(base_url + u'??bob0.js,bob1.js', None),
       
   240                     (u'http://ext.com/bob2.js', None),
       
   241                     (u'http://ext.com/bob3.js', None),
       
   242                     (base_url + u'??bob4.css,bob5.css', 'all'),
       
   243                     (base_url + u'??bob6.css,bob7.css', 'print'),
       
   244                     (base_url + u'bob8.css', ('all', u'[if IE 8]')),
       
   245                     (base_url + u'bob9.css', ('print', u'[if IE 8]'))
       
   246                     ]
       
   247         self.assertEqual(list(result), expected)
       
   248 
       
   249     def test_getvalue_with_concat(self):
       
   250         self.config.global_set_option('concat-resources', True)
       
   251         base_url = u'http://test.fr/data/'
       
   252         head = self.htmlhead(base_url)
       
   253         head.add_js(base_url + u'bob0.js')
       
   254         head.add_js(base_url + u'bob1.js')
       
   255         head.add_js(u'http://ext.com/bob2.js')
       
   256         head.add_js(u'http://ext.com/bob3.js')
       
   257         head.add_css(base_url + u'bob4.css')
       
   258         head.add_css(base_url + u'bob5.css')
       
   259         head.add_css(base_url + u'bob6.css', 'print')
       
   260         head.add_css(base_url + u'bob7.css', 'print')
       
   261         head.add_ie_css(base_url + u'bob8.css')
       
   262         head.add_ie_css(base_url + u'bob9.css', 'print', u'[if lt IE 7]')
       
   263         result = head.getvalue()
       
   264         expected = u"""<head>
       
   265 <link rel="stylesheet" type="text/css" media="all" href="http://test.fr/data/??bob4.css,bob5.css"/>
       
   266 <link rel="stylesheet" type="text/css" media="print" href="http://test.fr/data/??bob6.css,bob7.css"/>
       
   267 <!--[if lt IE 8]>
       
   268 <link rel="stylesheet" type="text/css" media="all" href="http://test.fr/data/bob8.css"/>
       
   269 <!--[if lt IE 7]>
       
   270 <link rel="stylesheet" type="text/css" media="print" href="http://test.fr/data/bob9.css"/>
       
   271 <![endif]--> 
       
   272 <script type="text/javascript" src="http://test.fr/data/??bob0.js,bob1.js"></script>
       
   273 <script type="text/javascript" src="http://ext.com/bob2.js"></script>
       
   274 <script type="text/javascript" src="http://ext.com/bob3.js"></script>
       
   275 </head>
       
   276 """
       
   277         self.assertEqual(result, expected)
       
   278 
       
   279     def test_getvalue_without_concat(self):
       
   280         self.config.global_set_option('concat-resources', False)
       
   281         try:
       
   282             base_url = u'http://test.fr/data/'
       
   283             head = self.htmlhead(base_url)
       
   284             head.add_js(base_url + u'bob0.js')
       
   285             head.add_js(base_url + u'bob1.js')
       
   286             head.add_js(u'http://ext.com/bob2.js')
       
   287             head.add_js(u'http://ext.com/bob3.js')
       
   288             head.add_css(base_url + u'bob4.css')
       
   289             head.add_css(base_url + u'bob5.css')
       
   290             head.add_css(base_url + u'bob6.css', 'print')
       
   291             head.add_css(base_url + u'bob7.css', 'print')
       
   292             head.add_ie_css(base_url + u'bob8.css')
       
   293             head.add_ie_css(base_url + u'bob9.css', 'print', u'[if lt IE 7]')
       
   294             result = head.getvalue()
       
   295             expected = u"""<head>
       
   296 <link rel="stylesheet" type="text/css" media="all" href="http://test.fr/data/bob4.css"/>
       
   297 <link rel="stylesheet" type="text/css" media="all" href="http://test.fr/data/bob5.css"/>
       
   298 <link rel="stylesheet" type="text/css" media="print" href="http://test.fr/data/bob6.css"/>
       
   299 <link rel="stylesheet" type="text/css" media="print" href="http://test.fr/data/bob7.css"/>
       
   300 <!--[if lt IE 8]>
       
   301 <link rel="stylesheet" type="text/css" media="all" href="http://test.fr/data/bob8.css"/>
       
   302 <!--[if lt IE 7]>
       
   303 <link rel="stylesheet" type="text/css" media="print" href="http://test.fr/data/bob9.css"/>
       
   304 <![endif]--> 
       
   305 <script type="text/javascript" src="http://test.fr/data/bob0.js"></script>
       
   306 <script type="text/javascript" src="http://test.fr/data/bob1.js"></script>
       
   307 <script type="text/javascript" src="http://ext.com/bob2.js"></script>
       
   308 <script type="text/javascript" src="http://ext.com/bob3.js"></script>
       
   309 </head>
       
   310 """
       
   311             self.assertEqual(result, expected)
       
   312         finally:
       
   313             self.config.global_set_option('concat-resources', True)
       
   314 
       
   315 class DocTest(DocTest):
       
   316     from cubicweb import utils as module
       
   317 
       
   318 if __name__ == '__main__':
       
   319     unittest_main()