Rev 3904: Merge delta-show-with-path-filter into log-deep in file:///net/bigmamac/Volumes/home/vila/src/bzr/cases/3232-spurious-conflict/

Vincent Ladeuil v.ladeuil+lp at free.fr
Thu Jan 22 14:22:24 GMT 2009


At file:///net/bigmamac/Volumes/home/vila/src/bzr/cases/3232-spurious-conflict/

------------------------------------------------------------
revno: 3904
revision-id: v.ladeuil+lp at free.fr-20090122142221-1wei8kf43drbulhk
parent: v.ladeuil+lp at free.fr-20090122101308-qjoh1n1vdh1qfg8h
parent: v.ladeuil+lp at free.fr-20090122142156-791ls83n1qxwhv8h
committer: Vincent Ladeuil <v.ladeuil+lp at free.fr>
branch nick: log-deep
timestamp: Thu 2009-01-22 15:22:21 +0100
message:
  Merge delta-show-with-path-filter into log-deep
modified:
  bzrlib/delta.py                delta.py-20050729221636-54cf14ef94783d0a
  bzrlib/tests/test_delta.py     test_delta.py-20070110134455-sqpd1y7mbjndelxf-1
    ------------------------------------------------------------
    revno: 3884.1.10
    revision-id: v.ladeuil+lp at free.fr-20090122142156-791ls83n1qxwhv8h
    parent: v.ladeuil+lp at free.fr-20090122104907-v0jsuvgmk2gx25dq
    committer: Vincent Ladeuil <v.ladeuil+lp at free.fr>
    branch nick: delta-show-with-path-filter
    timestamp: Thu 2009-01-22 15:21:56 +0100
    message:
      Fix renames filtering in delta.show().
      
      * bzrlib/tests/test_delta.py:
      (load_tests): More parametrized tests.
      (TestDeltaShowMixin): Fctor out some common utilities.
      (TestDeltaShow): New test to reproduce bug in renames filtering.
      
      * bzrlib/delta.py:
      (TreeDelta.show.rename_item_filter): Renames are a bit harder to
      filter for.
      (TreeDelta.show): Fix renames filtering.
    modified:
      bzrlib/delta.py                delta.py-20050729221636-54cf14ef94783d0a
      bzrlib/tests/test_delta.py     test_delta.py-20070110134455-sqpd1y7mbjndelxf-1
    ------------------------------------------------------------
    revno: 3884.1.9
    revision-id: v.ladeuil+lp at free.fr-20090122104907-v0jsuvgmk2gx25dq
    parent: v.ladeuil+lp at free.fr-20090122101300-ngpxt42zur06y0s9
    committer: Vincent Ladeuil <v.ladeuil+lp at free.fr>
    branch nick: delta-show-with-path-filter
    timestamp: Thu 2009-01-22 11:49:07 +0100
    message:
      Refactor delta.show() tests.
      
      * bzrlib/tests/test_delta.py:
      (load_tests): Created to handle parametrized tests.
      (delta_show_scenarios): Create scenarios for short and long status
      forms.
      (TestDeltaShow): Rewrite tessts as parametrized ones.
    modified:
      bzrlib/tests/test_delta.py     test_delta.py-20070110134455-sqpd1y7mbjndelxf-1
-------------- next part --------------
=== modified file 'bzrlib/delta.py'
--- a/bzrlib/delta.py	2008-12-10 09:33:06 +0000
+++ b/bzrlib/delta.py	2009-01-22 14:21:56 +0000
@@ -158,10 +158,19 @@
             else:
                 to_file.write(default_format % dec_path)
 
+        def rename_item_filter(item):
+            (oldpath, file_id, kind,
+             text_modified, meta_modified, newpath) = item
+            return filter(oldpath, file_id) or filter(newpath, file_id)
+
         def show_list(files, long_status_name, short_status_letter,
                       default_format='%s', with_file_id_format='%-30s',
-                      show_more=None):
+                      show_more=None, item_filter=None):
             if files:
+                if item_filter is None and filter is not None:
+                    def item_filter(item):
+                        path, file_id, kind = item[:3]
+                        return filter(path, file_id)
                 header_shown = False
                 if short_status:
                     prefix = short_status_letter
@@ -170,9 +179,9 @@
                 prefix = indent + prefix + '  '
 
                 for item in files:
+                    if (item_filter is not None and not item_filter(item)):
+                        continue # Not an interesting item
                     path, file_id, kind = item[:3]
-                    if (filter is not None and not filter(path, file_id)):
-                        continue
                     if not header_shown and not short_status:
                         to_file.write(indent + long_status_name + ':\n')
                         header_shown = True
@@ -189,7 +198,7 @@
                         to_file.write(' %s' % file_id)
                     to_file.write('\n')
 
