blob: 3053955ec1ae9d08222fb528056871dc9e6a799d [file] [log] [blame]
Andrew Grievee6c6bb382021-04-27 21:47:081#!/usr/bin/env python3
Nate Fischerac07b2622020-10-01 20:20:142
Avi Drissman73a09d12022-09-08 20:33:383# Copyright 2020 The Chromium Authors
Nate Fischerac07b2622020-10-01 20:20:144# 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
Daniel Chengc89c8532022-10-03 15:04:4630// Real comment. base::Feature intentionally split across two lines.
31BASE_FEATURE(kSomeFeature, "SomeFeature",
32 base::FEATURE_DISABLED_BY_DEFAULT);
Nate Fischerac07b2622020-10-01 20:20:1433
34// Real comment that spans
35// multiple lines.
Daniel Chengc89c8532022-10-03 15:04:4636BASE_FEATURE(kSomeOtherFeature, "SomeOtherFeature",
37 base::FEATURE_ENABLED_BY_DEFAULT);
Nate Fischerac07b2622020-10-01 20:20:1438
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
Daniel Chengc89c8532022-10-03 15:04:4655BASE_FEATURE(kShort, "Short", base::FEATURE_DISABLED_BY_DEFAULT);
Nate Fischerac07b2622020-10-01 20:20:1456
57// 2 lines
Daniel Chengc89c8532022-10-03 15:04:4658BASE_FEATURE(kTwoLineFeatureA, "TwoLineFeatureA",
59 base::FEATURE_DISABLED_BY_DEFAULT);
60BASE_FEATURE(kTwoLineFeatureB,
61 "TwoLineFeatureB", base::FEATURE_DISABLED_BY_DEFAULT);
Nate Fischerac07b2622020-10-01 20:20:1462
63// 3 lines
Daniel Chengc89c8532022-10-03 15:04:4664BASE_FEATURE(kFeatureWithAVeryLongNameThatWillHaveToWrap,
Nate Fischerac07b2622020-10-01 20:20:1465 "FeatureWithAVeryLongNameThatWillHaveToWrap",
Daniel Chengc89c8532022-10-03 15:04:4666 base::FEATURE_DISABLED_BY_DEFAULT);
Nate Fischerac07b2622020-10-01 20:20:1467""".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
Daniel Chengc89c8532022-10-03 15:04:4686BASE_FEATURE(kMismatchedFeature, "MismatchedName",
87 base::FEATURE_DISABLED_BY_DEFAULT);
Nate Fischerac07b2622020-10-01 20:20:1488
89namespace myfeature {
90// In a namespace
Daniel Chengc89c8532022-10-03 15:04:4691BASE_FEATURE(kSomeFeature, "SomeFeature",
92 base::FEATURE_DISABLED_BY_DEFAULT);
Nate Fischerac07b2622020-10-01 20:20:1493}
94
Nate Fischerac07b2622020-10-01 20:20:1495// Build config-specific base::Feature
Xiaohan Wang59f56422022-01-21 20:52:1896#if BUILDFLAG(IS_ANDROID)
Daniel Chengc89c8532022-10-03 15:04:4697BASE_FEATURE(kAndroidOnlyFeature, "AndroidOnlyFeature",
98 base::FEATURE_DISABLED_BY_DEFAULT);
Nate Fischerac07b2622020-10-01 20:20:1499#endif
100
101// Value depends on build config
Daniel Chengc89c8532022-10-03 15:04:46102BASE_FEATURE(kMaybeEnabled, "MaybeEnabled",
Xiaohan Wang59f56422022-01-21 20:52:18103#if BUILDFLAG(IS_ANDROID)
Nate Fischerac07b2622020-10-01 20:20:14104 base::FEATURE_DISABLED_BY_DEFAULT
105#else
106 base::FEATURE_ENABLED_BY_DEFAULT
107#endif
Daniel Chengc89c8532022-10-03 15:04:46108);
Nate Fischerac07b2622020-10-01 20:20:14109""".split('\n')
110 feature_file_parser = java_cpp_utils.CppConstantParser(
111 java_cpp_features.FeatureParserDelegate(), test_data)
112 features = feature_file_parser.Parse()
Daniel Chengc89c8532022-10-03 15:04:46113 self.assertEqual(4, len(features))
Nate Fischerac07b2622020-10-01 20:20:14114 self.assertEqual('MISMATCHED_FEATURE', features[0].name)
115 self.assertEqual('"MismatchedName"', features[0].value)
116 self.assertEqual('SOME_FEATURE', features[1].name)
117 self.assertEqual('"SomeFeature"', features[1].value)
Daniel Chengc89c8532022-10-03 15:04:46118 self.assertEqual('ANDROID_ONLY_FEATURE', features[2].name)
119 self.assertEqual('"AndroidOnlyFeature"', features[2].value)
120 self.assertEqual('MAYBE_ENABLED', features[3].name)
121 self.assertEqual('"MaybeEnabled"', features[3].value)
Nate Fischerac07b2622020-10-01 20:20:14122
123 def testNotYetSupported(self):
124 # Negative test for cases we don't yet support, to ensure we don't misparse
125 # these until we intentionally add proper support.
126 test_data = """
127// Not currently supported: name depends on C++ directive
Daniel Chengc89c8532022-10-03 15:04:46128BASE_FEATURE(kNameDependsOnOs,
Xiaohan Wang59f56422022-01-21 20:52:18129#if BUILDFLAG(IS_ANDROID)
Nate Fischerac07b2622020-10-01 20:20:14130 "MaybeName1",
131#else
132 "MaybeName2",
133#endif
Daniel Chengc89c8532022-10-03 15:04:46134 base::FEATURE_DISABLED_BY_DEFAULT);
Nate Fischerac07b2622020-10-01 20:20:14135
136// Not currently supported: feature named with a constant instead of literal
Daniel Chengc89c8532022-10-03 15:04:46137BASE_FEATURE(kNamedAfterConstant, kNamedStringConstant,
138 base::FEATURE_DISABLED_BY_DEFAULT};
Nate Fischerac07b2622020-10-01 20:20:14139""".split('\n')
140 feature_file_parser = java_cpp_utils.CppConstantParser(
141 java_cpp_features.FeatureParserDelegate(), test_data)
142 features = feature_file_parser.Parse()
143 self.assertEqual(0, len(features))
144
145 def testTreatWebViewLikeOneWord(self):
146 test_data = """
Daniel Chengc89c8532022-10-03 15:04:46147BASE_FEATURE(kSomeWebViewFeature, "SomeWebViewFeature",
148 base::FEATURE_DISABLED_BY_DEFAULT);
149BASE_FEATURE(kWebViewOtherFeature, "WebViewOtherFeature",
150 base::FEATURE_ENABLED_BY_DEFAULT);
151BASE_FEATURE(kFeatureWithPluralWebViews,
Nate Fischerac07b2622020-10-01 20:20:14152 "FeatureWithPluralWebViews",
Daniel Chengc89c8532022-10-03 15:04:46153 base::FEATURE_ENABLED_BY_DEFAULT);
Nate Fischerac07b2622020-10-01 20:20:14154""".split('\n')
155 feature_file_parser = java_cpp_utils.CppConstantParser(
156 java_cpp_features.FeatureParserDelegate(), test_data)
157 features = feature_file_parser.Parse()
158 self.assertEqual('SOME_WEBVIEW_FEATURE', features[0].name)
159 self.assertEqual('"SomeWebViewFeature"', features[0].value)
160 self.assertEqual('WEBVIEW_OTHER_FEATURE', features[1].name)
161 self.assertEqual('"WebViewOtherFeature"', features[1].value)
162 self.assertEqual('FEATURE_WITH_PLURAL_WEBVIEWS', features[2].name)
163 self.assertEqual('"FeatureWithPluralWebViews"', features[2].value)
164
165 def testSpecialCharacters(self):
166 test_data = r"""
Daniel Chengc89c8532022-10-03 15:04:46167BASE_FEATURE(kFeatureWithEscapes, "Weird\tfeature\"name\n",
168 base::FEATURE_DISABLED_BY_DEFAULT);
169BASE_FEATURE(kFeatureWithEscapes2,
Nate Fischerac07b2622020-10-01 20:20:14170 "Weird\tfeature\"name\n",
Daniel Chengc89c8532022-10-03 15:04:46171 base::FEATURE_ENABLED_BY_DEFAULT);
Nate Fischerac07b2622020-10-01 20:20:14172""".split('\n')
173 feature_file_parser = java_cpp_utils.CppConstantParser(
174 java_cpp_features.FeatureParserDelegate(), test_data)
175 features = feature_file_parser.Parse()
176 self.assertEqual('FEATURE_WITH_ESCAPES', features[0].name)
177 self.assertEqual(r'"Weird\tfeature\"name\n"', features[0].value)
178 self.assertEqual('FEATURE_WITH_ESCAPES2', features[1].name)
179 self.assertEqual(r'"Weird\tfeature\"name\n"', features[1].value)
180
Nate Fischerac07b2622020-10-01 20:20:14181
182if __name__ == '__main__':
183 unittest.main()