blob: 5dcdcd8b8c339391a7f3e04a65ed314d72115688 [file] [log] [blame]
Andrew Grievee6c6bb382021-04-27 21:47:081#!/usr/bin/env python3
Nate Fischerac07b2622020-10-01 20:20:142
3# Copyright 2020 The Chromium Authors. All rights reserved.
4# Use of this source code is governed by a BSD-style license that can be
5# found in the LICENSE file.
6"""Tests for java_cpp_features.py.
7
8This test suite contains various tests for the C++ -> Java base::Feature
9generator.
10"""
11
12import unittest
13
14import java_cpp_features
15from util import java_cpp_utils
16
17
18class _TestFeaturesParser(unittest.TestCase):
19 def testParseComments(self):
20 test_data = """
21/**
22 * This should be ignored as well.
23 */
24
25// Comment followed by a blank line.
26
27// Comment followed by unrelated code.
28int foo() { return 3; }
29
30// Real comment.
31const base::Feature kSomeFeature{"SomeFeature",
32 base::FEATURE_DISABLED_BY_DEFAULT};
33
34// Real comment that spans
35// multiple lines.
36const base::Feature kSomeOtherFeature{"SomeOtherFeature",
37 base::FEATURE_ENABLED_BY_DEFAULT};
38
39// Comment followed by nothing.
40""".split('\n')
41 feature_file_parser = java_cpp_utils.CppConstantParser(
42 java_cpp_features.FeatureParserDelegate(), test_data)
43 features = feature_file_parser.Parse()
44 self.assertEqual(2, len(features))
45 self.assertEqual('SOME_FEATURE', features[0].name)
46 self.assertEqual('"SomeFeature"', features[0].value)
47 self.assertEqual(1, len(features[0].comments.split('\n')))
48 self.assertEqual('SOME_OTHER_FEATURE', features[1].name)
49 self.assertEqual('"SomeOtherFeature"', features[1].value)
50 self.assertEqual(2, len(features[1].comments.split('\n')))
51
52 def testWhitespace(self):
53 test_data = """
54// 1 line
55const base::Feature kShort{"Short", base::FEATURE_DISABLED_BY_DEFAULT};
56
57// 2 lines
58const base::Feature kTwoLineFeatureA{"TwoLineFeatureA",
59 base::FEATURE_DISABLED_BY_DEFAULT};
60const base::Feature kTwoLineFeatureB{
61 "TwoLineFeatureB", base::FEATURE_DISABLED_BY_DEFAULT};
62
63// 3 lines
64const base::Feature kFeatureWithAVeryLongNameThatWillHaveToWrap{
65 "FeatureWithAVeryLongNameThatWillHaveToWrap",
66 base::FEATURE_DISABLED_BY_DEFAULT};
67""".split('\n')
68 feature_file_parser = java_cpp_utils.CppConstantParser(
69 java_cpp_features.FeatureParserDelegate(), test_data)
70 features = feature_file_parser.Parse()
71 self.assertEqual(4, len(features))
72 self.assertEqual('SHORT', features[0].name)
73 self.assertEqual('"Short"', features[0].value)
74 self.assertEqual('TWO_LINE_FEATURE_A', features[1].name)
75 self.assertEqual('"TwoLineFeatureA"', features[1].value)
76 self.assertEqual('TWO_LINE_FEATURE_B', features[2].name)
77 self.assertEqual('"TwoLineFeatureB"', features[2].value)
78 self.assertEqual('FEATURE_WITH_A_VERY_LONG_NAME_THAT_WILL_HAVE_TO_WRAP',
79 features[3].name)
80 self.assertEqual('"FeatureWithAVeryLongNameThatWillHaveToWrap"',
81 features[3].value)
82
83 def testCppSyntax(self):
84 test_data = """
85// Mismatched name
86const base::Feature kMismatchedFeature{"MismatchedName",
87 base::FEATURE_DISABLED_BY_DEFAULT};
88
89namespace myfeature {
90// In a namespace
91const base::Feature kSomeFeature{"SomeFeature",
92 base::FEATURE_DISABLED_BY_DEFAULT};
93}
94
95// Defined with equals sign
96const base::Feature kFoo = {"Foo", base::FEATURE_DISABLED_BY_DEFAULT};
97
98// Build config-specific base::Feature
99#if defined(OS_ANDROID)
100const base::Feature kAndroidOnlyFeature{"AndroidOnlyFeature",
101 base::FEATURE_DISABLED_BY_DEFAULT};
102#endif
103
104// Value depends on build config
105const base::Feature kMaybeEnabled{"MaybeEnabled",
106#if defined(OS_ANDROID)
107 base::FEATURE_DISABLED_BY_DEFAULT
108#else
109 base::FEATURE_ENABLED_BY_DEFAULT
110#endif
111};
112""".split('\n')
113 feature_file_parser = java_cpp_utils.CppConstantParser(
114 java_cpp_features.FeatureParserDelegate(), test_data)
115 features = feature_file_parser.Parse()
116 self.assertEqual(5, len(features))
117 self.assertEqual('MISMATCHED_FEATURE', features[0].name)
118 self.assertEqual('"MismatchedName"', features[0].value)
119 self.assertEqual('SOME_FEATURE', features[1].name)
120 self.assertEqual('"SomeFeature"', features[1].value)
121 self.assertEqual('FOO', features[2].name)
122 self.assertEqual('"Foo"', features[2].value)
123 self.assertEqual('ANDROID_ONLY_FEATURE', features[3].name)
124 self.assertEqual('"AndroidOnlyFeature"', features[3].value)
125 self.assertEqual('MAYBE_ENABLED', features[4].name)
126 self.assertEqual('"MaybeEnabled"', features[4].value)
127
128 def testNotYetSupported(self):
129 # Negative test for cases we don't yet support, to ensure we don't misparse
130 # these until we intentionally add proper support.
131 test_data = """
132// Not currently supported: name depends on C++ directive
133const base::Feature kNameDependsOnOs{
134#if defined(OS_ANDROID)
135 "MaybeName1",
136#else
137 "MaybeName2",
138#endif
139 base::FEATURE_DISABLED_BY_DEFAULT};
140
141// Not currently supported: feature named with a constant instead of literal
142const base::Feature kNamedAfterConstant{kNamedStringConstant,
143 base::FEATURE_DISABLED_BY_DEFAULT};
144""".split('\n')
145 feature_file_parser = java_cpp_utils.CppConstantParser(
146 java_cpp_features.FeatureParserDelegate(), test_data)
147 features = feature_file_parser.Parse()
148 self.assertEqual(0, len(features))
149
150 def testTreatWebViewLikeOneWord(self):
151 test_data = """
152const base::Feature kSomeWebViewFeature{"SomeWebViewFeature",
153 base::FEATURE_DISABLED_BY_DEFAULT};
154const base::Feature kWebViewOtherFeature{"WebViewOtherFeature",
155 base::FEATURE_ENABLED_BY_DEFAULT};
156const base::Feature kFeatureWithPluralWebViews{
157 "FeatureWithPluralWebViews",
158 base::FEATURE_ENABLED_BY_DEFAULT};
159""".split('\n')
160 feature_file_parser = java_cpp_utils.CppConstantParser(
161 java_cpp_features.FeatureParserDelegate(), test_data)
162 features = feature_file_parser.Parse()
163 self.assertEqual('SOME_WEBVIEW_FEATURE', features[0].name)
164 self.assertEqual('"SomeWebViewFeature"', features[0].value)
165 self.assertEqual('WEBVIEW_OTHER_FEATURE', features[1].name)
166 self.assertEqual('"WebViewOtherFeature"', features[1].value)
167 self.assertEqual('FEATURE_WITH_PLURAL_WEBVIEWS', features[2].name)
168 self.assertEqual('"FeatureWithPluralWebViews"', features[2].value)
169
170 def testSpecialCharacters(self):
171 test_data = r"""
172const base::Feature kFeatureWithEscapes{"Weird\tfeature\"name\n",
173 base::FEATURE_DISABLED_BY_DEFAULT};
174const base::Feature kFeatureWithEscapes2{
175 "Weird\tfeature\"name\n",
176 base::FEATURE_ENABLED_BY_DEFAULT};
177""".split('\n')
178 feature_file_parser = java_cpp_utils.CppConstantParser(
179 java_cpp_features.FeatureParserDelegate(), test_data)
180 features = feature_file_parser.Parse()
181 self.assertEqual('FEATURE_WITH_ESCAPES', features[0].name)
182 self.assertEqual(r'"Weird\tfeature\"name\n"', features[0].value)
183 self.assertEqual('FEATURE_WITH_ESCAPES2', features[1].name)
184 self.assertEqual(r'"Weird\tfeature\"name\n"', features[1].value)
185
186 def testNoBaseNamespacePrefix(self):
187 test_data = """
188const Feature kSomeFeature{"SomeFeature", FEATURE_DISABLED_BY_DEFAULT};
189""".split('\n')
190 feature_file_parser = java_cpp_utils.CppConstantParser(
191 java_cpp_features.FeatureParserDelegate(), test_data)
192 features = feature_file_parser.Parse()
193 self.assertEqual('SOME_FEATURE', features[0].name)
194 self.assertEqual('"SomeFeature"', features[0].value)
195
196
197if __name__ == '__main__':
198 unittest.main()