-        show_list(self.removed, 'removed', 'D')#
+        show_list(self.removed, 'removed', 'D')
         show_list(self.added, 'added', 'A')
         extra_modified = []
         # Reorder self.renamed tuples so that all lists share the same
@@ -197,8 +206,11 @@
         # the self.modified tuples
         renamed = [(p, i, k, tm, mm, np)
                    for  p, np, i, k, tm, mm  in self.renamed]
+        rfilter = None
+        if filter is not None:
+            rfilter = rename_item_filter
         show_list(renamed, 'renamed', 'R', with_file_id_format='%s',
-                  show_more=show_more_renamed)
+                  show_more=show_more_renamed, item_filter=rfilter)
         show_list(self.kind_changed, 'kind changed', 'K',
                   with_file_id_format='%s',
                   show_more=show_more_kind_changed)

=== modified file 'bzrlib/tests/test_delta.py'
--- a/bzrlib/tests/test_delta.py	2008-12-10 09:33:06 +0000
+++ b/bzrlib/tests/test_delta.py	2009-01-22 14:21:56 +0000
@@ -24,6 +24,23 @@
     )
 
 
+def load_tests(standard_tests, module, loader):
+    """Multiply tests for tranport implementations."""
+    result = loader.suiteClass()
+    delta_show_tests, other_tests = tests.split_suite_by_condition(
+        standard_tests,
+        tests.condition_isinstance((TestDeltaShow,
+                                    TestDeltaShowActions)))
+
+    result.addTests(other_tests)
+
+    adapter = tests.TestScenarioApplier()
+    adapter.scenarios = delta_show_scenarios()
+    tests.adapt_tests(delta_show_tests, adapter, result)
+
+    return result
+
+
 class InstrumentedReporter(object):
     def __init__(self):
         self.calls = []
@@ -241,7 +258,47 @@
         self.assertTrue(delta.touches_file_id('file-id'))
 
 
-class TestDeltaShow(tests.TestCaseWithTransport):
+def delta_show_scenarios():
+    """Create scenarios for delta.show() tests"""
+    scenarios = []
+    scenarios.append(('short', dict(short_status=True)))
+    scenarios.append(('long', dict(short_status=False)))
+    return scenarios
+
+
+class TestDeltaShowMixin(object):
+
+    def _show(self, delta, **kwargs):
+        out = StringIO()
+        delta.show(out, short_status=self.short_status, **kwargs)
+        return out.getvalue()
+
+    # This kind of duplicate some knowledge embedded in delta.show(), but at
+    # least that gives a single point to modify if tests break.
+    long_status_form = dict(A='added',
+                            D='removed',
+                            M='modified',
+                            )
+
+    def _build_status(self, short_action, file_list):
+        """Imitate statuses produced by delta.show()
+
+        We don't try to be perfect, instead we do the minimal work to allow
+        tests to be written for short and long status but don't go into details
+        about path formatting for example. I.e. we don't try to emulate
+        show_path().
+        """
+        if self.short_status:
+            status= ''
+            file_statuses = ['%s  %s\n' % (short_action, f) for  f in file_list]
+        else:
+            status = '%s:\n' % self.long_status_form[short_action]
+            file_statuses = ['  %s\n' % f for  f in file_list]
+        status += ''.join(file_statuses)
+        return status
+
+
+class TestDeltaShow(tests.TestCaseWithTransport, TestDeltaShowMixin):
 
     def _get_delta(self):
         # We build the delta from a real tree to avoid depending on internal
@@ -257,65 +314,106 @@
                ['f1-id', 'f2-id', 'f3-id', 'f4-id', 'dir-id'])
         wt.commit('commit one', rev_id='1')
 
