#!/usr/bin/env 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 patch.py.""" import os import sys import unittest ROOT_DIR = os.path.dirname(os.path.abspath(__file__)) sys.path.insert(0, os.path.join(ROOT_DIR, '..')) import patch SVN_PATCH = ( 'Index: chrome/file.cc\n' '===================================================================\n' '--- chrome/file.cc\t(revision 74690)\n' '+++ chrome/file.cc\t(working copy)\n' '@@ -80,10 +80,13 @@\n' ' // Foo\n' ' // Bar\n' ' void foo() {\n' '- return bar;\n' '+ return foo;\n' ' }\n' ' \n' ' \n') GIT_PATCH = ( 'diff --git a/chrome/file.cc b/chrome/file.cc\n' 'index 0e4de76..8320059 100644\n' '--- a/chrome/file.cc\n' '+++ b/chrome/file.cc\n' '@@ -3,6 +3,7 @@ bb\n' ' ccc\n' ' dd\n' ' e\n' '+FOO!\n' ' ff\n' ' ggg\n' ' hh\n') # http://codereview.chromium.org/download/issue6368055_22_29.diff GIT_DELETE = ( 'Index: tools/clang_check/README.chromium\n' 'diff --git a/tools/clang_check/README.chromium ' 'b/tools/clang_check/README.chromium\n' 'deleted file mode 100644\n' 'index fcaa7e0e94bb604a026c4f478fecb1c5796f5413..' '0000000000000000000000000000000000000000\n' '--- a/tools/clang_check/README.chromium\n' '+++ /dev/null\n' '@@ -1,9 +0,0 @@\n' '-These are terrible, terrible hacks.\n' '-\n' '-They are meant to be temporary. clang currently doesn\'t allow running a ' 'plugin\n' '-AND doing the normal codegen process. We want our syntax complaining ' 'plugins to\n' '-run during normal compile, but for now, you can user run_plugin.sh to ' 'hack the\n' '-build system to do a syntax check.\n' '-\n' '-Also see http://code.google.com/p/chromium/wiki/WritingClangPlugins\n' '-\n') # http://codereview.chromium.org/download/issue6250123_3013_6010.diff GIT_RENAME_PARTIAL = ( 'Index: chrome/browser/chromeos/views/webui_menu_widget.h\n' 'diff --git a/chrome/browser/chromeos/views/domui_menu_widget.h ' 'b/chrome/browser/chromeos/views/webui_menu_widget.h\n' 'similarity index 79%\n' 'rename from chrome/browser/chromeos/views/domui_menu_widget.h\n' 'rename to chrome/browser/chromeos/views/webui_menu_widget.h\n' 'index 095d4c474fd9718f5aebfa41a1ccb2d951356d41..' '157925075434b590e8acaaf605a64f24978ba08b 100644\n' '--- a/chrome/browser/chromeos/views/domui_menu_widget.h\n' '+++ b/chrome/browser/chromeos/views/webui_menu_widget.h\n' '@@ -1,9 +1,9 @@\n' '-// Copyright (c) 2010 The Chromium Authors. All rights reserved.\n' '+// Copyright (c) 2011 The Chromium Authors. All rights reserved.\n' ' // Use of this source code is governed by a BSD-style license that can be' '\n' ' // found in the LICENSE file.\n' ' \n' '-#ifndef CHROME_BROWSER_CHROMEOS_VIEWS_DOMUI_MENU_WIDGET_H_\n' '-#define CHROME_BROWSER_CHROMEOS_VIEWS_DOMUI_MENU_WIDGET_H_\n' '+#ifndef CHROME_BROWSER_CHROMEOS_VIEWS_WEBUI_MENU_WIDGET_H_\n' '+#define CHROME_BROWSER_CHROMEOS_VIEWS_WEBUI_MENU_WIDGET_H_\n' ' #pragma once\n' ' \n' ' #include \n') # http://codereview.chromium.org/download/issue6287022_3001_4010.diff GIT_RENAME = ( 'Index: tools/run_local_server.sh\n' 'diff --git a/tools/run_local_server.py b/tools/run_local_server.sh\n' 'similarity index 100%\n' 'rename from tools/run_local_server.py\n' 'rename to tools/run_local_server.sh\n') GIT_COPY = ( 'diff --git a/PRESUBMIT.py b/pp\n' 'similarity index 100%\n' 'copy from PRESUBMIT.py\n' 'copy to pp\n') GIT_NEW = ( 'diff --git a/foo b/foo\n' 'new file mode 100644\n' 'index 0000000..5716ca5\n' '--- /dev/null\n' '+++ b/foo\n' '@@ -0,0 +1 @@\n' '+bar\n') class PatchTest(unittest.TestCase): def testFilePatchDelete(self): c = patch.FilePatchDelete('foo', False) self.assertEquals(c.is_delete, True) self.assertEquals(c.is_binary, False) self.assertEquals(c.filename, 'foo') try: c.get() self.fail() except NotImplementedError: pass c = patch.FilePatchDelete('foo', True) self.assertEquals(c.is_delete, True) self.assertEquals(c.is_binary, True) self.assertEquals(c.filename, 'foo') try: c.get() self.fail() except NotImplementedError: pass def testFilePatchBinary(self): c = patch.FilePatchBinary('foo', 'data', []) self.assertEquals(c.is_delete, False) self.assertEquals(c.is_binary, True) self.assertEquals(c.filename, 'foo') self.assertEquals(c.get(), 'data') def testFilePatchDiff(self): c = patch.FilePatchDiff('chrome/file.cc', SVN_PATCH, []) self.assertEquals(c.is_delete, False) self.assertEquals(c.is_binary, False) self.assertEquals(c.filename, 'chrome/file.cc') self.assertEquals(c.is_git_diff, False) self.assertEquals(c.patchlevel, 0) self.assertEquals(c.get(), SVN_PATCH) diff = ( 'diff --git a/git_cl/git-cl b/git_cl/git-cl\n' 'old mode 100644\n' 'new mode 100755\n') c = patch.FilePatchDiff('git_cl/git-cl', diff, []) self.assertEquals(c.is_delete, False) self.assertEquals(c.is_binary, False) self.assertEquals(c.filename, 'git_cl/git-cl') self.assertEquals(c.is_git_diff, True) self.assertEquals(c.patchlevel, 1) self.assertEquals(c.get(), diff) diff = ( 'Index: Junk\n' 'diff --git a/git_cl/git-cl b/git_cl/git-cl\n' 'old mode 100644\n' 'new mode 100755\n') c = patch.FilePatchDiff('git_cl/git-cl', diff, []) self.assertEquals(c.is_delete, False) self.assertEquals(c.is_binary, False) self.assertEquals(c.filename, 'git_cl/git-cl') self.assertEquals(c.is_git_diff, True) self.assertEquals(c.patchlevel, 1) self.assertEquals(c.get(), diff) def testFilePatchBadDiff(self): try: patch.FilePatchDiff('foo', 'data', []) self.fail() except patch.UnsupportedPatchFormat: pass def testFilePatchBadDiffName(self): try: patch.FilePatchDiff('foo', SVN_PATCH, []) self.fail() except patch.UnsupportedPatchFormat: pass def testInvalidFilePatchDiffGit(self): try: patch.FilePatchDiff('svn_utils_test.txt', ( 'diff --git a/tests/svn_utils_test_data/svn_utils_test.txt ' 'b/tests/svn_utils_test_data/svn_utils_test.txt\n' 'index 0e4de76..8320059 100644\n' '--- a/svn_utils_test.txt\n' '+++ b/svn_utils_test.txt\n' '@@ -3,6 +3,7 @@ bb\n' 'ccc\n' 'dd\n' 'e\n' '+FOO!\n' 'ff\n' 'ggg\n' 'hh\n'), []) self.fail() except patch.UnsupportedPatchFormat: pass try: patch.FilePatchDiff('svn_utils_test2.txt', ( 'diff --git a/svn_utils_test_data/svn_utils_test.txt ' 'b/svn_utils_test.txt\n' 'index 0e4de76..8320059 100644\n' '--- a/svn_utils_test.txt\n' '+++ b/svn_utils_test.txt\n' '@@ -3,6 +3,7 @@ bb\n' 'ccc\n' 'dd\n' 'e\n' '+FOO!\n' 'ff\n' 'ggg\n' 'hh\n'), []) self.fail() except patch.UnsupportedPatchFormat: pass def testInvalidFilePatchDiffSvn(self): try: patch.FilePatchDiff('svn_utils_test.txt', ( '--- svn_utils_test.txt2\n' '+++ svn_utils_test.txt\n' '@@ -3,6 +3,7 @@ bb\n' 'ccc\n' 'dd\n' 'e\n' '+FOO!\n' 'ff\n' 'ggg\n' 'hh\n'), []) self.fail() except patch.UnsupportedPatchFormat: pass def testValidSvn(self): # pylint: disable=R0201 # Method could be a function # Should not throw. p = patch.FilePatchDiff('chrome/file.cc', SVN_PATCH, []) lines = SVN_PATCH.splitlines(True) header = ''.join(lines[:4]) hunks = ''.join(lines[4:]) self.assertEquals(header, p.diff_header) self.assertEquals(hunks, p.diff_hunks) self.assertEquals(SVN_PATCH, p.get()) def testValidSvnNew(self): text = '--- /dev/null\t2\n+++ chrome/file.cc\tfoo\n' p = patch.FilePatchDiff('chrome/file.cc', text, []) self.assertEquals(text, p.diff_header) self.assertEquals('', p.diff_hunks) self.assertEquals(text, p.get()) def testValidSvnDelete(self): text = '--- chrome/file.cc\tbar\n+++ /dev/null\tfoo\n' p = patch.FilePatchDiff('chrome/file.cc', text, []) self.assertEquals(text, p.diff_header) self.assertEquals('', p.diff_hunks) self.assertEquals(text, p.get()) def testRelPath(self): patches = patch.PatchSet([ patch.FilePatchDiff('chrome/file.cc', SVN_PATCH, []), patch.FilePatchDiff( 'tools\\clang_check/README.chromium', GIT_DELETE, []), patch.FilePatchDiff('tools/run_local_server.sh', GIT_RENAME, []), patch.FilePatchDiff( 'chrome\\browser/chromeos/views/webui_menu_widget.h', GIT_RENAME_PARTIAL, []), patch.FilePatchDiff('pp', GIT_COPY, []), patch.FilePatchDiff('foo', GIT_NEW, []), patch.FilePatchDelete('other/place/foo', True), patch.FilePatchBinary('bar', 'data', []), ]) expected = [ 'chrome/file.cc', 'tools/clang_check/README.chromium', 'tools/run_local_server.sh', 'chrome/browser/chromeos/views/webui_menu_widget.h', 'pp', 'foo', 'other/place/foo', 'bar'] self.assertEquals(expected, patches.filenames) orig_name = patches.patches[0].filename patches.set_relpath(os.path.join('a', 'bb')) expected = [os.path.join('a', 'bb', x) for x in expected] self.assertEquals(expected, patches.filenames) # Make sure each header is updated accordingly. header = [] new_name = os.path.join('a', 'bb', orig_name) for line in SVN_PATCH.splitlines(True): if line.startswith('@@'): break if line[:3] in ('---', '+++', 'Ind'): line = line.replace(orig_name, new_name) header.append(line) header = ''.join(header) self.assertEquals(header, patches.patches[0].diff_header) def testRelPathBad(self): patches = patch.PatchSet([ patch.FilePatchDiff('chrome\\file.cc', SVN_PATCH, []), patch.FilePatchDelete('other\\place\\foo', True), ]) try: patches.set_relpath('..') self.fail() except patch.UnsupportedPatchFormat: pass def testBackSlash(self): mangled_patch = SVN_PATCH.replace('chrome/', 'chrome\\') patches = patch.PatchSet([ patch.FilePatchDiff('chrome\\file.cc', mangled_patch, []), patch.FilePatchDelete('other\\place\\foo', True), ]) expected = ['chrome/file.cc', 'other/place/foo'] self.assertEquals(expected, patches.filenames) self.assertEquals(SVN_PATCH, patches.patches[0].get()) def testGitPatches(self): # Shouldn't throw. patch.FilePatchDiff('tools/clang_check/README.chromium', GIT_DELETE, []) patch.FilePatchDiff('tools/run_local_server.sh', GIT_RENAME, []) patch.FilePatchDiff( 'chrome/browser/chromeos/views/webui_menu_widget.h', GIT_RENAME_PARTIAL, []) patch.FilePatchDiff('pp', GIT_COPY, []) patch.FilePatchDiff('foo', GIT_NEW, []) self.assertTrue(True) if __name__ == '__main__': unittest.main()