CIDict, our case-insensitive dictionary, inherits from dict but did not
reimplement the full dict interface. Calling the missing methods
silently invoked case-sensitive behavior. Our code seems to avoid that,
but it's a bit of a minefield for new development.
Patch 119 adds the missing dict methods (except
view{items,keys,values}(), which now raise errors), and adds tests.
Patches 117-118 modernize the testsuite a bit (these have been sitting
in my queue for a while, I think now is a good time to submit them):
The first one moves some old tests from the main code tree to tests/.
(The adtrust_install test wasn't run before, this move makes nose notice
it).
The second converts CIDict's unittest-based suite to nose.
--
Petr³
From 7ea2a0abd92f6337e70c96599fb9a0118672921b Mon Sep 17 00:00:00 2001
From: Petr Viktorin <[email protected]>
Date: Fri, 20 Apr 2012 07:03:16 -0400
Subject: [PATCH] Move tests to test directories
Nose doesn't pick up directories that don't begin with 'test'.
Rename tests/test_ipaserver/install to test_install so that it's run.
Also, merge test_ipautil.py from ipapython/test into tests/test_ipapython,
so the whole test suite is in one place.
---
.../test => tests/test_ipapython}/test_ipautil.py | 64 ++++++++++++++++----
.../test_ipapython}/test_ipavalidate.py | 0
.../test_adtrustinstance.py | 0
3 files changed, 52 insertions(+), 12 deletions(-)
rename {ipapython/test => tests/test_ipapython}/test_ipautil.py (87%)
rename {ipapython/test => tests/test_ipapython}/test_ipavalidate.py (100%)
rename tests/test_ipaserver/{install => test_install}/test_adtrustinstance.py (100%)
diff --git a/ipapython/test/test_ipautil.py b/tests/test_ipapython/test_ipautil.py
similarity index 87%
rename from ipapython/test/test_ipautil.py
rename to tests/test_ipapython/test_ipautil.py
index ff9f282340c7900e51ecbf2abec912beb3f1f340..6783bd974ffe72a8ed191774aca6d2b2452036c7 100644
--- a/ipapython/test/test_ipautil.py
+++ b/tests/test_ipapython/test_ipautil.py
@@ -1,30 +1,74 @@
-#! /usr/bin/python -E
+# Authors:
+# Jan Cholasta <[email protected]>
#
-# Copyright (C) 2007 Red Hat
+# Copyright (C) 2011 Red Hat
# see file 'COPYING' for use and warranty information
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
-#
-
-import sys
-sys.path.insert(0, ".")
+"""
+Test the `ipapython/ipautil.py` module.
+"""
+import nose
import unittest
-import datetime
from ipapython import ipautil
+class CheckIPAddress:
+ def __init__(self, addr):
+ self.description = "Test IP address parsing and verification (%s)" % addr
+
+ def __call__(self, addr, words=None, prefixlen=None):
+ try:
+ ip = ipautil.CheckedIPAddress(addr, match_local=False)
+ assert ip.words == words and ip.prefixlen == prefixlen
+ except:
+ assert words is None and prefixlen is None
+
+def test_ip_address():
+ addrs = [
+ ('10.11.12.13', (10, 11, 12, 13), 8),
+ ('10.11.12.13/14', (10, 11, 12, 13), 14),
+ ('10.11.12.13%zoneid',),
+ ('10.11.12.13%zoneid/14',),
+ ('10.11.12.1337',),
+ ('10.11.12.13/33',),
+ ('127.0.0.1',),
+ ('241.1.2.3',),
+ ('169.254.1.2',),
+ ('10.11.12.0/24',),
+ ('224.5.6.7',),
+ ('10.11.12.255/24',),
+
+ ('2001::1', (0x2001, 0, 0, 0, 0, 0, 0, 1), 64),
+ ('2001::1/72', (0x2001, 0, 0, 0, 0, 0, 0, 1), 72),
+ ('2001::1%zoneid', (0x2001, 0, 0, 0, 0, 0, 0, 1), 64),
+ ('2001::1%zoneid/72',),
+ ('2001::1beef',),
+ ('2001::1/129',),
+ ('::1',),
+ ('6789::1',),
+ ('fe89::1',),
+ ('2001::/64',),
+ ('ff01::1',),
+
+ ('junk',)
+ ]
+
+ for addr in addrs:
+ yield (CheckIPAddress(addr[0]),) + addr
+
class TestCIDict(unittest.TestCase):
def setUp(self):
@@ -303,7 +347,3 @@ class TestTimeParser(unittest.TestCase):
self.assertEqual(-30, time.tzinfo.minoffset)
offset = time.tzinfo.utcoffset(time.tzinfo.dst())
self.assertEqual(((24 - 9) * 60 * 60) - (30 * 60), offset.seconds)
-
-
-if __name__ == '__main__':
- unittest.main()
diff --git a/ipapython/test/test_ipavalidate.py b/tests/test_ipapython/test_ipavalidate.py
similarity index 100%
rename from ipapython/test/test_ipavalidate.py
rename to tests/test_ipapython/test_ipavalidate.py
diff --git a/tests/test_ipaserver/install/test_adtrustinstance.py b/tests/test_ipaserver/test_install/test_adtrustinstance.py
similarity index 100%
rename from tests/test_ipaserver/install/test_adtrustinstance.py
rename to tests/test_ipaserver/test_install/test_adtrustinstance.py
--
1.7.7.6
From 070196ba607b2a88cbd3736f7cba4682fe916459 Mon Sep 17 00:00:00 2001
From: Petr Viktorin <[email protected]>
Date: Fri, 15 Jun 2012 05:17:49 -0400
Subject: [PATCH] Convert test_ipautil from unittest to nose
---
tests/test_ipapython/test_ipautil.py | 312 ++++++++++++++++------------------
1 files changed, 148 insertions(+), 164 deletions(-)
diff --git a/tests/test_ipapython/test_ipautil.py b/tests/test_ipapython/test_ipautil.py
index 6783bd974ffe72a8ed191774aca6d2b2452036c7..95933581f2f83f61008493079ba11fcda59487ef 100644
--- a/tests/test_ipapython/test_ipautil.py
+++ b/tests/test_ipapython/test_ipautil.py
@@ -21,7 +21,6 @@ Test the `ipapython/ipautil.py` module.
"""
import nose
-import unittest
from ipapython import ipautil
@@ -70,280 +69,265 @@ def test_ip_address():
yield (CheckIPAddress(addr[0]),) + addr
-class TestCIDict(unittest.TestCase):
- def setUp(self):
+class TestCIDict(object):
+ def setup(self):
self.cidict = ipautil.CIDict()
self.cidict["Key1"] = "val1"
self.cidict["key2"] = "val2"
self.cidict["KEY3"] = "VAL3"
- def tearDown(self):
- pass
+ def test_len(self):
+ nose.tools.assert_equal(3, len(self.cidict))
- def testLen(self):
- self.assertEqual(3, len(self.cidict))
-
- def test__GetItem(self):
- self.assertEqual("val1", self.cidict["Key1"])
- self.assertEqual("val1", self.cidict["key1"])
- self.assertEqual("val2", self.cidict["KEY2"])
- self.assertEqual("VAL3", self.cidict["key3"])
- self.assertEqual("VAL3", self.cidict["KEY3"])
- try:
+ def test_getitem(self):
+ nose.tools.assert_equal("val1", self.cidict["Key1"])
+ nose.tools.assert_equal("val1", self.cidict["key1"])
+ nose.tools.assert_equal("val2", self.cidict["KEY2"])
+ nose.tools.assert_equal("VAL3", self.cidict["key3"])
+ nose.tools.assert_equal("VAL3", self.cidict["KEY3"])
+ with nose.tools.assert_raises(KeyError):
self.cidict["key4"]
- fail("should have raised KeyError")
- except KeyError:
- pass
- def testGet(self):
- self.assertEqual("val1", self.cidict.get("Key1"))
- self.assertEqual("val1", self.cidict.get("key1"))
- self.assertEqual("val2", self.cidict.get("KEY2"))
- self.assertEqual("VAL3", self.cidict.get("key3"))
- self.assertEqual("VAL3", self.cidict.get("KEY3"))
- self.assertEqual("default", self.cidict.get("key4", "default"))
+ def test_get(self):
+ nose.tools.assert_equal("val1", self.cidict.get("Key1"))
+ nose.tools.assert_equal("val1", self.cidict.get("key1"))
+ nose.tools.assert_equal("val2", self.cidict.get("KEY2"))
+ nose.tools.assert_equal("VAL3", self.cidict.get("key3"))
+ nose.tools.assert_equal("VAL3", self.cidict.get("KEY3"))
+ nose.tools.assert_equal("default", self.cidict.get("key4", "default"))
- def test__SetItem(self):
+ def test_setitem(self):
self.cidict["key4"] = "val4"
- self.assertEqual("val4", self.cidict["key4"])
+ nose.tools.assert_equal("val4", self.cidict["key4"])
self.cidict["KEY4"] = "newval4"
- self.assertEqual("newval4", self.cidict["key4"])
+ nose.tools.assert_equal("newval4", self.cidict["key4"])
- def testDel(self):
- self.assert_(self.cidict.has_key("Key1"))
+ def test_del(self):
+ assert self.cidict.has_key("Key1")
del(self.cidict["Key1"])
- self.failIf(self.cidict.has_key("Key1"))
+ assert not self.cidict.has_key("Key1")
- self.assert_(self.cidict.has_key("key2"))
+ assert self.cidict.has_key("key2")
del(self.cidict["KEY2"])
- self.failIf(self.cidict.has_key("key2"))
+ assert not self.cidict.has_key("key2")
- def testClear(self):
- self.assertEqual(3, len(self.cidict))
+ def test_clear(self):
+ nose.tools.assert_equal(3, len(self.cidict))
self.cidict.clear()
- self.assertEqual(0, len(self.cidict))
+ nose.tools.assert_equal(0, len(self.cidict))
- def testCopy(self):
+ def test_copy(self):
"""A copy is no longer a CIDict, but should preserve the case of
the keys as they were inserted."""
copy = self.cidict.copy()
- self.assertEqual(3, len(copy))
- self.assert_(copy.has_key("Key1"))
- self.assertEqual("val1", copy["Key1"])
- self.failIf(copy.has_key("key1"))
+ nose.tools.assert_equal(3, len(copy))
+ assert copy.has_key("Key1")
+ nose.tools.assert_equal("val1", copy["Key1"])
+ assert not copy.has_key("key1")
- def testHasKey(self):
- self.assert_(self.cidict.has_key("KEY1"))
- self.assert_(self.cidict.has_key("key2"))
- self.assert_(self.cidict.has_key("key3"))
+ def test_haskey(self):
+ assert self.cidict.has_key("KEY1")
+ assert self.cidict.has_key("key2")
+ assert self.cidict.has_key("key3")
- def testItems(self):
+ def test_items(self):
items = self.cidict.items()
- self.assertEqual(3, len(items))
+ nose.tools.assert_equal(3, len(items))
items_set = set(items)
- self.assert_(("Key1", "val1") in items_set)
- self.assert_(("key2", "val2") in items_set)
- self.assert_(("KEY3", "VAL3") in items_set)
+ assert ("Key1", "val1") in items_set
+ assert ("key2", "val2") in items_set
+ assert ("KEY3", "VAL3") in items_set
- def testIterItems(self):
+ def test_iteritems(self):
items = []
for (k,v) in self.cidict.iteritems():
items.append((k,v))
- self.assertEqual(3, len(items))
+ nose.tools.assert_equal(3, len(items))
items_set = set(items)
- self.assert_(("Key1", "val1") in items_set)
- self.assert_(("key2", "val2") in items_set)
- self.assert_(("KEY3", "VAL3") in items_set)
+ assert ("Key1", "val1") in items_set
+ assert ("key2", "val2") in items_set
+ assert ("KEY3", "VAL3") in items_set
- def testIterKeys(self):
+ def test_iterkeys(self):
keys = []
for k in self.cidict.iterkeys():
keys.append(k)
- self.assertEqual(3, len(keys))
+ nose.tools.assert_equal(3, len(keys))
keys_set = set(keys)
- self.assert_("Key1" in keys_set)
- self.assert_("key2" in keys_set)
- self.assert_("KEY3" in keys_set)
+ assert "Key1" in keys_set
+ assert "key2" in keys_set
+ assert "KEY3" in keys_set
- def testIterValues(self):
+ def test_itervalues(self):
values = []
for k in self.cidict.itervalues():
values.append(k)
- self.assertEqual(3, len(values))
+ nose.tools.assert_equal(3, len(values))
values_set = set(values)
- self.assert_("val1" in values_set)
- self.assert_("val2" in values_set)
- self.assert_("VAL3" in values_set)
+ assert "val1" in values_set
+ assert "val2" in values_set
+ assert "VAL3" in values_set
- def testKeys(self):
+ def test_keys(self):
keys = self.cidict.keys()
- self.assertEqual(3, len(keys))
+ nose.tools.assert_equal(3, len(keys))
keys_set = set(keys)
- self.assert_("Key1" in keys_set)
- self.assert_("key2" in keys_set)
- self.assert_("KEY3" in keys_set)
+ assert "Key1" in keys_set
+ assert "key2" in keys_set
+ assert "KEY3" in keys_set
- def testValues(self):
+ def test_values(self):
values = self.cidict.values()
- self.assertEqual(3, len(values))
+ nose.tools.assert_equal(3, len(values))
values_set = set(values)
- self.assert_("val1" in values_set)
- self.assert_("val2" in values_set)
- self.assert_("VAL3" in values_set)
+ assert "val1" in values_set
+ assert "val2" in values_set
+ assert "VAL3" in values_set
- def testUpdate(self):
+ def test_update(self):
newdict = { "KEY2": "newval2",
"key4": "val4" }
self.cidict.update(newdict)
- self.assertEqual(4, len(self.cidict))
+ nose.tools.assert_equal(4, len(self.cidict))
items = self.cidict.items()
- self.assertEqual(4, len(items))
+ nose.tools.assert_equal(4, len(items))
items_set = set(items)
- self.assert_(("Key1", "val1") in items_set)
+ assert ("Key1", "val1") in items_set
# note the update "overwrites" the case of the key2
- self.assert_(("KEY2", "newval2") in items_set)
- self.assert_(("KEY3", "VAL3") in items_set)
- self.assert_(("key4", "val4") in items_set)
+ assert ("KEY2", "newval2") in items_set
+ assert ("KEY3", "VAL3") in items_set
+ assert ("key4", "val4") in items_set
- def testSetDefault(self):
- self.assertEqual("val1", self.cidict.setdefault("KEY1", "default"))
+ def test_setdefault(self):
+ nose.tools.assert_equal("val1", self.cidict.setdefault("KEY1", "default"))
- self.failIf(self.cidict.has_key("KEY4"))
- self.assertEqual("default", self.cidict.setdefault("KEY4", "default"))
- self.assert_(self.cidict.has_key("KEY4"))
- self.assertEqual("default", self.cidict["key4"])
+ assert not self.cidict.has_key("KEY4")
+ nose.tools.assert_equal("default", self.cidict.setdefault("KEY4", "default"))
+ assert self.cidict.has_key("KEY4")
+ nose.tools.assert_equal("default", self.cidict["key4"])
- self.failIf(self.cidict.has_key("KEY5"))
- self.assertEqual(None, self.cidict.setdefault("KEY5"))
- self.assert_(self.cidict.has_key("KEY5"))
- self.assertEqual(None, self.cidict["key5"])
+ assert not self.cidict.has_key("KEY5")
+ nose.tools.assert_equal(None, self.cidict.setdefault("KEY5"))
+ assert self.cidict.has_key("KEY5")
+ nose.tools.assert_equal(None, self.cidict["key5"])
- def testPop(self):
- self.assertEqual("val1", self.cidict.pop("KEY1", "default"))
- self.failIf(self.cidict.has_key("key1"))
+ def test_pop(self):
+ nose.tools.assert_equal("val1", self.cidict.pop("KEY1", "default"))
+ assert not self.cidict.has_key("key1")
- self.assertEqual("val2", self.cidict.pop("KEY2"))
- self.failIf(self.cidict.has_key("key2"))
+ nose.tools.assert_equal("val2", self.cidict.pop("KEY2"))
+ assert not self.cidict.has_key("key2")
- self.assertEqual("default", self.cidict.pop("key4", "default"))
- try:
+ nose.tools.assert_equal("default", self.cidict.pop("key4", "default"))
+ with nose.tools.assert_raises(KeyError):
self.cidict.pop("key4")
- fail("should have raised KeyError")
- except KeyError:
- pass
- def testPopItem(self):
+ def test_popitem(self):
items = set(self.cidict.items())
- self.assertEqual(3, len(self.cidict))
+ nose.tools.assert_equal(3, len(self.cidict))
item = self.cidict.popitem()
- self.assertEqual(2, len(self.cidict))
- self.assert_(item in items)
+ nose.tools.assert_equal(2, len(self.cidict))
+ assert item in items
items.discard(item)
item = self.cidict.popitem()
- self.assertEqual(1, len(self.cidict))
- self.assert_(item in items)
+ nose.tools.assert_equal(1, len(self.cidict))
+ assert item in items
items.discard(item)
item = self.cidict.popitem()
- self.assertEqual(0, len(self.cidict))
- self.assert_(item in items)
+ nose.tools.assert_equal(0, len(self.cidict))
+ assert item in items
items.discard(item)
-class TestTimeParser(unittest.TestCase):
- def setUp(self):
- pass
-
- def tearDown(self):
- pass
-
- def testSimple(self):
+class TestTimeParser(object):
+ def test_simple(self):
timestr = "20070803"
time = ipautil.parse_generalized_time(timestr)
- self.assertEqual(2007, time.year)
- self.assertEqual(8, time.month)
- self.assertEqual(3, time.day)
- self.assertEqual(0, time.hour)
- self.assertEqual(0, time.minute)
- self.assertEqual(0, time.second)
+ nose.tools.assert_equal(2007, time.year)
+ nose.tools.assert_equal(8, time.month)
+ nose.tools.assert_equal(3, time.day)
+ nose.tools.assert_equal(0, time.hour)
+ nose.tools.assert_equal(0, time.minute)
+ nose.tools.assert_equal(0, time.second)
- def testHourMinSec(self):
+ def test_hour_min_sec(self):
timestr = "20051213141205"
time = ipautil.parse_generalized_time(timestr)
- self.assertEqual(2005, time.year)
- self.assertEqual(12, time.month)
- self.assertEqual(13, time.day)
- self.assertEqual(14, time.hour)
- self.assertEqual(12, time.minute)
- self.assertEqual(5, time.second)
+ nose.tools.assert_equal(2005, time.year)
+ nose.tools.assert_equal(12, time.month)
+ nose.tools.assert_equal(13, time.day)
+ nose.tools.assert_equal(14, time.hour)
+ nose.tools.assert_equal(12, time.minute)
+ nose.tools.assert_equal(5, time.second)
- def testFractions(self):
+ def test_fractions(self):
timestr = "2003092208.5"
time = ipautil.parse_generalized_time(timestr)
- self.assertEqual(2003, time.year)
- self.assertEqual(9, time.month)
- self.assertEqual(22, time.day)
- self.assertEqual(8, time.hour)
- self.assertEqual(30, time.minute)
- self.assertEqual(0, time.second)
+ nose.tools.assert_equal(2003, time.year)
+ nose.tools.assert_equal(9, time.month)
+ nose.tools.assert_equal(22, time.day)
+ nose.tools.assert_equal(8, time.hour)
+ nose.tools.assert_equal(30, time.minute)
+ nose.tools.assert_equal(0, time.second)
timestr = "199203301544,25"
time = ipautil.parse_generalized_time(timestr)
- self.assertEqual(1992, time.year)
- self.assertEqual(3, time.month)
- self.assertEqual(30, time.day)
- self.assertEqual(15, time.hour)
- self.assertEqual(44, time.minute)
- self.assertEqual(15, time.second)
+ nose.tools.assert_equal(1992, time.year)
+ nose.tools.assert_equal(3, time.month)
+ nose.tools.assert_equal(30, time.day)
+ nose.tools.assert_equal(15, time.hour)
+ nose.tools.assert_equal(44, time.minute)
+ nose.tools.assert_equal(15, time.second)
timestr = "20060401185912,8"
time = ipautil.parse_generalized_time(timestr)
- self.assertEqual(2006, time.year)
- self.assertEqual(4, time.month)
- self.assertEqual(1, time.day)
- self.assertEqual(18, time.hour)
- self.assertEqual(59, time.minute)
- self.assertEqual(12, time.second)
- self.assertEqual(800000, time.microsecond)
+ nose.tools.assert_equal(2006, time.year)
+ nose.tools.assert_equal(4, time.month)
+ nose.tools.assert_equal(1, time.day)
+ nose.tools.assert_equal(18, time.hour)
+ nose.tools.assert_equal(59, time.minute)
+ nose.tools.assert_equal(12, time.second)
+ nose.tools.assert_equal(800000, time.microsecond)
- def testTimeZones(self):
+ def test_time_zones(self):
timestr = "20051213141205Z"
time = ipautil.parse_generalized_time(timestr)
- self.assertEqual(0, time.tzinfo.houroffset)
- self.assertEqual(0, time.tzinfo.minoffset)
+ nose.tools.assert_equal(0, time.tzinfo.houroffset)
+ nose.tools.assert_equal(0, time.tzinfo.minoffset)
offset = time.tzinfo.utcoffset(time.tzinfo.dst())
- self.assertEqual(0, offset.seconds)
+ nose.tools.assert_equal(0, offset.seconds)
timestr = "20051213141205+0500"
time = ipautil.parse_generalized_time(timestr)
- self.assertEqual(5, time.tzinfo.houroffset)
- self.assertEqual(0, time.tzinfo.minoffset)
+ nose.tools.assert_equal(5, time.tzinfo.houroffset)
+ nose.tools.assert_equal(0, time.tzinfo.minoffset)
offset = time.tzinfo.utcoffset(time.tzinfo.dst())
- self.assertEqual(5 * 60 * 60, offset.seconds)
+ nose.tools.assert_equal(5 * 60 * 60, offset.seconds)
timestr = "20051213141205-0500"
time = ipautil.parse_generalized_time(timestr)
- self.assertEqual(-5, time.tzinfo.houroffset)
- self.assertEqual(0, time.tzinfo.minoffset)
+ nose.tools.assert_equal(-5, time.tzinfo.houroffset)
+ nose.tools.assert_equal(0, time.tzinfo.minoffset)
# NOTE - the offset is always positive - it's minutes
# _east_ of UTC
offset = time.tzinfo.utcoffset(time.tzinfo.dst())
- self.assertEqual((24 - 5) * 60 * 60, offset.seconds)
+ nose.tools.assert_equal((24 - 5) * 60 * 60, offset.seconds)
timestr = "20051213141205-0930"
time = ipautil.parse_generalized_time(timestr)
- self.assertEqual(-9, time.tzinfo.houroffset)
- self.assertEqual(-30, time.tzinfo.minoffset)
+ nose.tools.assert_equal(-9, time.tzinfo.houroffset)
+ nose.tools.assert_equal(-30, time.tzinfo.minoffset)
offset = time.tzinfo.utcoffset(time.tzinfo.dst())
- self.assertEqual(((24 - 9) * 60 * 60) - (30 * 60), offset.seconds)
+ nose.tools.assert_equal(((24 - 9) * 60 * 60) - (30 * 60), offset.seconds)
--
1.7.7.6
From 3237ab534cc78376f786147e63efb4524db827b3 Mon Sep 17 00:00:00 2001
From: Petr Viktorin <[email protected]>
Date: Tue, 5 Feb 2013 10:24:46 -0500
Subject: [PATCH] Add missing dict methods to CIDict
Add __contains__, __iter__, clear.
Also add values() and itervalues(). Previously the dict versions were
used; the new ones guarantee that the order matches keys().
Mark view* methods as not implemented.
Document that CIDict.copy() returns a plain dict.
Test the above additions, and fromkeys() which worked but wasn't tested.
---
ipapython/ipautil.py | 45 +++++++++++++++++++++++++---------
tests/test_ipapython/test_ipautil.py | 35 ++++++++++++++++++++++++++
2 files changed, 68 insertions(+), 12 deletions(-)
diff --git a/ipapython/ipautil.py b/ipapython/ipautil.py
index c0ac3a1f76397e79672f1b99c2d46463d8e0af3e..a9708102c58b5c5660a6ddc189c6c1650f3983dd 100644
--- a/ipapython/ipautil.py
+++ b/ipapython/ipautil.py
@@ -441,7 +441,7 @@ class CIDict(dict):
def __init__(self, default=None):
super(CIDict, self).__init__()
- self._keys = {}
+ self._keys = {} # mapping of lowercased keys to proper case
self.update(default or {})
def __getitem__(self, key):
@@ -455,41 +455,49 @@ class CIDict(dict):
def __delitem__(self, key):
lower_key = key.lower()
del self._keys[lower_key]
- return super(CIDict, self).__delitem__(key.lower())
+ return super(CIDict, self).__delitem__(lower_key)
def update(self, dict):
for key in dict.keys():
self[key] = dict[key]
+ def __contains__(self, key):
+ return super(CIDict, self).__contains__(key.lower())
+
def has_key(self, key):
return super(CIDict, self).has_key(key.lower())
def get(self, key, failobj=None):
try:
return self[key]
except KeyError:
return failobj
+ def __iter__(self):
+ return self._keys.itervalues()
+
def keys(self):
- return self._keys.values()
+ return list(self.iterkeys())
def items(self):
- result = []
- for k in self._keys.values():
- result.append((k, self[k]))
- return result
+ return list(self.iteritems())
+
+ def values(self):
+ return list(self.itervalues())
def copy(self):
+ """Returns a copy of this CIDict as an ordinary dict"""
copy = {}
- for k in self._keys.values():
- copy[k] = self[k]
- return copy
+ return dict(self.items())
def iteritems(self):
- return self.copy().iteritems()
+ return ((k, self[k]) for k in self._keys.itervalues())
def iterkeys(self):
- return self.copy().iterkeys()
+ return self._keys.itervalues()
+
+ def itervalues(self):
+ return (v for k, v in self.iteritems())
def setdefault(self, key, value=None):
try:
@@ -515,6 +523,19 @@ class CIDict(dict):
return (key, value)
+ def clear(self):
+ self._keys.clear()
+ return super(CIDict, self).clear()
+
+ def viewitems(self):
+ raise NotImplementedError('CIDict.viewitems is not implemented')
+
+ def viewkeys(self):
+ raise NotImplementedError('CIDict.viewkeys is not implemented')
+
+ def viewvvalues(self):
+ raise NotImplementedError('CIDict.viewvvalues is not implemented')
+
class GeneralizedTimeZone(datetime.tzinfo):
"""This class is a basic timezone wrapper for the offset specified
diff --git a/tests/test_ipapython/test_ipautil.py b/tests/test_ipapython/test_ipautil.py
index 95933581f2f83f61008493079ba11fcda59487ef..bd2d0bdcb2a1794bd5358156ef4e5076ce102c8d 100644
--- a/tests/test_ipapython/test_ipautil.py
+++ b/tests/test_ipapython/test_ipautil.py
@@ -130,14 +130,31 @@ class TestCIDict(object):
assert self.cidict.has_key("key2")
assert self.cidict.has_key("key3")
+ assert not self.cidict.has_key("Key4")
+
+ def test_contains(self):
+ assert "KEY1" in self.cidict
+ assert "key2" in self.cidict
+ assert "key3" in self.cidict
+
+ assert "Key4" not in self.cidict
+
def test_items(self):
items = self.cidict.items()
nose.tools.assert_equal(3, len(items))
items_set = set(items)
assert ("Key1", "val1") in items_set
assert ("key2", "val2") in items_set
assert ("KEY3", "VAL3") in items_set
+ assert self.cidict.items() == list(self.cidict.iteritems()) == zip(
+ self.cidict.iterkeys(), self.cidict.itervalues())
+
+ def test_iter(self):
+ items = []
+ assert list(self.cidict) == list(self.cidict.keys())
+ assert sorted(self.cidict) == sorted(['Key1', 'key2', 'KEY3'])
+
def test_iteritems(self):
items = []
for (k,v) in self.cidict.iteritems():
@@ -176,14 +193,18 @@ class TestCIDict(object):
assert "key2" in keys_set
assert "KEY3" in keys_set
+ assert self.cidict.keys() == list(self.cidict.iterkeys())
+
def test_values(self):
values = self.cidict.values()
nose.tools.assert_equal(3, len(values))
values_set = set(values)
assert "val1" in values_set
assert "val2" in values_set
assert "VAL3" in values_set
+ assert self.cidict.values() == list(self.cidict.itervalues())
+
def test_update(self):
newdict = { "KEY2": "newval2",
"key4": "val4" }
@@ -242,6 +263,20 @@ class TestCIDict(object):
assert item in items
items.discard(item)
+ def test_fromkeys(self):
+ dct = ipautil.CIDict.fromkeys(('A', 'b', 'C'))
+ assert sorted(dct.keys()) == sorted(['A', 'b', 'C'])
+ assert sorted(dct.values()) == [None] * 3
+
+ def test_clear(self):
+ self.cidict.clear()
+ assert self.cidict == {}
+ assert self.cidict.keys() == []
+ assert self.cidict.values() == []
+ assert self.cidict.items() == []
+ assert self.cidict._keys == {}
+
+
class TestTimeParser(object):
def test_simple(self):
timestr = "20070803"
--
1.7.7.6
_______________________________________________
Freeipa-devel mailing list
[email protected]
https://www.redhat.com/mailman/listinfo/freeipa-devel