Add some unit tests. They don't pass yet.
Review URL: http://codereview.chromium.org/6612011 git-svn-id: svn://svn.chromium.org/chrome/trunk/tools/depot_tools@76980 0039d316-1c4b-4281-b951-d872f2087c98experimental/szager/collated-output
parent
898a10e4bb
commit
3c08dd45cc
@ -0,0 +1,70 @@
|
||||
#!/usr/bin/python
|
||||
# Copyright (c) 2011 The Chromium Authors. All rights reserved.
|
||||
# Use of this source code is governed by a BSD-style license that can be
|
||||
# found in the LICENSE file.
|
||||
|
||||
import errno
|
||||
import os
|
||||
import re
|
||||
import StringIO
|
||||
|
||||
def _RaiseNotFound(path):
|
||||
raise IOError(errno.ENOENT, path, os.strerror(errno.ENOENT))
|
||||
|
||||
|
||||
class MockFileSystem(object):
|
||||
"""Stripped-down version of WebKit's webkitpy.common.system.filesystem_mock
|
||||
|
||||
Implements a filesystem-like interface on top of a dict of filenames ->
|
||||
file contents. A file content value of None indicates that the file should
|
||||
not exist (IOError will be raised if it is opened;
|
||||
reading from a missing key raises a KeyError, not an IOError."""
|
||||
|
||||
def __init__(self, files=None):
|
||||
self.files = files or {}
|
||||
self.written_files = {}
|
||||
self._sep = '/'
|
||||
|
||||
@property
|
||||
def sep(self):
|
||||
return self._sep
|
||||
|
||||
def _split(self, path):
|
||||
return path.rsplit(self.sep, 1)
|
||||
|
||||
def dirname(self, path):
|
||||
if not self.sep in path:
|
||||
return ''
|
||||
return self._split(path)[0]
|
||||
|
||||
def exists(self, path):
|
||||
return self.isfile(path) or self.isdir(path)
|
||||
|
||||
def isfile(self, path):
|
||||
return path in self.files and self.files[path] is not None
|
||||
|
||||
def isdir(self, path):
|
||||
if path in self.files:
|
||||
return False
|
||||
if not path.endswith(self.sep):
|
||||
path += self.sep
|
||||
|
||||
# We need to use a copy of the keys here in order to avoid switching
|
||||
# to a different thread and potentially modifying the dict in
|
||||
# mid-iteration.
|
||||
files = self.files.keys()[:]
|
||||
return any(f.startswith(path) for f in files)
|
||||
|
||||
def join(self, *comps):
|
||||
# FIXME: might want tests for this and/or a better comment about how
|
||||
# it works.
|
||||
return re.sub(re.escape(os.path.sep), self.sep, os.path.join(*comps))
|
||||
|
||||
def open_for_reading(self, path):
|
||||
return StringIO.StringIO(self.read_binary_file(path))
|
||||
|
||||
def read_binary_file(self, path):
|
||||
# Intentionally raises KeyError if we don't recognize the path.
|
||||
if self.files[path] is None:
|
||||
_RaiseNotFound(path)
|
||||
return self.files[path]
|
||||
@ -0,0 +1,135 @@
|
||||
#!/usr/bin/python
|
||||
# Copyright (c) 2011 The Chromium Authors. All rights reserved.
|
||||
# Use of this source code is governed by a BSD-style license that can be
|
||||
# found in the LICENSE file.
|
||||
|
||||
"""Unit tests for owners.py."""
|
||||
|
||||
import unittest
|
||||
|
||||
import owners
|
||||
from tests import filesystem_mock
|
||||
|
||||
|
||||
def test_repo():
|
||||
return filesystem_mock.MockFileSystem(files={
|
||||
'/DEPS' : '',
|
||||
'/OWNERS':
|
||||
('# OWNERS'
|
||||
'*\n'),
|
||||
'/base/vlog.h':
|
||||
'// vlog.h\n',
|
||||
'/chrome/OWNERS':
|
||||
('ben@example.com\n'
|
||||
'brettw@example.com\n'),
|
||||
'/chrome/gpu/OWNERS':
|
||||
('kbr@example.com\n'),
|
||||
'/chrome/gpu/gpu_channel.h':
|
||||
'// gpu_channel.h\n',
|
||||
'/chrome/renderer/OWNERS':
|
||||
('pkasting@example.com\n'),
|
||||
'/chrome/renderer/gpu/gpu_channel_host.h':
|
||||
'// gpu_channel_host.h\n',
|
||||
'/chrome/renderer/safe_browsing/scorer.h':
|
||||
'// scorer.h\n',
|
||||
'/content/OWNERS':
|
||||
('set noparent\n'
|
||||
'jam@example.com\n'
|
||||
'darin@example.com\n'),
|
||||
'/content/content.gyp':
|
||||
'# content.gyp\n',
|
||||
})
|
||||
|
||||
|
||||
ben = 'ben@example.com'
|
||||
brett = 'brettw@example.com'
|
||||
darin = 'darin@example.com'
|
||||
jam = 'jam@example.com'
|
||||
kbr = 'kbr@example.com'
|
||||
pkasting = 'pkasting@example.com'
|
||||
|
||||
|
||||
class OwnersDatabaseTest(unittest.TestCase):
|
||||
def setUp(self):
|
||||
self.repo = test_repo()
|
||||
self.files = self.repo.files
|
||||
self.root = '/'
|
||||
|
||||
# pylint: disable=W0108
|
||||
self.fopen = self.repo.open_for_reading
|
||||
|
||||
def db(self, root=None, fopen=None, os_path=None):
|
||||
root = root or self.root
|
||||
fopen = fopen or self.fopen
|
||||
os_path = os_path or self.repo
|
||||
return owners.Database(root, fopen, os_path)
|
||||
|
||||
def assertReviewersFor(self, files, expected_reviewers):
|
||||
db = self.db()
|
||||
self.assertEquals(db.ReviewersFor(set(files)), set(expected_reviewers))
|
||||
|
||||
def assertCoveredBy(self, files, reviewers):
|
||||
db = self.db()
|
||||
self.assertTrue(db.FilesAreCoveredBy(set(files), set(reviewers)))
|
||||
|
||||
def assertNotCoveredBy(self, files, reviewers, unreviewed_files):
|
||||
db = self.db()
|
||||
self.assertEquals(db.FilesNotCoveredBy(set(files), set(reviewers)),
|
||||
set(unreviewed_files))
|
||||
|
||||
def test_constructor(self):
|
||||
self.assertNotEquals(self.db(), None)
|
||||
|
||||
def test_owners_for(self):
|
||||
self.assertReviewersFor(['DEPS'], [owners.ANYONE])
|
||||
self.assertReviewersFor(['content/content.gyp'], [jam, darin])
|
||||
self.assertReviewersFor(['chrome/gpu/gpu_channel.h'], [kbr])
|
||||
|
||||
def test_covered_by(self):
|
||||
self.assertCoveredBy(['DEPS'], [jam])
|
||||
self.assertCoveredBy(['DEPS'], [darin])
|
||||
self.assertCoveredBy(['content/content.gyp'], [jam])
|
||||
self.assertCoveredBy(['chrome/gpu/OWNERS'], [kbr])
|
||||
self.assertCoveredBy(['chrome/gpu/OWNERS'], [ben])
|
||||
|
||||
def test_not_covered_by(self):
|
||||
self.assertNotCoveredBy(['DEPS'], [], ['DEPS'])
|
||||
self.assertNotCoveredBy(['content/content.gyp'], [ben],
|
||||
['content/content.gyp'])
|
||||
self.assertNotCoveredBy(
|
||||
['chrome/gpu/gpu_channel.h', 'chrome/renderer/gpu/gpu_channel_host.h'],
|
||||
[pkasting], ['chrome/gpu/gpu_channel.h'])
|
||||
self.assertNotCoveredBy(
|
||||
['chrome/gpu/gpu_channel.h', 'chrome/renderer/gpu/gpu_channel_host.h'],
|
||||
[ben], [])
|
||||
|
||||
def test_comments_in_owners_file(self):
|
||||
# pylint: disable=W0212
|
||||
db = self.db()
|
||||
# Tests that this doesn't raise an error.
|
||||
db._ReadOwnersFile('OWNERS', 'DEPS')
|
||||
|
||||
def test_syntax_error_in_owners_file(self):
|
||||
# pylint: disable=W0212
|
||||
db = self.db()
|
||||
self.files['/foo/OWNERS'] = '{}\n'
|
||||
self.files['/foo/DEPS'] = '# DEPS\n'
|
||||
self.assertRaises(owners.SyntaxErrorInOwnersFile, db._ReadOwnersFile,
|
||||
'/foo/OWNERS', '/foo/DEPS')
|
||||
|
||||
self.files['/bar/OWNERS'] = 'set myparentislinus\n'
|
||||
self.files['/bar/DEPS'] = '# DEPS\n'
|
||||
self.assertRaises(owners.SyntaxErrorInOwnersFile, db._ReadOwnersFile,
|
||||
'/bar/OWNERS', '/bar/DEPS')
|
||||
|
||||
def test_owners_propagates_down(self):
|
||||
self.assertCoveredBy(['/chrome/renderer/gpu/gpu_channel_host.h'],
|
||||
[pkasting])
|
||||
|
||||
def test_set_noparent(self):
|
||||
self.assertNotCoveredBy(['/content/content.gyp'], [pkasting],
|
||||
['/content/content.gyp'])
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
Loading…
Reference in New Issue