This is an automated email from the ASF dual-hosted git repository. udim pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/beam.git
The following commit(s) were added to refs/heads/master by this push: new 459e270 Add assertArrayCountEqual, which checks if two containers have the same elements (#9235) 459e270 is described below commit 459e2700a5c3cb38f33194cba1fad8ce5c658b46 Author: Alexey Strokach <strok...@google.com> AuthorDate: Thu Aug 8 19:18:27 2019 -0700 Add assertArrayCountEqual, which checks if two containers have the same elements (#9235) Unlike [assertCountEqual](https://docs.python.org/3/library/unittest.html#unittest.TestCase.assertCountEqual), the two contaners can include numpy arrays. --- .../python/apache_beam/testing/extra_assertions.py | 64 +++++++++++++++++++ .../apache_beam/testing/extra_assertions_test.py | 71 ++++++++++++++++++++++ 2 files changed, 135 insertions(+) diff --git a/sdks/python/apache_beam/testing/extra_assertions.py b/sdks/python/apache_beam/testing/extra_assertions.py new file mode 100644 index 0000000..b7907bc --- /dev/null +++ b/sdks/python/apache_beam/testing/extra_assertions.py @@ -0,0 +1,64 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from __future__ import absolute_import + +import sys + +import numpy as np + + +class ExtraAssertionsMixin(object): + + if sys.version_info[0] < 3: + + def assertCountEqual(self, first, second, msg=None): + """Assert that two containers have the same number of the same items in + any order. + """ + return self.assertItemsEqual(first, second, msg=msg) + + def assertArrayCountEqual(self, data1, data2): + """Assert that two containers have the same items, with special treatment + for numpy arrays. + """ + try: + self.assertCountEqual(data1, data2) + except (TypeError, ValueError): + data1 = [self._to_hashable(d) for d in data1] + data2 = [self._to_hashable(d) for d in data1] + self.assertCountEqual(data1, data2) + + def _to_hashable(self, element): + try: + hash(element) + return element + except TypeError: + pass + + if isinstance(element, list): + return tuple(self._to_hashable(e) for e in element) + + if isinstance(element, dict): + hashable_elements = [] + for key, value in element.items(): + hashable_elements.append((key, self._to_hashable(value))) + return tuple(hashable_elements) + + if isinstance(element, np.ndarray): + return element.tobytes() + + raise AssertionError("Encountered unhashable element: {}.".format(element)) diff --git a/sdks/python/apache_beam/testing/extra_assertions_test.py b/sdks/python/apache_beam/testing/extra_assertions_test.py new file mode 100644 index 0000000..873122d --- /dev/null +++ b/sdks/python/apache_beam/testing/extra_assertions_test.py @@ -0,0 +1,71 @@ +# -*- coding: utf-8 -*- +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from __future__ import absolute_import + +import logging +import unittest + +import numpy as np + +from apache_beam.testing.extra_assertions import ExtraAssertionsMixin + + +class ExtraAssertionsMixinTest(ExtraAssertionsMixin, unittest.TestCase): + + def test_assert_array_count_equal_strings(self): + data1 = [u"±♠Ωℑ", u"hello", "world"] + data2 = ["hello", u"±♠Ωℑ", u"world"] + self.assertArrayCountEqual(data1, data2) + + def test_assert_array_count_equal_mixed(self): + # TODO(ostrokach): Add a timeout, since if assertArrayCountEqual is not + # implemented efficiently, this test has the potential to run for a very + # long time. + data1 = [ + # + {'a': 1, 123: 1.234}, + ['d', 1], + u"±♠Ωℑ", + np.zeros((3, 6)), + (1, 2, 3, 'b'), + 'def', + 100, + 'abc', + ('a', 'b', 'c'), + None + ] + data2 = [ + # + {'a': 1, 123: 1.234}, + ('a', 'b', 'c'), + ['d', 1], + None, + 'abc', + 'def', + u"±♠Ωℑ", + 100, + (1, 2, 3, 'b'), + np.zeros((3, 6)) + ] + self.assertArrayCountEqual(data1, data2) + self.assertArrayCountEqual(data1 * 2, data2 * 2) + + +if __name__ == '__main__': + logging.getLogger().setLevel(logging.INFO) + unittest.main()