blob: 253b0e2e2183981bf39bc20ea9e60fb82b28bb41 [file] [log] [blame]
import PRESUBMIT
import unittest
import re
import os
# There is a MockInputAPI in depot_tools/presubmit_unittest.py
# but it doesn't have a fake in-memory file system, which is useful. :)
# This is modeled after webkitpy's much more complete MockFileSystem:
# pylint: disable=C0301
# http://trac.webkit.org/browser/trunk/Tools/Scripts/webkitpy/common/system/filesystem_mock.py
class MockFileSystem(object):
"""A mock for os.walk as well as os.path for MockInputAPI"""
pathsep = '/'
def __init__(self, files=None, cwd=None):
self.cwd = cwd or '/mock'
# MockFileSystem allows files to have contents, we don't need that though.
self.files = map(self.abspath, files) if files else []
self.dirs = set([])
for f in self.files:
d = self.dirname(f)
while not d in self.dirs:
self.dirs.add(d)
d = self.dirname(d)
def normpath(self, path):
return re.sub(re.escape(os.path.sep), self.pathsep, os.path.normpath(path))
def abspath(self, path):
if os.path.isabs(path):
return self.normpath(path)
return self.abspath(self.join(self.cwd, path))
# This is modified from WebKit's which has a bug that
# dirname('/') == '' which was wrong.
def dirname(self, path):
if self.pathsep not in path:
return ''
parts = path.rsplit(self.pathsep, 1)
if not parts[0]:
return self.pathsep # Is this right on windows?
return parts[0]
def isfile(self, path):
return self.abspath(path) in self.files
# FIXME: This should probably use normpath(path), but we don't have normpath.
def isdir(self, path):
return self.abspath(path) in self.dirs
def exists(self, path):
return self.isfile(path) or self.isdir(path)
def join(self, *comps):
# Slow, but will work on windows, regardless of self.pathsep.
# See WebKit's MockFilesSystem for something faster.
return re.sub(re.escape(os.path.sep), self.pathsep, os.path.join(*comps))
# Not the same as os.walk, but close enough to work.
def walk(self, top):
sep = self.pathsep
if not self.isdir(top): # pragma: no cover
raise OSError("%s is not a directory" % top)
if not top.endswith(sep): # pragma: no cover
top += sep
dirs = []
files = []
for f in self.files:
if self.exists(f) and f.startswith(top):
remaining = f[len(top):]
if sep in remaining:
dir_name = remaining[:remaining.index(sep)]
if not dir_name in dirs:
dirs.append(dir_name)
else:
files.append(remaining)
yield top[:-1], dirs, files
for name in dirs:
for result in self.walk(self.join(top, name)):
yield result
class MockLogging(object):
@staticmethod
def info(ignored):
pass
class MockInputAPI(object):
def __init__(self, files=None):
mock_fs = MockFileSystem(files)
self.os_path = mock_fs
self.os_walk = mock_fs.walk
self.re = re
self.environ = {}
self.logging = MockLogging()
@staticmethod
def PresubmitLocalPath():
return '/mock'
class PresubmitTest(unittest.TestCase):
def test_GroupPythonFilesByRoot(self):
files = [
'PRESUBMIT.py',
'bootstrap/foo.py',
'infra/__init__.py',
'infra/bar/__init__.py',
'infra/bar/baz.py',
'infra/foo.py',
]
input_api = MockInputAPI(files)
expected_groups = {
'': ['PRESUBMIT.py'],
'bootstrap': ['bootstrap/foo.py'],
'infra': [
'infra/__init__.py',
'infra/bar/__init__.py',
'infra/bar/baz.py',
'infra/foo.py',
],
}
grouped_paths = PRESUBMIT.GroupPythonFilesByRoot(input_api, files)
self.assertEquals(dict(grouped_paths), expected_groups)
def test_FetchAllFiles(self):
files = [
'PRESUBMIT.py',
'bootstrap/foo.py',
'infra/__init__.py',
'infra/bar/__init__.py',
'infra/bar/baz.py',
'infra/bar/zoo.html',
'infra/foo.py',
'infra/README',
]
input_api = MockInputAPI(files)
# FIXME: Why are these regexp's instead of globs?
white_list = [
'.*\.py',
]
black_list = [
'.*/__init__\.py',
'infra/bar'
]
expected_paths = [
'PRESUBMIT.py',
'bootstrap/foo.py',
'infra/foo.py',
]
python_paths = PRESUBMIT.FetchAllFiles(input_api, white_list, black_list)
# Note that the files are repo-relative (no '/')
self.assertEquals(python_paths, expected_paths)
def test_EnvAddingPythonPath(self):
input_api = MockInputAPI()
paths = ['badlkfjsdf', 'asdlkfjadf']
env = PRESUBMIT.EnvAddingPythonPath(input_api, paths)
for path in paths:
self.assertIn(path, env['PYTHONPATH'])
def test_DirtyRootsFromAffectedFiles(self):
dirty_files = [
'PRESUBMIT.py',
'infra/bar/baz.py',
]
roots_to_paths = {
'': ['PRESUBMIT.py'],
'bootstrap': ['bootstrap/foo.py'],
'infra': [
'infra/__init__.py',
'infra/bar/__init__.py',
'infra/bar/baz.py',
'infra/foo.py',
],
}
expected_dirty_roots = set(['', 'infra'])
dirty_roots = PRESUBMIT.DirtyRootsFromAffectedFiles(dirty_files,
roots_to_paths)
self.assertEquals(expected_dirty_roots, dirty_roots)
if __name__ == '__main__':
unittest.main()