xref: /aosp_15_r20/external/cronet/build/android/gyp/java_cpp_features_tests.py (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1#!/usr/bin/env python3
2
3# Copyright 2020 The Chromium Authors
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. base::Feature intentionally split across two lines.
31BASE_FEATURE(kSomeFeature, "SomeFeature",
32             base::FEATURE_DISABLED_BY_DEFAULT);
33
34// Real comment that spans
35// multiple lines.
36BASE_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
55BASE_FEATURE(kShort, "Short", base::FEATURE_DISABLED_BY_DEFAULT);
56
57// 2 lines
58BASE_FEATURE(kTwoLineFeatureA, "TwoLineFeatureA",
59             base::FEATURE_DISABLED_BY_DEFAULT);
60BASE_FEATURE(kTwoLineFeatureB,
61    "TwoLineFeatureB", base::FEATURE_DISABLED_BY_DEFAULT);
62
63// 3 lines
64BASE_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
86BASE_FEATURE(kMismatchedFeature, "MismatchedName",
87    base::FEATURE_DISABLED_BY_DEFAULT);
88
89namespace myfeature {
90// In a namespace
91BASE_FEATURE(kSomeFeature, "SomeFeature",
92             base::FEATURE_DISABLED_BY_DEFAULT);
93}
94
95// Build config-specific base::Feature
96#if BUILDFLAG(IS_ANDROID)
97BASE_FEATURE(kAndroidOnlyFeature, "AndroidOnlyFeature",
98             base::FEATURE_DISABLED_BY_DEFAULT);
99#endif
100
101// Value depends on build config
102BASE_FEATURE(kMaybeEnabled, "MaybeEnabled",
103#if BUILDFLAG(IS_ANDROID)
104    base::FEATURE_DISABLED_BY_DEFAULT
105#else
106    base::FEATURE_ENABLED_BY_DEFAULT
107#endif
108);
109""".split('\n')
110    feature_file_parser = java_cpp_utils.CppConstantParser(
111        java_cpp_features.FeatureParserDelegate(), test_data)
112    features = feature_file_parser.Parse()
113    self.assertEqual(4, len(features))
114    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)
118    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)
122
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
128BASE_FEATURE(kNameDependsOnOs,
129#if BUILDFLAG(IS_ANDROID)
130    "MaybeName1",
131#else
132    "MaybeName2",
133#endif
134    base::FEATURE_DISABLED_BY_DEFAULT);
135
136// Not currently supported: feature named with a constant instead of literal
137BASE_FEATURE(kNamedAfterConstant, kNamedStringConstant,
138             base::FEATURE_DISABLED_BY_DEFAULT};
139""".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 = """
147BASE_FEATURE(kSomeWebViewFeature, "SomeWebViewFeature",
148             base::FEATURE_DISABLED_BY_DEFAULT);
149BASE_FEATURE(kWebViewOtherFeature, "WebViewOtherFeature",
150             base::FEATURE_ENABLED_BY_DEFAULT);
151BASE_FEATURE(kFeatureWithPluralWebViews,
152    "FeatureWithPluralWebViews",
153    base::FEATURE_ENABLED_BY_DEFAULT);
154""".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"""
167BASE_FEATURE(kFeatureWithEscapes, "Weird\tfeature\"name\n",
168             base::FEATURE_DISABLED_BY_DEFAULT);
169BASE_FEATURE(kFeatureWithEscapes2,
170    "Weird\tfeature\"name\n",
171    base::FEATURE_ENABLED_BY_DEFAULT);
172""".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
181
182if __name__ == '__main__':
183  unittest.main()
184