-        long_status = """added:
+        repo = wt.branch.repository
+        delta = wt.changes_from(repo.revision_tree(_mod_revision.NULL_REVISION))
+
+        if self.short_status:
+            expected_status = """A  dir/
+A  f1
+A  f2
+A  f3
+A  f4
+"""
+        else:
+            expected_status = """added:
   dir/
   f1
   f2
   f3
   f4
 """
-        short_status = """A  dir/
-A  f1
-A  f2
-A  f3
-A  f4
-"""
-
-        repo = wt.branch.repository
-        d = wt.changes_from(repo.revision_tree(_mod_revision.NULL_REVISION))
-        return d, long_status, short_status
-
-    def test_delta_show_short_status_no_filter(self):
-        d, long_status, short_status = self._get_delta()
-        out = StringIO()
-        d.show(out, short_status=True)
-        self.assertEquals(short_status, out.getvalue())
-
-    def test_delta_show_long_status_no_filter(self):
-        d, long_status, short_status = self._get_delta()
-        out = StringIO()
-        d.show(out, short_status=False)
-        self.assertEquals(long_status, out.getvalue())
-
-    def test_delta_show_no_filter(self):
-        d, long_status, short_status = self._get_delta()
-        out = StringIO()
-        def not_a_filter(path, file_id):
+        return delta, expected_status
+
+    def test_without_filter(self):
+        delta, expected_status = self._get_delta()
+        actual_status = self._show(delta)
+        self.assertEquals(expected_status, actual_status)
+
+    def test_with_dummy_filter(self):
+        delta, expected_status = self._get_delta()
+        def dummy_filter(path, file_id):
             return True
-        d.show(out, short_status=True, filter=not_a_filter)
-        self.assertEquals(short_status, out.getvalue())
-
-    def test_delta_show_short_status_single_file_filter(self):
-        d, long_status, short_status = self._get_delta()
-        out = StringIO()
-        def only_f2(path, file_id):
-            return path == 'f2'
-        d.show(out, short_status=True, filter=only_f2)
-        self.assertEquals("A  f2\n", out.getvalue())
-
-    def test_delta_show_long_status_single_file_filter(self):
-        d, long_status, short_status = self._get_delta()
-        out = StringIO()
-        def only_f2(path, file_id):
-            return path == 'f2'
-        d.show(out, short_status=False, filter=only_f2)
-        self.assertEquals("added:\n  f2\n", out.getvalue())
-
-    def test_delta_show_short_status_single_file_id_filter(self):
-        d, long_status, short_status = self._get_delta()
-        out = StringIO()
+        actual_status = self._show(delta, filter=dummy_filter)
+        self.assertEquals(expected_status, actual_status)
+
+    def test_with_single_file_filter(self):
+        delta, _ = self._get_delta()
+        def only_f2(path, file_id):
+            return path == 'f2'
+        actual_status = self._show(delta, filter=only_f2)
+        self.assertEquals(self._build_status('A', ['f2']), actual_status)
+
+    def test_with_single_file_id_filter(self):
+        delta, _ = self._get_delta()
         def only_f2_id(path, file_id):
             return file_id == 'f2-id'
-        d.show(out, short_status=True, filter=only_f2_id)
-        self.assertEquals("A  f2\n", out.getvalue())
-
+        actual_status = self._show(delta, filter=only_f2_id)
+        self.assertEquals(self._build_status('A', ['f2']), actual_status)
+
+
+class TestDeltaShowActions(tests.TestCaseWithTransport, TestDeltaShowMixin):
+
+    def _get_basis(self):
+        # We build the delta from a real tree to avoid depending on internal
+        # implementation details. And start with an initial state from which
+        # tests can build upon.
+        wt = self.make_branch_and_tree('branch')
+        self.build_tree_contents([('branch/f1', '1\n'),
+                                  ('branch/f2', '2\n'),])
+        wt.add(['f1', 'f2'], ['f1-id', 'f2-id'])
+        wt.commit('commit one', rev_id='1')
+        return wt, wt.branch.repository
+
+    def test_delete(self):
+        wt, repo = self._get_basis()
+        wt.remove(['f1'], keep_files=False)
+        wt.commit('delete f1', rev_id='2')
+
+        delta = wt.changes_from(repo.revision_tree('1'))
+        def only_f1(path, file_id):
+            return path == 'f1'
+        actual_status = self._show(delta, filter=only_f1)
+        self.assertEquals(self._build_status('D', ['f1']), actual_status)
+
+    def test_modify(self):
+        wt, repo = self._get_basis()
+        self.build_tree_contents([('branch/f1', 'new\n'),])
+        wt.commit('modify f1', rev_id='2')
+
+        delta = wt.changes_from(repo.revision_tree('1'))
+        def only_f1(path, file_id):
+            return path == 'f1'
+        actual_status = self._show(delta, filter=only_f1)
+        self.assertEquals(self._build_status('M', ['f1']), actual_status)
+
+    def test_rename(self):
+        wt, repo = self._get_basis()
+        wt.rename_one('f1', 'new')
+        wt.commit('rename f1', rev_id='2')
+
+        if self.short_status:
+            expected = 'R  f1 => new\n'
+        else:
+            expected = 'renamed:\n  f1 => new\n'
+
+        delta = wt.changes_from(repo.revision_tree('1'))
+
+        def only_f1(path, file_id):
+            return path == 'f1'
+        actual_status = self._show(delta, filter=only_f1)
+        self.assertEquals(expected, actual_status)
+
+        def only_new(path, file_id):
+            return path == 'new'
+        actual_status = self._show(delta, filter=only_new)
+        self.assertEquals(expected, actual_status)



More information about the bazaar-commits mailing list