blob: e04354e45d78920f07af367c3ea2771c9416bcd8 [file] [log] [blame]
#!/usr/bin/env vpython3
"""Tests for git_footers."""
import json
import os
import sys
import tempfile
import unittest
if sys.version_info.major == 2:
from StringIO import StringIO
import mock
else:
from io import StringIO
from unittest import mock
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
import gclient_utils
import git_footers
class GitFootersTest(unittest.TestCase):
_message = """
This is my commit message. There are many like it, but this one is mine.
My commit message is my best friend. It is my life. I must master it.
"""
_position = 'refs/heads/master@{#292272}'
_position_footer = 'Cr-Commit-Position: %s\n' % _position
def testFootersBasic(self):
self.assertEqual(
git_footers.split_footers('Not-A: footer'),
(['Not-A: footer'], [], []))
self.assertEqual(
git_footers.split_footers('Header\n\nActual: footer'),
(['Header', ''], ['Actual: footer'], [('Actual', 'footer')]))
self.assertEqual(
git_footers.split_footers('\nActual: footer'),
([''], ['Actual: footer'], [('Actual', 'footer')]))
self.assertEqual(
git_footers.split_footers('H\n\nBug:\nAlso: footer'),
(['H', ''], ['Bug:', 'Also: footer'],
[('Bug', ''), ('Also', 'footer')]))
self.assertEqual(
git_footers.split_footers('H\n\nBug: '),
(['H', ''], ['Bug: '], [('Bug', '')]))
self.assertEqual(
git_footers.parse_footers(self._message), {})
self.assertEqual(
git_footers.parse_footers(self._message + self._position_footer),
{ 'Cr-Commit-Position': [ self._position ] })
self.assertEqual(
git_footers.parse_footers(self._message + self._position_footer
+ self._position_footer),
{ 'Cr-Commit-Position': [ self._position, self._position ] })
self.assertEqual(
git_footers.parse_footers(self._message +
'Bug:\n' +
self._position_footer),
{ 'Bug': [''],
'Cr-Commit-Position': [ self._position ] })
def testSkippingBadFooterLines(self):
message = ('Title.\n'
'\n'
'Last: paragraph starts\n'
'It-may: contain\n'
'bad lines, which should be skipped\n'
'For: example\n'
'(cherry picked from)\n'
'And-only-valid: footers taken')
self.assertEqual(git_footers.split_footers(message),
(['Title.',
''],
['Last: paragraph starts',
'It-may: contain',
'bad lines, which should be skipped',
'For: example',
'(cherry picked from)',
'And-only-valid: footers taken'],
[('Last', 'paragraph starts'),
('It-may', 'contain'),
('For', 'example'),
('And-only-valid', 'footers taken')]))
self.assertEqual(git_footers.parse_footers(message),
{'Last': ['paragraph starts'],
'It-May': ['contain'],
'For': ['example'],
'And-Only-Valid': ['footers taken']})
def testAvoidingURLs(self):
message = ('Someone accidentally put a URL in the footers.\n'
'\n'
'Followed: by\n'
'http://domain.tld\n'
'Some: footers')
self.assertEqual(git_footers.split_footers(message),
(['Someone accidentally put a URL in the footers.',
''],
['Followed: by',
'http://domain.tld',
'Some: footers'],
[('Followed', 'by'),
('Some', 'footers')]))
self.assertEqual(git_footers.parse_footers(message),
{'Followed': ['by'],
'Some': ['footers']})
def testSplittingLastParagraph(self):
message = ('Title.\n'
'\n'
'The final paragraph has some normal text first.\n'
'Followed: by\n'
'nonsense trailers and\n'
'Some: footers')
self.assertEqual(git_footers.split_footers(message),
(['Title.',
'',
'The final paragraph has some normal text first.',
''],
['Followed: by',
'nonsense trailers and',
'Some: footers'],
[('Followed', 'by'),
('Some', 'footers')]))
self.assertEqual(git_footers.parse_footers(message),
{'Followed': ['by'],
'Some': ['footers']})
def testGetFooterChangeId(self):
msg = '\n'.join(['whatever',
'',
'Change-Id: ignored',
'', # Above is ignored because of this empty line.
'Change-Id: Ideadbeaf'])
self.assertEqual(['Ideadbeaf'], git_footers.get_footer_change_id(msg))
self.assertEqual([], git_footers.get_footer_change_id(
'desc\nBUG=not-a-valid-footer\nChange-Id: Ixxx'))
self.assertEqual(['Ixxx'], git_footers.get_footer_change_id(
'desc\nBUG=not-a-valid-footer\n\nChange-Id: Ixxx'))
def testAddFooterChangeId(self):
with self.assertRaises(AssertionError):
git_footers.add_footer_change_id('Already has\n\nChange-Id: Ixxx', 'Izzz')
self.assertEqual(
git_footers.add_footer_change_id('header-only', 'Ixxx'),
'header-only\n\nChange-Id: Ixxx')
self.assertEqual(
git_footers.add_footer_change_id('header\n\nsome: footer', 'Ixxx'),
'header\n\nsome: footer\nChange-Id: Ixxx')
self.assertEqual(
git_footers.add_footer_change_id('header\n\nBUG: yy', 'Ixxx'),
'header\n\nBUG: yy\nChange-Id: Ixxx')
self.assertEqual(
git_footers.add_footer_change_id('header\n\nBUG: yy\nPos: 1', 'Ixxx'),
'header\n\nBUG: yy\nChange-Id: Ixxx\nPos: 1')
self.assertEqual(
git_footers.add_footer_change_id('header\n\nBUG: yy\n\nPos: 1', 'Ixxx'),
'header\n\nBUG: yy\n\nPos: 1\nChange-Id: Ixxx')
# Special case: first line is never a footer, even if it looks line one.
self.assertEqual(
git_footers.add_footer_change_id('header: like footer', 'Ixxx'),
'header: like footer\n\nChange-Id: Ixxx')
self.assertEqual(
git_footers.add_footer_change_id('Header.\n\nBug: v8\nN=t\nT=z', 'Ix'),
'Header.\n\nBug: v8\nChange-Id: Ix\nN=t\nT=z')
def testAddFooter(self):
with self.assertRaises(ValueError):
git_footers.add_footer('', 'Invalid Footer', 'Value')
self.assertEqual(
git_footers.add_footer('', 'Key', 'Value'),
'\nKey: Value')
self.assertEqual(
git_footers.add_footer('Header with empty line.\n\n', 'Key', 'Value'),
'Header with empty line.\n\nKey: Value')
self.assertEqual(
git_footers.add_footer('Top\n\nSome: footer', 'Key', 'value'),
'Top\n\nSome: footer\nKey: value')
self.assertEqual(
git_footers.add_footer('Top\n\nSome: footer', 'Key', 'value',
after_keys=['Any']),
'Top\n\nSome: footer\nKey: value')
self.assertEqual(
git_footers.add_footer('Top\n\nSome: footer', 'Key', 'value',
after_keys=['Some']),
'Top\n\nSome: footer\nKey: value')
self.assertEqual(
git_footers.add_footer('Top\n\nSome: footer\nOther: footer',
'Key', 'value', after_keys=['Some']),
'Top\n\nSome: footer\nKey: value\nOther: footer')
self.assertEqual(
git_footers.add_footer('Top\n\nSome: footer\nOther: footer',
'Key', 'value', before_keys=['Other']),
'Top\n\nSome: footer\nKey: value\nOther: footer')
self.assertEqual(
git_footers.add_footer(
'Top\n\nSome: footer\nOther: footer\nFinal: footer',
'Key', 'value', after_keys=['Some'], before_keys=['Final']),
'Top\n\nSome: footer\nKey: value\nOther: footer\nFinal: footer')
self.assertEqual(
git_footers.add_footer(
'Top\n\nSome: footer\nOther: footer\nFinal: footer',
'Key', 'value', after_keys=['Other'], before_keys=['Some']),
'Top\n\nSome: footer\nOther: footer\nKey: value\nFinal: footer')
def testRemoveFooter(self):
self.assertEqual(
git_footers.remove_footer('message', 'Key'),
'message')
self.assertEqual(
git_footers.remove_footer('message\n\nSome: footer', 'Key'),
'message\n\nSome: footer')
self.assertEqual(
git_footers.remove_footer('message\n\nSome: footer\nKey: value', 'Key'),
'message\n\nSome: footer')
self.assertEqual(
git_footers.remove_footer(
'message\n\nKey: value\nSome: footer\nKey: value', 'Key'),
'message\n\nSome: footer')
@mock.patch('sys.stdout', StringIO())
@mock.patch(
'sys.stdin',
StringIO('line\r\notherline\r\n\r\n\r\nFoo: baz\r\nStill: footer'))
def testReadStdin(self):
self.assertEqual(git_footers.main([]), 0)
self.assertEqual(sys.stdout.getvalue(), 'Still: footer\nFoo: baz\n')
@mock.patch(
'sys.stdin',
StringIO('line\r\nany spaces\r\n\r\n\r\nFoo: 1\nBar: 2\nFoo: 3'))
def testToJson(self):
with gclient_utils.temporary_file() as tmp:
self.assertEqual(git_footers.main(['--json', tmp]), 0)
with open(tmp) as f:
js = json.load(f)
self.assertEqual(js, {'Foo': ['3', '1'], 'Bar': ['2']})
if __name__ == '__main__':
unittest.main()