Permalink
Browse files

Correct result of != comparison against List, Set, Map (fixes #2639)

Adds __ne__ method to JavaProxy{List, Set, Map}. Changes BaseSet __eq__
and __ne__ methods to use item by item comparison where needed. Some
minor improvements e.g. use entrySet for map comparison. Also refactors
methods for testing equality and inequality to be very similar across
JavaProxy{List, Set, Map}.

Adds test coverage of != comparisons to Java {List, Set, Map}, and
tests with more Java types, the comparions in both directions.

--HG--
extra : amend_source : c4b1212f099c499b8ed582a0a169323b4dfc7332
  • Loading branch information...
jamesmudd committed Jul 11, 2018
1 parent fb1b8d5 commit 03e78a74f61aebf97e3742cac0bf1fc15416d620
View
@@ -1,10 +1,14 @@
from test import test_support
from java.util import HashMap, Hashtable
import unittest
from collections import defaultdict
import test_dict
from java.util import HashMap, LinkedHashMap, Hashtable
from java.util.concurrent import ConcurrentHashMap
class DictInitTest(unittest.TestCase):
def testInternalSetitemInInit(self):
"""Test for http://jython.org/bugs/1816134
@@ -41,14 +45,17 @@ def testUnhashableKeys(self):
else:
self.fail("dict as dict key should raise TypeError")
class DictCmpTest(unittest.TestCase):
"Test for http://bugs.jython.org/issue1031"
def testDictCmp(self):
# 'Implicit' comparision of dicts against other types instances
# shouldn't raise exception:
self.assertNotEqual({}, '')
# The same, but explicitly calling __cmp__ should raise TypeError:
self.assertRaises(TypeError, {}.__cmp__, '')
def testDictDerivedCmp(self):
# With derived classes that doesn't override __cmp__, the behaviour
# should be the same that with dicts:
@@ -86,7 +93,9 @@ class yet_another_dict(derived_dict_with_custom_cmp): pass
self.assertEqual(derived_dict_with_custom_cmp(), '')
self.assertEqual(yet_another_dict(), '')
class DictMiscTest(unittest.TestCase):
def test_pop_key_error(self):
# tests http://bugs.jython.org/issue2247
with self.assertRaisesRegexp(KeyError, r"^1$"):
@@ -96,16 +105,18 @@ def test_pop_key_error(self):
with self.assertRaisesRegexp(KeyError, r"^frozenset\(\[\]\)$"):
{}.pop(frozenset())
class DerivedDictTest(unittest.TestCase):
"Tests for derived dict behaviour"
def test_raising_custom_key_error(self):
class CustomKeyError(KeyError):
pass
class DerivedDict(dict):
def __getitem__(self, key):
raise CustomKeyError("custom message")
self.assertRaises(CustomKeyError, lambda: DerivedDict()['foo'])
def test_issue1676(self):
#See http://bugs.jython.org/issue1676
x=defaultdict()
@@ -123,17 +134,20 @@ def test_big_dict(self):
class JavaIntegrationTest(unittest.TestCase):
"Tests for instantiating dicts from Java maps and hashtables"
def test_hashmap(self):
x = HashMap()
type2test = HashMap
def test_map(self):
x = self.type2test()
x.put('a', 1)
x.put('b', 2)
x.put('c', 3)
x.put((1,2), "xyz")
y = dict(x)
self.assertEqual(set(y.items()), set([('a', 1), ('b', 2), ('c', 3), ((1,2), "xyz")]))
def test_hashmap_builtin_pymethods(self):
x = HashMap()
def test_map_builtin_pymethods(self):
x = self.type2test()
x['a'] = 1
x[(1, 2)] = 'xyz'
self.assertEqual({tup for tup in x.iteritems()}, {('a', 1), ((1, 2), 'xyz')})
@@ -142,26 +156,96 @@ def test_hashmap_builtin_pymethods(self):
self.assertEqual(str(x), repr(x))
self.assertEqual(type(str(x)), type(repr(x)))
def test_hashtable_equal(self):
def test_equal(self):
for d in ({}, {1:2}):
x = Hashtable(d)
x = self.type2test(d)
self.assertEqual(x, d)
self.assertEqual(d, x)
self.assertEqual(x, HashMap(d))
def test_hashtable_remove(self):
x = Hashtable({})
def test_remove(self):
x = self.type2test({'a': 1})
del x['a']
self.assertEqual(x, {})
x = self.type2test({})
with self.assertRaises(KeyError):
del x[0]
def test_hashtable(self):
x = Hashtable()
x.put('a', 1)
x.put('b', 2)
x.put('c', 3)
x.put((1,2), "xyz")
y = dict(x)
self.assertEqual(set(y.items()), set([('a', 1), ('b', 2), ('c', 3), ((1,2), "xyz")]))
def test_equality_empty_dict(self):
jmap = self.type2test()
self.assertTrue(jmap == {})
self.assertTrue({} == jmap)
def test_equality_simple_dict(self):
jmap = self.type2test()
self.assertFalse({'a': 1} == jmap)
self.assertFalse(jmap == {'a': 1})
def test_equality_mixed_types_dict(self):
ref = {False:0, 'a':1, u'b':2L, 3:"3"}
alt = {0:False, u'a':True, 'b':2, 3:"3"}
self.assertEqual(ref, alt) # test assumption
jref = self.type2test(ref)
for v in [ref, alt, jref]:
self.assertTrue(jref == v)
self.assertTrue(v == jref)
self.assertTrue(jref == self.type2test(v))
self.assertTrue(self.type2test(v) == jref)
alt1 = ref.copy(); alt1['a'] = 2;
alt2 = ref.copy(); del alt2['a'];
alt3 = ref.copy(); alt3['c'] = [];
for v in [alt1, alt2, alt3, {}]:
self.assertFalse(jref == v)
self.assertFalse(v == jref)
self.assertFalse(jref == self.type2test(v))
self.assertFalse(self.type2test(v) == jref)
# Test for http://bugs.jython.org/issue2639
# This is to test the != comparisons between Java and Python maps/dict
def test_inequality_empty_dict(self):
jmap = self.type2test()
self.assertFalse(jmap != {})
self.assertFalse({} != jmap)
def test_inequality_simple_dict(self):
jmap = self.type2test()
self.assertTrue(jmap != {'a': 1})
self.assertTrue({'a': 1} != jmap)
def test_inequality_mixed_types_dict(self):
ref = {False:0, 'a':1, u'b':2L, 3:"3"}
alt = {0:False, u'a':True, 'b':2, 3:"3"}
self.assertEqual(ref, alt) # test assumption
jref = self.type2test(ref)
for v in [ref, alt, jref]:
self.assertFalse(jref != v)
self.assertFalse(v != jref)
self.assertFalse(jref != self.type2test(v))
self.assertFalse(self.type2test(v) != jref)
alt1 = ref.copy(); alt1['a'] = 2;
alt2 = ref.copy(); del alt2['a'];
alt3 = ref.copy(); alt3['c'] = [];
for v in [alt1, alt2, alt3, {}]:
self.assertTrue(jref != v)
self.assertTrue(v != jref)
self.assertTrue(jref != self.type2test(v))
self.assertTrue(self.type2test(v) != jref)
class JavaHashMapTest(JavaIntegrationTest):
type2test = HashMap
class JavaLinkedHashMapTest(JavaIntegrationTest):
type2test = LinkedHashMap
class JavaHashtableTest(JavaIntegrationTest):
type2test = Hashtable
class JavaConcurrentHashMapTest(JavaIntegrationTest):
type2test = HashMap
class JavaDictTest(test_dict.DictTest):
@@ -265,7 +349,10 @@ def test_main():
DictCmpTest,
DictMiscTest,
DerivedDictTest,
JavaIntegrationTest,
JavaHashMapTest,
JavaLinkedHashMapTest,
JavaConcurrentHashMapTest,
JavaHashtableTest,
JavaDictTest,
PyStringMapTest)
View
@@ -6,9 +6,10 @@
import test_list
if test_support.is_jython:
from java.util import ArrayList
from java.util import ArrayList, LinkedList, Vector
from java.lang import Integer, String
class ListTestCase(unittest.TestCase):
def test_recursive_list_slices(self):
@@ -60,6 +61,7 @@ def test_big_list(self):
self.assertEqual(len(lst), 64000)
self.assertEqual(sum(lst), 2047968000)
class ThreadSafetyTestCase(unittest.TestCase):
def run_threads(self, f, num=10):
@@ -112,6 +114,7 @@ def tester():
self.assert_(lst[1] in (1,10))
self.run_threads(tester)
class ExtendedSliceTestCase(unittest.TestCase):
'''Really thrash extended slice operations on list.'''
type2test = list
@@ -228,17 +231,17 @@ def test_init(self):
self.assertEqual(a, b)
def test_extend_java_ArrayList(self):
jl = ArrayList([])
jl = self.type2test([])
jl.extend([1,2])
self.assertEqual(jl, ArrayList([1,2]))
jl.extend(ArrayList([3,4]))
self.assertEqual(jl, self.type2test([1,2]))
jl.extend(self.type2test([3,4]))
self.assertEqual(jl, [1,2,3,4])
def test_remove(self):
# Verifies that overloaded java.util.List#remove(int) method can still be used, but with Python index semantics
# http://bugs.jython.org/issue2456
jl = ArrayList(xrange(10, -1, -1)) # 10 .. 0, inclusive
jl.remove(0) # removes jl[-1] (=0)
jl = self.type2test(xrange(10, -1, -1)) # 10 .. 0, inclusive
jl.remove(0) # removes jl[-1] (=0)
self.assertEqual(jl, range(10, 0, -1)) # 10 .. 1
self.assertRaises(ValueError, jl.remove, Integer(0)) # j.l.Integer does not support __index__ - maybe it should!
jl.remove(0) # removes jl[0] (=10)
@@ -251,7 +254,7 @@ def test_remove(self):
a_to_z = list(chr(i) for i in xrange(ord('a'), ord('z') + 1))
b_to_z_by_2 = list(chr(i) for i in xrange(ord('b'), ord('z') + 1, 2))
jl = ArrayList(a_to_z)
jl = self.type2test(a_to_z)
for i in xrange(13):
jl.remove(i)
self.assertEqual(jl, b_to_z_by_2)
@@ -263,6 +266,90 @@ def test_concat(self):
self.assertEquals(lst+lst2, [1, 2, 3, 4, 5, 6])
self.assertEquals(lst2+lst, [4, 5, 6, 1, 2, 3])
def test_equality_empty_list(self):
jl = self.type2test()
self.assertTrue(jl == [])
self.assertTrue([] == jl)
def test_equality_simple_list(self):
jl = self.type2test()
self.assertFalse(jl == [1])
self.assertFalse([1] == jl)
def test_equality_mixed_types_list(self):
ref = [False, 1, 3**9, "3"]
alt = [0, True, 3L**9, u"3"]
self.assertEqual(ref, alt) # test assumption
jref = self.type2test(ref)
for v in [ref, alt, jref]:
self.assertTrue(jref == v)
self.assertTrue(v == jref)
self.assertTrue(jref == self.type2test(v))
alt = [False, 1, 2e4, "3"]
for v in [alt, ref[:-1], ref+[{}], []]:
self.assertFalse(jref == v)
self.assertFalse(v == jref)
self.assertFalse(jref == self.type2test(v))
# Test for http://bugs.jython.org/issue2639
# This is to test the != comparisons between Java and Python lists
def test_inequality_empty_list(self):
jl = self.type2test()
self.assertFalse(jl != [])
self.assertFalse([] != jl)
def test_inequality_simple_list(self):
jl = self.type2test()
self.assertTrue(jl != [1])
self.assertTrue([1] != jl)
def test_inequality_mixed_types_list(self):
ref = [False, 1, 3**9, "3"]
alt = [0, True, 3L**9, u"3"]
self.assertEqual(ref, alt) # test assumption
jref = self.type2test(ref)
for v in [ref, alt, jref]:
self.assertFalse(jref != v)
self.assertFalse(v != jref)
self.assertFalse(jref != self.type2test(v))
alt = [False, 1, 2e4, "3"]
for v in [alt, ref[:-1], ref+[{}], []]:
self.assertTrue(jref != v)
self.assertTrue(v != jref)
self.assertTrue(jref != self.type2test(v))
class JavaArrayListTestCase(JavaListTestCase):
type2test = ArrayList
class JavaLinkedListTestCase(JavaListTestCase):
type2test = LinkedList
@unittest.skip("Fails for LinkedList see http://bugs.jython.org/issue2645")
def test_pop(self):
pass
@unittest.skip("Seems to hang for linked list")
def test_bigrepeat(self):
pass
@unittest.skip("Takes a long time and can cause OutOfMemory")
def test_overflow(self):
pass
class JavaVectorTestCase(JavaListTestCase):
type2test = Vector
@unittest.skip("Takes a long time and can cause OutOfMemory")
def test_bigrepeat(self):
pass
class ListSubclassTestCase(unittest.TestCase):
@@ -305,11 +392,13 @@ def __getitem__(self, index):
def test_main():
test_support.run_unittest(ListSubclassTestCase,
ListTestCase,
test_support.run_unittest(ListTestCase,
ThreadSafetyTestCase,
ExtendedSliceTestCase,
JavaListTestCase)
JavaArrayListTestCase,
JavaLinkedListTestCase,
JavaVectorTestCase,
ListSubclassTestCase)
if __name__ == "__main__":
test_main()
Oops, something went wrong.

0 comments on commit 03e78a7

Please sign in to comment.