| Index: tools/clang/pass_to_move/add_header_test.py
|
| diff --git a/tools/clang/pass_to_move/add_header_test.py b/tools/clang/pass_to_move/add_header_test.py
|
| new file mode 100755
|
| index 0000000000000000000000000000000000000000..7d12c880b13f5315db4007eaa61f095f4ace4f6d
|
| --- /dev/null
|
| +++ b/tools/clang/pass_to_move/add_header_test.py
|
| @@ -0,0 +1,417 @@
|
| +#!/usr/bin/env python
|
| +# Copyright 2015 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 unittest
|
| +
|
| +import add_header
|
| +
|
| +
|
| +class DecoratedFilenameTest(unittest.TestCase):
|
| +
|
| + def testCHeaderClassification(self):
|
| + self.assertTrue(add_header.IsCSystemHeader('<stdlib.h>'))
|
| + self.assertFalse(add_header.IsCSystemHeader('<type_traits>'))
|
| + self.assertFalse(add_header.IsCSystemHeader('"moo.h"'))
|
| +
|
| + def testCXXHeaderClassification(self):
|
| + self.assertFalse(add_header.IsCXXSystemHeader('<stdlib.h>'))
|
| + self.assertTrue(add_header.IsCXXSystemHeader('<type_traits>'))
|
| + self.assertFalse(add_header.IsCXXSystemHeader('"moo.h"'))
|
| +
|
| + def testUserHeaderClassification(self):
|
| + self.assertFalse(add_header.IsUserHeader('<stdlib.h>'))
|
| + self.assertFalse(add_header.IsUserHeader('<type_traits>'))
|
| + self.assertTrue(add_header.IsUserHeader('"moo.h"'))
|
| +
|
| + def testClassifyHeader(self):
|
| + self.assertEqual(
|
| + add_header.ClassifyHeader('<stdlib.h>'),
|
| + add_header._HEADER_TYPE_C_SYSTEM)
|
| + self.assertEqual(
|
| + add_header.ClassifyHeader('<type_traits>'),
|
| + add_header._HEADER_TYPE_CXX_SYSTEM)
|
| + self.assertEqual(
|
| + add_header.ClassifyHeader('"moo.h"'), add_header._HEADER_TYPE_USER)
|
| + self.assertEqual(
|
| + add_header.ClassifyHeader('invalid'), add_header._HEADER_TYPE_INVALID)
|
| +
|
| +
|
| +class FindIncludesTest(unittest.TestCase):
|
| +
|
| + def testEmpty(self):
|
| + begin, end = add_header.FindIncludes([])
|
| + self.assertEqual(begin, -1)
|
| + self.assertEqual(end, -1)
|
| +
|
| + def testNoIncludes(self):
|
| + begin, end = add_header.FindIncludes(['a'])
|
| + self.assertEqual(begin, -1)
|
| + self.assertEqual(end, -1)
|
| +
|
| + def testOneInclude(self):
|
| + begin, end = add_header.FindIncludes(['#include <algorithm>'])
|
| + self.assertEqual(begin, 0)
|
| + self.assertEqual(end, 1)
|
| +
|
| + def testIncludeWithInlineComment(self):
|
| + begin, end = add_header.FindIncludes(
|
| + ['#include "moo.h" // TODO: Add more sounds.'])
|
| + self.assertEqual(begin, 0)
|
| + self.assertEqual(end, 1)
|
| +
|
| + def testNewlinesBetweenIncludes(self):
|
| + begin, end = add_header.FindIncludes(['#include <utility>', '',
|
| + '#include "moo.h"'])
|
| + self.assertEqual(begin, 0)
|
| + self.assertEqual(end, 3)
|
| +
|
| + def testCommentsBetweenIncludes(self):
|
| + begin, end = add_header.FindIncludes(
|
| + ['#include <utility>', '// TODO: Add goat support.', '#include "moo.h"'
|
| + ])
|
| + self.assertEqual(begin, 0)
|
| + self.assertEqual(end, 3)
|
| +
|
| + def testEmptyLinesNotIncluded(self):
|
| + begin, end = add_header.FindIncludes(['', '#include <utility>', '',
|
| + '#include "moo.h"', ''])
|
| + self.assertEqual(begin, 1)
|
| + self.assertEqual(end, 4)
|
| +
|
| + def testCommentsNotIncluded(self):
|
| + begin, end = add_header.FindIncludes(
|
| + ['// Cow module.', '#include <utility>', '// For cow speech synthesis.',
|
| + '#include "moo.h"', '// TODO: Add Linux audio support.'])
|
| + self.assertEqual(begin, 1)
|
| + self.assertEqual(end, 4)
|
| +
|
| + def testNonIncludesLinesBeforeIncludesIgnored(self):
|
| + begin, end = add_header.FindIncludes(['#ifndef COW_H_', '#define COW_H_',
|
| + '#include "moo.h"'])
|
| + self.assertEqual(begin, 2)
|
| + self.assertEqual(end, 3)
|
| +
|
| + def testNonIncludesLinesAfterIncludesTerminates(self):
|
| + begin, end = add_header.FindIncludes(
|
| + ['#include "moo.h"', '#ifndef COW_MESSAGES_H_', '#define COW_MESSAGE_H_'
|
| + ])
|
| + self.assertEqual(begin, 0)
|
| + self.assertEqual(end, 1)
|
| +
|
| +
|
| +class IncludeTest(unittest.TestCase):
|
| +
|
| + def testToSource(self):
|
| + self.assertEqual(
|
| + add_header.Include('<moo.h>', 'include', [], None).ToSource(),
|
| + ['#include <moo.h>'])
|
| +
|
| + def testIncludeWithPreambleToSource(self):
|
| + self.assertEqual(
|
| + add_header.Include('"moo.h"', 'include', ['//preamble'],
|
| + None).ToSource(), ['// preamble'
|
| + '#include "moo.h"'])
|
| +
|
| + def testIncludeWithPreambleToSource(self):
|
| + self.assertEqual(
|
| + add_header.Include('"moo.h"', 'include', [],
|
| + ' inline comment').ToSource(),
|
| + ['#include "moo.h" // inline comment'])
|
| +
|
| + def testIncludeWithPreambleAndInlineCommentToSource(self):
|
| + # Make sure whitespace is vaguely normalized too.
|
| + self.assertEqual(
|
| + add_header.Include('"moo.h"', 'include',
|
| + ['// preamble with trailing space ',],
|
| + ' inline comment with trailing space ').ToSource(),
|
| + ['// preamble with trailing space',
|
| + '#include "moo.h" // inline comment with trailing space'])
|
| +
|
| + def testImportToSource(self):
|
| + self.assertEqual(
|
| + add_header.Include('"moo.h"', 'import', [], None).ToSource(),
|
| + ['#import "moo.h"'])
|
| +
|
| +
|
| +class ParseIncludesTest(unittest.TestCase):
|
| +
|
| + def testInvalid(self):
|
| + self.assertIsNone(add_header.ParseIncludes(['invalid']))
|
| +
|
| + def testInclude(self):
|
| + includes = add_header.ParseIncludes(['#include "moo.h"'])
|
| + self.assertEqual(len(includes), 1)
|
| + self.assertEqual(includes[0].decorated_name, '"moo.h"')
|
| + self.assertEqual(includes[0].directive, 'include')
|
| + self.assertEqual(includes[0].preamble, [])
|
| + self.assertIsNone(includes[0].inline_comment)
|
| + self.assertEqual(includes[0].header_type, add_header._HEADER_TYPE_USER)
|
| + self.assertFalse(includes[0].is_primary_header)
|
| +
|
| + def testIncludeSurroundedByWhitespace(self):
|
| + includes = add_header.ParseIncludes([' #include "moo.h" '])
|
| + self.assertEqual(len(includes), 1)
|
| + self.assertEqual(includes[0].decorated_name, '"moo.h"')
|
| + self.assertEqual(includes[0].directive, 'include')
|
| + self.assertEqual(includes[0].preamble, [])
|
| + self.assertIsNone(includes[0].inline_comment)
|
| + self.assertEqual(includes[0].header_type, add_header._HEADER_TYPE_USER)
|
| + self.assertFalse(includes[0].is_primary_header)
|
| +
|
| + def testImport(self):
|
| + includes = add_header.ParseIncludes(['#import "moo.h"'])
|
| + self.assertEqual(len(includes), 1)
|
| + self.assertEqual(includes[0].decorated_name, '"moo.h"')
|
| + self.assertEqual(includes[0].directive, 'import')
|
| + self.assertEqual(includes[0].preamble, [])
|
| + self.assertIsNone(includes[0].inline_comment)
|
| + self.assertEqual(includes[0].header_type, add_header._HEADER_TYPE_USER)
|
| + self.assertFalse(includes[0].is_primary_header)
|
| +
|
| + def testIncludeWithPreamble(self):
|
| + includes = add_header.ParseIncludes(['// preamble comment ',
|
| + '#include "moo.h"'])
|
| + self.assertEqual(len(includes), 1)
|
| + self.assertEqual(includes[0].decorated_name, '"moo.h"')
|
| + self.assertEqual(includes[0].directive, 'include')
|
| + self.assertEqual(includes[0].preamble, ['// preamble comment '])
|
| + self.assertIsNone(includes[0].inline_comment)
|
| + self.assertEqual(includes[0].header_type, add_header._HEADER_TYPE_USER)
|
| + self.assertFalse(includes[0].is_primary_header)
|
| +
|
| + def testIncludeWithInvalidPreamble(self):
|
| + self.assertIsNone(add_header.ParseIncludes(['// orphan comment', '',
|
| + '#include "moo.h"']))
|
| +
|
| + def testIncludeWIthInlineComment(self):
|
| + includes = add_header.ParseIncludes(['#include "moo.h"// For SFX '])
|
| + self.assertEqual(len(includes), 1)
|
| + self.assertEqual(includes[0].decorated_name, '"moo.h"')
|
| + self.assertEqual(includes[0].directive, 'include')
|
| + self.assertEqual(includes[0].preamble, [])
|
| + self.assertEqual(includes[0].inline_comment, ' For SFX ')
|
| + self.assertEqual(includes[0].header_type, add_header._HEADER_TYPE_USER)
|
| + self.assertFalse(includes[0].is_primary_header)
|
| +
|
| + def testIncludeWithInlineCommentAndPreamble(self):
|
| + includes = add_header.ParseIncludes(['// preamble comment ',
|
| + '#include "moo.h" // For SFX '])
|
| + self.assertEqual(len(includes), 1)
|
| + self.assertEqual(includes[0].decorated_name, '"moo.h"')
|
| + self.assertEqual(includes[0].directive, 'include')
|
| + self.assertEqual(includes[0].preamble, ['// preamble comment '])
|
| + self.assertEqual(includes[0].inline_comment, ' For SFX ')
|
| + self.assertEqual(includes[0].header_type, add_header._HEADER_TYPE_USER)
|
| + self.assertFalse(includes[0].is_primary_header)
|
| +
|
| + def testMultipleIncludes(self):
|
| + includes = add_header.ParseIncludes(
|
| + ['#include <time.h>', '', '#include "moo.h" // For SFX ',
|
| + '// TODO: Implement death ray.', '#import "goat.h"'])
|
| + self.assertEqual(len(includes), 3)
|
| + self.assertEqual(includes[0].decorated_name, '<time.h>')
|
| + self.assertEqual(includes[0].directive, 'include')
|
| + self.assertEqual(includes[0].preamble, [])
|
| + self.assertIsNone(includes[0].inline_comment)
|
| + self.assertEqual(includes[0].header_type, add_header._HEADER_TYPE_C_SYSTEM)
|
| + self.assertFalse(includes[0].is_primary_header)
|
| + self.assertEqual(includes[1].decorated_name, '"moo.h"')
|
| + self.assertEqual(includes[1].directive, 'include')
|
| + self.assertEqual(includes[1].preamble, [])
|
| + self.assertEqual(includes[1].inline_comment, ' For SFX ')
|
| + self.assertEqual(includes[1].header_type, add_header._HEADER_TYPE_USER)
|
| + self.assertFalse(includes[1].is_primary_header)
|
| + self.assertEqual(includes[2].decorated_name, '"goat.h"')
|
| + self.assertEqual(includes[2].directive, 'import')
|
| + self.assertEqual(includes[2].preamble, ['// TODO: Implement death ray.'])
|
| + self.assertIsNone(includes[2].inline_comment)
|
| + self.assertEqual(includes[2].header_type, add_header._HEADER_TYPE_USER)
|
| + self.assertFalse(includes[2].is_primary_header)
|
| +
|
| +
|
| +class MarkPrimaryIncludeTest(unittest.TestCase):
|
| +
|
| + def extractPrimaryName(self, includes):
|
| + for include in includes:
|
| + if include.is_primary_header:
|
| + return include.decorated_name
|
| +
|
| + def testNoOpOnHeader(self):
|
| + includes = [add_header.Include('"cow.h"', 'include', [], None)]
|
| + add_header.MarkPrimaryInclude(includes, 'cow.h')
|
| + self.assertIsNone(self.extractPrimaryName(includes))
|
| +
|
| + def testSystemHeaderNotMatched(self):
|
| + includes = [add_header.Include('<cow.h>', 'include', [], None)]
|
| + add_header.MarkPrimaryInclude(includes, 'cow.cc')
|
| + self.assertIsNone(self.extractPrimaryName(includes))
|
| +
|
| + def testExactMatch(self):
|
| + includes = [
|
| + add_header.Include('"cow.h"', 'include', [], None),
|
| + add_header.Include('"cow_posix.h"', 'include', [], None),
|
| + ]
|
| + add_header.MarkPrimaryInclude(includes, 'cow.cc')
|
| + self.assertEqual(self.extractPrimaryName(includes), '"cow.h"')
|
| +
|
| + def testFuzzyMatch(self):
|
| + includes = [add_header.Include('"cow.h"', 'include', [], None)]
|
| + add_header.MarkPrimaryInclude(includes, 'cow_linux_unittest.cc')
|
| + self.assertEqual(self.extractPrimaryName(includes), '"cow.h"')
|
| +
|
| + def testFuzzymatchInReverse(self):
|
| + includes = [add_header.Include('"cow.h"', 'include', [], None)]
|
| + add_header.MarkPrimaryInclude(includes, 'cow_uitest_aura.cc')
|
| + self.assertEqual(self.extractPrimaryName(includes), '"cow.h"')
|
| +
|
| + def testFuzzyMatchDoesntMatchDifferentSuffixes(self):
|
| + includes = [add_header.Include('"cow_posix.h"', 'include', [], None)]
|
| + add_header.MarkPrimaryInclude(includes, 'cow_windows.cc')
|
| + self.assertIsNone(self.extractPrimaryName(includes))
|
| +
|
| + def testMarksMostSpecific(self):
|
| + includes = [
|
| + add_header.Include('"cow.h"', 'include', [], None),
|
| + add_header.Include('"cow_posix.h"', 'include', [], None),
|
| + ]
|
| + add_header.MarkPrimaryInclude(includes, 'cow_posix.cc')
|
| + self.assertEqual(self.extractPrimaryName(includes), '"cow_posix.h"')
|
| +
|
| + def testFullPathMatch(self):
|
| + includes = [add_header.Include('"zfs/impl/cow.h"', 'include', [], None)]
|
| + add_header.MarkPrimaryInclude(includes, 'zfs/impl/cow.cc')
|
| + self.assertEqual(self.extractPrimaryName(includes), '"zfs/impl/cow.h"')
|
| +
|
| + def testTopmostDirectoryDoesNotMatch(self):
|
| + includes = [add_header.Include('"animal/impl/cow.h"', 'include', [], None)]
|
| + add_header.MarkPrimaryInclude(includes, 'zfs/impl/cow.cc')
|
| + self.assertIsNone(self.extractPrimaryName(includes))
|
| +
|
| + def testSubstantiallySimilarPaths(self):
|
| + includes = [add_header.Include('"farm/public/animal/cow.h"', 'include', [],
|
| + None)]
|
| + add_header.MarkPrimaryInclude(includes, 'farm/animal/cow.cc')
|
| + self.assertEqual(
|
| + self.extractPrimaryName(includes), '"farm/public/animal/cow.h"')
|
| +
|
| + def testNoMatchingSubdirectories(self):
|
| + includes = [add_header.Include('"base/zfs/cow.h"', 'include', [], None)]
|
| + add_header.MarkPrimaryInclude(includes, 'base/animal/cow.cc')
|
| + self.assertIsNone(self.extractPrimaryName(includes))
|
| +
|
| +
|
| +class SerializeIncludesTest(unittest.TestCase):
|
| +
|
| + def testSystemHeaders(self):
|
| + source = add_header.SerializeIncludes([
|
| + add_header.Include('<stdlib.h>', 'include', [], None),
|
| + add_header.Include('<map>', 'include', [], None),
|
| + ])
|
| + self.assertEqual(source, ['#include <stdlib.h>', '', '#include <map>'])
|
| +
|
| + def testUserHeaders(self):
|
| + source = add_header.SerializeIncludes([
|
| + add_header.Include('"goat.h"', 'include', [], None),
|
| + add_header.Include('"moo.h"', 'include', [], None),
|
| + ])
|
| + self.assertEqual(source, ['#include "goat.h"', '#include "moo.h"'])
|
| +
|
| + def testSystemAndUserHeaders(self):
|
| + source = add_header.SerializeIncludes([
|
| + add_header.Include('<stdlib.h>', 'include', [], None),
|
| + add_header.Include('<map>', 'include', [], None),
|
| + add_header.Include('"moo.h"', 'include', [], None),
|
| + ])
|
| + self.assertEqual(source, ['#include <stdlib.h>', '', '#include <map>', '',
|
| + '#include "moo.h"'])
|
| +
|
| + def testPrimaryAndSystemHeaders(self):
|
| + primary_header = add_header.Include('"cow.h"', 'include', [], None)
|
| + primary_header.is_primary_header = True
|
| + source = add_header.SerializeIncludes([
|
| + primary_header,
|
| + add_header.Include('<stdlib.h>', 'include', [], None),
|
| + add_header.Include('<map>', 'include', [], None),
|
| + ])
|
| + self.assertEqual(source, [
|
| + '#include "cow.h"', '', '#include <stdlib.h>', '', '#include <map>'
|
| + ])
|
| +
|
| + def testPrimaryAndUserHeaders(self):
|
| + primary_header = add_header.Include('"cow.h"', 'include', [], None)
|
| + primary_header.is_primary_header = True
|
| + source = add_header.SerializeIncludes([
|
| + primary_header,
|
| + add_header.Include('"moo.h"', 'include', [], None),
|
| + ])
|
| + self.assertEqual(source, ['#include "cow.h"', '', '#include "moo.h"'])
|
| +
|
| + def testPrimarySystemAndUserHeaders(self):
|
| + primary_header = add_header.Include('"cow.h"', 'include', [], None)
|
| + primary_header.is_primary_header = True
|
| + source = add_header.SerializeIncludes([
|
| + primary_header,
|
| + add_header.Include('<stdlib.h>', 'include', [], None),
|
| + add_header.Include('<map>', 'include', [], None),
|
| + add_header.Include('"moo.h"', 'include', [], None),
|
| + ])
|
| + self.assertEqual(source, [
|
| + '#include "cow.h"', '', '#include <stdlib.h>', '', '#include <map>', '',
|
| + '#include "moo.h"'
|
| + ])
|
| +
|
| +
|
| +class InsertHeaderIntoSourceTest(unittest.TestCase):
|
| +
|
| + def testAddInclude(self):
|
| + source = add_header.InsertHeaderIntoSource('cow.cc', '\n'.join(
|
| + ['// Copyright info here.', '', '#include <utility>',
|
| + '// For cow speech synthesis.',
|
| + '#include "moo.h" // TODO: Add Linux audio support.',
|
| + '#include <time.h>', '#include "cow.h"', 'namespace bovine {', '',
|
| + '// TODO: Implement.', '} // namespace bovine']), '<memory>')
|
| + self.assertEqual(
|
| + source,
|
| + '\n'.join(['// Copyright info here.', '', '#include "cow.h"', '',
|
| + '#include <time.h>', '', '#include <memory>',
|
| + '#include <utility>', '', '// For cow speech synthesis.',
|
| + '#include "moo.h" // TODO: Add Linux audio support.',
|
| + 'namespace bovine {', '', '// TODO: Implement.',
|
| + '} // namespace bovine', '']))
|
| +
|
| + def testAlreadyIncluded(self):
|
| + # To make sure the original source is returned unmodified, the input source
|
| + # intentionally scrambles the #include order.
|
| + source = '\n'.join([
|
| + '// Copyright info here.', '', '#include "moo.h"', '#include <utility>',
|
| + '#include <memory>', '#include "cow.h"', 'namespace bovine {', '',
|
| + '// TODO: Implement.', '} // namespace bovine'
|
| + ])
|
| + self.assertEqual(
|
| + add_header.InsertHeaderIntoSource('cow.cc', source, '<memory>'), source)
|
| +
|
| + def testConditionalIncludesLeftALone(self):
|
| + # TODO(dcheng): Conditional header handling could probably be more clever.
|
| + # But for the moment, this is probably Good Enough.
|
| + source = add_header.InsertHeaderIntoSource(
|
| + 'cow.cc',
|
| + '\n'.join(['// Copyright info here.', '', '#include "cow.h"',
|
| + '#include <utility>', '// For cow speech synthesis.',
|
| + '#include "moo.h" // TODO: Add Linux audio support.',
|
| + '#if defined(USE_AURA)'
|
| + '#include <memory>', '#endif // defined(USE_AURA)']),
|
| + '<memory>')
|
| + self.assertEqual(
|
| + source,
|
| + '\n'.join(['// Copyright info here.', '', '#include "cow.h"', '',
|
| + '#include <memory>', '#include <utility>', '',
|
| + '// For cow speech synthesis.',
|
| + '#include "moo.h" // TODO: Add Linux audio support.',
|
| + '#if defined(USE_AURA)'
|
| + '#include <memory>', '#endif // defined(USE_AURA)', '']))
|
| +
|
| +
|
| +if __name__ == '__main__':
|
| + unittest.main()
|
|
|