test_patch.py 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390
  1. # test_patch.py -- tests for patch.py
  2. # Copyright (C) 2010 Jelmer Vernooij <jelmer@samba.org>
  3. #
  4. # This program is free software; you can redistribute it and/or
  5. # modify it under the terms of the GNU General Public License
  6. # as published by the Free Software Foundation; version 2
  7. # of the License or (at your option) a later version.
  8. #
  9. # This program is distributed in the hope that it will be useful,
  10. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. # GNU General Public License for more details.
  13. #
  14. # You should have received a copy of the GNU General Public License
  15. # along with this program; if not, write to the Free Software
  16. # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
  17. # MA 02110-1301, USA.
  18. """Tests for patch.py."""
  19. from cStringIO import StringIO
  20. from dulwich.objects import (
  21. Blob,
  22. Commit,
  23. S_IFGITLINK,
  24. Tree,
  25. )
  26. from dulwich.object_store import (
  27. MemoryObjectStore,
  28. )
  29. from dulwich.patch import (
  30. git_am_patch_split,
  31. write_blob_diff,
  32. write_commit_patch,
  33. write_object_diff,
  34. write_tree_diff,
  35. )
  36. from dulwich.tests import (
  37. SkipTest,
  38. TestCase,
  39. )
  40. class WriteCommitPatchTests(TestCase):
  41. def test_simple(self):
  42. f = StringIO()
  43. c = Commit()
  44. c.committer = c.author = "Jelmer <jelmer@samba.org>"
  45. c.commit_time = c.author_time = 1271350201
  46. c.commit_timezone = c.author_timezone = 0
  47. c.message = "This is the first line\nAnd this is the second line.\n"
  48. c.tree = Tree().id
  49. write_commit_patch(f, c, "CONTENTS", (1, 1), version="custom")
  50. f.seek(0)
  51. lines = f.readlines()
  52. self.assertTrue(lines[0].startswith("From 0b0d34d1b5b596c928adc9a727a4b9e03d025298"))
  53. self.assertEquals(lines[1], "From: Jelmer <jelmer@samba.org>\n")
  54. self.assertTrue(lines[2].startswith("Date: "))
  55. self.assertEquals([
  56. "Subject: [PATCH 1/1] This is the first line\n",
  57. "And this is the second line.\n",
  58. "\n",
  59. "\n",
  60. "---\n"], lines[3:8])
  61. self.assertEquals([
  62. "CONTENTS-- \n",
  63. "custom\n"], lines[-2:])
  64. if len(lines) >= 12:
  65. # diffstat may not be present
  66. self.assertEquals(lines[8], " 0 files changed\n")
  67. class ReadGitAmPatch(TestCase):
  68. def test_extract(self):
  69. text = """From ff643aae102d8870cac88e8f007e70f58f3a7363 Mon Sep 17 00:00:00 2001
  70. From: Jelmer Vernooij <jelmer@samba.org>
  71. Date: Thu, 15 Apr 2010 15:40:28 +0200
  72. Subject: [PATCH 1/2] Remove executable bit from prey.ico (triggers a lintian warning).
  73. ---
  74. pixmaps/prey.ico | Bin 9662 -> 9662 bytes
  75. 1 files changed, 0 insertions(+), 0 deletions(-)
  76. mode change 100755 => 100644 pixmaps/prey.ico
  77. --
  78. 1.7.0.4
  79. """
  80. c, diff, version = git_am_patch_split(StringIO(text))
  81. self.assertEquals("Jelmer Vernooij <jelmer@samba.org>", c.committer)
  82. self.assertEquals("Jelmer Vernooij <jelmer@samba.org>", c.author)
  83. self.assertEquals("Remove executable bit from prey.ico "
  84. "(triggers a lintian warning).\n", c.message)
  85. self.assertEquals(""" pixmaps/prey.ico | Bin 9662 -> 9662 bytes
  86. 1 files changed, 0 insertions(+), 0 deletions(-)
  87. mode change 100755 => 100644 pixmaps/prey.ico
  88. """, diff)
  89. self.assertEquals("1.7.0.4", version)
  90. def test_extract_spaces(self):
  91. text = """From ff643aae102d8870cac88e8f007e70f58f3a7363 Mon Sep 17 00:00:00 2001
  92. From: Jelmer Vernooij <jelmer@samba.org>
  93. Date: Thu, 15 Apr 2010 15:40:28 +0200
  94. Subject: [Dulwich-users] [PATCH] Added unit tests for
  95. dulwich.object_store.tree_lookup_path.
  96. * dulwich/tests/test_object_store.py
  97. (TreeLookupPathTests): This test case contains a few tests that ensure the
  98. tree_lookup_path function works as expected.
  99. ---
  100. pixmaps/prey.ico | Bin 9662 -> 9662 bytes
  101. 1 files changed, 0 insertions(+), 0 deletions(-)
  102. mode change 100755 => 100644 pixmaps/prey.ico
  103. --
  104. 1.7.0.4
  105. """
  106. c, diff, version = git_am_patch_split(StringIO(text))
  107. self.assertEquals('Added unit tests for dulwich.object_store.tree_lookup_path.\n\n* dulwich/tests/test_object_store.py\n (TreeLookupPathTests): This test case contains a few tests that ensure the\n tree_lookup_path function works as expected.\n', c.message)
  108. def test_extract_pseudo_from_header(self):
  109. text = """From ff643aae102d8870cac88e8f007e70f58f3a7363 Mon Sep 17 00:00:00 2001
  110. From: Jelmer Vernooij <jelmer@samba.org>
  111. Date: Thu, 15 Apr 2010 15:40:28 +0200
  112. Subject: [Dulwich-users] [PATCH] Added unit tests for
  113. dulwich.object_store.tree_lookup_path.
  114. From: Jelmer Vernooy <jelmer@debian.org>
  115. * dulwich/tests/test_object_store.py
  116. (TreeLookupPathTests): This test case contains a few tests that ensure the
  117. tree_lookup_path function works as expected.
  118. ---
  119. pixmaps/prey.ico | Bin 9662 -> 9662 bytes
  120. 1 files changed, 0 insertions(+), 0 deletions(-)
  121. mode change 100755 => 100644 pixmaps/prey.ico
  122. --
  123. 1.7.0.4
  124. """
  125. c, diff, version = git_am_patch_split(StringIO(text))
  126. self.assertEquals("Jelmer Vernooy <jelmer@debian.org>", c.author)
  127. self.assertEquals('Added unit tests for dulwich.object_store.tree_lookup_path.\n\n* dulwich/tests/test_object_store.py\n (TreeLookupPathTests): This test case contains a few tests that ensure the\n tree_lookup_path function works as expected.\n', c.message)
  128. def test_extract_no_version_tail(self):
  129. text = """From ff643aae102d8870cac88e8f007e70f58f3a7363 Mon Sep 17 00:00:00 2001
  130. From: Jelmer Vernooij <jelmer@samba.org>
  131. Date: Thu, 15 Apr 2010 15:40:28 +0200
  132. Subject: [Dulwich-users] [PATCH] Added unit tests for
  133. dulwich.object_store.tree_lookup_path.
  134. From: Jelmer Vernooy <jelmer@debian.org>
  135. ---
  136. pixmaps/prey.ico | Bin 9662 -> 9662 bytes
  137. 1 files changed, 0 insertions(+), 0 deletions(-)
  138. mode change 100755 => 100644 pixmaps/prey.ico
  139. """
  140. c, diff, version = git_am_patch_split(StringIO(text))
  141. self.assertEquals(None, version)
  142. def test_extract_mercurial(self):
  143. raise SkipTest("git_am_patch_split doesn't handle Mercurial patches properly yet")
  144. expected_diff = """diff --git a/dulwich/tests/test_patch.py b/dulwich/tests/test_patch.py
  145. --- a/dulwich/tests/test_patch.py
  146. +++ b/dulwich/tests/test_patch.py
  147. @@ -158,7 +158,7 @@
  148. '''
  149. c, diff, version = git_am_patch_split(StringIO(text))
  150. - self.assertIs(None, version)
  151. + self.assertEquals(None, version)
  152. class DiffTests(TestCase):
  153. """
  154. text = """From dulwich-users-bounces+jelmer=samba.org@lists.launchpad.net Mon Nov 29 00:58:18 2010
  155. Date: Sun, 28 Nov 2010 17:57:27 -0600
  156. From: Augie Fackler <durin42@gmail.com>
  157. To: dulwich-users <dulwich-users@lists.launchpad.net>
  158. Subject: [Dulwich-users] [PATCH] test_patch: fix tests on Python 2.6
  159. Content-Transfer-Encoding: 8bit
  160. Change-Id: I5e51313d4ae3a65c3f00c665002a7489121bb0d6
  161. %s
  162. _______________________________________________
  163. Mailing list: https://launchpad.net/~dulwich-users
  164. Post to : dulwich-users@lists.launchpad.net
  165. Unsubscribe : https://launchpad.net/~dulwich-users
  166. More help : https://help.launchpad.net/ListHelp
  167. """ % expected_diff
  168. c, diff, version = git_am_patch_split(StringIO(text))
  169. self.assertEquals(expected_diff, diff)
  170. self.assertEquals(None, version)
  171. class DiffTests(TestCase):
  172. """Tests for write_blob_diff and write_tree_diff."""
  173. def test_blob_diff(self):
  174. f = StringIO()
  175. write_blob_diff(f, ("foo.txt", 0644, Blob.from_string("old\nsame\n")),
  176. ("bar.txt", 0644, Blob.from_string("new\nsame\n")))
  177. self.assertEquals([
  178. "diff --git a/foo.txt b/bar.txt",
  179. "index 3b0f961..a116b51 644",
  180. "--- a/foo.txt",
  181. "+++ b/bar.txt",
  182. "@@ -1,2 +1,2 @@",
  183. "-old",
  184. "+new",
  185. " same"
  186. ], f.getvalue().splitlines())
  187. def test_blob_add(self):
  188. f = StringIO()
  189. write_blob_diff(f, (None, None, None),
  190. ("bar.txt", 0644, Blob.from_string("new\nsame\n")))
  191. self.assertEquals([
  192. 'diff --git /dev/null b/bar.txt',
  193. 'new mode 644',
  194. 'index 0000000..a116b51 644',
  195. '--- /dev/null',
  196. '+++ b/bar.txt',
  197. '@@ -1,0 +1,2 @@',
  198. '+new',
  199. '+same'
  200. ], f.getvalue().splitlines())
  201. def test_blob_remove(self):
  202. f = StringIO()
  203. write_blob_diff(f, ("bar.txt", 0644, Blob.from_string("new\nsame\n")),
  204. (None, None, None))
  205. self.assertEquals([
  206. 'diff --git a/bar.txt /dev/null',
  207. 'deleted mode 644',
  208. 'index a116b51..0000000',
  209. '--- a/bar.txt',
  210. '+++ /dev/null',
  211. '@@ -1,2 +1,0 @@',
  212. '-new',
  213. '-same'
  214. ], f.getvalue().splitlines())
  215. def test_tree_diff(self):
  216. f = StringIO()
  217. store = MemoryObjectStore()
  218. added = Blob.from_string("add\n")
  219. removed = Blob.from_string("removed\n")
  220. changed1 = Blob.from_string("unchanged\nremoved\n")
  221. changed2 = Blob.from_string("unchanged\nadded\n")
  222. unchanged = Blob.from_string("unchanged\n")
  223. tree1 = Tree()
  224. tree1.add("removed.txt", 0644, removed.id)
  225. tree1.add("changed.txt", 0644, changed1.id)
  226. tree1.add("unchanged.txt", 0644, changed1.id)
  227. tree2 = Tree()
  228. tree2.add("added.txt", 0644, added.id)
  229. tree2.add("changed.txt", 0644, changed2.id)
  230. tree2.add("unchanged.txt", 0644, changed1.id)
  231. store.add_objects([(o, None) for o in [
  232. tree1, tree2, added, removed, changed1, changed2, unchanged]])
  233. write_tree_diff(f, store, tree1.id, tree2.id)
  234. self.assertEquals([
  235. 'diff --git /dev/null b/added.txt',
  236. 'new mode 644',
  237. 'index 0000000..76d4bb8 644',
  238. '--- /dev/null',
  239. '+++ b/added.txt',
  240. '@@ -1,0 +1,1 @@',
  241. '+add',
  242. 'diff --git a/changed.txt b/changed.txt',
  243. 'index bf84e48..1be2436 644',
  244. '--- a/changed.txt',
  245. '+++ b/changed.txt',
  246. '@@ -1,2 +1,2 @@',
  247. ' unchanged',
  248. '-removed',
  249. '+added',
  250. 'diff --git a/removed.txt /dev/null',
  251. 'deleted mode 644',
  252. 'index 2c3f0b3..0000000',
  253. '--- a/removed.txt',
  254. '+++ /dev/null',
  255. '@@ -1,1 +1,0 @@',
  256. '-removed',
  257. ], f.getvalue().splitlines())
  258. def test_tree_diff_submodule(self):
  259. f = StringIO()
  260. store = MemoryObjectStore()
  261. tree1 = Tree()
  262. tree1.add("asubmodule", S_IFGITLINK,
  263. "06d0bdd9e2e20377b3180e4986b14c8549b393e4")
  264. tree2 = Tree()
  265. tree2.add("asubmodule", S_IFGITLINK,
  266. "cc975646af69f279396d4d5e1379ac6af80ee637")
  267. store.add_objects([(o, None) for o in [tree1, tree2]])
  268. write_tree_diff(f, store, tree1.id, tree2.id)
  269. self.assertEquals([
  270. 'diff --git a/asubmodule b/asubmodule',
  271. 'index 06d0bdd..cc97564 160000',
  272. '--- a/asubmodule',
  273. '+++ b/asubmodule',
  274. '@@ -1,1 +1,1 @@',
  275. '-Submodule commit 06d0bdd9e2e20377b3180e4986b14c8549b393e4',
  276. '+Submodule commit cc975646af69f279396d4d5e1379ac6af80ee637',
  277. ], f.getvalue().splitlines())
  278. def test_object_diff_blob(self):
  279. f = StringIO()
  280. b1 = Blob.from_string("old\nsame\n")
  281. b2 = Blob.from_string("new\nsame\n")
  282. store = MemoryObjectStore()
  283. store.add_objects([(b1, None), (b2, None)])
  284. write_object_diff(f, store, ("foo.txt", 0644, b1.id),
  285. ("bar.txt", 0644, b2.id))
  286. self.assertEquals([
  287. "diff --git a/foo.txt b/bar.txt",
  288. "index 3b0f961..a116b51 644",
  289. "--- a/foo.txt",
  290. "+++ b/bar.txt",
  291. "@@ -1,2 +1,2 @@",
  292. "-old",
  293. "+new",
  294. " same"
  295. ], f.getvalue().splitlines())
  296. def test_object_diff_add_blob(self):
  297. f = StringIO()
  298. store = MemoryObjectStore()
  299. b2 = Blob.from_string("new\nsame\n")
  300. store.add_object(b2)
  301. write_object_diff(f, store, (None, None, None),
  302. ("bar.txt", 0644, b2.id))
  303. self.assertEquals([
  304. 'diff --git /dev/null b/bar.txt',
  305. 'new mode 644',
  306. 'index 0000000..a116b51 644',
  307. '--- /dev/null',
  308. '+++ b/bar.txt',
  309. '@@ -1,0 +1,2 @@',
  310. '+new',
  311. '+same'
  312. ], f.getvalue().splitlines())
  313. def test_object_diff_remove_blob(self):
  314. f = StringIO()
  315. b1 = Blob.from_string("new\nsame\n")
  316. store = MemoryObjectStore()
  317. store.add_object(b1)
  318. write_object_diff(f, store, ("bar.txt", 0644, b1.id),
  319. (None, None, None))
  320. self.assertEquals([
  321. 'diff --git a/bar.txt /dev/null',
  322. 'deleted mode 644',
  323. 'index a116b51..0000000',
  324. '--- a/bar.txt',
  325. '+++ /dev/null',
  326. '@@ -1,2 +1,0 @@',
  327. '-new',
  328. '-same'
  329. ], f.getvalue().splitlines())
  330. def test_object_diff_kind_change(self):
  331. f = StringIO()
  332. b1 = Blob.from_string("new\nsame\n")
  333. store = MemoryObjectStore()
  334. store.add_object(b1)
  335. write_object_diff(f, store, ("bar.txt", 0644, b1.id),
  336. ("bar.txt", 0160000, "06d0bdd9e2e20377b3180e4986b14c8549b393e4"))
  337. self.assertEquals([
  338. 'diff --git a/bar.txt b/bar.txt',
  339. 'old mode 644',
  340. 'new mode 160000',
  341. 'index a116b51..06d0bdd 160000',
  342. '--- a/bar.txt',
  343. '+++ b/bar.txt',
  344. '@@ -1,2 +1,1 @@',
  345. '-new',
  346. '-same',
  347. '+Submodule commit 06d0bdd9e2e20377b3180e4986b14c8549b393e4',
  348. ], f.getvalue().splitlines())