Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(233)

Side by Side Diff: appengine/findit/common/test/git_repository_test.py

Issue 2344443005: [Findit] Factoring the gitiles (etc) stuff out into its own directory (Closed)
Patch Set: reordering imports Created 4 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « appengine/findit/common/test/diff_test.py ('k') | appengine/findit/crash/callstack.py » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 # Copyright 2014 The Chromium Authors. All rights reserved.
2 # Use of this source code is governed by a BSD-style license that can be
3 # found in the LICENSE file.
4
5 import base64
6 from datetime import datetime
7 import json
8 import re
9
10 from testing_utils import testing
11
12 from common import git_repository
13 from common import retry_http_client
14 from common.change_log import ChangeLog
15
16
17 COMMIT_MESSAGE = ('Add popover for snapshot canvas log.\n\n'
18 'Review URL: https://codereview.chromium.org/320423004\n\n'
19 'Review URL: https://codereview.chromium.org/328113005\n\n'
20 'Cr-Commit-Position: refs/heads/master@{#175976}')
21
22 COMMIT_LOG = """)]}'
23 {
24 "commit": "bcfd5a12eea05588aee98b7cf7e032d8cb5b58bb",
25 "tree": "481fd0f3bdf6eda5ca29ec6cbc6aa476b3684143",
26 "parents": [
27 "42a94bb5e2ef8525d7dadbd8eae37fe7cb8d77d0"
28 ],
29 "author": {
30 "name": "test1@chromium.org",
31 "email": "test1@chromium.org@bbb929c8-8fbe-4397-9dbb-9b2b20218538",
32 "time": "Wed Jun 11 19:35:32 2014 -0400"
33 },
34 "committer": {
35 "name": "test1@chromium.org",
36 "email": "test1@chromium.org",
37 "time": "Wed Jun 11 19:35:32 2014"
38 },
39 "message": %s,
40 "tree_diff": [
41 {
42 "type": "add",
43 "old_id": "f71f1167c2204626057d26912b8a2ff096fe4bd2",
44 "old_mode": 33188,
45 "old_path": "/dev/null",
46 "new_id": "165fb11e0658f41d66038199056a53bcfab5dda0",
47 "new_mode": 33188,
48 "new_path": "Source/devtools/front_end/layers/added_file.js"
49 },
50 {
51 "type": "delete",
52 "old_id": "f71f1167c2204626057d26912b8a2ff096fe4bd3",
53 "old_mode": 33188,
54 "old_path": "Source/devtools/front_end/layers/deleted_file.js",
55 "new_id": "165fb11e0658f41d66038199056a53bcfab5dda1",
56 "new_mode": 33188,
57 "new_path": "/dev/null"
58 },
59 {
60 "type": "modify",
61 "old_id": "f71f1167c2204626057d26912b8a2ff096fe4bd1",
62 "old_mode": 33188,
63 "old_path": "Source/devtools/front_end/layers/modified_file.js",
64 "new_id": "165fb11e0658f41d66038199056a53bcfab5dda9",
65 "new_mode": 33188,
66 "new_path": "Source/devtools/front_end/layers/modified_file.js"
67 },
68 {
69 "type": "copy",
70 "old_id": "f71f1167c2204626057d26912b8a2ff096fe4bd4",
71 "old_mode": 33188,
72 "old_path": "Source/devtools/front_end/layers/file.js",
73 "new_id": "165fb11e0658f41d66038199056a53bcfab5dda2",
74 "new_mode": 33188,
75 "new_path": "Source/devtools/front_end/layers/copied_file.js"
76 },
77 {
78 "type": "rename",
79 "old_id": "f71f1167c2204626057d26912b8a2ff096fe4bd5",
80 "old_mode": 33188,
81 "old_path": "Source/devtools/front_end/layers/file.js",
82 "new_id": "165fb11e0658f41d66038199056a53bcfab5dda3",
83 "new_mode": 33188,
84 "new_path": "Source/devtools/front_end/layers/renamed_file.js"
85 }
86 ]
87 }""" % json.JSONEncoder().encode(COMMIT_MESSAGE)
88
89 EXPECTED_CHANGE_LOG_JSON = {
90 'author_name': 'test1@chromium.org',
91 'message': COMMIT_MESSAGE,
92 'committer_email': 'test1@chromium.org',
93 'commit_position': 175976,
94 'author_email': 'test1@chromium.org',
95 'touched_files': [
96 {
97 'change_type': 'add',
98 'new_path': 'Source/devtools/front_end/layers/added_file.js',
99 'old_path': '/dev/null'
100 },
101 {
102 'change_type': 'delete',
103 'new_path': '/dev/null',
104 'old_path': 'Source/devtools/front_end/layers/deleted_file.js'
105 },
106 {
107 'change_type': 'modify',
108 'new_path': 'Source/devtools/front_end/layers/modified_file.js',
109 'old_path': 'Source/devtools/front_end/layers/modified_file.js'
110 },
111 {
112 'change_type': 'copy',
113 'new_path': 'Source/devtools/front_end/layers/copied_file.js',
114 'old_path': 'Source/devtools/front_end/layers/file.js'
115 },
116 {
117 'change_type': 'rename',
118 'new_path': 'Source/devtools/front_end/layers/renamed_file.js',
119 'old_path': 'Source/devtools/front_end/layers/file.js'
120 }
121 ],
122 'author_time': datetime(2014, 06, 11, 23, 35, 32),
123 'committer_time': datetime(2014, 06, 11, 19, 35, 32),
124 'commit_url':
125 'https://repo.test/+/bcfd5a12eea05588aee98b7cf7e032d8cb5b58bb',
126 'code_review_url': 'https://codereview.chromium.org/328113005',
127 'committer_name': 'test1@chromium.org',
128 'revision': 'bcfd5a12eea05588aee98b7cf7e032d8cb5b58bb',
129 'reverted_revision': None
130 }
131
132 COMMIT_LOG_WITH_UNKNOWN_FILE_CHANGE_TYPE = """)]}'
133 {
134 "commit": "bcfd5a12eea05588aee98b7cf7e032d8cb5b58bb",
135 "tree": "481fd0f3bdf6eda5ca29ec6cbc6aa476b3684143",
136 "parents": [
137 "42a94bb5e2ef8525d7dadbd8eae37fe7cb8d77d0"
138 ],
139 "author": {
140 "name": "test1@chromium.org",
141 "email": "test1@chromium.org@bbb929c8-8fbe-4397-9dbb-9b2b20218538",
142 "time": "Wed Jun 11 19:35:32 2014"
143 },
144 "committer": {
145 "name": "test1@chromium.org",
146 "email": "test1@chromium.org@bbb929c8-8fbe-4397-9dbb-9b2b20218538",
147 "time": "Wed Jun 11 19:35:32 2014"
148 },
149 "message": "message",
150 "tree_diff": [
151 {
152 "type": "unknown_change_type",
153 "old_id": "f71f1167c2204626057d26912b8a2ff096fe4bd2",
154 "old_mode": 33188,
155 "old_path": "/dev/null",
156 "new_id": "165fb11e0658f41d66038199056a53bcfab5dda0",
157 "new_mode": 33188,
158 "new_path": "Source/devtools/front_end/layers/added_file.js"
159 }
160 ]
161 }"""
162
163 GITILES_FILE_BLAME_RESULT = """)]}'
164 {
165 "regions": [
166 {
167 "start": 1,
168 "count": 6,
169 "path": "chrome/test/chromedriver/element_commands.cc",
170 "commit": "584ae1f26b070150f65a03dba75fc8af6b6f6ece",
171 "author": {
172 "name": "test2@chromium.org",
173 "email": "test2@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98",
174 "time": "2013-02-11 20:18:51"
175 }
176 },
177 {
178 "start": 7,
179 "count": 1,
180 "path": "chrome/test/chromedriver/element_commands.cc",
181 "commit": "030b5d9bb7d6c9f673cd8f0c86d8f1e921de7076",
182 "author": {
183 "name": "test3@chromium.org",
184 "email": "test3@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98",
185 "time": "2014-02-06 10:02:10 +0400"
186 }
187 },
188 {
189 "start": 8,
190 "count": 1,
191 "path": "chrome/test/chromedriver/element_commands.cc",
192 "commit": "584ae1f26b070150f65a03dba75fc8af6b6f6ece",
193 "author": {
194 "name": "test2@chromium.org",
195 "email": "test2@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98",
196 "time": "2013-02-11 20:18:51"
197 }
198 }
199 ]
200 }"""
201
202 EXPECTED_FILE_BLAME_JSON = {
203 'regions': [
204 {
205 'count': 6,
206 'author_email': u'test2@chromium.org',
207 'author_time': datetime(2013, 02, 11, 20, 18, 51),
208 'author_name': u'test2@chromium.org',
209 'start': 1,
210 'revision': u'584ae1f26b070150f65a03dba75fc8af6b6f6ece'
211 },
212 {
213 'count': 1,
214 'author_email': u'test3@chromium.org',
215 'author_time': datetime(2014, 02, 06, 06, 02, 10),
216 'author_name': u'test3@chromium.org',
217 'start': 7,
218 'revision': u'030b5d9bb7d6c9f673cd8f0c86d8f1e921de7076'
219 },
220 {
221 'count': 1,
222 'author_email': u'test2@chromium.org',
223 'author_time': datetime(2013, 02, 11, 20, 18, 51),
224 'author_name': u'test2@chromium.org',
225 'start': 8,
226 'revision': u'584ae1f26b070150f65a03dba75fc8af6b6f6ece'
227 }
228 ],
229 'path': 'a/b/c.cc',
230 'revision': 'dummy_abcd1234'
231 }
232
233 DUMMY_CHANGELOG_JSON = {
234 'author_name': 'test@chromium.org',
235 'message': 'dummy',
236 'committer_email': 'test@chromium.org',
237 'commit_position': 175976,
238 'author_email': 'test1@chromium.org',
239 'touched_files': [
240 {
241 'change_type': 'add',
242 'new_path': 'Source/devtools/added_file.js',
243 'old_path': '/dev/null'
244 }
245 ],
246 'author_time': datetime(2016, 01, 11, 23, 35, 32),
247 'committer_time': datetime(2016, 01, 11, 19, 35, 32),
248 'commit_url':
249 'https://repo.test/+/bcfd',
250 'code_review_url': 'https://codereview.chromium.org/328113005',
251 'committer_name': 'test1@chromium.org',
252 'revision': 'bcfd',
253 'reverted_revision': None
254 }
255
256
257 class HttpClientForGit(retry_http_client.RetryHttpClient):
258
259 def __init__(self):
260 super(HttpClientForGit, self).__init__()
261 self.response_for_url = {}
262
263 def SetResponseForUrl(self, url, response):
264 self.response_for_url[url] = response
265
266 def GetBackoff(self, *_): # pragma: no cover
267 """Override to avoid sleep."""
268 return 0
269
270 def _Get(self, url, *_):
271 response = self.response_for_url.get(url)
272 if response is None:
273 return 404, 'Not Found'
274 else:
275 return 200, response
276
277 def _Post(self, *_): # pragma: no cover
278 pass
279
280 def _Put(self, *_): # pragma: no cover
281 pass
282
283
284 class GitRepositoryTest(testing.AppengineTestCase):
285
286 def setUp(self):
287 super(GitRepositoryTest, self).setUp()
288 self.http_client_for_git = HttpClientForGit()
289 self.repo_url = 'https://repo.test'
290 self.git_repo = git_repository.GitRepository(self.repo_url,
291 self.http_client_for_git)
292
293 def testGitRepositoryPropertySetters(self):
294 http_client_for_git = HttpClientForGit()
295 git_repo = git_repository.GitRepository(http_client=http_client_for_git)
296 git_repo.repo_url = 'https://repo'
297 self.assertEqual(git_repo.repo_url, 'https://repo')
298
299 self.assertEqual(git_repo. http_client, http_client_for_git)
300
301 def testExtractCommitPositionAndCodeReviewUrl(self):
302 testcases = [
303 {
304 'message':
305 'balabala...\n'
306 '\n'
307 'BUG=604502\n'
308 '\n'
309 'Review-Url: https://codereview.chromium.org/1927593004\n'
310 'Cr-Commit-Position: refs/heads/master@{#390254}\n',
311 'commit_position': 390254,
312 'code_review_url': 'https://codereview.chromium.org/1927593004',
313 },
314 {
315 'message':
316 'balabala...\n'
317 '\n'
318 'BUG=409934\n'
319 '\n'
320 'Review URL: https://codereview.chromium.org/547753003\n'
321 '\n'
322 'Cr-Commit-Position: refs/heads/master@{#293661}',
323 'commit_position': 293661,
324 'code_review_url': 'https://codereview.chromium.org/547753003',
325 },
326 {
327 'message':
328 'balabala...\n'
329 '\n'
330 'balabala...\n'
331 '\n'
332 'R=test4@chromium.org\n'
333 '\n'
334 'Review URL: https://codereview.chromium.org/469523002\n'
335 '\n'
336 'Cr-Commit-Position: refs/heads/master@{#289120}',
337 'commit_position': 289120,
338 'code_review_url': 'https://codereview.chromium.org/469523002',
339 },
340 {
341 'message': None,
342 'commit_position': None,
343 'code_review_url': None
344 }
345 ]
346
347 for testcase in testcases:
348 (commit_position,
349 code_review_url) = self.git_repo.ExtractCommitPositionAndCodeReviewUrl(
350 testcase['message'])
351 self.assertEqual(commit_position, testcase['commit_position'])
352 self.assertEqual(code_review_url, testcase['code_review_url'])
353
354 def testEndingSlashInRepoUrl(self):
355 git_repo1 = git_repository.GitRepository(self.repo_url,
356 self.http_client_for_git)
357 self.assertEqual(self.repo_url, git_repo1.repo_url)
358
359 git_repo2 = git_repository.GitRepository('%s/' % self.repo_url,
360 self.http_client_for_git)
361 self.assertEqual(self.repo_url, git_repo2.repo_url)
362
363 def testMalformattedJsonReponse(self):
364 self.http_client_for_git.SetResponseForUrl(
365 '%s/+/%s?format=json' % (self.repo_url, 'aaa'), 'abcde{"a": 1}')
366 self.assertRaisesRegexp(
367 Exception, re.escape('Response does not begin with )]}\'\n'),
368 self.git_repo.GetChangeLog, 'aaa')
369
370 def testGetChangeLog(self):
371 self.http_client_for_git.SetResponseForUrl(
372 '%s/+/%s?format=json' % (
373 self.repo_url, 'bcfd5a12eea05588aee98b7cf7e032d8cb5b58bb'),
374 COMMIT_LOG)
375
376 self.assertIsNone(self.git_repo.GetChangeLog('not_existing_revision'))
377
378 change_log = self.git_repo.GetChangeLog(
379 'bcfd5a12eea05588aee98b7cf7e032d8cb5b58bb')
380 self.assertEqual(EXPECTED_CHANGE_LOG_JSON, change_log.ToDict())
381
382 def testUnknownChangeType(self):
383 self.http_client_for_git.SetResponseForUrl(
384 '%s/+/%s?format=json' % (
385 self.repo_url, 'bcfd5a12eea05588aee98b7cf7e032d8cb5b58bb'),
386 COMMIT_LOG_WITH_UNKNOWN_FILE_CHANGE_TYPE)
387 self.assertRaisesRegexp(
388 Exception, 'Unknown change type "unknown_change_type"',
389 self.git_repo.GetChangeLog, 'bcfd5a12eea05588aee98b7cf7e032d8cb5b58bb')
390
391 def testGetChangeDiff(self):
392 self.assertIsNone(self.git_repo.GetChangeDiff('not_existing_revision'))
393
394 git_revision = 'dummy_abcd1234'
395 original_diff = 'dummy diff'
396 self.http_client_for_git.SetResponseForUrl(
397 '%s/+/%s%%5E%%21/?format=text' % (self.repo_url, git_revision),
398 base64.b64encode(original_diff))
399 diff = self.git_repo.GetChangeDiff(git_revision)
400 self.assertEqual(original_diff, diff)
401
402 def testGetBlame(self):
403 self.assertIsNone(self.git_repo.GetBlame('path', 'not_existing_revision'))
404
405 path = 'a/b/c.cc'
406 git_revision = 'dummy_abcd1234'
407 self.http_client_for_git.SetResponseForUrl(
408 '%s/+blame/%s/%s?format=json' % (self.repo_url, git_revision, path),
409 GITILES_FILE_BLAME_RESULT)
410
411 blame = self.git_repo.GetBlame(path, git_revision)
412 self.assertEqual(EXPECTED_FILE_BLAME_JSON, blame.ToDict())
413
414 def testGetSource(self):
415 self.assertIsNone(self.git_repo.GetSource('path', 'not_existing_revision'))
416
417 path = 'a/b/c.cc'
418 git_revision = 'dummy_abcd1234'
419 original_source = 'dummy source'
420 self.http_client_for_git.SetResponseForUrl(
421 '%s/+/%s/%s?format=text' % (self.repo_url, git_revision, path),
422 base64.b64encode(original_source))
423 source = self.git_repo.GetSource(path, git_revision)
424 self.assertEqual(original_source, source)
425
426 def testTimeConversion(self):
427 datetime_with_timezone = 'Wed Jul 22 19:35:32 2014 +0400'
428 expected_datetime = datetime(2014, 7, 22, 15, 35, 32)
429 utc_datetime = self.git_repo._GetDateTimeFromString(datetime_with_timezone)
430
431 self.assertEqual(expected_datetime, utc_datetime)
432
433 def testGetRevertedRevision(self):
434 message = (
435 'Revert of test1\n\nReason for revert:\nrevert test1\n\n'
436 'Original issue\'s description:\n> test 1\n>\n'
437 '> description of test 1.\n>\n> BUG=none\n> TEST=none\n'
438 '> R=test@chromium.org\n> TBR=test@chromium.org\n>\n'
439 '> Committed: https://chromium.googlesource.com/chromium/src/+/'
440 'c9cc182781484f9010f062859cda048afefefefe\n'
441 '> Cr-Commit-Position: refs/heads/master@{#341992}\n\n'
442 'TBR=test@chromium.org\nNOPRESUBMIT=true\nNOTREECHECKS=true\n'
443 'NOTRY=true\nBUG=none\n\n'
444 'Review URL: https://codereview.chromium.org/1278653002\n\n'
445 'Cr-Commit-Position: refs/heads/master@{#342013}\n')
446
447 reverted_revision = self.git_repo.GetRevertedRevision(message)
448 self.assertEqual('c9cc182781484f9010f062859cda048afefefefe',
449 reverted_revision)
450
451 def testGetRevertedRevisionRevertOfRevert(self):
452 message = (
453 'Revert of Revert\n\nReason for revert:\nRevert of revert\n\n'
454 'Original issue\'s description:\n> test case of revert of revert\n>\n'
455 '> Reason for revert:\n> reason\n>\n> Original issue\'s description:\n'
456 '> > base cl\n> >\n> > R=kalman\n> > BUG=424661\n> >\n'
457 '> > Committed: https://crrev.com/34ea66b8ac1d56dadd670431063857ffdd\n'
458 '> > Cr-Commit-Position: refs/heads/master@{#326953}\n>\n'
459 '> TBR=test@chromium.org\n> NOPRESUBMIT=true\n'
460 '> NOTREECHECKS=true\n> NOTRY=true\n> BUG=424661\n>\n'
461 '> Committed: https://crrev.com/76a7e3446188256ca240dc31f78de29511a'
462 '2c322\n'
463 '> Cr-Commit-Position: refs/heads/master@{#327021}\n\n'
464 'TBR=test@chromium.org\nNOPRESUBMIT=true\n'
465 'NOTREECHECKS=true\nNOTRY=true\nBUG=424661\n\n'
466 'Review URL: https://codereview.chromium.org/1161773008\n\n'
467 'Cr-Commit-Position: refs/heads/master@{#332062}\n')
468
469 reverted_revision = self.git_repo.GetRevertedRevision(message)
470 self.assertEqual('76a7e3446188256ca240dc31f78de29511a2c322',
471 reverted_revision)
472
473 def testGetRevertedRevisionNoRevertedCL(self):
474 message = (
475 'Test for not revert cl\n\n'
476 'TBR=test@chromium.org\nNOPRESUBMIT=true\n'
477 'NOTREECHECKS=true\nNOTRY=true\nBUG=424661\n\n'
478 'Review URL: https://codereview.chromium.org/1161773008\n\n'
479 'Cr-Commit-Position: refs/heads/master@{#332062}\n')
480
481 reverted_revision = self.git_repo.GetRevertedRevision(message)
482 self.assertIsNone(reverted_revision)
483
484 def testGetCommitsBetweenRevisions(self):
485 def _MockSendRequestForJsonResponse(*_):
486 return {
487 'log': [
488 {'commit': '3'},
489 {'commit': '2'},
490 {'commit': '1'}]
491 }
492 self.mock(git_repository.GitRepository, '_SendRequestForJsonResponse',
493 _MockSendRequestForJsonResponse)
494 expected_commits = ['3', '2', '1']
495 actual_commits = self.git_repo.GetCommitsBetweenRevisions('0', '3')
496 self.assertEqual(expected_commits, actual_commits)
497
498 def testGetCommitsBetweenRevisionsWithEmptyData(self):
499 def _MockSendRequestForJsonResponse(*_):
500 return None
501 self.mock(git_repository.GitRepository, '_SendRequestForJsonResponse',
502 _MockSendRequestForJsonResponse)
503 expected_commits = []
504 actual_commits = self.git_repo.GetCommitsBetweenRevisions('0', '3')
505 self.assertEqual(expected_commits, actual_commits)
506
507 def testGetCommitsBetweenRevisionsWithIncompleteData(self):
508 def _MockSendRequestForJsonResponse(*_):
509 return {
510 'log': [
511 {'commit': '1'},
512 {'something_else': '2'}
513 ]
514 }
515 self.mock(git_repository.GitRepository, '_SendRequestForJsonResponse',
516 _MockSendRequestForJsonResponse)
517 expected_commits = ['1']
518 actual_commits = self.git_repo.GetCommitsBetweenRevisions('0', '3')
519 self.assertEqual(expected_commits, actual_commits)
520
521 def testGetCommitsBetweenRevisionsWithPaging(self):
522 def _MockSendRequestForJsonResponse(*args, **_):
523 url = args[1]
524 if '0..3' in url:
525 return {
526 'log': [
527 {'commit': '3'},
528 {'commit': '2'}
529 ],
530 'next': '1'
531 }
532 else:
533 return {
534 'log': [
535 {'commit': '1'}
536 ]
537 }
538
539 self.mock(git_repository.GitRepository, '_SendRequestForJsonResponse',
540 _MockSendRequestForJsonResponse)
541 expected_commits = ['3', '2', '1']
542 actual_commits = self.git_repo.GetCommitsBetweenRevisions('0', '3', n=2)
543 self.assertEqual(expected_commits, actual_commits)
544
545 def testGetChangeLogs(self):
546 def _MockSendRequestForJsonResponse(*_, **kargs):
547 self.assertTrue(bool(kargs))
548 return {'log': [json.loads(COMMIT_LOG[5:])]}
549
550 self.mock(git_repository.GitRepository, '_SendRequestForJsonResponse',
551 _MockSendRequestForJsonResponse)
552
553 changelogs = self.git_repo.GetChangeLogs('0', '2')
554
555 self.assertEqual(len(changelogs), 1)
556 self.assertEqual(changelogs[0].ToDict(), EXPECTED_CHANGE_LOG_JSON)
557
558 def testGetChangeLogsNextPage(self):
559 log1 = json.loads(COMMIT_LOG[5:])
560 log1['commit'] = 'first_commit'
561 log2 = log1.copy()
562 log2['commit'] = 'next_page_commit'
563
564 def _MockSendRequestForJsonResponse(_, url, **kargs):
565 self.assertTrue(bool(kargs))
566 if 'next' in url:
567 return {'log': [log2]}
568
569 return {'log': [log1], 'next': 'next_page_commit'}
570
571 self.mock(git_repository.GitRepository, '_SendRequestForJsonResponse',
572 _MockSendRequestForJsonResponse)
573
574 changelogs = self.git_repo.GetChangeLogs('0', '2')
575
576 self.assertEqual(len(changelogs), 2)
577
578 def testGetWrappedGitRepositoryClass(self):
579 repo = git_repository.GitRepository('http://repo_url', HttpClientForGit())
580
581 self.assertEqual(repo.repo_url, 'http://repo_url')
582 self.assertTrue(isinstance(repo.http_client, HttpClientForGit))
OLDNEW
« no previous file with comments | « appengine/findit/common/test/diff_test.py ('k') | appengine/findit/crash/callstack.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698