From cbc1aa2b2d9e76d6b10b35f030efd900292c2464 Mon Sep 17 00:00:00 2001 From: Thomas Hauk Date: Tue, 14 Jun 2016 11:40:33 -0700 Subject: [PATCH 1/3] Add Dataset.compare() method --- tablib/core.py | 21 +++++++++++++++++++++ test_tablib.py | 24 +++++++++++++++++++++++- 2 files changed, 44 insertions(+), 1 deletion(-) diff --git a/tablib/core.py b/tablib/core.py index c5faad3a..ae5d7fd7 100644 --- a/tablib/core.py +++ b/tablib/core.py @@ -9,7 +9,9 @@ :license: MIT, see LICENSE for more details. """ +from collections import Counter from copy import copy +from itertools import izip from operator import itemgetter from tablib import formats @@ -1032,6 +1034,25 @@ def subset(self, rows=None, cols=None): return _dset + def compare(self, other): + if not isinstance(other, Dataset): + return + + if not self.headers or not other.headers: + raise HeadersNeeded + + if self.height != other.height: + return False + + if Counter(self.headers) != Counter(other.headers): + return False + + for header in self.headers: + for a, b in izip(self[header], other[header]): + if a != b: + return False + + return True class Databook(object): diff --git a/test_tablib.py b/test_tablib.py index be41ee71..efba5553 100755 --- a/test_tablib.py +++ b/test_tablib.py @@ -8,7 +8,7 @@ import os import tablib from tablib.compat import markup, unicode, is_py3 -from tablib.core import Row +from tablib.core import Row, HeadersNeeded class TablibTestCase(unittest.TestCase): @@ -933,6 +933,28 @@ def test_databook_formatter_support_kwargs(self): """Test XLSX export with formatter configuration.""" self.founders.export('xlsx', freeze_panes=False) + def test_compare(self): + empty_data = tablib.Dataset() + + original_data = tablib.Dataset() + original_data.headers = ['i', 'b', 's'] + original_data.append([1, True, "aaa"]) + + reordered_data = tablib.Dataset() + reordered_data.headers = ['s', 'i', 'b'] + reordered_data.append(["aaa", 1, True]) + + different_data = tablib.Dataset() + different_data.headers = ['i', 'b', 's'] + different_data.append([0, False, "bbb"]) + + self.assertTrue(original_data.compare(original_data)) + self.assertTrue(original_data.compare(reordered_data)) + self.assertFalse(original_data.compare(different_data)) + self.assertFalse(reordered_data.compare(different_data)) + self.assertIsNone(original_data.compare(None)) + self.assertRaises(HeadersNeeded, original_data.compare, empty_data) + if __name__ == '__main__': unittest.main() From 241a926050a3c3272fad4f45e81b352049e0e0ce Mon Sep 17 00:00:00 2001 From: Thomas Hauk Date: Tue, 14 Jun 2016 11:52:34 -0700 Subject: [PATCH 2/3] Remove dependency on collections.Counter for 2.6 build and itertools.izip for 3.x builds --- tablib/core.py | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/tablib/core.py b/tablib/core.py index ae5d7fd7..3019f92d 100644 --- a/tablib/core.py +++ b/tablib/core.py @@ -9,9 +9,7 @@ :license: MIT, see LICENSE for more details. """ -from collections import Counter from copy import copy -from itertools import izip from operator import itemgetter from tablib import formats @@ -1044,11 +1042,11 @@ def compare(self, other): if self.height != other.height: return False - if Counter(self.headers) != Counter(other.headers): + if sorted(self.headers) != sorted(other.headers): return False for header in self.headers: - for a, b in izip(self[header], other[header]): + for a, b in zip(self[header], other[header]): if a != b: return False From f3e9f533fc02431048541ba0fff3f4823ab3f62c Mon Sep 17 00:00:00 2001 From: Thomas Hauk Date: Tue, 14 Jun 2016 11:56:55 -0700 Subject: [PATCH 3/3] Remove dependency on unittest.assertIsNone for 2.6 build --- test_tablib.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test_tablib.py b/test_tablib.py index efba5553..5a43beb1 100755 --- a/test_tablib.py +++ b/test_tablib.py @@ -952,7 +952,7 @@ def test_compare(self): self.assertTrue(original_data.compare(reordered_data)) self.assertFalse(original_data.compare(different_data)) self.assertFalse(reordered_data.compare(different_data)) - self.assertIsNone(original_data.compare(None)) + self.assertTrue(original_data.compare(None) is None) self.assertRaises(HeadersNeeded, original_data.compare, empty_data)